From b9560df899fdea34ac69692ef2447ffdd2d3365a Mon Sep 17 00:00:00 2001 From: "Angel L. Mateo" Date: Tue, 2 Sep 2014 11:35:42 +0200 Subject: Check if file exists before loading with loadyaml. If not, return nil --- lib/puppet/parser/functions/loadyaml.rb | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/lib/puppet/parser/functions/loadyaml.rb b/lib/puppet/parser/functions/loadyaml.rb index 10c4005..ca655f6 100644 --- a/lib/puppet/parser/functions/loadyaml.rb +++ b/lib/puppet/parser/functions/loadyaml.rb @@ -13,7 +13,12 @@ module Puppet::Parser::Functions raise Puppet::ParseError, ("loadyaml(): wrong number of arguments (#{args.length}; must be 1)") end - YAML.load_file(args[0]) + if File.exists?(args[0]) then + YAML.load_file(args[0]) + else + warning("Can't load " + args[0] + ". File does not exist!") + nil + end end -- cgit v1.2.3 From 260c1f4b92113a1da3b30562a11d20a79e5b08db Mon Sep 17 00:00:00 2001 From: Oliver Bertuch Date: Thu, 4 Dec 2014 22:33:15 +0100 Subject: Add new functions validate_numeric() and validate_integer(). --- README.markdown | 70 ++++++++ lib/puppet/parser/functions/validate_integer.rb | 128 ++++++++++++++ lib/puppet/parser/functions/validate_numeric.rb | 90 ++++++++++ spec/functions/validate_integer_spec.rb | 219 ++++++++++++++++++++++++ spec/functions/validate_numeric_spec.rb | 217 +++++++++++++++++++++++ 5 files changed, 724 insertions(+) create mode 100644 lib/puppet/parser/functions/validate_integer.rb create mode 100644 lib/puppet/parser/functions/validate_numeric.rb create mode 100755 spec/functions/validate_integer_spec.rb create mode 100755 spec/functions/validate_numeric_spec.rb diff --git a/README.markdown b/README.markdown index 78839c6..69c5d3d 100644 --- a/README.markdown +++ b/README.markdown @@ -579,6 +579,76 @@ The first argument of this function should be the string to test, and the second *Type*: statement +* `validate_integer`: Validate that the first argument is an integer (or an array of integers). Abort catalog compilation if any of the checks fail. + + The second argument is optional and passes a maximum. (All elements of) the first argument has to be less or equal to this max. + + The third argument is optional and passes a minimum. (All elements of) the first argument has to be greater or equal to this min. + If, and only if, a minimum is given, the second argument may be an empty string or undef, which will be handled to just check + if (all elements of) the first argument are greater or equal to the given minimum. + + It will fail if the first argument is not an integer or array of integers, and if arg 2 and arg 3 are not convertable to an integer. + + The following values will pass: + + ``` + validate_integer(1) + validate_integer(1, 2) + validate_integer(1, 1) + validate_integer(1, 2, 0) + validate_integer(2, 2, 2) + validate_integer(2, '', 0) + validate_integer(2, undef, 0) + $foo = undef + validate_integer(2, $foo, 0) + validate_integer([1,2,3,4,5], 6) + validate_integer([1,2,3,4,5], 6, 0) + ``` + + * Plus all of the above, but any combination of values passed as strings ('1' or "1"). + * Plus all of the above, but with (correct) combinations of negative integer values. + + The following values will fail, causing compilation to abort: + + ``` + validate_integer(true) + validate_integer(false) + validate_integer(7.0) + validate_integer({ 1 => 2 }) + $foo = undef + validate_integer($foo) + validate_integer($foobaridontexist) + + validate_integer(1, 0) + validate_integer(1, true) + validate_integer(1, '') + validate_integer(1, undef) + validate_integer(1, , 0) + validate_integer(1, 2, 3) + validate_integer(1, 3, 2) + validate_integer(1, 3, true) + ``` + + * Plus all of the above, but any combination of values passed as strings ('false' or "false"). + * Plus all of the above, but with incorrect combinations of negative integer values. + * Plus all of the above, but with non-integer crap in arrays or maximum / minimum argument. + + *Type*: statement + +* `validate_numeric`: Validate that the first argument is a numeric value (or an array of numeric values). Abort catalog compilation if any of the checks fail. + + The second argument is optional and passes a maximum. (All elements of) the first argument has to be less or equal to this max. + + The third argument is optional and passes a minimum. (All elements of) the first argument has to be greater or equal to this min. + If, and only if, a minimum is given, the second argument may be an empty string or undef, which will be handled to just check + if (all elements of) the first argument are greater or equal to the given minimum. + + It will fail if the first argument is not a numeric (Integer or Float) or array of numerics, and if arg 2 and arg 3 are not convertable to a numeric. + + For passing and failing usage, see `validate_integer()`. It is all the same for validate_numeric, yet now floating point values are allowed, too. + + *Type*: statement + * `validate_re`: Performs simple validation of a string against one or more regular expressions. The first argument of this function should be the string to test, and the second argument should be a stringified regular expression (without the // delimiters) or an array of regular expressions. If none diff --git a/lib/puppet/parser/functions/validate_integer.rb b/lib/puppet/parser/functions/validate_integer.rb new file mode 100644 index 0000000..c12d676 --- /dev/null +++ b/lib/puppet/parser/functions/validate_integer.rb @@ -0,0 +1,128 @@ +module Puppet::Parser::Functions + + newfunction(:validate_integer, :doc => <<-'ENDHEREDOC') do |args| + Validate that the first argument is an integer (or an array of integers). Abort catalog compilation if any of the checks fail. + + The second argument is optional and passes a maximum. (All elements of) the first argument has to be less or equal to this max. + + The third argument is optional and passes a minimum. (All elements of) the first argument has to be greater or equal to this min. + If, and only if, a minimum is given, the second argument may be an empty string or undef, which will be handled to just check + if (all elements of) the first argument are greater or equal to the given minimum. + + It will fail if the first argument is not an integer or array of integers, and if arg 2 and arg 3 are not convertable to an integer. + + The following values will pass: + + validate_integer(1) + validate_integer(1, 2) + validate_integer(1, 1) + validate_integer(1, 2, 0) + validate_integer(2, 2, 2) + validate_integer(2, '', 0) + validate_integer(2, undef, 0) + $foo = undef + validate_integer(2, $foo, 0) + validate_integer([1,2,3,4,5], 6) + validate_integer([1,2,3,4,5], 6, 0) + + Plus all of the above, but any combination of values passed as strings ('1' or "1"). + Plus all of the above, but with (correct) combinations of negative integer values. + + The following values will not: + + validate_integer(true) + validate_integer(false) + validate_integer(7.0) + validate_integer({ 1 => 2 }) + $foo = undef + validate_integer($foo) + validate_integer($foobaridontexist) + + validate_integer(1, 0) + validate_integer(1, true) + validate_integer(1, '') + validate_integer(1, undef) + validate_integer(1, , 0) + validate_integer(1, 2, 3) + validate_integer(1, 3, 2) + validate_integer(1, 3, true) + + Plus all of the above, but any combination of values passed as strings ('false' or "false"). + Plus all of the above, but with incorrect combinations of negative integer values. + Plus all of the above, but with non-integer crap in arrays or maximum / minimum argument. + + ENDHEREDOC + + # tell the user we need at least one, and optionally up to two other parameters + raise Puppet::ParseError, "validate_integer(): Wrong number of arguments; must be 1, 2 or 3, got #{args.length}" unless args.length > 0 and args.length < 4 + + input, max, min = *args + + # check maximum parameter + if args.length > 1 + max = max.to_s + # allow max to be empty (or undefined) if we have a minimum set + if args.length > 2 and max == '' + max = nil + else + begin + max = Integer(max) + rescue TypeError, ArgumentError + raise Puppet::ParseError, "validate_integer(): Expected second argument to be unset or an Integer, got #{max}:#{max.class}" + end + end + else + max = nil + end + + # check minimum parameter + if args.length > 2 + begin + min = Integer(min.to_s) + rescue TypeError, ArgumentError + raise Puppet::ParseError, "validate_integer(): Expected third argument to be unset or an Integer, got #{min}:#{min.class}" + end + else + min = nil + end + + # ensure that min < max + if min and max and min > max + raise Puppet::ParseError, "validate_integer(): Expected second argument to be larger than third argument, got #{max} < #{min}" + end + + # create lamba validator function + validator = lambda do |num| + # check input < max + if max and num > max + raise Puppet::ParseError, "validate_integer(): Expected #{input.inspect} to be smaller or equal to #{max}, got #{input.inspect}." + end + # check input > min (this will only be checked if no exception has been raised before) + if min and num < min + raise Puppet::ParseError, "validate_integer(): Expected #{input.inspect} to be greater or equal to #{min}, got #{input.inspect}." + end + end + + # if this is an array, handle it. + case input + when Array + # check every element of the array + input.each_with_index do |arg, pos| + begin + arg = Integer(arg.to_s) + validator.call(arg) + rescue TypeError, ArgumentError + raise Puppet::ParseError, "validate_integer(): Expected element at array position #{pos} to be an Integer, got #{arg.class}" + end + end + # check the input. this will also fail any stuff other than pure, shiny integers + else + begin + input = Integer(input.to_s) + validator.call(input) + rescue TypeError, ArgumentError + raise Puppet::ParseError, "validate_integer(): Expected first argument to be an Integer or Array, got #{input.class}" + end + end + end +end diff --git a/lib/puppet/parser/functions/validate_numeric.rb b/lib/puppet/parser/functions/validate_numeric.rb new file mode 100644 index 0000000..27eec30 --- /dev/null +++ b/lib/puppet/parser/functions/validate_numeric.rb @@ -0,0 +1,90 @@ +module Puppet::Parser::Functions + + newfunction(:validate_numeric, :doc => <<-'ENDHEREDOC') do |args| + Validate that the first argument is a numeric value (or an array of numeric values). Abort catalog compilation if any of the checks fail. + + The second argument is optional and passes a maximum. (All elements of) the first argument has to be less or equal to this max. + + The third argument is optional and passes a minimum. (All elements of) the first argument has to be greater or equal to this min. + If, and only if, a minimum is given, the second argument may be an empty string or undef, which will be handled to just check + if (all elements of) the first argument are greater or equal to the given minimum. + + It will fail if the first argument is not a numeric (Integer or Float) or array of numerics, and if arg 2 and arg 3 are not convertable to a numeric. + + For passing and failing usage, see `validate_integer()`. It is all the same for validate_numeric, yet now floating point values are allowed, too. + + ENDHEREDOC + + # tell the user we need at least one, and optionally up to two other parameters + raise Puppet::ParseError, "validate_numeric(): Wrong number of arguments; must be 1, 2 or 3, got #{args.length}" unless args.length > 0 and args.length < 4 + + input, max, min = *args + + # check maximum parameter + if args.length > 1 + max = max.to_s + # allow max to be empty (or undefined) if we have a minimum set + if args.length > 2 and max == '' + max = nil + else + begin + max = Float(max) + rescue TypeError, ArgumentError + raise Puppet::ParseError, "validate_numeric(): Expected second argument to be unset or a Numeric, got #{max}:#{max.class}" + end + end + else + max = nil + end + + # check minimum parameter + if args.length > 2 + begin + min = Float(min.to_s) + rescue TypeError, ArgumentError + raise Puppet::ParseError, "validate_numeric(): Expected third argument to be unset or a Numeric, got #{min}:#{min.class}" + end + else + min = nil + end + + # ensure that min < max + if min and max and min > max + raise Puppet::ParseError, "validate_numeric(): Expected second argument to be larger than third argument, got #{max} < #{min}" + end + + # create lamba validator function + validator = lambda do |num| + # check input < max + if max and num > max + raise Puppet::ParseError, "validate_numeric(): Expected #{input.inspect} to be smaller or equal to #{max}, got #{input.inspect}." + end + # check input > min (this will only be checked if no exception has been raised before) + if min and num < min + raise Puppet::ParseError, "validate_numeric(): Expected #{input.inspect} to be greater or equal to #{min}, got #{input.inspect}." + end + end + + # if this is an array, handle it. + case input + when Array + # check every element of the array + input.each_with_index do |arg, pos| + begin + arg = Float(arg.to_s) + validator.call(arg) + rescue TypeError, ArgumentError + raise Puppet::ParseError, "validate_numeric(): Expected element at array position #{pos} to be a Numeric, got #{arg.class}" + end + end + # check the input. this will also fail any stuff other than pure, shiny integers + else + begin + input = Float(input.to_s) + validator.call(input) + rescue TypeError, ArgumentError + raise Puppet::ParseError, "validate_numeric(): Expected first argument to be a Numeric or Array, got #{input.class}" + end + end + end +end diff --git a/spec/functions/validate_integer_spec.rb b/spec/functions/validate_integer_spec.rb new file mode 100755 index 0000000..dff3415 --- /dev/null +++ b/spec/functions/validate_integer_spec.rb @@ -0,0 +1,219 @@ +#! /usr/bin/env ruby -S rspec + +require 'spec_helper' + +describe Puppet::Parser::Functions.function(:validate_integer) do + let(:scope) { PuppetlabsSpec::PuppetInternals.scope } + + describe 'when calling validate_integer from puppet without any argument or to many' do + it "should not compile when no argument is passed" do + Puppet[:code] = "validate_integer()" + expect { scope.compiler.compile }.to raise_error(Puppet::ParseError, /Wrong number of arguments/) + end + it "should not compile when more than three arguments are passed" do + Puppet[:code] = "validate_integer(1, 1, 1, 1)" + expect { scope.compiler.compile }.to raise_error(Puppet::ParseError, /Wrong number of arguments/) + end + end + + describe 'when calling validate_integer from puppet only with input' do + %w{ 1 -1 }.each do |the_number| + it "should compile when #{the_number} is an encapsulated integer" do + Puppet[:code] = "validate_integer('#{the_number}')" + scope.compiler.compile + end + it "should compile when #{the_number} is an bare integer" do + Puppet[:code] = "validate_integer(#{the_number})" + scope.compiler.compile + end + end + + %w{ [1,2,3,4,5] ['1','2','3','4','5'] }.each do |the_number| + it "should compile when multiple Integer arguments are passed in an Array" do + Puppet[:code] = "validate_integer(#{the_number})" + scope.compiler.compile + end + end + + %w{ true false iAmAString 1test 7.0 -7.0 }.each do |the_number| + it "should not compile when #{the_number} is in a string" do + Puppet[:code] = "validate_integer('#{the_number}')" + expect { scope.compiler.compile }.to raise_error(Puppet::ParseError, /to be an Integer/) + end + + it "should not compile when #{the_number} is a bare word" do + Puppet[:code] = "validate_integer(#{the_number})" + expect { scope.compiler.compile }.to raise_error(Puppet::ParseError, /to be an Integer/) + end + end + + it "should not compile when an Integer is part of a larger String" do + Puppet[:code] = "validate_integer('1 test')" + expect { scope.compiler.compile }.to raise_error(Puppet::ParseError, /to be an Integer/) + end + + it "should not compile when an Array with a non-Integer value is passed" do + Puppet[:code] = "validate_integer([1, '-7.0'])" + expect { scope.compiler.compile }.to raise_error(Puppet::ParseError, /at array position 1 to be an Integer/) + end + + it "should not compile when a Hash is passed" do + Puppet[:code] = "validate_integer({ 1 => 2 })" + expect { scope.compiler.compile }.to raise_error(Puppet::ParseError, /to be an Integer or Array/) + end + + it "should not compile when an explicitly undef variable is passed" do + Puppet[:code] = <<-'ENDofPUPPETcode' + $foo = undef + validate_integer($foo) + ENDofPUPPETcode + expect { scope.compiler.compile }.to raise_error(Puppet::ParseError, /to be an Integer/) + end + + it "should not compile when an undefined variable is passed" do + Puppet[:code] = <<-'ENDofPUPPETcode' + validate_integer($foobarbazishouldnotexist) + ENDofPUPPETcode + expect { scope.compiler.compile }.to raise_error(Puppet::ParseError, /to be an Integer/) + end + end + + describe 'when calling validate_integer from puppet with input and a maximum' do + max = 10 + %w{ 1 -1 }.each do |the_number| + it "should compile when #{the_number} is lower than a maximum of #{max}" do + Puppet[:code] = "validate_integer(#{the_number},#{max})" + scope.compiler.compile + end + end + + it "should compile when an Integer is equal the maximum" do + Puppet[:code] = "validate_integer(#{max},#{max})" + scope.compiler.compile + end + + it "should not compile when #{max+1} is greater than a maximum of #{max}" do + Puppet[:code] = "validate_integer(#{max+1},#{max})" + expect { scope.compiler.compile }.to raise_error(Puppet::ParseError, /to be smaller or equal to/) + end + + %w{ [-10,1,2,3,4,5,10] ['-10','1','2','3','4','5','10'] }.each do |the_number| + it "should compile when each element of #{the_number} is lower than a maximum of #{max}" do + Puppet[:code] = "validate_integer(#{the_number},#{max})" + scope.compiler.compile + end + end + + it "should not compile when an element of an Array [-10,1,2,3,4,5,#{max+1}] is greater than a maximum of #{max}" do + Puppet[:code] = "validate_integer([-10,1,2,3,4,5,#{max+1}],#{max})" + expect { scope.compiler.compile }.to raise_error(Puppet::ParseError, /to be smaller or equal to/) + end + + %w{ true false iAmAString 1test 7.0 -7.0 }.each do |the_max| + it "should not compile when a non-Integer maximum #{the_max}, encapsulated in a String, is passed" do + Puppet[:code] = "validate_integer(1,'#{the_max}')" + expect { scope.compiler.compile }.to raise_error(Puppet::ParseError, /to be unset or an Integer/) + end + + it "should not compile when a non-Integer maximum #{the_max} bare word is passed" do + Puppet[:code] = "validate_integer(1,#{the_max})" + expect { scope.compiler.compile }.to raise_error(Puppet::ParseError, /to be unset or an Integer/) + end + end + + it "should not compile when an explicitly undefined variable is passed as maximum and no minimum is passed" do + Puppet[:code] = <<-'ENDofPUPPETcode' + $foo = undef + validate_integer(10, $foo) + ENDofPUPPETcode + expect { scope.compiler.compile }.to raise_error(Puppet::ParseError, /to be unset or an Integer/) + end + it "should not compile when an explicitly undef is passed as maximum and no minimum is passed" do + Puppet[:code] = "validate_integer(10, undef)" + expect { scope.compiler.compile }.to raise_error(Puppet::ParseError, /to be unset or an Integer/) + end + it "should not compile when an empty string is passed as maximum and no minimum is passed" do + Puppet[:code] = "validate_integer(10, '')" + expect { scope.compiler.compile }.to raise_error(Puppet::ParseError, /to be unset or an Integer/) + end + it "should not compile when an undefined variable for a maximum is passed" do + Puppet[:code] = "validate_integer(10, $foobarbazishouldnotexist)" + expect { scope.compiler.compile }.to raise_error(Puppet::ParseError, /to be unset or an Integer/) + end + end + + describe 'when calling validate_integer from puppet with input, a maximum and a minimum' do + it "should not compile when a minimum larger than maximum is passed" do + Puppet[:code] = "validate_integer(1,1,2)" + expect { scope.compiler.compile }.to raise_error(Puppet::ParseError, /second argument to be larger than third argument/) + end + + max = 10 + min = -10 + %w{ 1 -1 }.each do |the_number| + it "should compile when each element of #{the_number} is within a range from #{min} to #{max}" do + Puppet[:code] = "validate_integer(#{the_number},#{max},#{min})" + scope.compiler.compile + end + end + + it "should compile when an Integer is equal the minimum" do + Puppet[:code] = "validate_integer(#{min},#{max},#{min})" + scope.compiler.compile + end + + it "should compile when an Integer is equal the minimum and maximum" do + Puppet[:code] = "validate_integer(#{max},#{max},#{max})" + scope.compiler.compile + end + + it "should compile when an empty maximum is passed and the Integer is greater than the minimum" do + Puppet[:code] = "validate_integer(#{max},'',#{min})" + scope.compiler.compile + end + it "should compile when an explicitly undefined maximum is passed and the Integer is greater than the minimum" do + Puppet[:code] = "validate_integer(#{max},undef,#{min})" + scope.compiler.compile + end + it "should compile when an explicitly undefined variable is passed for maximum and the Integer is greater than the minimum" do + Puppet[:code] = <<-"ENDofPUPPETcode" + $foo = undef + validate_integer(#{max}, $foo, #{min}) + ENDofPUPPETcode + scope.compiler.compile + end + it "should not compile when no maximum value is given and the Integer is greater than the minimum" do + Puppet[:code] = "validate_integer(#{max},,#{min})" + expect { scope.compiler.compile }.to raise_error(Puppet::Error, /Syntax error at ','/) + end + + it "should not compile when #{min-1} is lower than a minimum of #{min}" do + Puppet[:code] = "validate_integer(#{min-1},#{max},#{min})" + expect { scope.compiler.compile }.to raise_error(Puppet::ParseError, /to be greater or equal to/) + end + + %w{ [-10,1,2,3,4,5,10] ['-10','1','2','3','4','5','10'] }.each do |the_number| + it "should compile when each element of #{the_number} is within a range from #{min} to #{max}" do + Puppet[:code] = "validate_integer(#{the_number},#{max},#{min})" + scope.compiler.compile + end + end + + it "should not compile when an element of an Array [#{min-1},1,2,3,4,5,10] is lower than a minimum of #{min}" do + Puppet[:code] = "validate_integer([#{min-1},1,2,3,4,5,10],#{max},#{min})" + expect { scope.compiler.compile }.to raise_error(Puppet::ParseError, /to be greater or equal to/) + end + + %w{ true false iAmAString 1test 7.0 -7.0 }.each do |the_min| + it "should not compile when a non-Integer minimum #{the_min}, encapsulated in a String, is passed" do + Puppet[:code] = "validate_integer(1,#{max},'#{the_min}')" + expect { scope.compiler.compile }.to raise_error(Puppet::ParseError, /to be unset or an Integer/) + end + + it "should not compile when a non-Integer minimum #{the_min} bare word is passed" do + Puppet[:code] = "validate_integer(1,#{max},#{the_min})" + expect { scope.compiler.compile }.to raise_error(Puppet::ParseError, /to be unset or an Integer/) + end + end + end +end diff --git a/spec/functions/validate_numeric_spec.rb b/spec/functions/validate_numeric_spec.rb new file mode 100755 index 0000000..c8b0e4d --- /dev/null +++ b/spec/functions/validate_numeric_spec.rb @@ -0,0 +1,217 @@ +#! /usr/bin/env ruby -S rspec + +require 'spec_helper' + +describe Puppet::Parser::Functions.function(:validate_numeric) do + let(:scope) { PuppetlabsSpec::PuppetInternals.scope } + + describe 'when calling validate_numeric from puppet without any argument or to many' do + it "should not compile when no argument is passed" do + Puppet[:code] = "validate_numeric()" + expect { scope.compiler.compile }.to raise_error(Puppet::ParseError, /Wrong number of arguments/) + end + it "should not compile when more than three arguments are passed" do + Puppet[:code] = "validate_numeric(1, 1, 1, 1)" + expect { scope.compiler.compile }.to raise_error(Puppet::ParseError, /Wrong number of arguments/) + end + end + + describe 'when calling validate_numeric from puppet only with input' do + %w{ 1 -1 1.0 -1.0 }.each do |the_number| + it "should compile when #{the_number} is an encapsulated numeric" do + Puppet[:code] = "validate_numeric('#{the_number}')" + scope.compiler.compile + end + it "should compile when #{the_number} is a bare numeric" do + Puppet[:code] = "validate_numeric(#{the_number})" + scope.compiler.compile + end + end + + %w{ [1,2,3,4,5] ['1','2','3','4','5'] [1.1,2.2,3.3,4.4,5.5] ['1.1','2.2','3.3','4.4','5.5'] }.each do |the_number| + it "should compile when multiple Numeric arguments are passed in an Array" do + Puppet[:code] = "validate_numeric(#{the_number})" + scope.compiler.compile + end + end + + %w{ true false iAmAString 1test }.each do |the_number| + it "should not compile when #{the_number} is in a string" do + Puppet[:code] = "validate_numeric('#{the_number}')" + expect { scope.compiler.compile }.to raise_error(Puppet::ParseError, /to be a Numeric/) + end + + it "should not compile when #{the_number} is a bare word" do + Puppet[:code] = "validate_numeric(#{the_number})" + expect { scope.compiler.compile }.to raise_error(Puppet::ParseError, /to be a Numeric/) + end + end + + it "should not compile when a Numeric is part of a larger String" do + Puppet[:code] = "validate_numeric('1.0 test')" + expect { scope.compiler.compile }.to raise_error(Puppet::ParseError, /to be a Numeric/) + end + + it "should not compile when an Array with a non-Numeric value is passed" do + Puppet[:code] = "validate_numeric([1, 'test'])" + expect { scope.compiler.compile }.to raise_error(Puppet::ParseError, /at array position 1 to be a Numeric/) + end + + it "should not compile when a Hash is passed" do + Puppet[:code] = "validate_numeric({ 1 => 2 })" + expect { scope.compiler.compile }.to raise_error(Puppet::ParseError, /to be a Numeric or Array/) + end + + it "should not compile when an explicitly undef variable is passed" do + Puppet[:code] = <<-'ENDofPUPPETcode' + $foo = undef + validate_numeric($foo) + ENDofPUPPETcode + expect { scope.compiler.compile }.to raise_error(Puppet::ParseError, /to be a Numeric/) + end + + it "should not compile when an undefined variable is passed" do + Puppet[:code] = 'validate_numeric($foobarbazishouldnotexist)' + expect { scope.compiler.compile }.to raise_error(Puppet::ParseError, /to be a Numeric/) + end + end + + describe 'when calling validate_numeric from puppet with input and a maximum' do + max = 10 + %w{ 1 -1 1.0 -1.0 }.each do |the_number| + it "should compile when #{the_number} is lower than a maximum of #{max}" do + Puppet[:code] = "validate_numeric(#{the_number},#{max})" + scope.compiler.compile + end + end + + it "should compile when a Numeric is equal the maximum" do + Puppet[:code] = "validate_numeric(#{max},#{max})" + scope.compiler.compile + end + + it "should not compile when #{max+1} is greater than a maximum of #{max}" do + Puppet[:code] = "validate_numeric(#{max+1},#{max})" + expect { scope.compiler.compile }.to raise_error(Puppet::ParseError, /to be smaller or equal to/) + end + + %w{ [-10,1,2,3,4,5,10] ['-10','1','2','3','4','5','10'] }.each do |the_number| + it "should compile when each element of #{the_number} is lower than a maximum of #{max}" do + Puppet[:code] = "validate_numeric(#{the_number},#{max})" + scope.compiler.compile + end + end + + it "should not compile when an element of an Array [-10,1,2,3,4,5,#{max+1}] is greater than a maximum of #{max}" do + Puppet[:code] = "validate_numeric([-10,1,2,3,4,5,#{max+1}],#{max})" + expect { scope.compiler.compile }.to raise_error(Puppet::ParseError, /to be smaller or equal to/) + end + + %w{ true false iAmAString 1test }.each do |the_max| + it "should not compile when a non-Numeric maximum #{the_max}, encapsulated in a String, is passed" do + Puppet[:code] = "validate_numeric(1,'#{the_max}')" + expect { scope.compiler.compile }.to raise_error(Puppet::ParseError, /to be unset or a Numeric/) + end + + it "should not compile when a non-Numeric maximum #{the_max} bare word is passed" do + Puppet[:code] = "validate_numeric(1,#{the_max})" + expect { scope.compiler.compile }.to raise_error(Puppet::ParseError, /to be unset or a Numeric/) + end + end + + it "should not compile when an explicitly undefined variable is passed as maximum and no minimum is passed" do + Puppet[:code] = <<-'ENDofPUPPETcode' + $foo = undef + validate_numeric(10, $foo) + ENDofPUPPETcode + expect { scope.compiler.compile }.to raise_error(Puppet::ParseError, /to be unset or a Numeric/) + end + it "should not compile when an explicitly undef is passed as maximum and no minimum is passed" do + Puppet[:code] = "validate_numeric(10, undef)" + expect { scope.compiler.compile }.to raise_error(Puppet::ParseError, /to be unset or a Numeric/) + end + it "should not compile when an empty string is passed as maximum and no minimum is passed" do + Puppet[:code] = "validate_numeric(10, '')" + expect { scope.compiler.compile }.to raise_error(Puppet::ParseError, /to be unset or a Numeric/) + end + it "should not compile when an undefined variable for a maximum is passed" do + Puppet[:code] = "validate_numeric(10, $foobarbazishouldnotexist)" + expect { scope.compiler.compile }.to raise_error(Puppet::ParseError, /to be unset or a Numeric/) + end + end + + describe 'when calling validate_numeric from puppet with input, a maximum and a minimum' do + it "should not compile when a minimum larger than maximum is passed" do + Puppet[:code] = "validate_numeric(1,1,2)" + expect { scope.compiler.compile }.to raise_error(Puppet::ParseError, /second argument to be larger than third argument/) + end + + max = 10 + min = -10 + %w{ 1 -1 }.each do |the_number| + it "should compile when each element of #{the_number} is within a range from #{min} to #{max}" do + Puppet[:code] = "validate_numeric(#{the_number},#{max},#{min})" + scope.compiler.compile + end + end + + it "should compile when a Numeric is equal the minimum" do + Puppet[:code] = "validate_numeric(#{min},#{max},#{min})" + scope.compiler.compile + end + + it "should compile when a Numeric is equal the minimum and maximum" do + Puppet[:code] = "validate_numeric(#{max},#{max},#{max})" + scope.compiler.compile + end + + it "should compile when an empty maximum is passed and the Numeric is greater than the minimum" do + Puppet[:code] = "validate_numeric(#{max}.1,'',#{min})" + scope.compiler.compile + end + it "should compile when an explicitly undefined maximum is passed and the Numeric is greater than the minimum" do + Puppet[:code] = "validate_numeric(#{max}.1,undef,#{min})" + scope.compiler.compile + end + it "should compile when an explicitly undefined variable is passed for maximum and the Numeric is greater than the minimum" do + Puppet[:code] = <<-"ENDofPUPPETcode" + $foo = undef + validate_numeric(#{max}.1, $foo, #{min}) + ENDofPUPPETcode + scope.compiler.compile + end + it "should not compile when no maximum value is given and the Numeric is greater than the minimum" do + Puppet[:code] = "validate_numeric(#{max}.1,,#{min})" + expect { scope.compiler.compile }.to raise_error(Puppet::Error, /Syntax error at ','/) + end + + it "should not compile when #{min-1} is lower than a minimum of #{min}" do + Puppet[:code] = "validate_numeric(#{min-1.0},#{max},#{min})" + expect { scope.compiler.compile }.to raise_error(Puppet::ParseError, /to be greater or equal to/) + end + + %w{ [-10,1,2,3,4,5,10] ['-10.0','1','2','3','4','5','10.0'] }.each do |the_number| + it "should compile when each element of #{the_number} is within a range from #{min} to #{max}" do + Puppet[:code] = "validate_numeric(#{the_number},#{max},#{min})" + scope.compiler.compile + end + end + + it "should not compile when an element of an Array [#{min-1.1},1,2,3,4,5,10.0] is lower than a minimum of #{min}" do + Puppet[:code] = "validate_numeric([#{min-1},1,2,3,4,5,10],#{max},#{min})" + expect { scope.compiler.compile }.to raise_error(Puppet::ParseError, /to be greater or equal to/) + end + + %w{ true false iAmAString 1test }.each do |the_min| + it "should not compile when a non-Numeric minimum #{the_min}, encapsulated in a String, is passed" do + Puppet[:code] = "validate_numeric(1,#{max},'#{the_min}')" + expect { scope.compiler.compile }.to raise_error(Puppet::ParseError, /to be unset or a Numeric/) + end + + it "should not compile when a non-Numeric minimum #{the_min} bare word is passed" do + Puppet[:code] = "validate_numeric(1,#{max},#{the_min})" + expect { scope.compiler.compile }.to raise_error(Puppet::ParseError, /to be unset or a Numeric/) + end + end + end +end -- cgit v1.2.3 From 305342782998e36e48e1011d12a37c523b838bec Mon Sep 17 00:00:00 2001 From: Oliver Bertuch Date: Fri, 5 Dec 2014 08:48:10 +0100 Subject: Fixing ruby 1.8 support. --- lib/puppet/parser/functions/validate_integer.rb | 3 +++ lib/puppet/parser/functions/validate_numeric.rb | 3 +++ 2 files changed, 6 insertions(+) diff --git a/lib/puppet/parser/functions/validate_integer.rb b/lib/puppet/parser/functions/validate_integer.rb index c12d676..995f8db 100644 --- a/lib/puppet/parser/functions/validate_integer.rb +++ b/lib/puppet/parser/functions/validate_integer.rb @@ -115,6 +115,9 @@ module Puppet::Parser::Functions raise Puppet::ParseError, "validate_integer(): Expected element at array position #{pos} to be an Integer, got #{arg.class}" end end + # for the sake of compatibility with ruby 1.8, we need extra handling of hashes + when Hash + raise Puppet::ParseError, "validate_integer(): Expected first argument to be an Integer or Array, got #{input.class}" # check the input. this will also fail any stuff other than pure, shiny integers else begin diff --git a/lib/puppet/parser/functions/validate_numeric.rb b/lib/puppet/parser/functions/validate_numeric.rb index 27eec30..d2e4d16 100644 --- a/lib/puppet/parser/functions/validate_numeric.rb +++ b/lib/puppet/parser/functions/validate_numeric.rb @@ -77,6 +77,9 @@ module Puppet::Parser::Functions raise Puppet::ParseError, "validate_numeric(): Expected element at array position #{pos} to be a Numeric, got #{arg.class}" end end + # for the sake of compatibility with ruby 1.8, we need extra handling of hashes + when Hash + raise Puppet::ParseError, "validate_integer(): Expected first argument to be a Numeric or Array, got #{input.class}" # check the input. this will also fail any stuff other than pure, shiny integers else begin -- cgit v1.2.3 From 2a3babc348895a4c8990d57f003c41e50f3ed932 Mon Sep 17 00:00:00 2001 From: Rob Fugina Date: Tue, 18 Nov 2014 12:34:55 -0600 Subject: Added type checks for dirname(), and additional tests --- lib/puppet/parser/functions/dirname.rb | 14 ++++++++++---- spec/functions/dirname_spec.rb | 14 ++++++++++++++ 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/lib/puppet/parser/functions/dirname.rb b/lib/puppet/parser/functions/dirname.rb index ea8cc1e..40b300d 100644 --- a/lib/puppet/parser/functions/dirname.rb +++ b/lib/puppet/parser/functions/dirname.rb @@ -4,11 +4,17 @@ module Puppet::Parser::Functions EOS ) do |arguments| - raise(Puppet::ParseError, "dirname(): Wrong number of arguments " + - "given (#{arguments.size} for 1)") if arguments.size < 1 + if arguments.size < 1 then + raise(Puppet::ParseError, "dirname(): No arguments given") + end + if arguments.size > 1 then + raise(Puppet::ParseError, "dirname(): Too many arguments given (#{arguments.size})") + end + unless arguments[0].is_a?(String) + raise(Puppet::ParseError, 'dirname(): Requires string as argument') + end - path = arguments[0] - return File.dirname(path) + return File.dirname(arguments[0]) end end diff --git a/spec/functions/dirname_spec.rb b/spec/functions/dirname_spec.rb index 8a3bcab..4261144 100755 --- a/spec/functions/dirname_spec.rb +++ b/spec/functions/dirname_spec.rb @@ -12,6 +12,10 @@ describe "the dirname function" do expect { scope.function_dirname([]) }.to( raise_error(Puppet::ParseError)) end + it "should raise a ParseError if there is more than 1 argument" do + expect { scope.function_dirname(['a', 'b']) }.to( raise_error(Puppet::ParseError)) + end + it "should return dirname for an absolute path" do result = scope.function_dirname(['/path/to/a/file.ext']) expect(result).to(eq('/path/to/a')) @@ -21,4 +25,14 @@ describe "the dirname function" do result = scope.function_dirname(['path/to/a/file.ext']) expect(result).to(eq('path/to/a')) end + + it "should complain about hash argument" do + expect { scope.function_dirname([{}]) }.to( raise_error(Puppet::ParseError)) + end + it "should complain about list argument" do + expect { scope.function_dirname([[]]) }.to( raise_error(Puppet::ParseError)) + end + it "should complain about numeric argument" do + expect { scope.function_dirname([2112]) }.to( raise_error(Puppet::ParseError)) + end end -- cgit v1.2.3 From 53b1802a92010c9f2ef557005c57977cb219cb64 Mon Sep 17 00:00:00 2001 From: Adam Crews Date: Sun, 1 Feb 2015 22:46:16 -0800 Subject: Add a ceiling function to complement the floor function. --- README.markdown | 3 +++ lib/puppet/parser/functions/ceiling.rb | 25 ++++++++++++++++++++++ spec/acceptance/ceiling_spec.rb | 39 ++++++++++++++++++++++++++++++++++ spec/functions/ceiling_spec.rb | 39 ++++++++++++++++++++++++++++++++++ 4 files changed, 106 insertions(+) create mode 100644 lib/puppet/parser/functions/ceiling.rb create mode 100755 spec/acceptance/ceiling_spec.rb create mode 100755 spec/functions/ceiling_spec.rb diff --git a/README.markdown b/README.markdown index e9a1f4e..3292d3e 100644 --- a/README.markdown +++ b/README.markdown @@ -124,6 +124,9 @@ string. *Type*: rvalue * `capitalize`: Capitalizes the first letter of a string or array of strings. Requires either a single string or an array as an input. *Type*: rvalue +* `ceiling`: Returns the smallest integer greater than or equal to the argument. +Takes a single numeric value as an argument. *Type*: rvalue + * `chomp`: Removes the record separator from the end of a string or an array of strings; for example, 'hello\n' becomes 'hello'. Requires a single string or array as an input. *Type*: rvalue diff --git a/lib/puppet/parser/functions/ceiling.rb b/lib/puppet/parser/functions/ceiling.rb new file mode 100644 index 0000000..5f3b10b --- /dev/null +++ b/lib/puppet/parser/functions/ceiling.rb @@ -0,0 +1,25 @@ +module Puppet::Parser::Functions + newfunction(:ceiling, :type => :rvalue, :doc => <<-EOS + Returns the smallest integer greater or equal to the argument. + Takes a single numeric value as an argument. + EOS + ) do |arguments| + + raise(Puppet::ParseError, "ceiling(): Wrong number of arguments " + + "given (#{arguments.size} for 1)") if arguments.size != 1 + + begin + arg = Float(arguments[0]) + rescue TypeError, ArgumentError => e + raise(Puppet::ParseError, "ceiling(): Wrong argument type " + + "given (#{arguments[0]} for Numeric)") + end + + raise(Puppet::ParseError, "ceiling(): Wrong argument type " + + "given (#{arg.class} for Numeric)") if arg.is_a?(Numeric) == false + + arg.ceil + end +end + +# vim: set ts=2 sw=2 et : diff --git a/spec/acceptance/ceiling_spec.rb b/spec/acceptance/ceiling_spec.rb new file mode 100755 index 0000000..557986e --- /dev/null +++ b/spec/acceptance/ceiling_spec.rb @@ -0,0 +1,39 @@ +#! /usr/bin/env ruby -S rspec +require 'spec_helper_acceptance' + +describe 'ceiling function', :unless => UNSUPPORTED_PLATFORMS.include?(fact('operatingsystem')) do + describe 'success' do + it 'ceilings floats' do + pp = <<-EOS + $a = 12.8 + $b = 13 + $o = ceiling($a) + if $o == $b { + notify { 'output correct': } + } + EOS + + apply_manifest(pp, :catch_failures => true) do |r| + expect(r.stdout).to match(/Notice: output correct/) + end + end + it 'ceilings integers' do + pp = <<-EOS + $a = 7 + $b = 7 + $o = ceiling($a) + if $o == $b { + notify { 'output correct': } + } + EOS + + apply_manifest(pp, :catch_failures => true) do |r| + expect(r.stdout).to match(/Notice: output correct/) + end + end + end + describe 'failure' do + it 'handles improper argument counts' + it 'handles non-numbers' + end +end diff --git a/spec/functions/ceiling_spec.rb b/spec/functions/ceiling_spec.rb new file mode 100755 index 0000000..814aa7c --- /dev/null +++ b/spec/functions/ceiling_spec.rb @@ -0,0 +1,39 @@ +#! /usr/bin/env ruby -S rspec + +require 'spec_helper' + +describe "the ceiling function" do + let(:scope) { PuppetlabsSpec::PuppetInternals.scope } + + it "should exist" do + expect(Puppet::Parser::Functions.function("ceiling")).to eq("function_ceiling") + end + + it "should raise a ParseError if there is less than 1 argument" do + expect { scope.function_ceiling([]) }.to( raise_error(Puppet::ParseError, /Wrong number of arguments/)) + end + + it "should should raise a ParseError if input isn't numeric (eg. String)" do + expect { scope.function_ceiling(["foo"]) }.to( raise_error(Puppet::ParseError, /Wrong argument type/)) + end + + it "should should raise a ParseError if input isn't numeric (eg. Boolean)" do + expect { scope.function_ceiling([true]) }.to( raise_error(Puppet::ParseError, /Wrong argument type/)) + end + + it "should return an integer when a numeric type is passed" do + result = scope.function_ceiling([12.4]) + expect(result.is_a?(Integer)).to(eq(true)) + end + + it "should return the input when an integer is passed" do + result = scope.function_ceiling([7]) + expect(result).to(eq(7)) + end + + it "should return the smallest integer greater than or equal to the input" do + result = scope.function_ceiling([3.8]) + expect(result).to(eq(4)) + end +end + -- cgit v1.2.3 From 8524a17e0f51a36c6c7b518bb41f8bb80c2c96dd Mon Sep 17 00:00:00 2001 From: Eli Young Date: Thu, 12 Feb 2015 11:19:53 -0800 Subject: Fix Travis builds The release of rspec 3.2.0 broke a lot of tests. Pinning to rspec 3.1.0 provides a temporary fix. --- Gemfile | 1 + 1 file changed, 1 insertion(+) diff --git a/Gemfile b/Gemfile index 74a16f3..e2cd97d 100644 --- a/Gemfile +++ b/Gemfile @@ -12,6 +12,7 @@ end group :development, :unit_tests do gem 'rake', '~> 10.1.0', :require => false + gem 'rspec', '~> 3.1.0', :require => false gem 'rspec-puppet', :require => false gem 'puppetlabs_spec_helper', :require => false gem 'puppet-lint', :require => false -- cgit v1.2.3 From f9855d99ec117d336aa3860e2118f29ddfd10c35 Mon Sep 17 00:00:00 2001 From: Eli Young Date: Thu, 12 Feb 2015 11:43:34 -0800 Subject: Have Travis actually test Facter 1.6/1.7 The Gemfile didn't actually specify which version to use for Facter, even when there was an environment variable to that effect. --- Gemfile | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/Gemfile b/Gemfile index e2cd97d..fa2a31c 100644 --- a/Gemfile +++ b/Gemfile @@ -25,8 +25,14 @@ group :system_tests do gem 'serverspec', :require => false end -ENV['GEM_PUPPET_VERSION'] ||= ENV['PUPPET_GEM_VERSION'] -puppetversion = ENV['GEM_PUPPET_VERSION'] +facterversion = ENV['GEM_FACTER_VERSION'] || ENV['FACTER_GEM_VERSION'] +if facterversion + gem 'facter', *location_for(facterversion) +else + gem 'facter', :require => false +end + +puppetversion = ENV['GEM_PUPPET_VERSION'] || ENV['PUPPET_GEM_VERSION'] if puppetversion gem 'puppet', *location_for(puppetversion) else -- cgit v1.2.3 From 84f866ffafbb27a6aa6a1eea92c393a63829e242 Mon Sep 17 00:00:00 2001 From: Eli Young Date: Wed, 28 Jan 2015 15:28:54 -0800 Subject: (MODULES-1738) Don't modify global seed in fqdn_rotate() As per puppetlabs/puppet@292233c, this leaves the global seed in a deterministic state, which is bad. Puppet::Util.deterministic_rand() exists to avoid running into this issue, but is only present starting in Puppet 3.2.0. --- lib/puppet/parser/functions/fqdn_rotate.rb | 16 ++++++++++++++-- spec/functions/fqdn_rotate_spec.rb | 17 +++++++++++++++++ 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/lib/puppet/parser/functions/fqdn_rotate.rb b/lib/puppet/parser/functions/fqdn_rotate.rb index 7f4d37d..cf22d36 100644 --- a/lib/puppet/parser/functions/fqdn_rotate.rb +++ b/lib/puppet/parser/functions/fqdn_rotate.rb @@ -31,8 +31,20 @@ Rotates an array a random number of times based on a nodes fqdn. elements = result.size - srand(Digest::MD5.hexdigest([lookupvar('::fqdn'),arguments].join(':')).hex) - rand(elements).times { + seed = Digest::MD5.hexdigest([lookupvar('::fqdn'),arguments].join(':')).hex + # deterministic_rand() was added in Puppet 3.2.0; reimplement if necessary + if Puppet::Util.respond_to?(:deterministic_rand) + offset = Puppet::Util.deterministic_rand(seed, elements).to_i + else + if defined?(Random) == 'constant' && Random.class == Class + offset = Random.new(seed).rand(elements) + else + srand(seed) + offset = rand(elements) + srand() + end + end + offset.times { result.push result.shift } diff --git a/spec/functions/fqdn_rotate_spec.rb b/spec/functions/fqdn_rotate_spec.rb index 40057d4..673a8a3 100755 --- a/spec/functions/fqdn_rotate_spec.rb +++ b/spec/functions/fqdn_rotate_spec.rb @@ -40,4 +40,21 @@ describe "the fqdn_rotate function" do result = scope.function_fqdn_rotate([value]) result.size.should(eq(4)) end + + it "should use the Puppet::Util.deterministic_rand function if available" do + scope.expects(:lookupvar).with("::fqdn").returns("127.0.0.1") + if Puppet::Util.respond_to?(:deterministic_rand) + Puppet::Util.expects(:deterministic_rand).with(113646079810780526294648115052177588845,4) + end + scope.function_fqdn_rotate(["asdf"]) + end + + it "should not leave the global seed in a deterministic state" do + scope.expects(:lookupvar).with("::fqdn").returns("127.0.0.1").twice + scope.function_fqdn_rotate(["asdf"]) + rand1 = rand() + scope.function_fqdn_rotate(["asdf"]) + rand2 = rand() + expect(rand1).not_to eql(rand2) + end end -- cgit v1.2.3 From 1321d586a88edb7c8bf07c5edb2d5ce2ae44c1a3 Mon Sep 17 00:00:00 2001 From: Sean Millichamp Date: Sat, 14 Feb 2015 10:46:34 -0500 Subject: (MODULES-1771) Don't modify input to is_domain_name() Fix is_domain_name() so it dup's its incoming argument to avoid changing the original with a later chomp! --- lib/puppet/parser/functions/is_domain_name.rb | 2 +- spec/functions/is_domain_name_spec.rb | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/lib/puppet/parser/functions/is_domain_name.rb b/lib/puppet/parser/functions/is_domain_name.rb index b3fee96..24cc208 100644 --- a/lib/puppet/parser/functions/is_domain_name.rb +++ b/lib/puppet/parser/functions/is_domain_name.rb @@ -13,7 +13,7 @@ Returns true if the string passed to this function is a syntactically correct do "given #{arguments.size} for 1") end - domain = arguments[0] + domain = arguments[0].dup # Limits (rfc1035, 3.1) domain_max_length=255 diff --git a/spec/functions/is_domain_name_spec.rb b/spec/functions/is_domain_name_spec.rb index 4d05f5c..5ab8369 100755 --- a/spec/functions/is_domain_name_spec.rb +++ b/spec/functions/is_domain_name_spec.rb @@ -61,4 +61,11 @@ describe "the is_domain_name function" do result = scope.function_is_domain_name(["not valid"]) expect(result).to(be_falsey) end + + # Values obtained from Facter values will be frozen strings + # in newer versions of Facter: + it "should not throw an exception if passed a frozen string" do + result = scope.function_is_domain_name(["my.domain.name".freeze]) + expect(result).to(be_truthy) + end end -- cgit v1.2.3 From b693c870d20f8bf0c574b9581a92ce3842fb3c05 Mon Sep 17 00:00:00 2001 From: Morgan Haskel Date: Thu, 19 Feb 2015 12:01:26 -0800 Subject: Check for string before copying --- lib/puppet/parser/functions/is_domain_name.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/puppet/parser/functions/is_domain_name.rb b/lib/puppet/parser/functions/is_domain_name.rb index 24cc208..2860ded 100644 --- a/lib/puppet/parser/functions/is_domain_name.rb +++ b/lib/puppet/parser/functions/is_domain_name.rb @@ -13,6 +13,9 @@ Returns true if the string passed to this function is a syntactically correct do "given #{arguments.size} for 1") end + # Only allow string types + return false unless arguments[0].is_a?(String) + domain = arguments[0].dup # Limits (rfc1035, 3.1) @@ -20,9 +23,6 @@ Returns true if the string passed to this function is a syntactically correct do label_min_length=1 label_max_length=63 - # Only allow string types - return false unless domain.is_a?(String) - # Allow ".", it is the top level domain return true if domain == '.' -- cgit v1.2.3 From ef539388cbcb68ac5a59a7efb92fadbdb9fcdc72 Mon Sep 17 00:00:00 2001 From: Spencer Krum Date: Thu, 19 Feb 2015 13:58:14 -0800 Subject: Remove travis badge --- README.markdown | 2 -- 1 file changed, 2 deletions(-) diff --git a/README.markdown b/README.markdown index e9a1f4e..3d2d1b9 100644 --- a/README.markdown +++ b/README.markdown @@ -1,7 +1,5 @@ #stdlib -[![Build Status](https://travis-ci.org/puppetlabs/puppetlabs-stdlib.png?branch=master)](https://travis-ci.org/puppetlabs/puppetlabs-stdlib) - ####Table of Contents 1. [Overview](#overview) -- cgit v1.2.3 From 7021b1f55cdc320c7eb389cd91f6be294629669b Mon Sep 17 00:00:00 2001 From: Travis Fields Date: Wed, 25 Feb 2015 11:39:27 -0800 Subject: Add Hash to upcase --- lib/puppet/parser/functions/upcase.rb | 15 ++++++++++----- spec/functions/upcase_spec.rb | 8 +++++++- 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/lib/puppet/parser/functions/upcase.rb b/lib/puppet/parser/functions/upcase.rb index 4302b29..22eae3a 100644 --- a/lib/puppet/parser/functions/upcase.rb +++ b/lib/puppet/parser/functions/upcase.rb @@ -13,22 +13,27 @@ Converts a string or an array of strings to uppercase. Will return: ASDF - EOS + EOS ) do |arguments| raise(Puppet::ParseError, "upcase(): Wrong number of arguments " + - "given (#{arguments.size} for 1)") if arguments.size < 1 + "given (#{arguments.size} for 1)") if arguments.size < 1 value = arguments[0] - unless value.is_a?(Array) || value.is_a?(String) - raise(Puppet::ParseError, 'upcase(): Requires either ' + - 'array or string to work with') + unless value.is_a?(Array) || value.is_a?(String) || value.is_a?(Hash) + raise(Puppet::ParseError, 'upcase(): Requires an ' + + 'array, string or hash to work with') end if value.is_a?(Array) # Numbers in Puppet are often string-encoded which is troublesome ... result = value.collect { |i| i.is_a?(String) ? i.upcase : i } + elsif value.is_a?(Hash) + result = {} + result << value.each_pair do |k, v| + return {k.upcase => v.collect! { |p| p.upcase }} + end else result = value.upcase end diff --git a/spec/functions/upcase_spec.rb b/spec/functions/upcase_spec.rb index 3cf8b05..a50a3ab 100755 --- a/spec/functions/upcase_spec.rb +++ b/spec/functions/upcase_spec.rb @@ -9,7 +9,7 @@ describe "the upcase function" do end it "should raise a ParseError if there is less than 1 arguments" do - expect { scope.function_upcase([]) }.to( raise_error(Puppet::ParseError)) + expect { scope.function_upcase([]) }.to(raise_error(Puppet::ParseError)) end it "should upcase a string" do @@ -30,4 +30,10 @@ describe "the upcase function" do result = scope.function_upcase([value]) result.should(eq('ABC')) end + + it 'should accept hashes and return uppercase' do + expect( + scope.function_upcase([{'test' => %w(this that and other thing)}]) + ).to eq({'TEST' => %w(THIS THAT AND OTHER THING)}) + end end -- cgit v1.2.3 From 419f51bdd9d2aa35a94fbabbfaaf1cbfd81920f4 Mon Sep 17 00:00:00 2001 From: Travis Fields Date: Thu, 26 Feb 2015 10:13:28 -0800 Subject: Fix issue with Ruby 1.8.7 which did not allow for the return in an each_pair of the hash --- lib/puppet/parser/functions/upcase.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/puppet/parser/functions/upcase.rb b/lib/puppet/parser/functions/upcase.rb index 22eae3a..2b05db4 100644 --- a/lib/puppet/parser/functions/upcase.rb +++ b/lib/puppet/parser/functions/upcase.rb @@ -31,8 +31,8 @@ Will return: result = value.collect { |i| i.is_a?(String) ? i.upcase : i } elsif value.is_a?(Hash) result = {} - result << value.each_pair do |k, v| - return {k.upcase => v.collect! { |p| p.upcase }} + value.each_pair do |k, v| + result.merge!({k.upcase => v.collect! { |p| p.upcase }}) end else result = value.upcase -- cgit v1.2.3 From 85e81f9bdf9d482338c504ff3c658993a24978a0 Mon Sep 17 00:00:00 2001 From: Travis Fields Date: Fri, 27 Feb 2015 17:40:32 -0800 Subject: Loosen the restrictions of upcase and allow for recursion of the objects and only worry if the object responds to upcase --- README.markdown | 2 +- lib/puppet/parser/functions/upcase.rb | 10 +++++----- spec/functions/upcase_spec.rb | 19 +++++++++++++++++++ 3 files changed, 25 insertions(+), 6 deletions(-) diff --git a/README.markdown b/README.markdown index 3d2d1b9..0ea0c4e 100644 --- a/README.markdown +++ b/README.markdown @@ -475,7 +475,7 @@ Takes a single string value as an argument. *Type*: rvalue You can also use this with arrays. For example, `unique(["a","a","b","b","c","c"])` returns ["a","b","c"]. *Type*: rvalue -* `upcase`: Converts a string or an array of strings to uppercase. For example, `upcase("abcd")` returns 'ABCD'. *Type*: rvalue +* `upcase`: Converts an object, array or hash of objects that respond to upcase to uppercase. For example, `upcase("abcd")` returns 'ABCD'. *Type*: rvalue * `uriescape`: Urlencodes a string or array of strings. Requires either a single string or an array as an input. *Type*: rvalue diff --git a/lib/puppet/parser/functions/upcase.rb b/lib/puppet/parser/functions/upcase.rb index 2b05db4..0226a88 100644 --- a/lib/puppet/parser/functions/upcase.rb +++ b/lib/puppet/parser/functions/upcase.rb @@ -17,22 +17,22 @@ Will return: ) do |arguments| raise(Puppet::ParseError, "upcase(): Wrong number of arguments " + - "given (#{arguments.size} for 1)") if arguments.size < 1 + "given (#{arguments.size} for 1)") if arguments.size != 1 value = arguments[0] - unless value.is_a?(Array) || value.is_a?(String) || value.is_a?(Hash) + unless value.is_a?(Array) || value.is_a?(Hash) || value.respond_to?(:upcase) raise(Puppet::ParseError, 'upcase(): Requires an ' + - 'array, string or hash to work with') + 'array, hash or object that responds to upcase in order to work') end if value.is_a?(Array) # Numbers in Puppet are often string-encoded which is troublesome ... - result = value.collect { |i| i.is_a?(String) ? i.upcase : i } + result = value.collect { |i| function_upcase([i]) } elsif value.is_a?(Hash) result = {} value.each_pair do |k, v| - result.merge!({k.upcase => v.collect! { |p| p.upcase }}) + result[function_upcase([k])] = function_upcase([v]) end else result = value.upcase diff --git a/spec/functions/upcase_spec.rb b/spec/functions/upcase_spec.rb index a50a3ab..0689099 100755 --- a/spec/functions/upcase_spec.rb +++ b/spec/functions/upcase_spec.rb @@ -36,4 +36,23 @@ describe "the upcase function" do scope.function_upcase([{'test' => %w(this that and other thing)}]) ).to eq({'TEST' => %w(THIS THAT AND OTHER THING)}) end + + if :test.respond_to?(:upcase) + it 'should accept hashes of symbols' do + expect( + scope.function_upcase([{:test => [:this, :that, :other]}]) + ).to eq({:TEST => [:THIS, :THAT, :OTHER]}) + end + it 'should return upcase symbol' do + expect( + scope.function_upcase([:test]) + ).to eq(:TEST) + end + it 'should return mixed objects in upcease' do + expect( + scope.function_upcase([[:test, 'woot']]) + ).to eq([:TEST, 'WOOT']) + + end + end end -- cgit v1.2.3 From 41baef8502eabd34dc4fe49f43c6ef7c61f8e6c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bryon=20Roch=C3=A9?= Date: Fri, 8 Aug 2014 16:59:37 -0700 Subject: URI.escape for the array case was incorrect. The previous commit to uriescape() changed the implementation to use the ruby default escape list for URI.escape(), but did not change the call triggered when uriescape() was called on an array, triggering ruby errors. --- lib/puppet/parser/functions/uriescape.rb | 2 +- spec/functions/uriescape_spec.rb | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/lib/puppet/parser/functions/uriescape.rb b/lib/puppet/parser/functions/uriescape.rb index a486eee..45bbed2 100644 --- a/lib/puppet/parser/functions/uriescape.rb +++ b/lib/puppet/parser/functions/uriescape.rb @@ -22,7 +22,7 @@ module Puppet::Parser::Functions if value.is_a?(Array) # Numbers in Puppet are often string-encoded which is troublesome ... - result = value.collect { |i| i.is_a?(String) ? URI.escape(i,unsafe) : i } + result = value.collect { |i| i.is_a?(String) ? URI.escape(i) : i } else result = URI.escape(value) end diff --git a/spec/functions/uriescape_spec.rb b/spec/functions/uriescape_spec.rb index 2321e5a..d0f37de 100755 --- a/spec/functions/uriescape_spec.rb +++ b/spec/functions/uriescape_spec.rb @@ -17,6 +17,13 @@ describe "the uriescape function" do expect(result).to(eq(':/?%23[]@!$&\'()*+,;=%20%22%7B%7D')) end + it "should uriescape an array of strings, while not touching up nonstrings" do + teststring = ":/?#[]@!$&'()*+,;= \"{}" + expectstring = ':/?%23[]@!$&\'()*+,;=%20%22%7B%7D' + result = scope.function_uriescape([[teststring, teststring, 1]]) + expect(result).to(eq([expectstring, expectstring, 1])) + end + it "should do nothing if a string is already safe" do result = scope.function_uriescape(["ABCdef"]) expect(result).to(eq('ABCdef')) -- cgit v1.2.3 From 0236cd51bc2724b4ac68b91dda01d1b58b572df8 Mon Sep 17 00:00:00 2001 From: Stefan Goethals Date: Wed, 4 Jun 2014 06:12:22 -0700 Subject: Add support for hashes in the prefix function Signed-off-by: Julien Pivotto --- README.markdown | 3 +-- lib/puppet/parser/functions/prefix.rb | 23 +++++++++++++++-------- spec/functions/prefix_spec.rb | 5 +++++ 3 files changed, 21 insertions(+), 10 deletions(-) diff --git a/README.markdown b/README.markdown index ac0cae6..3a33d48 100644 --- a/README.markdown +++ b/README.markdown @@ -360,7 +360,7 @@ returns the value of the resource's parameter. For example, the following code r *Type*: rvalue -* `prefix`: This function applies a prefix to all elements in an array. For example, `prefix(['a','b','c'], 'p')` returns ['pa','pb','pc']. *Type*: rvalue +* `prefix`: This function applies a prefix to all elements in an array or to the keys in a hash. For example, `prefix(['a','b','c'], 'p')` returns ['pa','pb','pc'], and `prefix({'a'=>'b','b'=>'c','c'=>'d'}, 'p')` returns {'pa'=>'b','pb'=>'c','pc'=>'d'}. *Type*: rvalue * `private`: This function sets the current class or definition as private. @@ -453,7 +453,6 @@ manifests as a valid password attribute. *Type*: rvalue * `%Z`: Time zone name * `%%`: Literal '%' character - * `strip`: This function removes leading and trailing whitespace from a string or from every string inside an array. For example, `strip(" aaa ")` results in "aaa". *Type*: rvalue * `suffix`: This function applies a suffix to all elements in an array. For example, `suffix(['a','b','c'], 'p')` returns ['ap','bp','cp']. *Type*: rvalue diff --git a/lib/puppet/parser/functions/prefix.rb b/lib/puppet/parser/functions/prefix.rb index d02286a..ac1c58a 100644 --- a/lib/puppet/parser/functions/prefix.rb +++ b/lib/puppet/parser/functions/prefix.rb @@ -4,7 +4,7 @@ module Puppet::Parser::Functions newfunction(:prefix, :type => :rvalue, :doc => <<-EOS -This function applies a prefix to all elements in an array. +This function applies a prefix to all elements in an array or a hash. *Examples:* @@ -18,10 +18,10 @@ Will return: ['pa','pb','pc'] raise(Puppet::ParseError, "prefix(): Wrong number of arguments " + "given (#{arguments.size} for 1)") if arguments.size < 1 - array = arguments[0] + enumerable = arguments[0] - unless array.is_a?(Array) - raise Puppet::ParseError, "prefix(): expected first argument to be an Array, got #{array.inspect}" + unless enumerable.is_a?(Array) or enumerable.is_a?(Hash) + raise Puppet::ParseError, "prefix(): expected first argument to be an Array or a Hash, got #{enumerable.inspect}" end prefix = arguments[1] if arguments[1] @@ -32,10 +32,17 @@ Will return: ['pa','pb','pc'] end end - # Turn everything into string same as join would do ... - result = array.collect do |i| - i = i.to_s - prefix ? prefix + i : i + if enumerable.is_a?(Array) + # Turn everything into string same as join would do ... + result = enumerable.collect do |i| + i = i.to_s + prefix ? prefix + i : i + end + else + result = Hash[enumerable.map do |k,v| + k = k.to_s + [ prefix ? prefix + k : k, v ] + end] end return result diff --git a/spec/functions/prefix_spec.rb b/spec/functions/prefix_spec.rb index 34cac53..aec8a7d 100755 --- a/spec/functions/prefix_spec.rb +++ b/spec/functions/prefix_spec.rb @@ -25,4 +25,9 @@ describe "the prefix function" do result = scope.function_prefix([['a','b','c'], 'p']) expect(result).to(eq(['pa','pb','pc'])) end + + it "returns a prefixed hash" do + result = scope.function_prefix([{'a' => 'b','b' => 'c','c' => 'd'}, 'p']) + expect(result).to(eq({'pa'=>'b','pb'=>'c','pc'=>'d'})) + end end -- cgit v1.2.3 From 380cb02a65f51a520dc5ee000b605d3b7dbe9bd4 Mon Sep 17 00:00:00 2001 From: robruma Date: Wed, 11 Feb 2015 20:27:30 -0500 Subject: Adding markdown for the range() function's 3rd argument Adding markdown for the range() function's 3rd argument Adding markdown for the range() function's 3rd argument --- README.markdown | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.markdown b/README.markdown index ac0cae6..26a6b94 100644 --- a/README.markdown +++ b/README.markdown @@ -382,6 +382,8 @@ Calling the class or definition from outside the current module will fail. For e Non-integer strings are accepted; `range("a", "c")` returns ["a","b","c"], and `range("host01", "host10")` returns ["host01", "host02", ..., "host09", "host10"]. + Passing a third argument will cause the generated range to step by that interval, e.g. `range("0", "9", "2")` returns ["0","2","4","6","8"] + *Type*: rvalue * `reject`: This function searches through an array and rejects all elements that match the provided regular expression. For example, `reject(['aaa','bbb','ccc','aaaddd'], 'aaa')` returns ['bbb','ccc']. *Type*: rvalue -- cgit v1.2.3 From 56d815bcfc5f57d8dff974fd8bba192c6b141f89 Mon Sep 17 00:00:00 2001 From: Franz Pletz Date: Fri, 19 Dec 2014 12:25:21 +0100 Subject: Rename private() to assert_private() As mentioned in #270, private is a reserved keyword in the future parser which is to be released with Puppet 4. As it stands, this function is not useable with the future parser so it needs to renamed. This is a breaking change. --- README.markdown | 6 +-- lib/puppet/parser/functions/assert_private.rb | 29 ++++++++++++++ lib/puppet/parser/functions/private.rb | 29 -------------- spec/functions/assert_private_spec.rb | 55 +++++++++++++++++++++++++++ spec/functions/private_spec.rb | 55 --------------------------- 5 files changed, 87 insertions(+), 87 deletions(-) create mode 100644 lib/puppet/parser/functions/assert_private.rb delete mode 100644 lib/puppet/parser/functions/private.rb create mode 100755 spec/functions/assert_private_spec.rb delete mode 100755 spec/functions/private_spec.rb diff --git a/README.markdown b/README.markdown index 32d3b18..5adabf7 100644 --- a/README.markdown +++ b/README.markdown @@ -363,8 +363,8 @@ returns the value of the resource's parameter. For example, the following code r * `prefix`: This function applies a prefix to all elements in an array or to the keys in a hash. For example, `prefix(['a','b','c'], 'p')` returns ['pa','pb','pc'], and `prefix({'a'=>'b','b'=>'c','c'=>'d'}, 'p')` returns {'pa'=>'b','pb'=>'c','pc'=>'d'}. *Type*: rvalue -* `private`: This function sets the current class or definition as private. -Calling the class or definition from outside the current module will fail. For example, `private()` called in class `foo::bar` outputs the following message if class is called from outside module `foo`: +* `assert_private`: This function sets the current class or definition as private. +Calling the class or definition from outside the current module will fail. For example, `assert_private()` called in class `foo::bar` outputs the following message if class is called from outside module `foo`: ``` Class foo::bar is private @@ -373,7 +373,7 @@ Calling the class or definition from outside the current module will fail. For e You can specify the error message you want to use: ``` - private("You're not supposed to do that!") + assert_private("You're not supposed to do that!") ``` *Type*: statement diff --git a/lib/puppet/parser/functions/assert_private.rb b/lib/puppet/parser/functions/assert_private.rb new file mode 100644 index 0000000..66c79cc --- /dev/null +++ b/lib/puppet/parser/functions/assert_private.rb @@ -0,0 +1,29 @@ +# +# assert_private.rb +# + +module Puppet::Parser::Functions + newfunction(:assert_private, :doc => <<-'EOS' + Sets the current class or definition as private. + Calling the class or definition from outside the current module will fail. + EOS + ) do |args| + + raise(Puppet::ParseError, "assert_private(): Wrong number of arguments "+ + "given (#{args.size}}) for 0 or 1)") if args.size > 1 + + scope = self + if scope.lookupvar('module_name') != scope.lookupvar('caller_module_name') + message = nil + if args[0] and args[0].is_a? String + message = args[0] + else + manifest_name = scope.source.name + manifest_type = scope.source.type + message = (manifest_type.to_s == 'hostclass') ? 'Class' : 'Definition' + message += " #{manifest_name} is private" + end + raise(Puppet::ParseError, message) + end + end +end diff --git a/lib/puppet/parser/functions/private.rb b/lib/puppet/parser/functions/private.rb deleted file mode 100644 index 60210d3..0000000 --- a/lib/puppet/parser/functions/private.rb +++ /dev/null @@ -1,29 +0,0 @@ -# -# private.rb -# - -module Puppet::Parser::Functions - newfunction(:private, :doc => <<-'EOS' - Sets the current class or definition as private. - Calling the class or definition from outside the current module will fail. - EOS - ) do |args| - - raise(Puppet::ParseError, "private(): Wrong number of arguments "+ - "given (#{args.size}}) for 0 or 1)") if args.size > 1 - - scope = self - if scope.lookupvar('module_name') != scope.lookupvar('caller_module_name') - message = nil - if args[0] and args[0].is_a? String - message = args[0] - else - manifest_name = scope.source.name - manifest_type = scope.source.type - message = (manifest_type.to_s == 'hostclass') ? 'Class' : 'Definition' - message += " #{manifest_name} is private" - end - raise(Puppet::ParseError, message) - end - end -end diff --git a/spec/functions/assert_private_spec.rb b/spec/functions/assert_private_spec.rb new file mode 100755 index 0000000..a009d28 --- /dev/null +++ b/spec/functions/assert_private_spec.rb @@ -0,0 +1,55 @@ +#! /usr/bin/env ruby -S rspec +require 'spec_helper' + +describe Puppet::Parser::Functions.function(:assert_private) do + let(:scope) { PuppetlabsSpec::PuppetInternals.scope } + + subject do + function_name = Puppet::Parser::Functions.function(:assert_private) + scope.method(function_name) + end + + context "when called from inside module" do + it "should not fail" do + scope.expects(:lookupvar).with('module_name').returns('foo') + scope.expects(:lookupvar).with('caller_module_name').returns('foo') + expect { + subject.call [] + }.not_to raise_error + end + end + + context "with an explicit failure message" do + it "prints the failure message on error" do + scope.expects(:lookupvar).with('module_name').returns('foo') + scope.expects(:lookupvar).with('caller_module_name').returns('bar') + expect { + subject.call ['failure message!'] + }.to raise_error Puppet::ParseError, /failure message!/ + end + end + + context "when called from private class" do + it "should fail with a class error message" do + scope.expects(:lookupvar).with('module_name').returns('foo') + scope.expects(:lookupvar).with('caller_module_name').returns('bar') + scope.source.expects(:name).returns('foo::baz') + scope.source.expects(:type).returns('hostclass') + expect { + subject.call [] + }.to raise_error Puppet::ParseError, /Class foo::baz is private/ + end + end + + context "when called from private definition" do + it "should fail with a class error message" do + scope.expects(:lookupvar).with('module_name').returns('foo') + scope.expects(:lookupvar).with('caller_module_name').returns('bar') + scope.source.expects(:name).returns('foo::baz') + scope.source.expects(:type).returns('definition') + expect { + subject.call [] + }.to raise_error Puppet::ParseError, /Definition foo::baz is private/ + end + end +end diff --git a/spec/functions/private_spec.rb b/spec/functions/private_spec.rb deleted file mode 100755 index c70759f..0000000 --- a/spec/functions/private_spec.rb +++ /dev/null @@ -1,55 +0,0 @@ -#! /usr/bin/env ruby -S rspec -require 'spec_helper' - -describe Puppet::Parser::Functions.function(:private) do - let(:scope) { PuppetlabsSpec::PuppetInternals.scope } - - subject do - function_name = Puppet::Parser::Functions.function(:private) - scope.method(function_name) - end - - context "when called from inside module" do - it "should not fail" do - scope.expects(:lookupvar).with('module_name').returns('foo') - scope.expects(:lookupvar).with('caller_module_name').returns('foo') - expect { - subject.call [] - }.not_to raise_error - end - end - - context "with an explicit failure message" do - it "prints the failure message on error" do - scope.expects(:lookupvar).with('module_name').returns('foo') - scope.expects(:lookupvar).with('caller_module_name').returns('bar') - expect { - subject.call ['failure message!'] - }.to raise_error Puppet::ParseError, /failure message!/ - end - end - - context "when called from private class" do - it "should fail with a class error message" do - scope.expects(:lookupvar).with('module_name').returns('foo') - scope.expects(:lookupvar).with('caller_module_name').returns('bar') - scope.source.expects(:name).returns('foo::baz') - scope.source.expects(:type).returns('hostclass') - expect { - subject.call [] - }.to raise_error Puppet::ParseError, /Class foo::baz is private/ - end - end - - context "when called from private definition" do - it "should fail with a class error message" do - scope.expects(:lookupvar).with('module_name').returns('foo') - scope.expects(:lookupvar).with('caller_module_name').returns('bar') - scope.source.expects(:name).returns('foo::baz') - scope.source.expects(:type).returns('definition') - expect { - subject.call [] - }.to raise_error Puppet::ParseError, /Definition foo::baz is private/ - end - end -end -- cgit v1.2.3 From 4a68b224c4a4a986be6b4bf9580fc4f23251e3c6 Mon Sep 17 00:00:00 2001 From: Travis Fields Date: Thu, 5 Mar 2015 11:01:31 -0800 Subject: Add private function back and forward to assert_private with deprecation warning --- lib/puppet/parser/functions/private.rb | 17 ++++++++++ spec/functions/private_spec.rb | 60 ++++++++++++++++++++++++++++++++++ 2 files changed, 77 insertions(+) create mode 100644 lib/puppet/parser/functions/private.rb create mode 100644 spec/functions/private_spec.rb diff --git a/lib/puppet/parser/functions/private.rb b/lib/puppet/parser/functions/private.rb new file mode 100644 index 0000000..3b00ba1 --- /dev/null +++ b/lib/puppet/parser/functions/private.rb @@ -0,0 +1,17 @@ +# +# private.rb +# + +module Puppet::Parser::Functions + newfunction(:private, :doc => <<-'EOS' + DEPRECATED: Sets the current class or definition as private. + Calling the class or definition from outside the current module will fail. + EOS + ) do |args| + warning("private() DEPRECATED: This function will cease to function on Puppet 4; please use assert_private() before upgrading to puppet 4 for backwards-compatibility, or migrate to the new parser's typing system.") + if !Puppet::Parser::Functions.autoloader.loaded?(:assert_private) + Puppet::Parser::Functions.autoloader.load(:assert_private) + end + function_assert_private([(args[0] unless args.size < 1)]) + end +end diff --git a/spec/functions/private_spec.rb b/spec/functions/private_spec.rb new file mode 100644 index 0000000..c90282e --- /dev/null +++ b/spec/functions/private_spec.rb @@ -0,0 +1,60 @@ +#! /usr/bin/env ruby -S rspec +require 'spec_helper' + +describe Puppet::Parser::Functions.function(:private) do + let(:scope) { PuppetlabsSpec::PuppetInternals.scope } + + subject do + function_name = Puppet::Parser::Functions.function(:private) + scope.method(function_name) + end + + it 'should issue a warning' do + scope.expects(:warning).with("private() DEPRECATED: This function will cease to function on Puppet 4; please use assert_private() before upgrading to puppet 4 for backwards-compatibility, or migrate to the new parser's typing system.") + subject.call [] + end + + context "when called from inside module" do + it "should not fail" do + scope.expects(:lookupvar).with('module_name').returns('foo') + scope.expects(:lookupvar).with('caller_module_name').returns('foo') + expect { + subject.call [] + }.not_to raise_error + end + end + + context "with an explicit failure message" do + it "prints the failure message on error" do + scope.expects(:lookupvar).with('module_name').returns('foo') + scope.expects(:lookupvar).with('caller_module_name').returns('bar') + expect { + subject.call ['failure message!'] + }.to raise_error Puppet::ParseError, /failure message!/ + end + end + + context "when called from private class" do + it "should fail with a class error message" do + scope.expects(:lookupvar).with('module_name').returns('foo') + scope.expects(:lookupvar).with('caller_module_name').returns('bar') + scope.source.expects(:name).returns('foo::baz') + scope.source.expects(:type).returns('hostclass') + expect { + subject.call [] + }.to raise_error Puppet::ParseError, /Class foo::baz is private/ + end + end + + context "when called from private definition" do + it "should fail with a class error message" do + scope.expects(:lookupvar).with('module_name').returns('foo') + scope.expects(:lookupvar).with('caller_module_name').returns('bar') + scope.source.expects(:name).returns('foo::baz') + scope.source.expects(:type).returns('definition') + expect { + subject.call [] + }.to raise_error Puppet::ParseError, /Definition foo::baz is private/ + end + end +end -- cgit v1.2.3 From e319b85046829870057c9b378b69687314a85410 Mon Sep 17 00:00:00 2001 From: Travis Fields Date: Thu, 5 Mar 2015 14:12:57 -0800 Subject: Add ability to pin beaker versions --- Gemfile | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Gemfile b/Gemfile index fa2a31c..e1a59fa 100644 --- a/Gemfile +++ b/Gemfile @@ -20,7 +20,11 @@ group :development, :unit_tests do gem 'simplecov', :require => false end +beaker_version = ENV['BEAKER_VERSION'] group :system_tests do + if beaker_version + gem 'beaker', *location_for(beaker_version) + end gem 'beaker-rspec', :require => false gem 'serverspec', :require => false end -- cgit v1.2.3 From ee13438d2a71cea8a07202eee1eeaa29553b2131 Mon Sep 17 00:00:00 2001 From: Rod Montgomery Date: Thu, 15 Jan 2015 15:10:33 -0600 Subject: If present, top-level domain must be alphabetic See RFC 1123, Section 2.1 http://tools.ietf.org/html/rfc1123#section-2 --- lib/puppet/parser/functions/is_domain_name.rb | 4 ++++ spec/functions/is_domain_name_spec.rb | 10 ++++++++++ 2 files changed, 14 insertions(+) diff --git a/lib/puppet/parser/functions/is_domain_name.rb b/lib/puppet/parser/functions/is_domain_name.rb index 2860ded..90ede32 100644 --- a/lib/puppet/parser/functions/is_domain_name.rb +++ b/lib/puppet/parser/functions/is_domain_name.rb @@ -33,6 +33,10 @@ Returns true if the string passed to this function is a syntactically correct do return false if domain.empty? return false if domain.length > domain_max_length + # The top level domain must be alphabetic if there are multiple labels. + # See rfc1123, 2.1 + return false if domain.include? '.' and not /\.[A-Za-z]+$/.match(domain) + # Check each label in the domain labels = domain.split('.') vlabels = labels.each do |label| diff --git a/spec/functions/is_domain_name_spec.rb b/spec/functions/is_domain_name_spec.rb index 5ab8369..ef88061 100755 --- a/spec/functions/is_domain_name_spec.rb +++ b/spec/functions/is_domain_name_spec.rb @@ -68,4 +68,14 @@ describe "the is_domain_name function" do result = scope.function_is_domain_name(["my.domain.name".freeze]) expect(result).to(be_truthy) end + + it "should return false if top-level domain is not entirely alphabetic" do + result = scope.function_is_domain_name(["kiwi.2bar"]) + expect(result).to(be_falsey) + end + + it "should return false if domain name has the dotted-decimal form, e.g. an IPv4 address" do + result = scope.function_is_domain_name(["192.168.1.1"]) + expect(result).to(be_falsey) + end end -- cgit v1.2.3 From 3fec51ac65725ee10710030953a6d6b206de931d Mon Sep 17 00:00:00 2001 From: Mark Jeffcoat Date: Tue, 10 Mar 2015 17:43:51 -0500 Subject: Fix off-by-one error in validate_augeas_spec.rb that was causing rspec failure. --- spec/functions/validate_augeas_spec.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/functions/validate_augeas_spec.rb b/spec/functions/validate_augeas_spec.rb index c695ba2..99523ab 100755 --- a/spec/functions/validate_augeas_spec.rb +++ b/spec/functions/validate_augeas_spec.rb @@ -60,7 +60,7 @@ describe Puppet::Parser::Functions.function(:validate_augeas), :if => Puppet.fea end describe "Nicer Error Messages" do - # The intent here is to make sure the function returns the 3rd argument + # The intent here is to make sure the function returns the 4th argument # in the exception thrown inputs = [ [ "root:x:0:0:root\n", 'Passwd.lns', [], 'Failed to validate passwd content' ], @@ -69,7 +69,7 @@ describe Puppet::Parser::Functions.function(:validate_augeas), :if => Puppet.fea inputs.each do |input| it "validate_augeas(#{input.inspect}) should fail" do - expect { subject.call input }.to raise_error /#{input[2]}/ + expect { subject.call input }.to raise_error /#{input[3]}/ end end end -- cgit v1.2.3 From 2381f7cff480019013da87baf962ce6e665779f4 Mon Sep 17 00:00:00 2001 From: Alice Nodelman Date: Tue, 24 Mar 2015 15:07:42 -0700 Subject: (BKR-147) add Gemfile setting for BEAKER_VERSION for puppet... puppetdb, etc - support for BEAKER_VERSION and BEAKER_RSPEC_VERSION in gemfile --- Gemfile | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/Gemfile b/Gemfile index e1a59fa..2d19594 100644 --- a/Gemfile +++ b/Gemfile @@ -21,12 +21,17 @@ group :development, :unit_tests do 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) + gem 'beaker', *location_for(beaker_version) end - gem 'beaker-rspec', :require => false - gem 'serverspec', :require => false + if beaker_rspec_version + gem 'beaker-rspec', *location_for(beaker_rspec_version) + else + gem 'beaker-rspec', :require => false + end + gem 'serverspec', :require => false end facterversion = ENV['GEM_FACTER_VERSION'] || ENV['FACTER_GEM_VERSION'] -- cgit v1.2.3 From c297bd80e38c73618c0c706783386fef63bf0682 Mon Sep 17 00:00:00 2001 From: Spencer Krum Date: Sat, 28 Mar 2015 20:27:06 -0700 Subject: Make each function a link in the readme Using a ####, github will create a link. This makes it so I can link someone directly to the function I want to show them. --- README.markdown | 388 ++++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 291 insertions(+), 97 deletions(-) diff --git a/README.markdown b/README.markdown index 9c6a54b..293a81a 100644 --- a/README.markdown +++ b/README.markdown @@ -99,44 +99,68 @@ If you want to use a standardized set of run stages for Puppet, `include stdlib` ### Functions -* `abs`: Returns the absolute value of a number; for example, '-34.56' becomes '34.56'. Takes a single integer and float value as an argument. *Type*: rvalue +#### `abs` -* `any2array`: This converts any object to an array containing that object. Empty argument lists are converted to an empty array. Arrays are left untouched. Hashes are converted to arrays of alternating keys and values. *Type*: rvalue +Returns the absolute value of a number; for example, '-34.56' becomes '34.56'. Takes a single integer and float value as an argument. *Type*: rvalue -* `base64`: Converts a string to and from base64 encoding. +#### `any2array` + +This converts any object to an array containing that object. Empty argument lists are converted to an empty array. Arrays are left untouched. Hashes are converted to arrays of alternating keys and values. *Type*: rvalue + +#### `base64` + +Converts a string to and from base64 encoding. Requires an action ('encode', 'decode') and either a plain or base64-encoded string. *Type*: rvalue -* `basename`: Returns the `basename` of a path (optionally stripping an extension). For example: +#### `basename` + +Returns the `basename` of a path (optionally stripping an extension). For example: * ('/path/to/a/file.ext') returns 'file.ext' * ('relative/path/file.ext') returns 'file.ext' * ('/path/to/a/file.ext', '.ext') returns 'file' *Type*: rvalue -* `bool2num`: Converts a boolean to a number. Converts values: +#### `bool2num` + +Converts a boolean to a number. Converts values: * 'false', 'f', '0', 'n', and 'no' to 0. * 'true', 't', '1', 'y', and 'yes' to 1. Requires a single boolean or string as an input. *Type*: rvalue -* `capitalize`: Capitalizes the first letter of a string or array of strings. +#### `capitalize` + +Capitalizes the first letter of a string or array of strings. Requires either a single string or an array as an input. *Type*: rvalue -* `ceiling`: Returns the smallest integer greater than or equal to the argument. +#### `ceiling` + +Returns the smallest integer greater than or equal to the argument. Takes a single numeric value as an argument. *Type*: rvalue -* `chomp`: Removes the record separator from the end of a string or an array of +#### `chomp` + +Removes the record separator from the end of a string or an array of strings; for example, 'hello\n' becomes 'hello'. Requires a single string or array as an input. *Type*: rvalue -* `chop`: Returns a new string with the last character removed. If the string ends with '\r\n', both characters are removed. Applying `chop` to an empty string returns an empty string. If you want to merely remove record separators, then you should use the `chomp` function. Requires a string or an array of strings as input. *Type*: rvalue +#### `chop` + +Returns a new string with the last character removed. If the string ends with '\r\n', both characters are removed. Applying `chop` to an empty string returns an empty string. If you want to merely remove record separators, then you should use the `chomp` function. Requires a string or an array of strings as input. *Type*: rvalue + +#### `concat` -* `concat`: Appends the contents of multiple arrays onto array 1. For example: +Appends the contents of multiple arrays onto array 1. For example: * `concat(['1','2','3'],'4')` results in: ['1','2','3','4']. * `concat(['1','2','3'],'4',['5','6','7'])` results in: ['1','2','3','4','5','6','7']. -* `count`: Takes an array as first argument and an optional second argument. Count the number of elements in array that matches second argument. If called with only an array, it counts the number of elements that are **not** nil/undef. *Type*: rvalue +#### `count` -* `defined_with_params`: Takes a resource reference and an optional hash of attributes. Returns 'true' if a resource with the specified attributes has already been added to the catalog. Returns 'false' otherwise. +Takes an array as first argument and an optional second argument. Count the number of elements in array that matches second argument. If called with only an array, it counts the number of elements that are **not** nil/undef. *Type*: rvalue + +#### `defined_with_params` + +Takes a resource reference and an optional hash of attributes. Returns 'true' if a resource with the specified attributes has already been added to the catalog. Returns 'false' otherwise. ``` user { 'dan': @@ -150,28 +174,48 @@ strings; for example, 'hello\n' becomes 'hello'. Requires a single string or arr *Type*: rvalue -* `delete`: Deletes all instances of a given element from an array, substring from a +#### `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 -* `delete_at`: Deletes a determined indexed value from an array. For example, `delete_at(['a','b','c'], 1)` returns ['a','c']. *Type*: rvalue +#### `delete_at` -* `delete_values`: Deletes all instances of a given value from a hash. For example, `delete_values({'a'=>'A','b'=>'B','c'=>'C','B'=>'D'}, 'B')` returns {'a'=>'A','c'=>'C','B'=>'D'} *Type*: rvalue +Deletes a determined indexed value from an array. For example, `delete_at(['a','b','c'], 1)` returns ['a','c']. *Type*: rvalue -* `delete_undef_values`: Deletes all instances of the undef value from an array or hash. For example, `$hash = delete_undef_values({a=>'A', b=>'', c=>undef, d => false})` returns {a => 'A', b => '', d => false}. *Type*: rvalue +#### `delete_values` -* `difference`: Returns the difference between two arrays. +Deletes all instances of a given value from a hash. For example, `delete_values({'a'=>'A','b'=>'B','c'=>'C','B'=>'D'}, 'B')` returns {'a'=>'A','c'=>'C','B'=>'D'} *Type*: rvalue + +#### `delete_undef_values` + +Deletes all instances of the undef value from an array or hash. For example, `$hash = delete_undef_values({a=>'A', b=>'', c=>undef, d => false})` returns {a => 'A', b => '', d => false}. *Type*: rvalue + +#### `difference` + +Returns the difference between two arrays. The returned array is a copy of the original array, removing any items that also appear in the second array. For example, `difference(["a","b","c"],["b","c","d"])` returns ["a"]. -* `dirname`: Returns the `dirname` of a path. For example, `dirname('/path/to/a/file.ext')` returns '/path/to/a'. +#### `dirname` + +Returns the `dirname` of a path. For example, `dirname('/path/to/a/file.ext')` returns '/path/to/a'. + +#### `downcase` -* `downcase`: Converts the case of a string or of all strings in an array to lowercase. *Type*: rvalue +Converts the case of a string or of all strings in an array to lowercase. *Type*: rvalue -* `empty`: Returns 'true' if the variable is empty. *Type*: rvalue +#### `empty` -* `ensure_packages`: Takes a list of packages and only installs them if they don't already exist. It optionally takes a hash as a second parameter to be passed as the third argument to the `ensure_resource()` function. *Type*: statement +Returns 'true' if the variable is empty. *Type*: rvalue -* `ensure_resource`: Takes a resource type, title, and a list of attributes that describe a resource. +#### `ensure_packages` + +Takes a list of packages and only installs them if they don't already exist. It optionally takes a hash as a second parameter to be passed as the third argument to the `ensure_resource()` function. *Type*: statement + +#### `ensure_resource` + +Takes a resource type, title, and a list of attributes that describe a resource. ``` user { 'dan': @@ -191,20 +235,30 @@ also appear in the second array. For example, `difference(["a","b","c"],["b","c" *Type*: statement -* `flatten`: This function flattens any deeply nested arrays and returns a single flat array as a result. For example, `flatten(['a', ['b', ['c']]])` returns ['a','b','c']. *Type*: rvalue +#### `flatten` -* `floor`: Returns the largest integer less than or equal to the argument. +This function flattens any deeply nested arrays and returns a single flat array as a result. For example, `flatten(['a', ['b', ['c']]])` returns ['a','b','c']. *Type*: rvalue + +#### `floor` + +Returns the largest integer less than or equal to the argument. Takes a single numeric value as an argument. *Type*: rvalue -* `fqdn_rotate`: Rotates an array a random number of times based on a node's fqdn. *Type*: rvalue +#### `fqdn_rotate` + +Rotates an array a random number of times based on a node's fqdn. *Type*: rvalue -* `get_module_path`: Returns the absolute path of the specified module for the current environment. +#### `get_module_path` + +Returns the absolute path of the specified module for the current environment. `$module_path = get_module_path('stdlib')` *Type*: rvalue -* `getparam`: Takes a resource reference and the name of the parameter and +#### `getparam` + +Takes a resource reference and the name of the parameter and returns the value of the resource's parameter. For example, the following code returns 'param_value'. *Example:* @@ -222,7 +276,9 @@ returns the value of the resource's parameter. For example, the following code r *Type*: rvalue -* `getvar`: Lookup a variable in a remote namespace. +#### `getvar` + +Lookup a variable in a remote namespace. For example: @@ -241,9 +297,13 @@ returns the value of the resource's parameter. For example, the following code r *Type*: rvalue -* `grep`: This function searches through an array and returns any elements that match the provided regular expression. For example, `grep(['aaa','bbb','ccc','aaaddd'], 'aaa')` returns ['aaa','aaaddd']. *Type*: rvalue +#### `grep` -* `has_interface_with`: Returns boolean based on kind and value: +This function searches through an array and returns any elements that match the provided regular expression. For example, `grep(['aaa','bbb','ccc','aaaddd'], 'aaa')` returns ['aaa','aaaddd']. *Type*: rvalue + +#### `has_interface_with` + +Returns boolean based on kind and value: * macaddress * netmask * ipaddress @@ -264,11 +324,17 @@ returns the value of the resource's parameter. For example, the following code r *Type*: rvalue -* `has_ip_address`: Returns true if the client has the requested IP address on some interface. This function iterates through the `interfaces` fact and checks the `ipaddress_IFACE` facts, performing a simple string comparison. *Type*: rvalue +#### `has_ip_address` + +Returns true if the client has the requested IP address on some interface. This function iterates through the `interfaces` fact and checks the `ipaddress_IFACE` facts, performing a simple string comparison. *Type*: rvalue -* `has_ip_network`: Returns true if the client has an IP address within the requested network. This function iterates through the 'interfaces' fact and checks the 'network_IFACE' facts, performing a simple string comparision. *Type*: rvalue +#### `has_ip_network` -* `has_key`: Determine if a hash has a certain key value. +Returns true if the client has an IP address within the requested network. This function iterates through the 'interfaces' fact and checks the 'network_IFACE' facts, performing a simple string comparision. *Type*: rvalue + +#### `has_key` + +Determine if a hash has a certain key value. *Example*: @@ -284,39 +350,73 @@ returns the value of the resource's parameter. For example, the following code r *Type*: rvalue -* `hash`: This function converts an array into a hash. For example, `hash(['a',1,'b',2,'c',3])` returns {'a'=>1,'b'=>2,'c'=>3}. *Type*: rvalue +#### `hash` + +This function converts an array into a hash. For example, `hash(['a',1,'b',2,'c',3])` returns {'a'=>1,'b'=>2,'c'=>3}. *Type*: rvalue + +#### `intersection` + +This function returns an array an intersection of two. For example, `intersection(["a","b","c"],["b","c","d"])` returns ["b","c"]. + +#### `is_array` + +Returns 'true' if the variable passed to this function is an array. *Type*: rvalue + +#### `is_bool` + +Returns 'true' if the variable passed to this function is a boolean. *Type*: rvalue + +#### `is_domain_name` + +Returns 'true' if the string passed to this function is a syntactically correct domain name. *Type*: rvalue + +#### `is_float` + +Returns 'true' if the variable passed to this function is a float. *Type*: rvalue + +#### `is_function_available` + +This function accepts a string as an argument and determines whether the Puppet runtime has access to a function by that name. It returns 'true' if the function exists, 'false' if not. *Type*: rvalue + +#### `is_hash` + +Returns 'true' if the variable passed to this function is a hash. *Type*: rvalue + +#### `is_integer` -* `intersection`: This function returns an array an intersection of two. For example, `intersection(["a","b","c"],["b","c","d"])` returns ["b","c"]. +Returns 'true' if the variable returned to this string is an integer. *Type*: rvalue -* `is_array`: Returns 'true' if the variable passed to this function is an array. *Type*: rvalue +#### `is_ip_address` -* `is_bool`: Returns 'true' if the variable passed to this function is a boolean. *Type*: rvalue +Returns 'true' if the string passed to this function is a valid IP address. *Type*: rvalue -* `is_domain_name`: Returns 'true' if the string passed to this function is a syntactically correct domain name. *Type*: rvalue +#### `is_mac_address` -* `is_float`: Returns 'true' if the variable passed to this function is a float. *Type*: rvalue +Returns 'true' if the string passed to this function is a valid MAC address. *Type*: rvalue -* `is_function_available`: This function accepts a string as an argument and determines whether the Puppet runtime has access to a function by that name. It returns 'true' if the function exists, 'false' if not. *Type*: rvalue +#### `is_numeric` -* `is_hash`: Returns 'true' if the variable passed to this function is a hash. *Type*: rvalue +Returns 'true' if the variable passed to this function is a number. *Type*: rvalue -* `is_integer`: Returns 'true' if the variable returned to this string is an integer. *Type*: rvalue +#### `is_string` -* `is_ip_address`: Returns 'true' if the string passed to this function is a valid IP address. *Type*: rvalue +Returns 'true' if the variable passed to this function is a string. *Type*: rvalue -* `is_mac_address`: Returns 'true' if the string passed to this function is a valid MAC address. *Type*: rvalue +#### `join` -* `is_numeric`: Returns 'true' if the variable passed to this function is a number. *Type*: rvalue +This function joins an array into a string using a separator. For example, `join(['a','b','c'], ",")` results in: "a,b,c". *Type*: rvalue -* `is_string`: Returns 'true' if the variable passed to this function is a string. *Type*: rvalue +#### `join_keys_to_values` -* `join`: This function joins an array into a string using a separator. For example, `join(['a','b','c'], ",")` results in: "a,b,c". *Type*: rvalue +This function joins each key of a hash to that key's corresponding value with a separator. Keys and values are cast to strings. The return value is an array in which each element is one joined key/value pair. For example, `join_keys_to_values({'a'=>1,'b'=>2}, " is ")` results in ["a is 1","b is 2"]. *Type*: rvalue -* `join_keys_to_values`: This function joins each key of a hash to that key's corresponding value with a separator. Keys and values are cast to strings. The return value is an array in which each element is one joined key/value pair. For example, `join_keys_to_values({'a'=>1,'b'=>2}, " is ")` results in ["a is 1","b is 2"]. *Type*: rvalue +#### `keys` -* `keys`: Returns the keys of a hash as an array. *Type*: rvalue +Returns the keys of a hash as an array. *Type*: rvalue -* `loadyaml`: Load a YAML file containing an array, string, or hash, and return the data in the corresponding native data type. For example: +#### `loadyaml` + +Load a YAML file containing an array, string, or hash, and return the data in the corresponding native data type. For example: ``` $myhash = loadyaml('/etc/puppet/data/myhash.yaml') @@ -324,13 +424,21 @@ returns the value of the resource's parameter. For example, the following code r *Type*: rvalue -* `lstrip`: Strips leading spaces to the left of a string. *Type*: rvalue +#### `lstrip` + +Strips leading spaces to the left of a string. *Type*: rvalue + +#### `max` -* `max`: Returns the highest value of all arguments. Requires at least one argument. *Type*: rvalue +Returns the highest value of all arguments. Requires at least one argument. *Type*: rvalue -* `member`: This function determines if a variable is a member of an array. The variable can be either a string, array, or fixnum. For example, `member(['a','b'], 'b')` and `member(['a','b','c'], ['b','c'])` return 'true', while `member(['a','b'], 'c')` and `member(['a','b','c'], ['c','d'])` return 'false'. *Type*: rvalue +#### `member` -* `merge`: Merges two or more hashes together and returns the resulting hash. +This function determines if a variable is a member of an array. The variable can be either a string, array, or fixnum. For example, `member(['a','b'], 'b')` and `member(['a','b','c'], ['b','c'])` return 'true', while `member(['a','b'], 'c')` and `member(['a','b','c'], ['c','d'])` return 'false'. *Type*: rvalue + +#### `merge` + +Merges two or more hashes together and returns the resulting hash. *Example*: @@ -344,15 +452,25 @@ returns the value of the resource's parameter. For example, the following code r When there is a duplicate key, the key in the rightmost hash "wins." *Type*: rvalue -* `min`: Returns the lowest value of all arguments. Requires at least one argument. *Type*: rvalue +#### `min` + +Returns the lowest value of all arguments. Requires at least one argument. *Type*: rvalue -* `num2bool`: This function converts a number or a string representation of a number into a true boolean. Zero or anything non-numeric becomes 'false'. Numbers greater than 0 become 'true'. *Type*: rvalue +#### `num2bool` -* `parsejson`: This function accepts JSON as a string and converts into the correct Puppet structure. *Type*: rvalue +This function converts a number or a string representation of a number into a true boolean. Zero or anything non-numeric becomes 'false'. Numbers greater than 0 become 'true'. *Type*: rvalue -* `parseyaml`: This function accepts YAML as a string and converts it into the correct Puppet structure. *Type*: rvalue +#### `parsejson` -* `pick`: From a list of values, returns the first value that is not undefined or an empty string. Takes any number of arguments, and raises an error if all values are undefined or empty. +This function accepts JSON as a string and converts into the correct Puppet structure. *Type*: rvalue + +#### `parseyaml` + +This function accepts YAML as a string and converts it into the correct Puppet structure. *Type*: rvalue + +#### `pick` + +From a list of values, returns the first value that is not undefined or an empty string. Takes any number of arguments, and raises an error if all values are undefined or empty. ``` $real_jenkins_version = pick($::jenkins_version, '1.449') @@ -360,10 +478,14 @@ returns the value of the resource's parameter. For example, the following code r *Type*: rvalue -* `prefix`: This function applies a prefix to all elements in an array or to the keys in a hash. For example, `prefix(['a','b','c'], 'p')` returns ['pa','pb','pc'], and `prefix({'a'=>'b','b'=>'c','c'=>'d'}, 'p')` returns {'pa'=>'b','pb'=>'c','pc'=>'d'}. *Type*: rvalue +#### `prefix` + +This function applies a prefix to all elements in an array or to the keys in a hash. For example, `prefix(['a','b','c'], 'p')` returns ['pa','pb','pc'], and `prefix({'a'=>'b','b'=>'c','c'=>'d'}, 'p')` returns {'pa'=>'b','pb'=>'c','pc'=>'d'}. *Type*: rvalue + +#### `assert_private` -* `assert_private`: This function sets the current class or definition as private. +This function sets the current class or definition as private. Calling the class or definition from outside the current module will fail. For example, `assert_private()` called in class `foo::bar` outputs the following message if class is called from outside module `foo`: ``` @@ -378,7 +500,9 @@ Calling the class or definition from outside the current module will fail. For e *Type*: statement -* `range`: When given range in the form of '(start, stop)', `range` extrapolates a range as an array. For example, `range("0", "9")` returns [0,1,2,3,4,5,6,7,8,9]. Zero-padded strings are converted to integers automatically, so `range("00", "09")` returns [0,1,2,3,4,5,6,7,8,9]. +#### `range` + +When given range in the form of '(start, stop)', `range` extrapolates a range as an array. For example, `range("0", "9")` returns [0,1,2,3,4,5,6,7,8,9]. Zero-padded strings are converted to integers automatically, so `range("00", "09")` returns [0,1,2,3,4,5,6,7,8,9]. Non-integer strings are accepted; `range("a", "c")` returns ["a","b","c"], and `range("host01", "host10")` returns ["host01", "host02", ..., "host09", "host10"]. @@ -386,26 +510,46 @@ Calling the class or definition from outside the current module will fail. For e *Type*: rvalue -* `reject`: This function searches through an array and rejects all elements that match the provided regular expression. For example, `reject(['aaa','bbb','ccc','aaaddd'], 'aaa')` returns ['bbb','ccc']. *Type*: rvalue +#### `reject` + +This function searches through an array and rejects all elements that match the provided regular expression. For example, `reject(['aaa','bbb','ccc','aaaddd'], 'aaa')` returns ['bbb','ccc']. *Type*: rvalue + +#### `reverse` + +Reverses the order of a string or array. *Type*: rvalue + +#### `rstrip` + +Strips leading spaces to the right of the string.*Type*: rvalue -* `reverse`: Reverses the order of a string or array. *Type*: rvalue +#### `shuffle` -* `rstrip`: Strips leading spaces to the right of the string.*Type*: rvalue +Randomizes the order of a string or array elements. *Type*: rvalue -* `shuffle`: Randomizes the order of a string or array elements. *Type*: rvalue +#### `size` -* `size`: Returns the number of elements in a string or array. *Type*: rvalue +Returns the number of elements in a string or array. *Type*: rvalue -* `sort`: Sorts strings and arrays lexically. *Type*: rvalue +#### `sort` -* `squeeze`: Returns a new string where runs of the same character that occur in this set are replaced by a single character. *Type*: rvalue +Sorts strings and arrays lexically. *Type*: rvalue -* `str2bool`: This converts a string to a boolean. This attempts to convert strings that contain values such as '1', 't', 'y', and 'yes' to 'true' and strings that contain values such as '0', 'f', 'n', and 'no' to 'false'. *Type*: rvalue +#### `squeeze` -* `str2saltedsha512`: This converts a string to a salted-SHA512 password hash, used for OS X versions >= 10.7. Given any string, this function returns a hex version of a salted-SHA512 password hash, which can be inserted into your Puppet +Returns a new string where runs of the same character that occur in this set are replaced by a single character. *Type*: rvalue + +#### `str2bool` + +This converts a string to a boolean. This attempts to convert strings that contain values such as '1', 't', 'y', and 'yes' to 'true' and strings that contain values such as '0', 'f', 'n', and 'no' to 'false'. *Type*: rvalue + +#### `str2saltedsha512` + +This converts a string to a salted-SHA512 password hash, used for OS X versions >= 10.7. Given any string, this function returns a hex version of a salted-SHA512 password hash, which can be inserted into your Puppet manifests as a valid password attribute. *Type*: rvalue -* `strftime`: This function returns formatted time. For example, `strftime("%s")` returns the time since epoch, and `strftime("%Y=%m-%d")` returns the date. *Type*: rvalue +#### `strftime` + +This function returns formatted time. For example, `strftime("%s")` returns the time since epoch, and `strftime("%Y=%m-%d")` returns the date. *Type*: rvalue *Format:* @@ -455,35 +599,59 @@ manifests as a valid password attribute. *Type*: rvalue * `%Z`: Time zone name * `%%`: Literal '%' character -* `strip`: This function removes leading and trailing whitespace from a string or from every string inside an array. For example, `strip(" aaa ")` results in "aaa". *Type*: rvalue +#### `strip` + +This function removes leading and trailing whitespace from a string or from every string inside an array. For example, `strip(" aaa ")` results in "aaa". *Type*: rvalue -* `suffix`: This function applies a suffix to all elements in an array. For example, `suffix(['a','b','c'], 'p')` returns ['ap','bp','cp']. *Type*: rvalue +#### `suffix` -* `swapcase`: This function swaps the existing case of a string. For example, `swapcase("aBcD")` results in "AbCd". *Type*: rvalue +This function applies a suffix to all elements in an array. For example, `suffix(['a','b','c'], 'p')` returns ['ap','bp','cp']. *Type*: rvalue -* `time`: This function returns the current time since epoch as an integer. For example, `time()` returns something like '1311972653'. *Type*: rvalue +#### `swapcase` -* `to_bytes`: Converts the argument into bytes, for example 4 kB becomes 4096. +This function swaps the existing case of a string. For example, `swapcase("aBcD")` results in "AbCd". *Type*: rvalue + +#### `time` + +This function returns the current time since epoch as an integer. For example, `time()` returns something like '1311972653'. *Type*: rvalue + +#### `to_bytes` + +Converts the argument into bytes, for example 4 kB becomes 4096. Takes a single string value as an argument. *Type*: rvalue -* `type3x`: Returns a string description of the type when passed a value. Type can be a string, array, hash, float, integer, or boolean. This function will be removed when puppet 3 support is dropped and the new type system may be used. *Type*: rvalue +#### `type3x` + +Returns a string description of the type when passed a value. Type can be a string, array, hash, float, integer, or boolean. This function will be removed when puppet 3 support is dropped and the new type system may be used. *Type*: rvalue + +#### `type_of` -* `type_of`: Returns the literal type when passed a value. Requires the new +Returns the literal type when passed a value. Requires the new parser. Useful for comparison of types with `<=` such as in `if type_of($some_value) <= Array[String] { ... }` (which is equivalent to `if $some_value =~ Array[String] { ... }`) *Type*: rvalue -* `union`: This function returns a union of two arrays. For example, `union(["a","b","c"],["b","c","d"])` returns ["a","b","c","d"]. +#### `union` -* `unique`: This function removes duplicates from strings and arrays. For example, `unique("aabbcc")` returns 'abc'. +This function returns a union of two arrays. For example, `union(["a","b","c"],["b","c","d"])` returns ["a","b","c","d"]. + +#### `unique` + +This function removes duplicates from strings and arrays. For example, `unique("aabbcc")` returns 'abc'. You can also use this with arrays. For example, `unique(["a","a","b","b","c","c"])` returns ["a","b","c"]. *Type*: rvalue -* `upcase`: Converts an object, array or hash of objects that respond to upcase to uppercase. For example, `upcase("abcd")` returns 'ABCD'. *Type*: rvalue +#### `upcase` + +Converts an object, array or hash of objects that respond to upcase to uppercase. For example, `upcase("abcd")` returns 'ABCD'. *Type*: rvalue -* `uriescape`: Urlencodes a string or array of strings. Requires either a single string or an array as an input. *Type*: rvalue +#### `uriescape` -* `validate_absolute_path`: Validate the string represents an absolute path in the filesystem. This function works for Windows and Unix style paths. +Urlencodes a string or array of strings. Requires either a single string or an array as an input. *Type*: rvalue + +#### `validate_absolute_path` + +Validate the string represents an absolute path in the filesystem. This function works for Windows and Unix style paths. The following values will pass: @@ -512,7 +680,9 @@ You can also use this with arrays. For example, `unique(["a","a","b","b","c","c" *Type*: statement -* `validate_array`: Validate that all passed values are array data structures. Abort catalog compilation if any value fails this check. +#### `validate_array` + +Validate that all passed values are array data structures. Abort catalog compilation if any value fails this check. The following values will pass: @@ -532,7 +702,9 @@ You can also use this with arrays. For example, `unique(["a","a","b","b","c","c" *Type*: statement -* `validate_augeas`: Performs validation of a string using an Augeas lens. +#### `validate_augeas` + +Performs validation of a string using an Augeas lens. The first argument of this function should be the string to test, and the second argument should be the name of the Augeas lens to use. If Augeas fails to parse the string with the lens, the compilation aborts with a parse error. A third optional argument lists paths which should **not** be found in the file. The `$file` variable points to the location of the temporary file being tested in the Augeas tree. @@ -557,7 +729,9 @@ The first argument of this function should be the string to test, and the second *Type*: statement -* `validate_bool`: Validate that all passed values are either true or false. Abort catalog compilation if any value fails this check. +#### `validate_bool` + +Validate that all passed values are either true or false. Abort catalog compilation if any value fails this check. The following values will pass: @@ -578,7 +752,9 @@ The first argument of this function should be the string to test, and the second *Type*: statement -* `validate_cmd`: Performs validation of a string with an external command. The first argument of this function should be a string to test, and the second argument should be a path to a test command taking a % as a placeholder for the file path (will default to the end of the command if no % placeholder given). If the command, launched against a tempfile containing the passed string, returns a non-null value, compilation will abort with a parse error. +#### `validate_cmd` + +Performs validation of a string with an external command. The first argument of this function should be a string to test, and the second argument should be a path to a test command taking a % as a placeholder for the file path (will default to the end of the command if no % placeholder given). If the command, launched against a tempfile containing the passed string, returns a non-null value, compilation will abort with a parse error. If a third argument is specified, this will be the error message raised and seen by the user. @@ -593,7 +769,9 @@ If a third argument is specified, this will be the error message raised and seen *Type*: statement -* `validate_hash`: Validates that all passed values are hash data structures. Abort catalog compilation if any value fails this check. +#### `validate_hash` + +Validates that all passed values are hash data structures. Abort catalog compilation if any value fails this check. The following values will pass: @@ -613,7 +791,9 @@ If a third argument is specified, this will be the error message raised and seen *Type*: statement -* `validate_integer`: Validate that the first argument is an integer (or an array of integers). Abort catalog compilation if any of the checks fail. +#### `validate_integer` + +Validate that the first argument is an integer (or an array of integers). Abort catalog compilation if any of the checks fail. The second argument is optional and passes a maximum. (All elements of) the first argument has to be less or equal to this max. @@ -669,7 +849,9 @@ If a third argument is specified, this will be the error message raised and seen *Type*: statement -* `validate_numeric`: Validate that the first argument is a numeric value (or an array of numeric values). Abort catalog compilation if any of the checks fail. +#### `validate_numeric` + +Validate that the first argument is a numeric value (or an array of numeric values). Abort catalog compilation if any of the checks fail. The second argument is optional and passes a maximum. (All elements of) the first argument has to be less or equal to this max. @@ -683,7 +865,9 @@ If a third argument is specified, this will be the error message raised and seen *Type*: statement -* `validate_re`: Performs simple validation of a string against one or more regular expressions. The first argument of this function should be the string to +#### `validate_re` + +Performs simple validation of a string against one or more regular expressions. The first argument of this function should be the string to test, and the second argument should be a stringified regular expression (without the // delimiters) or an array of regular expressions. If none of the regular expressions match the string passed in, compilation aborts with a parse error. @@ -711,7 +895,9 @@ of the regular expressions match the string passed in, compilation aborts with a *Type*: statement -* `validate_slength`: Validates that the first argument is a string (or an array of strings), and is less than or equal to the length of the second argument. It fails if the first argument is not a string or array of strings, or if arg 2 is not convertable to a number. +#### `validate_slength` + +Validates that the first argument is a string (or an array of strings), and is less than or equal to the length of the second argument. It fails if the first argument is not a string or array of strings, or if arg 2 is not convertable to a number. The following values pass: @@ -729,7 +915,9 @@ of the regular expressions match the string passed in, compilation aborts with a *Type*: statement -* `validate_string`: Validates that all passed values are string data structures. Aborts catalog compilation if any value fails this check. +#### `validate_string` + +Validates that all passed values are string data structures. Aborts catalog compilation if any value fails this check. The following values pass: @@ -749,7 +937,9 @@ of the regular expressions match the string passed in, compilation aborts with a *Type*: statement -* `values`: When given a hash, this function returns the values of that hash. +#### `values` + +When given a hash, this function returns the values of that hash. *Examples:* @@ -766,7 +956,9 @@ of the regular expressions match the string passed in, compilation aborts with a *Type*: rvalue -* `values_at`: Finds value inside an array based on location. The first argument is the array you want to analyze, and the second element can be a combination of: +#### `values_at` + +Finds value inside an array based on location. The first argument is the array you want to analyze, and the second element can be a combination of: * A single numeric index * A range in the form of 'start-stop' (eg. 4-9) @@ -776,7 +968,9 @@ of the regular expressions match the string passed in, compilation aborts with a *Type*: rvalue -* `zip`: Takes one element from first array and merges corresponding elements from second array. This generates a sequence of n-element arrays, where n is one more than the count of arguments. For example, `zip(['1','2','3'],['4','5','6'])` results in ["1", "4"], ["2", "5"], ["3", "6"]. *Type*: rvalue +#### `zip` + +Takes one element from first array and merges corresponding elements from second array. This generates a sequence of n-element arrays, where n is one more than the count of arguments. For example, `zip(['1','2','3'],['4','5','6'])` results in ["1", "4"], ["2", "5"], ["3", "6"]. *Type*: rvalue ##Limitations -- cgit v1.2.3 From a82266c256784c4af229e026b00a4dcf9e779270 Mon Sep 17 00:00:00 2001 From: Eli Young Date: Mon, 26 Jan 2015 19:17:53 -0800 Subject: (MODULES-1715) Add fqdn_rand string generators --- README.markdown | 17 +++++ lib/puppet/parser/functions/fqdn_rand_string.rb | 34 +++++++++ spec/acceptance/fqdn_rand_base64_spec.rb | 60 ++++++++++++++++ spec/acceptance/fqdn_rand_string_spec.rb | 60 ++++++++++++++++ spec/functions/fqdn_rand_string_spec.rb | 91 +++++++++++++++++++++++++ 5 files changed, 262 insertions(+) create mode 100644 lib/puppet/parser/functions/fqdn_rand_string.rb create mode 100644 spec/acceptance/fqdn_rand_base64_spec.rb create mode 100644 spec/acceptance/fqdn_rand_string_spec.rb create mode 100644 spec/functions/fqdn_rand_string_spec.rb diff --git a/README.markdown b/README.markdown index 293a81a..724a48e 100644 --- a/README.markdown +++ b/README.markdown @@ -244,6 +244,23 @@ This function flattens any deeply nested arrays and returns a single flat array Returns the largest integer less than or equal to the argument. Takes a single numeric value as an argument. *Type*: rvalue +#### `fqdn_rand_string` + +Generates a random alphanumeric string using an optionally-specified character set (default is alphanumeric), combining the `$fqdn` fact and an optional seed for repeatable randomness. + +*Usage:* +``` +fqdn_rand_string(LENGTH, [CHARSET], [SEED]) +``` +*Examples:* +``` +fqdn_rand_string(10) +fqdn_rand_string(10, 'ABCDEF!@#$%^') +fqdn_rand_string(10, '', 'custom seed') +``` + +*Type*: rvalue + #### `fqdn_rotate` Rotates an array a random number of times based on a node's fqdn. *Type*: rvalue diff --git a/lib/puppet/parser/functions/fqdn_rand_string.rb b/lib/puppet/parser/functions/fqdn_rand_string.rb new file mode 100644 index 0000000..785c9fd --- /dev/null +++ b/lib/puppet/parser/functions/fqdn_rand_string.rb @@ -0,0 +1,34 @@ +Puppet::Parser::Functions::newfunction( + :fqdn_rand_string, + :arity => -2, + :type => :rvalue, + :doc => "Usage: `fqdn_rand_string(LENGTH, [CHARSET], [SEED])`. LENGTH is + required and must be a positive integer. CHARSET is optional and may be + `undef` or a string. SEED is optional and may be any number or string. + + Generates a random string LENGTH characters long using the character set + provided by CHARSET, combining the `$fqdn` fact and the value of SEED for + repeatable randomness. (That is, each node will get a different random + string from this function, but a given node's result will be the same every + time unless its hostname changes.) Adding a SEED can be useful if you need + more than one unrelated string. CHARSET will default to alphanumeric if + `undef` or an empty string.") do |args| + raise(ArgumentError, "fqdn_rand_string(): wrong number of arguments (0 for 1)") if args.size == 0 + Puppet::Parser::Functions.function('is_integer') + raise(ArgumentError, "fqdn_rand_base64(): first argument must be a positive integer") unless function_is_integer([args[0]]) and args[0].to_i > 0 + raise(ArgumentError, "fqdn_rand_base64(): second argument must be undef or a string") unless args[1].nil? or args[1].is_a? String + + Puppet::Parser::Functions.function('fqdn_rand') + + length = args.shift.to_i + charset = args.shift.to_s.chars.to_a + + charset = (0..9).map { |i| i.to_s } + ('A'..'Z').to_a + ('a'..'z').to_a if charset.empty? + + rand_string = '' + for current in 1..length + rand_string << charset[function_fqdn_rand([charset.size, (args + [current.to_s]).join(':')]).to_i] + end + + rand_string +end diff --git a/spec/acceptance/fqdn_rand_base64_spec.rb b/spec/acceptance/fqdn_rand_base64_spec.rb new file mode 100644 index 0000000..7c58942 --- /dev/null +++ b/spec/acceptance/fqdn_rand_base64_spec.rb @@ -0,0 +1,60 @@ +#! /usr/bin/env ruby -S rspec +require 'spec_helper_acceptance' + +describe 'fqdn_rand_base64 function', :unless => unsupported_platforms.include?(fact('operatingsystem')) do + describe 'success' do + let(:facts_d) do + if fact('is_pe', '--puppet') == "true" + if fact('osfamily') =~ /windows/i + if fact('kernelmajversion').to_f < 6.0 + 'c:/documents and settings/all users/application data/puppetlabs/facter/facts.d' + else + 'c:/programdata/puppetlabs/facter/facts.d' + end + else + '/etc/puppetlabs/facter/facts.d' + end + else + '/etc/facter/facts.d' + end + end + after :each do + shell("if [ -f '#{facts_d}/fqdn.txt' ] ; then rm '#{facts_d}/fqdn.txt' ; fi") + end + before :each do + #no need to create on windows, pe creates by default + if fact('osfamily') !~ /windows/i + shell("mkdir -p '#{facts_d}'") + end + end + it 'generates random base64 strings' do + shell("echo fqdn=fakehost.localdomain > '#{facts_d}/fqdn.txt'") + pp = <<-eos + $l = 10 + $o = fqdn_rand_base64($l) + notice(inline_template('fqdn_rand_base64 is <%= @o.inspect %>')) + eos + + apply_manifest(pp, :catch_failures => true) do |r| + expect(r.stdout).to match(/fqdn_rand_base64 is "8ySYp0dq0B"/) + end + end + it 'generates random base64 strings with custom seeds' do + shell("echo fqdn=fakehost.localdomain > '#{facts_d}/fqdn.txt'") + pp = <<-eos + $l = 10 + $s = 'seed' + $o = fqdn_rand_base64($l, $s) + notice(inline_template('fqdn_rand_base64 is <%= @o.inspect %>')) + eos + + apply_manifest(pp, :catch_failures => true) do |r| + expect(r.stdout).to match(/fqdn_rand_base64 is "6J2c4oMRUJ"/) + end + end + end + describe 'failure' do + it 'handles improper argument counts' + it 'handles non-numbers for length argument' + end +end diff --git a/spec/acceptance/fqdn_rand_string_spec.rb b/spec/acceptance/fqdn_rand_string_spec.rb new file mode 100644 index 0000000..0e79723 --- /dev/null +++ b/spec/acceptance/fqdn_rand_string_spec.rb @@ -0,0 +1,60 @@ +#! /usr/bin/env ruby -S rspec +require 'spec_helper_acceptance' + +describe 'fqdn_rand_string function', :unless => unsupported_platforms.include?(fact('operatingsystem')) do + describe 'success' do + let(:facts_d) do + if fact('is_pe', '--puppet') == "true" + if fact('osfamily') =~ /windows/i + if fact('kernelmajversion').to_f < 6.0 + 'c:/documents and settings/all users/application data/puppetlabs/facter/facts.d' + else + 'c:/programdata/puppetlabs/facter/facts.d' + end + else + '/etc/puppetlabs/facter/facts.d' + end + else + '/etc/facter/facts.d' + end + end + after :each do + shell("if [ -f '#{facts_d}/fqdn.txt' ] ; then rm '#{facts_d}/fqdn.txt' ; fi") + end + before :each do + #no need to create on windows, pe creates by default + if fact('osfamily') !~ /windows/i + shell("mkdir -p '#{facts_d}'") + end + end + it 'generates random alphanumeric strings' do + shell("echo fqdn=fakehost.localdomain > '#{facts_d}/fqdn.txt'") + pp = <<-eos + $l = 10 + $o = fqdn_rand_string($l) + notice(inline_template('fqdn_rand_string is <%= @o.inspect %>')) + eos + + apply_manifest(pp, :catch_failures => true) do |r| + expect(r.stdout).to match(/fqdn_rand_string is "7oDp0KOr1b"/) + end + end + it 'generates random alphanumeric strings with custom seeds' do + shell("echo fqdn=fakehost.localdomain > '#{facts_d}/fqdn.txt'") + pp = <<-eos + $l = 10 + $s = 'seed' + $o = fqdn_rand_string($l, $s) + notice(inline_template('fqdn_rand_string is <%= @o.inspect %>')) + eos + + apply_manifest(pp, :catch_failures => true) do |r| + expect(r.stdout).to match(/fqdn_rand_string is "3HS4mbuI3E"/) + end + end + end + describe 'failure' do + it 'handles improper argument counts' + it 'handles non-numbers for length argument' + end +end diff --git a/spec/functions/fqdn_rand_string_spec.rb b/spec/functions/fqdn_rand_string_spec.rb new file mode 100644 index 0000000..949d930 --- /dev/null +++ b/spec/functions/fqdn_rand_string_spec.rb @@ -0,0 +1,91 @@ +#! /usr/bin/env ruby -S rspec +require 'spec_helper' + +describe "the fqdn_rand_string function" do + let(:scope) { PuppetlabsSpec::PuppetInternals.scope } + + it "should exist" do + expect(Puppet::Parser::Functions.function("fqdn_rand_string")).to eq("function_fqdn_rand_string") + end + + it "should raise an ArgumentError if there is less than 1 argument" do + expect { fqdn_rand_string() }.to( raise_error(ArgumentError, /wrong number of arguments/)) + end + + it "should raise an ArgumentError if argument 1 isn't a positive integer" do + expect { fqdn_rand_string(0) }.to( raise_error(ArgumentError, /first argument must be a positive integer/)) + expect { fqdn_rand_string(-1) }.to( raise_error(ArgumentError, /first argument must be a positive integer/)) + expect { fqdn_rand_string(0.5) }.to( raise_error(ArgumentError, /first argument must be a positive integer/)) + end + + it "provides a valid alphanumeric string when no character set is provided" do + length = 100 + string = %r{\A[a-zA-Z0-9]{#{length}}\z} + expect(fqdn_rand_string(length).match(string)).not_to eq(nil) + end + + it "provides a valid alphanumeric string when an undef character set is provided" do + length = 100 + string = %r{\A[a-zA-Z0-9]{#{length}}\z} + expect(fqdn_rand_string(length, :charset => nil).match(string)).not_to eq(nil) + end + + it "provides a valid alphanumeric string when an empty character set is provided" do + length = 100 + string = %r{\A[a-zA-Z0-9]{#{length}}\z} + expect(fqdn_rand_string(length, :charset => '').match(string)).not_to eq(nil) + end + + it "uses a provided character set" do + length = 100 + charset = '!@#$%^&*()-_=+' + string = %r{\A[#{charset}]{#{length}}\z} + expect(fqdn_rand_string(length, :charset => charset).match(string)).not_to eq(nil) + end + + it "provides a random string exactly as long as the given length" do + expect(fqdn_rand_string(10).size).to eql(10) + end + + it "provides the same 'random' value on subsequent calls for the same host" do + expect(fqdn_rand_string(10)).to eql(fqdn_rand_string(10)) + end + + it "considers the same host and same extra arguments to have the same random sequence" do + first_random = fqdn_rand_string(10, :extra_identifier => [1, "same", "host"]) + second_random = fqdn_rand_string(10, :extra_identifier => [1, "same", "host"]) + + expect(first_random).to eql(second_random) + end + + it "allows extra arguments to control the random value on a single host" do + first_random = fqdn_rand_string(10, :extra_identifier => [1, "different", "host"]) + second_different_random = fqdn_rand_string(10, :extra_identifier => [2, "different", "host"]) + + expect(first_random).not_to eql(second_different_random) + end + + it "should return different strings for different hosts" do + val1 = fqdn_rand_string(10, :host => "first.host.com") + val2 = fqdn_rand_string(10, :host => "second.host.com") + + expect(val1).not_to eql(val2) + end + + def fqdn_rand_string(max, args = {}) + host = args[:host] || '127.0.0.1' + charset = args[:charset] + extra = args[:extra_identifier] || [] + + scope = PuppetlabsSpec::PuppetInternals.scope + scope.stubs(:[]).with("::fqdn").returns(host) + scope.stubs(:lookupvar).with("::fqdn").returns(host) + + function_args = [max] + if args.has_key?(:charset) or !extra.empty? + function_args << charset + end + function_args += extra + scope.function_fqdn_rand_string(function_args) + end +end -- cgit v1.2.3 From 23be4020ddd4f95dc589ecebe57cd1b27d85248b Mon Sep 17 00:00:00 2001 From: Eli Young Date: Mon, 2 Feb 2015 16:41:38 -0800 Subject: (MODULES-1737) Add pw_hash() function --- README.markdown | 18 +++++++ lib/puppet/parser/functions/pw_hash.rb | 56 ++++++++++++++++++++++ spec/acceptance/pw_hash_spec.rb | 34 +++++++++++++ spec/functions/pw_hash_spec.rb | 87 ++++++++++++++++++++++++++++++++++ 4 files changed, 195 insertions(+) create mode 100644 lib/puppet/parser/functions/pw_hash.rb create mode 100644 spec/acceptance/pw_hash_spec.rb create mode 100644 spec/functions/pw_hash_spec.rb diff --git a/README.markdown b/README.markdown index 293a81a..d6be689 100644 --- a/README.markdown +++ b/README.markdown @@ -500,6 +500,24 @@ Calling the class or definition from outside the current module will fail. For e *Type*: statement +#### `pw_hash` + +Hashes a password using the crypt function. Provides a hash usable on most POSIX systems. + +The first argument to this function is the password to hash. If it is undef or an empty string, this function returns undef. + +The second argument to this function is which type of hash to use. It will be converted into the appropriate crypt(3) hash specifier. Valid hash types are: + +|Hash type |Specifier| +|---------------------|---------| +|MD5 |1 | +|SHA-256 |5 | +|SHA-512 (recommended)|6 | + +The third argument to this function is the salt to use. + +Note: this uses the Puppet Master's implementation of crypt(3). If your environment contains several different operating systems, ensure that they are compatible before using this function. + #### `range` When given range in the form of '(start, stop)', `range` extrapolates a range as an array. For example, `range("0", "9")` returns [0,1,2,3,4,5,6,7,8,9]. Zero-padded strings are converted to integers automatically, so `range("00", "09")` returns [0,1,2,3,4,5,6,7,8,9]. diff --git a/lib/puppet/parser/functions/pw_hash.rb b/lib/puppet/parser/functions/pw_hash.rb new file mode 100644 index 0000000..ad3e393 --- /dev/null +++ b/lib/puppet/parser/functions/pw_hash.rb @@ -0,0 +1,56 @@ +Puppet::Parser::Functions::newfunction( + :pw_hash, + :type => :rvalue, + :arity => 3, + :doc => "Hashes a password using the crypt function. Provides a hash + usable on most POSIX systems. + + The first argument to this function is the password to hash. If it is + undef or an empty string, this function returns undef. + + The second argument to this function is which type of hash to use. It + will be converted into the appropriate crypt(3) hash specifier. Valid + hash types are: + + |Hash type |Specifier| + |---------------------|---------| + |MD5 |1 | + |SHA-256 |5 | + |SHA-512 (recommended)|6 | + + The third argument to this function is the salt to use. + + Note: this uses the Puppet Master's implementation of crypt(3). If your + environment contains several different operating systems, ensure that they + are compatible before using this function.") do |args| + raise ArgumentError, "pw_hash(): wrong number of arguments (#{args.size} for 3)" if args.size != 3 + raise ArgumentError, "pw_hash(): first argument must be a string" unless args[0].is_a? String or args[0].nil? + raise ArgumentError, "pw_hash(): second argument must be a string" unless args[1].is_a? String + hashes = { 'md5' => '1', + 'sha-256' => '5', + 'sha-512' => '6' } + hash_type = hashes[args[1].downcase] + raise ArgumentError, "pw_hash(): #{args[1]} is not a valid hash type" if hash_type.nil? + raise ArgumentError, "pw_hash(): third argument must be a string" unless args[2].is_a? String + raise ArgumentError, "pw_hash(): third argument must not be empty" if args[2].empty? + raise ArgumentError, "pw_hash(): characters in salt must be in the set [a-zA-Z0-9./]" unless args[2].match(/\A[a-zA-Z0-9.\/]+\z/) + + password = args[0] + return nil if password.nil? or password.empty? + + # handle weak implementations of String#crypt + if 'test'.crypt('$1$1') != '$1$1$Bp8CU9Oujr9SSEw53WV6G.' + # JRuby < 1.7.17 + if RUBY_PLATFORM == 'java' + # override String#crypt for password variable + def password.crypt(salt) + # puppetserver bundles Apache Commons Codec + org.apache.commons.codec.digest.Crypt.crypt(self.to_java_bytes, salt) + end + else + # MS Windows and other systems that don't support enhanced salts + raise Puppet::ParseError, 'system does not support enhanced salts' + end + end + password.crypt("$#{hash_type}$#{args[2]}") +end diff --git a/spec/acceptance/pw_hash_spec.rb b/spec/acceptance/pw_hash_spec.rb new file mode 100644 index 0000000..4768975 --- /dev/null +++ b/spec/acceptance/pw_hash_spec.rb @@ -0,0 +1,34 @@ +#! /usr/bin/env ruby -S rspec +require 'spec_helper_acceptance' + +# Windows and OS X do not have useful implementations of crypt(3) +describe 'pw_hash function', :unless => (UNSUPPORTED_PLATFORMS + ['windows', 'Darwin']).include?(fact('operatingsystem')) do + describe 'success' do + it 'hashes passwords' do + pp = <<-EOS + $o = pw_hash('password', 6, 'salt') + notice(inline_template('pw_hash is <%= @o.inspect %>')) + EOS + + apply_manifest(pp, :catch_failures => true) do |r| + expect(r.stdout).to match(/pw_hash is "\$6\$salt\$IxDD3jeSOb5eB1CX5LBsqZFVkJdido3OUILO5Ifz5iwMuTS4XMS130MTSuDDl3aCI6WouIL9AjRbLCelDCy\.g\."/) + end + end + + it 'returns nil if no password is provided' do + pp = <<-EOS + $o = pw_hash('', 6, 'salt') + notice(inline_template('pw_hash is <%= @o.inspect %>')) + EOS + + apply_manifest(pp, :catch_failures => true) do |r| + expect(r.stdout).to match(/pw_hash is ""/) + end + end + end + describe 'failure' do + it 'handles less than three arguments' + it 'handles more than three arguments' + it 'handles non strings' + end +end diff --git a/spec/functions/pw_hash_spec.rb b/spec/functions/pw_hash_spec.rb new file mode 100644 index 0000000..01a1105 --- /dev/null +++ b/spec/functions/pw_hash_spec.rb @@ -0,0 +1,87 @@ +#! /usr/bin/env ruby -S rspec +require 'spec_helper' + +describe "the pw_hash function" do + let(:scope) { PuppetlabsSpec::PuppetInternals.scope } + + it "should exist" do + expect(Puppet::Parser::Functions.function("pw_hash")).to eq("function_pw_hash") + end + + it "should raise an ArgumentError if there are less than 3 arguments" do + expect { scope.function_pw_hash([]) }.to( raise_error(ArgumentError, /[Ww]rong number of arguments/) ) + expect { scope.function_pw_hash(['password']) }.to( raise_error(ArgumentError, /[Ww]rong number of arguments/) ) + expect { scope.function_pw_hash(['password', 'sha-512']) }.to( raise_error(ArgumentError, /[Ww]rong number of arguments/) ) + end + + it "should raise an ArgumentError if there are more than 3 arguments" do + expect { scope.function_pw_hash(['password', 'sha-512', 'salt', 5]) }.to( raise_error(ArgumentError, /[Ww]rong number of arguments/) ) + end + + it "should raise an ArgumentError if the first argument is not a string" do + expect { scope.function_pw_hash([['password'], 'sha-512', 'salt']) }.to( raise_error(ArgumentError, /first argument must be a string/) ) + # in Puppet 3, numbers are passed as strings, so we can't test that + end + + it "should return nil if the first argument is empty" do + expect(scope.function_pw_hash(['', 'sha-512', 'salt'])).to eq(nil) + end + + it "should return nil if the first argument is undef" do + expect(scope.function_pw_hash([nil, 'sha-512', 'salt'])).to eq(nil) + end + + it "should raise an ArgumentError if the second argument is an invalid hash type" do + expect { scope.function_pw_hash(['', 'invalid', 'salt']) }.to( raise_error(ArgumentError, /not a valid hash type/) ) + end + + it "should raise an ArgumentError if the second argument is not a string" do + expect { scope.function_pw_hash(['', [], 'salt']) }.to( raise_error(ArgumentError, /second argument must be a string/) ) + end + + it "should raise an ArgumentError if the third argument is not a string" do + expect { scope.function_pw_hash(['password', 'sha-512', ['salt']]) }.to( raise_error(ArgumentError, /third argument must be a string/) ) + # in Puppet 3, numbers are passed as strings, so we can't test that + end + + it "should raise an ArgumentError if the third argument is empty" do + expect { scope.function_pw_hash(['password', 'sha-512', '']) }.to( raise_error(ArgumentError, /third argument must not be empty/) ) + end + + it "should raise an ArgumentError if the third argument has invalid characters" do + expect { scope.function_pw_hash(['password', 'sha-512', '%']) }.to( raise_error(ArgumentError, /characters in salt must be in the set/) ) + end + + it "should fail on platforms with weak implementations of String#crypt" do + String.any_instance.expects(:crypt).with('$1$1').returns('$1SoNol0Ye6Xk') + expect { scope.function_pw_hash(['password', 'sha-512', 'salt']) }.to( raise_error(Puppet::ParseError, /system does not support enhanced salts/) ) + end + + it "should return a hashed password" do + result = scope.function_pw_hash(['password', 'sha-512', 'salt']) + expect(result).to eql('$6$salt$IxDD3jeSOb5eB1CX5LBsqZFVkJdido3OUILO5Ifz5iwMuTS4XMS130MTSuDDl3aCI6WouIL9AjRbLCelDCy.g.') + end + + it "should use the specified salt" do + result = scope.function_pw_hash(['password', 'sha-512', 'salt']) + expect(result).to match('salt') + end + + it "should use the specified hash type" do + resultmd5 = scope.function_pw_hash(['password', 'md5', 'salt']) + resultsha256 = scope.function_pw_hash(['password', 'sha-256', 'salt']) + resultsha512 = scope.function_pw_hash(['password', 'sha-512', 'salt']) + + expect(resultmd5).to eql('$1$salt$qJH7.N4xYta3aEG/dfqo/0') + expect(resultsha256).to eql('$5$salt$Gcm6FsVtF/Qa77ZKD.iwsJlCVPY0XSMgLJL0Hnww/c1') + expect(resultsha512).to eql('$6$salt$IxDD3jeSOb5eB1CX5LBsqZFVkJdido3OUILO5Ifz5iwMuTS4XMS130MTSuDDl3aCI6WouIL9AjRbLCelDCy.g.') + end + + it "should generate a valid hash" do + password_hash = scope.function_pw_hash(['password', 'sha-512', 'salt']) + + hash_parts = password_hash.match(%r{\A\$(.*)\$([a-zA-Z0-9./]+)\$([a-zA-Z0-9./]+)\z}) + + expect(hash_parts).not_to eql(nil) + end +end -- cgit v1.2.3 From 9a1fee6c682717b20ab5c287a47ae46ab06b8e11 Mon Sep 17 00:00:00 2001 From: David Schmitt Date: Wed, 8 Apr 2015 13:46:56 +0100 Subject: Update Travis CI job from current modulesync_configs --- .travis.yml | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index 503e184..b29f7e7 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,13 +6,19 @@ script: "bundle exec rake validate && bundle exec rake lint && bundle exec rake matrix: fast_finish: true include: + - rvm: 1.9.3 + env: PUPPET_GEM_VERSION="~> 3.4.0" - rvm: 1.8.7 - env: PUPPET_GEM_VERSION="~> 2.7.0" FACTER_GEM_VERSION="~> 1.6.0" - - rvm: 1.8.7 - env: PUPPET_GEM_VERSION="~> 2.7.0" FACTER_GEM_VERSION="~> 1.7.0" + env: PUPPET_GEM_VERSION="~> 3.0" - rvm: 1.9.3 env: PUPPET_GEM_VERSION="~> 3.0" - - rvm: 2.0.0 + - rvm: 1.9.3 + env: PUPPET_GEM_VERSION="~> 3.0" FUTURE_PARSER="yes" + - rvm: 2.1.5 env: PUPPET_GEM_VERSION="~> 3.0" + - rvm: 2.1.5 + env: PUPPET_GEM_VERSION="~> 3.4.0" + - rvm: 2.1.5 + env: PUPPET_GEM_VERSION="~> 3.0" FUTURE_PARSER="yes" notifications: email: false -- cgit v1.2.3 From ee2225b63c4356dafffedc16ec0376af58d42dad Mon Sep 17 00:00:00 2001 From: Gerrard Geldenhuis Date: Fri, 24 Oct 2014 15:41:58 +0100 Subject: Clarifying behaviour of attributes and adding an extra example. --- lib/puppet/type/file_line.rb | 30 +++++++++++++++++++++++------- 1 file changed, 23 insertions(+), 7 deletions(-) diff --git a/lib/puppet/type/file_line.rb b/lib/puppet/type/file_line.rb index df263e6..29f9538 100644 --- a/lib/puppet/type/file_line.rb +++ b/lib/puppet/type/file_line.rb @@ -3,9 +3,9 @@ Puppet::Type.newtype(:file_line) do desc <<-EOT Ensures that a given line is contained within a file. The implementation matches the full line, including whitespace at the beginning and end. If - the line is not contained in the given file, Puppet will add the line to - ensure the desired state. Multiple resources may be declared to manage - multiple lines in the same file. + the line is not contained in the given file, Puppet will append the line to + the end of the file to ensure the desired state. Multiple resources may + be declared to manage multiple lines in the same file. Example: @@ -13,6 +13,7 @@ Puppet::Type.newtype(:file_line) do path => '/etc/sudoers', line => '%sudo ALL=(ALL) ALL', } + file_line { 'sudo_rule_nopw': path => '/etc/sudoers', line => '%sudonopw ALL=(ALL) NOPASSWD: ALL', @@ -21,6 +22,18 @@ Puppet::Type.newtype(:file_line) do In this example, Puppet will ensure both of the specified lines are contained in the file /etc/sudoers. + Match Example: + + file_line { 'bashrc_proxy': + ensure => present, + path => '/etc/bashrc', + line => 'export HTTP_PROXY=http://squid.puppetlabs.vm:3128', + match => '^export\ HTTP_PROXY\=', + } + + In this code example match will look for a line beginning with export + followed by HTTP_PROXY and replace it with the value in line. + **Autorequires:** If Puppet is managing the file that will contain the line being managed, the file_line resource will autorequire that file. @@ -36,12 +49,15 @@ Puppet::Type.newtype(:file_line) do end newparam(:match) do - desc 'An optional regular expression to run against existing lines in the file;\n' + - 'if a match is found, we replace that line rather than adding a new line.' + desc 'An optional ruby regular expression to run against existing lines in the file.' + + ' If a match is found, we replace that line rather than adding a new line.' + + ' A regex comparisson is performed against the line value and if it does not' + + ' match an exception will be raised. ' end newparam(:multiple) do - desc 'An optional value to determine if match can change multiple lines.' + desc 'An optional value to determine if match can change multiple lines.' + + ' If set to false, an exception will be raised if more than one line matches' newvalues(true, false) end @@ -50,7 +66,7 @@ Puppet::Type.newtype(:file_line) do end newparam(:line) do - desc 'The line to be appended to the file located by the path parameter.' + desc 'The line to be appended to the file or used to replace matches found by the match attribute.' end newparam(:path) do -- cgit v1.2.3 From 35303ce0f7cf66feb7499d9671a7d2121a0f52b1 Mon Sep 17 00:00:00 2001 From: Bryan Jen Date: Thu, 9 Apr 2015 11:30:22 -0700 Subject: file_line honors after if match not found. --- lib/puppet/provider/file_line/ruby.rb | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/lib/puppet/provider/file_line/ruby.rb b/lib/puppet/provider/file_line/ruby.rb index ae1a8b3..a1acab8 100644 --- a/lib/puppet/provider/file_line/ruby.rb +++ b/lib/puppet/provider/file_line/ruby.rb @@ -34,13 +34,22 @@ Puppet::Type.type(:file_line).provide(:ruby) do def handle_create_with_match() regex = resource[:match] ? Regexp.new(resource[:match]) : nil + regex_after = resource[:after] ? Regexp.new(resource[:after]) : nil match_count = count_matches(regex) + if match_count > 1 && resource[:multiple].to_s != 'true' raise Puppet::Error, "More than one line in file '#{resource[:path]}' matches pattern '#{resource[:match]}'" end + File.open(resource[:path], 'w') do |fh| lines.each do |l| fh.puts(regex.match(l) ? resource[:line] : l) + if (match_count == 0 and regex_after) + if regex_after.match(l) + fh.puts(resource[:line]) + match_count += 1 #Increment match_count to indicate that the new line has been inserted. + end + end end if (match_count == 0) -- cgit v1.2.3 From 0af0d7e5392a69f0ed72fa1b0225fe2a61188319 Mon Sep 17 00:00:00 2001 From: Travis Fields Date: Thu, 9 Apr 2015 11:02:29 -0700 Subject: Add spec tests and pulled in PR #427 Changed append line to open in 'w' mode and have to rewrite lines in order to append new line --- lib/puppet/provider/file_line/ruby.rb | 5 +- spec/unit/puppet/provider/file_line/ruby_spec.rb | 88 +++++++++++++++++++----- 2 files changed, 74 insertions(+), 19 deletions(-) diff --git a/lib/puppet/provider/file_line/ruby.rb b/lib/puppet/provider/file_line/ruby.rb index a1acab8..e7854f0 100644 --- a/lib/puppet/provider/file_line/ruby.rb +++ b/lib/puppet/provider/file_line/ruby.rb @@ -87,7 +87,10 @@ Puppet::Type.type(:file_line).provide(:ruby) do # # @api private def append_line - File.open(resource[:path], 'a') do |fh| + File.open(resource[:path], 'w') do |fh| + lines.each do |l| + fh.puts(l) + end fh.puts resource[:line] end end diff --git a/spec/unit/puppet/provider/file_line/ruby_spec.rb b/spec/unit/puppet/provider/file_line/ruby_spec.rb index d2a129c..a84fc78 100755 --- a/spec/unit/puppet/provider/file_line/ruby_spec.rb +++ b/spec/unit/puppet/provider/file_line/ruby_spec.rb @@ -46,12 +46,12 @@ describe provider_class do @tmpfile = tmp.path tmp.close! @resource = Puppet::Type::File_line.new( - { - :name => 'foo', - :path => @tmpfile, - :line => 'foo = bar', - :match => '^foo\s*=.*$', - } + { + :name => 'foo', + :path => @tmpfile, + :line => 'foo = bar', + :match => '^foo\s*=.*$', + } ) @provider = provider_class.new(@resource) end @@ -69,11 +69,11 @@ describe provider_class do it 'should replace all lines that matches' do @resource = Puppet::Type::File_line.new( { - :name => 'foo', - :path => @tmpfile, - :line => 'foo = bar', - :match => '^foo\s*=.*$', - :multiple => true + :name => 'foo', + :path => @tmpfile, + :line => 'foo = bar', + :match => '^foo\s*=.*$', + :multiple => true, } ) @provider = provider_class.new(@resource) @@ -89,11 +89,11 @@ describe provider_class do expect { @resource = Puppet::Type::File_line.new( { - :name => 'foo', - :path => @tmpfile, - :line => 'foo = bar', - :match => '^foo\s*=.*$', - :multiple => 'asgadga' + :name => 'foo', + :path => @tmpfile, + :line => 'foo = bar', + :match => '^foo\s*=.*$', + :multiple => 'asgadga', } ) }.to raise_error(Puppet::Error, /Invalid value "asgadga"\. Valid values are true, false\./) @@ -140,7 +140,54 @@ describe provider_class do let :provider do provider_class.new(resource) end - + context 'match and after set' do + shared_context 'resource_create' do + let(:match) { '^foo2$' } + let(:after) { '^foo1$' } + let(:resource) { + Puppet::Type::File_line.new( + { + :name => 'foo', + :path => @tmpfile, + :line => 'inserted = line', + :after => after, + :match => match, + } + ) + } + end + before :each do + File.open(@tmpfile, 'w') do |fh| + fh.write("foo1\nfoo2\nfoo = baz") + end + end + describe 'inserts at match' do + include_context 'resource_create' + it { + provider.create + expect(File.read(@tmpfile).chomp).to eq("foo1\ninserted = line\nfoo = baz") + } + end + describe 'inserts a new line after when no match' do + include_context 'resource_create' do + let(:match) { '^nevergoingtomatch$' } + end + it { + provider.create + expect(File.read(@tmpfile).chomp).to eq("foo1\ninserted = line\nfoo2\nfoo = baz") + } + end + describe 'append to end of file if no match for both after and match' do + include_context 'resource_create' do + let(:match) { '^nevergoingtomatch$' } + let(:after) { '^stillneverafter' } + end + it { + provider.create + expect(File.read(@tmpfile).chomp).to eq("foo1\nfoo2\nfoo = baz\ninserted = line") + } + end + end context 'with one line matching the after expression' do before :each do File.open(@tmpfile, 'w') do |fh| @@ -194,7 +241,12 @@ describe provider_class do @tmpfile = tmp.path tmp.close! @resource = Puppet::Type::File_line.new( - {:name => 'foo', :path => @tmpfile, :line => 'foo', :ensure => 'absent' } + { + :name => 'foo', + :path => @tmpfile, + :line => 'foo', + :ensure => 'absent', + } ) @provider = provider_class.new(@resource) end -- cgit v1.2.3 From e43f0582960707f8a7ff9f087ca2b521c1797a91 Mon Sep 17 00:00:00 2001 From: Colleen Murphy Date: Thu, 9 Apr 2015 15:47:04 -0700 Subject: Fix unsupported platforms variable name in tests unsupported_platforms is not a valid identifier, and trying to use it causes acceptance tests to error out before running any tests. The correct identifier for the unsupported platforms constants is UNSUPPORTED_PLATFORMS. --- spec/acceptance/fqdn_rand_base64_spec.rb | 2 +- spec/acceptance/fqdn_rand_string_spec.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/acceptance/fqdn_rand_base64_spec.rb b/spec/acceptance/fqdn_rand_base64_spec.rb index 7c58942..1b4eb72 100644 --- a/spec/acceptance/fqdn_rand_base64_spec.rb +++ b/spec/acceptance/fqdn_rand_base64_spec.rb @@ -1,7 +1,7 @@ #! /usr/bin/env ruby -S rspec require 'spec_helper_acceptance' -describe 'fqdn_rand_base64 function', :unless => unsupported_platforms.include?(fact('operatingsystem')) do +describe 'fqdn_rand_base64 function', :unless => UNSUPPORTED_PLATFORMS.include?(fact('operatingsystem')) do describe 'success' do let(:facts_d) do if fact('is_pe', '--puppet') == "true" diff --git a/spec/acceptance/fqdn_rand_string_spec.rb b/spec/acceptance/fqdn_rand_string_spec.rb index 0e79723..a934fbb 100644 --- a/spec/acceptance/fqdn_rand_string_spec.rb +++ b/spec/acceptance/fqdn_rand_string_spec.rb @@ -1,7 +1,7 @@ #! /usr/bin/env ruby -S rspec require 'spec_helper_acceptance' -describe 'fqdn_rand_string function', :unless => unsupported_platforms.include?(fact('operatingsystem')) do +describe 'fqdn_rand_string function', :unless => UNSUPPORTED_PLATFORMS.include?(fact('operatingsystem')) do describe 'success' do let(:facts_d) do if fact('is_pe', '--puppet') == "true" -- cgit v1.2.3 From 65116dafd507c5111044853861f9b10b02c91854 Mon Sep 17 00:00:00 2001 From: Colleen Murphy Date: Fri, 10 Apr 2015 09:09:46 -0700 Subject: Fix acceptance tests for #405 This fixes the acceptance tests by: - Ensuring the fqdn_rand_string spec is passed undef as the second parameter so that the seed is not used as the charset - Ensuring the pw_hash spec is passed the key specifying the type of hash, rather than the value that will be used to generate the password - Expecting puppet to report nil instead of empty string for undef passwords - Removing the fqdn_rand_base64 test because there is no such function --- spec/acceptance/fqdn_rand_base64_spec.rb | 60 -------------------------------- spec/acceptance/fqdn_rand_string_spec.rb | 2 +- spec/acceptance/pw_hash_spec.rb | 6 ++-- 3 files changed, 4 insertions(+), 64 deletions(-) delete mode 100644 spec/acceptance/fqdn_rand_base64_spec.rb diff --git a/spec/acceptance/fqdn_rand_base64_spec.rb b/spec/acceptance/fqdn_rand_base64_spec.rb deleted file mode 100644 index 1b4eb72..0000000 --- a/spec/acceptance/fqdn_rand_base64_spec.rb +++ /dev/null @@ -1,60 +0,0 @@ -#! /usr/bin/env ruby -S rspec -require 'spec_helper_acceptance' - -describe 'fqdn_rand_base64 function', :unless => UNSUPPORTED_PLATFORMS.include?(fact('operatingsystem')) do - describe 'success' do - let(:facts_d) do - if fact('is_pe', '--puppet') == "true" - if fact('osfamily') =~ /windows/i - if fact('kernelmajversion').to_f < 6.0 - 'c:/documents and settings/all users/application data/puppetlabs/facter/facts.d' - else - 'c:/programdata/puppetlabs/facter/facts.d' - end - else - '/etc/puppetlabs/facter/facts.d' - end - else - '/etc/facter/facts.d' - end - end - after :each do - shell("if [ -f '#{facts_d}/fqdn.txt' ] ; then rm '#{facts_d}/fqdn.txt' ; fi") - end - before :each do - #no need to create on windows, pe creates by default - if fact('osfamily') !~ /windows/i - shell("mkdir -p '#{facts_d}'") - end - end - it 'generates random base64 strings' do - shell("echo fqdn=fakehost.localdomain > '#{facts_d}/fqdn.txt'") - pp = <<-eos - $l = 10 - $o = fqdn_rand_base64($l) - notice(inline_template('fqdn_rand_base64 is <%= @o.inspect %>')) - eos - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/fqdn_rand_base64 is "8ySYp0dq0B"/) - end - end - it 'generates random base64 strings with custom seeds' do - shell("echo fqdn=fakehost.localdomain > '#{facts_d}/fqdn.txt'") - pp = <<-eos - $l = 10 - $s = 'seed' - $o = fqdn_rand_base64($l, $s) - notice(inline_template('fqdn_rand_base64 is <%= @o.inspect %>')) - eos - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/fqdn_rand_base64 is "6J2c4oMRUJ"/) - end - end - end - describe 'failure' do - it 'handles improper argument counts' - it 'handles non-numbers for length argument' - end -end diff --git a/spec/acceptance/fqdn_rand_string_spec.rb b/spec/acceptance/fqdn_rand_string_spec.rb index a934fbb..8fe1a69 100644 --- a/spec/acceptance/fqdn_rand_string_spec.rb +++ b/spec/acceptance/fqdn_rand_string_spec.rb @@ -44,7 +44,7 @@ describe 'fqdn_rand_string function', :unless => UNSUPPORTED_PLATFORMS.include?( pp = <<-eos $l = 10 $s = 'seed' - $o = fqdn_rand_string($l, $s) + $o = fqdn_rand_string($l, undef, $s) notice(inline_template('fqdn_rand_string is <%= @o.inspect %>')) eos diff --git a/spec/acceptance/pw_hash_spec.rb b/spec/acceptance/pw_hash_spec.rb index 4768975..eddb782 100644 --- a/spec/acceptance/pw_hash_spec.rb +++ b/spec/acceptance/pw_hash_spec.rb @@ -6,7 +6,7 @@ describe 'pw_hash function', :unless => (UNSUPPORTED_PLATFORMS + ['windows', 'Da describe 'success' do it 'hashes passwords' do pp = <<-EOS - $o = pw_hash('password', 6, 'salt') + $o = pw_hash('password', 'sha-512', 'salt') notice(inline_template('pw_hash is <%= @o.inspect %>')) EOS @@ -17,12 +17,12 @@ describe 'pw_hash function', :unless => (UNSUPPORTED_PLATFORMS + ['windows', 'Da it 'returns nil if no password is provided' do pp = <<-EOS - $o = pw_hash('', 6, 'salt') + $o = pw_hash('', 'sha-512', 'salt') notice(inline_template('pw_hash is <%= @o.inspect %>')) EOS apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/pw_hash is ""/) + expect(r.stdout).to match(/pw_hash is nil/) end end end -- cgit v1.2.3 From 601e2e2574c37f5496323ed56702d4a657c278dd Mon Sep 17 00:00:00 2001 From: Bryan Jen Date: Fri, 10 Apr 2015 11:38:15 -0700 Subject: Modules-2474: Only runs enhanced salts functional test on systems that support it. --- spec/functions/pw_hash_spec.rb | 49 +++++++++++++++++++++++++----------------- 1 file changed, 29 insertions(+), 20 deletions(-) diff --git a/spec/functions/pw_hash_spec.rb b/spec/functions/pw_hash_spec.rb index 01a1105..3378090 100644 --- a/spec/functions/pw_hash_spec.rb +++ b/spec/functions/pw_hash_spec.rb @@ -2,6 +2,11 @@ require 'spec_helper' describe "the pw_hash function" do + + before :all do + @enhanced_salts_supported = RUBY_PLATFORM == 'java' + end + let(:scope) { PuppetlabsSpec::PuppetInternals.scope } it "should exist" do @@ -57,31 +62,35 @@ describe "the pw_hash function" do expect { scope.function_pw_hash(['password', 'sha-512', 'salt']) }.to( raise_error(Puppet::ParseError, /system does not support enhanced salts/) ) end - it "should return a hashed password" do - result = scope.function_pw_hash(['password', 'sha-512', 'salt']) - expect(result).to eql('$6$salt$IxDD3jeSOb5eB1CX5LBsqZFVkJdido3OUILO5Ifz5iwMuTS4XMS130MTSuDDl3aCI6WouIL9AjRbLCelDCy.g.') - end + if @enhanced_salts_supported + describe "on systems with enhanced salts support" do + it "should return a hashed password" do + result = scope.function_pw_hash(['password', 'sha-512', 'salt']) + expect(result).to eql('$6$salt$IxDD3jeSOb5eB1CX5LBsqZFVkJdido3OUILO5Ifz5iwMuTS4XMS130MTSuDDl3aCI6WouIL9AjRbLCelDCy.g.') + end - it "should use the specified salt" do - result = scope.function_pw_hash(['password', 'sha-512', 'salt']) - expect(result).to match('salt') - end + it "should use the specified salt" do + result = scope.function_pw_hash(['password', 'sha-512', 'salt']) + expect(result).to match('salt') + end - it "should use the specified hash type" do - resultmd5 = scope.function_pw_hash(['password', 'md5', 'salt']) - resultsha256 = scope.function_pw_hash(['password', 'sha-256', 'salt']) - resultsha512 = scope.function_pw_hash(['password', 'sha-512', 'salt']) + it "should use the specified hash type" do + resultmd5 = scope.function_pw_hash(['password', 'md5', 'salt']) + resultsha256 = scope.function_pw_hash(['password', 'sha-256', 'salt']) + resultsha512 = scope.function_pw_hash(['password', 'sha-512', 'salt']) - expect(resultmd5).to eql('$1$salt$qJH7.N4xYta3aEG/dfqo/0') - expect(resultsha256).to eql('$5$salt$Gcm6FsVtF/Qa77ZKD.iwsJlCVPY0XSMgLJL0Hnww/c1') - expect(resultsha512).to eql('$6$salt$IxDD3jeSOb5eB1CX5LBsqZFVkJdido3OUILO5Ifz5iwMuTS4XMS130MTSuDDl3aCI6WouIL9AjRbLCelDCy.g.') - end + expect(resultmd5).to eql('$1$salt$qJH7.N4xYta3aEG/dfqo/0') + expect(resultsha256).to eql('$5$salt$Gcm6FsVtF/Qa77ZKD.iwsJlCVPY0XSMgLJL0Hnww/c1') + expect(resultsha512).to eql('$6$salt$IxDD3jeSOb5eB1CX5LBsqZFVkJdido3OUILO5Ifz5iwMuTS4XMS130MTSuDDl3aCI6WouIL9AjRbLCelDCy.g.') + end - it "should generate a valid hash" do - password_hash = scope.function_pw_hash(['password', 'sha-512', 'salt']) + it "should generate a valid hash" do + password_hash = scope.function_pw_hash(['password', 'sha-512', 'salt']) - hash_parts = password_hash.match(%r{\A\$(.*)\$([a-zA-Z0-9./]+)\$([a-zA-Z0-9./]+)\z}) + hash_parts = password_hash.match(%r{\A\$(.*)\$([a-zA-Z0-9./]+)\$([a-zA-Z0-9./]+)\z}) - expect(hash_parts).not_to eql(nil) + expect(hash_parts).not_to eql(nil) + end + end end end -- cgit v1.2.3 From ac24e7acc767bce9cc1977f90c798df94292813e Mon Sep 17 00:00:00 2001 From: "Angel L. Mateo" Date: Mon, 13 Apr 2015 09:27:03 +0200 Subject: test case for when the file does not exist --- spec/functions/loadyaml_spec.rb | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/spec/functions/loadyaml_spec.rb b/spec/functions/loadyaml_spec.rb index cdc3d6f..4b8d406 100755 --- a/spec/functions/loadyaml_spec.rb +++ b/spec/functions/loadyaml_spec.rb @@ -14,6 +14,12 @@ describe "the loadyaml function" do expect { scope.function_loadyaml([]) }.to raise_error(Puppet::ParseError) end + it "should return nil when file does not exist" do + yaml_file = tmpfilename ('yamlfile') + result = scope.function_loadyaml([yaml_file]) + expect(result).to(eq(nil)) + end + it "should convert YAML file to a data structure" do yaml_file = tmpfilename ('yamlfile') File.open(yaml_file, 'w') do |fh| -- cgit v1.2.3 From 5382ca0176f9638aa9acdfc22cf68ba233b77f57 Mon Sep 17 00:00:00 2001 From: Hunter Haugen Date: Tue, 14 Apr 2015 11:39:22 -0700 Subject: Prep for 4.6.0 --- CHANGELOG.md | 29 ++++++++++++++++++++++------- metadata.json | 2 +- 2 files changed, 23 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1385695..0f4c9e4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,17 +1,32 @@ ##2015-01-14 - Supported Release 4.6.0 ###Summary -Improved functionality and preparing for Puppet Next with new parser +Adds functions and function argument abilities, and improves compatibility with the new puppet parser ####Features -- MODULES-444: concat can now take more than two arrays -- basename function added to have Ruby File.basename functionality -- delete function can now take an array of items to remove -- MODULES-1473: deprecate type function in favor of type_of +- MODULES-444: `concat()` can now take more than two arrays +- `basename()` added to have Ruby File.basename functionality +- `delete()` can now take an array of items to remove +- `prefix()` can now take a hash +- `upcase()` can now take a hash or array of upcaseable things +- `validate_absolute_path()` can now take an array +- `validate_cmd()` can now use % in the command to embed the validation file argument in the string +- MODULES-1473: deprecate `type()` function in favor of `type3x()` +- MODULES-1473: Add `type_of()` to give better time information on future parser +- Deprecate `private()` for `assert_private()` due to future parser +- Adds `ceiling()` to take the ceiling of a number +- Adds `fqdn_rand_string()` to generate random string based on fqdn +- Adds `pw_hash()` to generate password hashes +- Adds `validate_integer()` +- Adds `validate_numeric()` (like `validate_integer()` but also accepts floats) ####Bugfixes -- Several test case fixes -- Ensure_resource is more verbose on debug mode +- Fix seeding of `fqdn_rotate()` +- `ensure_resource()` is more verbose on debug mode +- Stricter argument checking for `dirname()` +- Fix `is_domain_name()` to better match RFC +- Fix `uriescape()` when called with array +- Fix `file_line` resource when using the `after` attribute with `match` ##2015-01-14 - Supported Release 4.5.1 ###Summary diff --git a/metadata.json b/metadata.json index 27def9c..51b73f7 100644 --- a/metadata.json +++ b/metadata.json @@ -1,6 +1,6 @@ { "name": "puppetlabs-stdlib", - "version": "4.5.1", + "version": "4.6.0", "author": "puppetlabs", "summary": "Standard library of resources for Puppet modules.", "license": "Apache-2.0", -- cgit v1.2.3 From ba4033ed253507a922ae7a927cd70d3967d34b98 Mon Sep 17 00:00:00 2001 From: Hunter Haugen Date: Tue, 14 Apr 2015 15:24:50 -0700 Subject: Fix the 4.6.0 release date --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0f4c9e4..c17e750 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,4 @@ -##2015-01-14 - Supported Release 4.6.0 +##2015-04-14 - Supported Release 4.6.0 ###Summary Adds functions and function argument abilities, and improves compatibility with the new puppet parser -- cgit v1.2.3 From c27513463d9b0a59cda1287273621fc4e158a486 Mon Sep 17 00:00:00 2001 From: David Schmitt Date: Fri, 17 Apr 2015 14:24:40 -0700 Subject: fqdn_rand_string: fix argument error message --- lib/puppet/parser/functions/fqdn_rand_string.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/puppet/parser/functions/fqdn_rand_string.rb b/lib/puppet/parser/functions/fqdn_rand_string.rb index 785c9fd..2bb1287 100644 --- a/lib/puppet/parser/functions/fqdn_rand_string.rb +++ b/lib/puppet/parser/functions/fqdn_rand_string.rb @@ -15,8 +15,8 @@ Puppet::Parser::Functions::newfunction( `undef` or an empty string.") do |args| raise(ArgumentError, "fqdn_rand_string(): wrong number of arguments (0 for 1)") if args.size == 0 Puppet::Parser::Functions.function('is_integer') - raise(ArgumentError, "fqdn_rand_base64(): first argument must be a positive integer") unless function_is_integer([args[0]]) and args[0].to_i > 0 - raise(ArgumentError, "fqdn_rand_base64(): second argument must be undef or a string") unless args[1].nil? or args[1].is_a? String + raise(ArgumentError, "fqdn_rand_string(): first argument must be a positive integer") unless function_is_integer([args[0]]) and args[0].to_i > 0 + raise(ArgumentError, "fqdn_rand_string(): second argument must be undef or a string") unless args[1].nil? or args[1].is_a? String Puppet::Parser::Functions.function('fqdn_rand') -- cgit v1.2.3 From cf499315c1cc693679e4b1c1609d989d32451b94 Mon Sep 17 00:00:00 2001 From: Chris Barker Date: Mon, 20 Apr 2015 10:06:00 -0700 Subject: uses include type class declaration previous behavior used class { 'stdlib::stages':} which isn't singleton and could cause duplication resource declaration on the stages class. Since many community modules work by calling 'include stdlib' we should make stdlib's include of stages singleton as well. --- manifests/init.pp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/manifests/init.pp b/manifests/init.pp index 500ad77..87ea975 100644 --- a/manifests/init.pp +++ b/manifests/init.pp @@ -14,7 +14,5 @@ # Requires: nothing # class stdlib { - - class { 'stdlib::stages': } - + include stdlib::stages } -- cgit v1.2.3 From b664fec30f8b7d8a4dd8621d8064df9b9789169b Mon Sep 17 00:00:00 2001 From: David Schmitt Date: Thu, 23 Apr 2015 16:37:01 -0700 Subject: specs: loosen certain error expectations to make tests pass on future parser --- spec/functions/validate_integer_spec.rb | 6 +++--- spec/functions/validate_ipv4_address_spec.rb | 4 +--- spec/functions/validate_ipv6_address_spec.rb | 4 +--- spec/functions/validate_numeric_spec.rb | 6 +++--- 4 files changed, 8 insertions(+), 12 deletions(-) diff --git a/spec/functions/validate_integer_spec.rb b/spec/functions/validate_integer_spec.rb index dff3415..3865c4f 100755 --- a/spec/functions/validate_integer_spec.rb +++ b/spec/functions/validate_integer_spec.rb @@ -43,7 +43,7 @@ describe Puppet::Parser::Functions.function(:validate_integer) do it "should not compile when #{the_number} is a bare word" do Puppet[:code] = "validate_integer(#{the_number})" - expect { scope.compiler.compile }.to raise_error(Puppet::ParseError, /to be an Integer/) + expect { scope.compiler.compile }.to raise_error end end @@ -117,7 +117,7 @@ describe Puppet::Parser::Functions.function(:validate_integer) do it "should not compile when a non-Integer maximum #{the_max} bare word is passed" do Puppet[:code] = "validate_integer(1,#{the_max})" - expect { scope.compiler.compile }.to raise_error(Puppet::ParseError, /to be unset or an Integer/) + expect { scope.compiler.compile }.to raise_error end end @@ -212,7 +212,7 @@ describe Puppet::Parser::Functions.function(:validate_integer) do it "should not compile when a non-Integer minimum #{the_min} bare word is passed" do Puppet[:code] = "validate_integer(1,#{max},#{the_min})" - expect { scope.compiler.compile }.to raise_error(Puppet::ParseError, /to be unset or an Integer/) + expect { scope.compiler.compile }.to raise_error end end end diff --git a/spec/functions/validate_ipv4_address_spec.rb b/spec/functions/validate_ipv4_address_spec.rb index 45401a4..27ea4fe 100755 --- a/spec/functions/validate_ipv4_address_spec.rb +++ b/spec/functions/validate_ipv4_address_spec.rb @@ -39,9 +39,7 @@ describe Puppet::Parser::Functions.function(:validate_ipv4_address) do describe "when given numbers" do it "should not compile" do Puppet[:code] = "validate_ipv4_address(1, 2)" - expect { - scope.compiler.compile - }.to raise_error(Puppet::ParseError, /is not a valid IPv4 address/) + expect { scope.compiler.compile }.to raise_error end end diff --git a/spec/functions/validate_ipv6_address_spec.rb b/spec/functions/validate_ipv6_address_spec.rb index a839d90..e87b372 100755 --- a/spec/functions/validate_ipv6_address_spec.rb +++ b/spec/functions/validate_ipv6_address_spec.rb @@ -41,9 +41,7 @@ describe Puppet::Parser::Functions.function(:validate_ipv6_address) do describe "when given numbers" do it "should not compile" do Puppet[:code] = "validate_ipv6_address(1, 2)" - expect { - scope.compiler.compile - }.to raise_error(Puppet::ParseError, /not a valid IPv6 address/) + expect { scope.compiler.compile }.to raise_error end end end diff --git a/spec/functions/validate_numeric_spec.rb b/spec/functions/validate_numeric_spec.rb index c8b0e4d..1623a3d 100755 --- a/spec/functions/validate_numeric_spec.rb +++ b/spec/functions/validate_numeric_spec.rb @@ -43,7 +43,7 @@ describe Puppet::Parser::Functions.function(:validate_numeric) do it "should not compile when #{the_number} is a bare word" do Puppet[:code] = "validate_numeric(#{the_number})" - expect { scope.compiler.compile }.to raise_error(Puppet::ParseError, /to be a Numeric/) + expect { scope.compiler.compile }.to raise_error end end @@ -115,7 +115,7 @@ describe Puppet::Parser::Functions.function(:validate_numeric) do it "should not compile when a non-Numeric maximum #{the_max} bare word is passed" do Puppet[:code] = "validate_numeric(1,#{the_max})" - expect { scope.compiler.compile }.to raise_error(Puppet::ParseError, /to be unset or a Numeric/) + expect { scope.compiler.compile }.to raise_error end end @@ -210,7 +210,7 @@ describe Puppet::Parser::Functions.function(:validate_numeric) do it "should not compile when a non-Numeric minimum #{the_min} bare word is passed" do Puppet[:code] = "validate_numeric(1,#{max},#{the_min})" - expect { scope.compiler.compile }.to raise_error(Puppet::ParseError, /to be unset or a Numeric/) + expect { scope.compiler.compile }.to raise_error end end end -- cgit v1.2.3 From a3016c45c5aaa979c9d148eb88bb3f7d1369a507 Mon Sep 17 00:00:00 2001 From: David Schmitt Date: Wed, 15 Apr 2015 16:55:28 -0700 Subject: specs: move function specs to where rspec-puppet expects them --- spec/functions/basename_spec.rb | 46 ++++++++++++++++++++++ spec/functions/bool2str_spec.rb | 46 ++++++++++++++++++++++ spec/functions/camelcase_spec.rb | 24 +++++++++++ spec/functions/type_of_spec.rb | 33 ++++++++++++++++ spec/unit/puppet/functions/type_of_spec.rb | 33 ---------------- spec/unit/puppet/parser/functions/basename_spec.rb | 46 ---------------------- spec/unit/puppet/parser/functions/bool2str_spec.rb | 46 ---------------------- .../unit/puppet/parser/functions/camelcase_spec.rb | 24 ----------- 8 files changed, 149 insertions(+), 149 deletions(-) create mode 100755 spec/functions/basename_spec.rb create mode 100755 spec/functions/bool2str_spec.rb create mode 100755 spec/functions/camelcase_spec.rb create mode 100644 spec/functions/type_of_spec.rb delete mode 100644 spec/unit/puppet/functions/type_of_spec.rb delete mode 100755 spec/unit/puppet/parser/functions/basename_spec.rb delete mode 100755 spec/unit/puppet/parser/functions/bool2str_spec.rb delete mode 100755 spec/unit/puppet/parser/functions/camelcase_spec.rb diff --git a/spec/functions/basename_spec.rb b/spec/functions/basename_spec.rb new file mode 100755 index 0000000..8a2d0dc --- /dev/null +++ b/spec/functions/basename_spec.rb @@ -0,0 +1,46 @@ +#! /usr/bin/env ruby -S rspec +require 'spec_helper' + +describe "the basename function" do + let(:scope) { PuppetlabsSpec::PuppetInternals.scope } + + it "should exist" do + Puppet::Parser::Functions.function("basename").should == "function_basename" + end + + it "should raise a ParseError if there is less than 1 argument" do + lambda { scope.function_basename([]) }.should( raise_error(Puppet::ParseError)) + end + + it "should raise a ParseError if there are more than 2 arguments" do + lambda { scope.function_basename(['a', 'b', 'c']) }.should( raise_error(Puppet::ParseError)) + end + + it "should return basename for an absolute path" do + result = scope.function_basename(['/path/to/a/file.ext']) + result.should(eq('file.ext')) + end + + it "should return basename for a relative path" do + result = scope.function_basename(['path/to/a/file.ext']) + result.should(eq('file.ext')) + end + + it "should strip extention when extension specified (absolute path)" do + result = scope.function_basename(['/path/to/a/file.ext', '.ext']) + result.should(eq('file')) + end + + it "should strip extention when extension specified (relative path)" do + result = scope.function_basename(['path/to/a/file.ext', '.ext']) + result.should(eq('file')) + end + + it "should complain about non-string first argument" do + lambda { scope.function_basename([[]]) }.should( raise_error(Puppet::ParseError)) + end + + it "should complain about non-string second argument" do + lambda { scope.function_basename(['/path/to/a/file.ext', []]) }.should( raise_error(Puppet::ParseError)) + end +end diff --git a/spec/functions/bool2str_spec.rb b/spec/functions/bool2str_spec.rb new file mode 100755 index 0000000..b878891 --- /dev/null +++ b/spec/functions/bool2str_spec.rb @@ -0,0 +1,46 @@ +#! /usr/bin/env ruby -S rspec +require 'spec_helper' + +describe "the bool2str function" do + let(:scope) { PuppetlabsSpec::PuppetInternals.scope } + + it "should exist" do + expect(Puppet::Parser::Functions.function("bool2str")).to eq("function_bool2str") + end + + it "should raise a ParseError if there is less than 1 arguments" do + expect { scope.function_bool2str([]) }.to( raise_error(Puppet::ParseError)) + end + + it "should convert true to 'true'" do + result = scope.function_bool2str([true]) + expect(result).to(eq('true')) + end + + it "should convert true to a string" do + result = scope.function_bool2str([true]) + expect(result.class).to(eq(String)) + end + + it "should convert false to 'false'" do + result = scope.function_bool2str([false]) + expect(result).to(eq('false')) + end + + it "should convert false to a string" do + result = scope.function_bool2str([false]) + expect(result.class).to(eq(String)) + end + + it "should not accept a string" do + expect { scope.function_bool2str(["false"]) }.to( raise_error(Puppet::ParseError)) + end + + it "should not accept a nil value" do + expect { scope.function_bool2str([nil]) }.to( raise_error(Puppet::ParseError)) + end + + it "should not accept an undef" do + expect { scope.function_bool2str([:undef]) }.to( raise_error(Puppet::ParseError)) + end +end diff --git a/spec/functions/camelcase_spec.rb b/spec/functions/camelcase_spec.rb new file mode 100755 index 0000000..70382ad --- /dev/null +++ b/spec/functions/camelcase_spec.rb @@ -0,0 +1,24 @@ +#! /usr/bin/env ruby -S rspec +require 'spec_helper' + +describe "the camelcase function" do + let(:scope) { PuppetlabsSpec::PuppetInternals.scope } + + it "should exist" do + expect(Puppet::Parser::Functions.function("camelcase")).to eq("function_camelcase") + end + + it "should raise a ParseError if there is less than 1 arguments" do + expect { scope.function_camelcase([]) }.to( raise_error(Puppet::ParseError)) + end + + it "should capitalize the beginning of a normal string" do + result = scope.function_camelcase(["abc"]) + expect(result).to(eq("Abc")) + end + + it "should camelcase an underscore-delimited string" do + result = scope.function_camelcase(["aa_bb_cc"]) + expect(result).to(eq("AaBbCc")) + end +end diff --git a/spec/functions/type_of_spec.rb b/spec/functions/type_of_spec.rb new file mode 100644 index 0000000..8afb624 --- /dev/null +++ b/spec/functions/type_of_spec.rb @@ -0,0 +1,33 @@ +#! /usr/bin/env ruby -S rspec + +require 'spec_helper' + +if ENV["FUTURE_PARSER"] == 'yes' or Puppet.version >= "4" + require 'puppet/pops' + require 'puppet/loaders' + + describe 'the type_of function' do + before(:all) do + loaders = Puppet::Pops::Loaders.new(Puppet::Node::Environment.create(:testing, [File.join(fixtures, "modules")])) + Puppet.push_context({:loaders => loaders}, "test-examples") + end + + after(:all) do + Puppet::Pops::Loaders.clear + Puppet::pop_context() + end + + let(:func) do + # Load the function from the environment modulepath's modules (ie, fixtures) + Puppet.lookup(:loaders).private_environment_loader.load(:function, 'type_of') + end + + it 'gives the type of a string' do + expect(func.call({}, 'hello world')).to be_kind_of(Puppet::Pops::Types::PStringType) + end + + it 'gives the type of an integer' do + expect(func.call({}, 5)).to be_kind_of(Puppet::Pops::Types::PIntegerType) + end + end +end diff --git a/spec/unit/puppet/functions/type_of_spec.rb b/spec/unit/puppet/functions/type_of_spec.rb deleted file mode 100644 index 8afb624..0000000 --- a/spec/unit/puppet/functions/type_of_spec.rb +++ /dev/null @@ -1,33 +0,0 @@ -#! /usr/bin/env ruby -S rspec - -require 'spec_helper' - -if ENV["FUTURE_PARSER"] == 'yes' or Puppet.version >= "4" - require 'puppet/pops' - require 'puppet/loaders' - - describe 'the type_of function' do - before(:all) do - loaders = Puppet::Pops::Loaders.new(Puppet::Node::Environment.create(:testing, [File.join(fixtures, "modules")])) - Puppet.push_context({:loaders => loaders}, "test-examples") - end - - after(:all) do - Puppet::Pops::Loaders.clear - Puppet::pop_context() - end - - let(:func) do - # Load the function from the environment modulepath's modules (ie, fixtures) - Puppet.lookup(:loaders).private_environment_loader.load(:function, 'type_of') - end - - it 'gives the type of a string' do - expect(func.call({}, 'hello world')).to be_kind_of(Puppet::Pops::Types::PStringType) - end - - it 'gives the type of an integer' do - expect(func.call({}, 5)).to be_kind_of(Puppet::Pops::Types::PIntegerType) - end - end -end diff --git a/spec/unit/puppet/parser/functions/basename_spec.rb b/spec/unit/puppet/parser/functions/basename_spec.rb deleted file mode 100755 index 8a2d0dc..0000000 --- a/spec/unit/puppet/parser/functions/basename_spec.rb +++ /dev/null @@ -1,46 +0,0 @@ -#! /usr/bin/env ruby -S rspec -require 'spec_helper' - -describe "the basename function" do - let(:scope) { PuppetlabsSpec::PuppetInternals.scope } - - it "should exist" do - Puppet::Parser::Functions.function("basename").should == "function_basename" - end - - it "should raise a ParseError if there is less than 1 argument" do - lambda { scope.function_basename([]) }.should( raise_error(Puppet::ParseError)) - end - - it "should raise a ParseError if there are more than 2 arguments" do - lambda { scope.function_basename(['a', 'b', 'c']) }.should( raise_error(Puppet::ParseError)) - end - - it "should return basename for an absolute path" do - result = scope.function_basename(['/path/to/a/file.ext']) - result.should(eq('file.ext')) - end - - it "should return basename for a relative path" do - result = scope.function_basename(['path/to/a/file.ext']) - result.should(eq('file.ext')) - end - - it "should strip extention when extension specified (absolute path)" do - result = scope.function_basename(['/path/to/a/file.ext', '.ext']) - result.should(eq('file')) - end - - it "should strip extention when extension specified (relative path)" do - result = scope.function_basename(['path/to/a/file.ext', '.ext']) - result.should(eq('file')) - end - - it "should complain about non-string first argument" do - lambda { scope.function_basename([[]]) }.should( raise_error(Puppet::ParseError)) - end - - it "should complain about non-string second argument" do - lambda { scope.function_basename(['/path/to/a/file.ext', []]) }.should( raise_error(Puppet::ParseError)) - end -end diff --git a/spec/unit/puppet/parser/functions/bool2str_spec.rb b/spec/unit/puppet/parser/functions/bool2str_spec.rb deleted file mode 100755 index b878891..0000000 --- a/spec/unit/puppet/parser/functions/bool2str_spec.rb +++ /dev/null @@ -1,46 +0,0 @@ -#! /usr/bin/env ruby -S rspec -require 'spec_helper' - -describe "the bool2str function" do - let(:scope) { PuppetlabsSpec::PuppetInternals.scope } - - it "should exist" do - expect(Puppet::Parser::Functions.function("bool2str")).to eq("function_bool2str") - end - - it "should raise a ParseError if there is less than 1 arguments" do - expect { scope.function_bool2str([]) }.to( raise_error(Puppet::ParseError)) - end - - it "should convert true to 'true'" do - result = scope.function_bool2str([true]) - expect(result).to(eq('true')) - end - - it "should convert true to a string" do - result = scope.function_bool2str([true]) - expect(result.class).to(eq(String)) - end - - it "should convert false to 'false'" do - result = scope.function_bool2str([false]) - expect(result).to(eq('false')) - end - - it "should convert false to a string" do - result = scope.function_bool2str([false]) - expect(result.class).to(eq(String)) - end - - it "should not accept a string" do - expect { scope.function_bool2str(["false"]) }.to( raise_error(Puppet::ParseError)) - end - - it "should not accept a nil value" do - expect { scope.function_bool2str([nil]) }.to( raise_error(Puppet::ParseError)) - end - - it "should not accept an undef" do - expect { scope.function_bool2str([:undef]) }.to( raise_error(Puppet::ParseError)) - end -end diff --git a/spec/unit/puppet/parser/functions/camelcase_spec.rb b/spec/unit/puppet/parser/functions/camelcase_spec.rb deleted file mode 100755 index 70382ad..0000000 --- a/spec/unit/puppet/parser/functions/camelcase_spec.rb +++ /dev/null @@ -1,24 +0,0 @@ -#! /usr/bin/env ruby -S rspec -require 'spec_helper' - -describe "the camelcase function" do - let(:scope) { PuppetlabsSpec::PuppetInternals.scope } - - it "should exist" do - expect(Puppet::Parser::Functions.function("camelcase")).to eq("function_camelcase") - end - - it "should raise a ParseError if there is less than 1 arguments" do - expect { scope.function_camelcase([]) }.to( raise_error(Puppet::ParseError)) - end - - it "should capitalize the beginning of a normal string" do - result = scope.function_camelcase(["abc"]) - expect(result).to(eq("Abc")) - end - - it "should camelcase an underscore-delimited string" do - result = scope.function_camelcase(["aa_bb_cc"]) - expect(result).to(eq("AaBbCc")) - end -end -- cgit v1.2.3 From c0cf14e77405ba3a0b7ae471d1ee1c249c7d4da8 Mon Sep 17 00:00:00 2001 From: David Schmitt Date: Thu, 9 Apr 2015 15:56:43 +0100 Subject: spec_helper_acceptance: fix FUTURE_PARSER usage Use the more common "yes", instead of "true" to detect FUTURE_PARSER. --- spec/spec_helper_acceptance.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/spec_helper_acceptance.rb b/spec/spec_helper_acceptance.rb index 3203ce9..79b1390 100755 --- a/spec/spec_helper_acceptance.rb +++ b/spec/spec_helper_acceptance.rb @@ -33,7 +33,7 @@ RSpec.configure do |c| # Configure all nodes in nodeset c.before :suite do - if ENV['FUTURE_PARSER'] == 'true' + if ENV['FUTURE_PARSER'] == 'yes' default[:default_apply_opts] ||= {} default[:default_apply_opts].merge!({:parser => 'future'}) end -- cgit v1.2.3 From 29f09e2181a56ec801b39e56bd28119709495dd9 Mon Sep 17 00:00:00 2001 From: David Schmitt Date: Wed, 15 Apr 2015 16:46:09 -0700 Subject: spec_helper: set parser config if requested --- spec/lib/puppet_spec/compiler.rb | 1 + spec/spec_helper.rb | 2 ++ 2 files changed, 3 insertions(+) diff --git a/spec/lib/puppet_spec/compiler.rb b/spec/lib/puppet_spec/compiler.rb index 2f0ae4d..1f322ca 100755 --- a/spec/lib/puppet_spec/compiler.rb +++ b/spec/lib/puppet_spec/compiler.rb @@ -2,6 +2,7 @@ module PuppetSpec::Compiler def compile_to_catalog(string, node = Puppet::Node.new('foonode')) Puppet[:code] = string + Puppet[:parser] = 'future' if ENV['FUTURE_PARSER'] == 'yes' Puppet::Parser::Compiler.compile(node) end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index b490ca3..13014ab 100755 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -30,5 +30,7 @@ RSpec.configure do |config| Facter::Util::Loader.any_instance.stubs(:load_all) Facter.clear Facter.clear_messages + + Puppet[:parser] = 'future' if ENV['FUTURE_PARSER'] == 'yes' end end -- cgit v1.2.3 From 24680aceec28df9e6dbe8c07a1136bfb78cad2fa Mon Sep 17 00:00:00 2001 From: David Schmitt Date: Tue, 5 May 2015 13:30:54 +0100 Subject: spec_helper: use proper mocha import to avoid warning --- Gemfile | 1 + spec/spec_helper.rb | 4 +--- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/Gemfile b/Gemfile index 2d19594..82a5204 100644 --- a/Gemfile +++ b/Gemfile @@ -14,6 +14,7 @@ group :development, :unit_tests do gem 'rake', '~> 10.1.0', :require => false gem 'rspec', '~> 3.1.0', :require => false gem 'rspec-puppet', :require => false + gem 'mocha', :require => false gem 'puppetlabs_spec_helper', :require => false gem 'puppet-lint', :require => false gem 'pry', :require => false diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 13014ab..d3c9847 100755 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -17,9 +17,7 @@ require 'puppet_spec/fixtures' require 'puppet_spec/matchers' require 'puppet_spec/database' require 'monkey_patches/alias_should_to_must' -require 'mocha/setup' - - +require 'mocha/api' RSpec.configure do |config| config.before :each do -- cgit v1.2.3 From 6a0a6153d59715d07f6bc50135df4adbae3d1334 Mon Sep 17 00:00:00 2001 From: David Schmitt Date: Tue, 5 May 2015 10:53:04 +0100 Subject: spec_helper: Remove unneccesary stubbing This only roots all Facter instances into memory, while something already creates a new Facter instance each run. --- spec/spec_helper.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index d3c9847..896cb83 100755 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -25,7 +25,6 @@ RSpec.configure do |config| # test cases. This requires each example group to explicitly load the # facts being exercised with something like # Facter.collection.loader.load(:ipaddress) - Facter::Util::Loader.any_instance.stubs(:load_all) Facter.clear Facter.clear_messages -- cgit v1.2.3 From 9bae8356fded9d1c7aaea96cba246709bfe1a516 Mon Sep 17 00:00:00 2001 From: David Schmitt Date: Wed, 22 Apr 2015 16:04:00 -0700 Subject: pw_hash: avoid ruby magic when running on java --- lib/puppet/parser/functions/pw_hash.rb | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/lib/puppet/parser/functions/pw_hash.rb b/lib/puppet/parser/functions/pw_hash.rb index ad3e393..4682a63 100644 --- a/lib/puppet/parser/functions/pw_hash.rb +++ b/lib/puppet/parser/functions/pw_hash.rb @@ -42,15 +42,13 @@ Puppet::Parser::Functions::newfunction( if 'test'.crypt('$1$1') != '$1$1$Bp8CU9Oujr9SSEw53WV6G.' # JRuby < 1.7.17 if RUBY_PLATFORM == 'java' - # override String#crypt for password variable - def password.crypt(salt) - # puppetserver bundles Apache Commons Codec - org.apache.commons.codec.digest.Crypt.crypt(self.to_java_bytes, salt) - end + # puppetserver bundles Apache Commons Codec + org.apache.commons.codec.digest.Crypt.crypt(password.to_java_bytes, salt) else # MS Windows and other systems that don't support enhanced salts raise Puppet::ParseError, 'system does not support enhanced salts' end + else + password.crypt("$#{hash_type}$#{args[2]}") end - password.crypt("$#{hash_type}$#{args[2]}") end -- cgit v1.2.3 From 063c58a992c1b5441b7e7b2a2e4886531035bb25 Mon Sep 17 00:00:00 2001 From: David Schmitt Date: Wed, 22 Apr 2015 16:21:21 -0700 Subject: range: remove dead code Since a ParseError is always thrown for zero arguments, the if and all dependent code can be removed. --- lib/puppet/parser/functions/range.rb | 36 ++++++------------------------------ 1 file changed, 6 insertions(+), 30 deletions(-) diff --git a/lib/puppet/parser/functions/range.rb b/lib/puppet/parser/functions/range.rb index 49fba21..16d189f 100644 --- a/lib/puppet/parser/functions/range.rb +++ b/lib/puppet/parser/functions/range.rb @@ -41,29 +41,9 @@ Will return: [0,2,4,6,8] raise(Puppet::ParseError, "range(): Wrong number of " + "arguments given (#{arguments.size} for 1)") if arguments.size < 1 - if arguments.size > 1 - start = arguments[0] - stop = arguments[1] - step = arguments[2].nil? ? 1 : arguments[2].to_i.abs - - type = '..' # We select simplest type for Range available in Ruby ... - - elsif arguments.size > 0 - value = arguments[0] - - if m = value.match(/^(\w+)(\.\.\.?|\-)(\w+)$/) - start = m[1] - stop = m[3] - - type = m[2] - - elsif value.match(/^.+$/) - raise(Puppet::ParseError, 'range(): Unable to compute range ' + - 'from the value given') - else - raise(Puppet::ParseError, 'range(): Unknown format of range given') - end - end + start = arguments[0] + stop = arguments[1] + step = arguments[2].nil? ? 1 : arguments[2].to_i.abs # Check whether we have integer value if so then make it so ... if start.to_s.match(/^\d+$/) @@ -74,14 +54,10 @@ Will return: [0,2,4,6,8] stop = stop.to_s end - range = case type - when /^(\.\.|\-)$/ then (start .. stop) - when /^(\.\.\.)$/ then (start ... stop) # Exclusive of last element ... - end - - result = range.step(step).collect { |i| i } # Get them all ... Pokemon ... + # We select simplest type for Range available in Ruby ... + range = (start .. stop) - return result + range.step(step).collect { |i| i } # Get them all ... Pokemon ... end end -- cgit v1.2.3 From d4f3d57f1678ae03a58a17181f863c44c248f09b Mon Sep 17 00:00:00 2001 From: David Schmitt Date: Wed, 29 Apr 2015 12:13:08 +0100 Subject: validate_augeas: fix URL to docs --- lib/puppet/parser/functions/validate_augeas.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/puppet/parser/functions/validate_augeas.rb b/lib/puppet/parser/functions/validate_augeas.rb index 4ea4fe0..2196c3e 100644 --- a/lib/puppet/parser/functions/validate_augeas.rb +++ b/lib/puppet/parser/functions/validate_augeas.rb @@ -31,7 +31,7 @@ module Puppet::Parser::Functions ENDHEREDOC unless Puppet.features.augeas? - raise Puppet::ParseError, ("validate_augeas(): this function requires the augeas feature. See http://projects.puppetlabs.com/projects/puppet/wiki/Puppet_Augeas#Pre-requisites for how to activate it.") + raise Puppet::ParseError, ("validate_augeas(): this function requires the augeas feature. See http://docs.puppetlabs.com/guides/augeas.html#pre-requisites for how to activate it.") end if (args.length < 2) or (args.length > 4) then -- cgit v1.2.3 From 7d7e905b543448f5d37d13c9e1a03d1e0be307fe Mon Sep 17 00:00:00 2001 From: Eli Young Date: Tue, 5 May 2015 15:16:35 -0700 Subject: pw_hash: Fix functionality on JRuby < 1.7.17 The previous change to this function broke it on JRuby before 1.7.17 by attempting to use a variable that wasn't defined (`salt`). To fix this, define `salt` ahead of time and use that instead of building the salt later. cf. https://github.com/puppetlabs/puppetlabs-stdlib/pull/443#discussion_r29718588 --- lib/puppet/parser/functions/pw_hash.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/puppet/parser/functions/pw_hash.rb b/lib/puppet/parser/functions/pw_hash.rb index 4682a63..41d4223 100644 --- a/lib/puppet/parser/functions/pw_hash.rb +++ b/lib/puppet/parser/functions/pw_hash.rb @@ -38,6 +38,8 @@ Puppet::Parser::Functions::newfunction( password = args[0] return nil if password.nil? or password.empty? + salt = "$#{hash_type}$#{args[2]}" + # handle weak implementations of String#crypt if 'test'.crypt('$1$1') != '$1$1$Bp8CU9Oujr9SSEw53WV6G.' # JRuby < 1.7.17 @@ -49,6 +51,6 @@ Puppet::Parser::Functions::newfunction( raise Puppet::ParseError, 'system does not support enhanced salts' end else - password.crypt("$#{hash_type}$#{args[2]}") + password.crypt(salt) end end -- cgit v1.2.3 From 8cf011d7a27d696ebfac728cafc4f26e6d009fdd Mon Sep 17 00:00:00 2001 From: Eli Young Date: Tue, 5 May 2015 15:44:08 -0700 Subject: Revert "range: remove dead code" This reverts commit 063c58a992c1b5441b7e7b2a2e4886531035bb25, which actually removed non-dead code. Specifically, it removed the ability to make calls such as `range('2..3')`, `range('2...3')`, and `range('2-3')`. cf. https://github.com/puppetlabs/puppetlabs-stdlib/pull/443#commitcomment-11055565 --- lib/puppet/parser/functions/range.rb | 36 ++++++++++++++++++++++++++++++------ 1 file changed, 30 insertions(+), 6 deletions(-) diff --git a/lib/puppet/parser/functions/range.rb b/lib/puppet/parser/functions/range.rb index 16d189f..49fba21 100644 --- a/lib/puppet/parser/functions/range.rb +++ b/lib/puppet/parser/functions/range.rb @@ -41,9 +41,29 @@ Will return: [0,2,4,6,8] raise(Puppet::ParseError, "range(): Wrong number of " + "arguments given (#{arguments.size} for 1)") if arguments.size < 1 - start = arguments[0] - stop = arguments[1] - step = arguments[2].nil? ? 1 : arguments[2].to_i.abs + if arguments.size > 1 + start = arguments[0] + stop = arguments[1] + step = arguments[2].nil? ? 1 : arguments[2].to_i.abs + + type = '..' # We select simplest type for Range available in Ruby ... + + elsif arguments.size > 0 + value = arguments[0] + + if m = value.match(/^(\w+)(\.\.\.?|\-)(\w+)$/) + start = m[1] + stop = m[3] + + type = m[2] + + elsif value.match(/^.+$/) + raise(Puppet::ParseError, 'range(): Unable to compute range ' + + 'from the value given') + else + raise(Puppet::ParseError, 'range(): Unknown format of range given') + end + end # Check whether we have integer value if so then make it so ... if start.to_s.match(/^\d+$/) @@ -54,10 +74,14 @@ Will return: [0,2,4,6,8] stop = stop.to_s end - # We select simplest type for Range available in Ruby ... - range = (start .. stop) + range = case type + when /^(\.\.|\-)$/ then (start .. stop) + when /^(\.\.\.)$/ then (start ... stop) # Exclusive of last element ... + end + + result = range.step(step).collect { |i| i } # Get them all ... Pokemon ... - range.step(step).collect { |i| i } # Get them all ... Pokemon ... + return result end end -- cgit v1.2.3 From 25ed4b43c41324902e50d21eb98b5fa0db511b96 Mon Sep 17 00:00:00 2001 From: Eli Young Date: Tue, 5 May 2015 15:52:31 -0700 Subject: range: Clean up and clarify function contents --- lib/puppet/parser/functions/range.rb | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/lib/puppet/parser/functions/range.rb b/lib/puppet/parser/functions/range.rb index 49fba21..c14f6e6 100644 --- a/lib/puppet/parser/functions/range.rb +++ b/lib/puppet/parser/functions/range.rb @@ -37,18 +37,17 @@ Will return: [0,2,4,6,8] EOS ) do |arguments| - # We support more than one argument but at least one is mandatory ... - raise(Puppet::ParseError, "range(): Wrong number of " + - "arguments given (#{arguments.size} for 1)") if arguments.size < 1 + raise(Puppet::ParseError, 'range(): Wrong number of ' + + 'arguments given (0 for 1)') if arguments.size == 0 if arguments.size > 1 start = arguments[0] stop = arguments[1] step = arguments[2].nil? ? 1 : arguments[2].to_i.abs - type = '..' # We select simplest type for Range available in Ruby ... + type = '..' # Use the simplest type of Range available in Ruby - elsif arguments.size > 0 + else # arguments.size == 0 value = arguments[0] if m = value.match(/^(\w+)(\.\.\.?|\-)(\w+)$/) @@ -58,14 +57,14 @@ Will return: [0,2,4,6,8] type = m[2] elsif value.match(/^.+$/) - raise(Puppet::ParseError, 'range(): Unable to compute range ' + - 'from the value given') + raise(Puppet::ParseError, "range(): Unable to compute range " + + "from the value: #{value}") else - raise(Puppet::ParseError, 'range(): Unknown format of range given') + raise(Puppet::ParseError, "range(): Unknown range format: #{value}") end end - # Check whether we have integer value if so then make it so ... + # If we were given an integer, ensure we work with one if start.to_s.match(/^\d+$/) start = start.to_i stop = stop.to_i @@ -76,10 +75,10 @@ Will return: [0,2,4,6,8] range = case type when /^(\.\.|\-)$/ then (start .. stop) - when /^(\.\.\.)$/ then (start ... stop) # Exclusive of last element ... + when '...' then (start ... stop) # Exclusive of last element end - result = range.step(step).collect { |i| i } # Get them all ... Pokemon ... + result = range.step(step).collect { |i| i } return result end -- cgit v1.2.3 From f49eb6b8e20a8517916d984d1606daaabbba9a23 Mon Sep 17 00:00:00 2001 From: David Schmitt Date: Wed, 6 May 2015 10:13:27 +0100 Subject: range(): fix TypeError(can't convert nil into Integer) when using range syntax --- lib/puppet/parser/functions/range.rb | 6 +++--- spec/functions/range_spec.rb | 7 +++++++ 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/lib/puppet/parser/functions/range.rb b/lib/puppet/parser/functions/range.rb index c14f6e6..2fc2113 100644 --- a/lib/puppet/parser/functions/range.rb +++ b/lib/puppet/parser/functions/range.rb @@ -47,7 +47,7 @@ Will return: [0,2,4,6,8] type = '..' # Use the simplest type of Range available in Ruby - else # arguments.size == 0 + else # arguments.size == 1 value = arguments[0] if m = value.match(/^(\w+)(\.\.\.?|\-)(\w+)$/) @@ -55,7 +55,7 @@ Will return: [0,2,4,6,8] stop = m[3] type = m[2] - + step = 1 elsif value.match(/^.+$/) raise(Puppet::ParseError, "range(): Unable to compute range " + "from the value: #{value}") @@ -78,7 +78,7 @@ Will return: [0,2,4,6,8] when '...' then (start ... stop) # Exclusive of last element end - result = range.step(step).collect { |i| i } + result = range.step(step).to_a return result end diff --git a/spec/functions/range_spec.rb b/spec/functions/range_spec.rb index ef86f97..f18b89e 100755 --- a/spec/functions/range_spec.rb +++ b/spec/functions/range_spec.rb @@ -68,6 +68,13 @@ describe "the range function" do end end + describe 'with a ruby-like range' do + it "returns a number range" do + result = scope.function_range(["1..4"]) + expect(result).to eq [1,2,3,4] + end + end + describe 'with a numeric range' do it "returns a range of numbers" do expected = (1..10).to_a -- cgit v1.2.3 From ecd4f3e4dc12af9953473c6c89361f4b1dd85646 Mon Sep 17 00:00:00 2001 From: Morgan Haskel Date: Wed, 6 May 2015 14:10:40 -0700 Subject: sync via modulesync --- .travis.yml | 6 ------ 1 file changed, 6 deletions(-) diff --git a/.travis.yml b/.travis.yml index b29f7e7..58e62d9 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,18 +6,12 @@ script: "bundle exec rake validate && bundle exec rake lint && bundle exec rake matrix: fast_finish: true include: - - rvm: 1.9.3 - env: PUPPET_GEM_VERSION="~> 3.4.0" - rvm: 1.8.7 env: PUPPET_GEM_VERSION="~> 3.0" - rvm: 1.9.3 env: PUPPET_GEM_VERSION="~> 3.0" - - rvm: 1.9.3 - env: PUPPET_GEM_VERSION="~> 3.0" FUTURE_PARSER="yes" - rvm: 2.1.5 env: PUPPET_GEM_VERSION="~> 3.0" - - rvm: 2.1.5 - env: PUPPET_GEM_VERSION="~> 3.4.0" - rvm: 2.1.5 env: PUPPET_GEM_VERSION="~> 3.0" FUTURE_PARSER="yes" notifications: -- cgit v1.2.3 From 3b8ded184d6b6b5c2823018a231deee9dcd7df83 Mon Sep 17 00:00:00 2001 From: Eli Young Date: Mon, 11 May 2015 11:12:15 -0700 Subject: (FM-2130) Document new location of facts.d cache --- lib/facter/facter_dot_d.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/facter/facter_dot_d.rb b/lib/facter/facter_dot_d.rb index b058437..d85940d 100644 --- a/lib/facter/facter_dot_d.rb +++ b/lib/facter/facter_dot_d.rb @@ -8,7 +8,7 @@ # contains a cache TTL. For foo.sh store the ttl as just # a number in foo.sh.ttl # -# The cache is stored in /tmp/facts_cache.yaml as a mode +# The cache is stored in $libdir/facts_dot_d.cache as a mode # 600 file and will have the end result of not calling your # fact scripts more often than is needed -- cgit v1.2.3 From 732f7e8b3509197eb77586a01cf4e3a2e7cac9d2 Mon Sep 17 00:00:00 2001 From: Hunter Haugen Date: Tue, 12 May 2015 15:03:27 -0700 Subject: Remove all the pops stuff The rspec-puppet matchers don't allow to check the return types, but this is a pretty rare thing to need to do anyway, so probably not worth patching rspec-puppet --- spec/functions/type_of_spec.rb | 32 ++++++-------------------------- 1 file changed, 6 insertions(+), 26 deletions(-) diff --git a/spec/functions/type_of_spec.rb b/spec/functions/type_of_spec.rb index 8afb624..b823460 100644 --- a/spec/functions/type_of_spec.rb +++ b/spec/functions/type_of_spec.rb @@ -2,32 +2,12 @@ require 'spec_helper' -if ENV["FUTURE_PARSER"] == 'yes' or Puppet.version >= "4" - require 'puppet/pops' - require 'puppet/loaders' - - describe 'the type_of function' do - before(:all) do - loaders = Puppet::Pops::Loaders.new(Puppet::Node::Environment.create(:testing, [File.join(fixtures, "modules")])) - Puppet.push_context({:loaders => loaders}, "test-examples") - end - - after(:all) do - Puppet::Pops::Loaders.clear - Puppet::pop_context() - end - - let(:func) do - # Load the function from the environment modulepath's modules (ie, fixtures) - Puppet.lookup(:loaders).private_environment_loader.load(:function, 'type_of') - end - - it 'gives the type of a string' do - expect(func.call({}, 'hello world')).to be_kind_of(Puppet::Pops::Types::PStringType) - end +describe 'type_of', :if => Puppet.version.to_f >= 4.0 do + it 'gives the type of a string' do + expect(subject.call_function('type_of', 'hello world')).to be_kind_of(Puppet::Pops::Types::PStringType) + end - it 'gives the type of an integer' do - expect(func.call({}, 5)).to be_kind_of(Puppet::Pops::Types::PIntegerType) - end + it 'gives the type of an integer' do + expect(subject.call_function('type_of', 5)).to be_kind_of(Puppet::Pops::Types::PIntegerType) end end -- cgit v1.2.3 From 593f74ced794dd461f4483fc32eecba8ac2e1f5a Mon Sep 17 00:00:00 2001 From: Jorie Tappa Date: Mon, 4 May 2015 17:23:16 -0700 Subject: DOC-1504: README edits --- README.markdown | 654 +++++++++++++++++++++++++++----------------------------- 1 file changed, 319 insertions(+), 335 deletions(-) diff --git a/README.markdown b/README.markdown index 3889088..a7a2d3a 100644 --- a/README.markdown +++ b/README.markdown @@ -16,8 +16,7 @@ Adds a standard library of resources for Puppet modules. ##Module Description -This module provides a standard library of resources for the development of Puppet -modules. Puppet modules make heavy use of this standard library. The stdlib module adds the following resources to Puppet: +This module provides a standard library of resources for the development of Puppet modules. Puppet modules make heavy use of this standard library. The stdlib module adds the following resources to Puppet: * Stages * Facts @@ -38,23 +37,11 @@ After you've installed stdlib, all of its functions, facts, and resources are av If you want to use a standardized set of run stages for Puppet, `include stdlib` in your manifest. -## Reference - -### Classes - -#### Public Classes - * `stdlib`: Most of stdlib's features are automatically loaded by Puppet. To use standardized run stages in Puppet, declare this class in your manifest with `include stdlib`. When declared, stdlib declares all other classes in the module. The only other class currently included in the module is `stdlib::stages`. - The stdlib class has no parameters. - -#### Private Classes - -* `stdlib::stages`: This class manages a standard set of run stages for Puppet. It is managed by the stdlib class and should not be declared independently. - - The `stdlib::stages` class declares various run stages for deploying infrastructure, language runtimes, and application layers. The high level stages are (in order): +The `stdlib::stages` class declares various run stages for deploying infrastructure, language runtimes, and application layers. The high level stages are (in order): * setup * main @@ -67,18 +54,31 @@ If you want to use a standardized set of run stages for Puppet, `include stdlib` Sample usage: - ``` + ~~~ node default { include stdlib class { java: stage => 'runtime' } } - ``` + ~~~ -### Resources +## Reference -* `file_line`: This resource ensures that a given line, including whitespace at the beginning and end, is contained within a file. If the line is not contained in the given file, Puppet will add the line. Multiple resources can be declared to manage multiple lines in the same file. You can also use match to replace existing lines. +### Classes + +#### Public Classes - ``` + The stdlib class has no parameters. + +#### Private Classes + +* `stdlib::stages`: Manages a standard set of run stages for Puppet. It is managed by the stdlib class and should not be declared independently. + +### Types + +#### `file_line` + Ensures that a given line, including whitespace at the beginning and end, is contained within a file. If the line is not contained in the given file, Puppet will add the line. Multiple resources can be declared to manage multiple lines in the same file. You can also use `match` to replace existing lines. + + ~~~ file_line { 'sudo_rule': path => '/etc/sudoers', line => '%sudo ALL=(ALL) ALL', @@ -87,31 +87,33 @@ If you want to use a standardized set of run stages for Puppet, `include stdlib` path => '/etc/sudoers', line => '%sudonopw ALL=(ALL) NOPASSWD: ALL', } - ``` + ~~~ + +##### Parameters +All parameters are optional, unless otherwise noted. + +* `after`: Specifies the line after which Puppet will add any new lines. (Existing lines are added in place.) Valid options: String. Default: Undefined. +* `ensure`: Ensures whether the resource is present. Valid options: 'present', 'absent'. Default: 'present'. +* `line`: **Required.** Sets the line to be added to the file located by the `path` parameter. Valid options: String. Default: Undefined. +* `match`: Specifies a regular expression to run against existing lines in the file; if a match is found, it is replaced rather than adding a new line. Valid options: String containing a regex. Default: Undefined. +* `multiple`: Determines if `match` can change multiple lines. If set to false, an exception will be raised if more than one line matches. Valid options: 'true', 'false'. Default: Undefined. +* `name`: Sets the name to use as the identity of the resource. This is necessary if you want the resource namevar to differ from the supplied `title` of the resource. Valid options: String. Default: Undefined. +* `path`: **Required.** Defines the file in which Puppet will ensure the line specified by `line`. Must be an absolute path to the file. - * `after`: Specify the line after which Puppet will add any new lines. (Existing lines are added in place.) Optional. - * `ensure`: Ensures whether the resource is present. Valid values are 'present', 'absent'. - * `line`: The line to be added to the file located by the `path` parameter. - * `match`: A regular expression to run against existing lines in the file; if a match is found, we replace that line rather than adding a new line. Optional. - * `multiple`: Determine if match can change multiple lines. Valid values are 'true', 'false'. Optional. - * `name`: An arbitrary name used as the identity of the resource. - * `path`: The file in which Puppet will ensure the line specified by the line parameter. ### Functions #### `abs` -Returns the absolute value of a number; for example, '-34.56' becomes '34.56'. Takes a single integer and float value as an argument. *Type*: rvalue +Returns the absolute value of a number; for example, '-34.56' becomes '34.56'. Takes a single integer and float value as an argument. *Type*: rvalue. #### `any2array` -This converts any object to an array containing that object. Empty argument lists are converted to an empty array. Arrays are left untouched. Hashes are converted to arrays of alternating keys and values. *Type*: rvalue +Converts any object to an array containing that object. Empty argument lists are converted to an empty array. Arrays are left untouched. Hashes are converted to arrays of alternating keys and values. *Type*: rvalue. #### `base64` -Converts a string to and from base64 encoding. -Requires an action ('encode', 'decode') and either a plain or base64-encoded -string. *Type*: rvalue +Converts a string to and from base64 encoding. Requires an action ('encode', 'decode') and either a plain or base64-encoded string. *Type*: rvalue. #### `basename` @@ -120,49 +122,47 @@ Returns the `basename` of a path (optionally stripping an extension). For exampl * ('relative/path/file.ext') returns 'file.ext' * ('/path/to/a/file.ext', '.ext') returns 'file' - *Type*: rvalue +*Type*: rvalue. #### `bool2num` Converts a boolean to a number. Converts values: * 'false', 'f', '0', 'n', and 'no' to 0. * 'true', 't', '1', 'y', and 'yes' to 1. - Requires a single boolean or string as an input. *Type*: rvalue + Requires a single boolean or string as an input. *Type*: rvalue. #### `capitalize` -Capitalizes the first letter of a string or array of strings. -Requires either a single string or an array as an input. *Type*: rvalue +Capitalizes the first letter of a string or array of strings. Requires either a single string or an array as an input. *Type*: rvalue. #### `ceiling` -Returns the smallest integer greater than or equal to the argument. -Takes a single numeric value as an argument. *Type*: rvalue +Returns the smallest integer greater than or equal to the argument. Takes a single numeric value as an argument. *Type*: rvalue. #### `chomp` -Removes the record separator from the end of a string or an array of -strings; for example, 'hello\n' becomes 'hello'. Requires a single string or array as an input. *Type*: rvalue +Removes the record separator from the end of a string or an array of strings; for example, 'hello\n' becomes 'hello'. Requires a single string or array as an input. *Type*: rvalue. #### `chop` -Returns a new string with the last character removed. If the string ends with '\r\n', both characters are removed. Applying `chop` to an empty string returns an empty string. If you want to merely remove record separators, then you should use the `chomp` function. Requires a string or an array of strings as input. *Type*: rvalue +Returns a new string with the last character removed. If the string ends with '\r\n', both characters are removed. Applying `chop` to an empty string returns an empty string. If you want to merely remove record separators, then you should use the `chomp` function. Requires a string or an array of strings as input. *Type*: rvalue. #### `concat` -Appends the contents of multiple arrays onto array 1. For example: - * `concat(['1','2','3'],'4')` results in: ['1','2','3','4']. - * `concat(['1','2','3'],'4',['5','6','7'])` results in: ['1','2','3','4','5','6','7']. +Appends the contents of multiple arrays onto the first array given. For example: + * `concat(['1','2','3'],'4')` returns ['1','2','3','4']. + * `concat(['1','2','3'],'4',['5','6','7'])` returns ['1','2','3','4','5','6','7']. + *Type*: rvalue. #### `count` -Takes an array as first argument and an optional second argument. Count the number of elements in array that matches second argument. If called with only an array, it counts the number of elements that are **not** nil/undef. *Type*: rvalue +If called with only an array, it counts the number of elements that are **not** nil/undef. If called with a second argument, counts the number of elements in an array that matches the second argument. *Type*: rvalue. #### `defined_with_params` Takes a resource reference and an optional hash of attributes. Returns 'true' if a resource with the specified attributes has already been added to the catalog. Returns 'false' otherwise. - ``` + ~~~ user { 'dan': ensure => present, } @@ -170,100 +170,96 @@ Takes a resource reference and an optional hash of attributes. Returns 'true' if if ! defined_with_params(User[dan], {'ensure' => 'present' }) { user { 'dan': ensure => present, } } - ``` + ~~~ - *Type*: rvalue +*Type*: rvalue. #### `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. 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. #### `delete_at` -Deletes a determined indexed value from an array. For example, `delete_at(['a','b','c'], 1)` returns ['a','c']. *Type*: rvalue +Deletes a determined indexed value from an array. For example, `delete_at(['a','b','c'], 1)` returns ['a','c']. *Type*: rvalue. #### `delete_values` -Deletes all instances of a given value from a hash. For example, `delete_values({'a'=>'A','b'=>'B','c'=>'C','B'=>'D'}, 'B')` returns {'a'=>'A','c'=>'C','B'=>'D'} *Type*: rvalue +Deletes all instances of a given value from a hash. For example, `delete_values({'a'=>'A','b'=>'B','c'=>'C','B'=>'D'}, 'B')` returns {'a'=>'A','c'=>'C','B'=>'D'} *Type*: rvalue. #### `delete_undef_values` -Deletes all instances of the undef value from an array or hash. For example, `$hash = delete_undef_values({a=>'A', b=>'', c=>undef, d => false})` returns {a => 'A', b => '', d => false}. *Type*: rvalue +Deletes all instances of the undef value from an array or hash. For example, `$hash = delete_undef_values({a=>'A', b=>'', c=>undef, d => false})` returns {a => 'A', b => '', d => false}. *Type*: rvalue. #### `difference` -Returns the difference between two arrays. -The returned array is a copy of the original array, removing any items that -also appear in the second array. For example, `difference(["a","b","c"],["b","c","d"])` returns ["a"]. +Returns the difference between two arrays. The returned array is a copy of the original array, removing any items that also appear in the second array. For example, `difference(["a","b","c"],["b","c","d"])` returns ["a"]. *Type*: rvalue. #### `dirname` -Returns the `dirname` of a path. For example, `dirname('/path/to/a/file.ext')` returns '/path/to/a'. +Returns the `dirname` of a path. For example, `dirname('/path/to/a/file.ext')` returns '/path/to/a'. *Type*: rvalue. #### `downcase` -Converts the case of a string or of all strings in an array to lowercase. *Type*: rvalue +Converts the case of a string or of all strings in an array to lowercase. *Type*: rvalue. #### `empty` -Returns 'true' if the variable is empty. *Type*: rvalue +Returns 'true' if the variable is empty. *Type*: rvalue. #### `ensure_packages` -Takes a list of packages and only installs them if they don't already exist. It optionally takes a hash as a second parameter to be passed as the third argument to the `ensure_resource()` function. *Type*: statement +Takes a list of packages and only installs them if they don't already exist. It optionally takes a hash as a second parameter to be passed as the third argument to the `ensure_resource()` function. *Type*: statement. #### `ensure_resource` Takes a resource type, title, and a list of attributes that describe a resource. - ``` - user { 'dan': - ensure => present, - } - ``` +~~~ +user { 'dan': + ensure => present, +} +~~~ - This example only creates the resource if it does not already exist: +This example only creates the resource if it does not already exist: - `ensure_resource('user', 'dan', {'ensure' => 'present' })` + `ensure_resource('user', 'dan', {'ensure' => 'present' })` - If the resource already exists, but does not match the specified parameters, this function attempts to recreate the resource, leading to a duplicate resource definition error. +If the resource already exists, but does not match the specified parameters, this function attempts to recreate the resource, leading to a duplicate resource definition error. - An array of resources can also be passed in, and each will be created with the type and parameters specified if it doesn't already exist. +An array of resources can also be passed in, and each will be created with the type and parameters specified if it doesn't already exist. `ensure_resource('user', ['dan','alex'], {'ensure' => 'present'})` - *Type*: statement +*Type*: statement. #### `flatten` -This function flattens any deeply nested arrays and returns a single flat array as a result. For example, `flatten(['a', ['b', ['c']]])` returns ['a','b','c']. *Type*: rvalue +Flattens deeply nested arrays and returns a single flat array as a result. For example, `flatten(['a', ['b', ['c']]])` returns ['a','b','c']. *Type*: rvalue. #### `floor` -Returns the largest integer less than or equal to the argument. -Takes a single numeric value as an argument. *Type*: rvalue +Takes a single numeric value as an argument, and returns the largest integer less than or equal to the argument. *Type*: rvalue. #### `fqdn_rand_string` Generates a random alphanumeric string using an optionally-specified character set (default is alphanumeric), combining the `$fqdn` fact and an optional seed for repeatable randomness. *Usage:* -``` +~~~ fqdn_rand_string(LENGTH, [CHARSET], [SEED]) -``` +~~~ *Examples:* -``` +~~~ fqdn_rand_string(10) fqdn_rand_string(10, 'ABCDEF!@#$%^') fqdn_rand_string(10, '', 'custom seed') -``` +~~~ -*Type*: rvalue +*Type*: rvalue. #### `fqdn_rotate` -Rotates an array a random number of times based on a node's fqdn. *Type*: rvalue +Rotates an array a random number of times, based on a node's fqdn. *Type*: rvalue. #### `get_module_path` @@ -271,16 +267,15 @@ Returns the absolute path of the specified module for the current environment. `$module_path = get_module_path('stdlib')` - *Type*: rvalue +*Type*: rvalue. #### `getparam` -Takes a resource reference and the name of the parameter and -returns the value of the resource's parameter. For example, the following code returns 'param_value'. +Takes a resource reference and the name of the parameter, and returns the value of the resource's parameter. - *Example:* +For example, the following returns 'param_value': - ``` + ~~~ define example_resource($param) { } @@ -289,73 +284,73 @@ returns the value of the resource's parameter. For example, the following code r } getparam(Example_resource["example_resource_instance"], "param") - ``` + ~~~ - *Type*: rvalue +*Type*: rvalue. #### `getvar` -Lookup a variable in a remote namespace. +Looks up a variable in a remote namespace. - For example: +For example: - ``` + ~~~ $foo = getvar('site::data::foo') # Equivalent to $foo = $site::data::foo - ``` + ~~~ - This is useful if the namespace itself is stored in a string: +This is useful if the namespace itself is stored in a string: - ``` + ~~~ $datalocation = 'site::data' $bar = getvar("${datalocation}::bar") # Equivalent to $bar = $site::data::bar - ``` + ~~~ - *Type*: rvalue +*Type*: rvalue. #### `grep` -This function searches through an array and returns any elements that match the provided regular expression. For example, `grep(['aaa','bbb','ccc','aaaddd'], 'aaa')` returns ['aaa','aaaddd']. *Type*: rvalue +Searches through an array and returns any elements that match the provided regular expression. For example, `grep(['aaa','bbb','ccc','aaaddd'], 'aaa')` returns ['aaa','aaaddd']. *Type*: rvalue. #### `has_interface_with` -Returns boolean based on kind and value: +Returns a boolean based on kind and value: * macaddress * netmask * ipaddress * network - *Examples:* +*Examples:* - ``` + ~~~ has_interface_with("macaddress", "x:x:x:x:x:x") has_interface_with("ipaddress", "127.0.0.1") => true - ``` + ~~~ - If no kind is given, then the presence of the interface is checked: +If no kind is given, then the presence of the interface is checked: - ``` + ~~~ has_interface_with("lo") => true - ``` + ~~~ - *Type*: rvalue +*Type*: rvalue. #### `has_ip_address` -Returns true if the client has the requested IP address on some interface. This function iterates through the `interfaces` fact and checks the `ipaddress_IFACE` facts, performing a simple string comparison. *Type*: rvalue +Returns 'true' if the client has the requested IP address on some interface. This function iterates through the `interfaces` fact and checks the `ipaddress_IFACE` facts, performing a simple string comparison. *Type*: rvalue. #### `has_ip_network` -Returns true if the client has an IP address within the requested network. This function iterates through the 'interfaces' fact and checks the 'network_IFACE' facts, performing a simple string comparision. *Type*: rvalue +Returns 'true' if the client has an IP address within the requested network. This function iterates through the `interfaces` fact and checks the `network_IFACE` facts, performing a simple string comparision. *Type*: rvalue. #### `has_key` -Determine if a hash has a certain key value. +Determines if a hash has a certain key value. - *Example*: +*Example*: - ``` + ~~~ $my_hash = {'key_one' => 'value_one'} if has_key($my_hash, 'key_two') { notice('we will not reach here') @@ -363,159 +358,166 @@ Determine if a hash has a certain key value. if has_key($my_hash, 'key_one') { notice('this will be printed') } - ``` + ~~~ - *Type*: rvalue +*Type*: rvalue. #### `hash` -This function converts an array into a hash. For example, `hash(['a',1,'b',2,'c',3])` returns {'a'=>1,'b'=>2,'c'=>3}. *Type*: rvalue +Converts an array into a hash. For example, `hash(['a',1,'b',2,'c',3])` returns {'a'=>1,'b'=>2,'c'=>3}. *Type*: rvalue. #### `intersection` -This function returns an array an intersection of two. For example, `intersection(["a","b","c"],["b","c","d"])` returns ["b","c"]. +Returns an array an intersection of two. For example, `intersection(["a","b","c"],["b","c","d"])` returns ["b","c"]. *Type*: rvalue. #### `is_array` -Returns 'true' if the variable passed to this function is an array. *Type*: rvalue +Returns 'true' if the variable passed to this function is an array. *Type*: rvalue. #### `is_bool` -Returns 'true' if the variable passed to this function is a boolean. *Type*: rvalue +Returns 'true' if the variable passed to this function is a boolean. *Type*: rvalue. #### `is_domain_name` -Returns 'true' if the string passed to this function is a syntactically correct domain name. *Type*: rvalue +Returns 'true' if the string passed to this function is a syntactically correct domain name. *Type*: rvalue. #### `is_float` -Returns 'true' if the variable passed to this function is a float. *Type*: rvalue +Returns 'true' if the variable passed to this function is a float. *Type*: rvalue. #### `is_function_available` -This function accepts a string as an argument and determines whether the Puppet runtime has access to a function by that name. It returns 'true' if the function exists, 'false' if not. *Type*: rvalue +Accepts a string as an argument and determines whether the Puppet runtime has access to a function by that name. It returns 'true' if the function exists, 'false' if not. *Type*: rvalue. #### `is_hash` -Returns 'true' if the variable passed to this function is a hash. *Type*: rvalue +Returns 'true' if the variable passed to this function is a hash. *Type*: rvalue. #### `is_integer` -Returns 'true' if the variable returned to this string is an integer. *Type*: rvalue +Returns 'true' if the variable returned to this string is an integer. *Type*: rvalue. #### `is_ip_address` -Returns 'true' if the string passed to this function is a valid IP address. *Type*: rvalue +Returns 'true' if the string passed to this function is a valid IP address. *Type*: rvalue. #### `is_mac_address` -Returns 'true' if the string passed to this function is a valid MAC address. *Type*: rvalue +Returns 'true' if the string passed to this function is a valid MAC address. *Type*: rvalue. #### `is_numeric` -Returns 'true' if the variable passed to this function is a number. *Type*: rvalue +Returns 'true' if the variable passed to this function is a number. *Type*: rvalue. #### `is_string` -Returns 'true' if the variable passed to this function is a string. *Type*: rvalue +Returns 'true' if the variable passed to this function is a string. *Type*: rvalue. #### `join` -This function joins an array into a string using a separator. For example, `join(['a','b','c'], ",")` results in: "a,b,c". *Type*: rvalue +Joins an array into a string using a separator. For example, `join(['a','b','c'], ",")` results in: "a,b,c". *Type*: rvalue. #### `join_keys_to_values` -This function joins each key of a hash to that key's corresponding value with a separator. Keys and values are cast to strings. The return value is an array in which each element is one joined key/value pair. For example, `join_keys_to_values({'a'=>1,'b'=>2}, " is ")` results in ["a is 1","b is 2"]. *Type*: rvalue +Joins each key of a hash to that key's corresponding value with a separator. Keys and values are cast to strings. The return value is an array in which each element is one joined key/value pair. For example, `join_keys_to_values({'a'=>1,'b'=>2}, " is ")` results in ["a is 1","b is 2"]. *Type*: rvalue. #### `keys` -Returns the keys of a hash as an array. *Type*: rvalue +Returns the keys of a hash as an array. *Type*: rvalue. #### `loadyaml` -Load a YAML file containing an array, string, or hash, and return the data in the corresponding native data type. For example: +Loads a YAML file containing an array, string, or hash, and returns the data in the corresponding native data type. For example: - ``` + ~~~ $myhash = loadyaml('/etc/puppet/data/myhash.yaml') - ``` + ~~~ - *Type*: rvalue +*Type*: rvalue. #### `lstrip` -Strips leading spaces to the left of a string. *Type*: rvalue +Strips spaces to the left of a string. *Type*: rvalue. #### `max` -Returns the highest value of all arguments. Requires at least one argument. *Type*: rvalue +Returns the highest value of all arguments. Requires at least one argument. *Type*: rvalue. #### `member` -This function determines if a variable is a member of an array. The variable can be either a string, array, or fixnum. For example, `member(['a','b'], 'b')` and `member(['a','b','c'], ['b','c'])` return 'true', while `member(['a','b'], 'c')` and `member(['a','b','c'], ['c','d'])` return 'false'. *Type*: rvalue +This function determines if a variable is a member of an array. The variable can be either a string, array, or fixnum. For example, `member(['a','b'], 'b')` and `member(['a','b','c'], ['b','c'])` return 'true', while `member(['a','b'], 'c')` and `member(['a','b','c'], ['c','d'])` return 'false'. *Note*: This function does not support nested arrays. If the first argument contains nested arrays, it will not recurse through them. + +*Type*: rvalue. #### `merge` Merges two or more hashes together and returns the resulting hash. - *Example*: +*Example*: - ``` + ~~~ $hash1 = {'one' => 1, 'two' => 2} $hash2 = {'two' => 'dos', 'three' => 'tres'} $merged_hash = merge($hash1, $hash2) # The resulting hash is equivalent to: # $merged_hash = {'one' => 1, 'two' => 'dos', 'three' => 'tres'} - ``` + ~~~ - When there is a duplicate key, the key in the rightmost hash "wins." *Type*: rvalue +When there is a duplicate key, the key in the rightmost hash "wins." *Type*: rvalue. #### `min` -Returns the lowest value of all arguments. Requires at least one argument. *Type*: rvalue +Returns the lowest value of all arguments. Requires at least one argument. *Type*: rvalue. #### `num2bool` -This function converts a number or a string representation of a number into a true boolean. Zero or anything non-numeric becomes 'false'. Numbers greater than 0 become 'true'. *Type*: rvalue +Converts a number or a string representation of a number into a true boolean. Zero or anything non-numeric becomes 'false'. Numbers greater than 0 become 'true'. *Type*: rvalue. #### `parsejson` -This function accepts JSON as a string and converts into the correct Puppet structure. *Type*: rvalue +Converts a string of JSON into the correct Puppet structure. *Type*: rvalue. #### `parseyaml` -This function accepts YAML as a string and converts it into the correct Puppet structure. *Type*: rvalue +Converts a string of YAML into the correct Puppet structure. *Type*: rvalue. #### `pick` From a list of values, returns the first value that is not undefined or an empty string. Takes any number of arguments, and raises an error if all values are undefined or empty. - ``` + ~~~ $real_jenkins_version = pick($::jenkins_version, '1.449') - ``` + ~~~ - *Type*: rvalue +*Type*: rvalue. #### `prefix` -This function applies a prefix to all elements in an array or to the keys in a hash. For example, `prefix(['a','b','c'], 'p')` returns ['pa','pb','pc'], and `prefix({'a'=>'b','b'=>'c','c'=>'d'}, 'p')` returns {'pa'=>'b','pb'=>'c','pc'=>'d'}. *Type*: rvalue +Applies a prefix to all elements in an array, or to the keys in a hash. +For example: +* `prefix(['a','b','c'], 'p')` returns ['pa','pb','pc'] +* `prefix({'a'=>'b','b'=>'c','c'=>'d'}, 'p')` returns {'pa'=>'b','pb'=>'c','pc'=>'d'}. +*Type*: rvalue. #### `assert_private` -This function sets the current class or definition as private. -Calling the class or definition from outside the current module will fail. For example, `assert_private()` called in class `foo::bar` outputs the following message if class is called from outside module `foo`: +Sets the current class or definition as private. Calling the class or definition from outside the current module will fail. - ``` +For example, `assert_private()` called in class `foo::bar` outputs the following message if class is called from outside module `foo`: + + ~~~ Class foo::bar is private - ``` + ~~~ - You can specify the error message you want to use: + To specify the error message you want to use: - ``` + ~~~ assert_private("You're not supposed to do that!") - ``` + ~~~ - *Type*: statement +*Type*: statement. #### `pw_hash` @@ -533,65 +535,65 @@ The second argument to this function is which type of hash to use. It will be co The third argument to this function is the salt to use. -Note: this uses the Puppet Master's implementation of crypt(3). If your environment contains several different operating systems, ensure that they are compatible before using this function. +**Note:** this uses the Puppet master's implementation of crypt(3). If your environment contains several different operating systems, ensure that they are compatible before using this function. #### `range` -When given range in the form of '(start, stop)', `range` extrapolates a range as an array. For example, `range("0", "9")` returns [0,1,2,3,4,5,6,7,8,9]. Zero-padded strings are converted to integers automatically, so `range("00", "09")` returns [0,1,2,3,4,5,6,7,8,9]. +Extrapolates a range as an array when given in the form of '(start, stop)'. For example, `range("0", "9")` returns [0,1,2,3,4,5,6,7,8,9]. Zero-padded strings are converted to integers automatically, so `range("00", "09")` returns [0,1,2,3,4,5,6,7,8,9]. - Non-integer strings are accepted; `range("a", "c")` returns ["a","b","c"], and `range("host01", "host10")` returns ["host01", "host02", ..., "host09", "host10"]. +Non-integer strings are accepted; `range("a", "c")` returns ["a","b","c"], and `range("host01", "host10")` returns ["host01", "host02", ..., "host09", "host10"]. - Passing a third argument will cause the generated range to step by that interval, e.g. `range("0", "9", "2")` returns ["0","2","4","6","8"] +Passing a third argument will cause the generated range to step by that interval, e.g. `range("0", "9", "2")` returns ["0","2","4","6","8"]. - *Type*: rvalue +*Type*: rvalue. #### `reject` -This function searches through an array and rejects all elements that match the provided regular expression. For example, `reject(['aaa','bbb','ccc','aaaddd'], 'aaa')` returns ['bbb','ccc']. *Type*: rvalue +Searches through an array and rejects all elements that match the provided regular expression. For example, `reject(['aaa','bbb','ccc','aaaddd'], 'aaa')` returns ['bbb','ccc']. *Type*: rvalue. #### `reverse` -Reverses the order of a string or array. *Type*: rvalue +Reverses the order of a string or array. *Type*: rvalue. #### `rstrip` -Strips leading spaces to the right of the string.*Type*: rvalue +Strips spaces to the right of the string. *Type*: rvalue. #### `shuffle` -Randomizes the order of a string or array elements. *Type*: rvalue +Randomizes the order of a string or array elements. *Type*: rvalue. #### `size` -Returns the number of elements in a string or array. *Type*: rvalue +Returns the number of elements in a string or an array. *Type*: rvalue. #### `sort` -Sorts strings and arrays lexically. *Type*: rvalue +Sorts strings and arrays lexically. *Type*: rvalue. #### `squeeze` -Returns a new string where runs of the same character that occur in this set are replaced by a single character. *Type*: rvalue +Returns a new string where runs of the same character that occur in this set are replaced by a single character. *Type*: rvalue. #### `str2bool` -This converts a string to a boolean. This attempts to convert strings that contain values such as '1', 't', 'y', and 'yes' to 'true' and strings that contain values such as '0', 'f', 'n', and 'no' to 'false'. *Type*: rvalue +Converts a string to a boolean. This attempts to convert strings that contain values such as '1', 't', 'y', and 'yes' to 'true' and strings that contain values such as '0', 'f', 'n', and 'no' to 'false'. *Type*: rvalue. #### `str2saltedsha512` -This converts a string to a salted-SHA512 password hash, used for OS X versions >= 10.7. Given any string, this function returns a hex version of a salted-SHA512 password hash, which can be inserted into your Puppet -manifests as a valid password attribute. *Type*: rvalue +Converts a string to a salted-SHA512 password hash, used for OS X versions >= 10.7. Given any string, this function returns a hex version of a salted-SHA512 password hash, which can be inserted into your Puppet +manifests as a valid password attribute. *Type*: rvalue. #### `strftime` -This function returns formatted time. For example, `strftime("%s")` returns the time since epoch, and `strftime("%Y=%m-%d")` returns the date. *Type*: rvalue +Returns formatted time. For example, `strftime("%s")` returns the time since Unix epoch, and `strftime("%Y-%m-%d")` returns the date. *Type*: rvalue. *Format:* * `%a`: The abbreviated weekday name ('Sun') - * `%A`: The full weekday name ('Sunday') + * `%A`: The full weekday name ('Sunday') * `%b`: The abbreviated month name ('Jan') - * `%B`: The full month name ('January') + * `%B`: The full month name ('January') * `%c`: The preferred local date and time representation * `%C`: Century (20 in 2009) * `%d`: Day of the month (01..31) @@ -612,227 +614,220 @@ This function returns formatted time. For example, `strftime("%s")` returns the * `%3N`: Millisecond (3 digits) * `%6N`: Microsecond (6 digits) * `%9N`: Nanosecond (9 digits) - * `%p`: Meridian indicator ('AM' or 'PM') - * `%P`: Meridian indicator ('am' or 'pm') + * `%p`: Meridian indicator ('AM' or 'PM') + * `%P`: Meridian indicator ('am' or 'pm') * `%r`: Time, 12-hour (same as %I:%M:%S %p) * `%R`: Time, 24-hour (%H:%M) - * `%s`: Number of seconds since 1970-01-01 00:00:00 UTC. + * `%s`: Number of seconds since the Unix epoch, 1970-01-01 00:00:00 UTC. * `%S`: Second of the minute (00..60) * `%t`: Tab character ( ) * `%T`: Time, 24-hour (%H:%M:%S) * `%u`: Day of the week as a decimal, Monday being 1. (1..7) - * `%U`: Week number of the current year, starting with the first Sunday as the first day of the first week (00..53) + * `%U`: Week number of the current year, starting with the first Sunday as the first day of the first week (00..53) * `%v`: VMS date (%e-%b-%Y) * `%V`: Week number of year according to ISO 8601 (01..53) - * `%W`: Week number of the current year, starting with the first Monday as the first day of the first week (00..53) + * `%W`: Week number of the current year, starting with the first Monday as the first day of the first week (00..53) * `%w`: Day of the week (Sunday is 0, 0..6) * `%x`: Preferred representation for the date alone, no time * `%X`: Preferred representation for the time alone, no date * `%y`: Year without a century (00..99) * `%Y`: Year with century - * `%z`: Time zone as hour offset from UTC (e.g. +0900) + * `%z`: Time zone as hour offset from UTC (e.g. +0900) * `%Z`: Time zone name * `%%`: Literal '%' character #### `strip` -This function removes leading and trailing whitespace from a string or from every string inside an array. For example, `strip(" aaa ")` results in "aaa". *Type*: rvalue +Removes leading and trailing whitespace from a string or from every string inside an array. For example, `strip(" aaa ")` results in "aaa". *Type*: rvalue. #### `suffix` -This function applies a suffix to all elements in an array. For example, `suffix(['a','b','c'], 'p')` returns ['ap','bp','cp']. *Type*: rvalue +Applies a suffix to all elements in an array. For example, `suffix(['a','b','c'], 'p')` returns ['ap','bp','cp']. *Type*: rvalue. #### `swapcase` -This function swaps the existing case of a string. For example, `swapcase("aBcD")` results in "AbCd". *Type*: rvalue +Swaps the existing case of a string. For example, `swapcase("aBcD")` results in "AbCd". *Type*: rvalue. #### `time` -This function returns the current time since epoch as an integer. For example, `time()` returns something like '1311972653'. *Type*: rvalue +Returns the current Unix epoch time as an integer. For example, `time()` returns something like '1311972653'. *Type*: rvalue. #### `to_bytes` -Converts the argument into bytes, for example 4 kB becomes 4096. -Takes a single string value as an argument. *Type*: rvalue +Converts the argument into bytes, for example "4 kB" becomes "4096". Takes a single string value as an argument. *Type*: rvalue. #### `type3x` -Returns a string description of the type when passed a value. Type can be a string, array, hash, float, integer, or boolean. This function will be removed when puppet 3 support is dropped and the new type system may be used. *Type*: rvalue +Returns a string description of the type when passed a value. Type can be a string, array, hash, float, integer, or boolean. This function will be removed when Puppet 3 support is dropped and the new type system can be used. *Type*: rvalue. #### `type_of` -Returns the literal type when passed a value. Requires the new - parser. Useful for comparison of types with `<=` such as in `if - type_of($some_value) <= Array[String] { ... }` (which is equivalent to `if - $some_value =~ Array[String] { ... }`) *Type*: rvalue +Returns the literal type when passed a value. Requires the new parser. Useful for comparison of types with `<=` such as in `if type_of($some_value) <= Array[String] { ... }` (which is equivalent to `if $some_value =~ Array[String] { ... }`) *Type*: rvalue. #### `union` -This function returns a union of two arrays. For example, `union(["a","b","c"],["b","c","d"])` returns ["a","b","c","d"]. +Returns a union of two arrays, without duplicates. For example, `union(["a","b","c"],["b","c","d"])` returns ["a","b","c","d"]. #### `unique` -This function removes duplicates from strings and arrays. For example, `unique("aabbcc")` returns 'abc'. - -You can also use this with arrays. For example, `unique(["a","a","b","b","c","c"])` returns ["a","b","c"]. *Type*: rvalue +Removes duplicates from strings and arrays. For example, `unique("aabbcc")` returns 'abc', and `unique(["a","a","b","b","c","c"])` returns ["a","b","c"]. *Type*: rvalue. #### `upcase` -Converts an object, array or hash of objects that respond to upcase to uppercase. For example, `upcase("abcd")` returns 'ABCD'. *Type*: rvalue +Converts an object, array or hash of objects that respond to upcase to uppercase. For example, `upcase('abcd')` returns 'ABCD'. *Type*: rvalue. #### `uriescape` -Urlencodes a string or array of strings. Requires either a single string or an array as an input. *Type*: rvalue +URLEncodes a string or array of strings. Requires either a single string or an array as an input. *Type*: rvalue. #### `validate_absolute_path` -Validate the string represents an absolute path in the filesystem. This function works for Windows and Unix style paths. +Validates that a given string represents an absolute path in the filesystem. Works for Windows and Unix style paths. - The following values will pass: +The following values pass: - ``` - $my_path = 'C:/Program Files (x86)/Puppet Labs/Puppet' - validate_absolute_path($my_path) - $my_path2 = '/var/lib/puppet' - validate_absolute_path($my_path2) - $my_path3 = ['C:/Program Files (x86)/Puppet Labs/Puppet','C:/Program Files/Puppet Labs/Puppet'] - validate_absolute_path($my_path3) - $my_path4 = ['/var/lib/puppet','/usr/share/puppet'] - validate_absolute_path($my_path4) - ``` +~~~ +$my_path = 'C:/Program Files (x86)/Puppet Labs/Puppet' +validate_absolute_path($my_path) +$my_path2 = '/var/lib/puppet' +validate_absolute_path($my_path2) +$my_path3 = ['C:/Program Files (x86)/Puppet Labs/Puppet','C:/Program Files/Puppet Labs/Puppet'] +validate_absolute_path($my_path3) +$my_path4 = ['/var/lib/puppet','/usr/share/puppet'] +validate_absolute_path($my_path4) +~~~ - The following values will fail, causing compilation to abort: +The following values fail, causing compilation to abort: - ``` - validate_absolute_path(true) - validate_absolute_path('../var/lib/puppet') - validate_absolute_path('var/lib/puppet') - validate_absolute_path([ 'var/lib/puppet', '/var/foo' ]) - validate_absolute_path([ '/var/lib/puppet', 'var/foo' ]) - $undefined = undef - validate_absolute_path($undefined) - ``` +~~~ +validate_absolute_path(true) +validate_absolute_path('../var/lib/puppet') +validate_absolute_path('var/lib/puppet') +validate_absolute_path([ 'var/lib/puppet', '/var/foo' ]) +validate_absolute_path([ '/var/lib/puppet', 'var/foo' ]) +$undefined = undef +validate_absolute_path($undefined) +~~~ - *Type*: statement +*Type*: statement. #### `validate_array` -Validate that all passed values are array data structures. Abort catalog compilation if any value fails this check. +Validates that all passed values are array data structures. Aborts catalog compilation if any value fails this check. - The following values will pass: +The following values pass: - ``` - $my_array = [ 'one', 'two' ] - validate_array($my_array) - ``` +~~~ +$my_array = [ 'one', 'two' ] +validate_array($my_array) +~~~ - The following values will fail, causing compilation to abort: +The following values fail, causing compilation to abort: - ``` - validate_array(true) - validate_array('some_string') - $undefined = undef - validate_array($undefined) - ``` +~~~ +validate_array(true) +validate_array('some_string') +$undefined = undef +validate_array($undefined) +~~~ - *Type*: statement +*Type*: statement. #### `validate_augeas` -Performs validation of a string using an Augeas lens. -The first argument of this function should be the string to test, and the second argument should be the name of the Augeas lens to use. If Augeas fails to parse the string with the lens, the compilation aborts with a parse error. +Performs validation of a string using an Augeas lens. The first argument of this function should be the string to test, and the second argument should be the name of the Augeas lens to use. If Augeas fails to parse the string with the lens, the compilation aborts with a parse error. - A third optional argument lists paths which should **not** be found in the file. The `$file` variable points to the location of the temporary file being tested in the Augeas tree. +A third optional argument lists paths which should **not** be found in the file. The `$file` variable points to the location of the temporary file being tested in the Augeas tree. - For example, to make sure your passwd content never contains user `foo`: +For example, to make sure your $passwdcontent never contains user `foo`: - ``` - validate_augeas($passwdcontent, 'Passwd.lns', ['$file/foo']) - ``` +~~~ +validate_augeas($passwdcontent, 'Passwd.lns', ['$file/foo']) +~~~ - To ensure that no users use the '/bin/barsh' shell: +To ensure that no users use the '/bin/barsh' shell: - ``` - validate_augeas($passwdcontent, 'Passwd.lns', ['$file/*[shell="/bin/barsh"]'] - ``` +~~~ +validate_augeas($passwdcontent, 'Passwd.lns', ['$file/*[shell="/bin/barsh"]'] +~~~ - You can pass a fourth argument as the error message raised and shown to the user: +You can pass a fourth argument as the error message raised and shown to the user: - ``` - validate_augeas($sudoerscontent, 'Sudoers.lns', [], 'Failed to validate sudoers content with Augeas') - ``` +~~~ +validate_augeas($sudoerscontent, 'Sudoers.lns', [], 'Failed to validate sudoers content with Augeas') +~~~ - *Type*: statement +*Type*: statement. #### `validate_bool` -Validate that all passed values are either true or false. Abort catalog compilation if any value fails this check. +Validates that all passed values are either true or false. Aborts catalog compilation if any value fails this check. - The following values will pass: +The following values will pass: - ``` - $iamtrue = true - validate_bool(true) - validate_bool(true, true, false, $iamtrue) - ``` +~~~ +$iamtrue = true +validate_bool(true) +validate_bool(true, true, false, $iamtrue) +~~~ - The following values will fail, causing compilation to abort: +The following values will fail, causing compilation to abort: - ``` - $some_array = [ true ] - validate_bool("false") - validate_bool("true") - validate_bool($some_array) - ``` +~~~ +$some_array = [ true ] +validate_bool("false") +validate_bool("true") +validate_bool($some_array) +~~~ - *Type*: statement +*Type*: statement. #### `validate_cmd` -Performs validation of a string with an external command. The first argument of this function should be a string to test, and the second argument should be a path to a test command taking a % as a placeholder for the file path (will default to the end of the command if no % placeholder given). If the command, launched against a tempfile containing the passed string, returns a non-null value, compilation will abort with a parse error. +Performs validation of a string with an external command. The first argument of this function should be a string to test, and the second argument should be a path to a test command taking a % as a placeholder for the file path (will default to the end of the command if no % placeholder given). If the command is launched against a tempfile containing the passed string, or returns a non-null value, compilation will abort with a parse error. If a third argument is specified, this will be the error message raised and seen by the user. - ``` - # Defaults to end of path - validate_cmd($sudoerscontent, '/usr/sbin/visudo -c -f', 'Visudo failed to validate sudoers content') - ``` - ``` - # % as file location - validate_cmd($haproxycontent, '/usr/sbin/haproxy -f % -c', 'Haproxy failed to validate config content') - ``` +~~~ +# Defaults to end of path +validate_cmd($sudoerscontent, '/usr/sbin/visudo -c -f', 'Visudo failed to validate sudoers content') +~~~ +~~~ +# % as file location +validate_cmd($haproxycontent, '/usr/sbin/haproxy -f % -c', 'Haproxy failed to validate config content') +~~~ - *Type*: statement +*Type*: statement. #### `validate_hash` -Validates that all passed values are hash data structures. Abort catalog compilation if any value fails this check. +Validates that all passed values are hash data structures. Aborts catalog compilation if any value fails this check. The following values will pass: - ``` + ~~~ $my_hash = { 'one' => 'two' } validate_hash($my_hash) - ``` + ~~~ The following values will fail, causing compilation to abort: - ``` + ~~~ validate_hash(true) validate_hash('some_string') $undefined = undef validate_hash($undefined) - ``` + ~~~ - *Type*: statement +*Type*: statement. #### `validate_integer` -Validate that the first argument is an integer (or an array of integers). Abort catalog compilation if any of the checks fail. - +Validates that the first argument is an integer (or an array of integers). Aborts catalog compilation if any of the checks fail. + The second argument is optional and passes a maximum. (All elements of) the first argument has to be less or equal to this max. - The third argument is optional and passes a minimum. (All elements of) the first argument has to be greater or equal to this min. + The third argument is optional and passes a minimum. (All elements of) the first argument has to be greater or equal to this min. If, and only if, a minimum is given, the second argument may be an empty string or undef, which will be handled to just check if (all elements of) the first argument are greater or equal to the given minimum. @@ -840,7 +835,7 @@ Validate that the first argument is an integer (or an array of integers). Abort The following values will pass: - ``` + ~~~ validate_integer(1) validate_integer(1, 2) validate_integer(1, 1) @@ -852,14 +847,14 @@ Validate that the first argument is an integer (or an array of integers). Abort validate_integer(2, $foo, 0) validate_integer([1,2,3,4,5], 6) validate_integer([1,2,3,4,5], 6, 0) - ``` + ~~~ * Plus all of the above, but any combination of values passed as strings ('1' or "1"). * Plus all of the above, but with (correct) combinations of negative integer values. The following values will fail, causing compilation to abort: - ``` + ~~~ validate_integer(true) validate_integer(false) validate_integer(7.0) @@ -876,21 +871,21 @@ Validate that the first argument is an integer (or an array of integers). Abort validate_integer(1, 2, 3) validate_integer(1, 3, 2) validate_integer(1, 3, true) - ``` + ~~~ * Plus all of the above, but any combination of values passed as strings ('false' or "false"). * Plus all of the above, but with incorrect combinations of negative integer values. * Plus all of the above, but with non-integer crap in arrays or maximum / minimum argument. - *Type*: statement + *Type*: statement. #### `validate_numeric` -Validate that the first argument is a numeric value (or an array of numeric values). Abort catalog compilation if any of the checks fail. +Validates that the first argument is a numeric value (or an array of numeric values). Aborts catalog compilation if any of the checks fail. The second argument is optional and passes a maximum. (All elements of) the first argument has to be less or equal to this max. - The third argument is optional and passes a minimum. (All elements of) the first argument has to be greater or equal to this min. + The third argument is optional and passes a minimum. (All elements of) the first argument has to be greater or equal to this min. If, and only if, a minimum is given, the second argument may be an empty string or undef, which will be handled to just check if (all elements of) the first argument are greater or equal to the given minimum. @@ -898,37 +893,35 @@ Validate that the first argument is a numeric value (or an array of numeric valu For passing and failing usage, see `validate_integer()`. It is all the same for validate_numeric, yet now floating point values are allowed, too. - *Type*: statement +*Type*: statement. #### `validate_re` Performs simple validation of a string against one or more regular expressions. The first argument of this function should be the string to -test, and the second argument should be a stringified regular expression -(without the // delimiters) or an array of regular expressions. If none -of the regular expressions match the string passed in, compilation aborts with a parse error. +test, and the second argument should be a stringified regular expression (without the // delimiters) or an array of regular expressions. If none of the regular expressions match the string passed in, compilation aborts with a parse error. You can pass a third argument as the error message raised and shown to the user. The following strings validate against the regular expressions: - ``` + ~~~ validate_re('one', '^one$') validate_re('one', [ '^one', '^two' ]) - ``` + ~~~ The following string fails to validate, causing compilation to abort: - ``` + ~~~ validate_re('one', [ '^two', '^three' ]) - ``` + ~~~ To set the error message: - ``` + ~~~ validate_re($::puppetversion, '^2.7', 'The $puppetversion fact value does not match 2.7') - ``` + ~~~ - *Type*: statement +*Type*: statement. #### `validate_slength` @@ -936,64 +929,59 @@ Validates that the first argument is a string (or an array of strings), and is l The following values pass: - ``` + ~~~ validate_slength("discombobulate",17) validate_slength(["discombobulate","moo"],17) - ``` + ~~~ The following values fail: - ``` + ~~~ validate_slength("discombobulate",1) validate_slength(["discombobulate","thermometer"],5) - ``` + ~~~ - *Type*: statement +*Type*: statement. #### `validate_string` Validates that all passed values are string data structures. Aborts catalog compilation if any value fails this check. - The following values pass: +The following values pass: - ``` + ~~~ $my_string = "one two" validate_string($my_string, 'three') - ``` + ~~~ The following values fail, causing compilation to abort: - ``` + ~~~ validate_string(true) validate_string([ 'some', 'array' ]) - $undefined = undef - validate_string($undefined) - ``` + ~~~ - *Type*: statement +*Note:* validate_string(undef) will not fail in this version of the functions API (incl. current and future parser). -#### `values` +Instead, use: -When given a hash, this function returns the values of that hash. + ~~~ + if $var == undef { + fail('...') + } + ~~~ - *Examples:* +*Type*: statement. - ``` - $hash = { - 'a' => 1, - 'b' => 2, - 'c' => 3, - } - values($hash) - ``` +#### `values` - The example above returns [1,2,3]. +Returns the values of a given hash. For example, given `$hash = {'a'=1, 'b'=2, 'c'=3} values($hash)` returns [1,2,3]. - *Type*: rvalue +*Type*: rvalue. #### `values_at` -Finds value inside an array based on location. The first argument is the array you want to analyze, and the second element can be a combination of: +Finds values inside an array based on location. The first argument is the array you want to analyze, and the second argument can be a combination of: * A single numeric index * A range in the form of 'start-stop' (eg. 4-9) @@ -1001,15 +989,15 @@ Finds value inside an array based on location. The first argument is the array y For example, `values_at(['a','b','c'], 2)` returns ['c']; `values_at(['a','b','c'], ["0-1"])` returns ['a','b']; and `values_at(['a','b','c','d','e'], [0, "2-3"])` returns ['a','c','d']. - *Type*: rvalue +*Type*: rvalue. #### `zip` -Takes one element from first array and merges corresponding elements from second array. This generates a sequence of n-element arrays, where n is one more than the count of arguments. For example, `zip(['1','2','3'],['4','5','6'])` results in ["1", "4"], ["2", "5"], ["3", "6"]. *Type*: rvalue +Takes one element from first array given and merges corresponding elements from second array given. This generates a sequence of n-element arrays, where *n* is one more than the count of arguments. For example, `zip(['1','2','3'],['4','5','6'])` results in ["1", "4"], ["2", "5"], ["3", "6"]. *Type*: rvalue. ##Limitations -As of Puppet Enterprise version 3.7, the stdlib module is no longer included in PE. PE users should install the most recent release of stdlib for compatibility with Puppet modules. +As of Puppet Enterprise 3.7, the stdlib module is no longer included in PE. PE users should install the most recent release of stdlib for compatibility with Puppet modules. ###Version Compatibility @@ -1024,11 +1012,7 @@ Versions | Puppet 2.6 | Puppet 2.7 | Puppet 3.x | Puppet 4.x | ##Development -Puppet Labs modules on the Puppet Forge are open projects, and community contributions are essential for keeping them great. We can’t access the huge number of platforms and myriad of hardware, software, and deployment configurations that Puppet is intended to serve. - -We want to keep it as easy as possible to contribute changes so that our modules work in your environment. There are a few guidelines that we need contributors to follow so that we can have a chance of keeping on top of things. - -You can read the complete module contribution guide on the [Puppet Labs wiki](http://projects.puppetlabs.com/projects/module-site/wiki/Module_contributing). +Puppet Labs modules on the Puppet Forge are open projects, and community contributions are essential for keeping them great. We can’t access the huge number of platforms and myriad hardware, software, and deployment configurations that Puppet is intended to serve. We want to keep it as easy as possible to contribute changes so that our modules work in your environment. There are a few guidelines that we need contributors to follow so that we can have a chance of keeping on top of things. For more information, see our [module contribution guide.](https://docs.puppetlabs.com/forge/contributing.html) To report or research a bug with any part of this module, please go to [http://tickets.puppetlabs.com/browse/PUP](http://tickets.puppetlabs.com/browse/PUP). -- cgit v1.2.3 From 48e516be6b83ca2b451af0afcc7fe12429f86f5b Mon Sep 17 00:00:00 2001 From: Garrett Honeycutt Date: Wed, 20 May 2015 15:16:45 -0400 Subject: Update CHANGELOG.md --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c17e750..eef0473 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,7 +12,7 @@ Adds functions and function argument abilities, and improves compatibility with - `validate_absolute_path()` can now take an array - `validate_cmd()` can now use % in the command to embed the validation file argument in the string - MODULES-1473: deprecate `type()` function in favor of `type3x()` -- MODULES-1473: Add `type_of()` to give better time information on future parser +- MODULES-1473: Add `type_of()` to give better type information on future parser - Deprecate `private()` for `assert_private()` due to future parser - Adds `ceiling()` to take the ceiling of a number - Adds `fqdn_rand_string()` to generate random string based on fqdn -- cgit v1.2.3 From 0dc0e0dbcf9574ed1515cf6cfe2800f06d8c1d0e Mon Sep 17 00:00:00 2001 From: David Schmitt Date: Tue, 12 May 2015 15:01:55 +0100 Subject: fqdn_rotate: reset srand seed correctly on old ruby versions Without this, the global seed is reseeded on every use of fqdn_rotate, which is a waste. Older rubies might even use a time-base seed which adversly impacts the quality of the RNG. --- lib/puppet/parser/functions/fqdn_rotate.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/puppet/parser/functions/fqdn_rotate.rb b/lib/puppet/parser/functions/fqdn_rotate.rb index cf22d36..d9741a0 100644 --- a/lib/puppet/parser/functions/fqdn_rotate.rb +++ b/lib/puppet/parser/functions/fqdn_rotate.rb @@ -39,9 +39,9 @@ Rotates an array a random number of times based on a nodes fqdn. if defined?(Random) == 'constant' && Random.class == Class offset = Random.new(seed).rand(elements) else - srand(seed) + old_seed = srand(seed) offset = rand(elements) - srand() + srand(old_seed) end end offset.times { -- cgit v1.2.3 From b4090184c76666e58694aa4f09a39be009a42f5f Mon Sep 17 00:00:00 2001 From: Hunter Haugen Date: Wed, 27 May 2015 08:14:19 -0700 Subject: Add ability to unittest puppet 4 --- .travis.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.travis.yml b/.travis.yml index 58e62d9..371586b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -14,5 +14,10 @@ matrix: env: PUPPET_GEM_VERSION="~> 3.0" - rvm: 2.1.5 env: PUPPET_GEM_VERSION="~> 3.0" FUTURE_PARSER="yes" + - rvm: 2.1.6 + env: PUPPET_GEM_VERSION="~> 4.0" STRICT_VARIABLES="yes" + allow_failures: + - rvm: 2.1.6 + env: PUPPET_GEM_VERSION="~> 4.0" STRICT_VARIABLES="yes" notifications: email: false -- cgit v1.2.3 From cf9f7a6b7e4ede7edd612fde33f7149f9c7f3385 Mon Sep 17 00:00:00 2001 From: David Schmitt Date: Wed, 27 May 2015 20:05:01 +0100 Subject: validate_integer, validate_numeric: explicitely reject hashes in arrays Without this patch, Ruby 1.8's Hash#to_s behaviour causes [{1=>2}] to be treated as "12" when validating values. --- lib/puppet/parser/functions/validate_integer.rb | 1 + lib/puppet/parser/functions/validate_numeric.rb | 1 + spec/functions/validate_integer_spec.rb | 5 +++++ spec/functions/validate_numeric_spec.rb | 5 +++++ 4 files changed, 12 insertions(+) diff --git a/lib/puppet/parser/functions/validate_integer.rb b/lib/puppet/parser/functions/validate_integer.rb index 995f8db..95da0c4 100644 --- a/lib/puppet/parser/functions/validate_integer.rb +++ b/lib/puppet/parser/functions/validate_integer.rb @@ -109,6 +109,7 @@ module Puppet::Parser::Functions # check every element of the array input.each_with_index do |arg, pos| begin + raise TypeError if arg.is_a?(Hash) arg = Integer(arg.to_s) validator.call(arg) rescue TypeError, ArgumentError diff --git a/lib/puppet/parser/functions/validate_numeric.rb b/lib/puppet/parser/functions/validate_numeric.rb index d2e4d16..3a14443 100644 --- a/lib/puppet/parser/functions/validate_numeric.rb +++ b/lib/puppet/parser/functions/validate_numeric.rb @@ -71,6 +71,7 @@ module Puppet::Parser::Functions # check every element of the array input.each_with_index do |arg, pos| begin + raise TypeError if arg.is_a?(Hash) arg = Float(arg.to_s) validator.call(arg) rescue TypeError, ArgumentError diff --git a/spec/functions/validate_integer_spec.rb b/spec/functions/validate_integer_spec.rb index 3865c4f..e95da6a 100755 --- a/spec/functions/validate_integer_spec.rb +++ b/spec/functions/validate_integer_spec.rb @@ -62,6 +62,11 @@ describe Puppet::Parser::Functions.function(:validate_integer) do expect { scope.compiler.compile }.to raise_error(Puppet::ParseError, /to be an Integer or Array/) end + it "should not compile when a Hash is passed as Array" do + Puppet[:code] = "validate_integer([{ 1 => 2 }])" + expect { scope.compiler.compile }.to raise_error(Puppet::ParseError, /to be an Integer/) + end + it "should not compile when an explicitly undef variable is passed" do Puppet[:code] = <<-'ENDofPUPPETcode' $foo = undef diff --git a/spec/functions/validate_numeric_spec.rb b/spec/functions/validate_numeric_spec.rb index 1623a3d..c99d879 100755 --- a/spec/functions/validate_numeric_spec.rb +++ b/spec/functions/validate_numeric_spec.rb @@ -62,6 +62,11 @@ describe Puppet::Parser::Functions.function(:validate_numeric) do expect { scope.compiler.compile }.to raise_error(Puppet::ParseError, /to be a Numeric or Array/) end + it "should not compile when a Hash is passed in an Array" do + Puppet[:code] = "validate_numeric([{ 1 => 2 }])" + expect { scope.compiler.compile }.to raise_error(Puppet::ParseError, /to be a Numeric/) + end + it "should not compile when an explicitly undef variable is passed" do Puppet[:code] = <<-'ENDofPUPPETcode' $foo = undef -- cgit v1.2.3 From 72089f3d134a00e64f0b3d81237a266131d40412 Mon Sep 17 00:00:00 2001 From: Raymond Maika Date: Fri, 29 May 2015 00:27:08 -0400 Subject: (MODULES-2071) Refactor file_line provider to contain logic to handle parameter multiple in function handle_create_with_after Without this, file_line resource without the `match` parameter but with the `after` param will throw an error if there are multiple matches for the after expression. This patch creates the handling for the `multiple` parameter in handle_create_with_after. This allows you to add a line after the `after` expression if it appears at multiple points in a file. Updated reference to `file_line` in the README to reflect that the multiple parameter can be set when using `after` and/or `match` as the matching regex. --- README.markdown | 4 ++-- lib/puppet/provider/file_line/ruby.rb | 24 +++++++++++++----------- spec/unit/puppet/provider/file_line/ruby_spec.rb | 18 +++++++++++++++++- 3 files changed, 32 insertions(+), 14 deletions(-) diff --git a/README.markdown b/README.markdown index a7a2d3a..c140af4 100644 --- a/README.markdown +++ b/README.markdown @@ -96,8 +96,8 @@ All parameters are optional, unless otherwise noted. * `ensure`: Ensures whether the resource is present. Valid options: 'present', 'absent'. Default: 'present'. * `line`: **Required.** Sets the line to be added to the file located by the `path` parameter. Valid options: String. Default: Undefined. * `match`: Specifies a regular expression to run against existing lines in the file; if a match is found, it is replaced rather than adding a new line. Valid options: String containing a regex. Default: Undefined. -* `multiple`: Determines if `match` can change multiple lines. If set to false, an exception will be raised if more than one line matches. Valid options: 'true', 'false'. Default: Undefined. -* `name`: Sets the name to use as the identity of the resource. This is necessary if you want the resource namevar to differ from the supplied `title` of the resource. Valid options: String. Default: Undefined. +* `multiple`: Determines if `match` and/or `after` can change multiple lines. If set to false, an exception will be raised if more than one line matches. Valid options: 'true', 'false'. Default: Undefined. +* `name`: Sets the name to use as the identity of the resource. This is necessary if you want the resource namevar to differ from the supplied `title` of the resource. Valid options: String. Default: Undefined. * `path`: **Required.** Defines the file in which Puppet will ensure the line specified by `line`. Must be an absolute path to the file. diff --git a/lib/puppet/provider/file_line/ruby.rb b/lib/puppet/provider/file_line/ruby.rb index e7854f0..c58e27e 100644 --- a/lib/puppet/provider/file_line/ruby.rb +++ b/lib/puppet/provider/file_line/ruby.rb @@ -61,20 +61,22 @@ Puppet::Type.type(:file_line).provide(:ruby) do def handle_create_with_after regex = Regexp.new(resource[:after]) count = count_matches(regex) - case count - when 1 # find the line to put our line after - File.open(resource[:path], 'w') do |fh| - lines.each do |l| - fh.puts(l) - if regex.match(l) then - fh.puts(resource[:line]) - end + + if count > 1 && resource[:multiple].to_s != 'true' + raise Puppet::Error, "#{count} lines match pattern '#{resource[:after]}' in file '#{resource[:path]}'. One or no line must match the pattern." + end + + File.open(resource[:path], 'w') do |fh| + lines.each do |l| + fh.puts(l) + if regex.match(l) then + fh.puts(resource[:line]) end end - when 0 # append the line to the end of the file + end + + if (count == 0) # append the line to the end of the file append_line - else - raise Puppet::Error, "#{count} lines match pattern '#{resource[:after]}' in file '#{resource[:path]}'. One or no line must match the pattern." end end diff --git a/spec/unit/puppet/provider/file_line/ruby_spec.rb b/spec/unit/puppet/provider/file_line/ruby_spec.rb index a84fc78..8fe3932 100755 --- a/spec/unit/puppet/provider/file_line/ruby_spec.rb +++ b/spec/unit/puppet/provider/file_line/ruby_spec.rb @@ -201,7 +201,7 @@ describe provider_class do end end - context 'with two lines matching the after expression' do + context 'with multiple lines matching the after expression' do before :each do File.open(@tmpfile, 'w') do |fh| fh.write("foo1\nfoo = blah\nfoo2\nfoo1\nfoo = baz") @@ -211,6 +211,22 @@ describe provider_class do it 'errors out stating "One or no line must match the pattern"' do expect { provider.create }.to raise_error(Puppet::Error, /One or no line must match the pattern/) end + + it 'adds the line after all lines matching the after expression' do + @resource = Puppet::Type::File_line.new( + { + :name => 'foo', + :path => @tmpfile, + :line => 'inserted = line', + :after => '^foo1$', + :multiple => true, + } + ) + @provider = provider_class.new(@resource) + expect(@provider.exists?).to be_nil + @provider.create + expect(File.read(@tmpfile).chomp).to eql("foo1\ninserted = line\nfoo = blah\nfoo2\nfoo1\ninserted = line\nfoo = baz") + end end context 'with no lines matching the after expression' do -- cgit v1.2.3 From 687600c30cb4279c36215517c02ee8e5e7c0d3cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Igor=20Gali=C4=87?= Date: Fri, 29 May 2015 20:13:21 +0200 Subject: simplify mac address regex let the computer do the counting and repetition and case --- lib/puppet/parser/functions/is_mac_address.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/puppet/parser/functions/is_mac_address.rb b/lib/puppet/parser/functions/is_mac_address.rb index 1b3088a..2619d44 100644 --- a/lib/puppet/parser/functions/is_mac_address.rb +++ b/lib/puppet/parser/functions/is_mac_address.rb @@ -15,7 +15,7 @@ Returns true if the string passed to this function is a valid mac address. mac = arguments[0] - if /^[a-fA-F0-9]{1,2}:[a-fA-F0-9]{1,2}:[a-fA-F0-9]{1,2}:[a-fA-F0-9]{1,2}:[a-fA-F0-9]{1,2}:[a-fA-F0-9]{1,2}$/.match(mac) then + if /^[a-f0-9]{1,2}(:[a-f0-9]{1,2}){5}$/i.match(mac) then return true else return false -- cgit v1.2.3 From 080d1637f028f8b08221ffd3b7e0ef7aa9eddd73 Mon Sep 17 00:00:00 2001 From: David Schmitt Date: Mon, 1 Jun 2015 12:21:58 +0100 Subject: Enable bundler caching on travis --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 371586b..7268682 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,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'" matrix: -- cgit v1.2.3 From 65b56c711dc882d7d7f8e26c4e020a6beb297c75 Mon Sep 17 00:00:00 2001 From: David Schmitt Date: Mon, 1 Jun 2015 12:21:59 +0100 Subject: Workaround the broken rspec-mocks support in rspec-puppet --- spec/spec_helper.rb | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 896cb83..ccc4d95 100755 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -19,6 +19,9 @@ require 'puppet_spec/database' require 'monkey_patches/alias_should_to_must' require 'mocha/api' +# 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.before :each do # Ensure that we don't accidentally cache facts and environment between @@ -29,5 +32,12 @@ RSpec.configure do |config| Facter.clear_messages Puppet[:parser] = 'future' if ENV['FUTURE_PARSER'] == 'yes' + + RSpec::Mocks.setup + end + + config.after :each do + RSpec::Mocks.verify + RSpec::Mocks.teardown end end -- cgit v1.2.3 From ad7d12e460599995b5b53b9d05881a9a547425d0 Mon Sep 17 00:00:00 2001 From: David Schmitt Date: Mon, 1 Jun 2015 12:21:59 +0100 Subject: Remove duplicate rake task and enable metadata.json linting The :validate task is already provided by puppetlabs_spec_helper/rake_tasks and would check files twice. The metadata.json linting is just good form. --- Gemfile | 1 + Rakefile | 12 ------------ 2 files changed, 1 insertion(+), 12 deletions(-) diff --git a/Gemfile b/Gemfile index 82a5204..9d38f35 100644 --- a/Gemfile +++ b/Gemfile @@ -17,6 +17,7 @@ group :development, :unit_tests do gem 'mocha', :require => false 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 end diff --git a/Rakefile b/Rakefile index 4ed1327..13ee3d9 100644 --- a/Rakefile +++ b/Rakefile @@ -4,15 +4,3 @@ require 'puppet-lint/tasks/puppet-lint' PuppetLint.configuration.send('disable_80chars') PuppetLint.configuration.ignore_paths = ["spec/**/*.pp", "pkg/**/*.pp"] -desc "Validate manifests, templates, and ruby files in lib." -task :validate do - Dir['manifests/**/*.pp'].each do |manifest| - sh "puppet parser validate --noop #{manifest}" - end - Dir['lib/**/*.rb'].each do |lib_file| - sh "ruby -c #{lib_file}" - end - Dir['templates/**/*.erb'].each do |template| - sh "erb -P -x -T '-' #{template} | ruby -c" - end -end -- cgit v1.2.3 From 1fcce9082fd918100d7d6eaa5dc5c90cebb39bc9 Mon Sep 17 00:00:00 2001 From: David Schmitt Date: Mon, 1 Jun 2015 12:21:59 +0100 Subject: root all the gitignore patterns to avoid unintentional matches --- .gitignore | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/.gitignore b/.gitignore index b5db85e..c64330e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,9 +1,9 @@ -pkg/ -Gemfile.lock -vendor/ -spec/fixtures/ -.vagrant/ -.bundle/ -coverage/ -.idea/ +/pkg/ +/Gemfile.lock +/vendor/ +/spec/fixtures/ +/.vagrant/ +/.bundle/ +/coverage/ +/.idea/ *.iml -- cgit v1.2.3 From 78bd9c8cbea75ae21ca7403d19ff952f77617585 Mon Sep 17 00:00:00 2001 From: David Schmitt Date: Mon, 1 Jun 2015 12:21:59 +0100 Subject: Add the missing symlinks to get puppet 4 pickup the functions from the environmentpath --- .gitignore | 5 ++++- spec/fixtures/modules/stdlib/lib | 1 + spec/fixtures/modules/stdlib/manifests | 1 + 3 files changed, 6 insertions(+), 1 deletion(-) create mode 120000 spec/fixtures/modules/stdlib/lib create mode 120000 spec/fixtures/modules/stdlib/manifests diff --git a/.gitignore b/.gitignore index c64330e..37c4f59 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,10 @@ /pkg/ /Gemfile.lock /vendor/ -/spec/fixtures/ +/spec/fixtures/manifests/* +/spec/fixtures/modules/* +!/spec/fixtures/modules/stdlib +!/spec/fixtures/modules/stdlib/* /.vagrant/ /.bundle/ /coverage/ diff --git a/spec/fixtures/modules/stdlib/lib b/spec/fixtures/modules/stdlib/lib new file mode 120000 index 0000000..b6ce6cc --- /dev/null +++ b/spec/fixtures/modules/stdlib/lib @@ -0,0 +1 @@ +../../../../lib/ \ No newline at end of file diff --git a/spec/fixtures/modules/stdlib/manifests b/spec/fixtures/modules/stdlib/manifests new file mode 120000 index 0000000..cdcdae0 --- /dev/null +++ b/spec/fixtures/modules/stdlib/manifests @@ -0,0 +1 @@ +../../../../manifests/ \ No newline at end of file -- cgit v1.2.3 From b62dff0c6e09faf9bacfb02575e689ed09ee5e56 Mon Sep 17 00:00:00 2001 From: David Schmitt Date: Mon, 1 Jun 2015 12:21:59 +0100 Subject: spec_helper: implement an easy way for specs to confine to puppet version Usage: describe 'puppet3 behaviour', :unless => RSpec.configuration.puppet_future do describe 'puppet4 behaviour', :if => RSpec.configuration.puppet_future do --- spec/spec_helper.rb | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index ccc4d95..be392fd 100755 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -23,6 +23,10 @@ require 'mocha/api' RSpec::Mocks::Syntax.enable_expect(RSpec::Puppet::ManifestMatchers) RSpec.configure do |config| + 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 -- cgit v1.2.3 From f3e79ddcd56a221c7799b35efde7e9803a5c7923 Mon Sep 17 00:00:00 2001 From: David Schmitt Date: Mon, 1 Jun 2015 12:21:59 +0100 Subject: Convert tests to use plain rspec-puppet Tests in the new style produces the following documentation output: abs should not eq nil should run abs() and raise an Puppet::ParseError should run abs(-34) and return 34 should run abs("-34") and return 34 should run abs(34) and return 34 should run abs("34") and return 34 --- Gemfile | 1 + Rakefile | 1 + lib/puppet/parser/functions/member.rb | 2 +- spec/acceptance/anchor_spec.rb | 26 +++ spec/classes/anchor_spec.rb | 30 --- spec/functions/abs_spec.rb | 39 ++-- spec/functions/any2array_spec.rb | 64 ++---- spec/functions/assert_private_spec.rb | 12 +- spec/functions/base64_spec.rb | 43 ++--- spec/functions/basename_spec.rb | 53 +---- spec/functions/bool2num_spec.rb | 38 +--- spec/functions/bool2str_spec.rb | 49 +---- spec/functions/camelcase_spec.rb | 35 ++-- spec/functions/capitalize_spec.rb | 37 ++-- spec/functions/ceiling_spec.rb | 44 +---- spec/functions/chomp_spec.rb | 40 ++-- spec/functions/chop_spec.rb | 40 ++-- spec/functions/concat_spec.rb | 62 ++---- spec/functions/count_spec.rb | 43 ++--- spec/functions/deep_merge_spec.rb | 144 +++++--------- spec/functions/defined_with_params_spec.rb | 29 +-- spec/functions/delete_at_spec.rb | 37 ++-- spec/functions/delete_spec.rb | 102 +++++----- spec/functions/delete_undef_values_spec.rb | 85 ++++---- spec/functions/delete_values_spec.rb | 57 +++--- spec/functions/difference_spec.rb | 34 ++-- spec/functions/dirname_spec.rb | 45 +---- spec/functions/downcase_spec.rb | 42 ++-- spec/functions/empty_spec.rb | 42 ++-- spec/functions/ensure_packages_spec.rb | 105 +++------- spec/functions/ensure_resource_spec.rb | 128 ++++-------- spec/functions/flatten_spec.rb | 35 ++-- spec/functions/floor_spec.rb | 45 +---- spec/functions/fqdn_rand_string_spec.rb | 72 +++---- spec/functions/fqdn_rotate_spec.rb | 71 +++---- spec/functions/get_module_path_spec.rb | 60 +++--- spec/functions/getparam_spec.rb | 90 +++------ spec/functions/getvar_spec.rb | 47 ++--- spec/functions/grep_spec.rb | 32 +-- spec/functions/has_interface_with_spec.rb | 80 +++----- spec/functions/has_ip_address_spec.rb | 45 ++--- spec/functions/has_ip_network_spec.rb | 42 ++-- spec/functions/has_key_spec.rb | 51 ++--- spec/functions/hash_spec.rb | 27 ++- spec/functions/intersection_spec.rb | 34 ++-- spec/functions/is_array_spec.rb | 42 ++-- spec/functions/is_bool_spec.rb | 53 ++--- spec/functions/is_domain_name_spec.rb | 108 ++++------- spec/functions/is_float_spec.rb | 41 ++-- spec/functions/is_function_available.rb | 34 +--- spec/functions/is_hash_spec.rb | 34 +--- spec/functions/is_integer_spec.rb | 88 +++------ spec/functions/is_ip_address_spec.rb | 56 ++---- spec/functions/is_mac_address_spec.rb | 47 ++--- spec/functions/is_numeric_spec.rb | 141 +++----------- spec/functions/is_string_spec.rb | 50 +++-- spec/functions/join_keys_to_values_spec.rb | 51 ++--- spec/functions/join_spec.rb | 30 +-- spec/functions/keys_spec.rb | 32 ++- spec/functions/loadyaml_spec.rb | 45 ++--- spec/functions/lstrip_spec.rb | 56 +++--- spec/functions/max_spec.rb | 38 ++-- spec/functions/member_spec.rb | 49 ++--- spec/functions/merge_spec.rb | 69 ++----- spec/functions/min_spec.rb | 38 ++-- spec/functions/num2bool_spec.rb | 83 ++------ spec/functions/parsejson_spec.rb | 25 +-- spec/functions/parseyaml_spec.rb | 28 +-- spec/functions/pick_default_spec.rb | 74 ++----- spec/functions/pick_spec.rb | 40 +--- spec/functions/prefix_spec.rb | 55 +++--- spec/functions/private_spec.rb | 16 +- spec/functions/pw_hash_spec.rb | 107 ++++------ spec/functions/range_spec.rb | 169 +++++++++------- spec/functions/reject_spec.rb | 31 ++- spec/functions/reverse_spec.rb | 45 +++-- spec/functions/rstrip_spec.rb | 61 +++--- spec/functions/shuffle_spec.rb | 48 ++--- spec/functions/size_spec.rb | 44 +++-- spec/functions/sort_spec.rb | 32 +-- spec/functions/squeeze_spec.rb | 50 +++-- spec/functions/str2bool_spec.rb | 40 ++-- spec/functions/str2saltedsha512_spec.rb | 50 ++--- spec/functions/strftime_spec.rb | 5 +- spec/functions/strip_spec.rb | 55 +++--- spec/functions/suffix_spec.rb | 65 ++++--- spec/functions/swapcase_spec.rb | 54 ++++-- spec/functions/time_spec.rb | 43 ++--- spec/functions/to_bytes_spec.rb | 147 +++++++------- spec/functions/type3x_spec.rb | 4 +- spec/functions/type_of_spec.rb | 24 ++- spec/functions/type_spec.rb | 4 +- spec/functions/union_spec.rb | 32 +-- spec/functions/unique_spec.rb | 44 ++--- spec/functions/upcase_spec.rb | 64 ++---- spec/functions/uriescape_spec.rb | 56 +++--- spec/functions/validate_absolute_path_spec.rb | 120 ++++-------- spec/functions/validate_array_spec.rb | 49 ++--- spec/functions/validate_augeas_spec.rb | 68 ++----- spec/functions/validate_bool_spec.rb | 64 ++---- spec/functions/validate_cmd_spec.rb | 104 +++------- spec/functions/validate_hash_spec.rb | 53 ++--- spec/functions/validate_integer_spec.rb | 268 +++++++------------------- spec/functions/validate_ipv4_address_spec.rb | 90 ++++----- spec/functions/validate_ipv6_address_spec.rb | 85 +++----- spec/functions/validate_numeric_spec.rb | 265 +++++++------------------ spec/functions/validate_re_spec.rb | 109 ++++------- spec/functions/validate_slength_spec.rb | 94 +++++---- spec/functions/validate_string_spec.rb | 65 ++----- spec/functions/values_at_spec.rb | 71 ++++--- spec/functions/values_spec.rb | 42 ++-- spec/functions/zip_spec.rb | 40 ++-- spec/puppetlabs_spec_helper_clone.rb | 34 ++++ spec/spec_helper.rb | 12 +- spec/unit/facter/util/puppet_settings_spec.rb | 1 + 115 files changed, 2432 insertions(+), 4139 deletions(-) create mode 100755 spec/acceptance/anchor_spec.rb delete mode 100755 spec/classes/anchor_spec.rb create mode 100644 spec/puppetlabs_spec_helper_clone.rb diff --git a/Gemfile b/Gemfile index 9d38f35..e35a729 100644 --- a/Gemfile +++ b/Gemfile @@ -15,6 +15,7 @@ group :development, :unit_tests do gem 'rspec', '~> 3.1.0', :require => false gem 'rspec-puppet', :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 diff --git a/Rakefile b/Rakefile index 13ee3d9..e136b8e 100644 --- a/Rakefile +++ b/Rakefile @@ -1,4 +1,5 @@ require 'rubygems' +# keep for compatibility for now require 'puppetlabs_spec_helper/rake_tasks' require 'puppet-lint/tasks/puppet-lint' PuppetLint.configuration.send('disable_80chars') diff --git a/lib/puppet/parser/functions/member.rb b/lib/puppet/parser/functions/member.rb index 88609ce..1e5b3de 100644 --- a/lib/puppet/parser/functions/member.rb +++ b/lib/puppet/parser/functions/member.rb @@ -44,7 +44,7 @@ would return: false end if arguments[1].is_a? String or arguments[1].is_a? Fixnum - item = Array(arguments[1]) + item = [arguments[1]] else item = arguments[1] end diff --git a/spec/acceptance/anchor_spec.rb b/spec/acceptance/anchor_spec.rb new file mode 100755 index 0000000..5bc2bbb --- /dev/null +++ b/spec/acceptance/anchor_spec.rb @@ -0,0 +1,26 @@ +require 'spec_helper_acceptance' + +describe 'anchor type', :unless => UNSUPPORTED_PLATFORMS.include?(fact('operatingsystem')) do + describe 'success' do + it 'should effect proper chaining of resources' do + pp = <<-EOS + class anchored { + anchor { 'anchored::begin': } + ~> anchor { 'anchored::end': } + } + + class anchorrefresh { + notify { 'first': } + ~> class { 'anchored': } + ~> anchor { 'final': } + } + + include anchorrefresh + EOS + + apply_manifest(pp, :catch_failures => true) do |r| + expect(r.stdout).to match(/Anchor\[final\]: Triggered 'refresh'/) + end + end + end +end diff --git a/spec/classes/anchor_spec.rb b/spec/classes/anchor_spec.rb deleted file mode 100755 index 2d4455e..0000000 --- a/spec/classes/anchor_spec.rb +++ /dev/null @@ -1,30 +0,0 @@ -#! /usr/bin/env ruby -S rspec -require 'spec_helper' -require 'puppet_spec/compiler' - -describe "anchorrefresh" do - include PuppetSpec::Compiler - - let :transaction do - apply_compiled_manifest(<<-ANCHORCLASS) - class anchored { - anchor { 'anchored::begin': } - ~> anchor { 'anchored::end': } - } - - class anchorrefresh { - notify { 'first': } - ~> class { 'anchored': } - ~> anchor { 'final': } - } - - include anchorrefresh - ANCHORCLASS - end - - it 'propagates events through the anchored class' do - resource = transaction.resource_status('Anchor[final]') - - expect(resource.restarted).to eq(true) - end -end diff --git a/spec/functions/abs_spec.rb b/spec/functions/abs_spec.rb index 3c25ce2..7d2257b 100755 --- a/spec/functions/abs_spec.rb +++ b/spec/functions/abs_spec.rb @@ -1,25 +1,30 @@ -#! /usr/bin/env ruby -S rspec - require 'spec_helper' -describe "the abs function" do - let(:scope) { PuppetlabsSpec::PuppetInternals.scope } - - it "should exist" do - expect(Puppet::Parser::Functions.function("abs")).to eq("function_abs") - end +describe 'abs' do + it { is_expected.not_to eq(nil) } - it "should raise a ParseError if there is less than 1 arguments" do - expect { scope.function_abs([]) }.to( raise_error(Puppet::ParseError)) + describe 'signature validation in puppet3', :unless => RSpec.configuration.puppet_future do + it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } + it { + pending("Current implementation ignores parameters after the first.") + is_expected.to run.with_params(1, 2).and_raise_error(Puppet::ParseError, /wrong number of arguments/i) + } end - it "should convert a negative number into a positive" do - result = scope.function_abs(["-34"]) - expect(result).to(eq(34)) + describe 'signature validation in puppet4', :if => RSpec.configuration.puppet_future do + it { pending "the puppet 4 implementation"; is_expected.to run.with_params().and_raise_error(ArgumentError) } + it { pending "the puppet 4 implementation"; is_expected.to run.with_params(1, 2).and_raise_error(ArgumentError) } + it { pending "the puppet 4 implementation"; is_expected.to run.with_params([]).and_raise_error(ArgumentError) } + it { pending "the puppet 4 implementation"; is_expected.to run.with_params({}).and_raise_error(ArgumentError) } + it { pending "the puppet 4 implementation"; is_expected.to run.with_params(true).and_raise_error(ArgumentError) } end - it "should do nothing with a positive number" do - result = scope.function_abs(["5678"]) - expect(result).to(eq(5678)) - end + it { is_expected.to run.with_params(-34).and_return(34) } + it { is_expected.to run.with_params("-34").and_return(34) } + it { is_expected.to run.with_params(34).and_return(34) } + it { is_expected.to run.with_params("34").and_return(34) } + it { is_expected.to run.with_params(-34.5).and_return(34.5) } + it { is_expected.to run.with_params("-34.5").and_return(34.5) } + it { is_expected.to run.with_params(34.5).and_return(34.5) } + it { is_expected.to run.with_params("34.5").and_return(34.5) } end diff --git a/spec/functions/any2array_spec.rb b/spec/functions/any2array_spec.rb index 87cd04b..70121f1 100755 --- a/spec/functions/any2array_spec.rb +++ b/spec/functions/any2array_spec.rb @@ -1,55 +1,15 @@ -#! /usr/bin/env ruby -S rspec require 'spec_helper' -describe "the any2array function" do - let(:scope) { PuppetlabsSpec::PuppetInternals.scope } - - it "should exist" do - expect(Puppet::Parser::Functions.function("any2array")).to eq("function_any2array") - end - - it "should return an empty array if there is less than 1 argument" do - result = scope.function_any2array([]) - expect(result).to(eq([])) - end - - it "should convert boolean true to [ true ] " do - result = scope.function_any2array([true]) - expect(result).to(eq([true])) - end - - it "should convert one object to [object]" do - result = scope.function_any2array(['one']) - expect(result).to(eq(['one'])) - end - - it "should convert multiple objects to [objects]" do - result = scope.function_any2array(['one', 'two']) - expect(result).to(eq(['one', 'two'])) - end - - it "should return empty array it was called with" do - result = scope.function_any2array([[]]) - expect(result).to(eq([])) - end - - it "should return one-member array it was called with" do - result = scope.function_any2array([['string']]) - expect(result).to(eq(['string'])) - end - - it "should return multi-member array it was called with" do - result = scope.function_any2array([['one', 'two']]) - expect(result).to(eq(['one', 'two'])) - end - - it "should return members of a hash it was called with" do - result = scope.function_any2array([{ 'key' => 'value' }]) - expect(result).to(eq(['key', 'value'])) - end - - it "should return an empty array if it was called with an empty hash" do - result = scope.function_any2array([{ }]) - expect(result).to(eq([])) - end +describe "any2array" do + it { is_expected.not_to eq(nil) } + it { is_expected.to run.with_params().and_return([]) } + it { is_expected.to run.with_params(true).and_return([true]) } + it { is_expected.to run.with_params('one').and_return(['one']) } + it { is_expected.to run.with_params('one', 'two').and_return(['one', 'two']) } + it { is_expected.to run.with_params([]).and_return([]) } + it { is_expected.to run.with_params(['one']).and_return(['one']) } + it { is_expected.to run.with_params(['one', 'two']).and_return(['one', 'two']) } + it { is_expected.to run.with_params({}).and_return([]) } + it { is_expected.to run.with_params({ 'key' => 'value' }).and_return(['key', 'value']) } + it { is_expected.to run.with_params({ 'key' => 'value' }).and_return(['key', 'value']) } end diff --git a/spec/functions/assert_private_spec.rb b/spec/functions/assert_private_spec.rb index a009d28..98f2598 100755 --- a/spec/functions/assert_private_spec.rb +++ b/spec/functions/assert_private_spec.rb @@ -1,15 +1,7 @@ -#! /usr/bin/env ruby -S rspec require 'spec_helper' -describe Puppet::Parser::Functions.function(:assert_private) do - let(:scope) { PuppetlabsSpec::PuppetInternals.scope } - - subject do - function_name = Puppet::Parser::Functions.function(:assert_private) - scope.method(function_name) - end - - context "when called from inside module" do +describe 'assert_private' do + context 'when called from inside module' do it "should not fail" do scope.expects(:lookupvar).with('module_name').returns('foo') scope.expects(:lookupvar).with('caller_module_name').returns('foo') diff --git a/spec/functions/base64_spec.rb b/spec/functions/base64_spec.rb index e93fafc..42512b3 100755 --- a/spec/functions/base64_spec.rb +++ b/spec/functions/base64_spec.rb @@ -1,34 +1,15 @@ -#! /usr/bin/env ruby -S rspec - require 'spec_helper' -describe "the base64 function" do - let(:scope) { PuppetlabsSpec::PuppetInternals.scope } - - it "should exist" do - expect(Puppet::Parser::Functions.function("base64")).to eq("function_base64") - end - - it "should raise a ParseError if there are other than 2 arguments" do - expect { scope.function_base64([]) }.to(raise_error(Puppet::ParseError)) - expect { scope.function_base64(["asdf"]) }.to(raise_error(Puppet::ParseError)) - expect { scope.function_base64(["asdf","moo","cow"]) }.to(raise_error(Puppet::ParseError)) - end - - it "should raise a ParseError if argument 1 isn't 'encode' or 'decode'" do - expect { scope.function_base64(["bees","astring"]) }.to(raise_error(Puppet::ParseError, /first argument must be one of/)) - end - - it "should raise a ParseError if argument 2 isn't a string" do - expect { scope.function_base64(["encode",["2"]]) }.to(raise_error(Puppet::ParseError, /second argument must be a string/)) - end - - it "should encode a encoded string" do - result = scope.function_base64(["encode",'thestring']) - expect(result).to match(/\AdGhlc3RyaW5n\n\Z/) - end - it "should decode a base64 encoded string" do - result = scope.function_base64(["decode",'dGhlc3RyaW5n']) - expect(result).to eq('thestring') - end +describe 'base64' do + it { is_expected.not_to eq(nil) } + it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError) } + it { is_expected.to run.with_params("one").and_raise_error(Puppet::ParseError) } + it { is_expected.to run.with_params("one", "two", "three").and_raise_error(Puppet::ParseError) } + it { is_expected.to run.with_params("one", "two").and_raise_error(Puppet::ParseError, /first argument must be one of/) } + it { is_expected.to run.with_params("encode", ["two"]).and_raise_error(Puppet::ParseError, /second argument must be a string/) } + it { is_expected.to run.with_params("encode", 2).and_raise_error(Puppet::ParseError, /second argument must be a string/) } + + it { is_expected.to run.with_params("encode", "thestring").and_return("dGhlc3RyaW5n\n") } + it { is_expected.to run.with_params("decode", "dGhlc3RyaW5n").and_return("thestring") } + it { is_expected.to run.with_params("decode", "dGhlc3RyaW5n\n").and_return("thestring") } end diff --git a/spec/functions/basename_spec.rb b/spec/functions/basename_spec.rb index 8a2d0dc..0ea30e7 100755 --- a/spec/functions/basename_spec.rb +++ b/spec/functions/basename_spec.rb @@ -1,46 +1,13 @@ -#! /usr/bin/env ruby -S rspec require 'spec_helper' -describe "the basename function" do - let(:scope) { PuppetlabsSpec::PuppetInternals.scope } - - it "should exist" do - Puppet::Parser::Functions.function("basename").should == "function_basename" - end - - it "should raise a ParseError if there is less than 1 argument" do - lambda { scope.function_basename([]) }.should( raise_error(Puppet::ParseError)) - end - - it "should raise a ParseError if there are more than 2 arguments" do - lambda { scope.function_basename(['a', 'b', 'c']) }.should( raise_error(Puppet::ParseError)) - end - - it "should return basename for an absolute path" do - result = scope.function_basename(['/path/to/a/file.ext']) - result.should(eq('file.ext')) - end - - it "should return basename for a relative path" do - result = scope.function_basename(['path/to/a/file.ext']) - result.should(eq('file.ext')) - end - - it "should strip extention when extension specified (absolute path)" do - result = scope.function_basename(['/path/to/a/file.ext', '.ext']) - result.should(eq('file')) - end - - it "should strip extention when extension specified (relative path)" do - result = scope.function_basename(['path/to/a/file.ext', '.ext']) - result.should(eq('file')) - end - - it "should complain about non-string first argument" do - lambda { scope.function_basename([[]]) }.should( raise_error(Puppet::ParseError)) - end - - it "should complain about non-string second argument" do - lambda { scope.function_basename(['/path/to/a/file.ext', []]) }.should( raise_error(Puppet::ParseError)) - end +describe 'basename' do + it { is_expected.not_to eq(nil) } + it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError) } + it { is_expected.to run.with_params('one', 'two', 'three').and_raise_error(Puppet::ParseError) } + it { is_expected.to run.with_params([]).and_raise_error(Puppet::ParseError) } + it { is_expected.to run.with_params('/path/to/a/file.ext', []).and_raise_error(Puppet::ParseError) } + it { is_expected.to run.with_params('/path/to/a/file.ext').and_return('file.ext') } + it { is_expected.to run.with_params('relative_path/to/a/file.ext').and_return('file.ext') } + it { is_expected.to run.with_params('/path/to/a/file.ext', '.ext').and_return('file') } + it { is_expected.to run.with_params('relative_path/to/a/file.ext', '.ext').and_return('file') } end diff --git a/spec/functions/bool2num_spec.rb b/spec/functions/bool2num_spec.rb index 3904d7e..e506859 100755 --- a/spec/functions/bool2num_spec.rb +++ b/spec/functions/bool2num_spec.rb @@ -1,38 +1,14 @@ -#! /usr/bin/env ruby -S rspec require 'spec_helper' -describe "the bool2num function" do - let(:scope) { PuppetlabsSpec::PuppetInternals.scope } +describe 'bool2num' do + it { is_expected.not_to eq(nil) } + it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError) } - it "should exist" do - expect(Puppet::Parser::Functions.function("bool2num")).to eq("function_bool2num") + [ true, 'true', AlsoString.new('true') ].each do |truthy| + it { is_expected.to run.with_params(truthy).and_return(1) } end - it "should raise a ParseError if there is less than 1 arguments" do - expect { scope.function_bool2num([]) }.to( raise_error(Puppet::ParseError)) - end - - it "should convert true to 1" do - result = scope.function_bool2num([true]) - expect(result).to(eq(1)) - end - - it "should convert 'true' to 1" do - result = scope.function_bool2num(['true']) - result.should(eq(1)) - end - - it "should convert 'false' to 0" do - result = scope.function_bool2num(['false']) - expect(result).to(eq(0)) - end - - it "should accept objects which extend String" do - class AlsoString < String - end - - value = AlsoString.new('true') - result = scope.function_bool2num([value]) - result.should(eq(1)) + [ false, 'false', AlsoString.new('false') ].each do |falsey| + it { is_expected.to run.with_params(falsey).and_return(0) } end end diff --git a/spec/functions/bool2str_spec.rb b/spec/functions/bool2str_spec.rb index b878891..8d35598 100755 --- a/spec/functions/bool2str_spec.rb +++ b/spec/functions/bool2str_spec.rb @@ -1,46 +1,11 @@ -#! /usr/bin/env ruby -S rspec require 'spec_helper' -describe "the bool2str function" do - let(:scope) { PuppetlabsSpec::PuppetInternals.scope } - - it "should exist" do - expect(Puppet::Parser::Functions.function("bool2str")).to eq("function_bool2str") - end - - it "should raise a ParseError if there is less than 1 arguments" do - expect { scope.function_bool2str([]) }.to( raise_error(Puppet::ParseError)) - end - - it "should convert true to 'true'" do - result = scope.function_bool2str([true]) - expect(result).to(eq('true')) - end - - it "should convert true to a string" do - result = scope.function_bool2str([true]) - expect(result.class).to(eq(String)) - end - - it "should convert false to 'false'" do - result = scope.function_bool2str([false]) - expect(result).to(eq('false')) - end - - it "should convert false to a string" do - result = scope.function_bool2str([false]) - expect(result.class).to(eq(String)) - end - - it "should not accept a string" do - expect { scope.function_bool2str(["false"]) }.to( raise_error(Puppet::ParseError)) - end - - it "should not accept a nil value" do - expect { scope.function_bool2str([nil]) }.to( raise_error(Puppet::ParseError)) - end - - it "should not accept an undef" do - expect { scope.function_bool2str([:undef]) }.to( raise_error(Puppet::ParseError)) +describe 'bool2str' do + it { is_expected.not_to eq(nil) } + it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError) } + [ 'true', 'false', nil, :undef, ''].each do |invalid| + it { is_expected.to run.with_params(invalid).and_raise_error(Puppet::ParseError) } end + it { is_expected.to run.with_params(true).and_return("true") } + it { is_expected.to run.with_params(false).and_return("false") } end diff --git a/spec/functions/camelcase_spec.rb b/spec/functions/camelcase_spec.rb index 70382ad..c78aa62 100755 --- a/spec/functions/camelcase_spec.rb +++ b/spec/functions/camelcase_spec.rb @@ -1,24 +1,17 @@ -#! /usr/bin/env ruby -S rspec require 'spec_helper' -describe "the camelcase function" do - let(:scope) { PuppetlabsSpec::PuppetInternals.scope } - - it "should exist" do - expect(Puppet::Parser::Functions.function("camelcase")).to eq("function_camelcase") - end - - it "should raise a ParseError if there is less than 1 arguments" do - expect { scope.function_camelcase([]) }.to( raise_error(Puppet::ParseError)) - end - - it "should capitalize the beginning of a normal string" do - result = scope.function_camelcase(["abc"]) - expect(result).to(eq("Abc")) - end - - it "should camelcase an underscore-delimited string" do - result = scope.function_camelcase(["aa_bb_cc"]) - expect(result).to(eq("AaBbCc")) - end +describe 'camelcase' do + it { is_expected.not_to eq(nil) } + it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError) } + it { is_expected.to run.with_params(100).and_raise_error(Puppet::ParseError) } + it { is_expected.to run.with_params("abc").and_return("Abc") } + it { is_expected.to run.with_params("aa_bb_cc").and_return("AaBbCc") } + it { is_expected.to run.with_params("_aa__bb__cc_").and_return("AaBbCc") } + it { is_expected.to run.with_params("100").and_return("100") } + it { is_expected.to run.with_params("1_00").and_return("100") } + it { is_expected.to run.with_params("_").and_return("") } + it { is_expected.to run.with_params("").and_return("") } + it { is_expected.to run.with_params([]).and_return([]) } + it { is_expected.to run.with_params(["abc", "aa_bb_cc"]).and_return(["Abc", "AaBbCc"]) } + it { is_expected.to run.with_params(["abc", 1, "aa_bb_cc"]).and_return(["Abc", 1, "AaBbCc"]) } end diff --git a/spec/functions/capitalize_spec.rb b/spec/functions/capitalize_spec.rb index fd0e92b..7ce2e16 100755 --- a/spec/functions/capitalize_spec.rb +++ b/spec/functions/capitalize_spec.rb @@ -1,28 +1,15 @@ -#! /usr/bin/env ruby -S rspec require 'spec_helper' -describe "the capitalize function" do - let(:scope) { PuppetlabsSpec::PuppetInternals.scope } - - it "should exist" do - expect(Puppet::Parser::Functions.function("capitalize")).to eq("function_capitalize") - end - - it "should raise a ParseError if there is less than 1 arguments" do - expect { scope.function_capitalize([]) }.to( raise_error(Puppet::ParseError)) - end - - it "should capitalize the beginning of a string" do - result = scope.function_capitalize(["abc"]) - expect(result).to(eq("Abc")) - end - - it "should accept objects which extend String" do - class AlsoString < String - end - - value = AlsoString.new('abc') - result = scope.function_capitalize([value]) - result.should(eq('Abc')) - end +describe 'capitalize' do + it { is_expected.not_to eq(nil) } + it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError) } + it { is_expected.to run.with_params(100).and_raise_error(Puppet::ParseError) } + it { is_expected.to run.with_params("one").and_return("One") } + it { is_expected.to run.with_params("one two").and_return("One two") } + it { is_expected.to run.with_params("ONE TWO").and_return("One two") } + + it { is_expected.to run.with_params(AlsoString.new("one")).and_return("One") } + it { is_expected.to run.with_params([]).and_return([]) } + it { is_expected.to run.with_params(["one", "two"]).and_return(["One", "Two"]) } + it { is_expected.to run.with_params(["one", 1, "two"]).and_return(["One", 1, "Two"]) } end diff --git a/spec/functions/ceiling_spec.rb b/spec/functions/ceiling_spec.rb index 814aa7c..567426f 100755 --- a/spec/functions/ceiling_spec.rb +++ b/spec/functions/ceiling_spec.rb @@ -1,39 +1,13 @@ -#! /usr/bin/env ruby -S rspec - require 'spec_helper' -describe "the ceiling function" do - let(:scope) { PuppetlabsSpec::PuppetInternals.scope } - - it "should exist" do - expect(Puppet::Parser::Functions.function("ceiling")).to eq("function_ceiling") - end - - it "should raise a ParseError if there is less than 1 argument" do - expect { scope.function_ceiling([]) }.to( raise_error(Puppet::ParseError, /Wrong number of arguments/)) - end - - it "should should raise a ParseError if input isn't numeric (eg. String)" do - expect { scope.function_ceiling(["foo"]) }.to( raise_error(Puppet::ParseError, /Wrong argument type/)) - end - - it "should should raise a ParseError if input isn't numeric (eg. Boolean)" do - expect { scope.function_ceiling([true]) }.to( raise_error(Puppet::ParseError, /Wrong argument type/)) - end - - it "should return an integer when a numeric type is passed" do - result = scope.function_ceiling([12.4]) - expect(result.is_a?(Integer)).to(eq(true)) - end - - it "should return the input when an integer is passed" do - result = scope.function_ceiling([7]) - expect(result).to(eq(7)) - end - - it "should return the smallest integer greater than or equal to the input" do - result = scope.function_ceiling([3.8]) - expect(result).to(eq(4)) - end +describe 'ceiling' do + it { is_expected.not_to eq(nil) } + it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError) } + it { is_expected.to run.with_params("foo").and_raise_error(Puppet::ParseError) } + it { is_expected.to run.with_params([]).and_raise_error(Puppet::ParseError) } + it { is_expected.to run.with_params(34).and_return(34) } + it { is_expected.to run.with_params(-34).and_return(-34) } + it { is_expected.to run.with_params(33.1).and_return(34) } + it { is_expected.to run.with_params(-33.1).and_return(-33) } end diff --git a/spec/functions/chomp_spec.rb b/spec/functions/chomp_spec.rb index b1e1e60..6878742 100755 --- a/spec/functions/chomp_spec.rb +++ b/spec/functions/chomp_spec.rb @@ -1,28 +1,20 @@ -#! /usr/bin/env ruby -S rspec require 'spec_helper' -describe "the chomp function" do - let(:scope) { PuppetlabsSpec::PuppetInternals.scope } +describe 'chomp' do + it { is_expected.not_to eq(nil) } + it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError) } + it { is_expected.to run.with_params(1).and_raise_error(Puppet::ParseError) } + it { + pending("Current implementation ignores parameters after the first.") + is_expected.to run.with_params("a", "b").and_raise_error(Puppet::ParseError) + } + it { is_expected.to run.with_params("one").and_return("one") } + it { is_expected.to run.with_params("one\n").and_return("one") } + it { is_expected.to run.with_params("one\n\n").and_return("one\n") } + it { is_expected.to run.with_params(["one\n", "two", "three\n"]).and_return(["one", "two", "three"]) } - it "should exist" do - expect(Puppet::Parser::Functions.function("chomp")).to eq("function_chomp") - end - - it "should raise a ParseError if there is less than 1 arguments" do - expect { scope.function_chomp([]) }.to( raise_error(Puppet::ParseError)) - end - - it "should chomp the end of a string" do - result = scope.function_chomp(["abc\n"]) - expect(result).to(eq("abc")) - end - - it "should accept objects which extend String" do - class AlsoString < String - end - - value = AlsoString.new("abc\n") - result = scope.function_chomp([value]) - result.should(eq("abc")) - end + it { is_expected.to run.with_params(AlsoString.new("one")).and_return("one") } + it { is_expected.to run.with_params(AlsoString.new("one\n")).and_return("one") } + it { is_expected.to run.with_params(AlsoString.new("one\n\n")).and_return("one\n") } + it { is_expected.to run.with_params([AlsoString.new("one\n"), AlsoString.new("two"), "three\n"]).and_return(["one", "two", "three"]) } end diff --git a/spec/functions/chop_spec.rb b/spec/functions/chop_spec.rb index c8a1951..db7d18b 100755 --- a/spec/functions/chop_spec.rb +++ b/spec/functions/chop_spec.rb @@ -1,28 +1,20 @@ -#! /usr/bin/env ruby -S rspec require 'spec_helper' -describe "the chop function" do - let(:scope) { PuppetlabsSpec::PuppetInternals.scope } +describe 'chop' do + it { is_expected.not_to eq(nil) } + it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError) } + it { is_expected.to run.with_params(1).and_raise_error(Puppet::ParseError) } + it { + pending("Current implementation ignores parameters after the first.") + is_expected.to run.with_params("a", "b").and_raise_error(Puppet::ParseError) + } + it { is_expected.to run.with_params("one").and_return("on") } + it { is_expected.to run.with_params("one\n").and_return("one") } + it { is_expected.to run.with_params("one\n\n").and_return("one\n") } + it { is_expected.to run.with_params(["one\n", "two", "three\n"]).and_return(["one", "tw", "three"]) } - it "should exist" do - expect(Puppet::Parser::Functions.function("chop")).to eq("function_chop") - end - - it "should raise a ParseError if there is less than 1 arguments" do - expect { scope.function_chop([]) }.to( raise_error(Puppet::ParseError)) - end - - it "should chop the end of a string" do - result = scope.function_chop(["asdf\n"]) - expect(result).to(eq("asdf")) - end - - it "should accept objects which extend String" do - class AlsoString < String - end - - value = AlsoString.new("abc\n") - result = scope.function_chop([value]) - result.should(eq('abc')) - end + it { is_expected.to run.with_params(AlsoString.new("one")).and_return("on") } + it { is_expected.to run.with_params(AlsoString.new("one\n")).and_return("one") } + it { is_expected.to run.with_params(AlsoString.new("one\n\n")).and_return("one\n") } + it { is_expected.to run.with_params([AlsoString.new("one\n"), AlsoString.new("two"), "three\n"]).and_return(["one", "tw", "three"]) } end diff --git a/spec/functions/concat_spec.rb b/spec/functions/concat_spec.rb index 49fa6bb..1694d5e 100755 --- a/spec/functions/concat_spec.rb +++ b/spec/functions/concat_spec.rb @@ -1,50 +1,24 @@ -#! /usr/bin/env ruby -S rspec require 'spec_helper' -describe "the concat function" do - let(:scope) { PuppetlabsSpec::PuppetInternals.scope } - - it "should raise a ParseError if the client does not provide at least two arguments" do - expect { scope.function_concat([]) }.to(raise_error(Puppet::ParseError)) - expect { scope.function_concat([[1]]) }.to(raise_error(Puppet::ParseError)) - end - - it "should raise a ParseError if the first parameter is not an array" do - expect { scope.function_concat([1, []])}.to(raise_error(Puppet::ParseError)) - end - - it "should not raise a ParseError if the client provides more than two arguments" do - expect { scope.function_concat([[1],[2],[3]]) }.not_to raise_error - end - - it "should be able to concat an array" do - result = scope.function_concat([['1','2','3'],['4','5','6']]) - expect(result).to(eq(['1','2','3','4','5','6'])) - end - - it "should be able to concat a primitive to an array" do - result = scope.function_concat([['1','2','3'],'4']) - expect(result).to(eq(['1','2','3','4'])) - end - - it "should not accidentally flatten nested arrays" do - result = scope.function_concat([['1','2','3'],[['4','5'],'6']]) - expect(result).to(eq(['1','2','3',['4','5'],'6'])) - end +describe 'concat' do + it { is_expected.not_to eq(nil) } + it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError) } + it { is_expected.to run.with_params([1]).and_raise_error(Puppet::ParseError) } + it { is_expected.to run.with_params(1, [2]).and_raise_error(Puppet::ParseError) } + it { is_expected.to run.with_params([1], [2], [3]).and_return([1, 2, 3]) } + 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').and_return(['1','2','3','4']) } + 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 "should leave the original array intact" do - array_original = ['1','2','3'] - result = scope.function_concat([array_original,['4','5','6']]) - array_original.should(eq(['1','2','3'])) - end - - it "should be able to concat multiple arrays" do - result = scope.function_concat([['1','2','3'],['4','5','6'],['7','8','9']]) - expect(result).to(eq(['1','2','3','4','5','6','7','8','9'])) - end - - it "should be able to concat mix of primitives and arrays to a final array" do - result = scope.function_concat([['1','2','3'],'4',['5','6','7']]) - expect(result).to(eq(['1','2','3','4','5','6','7'])) + argument1 = ['1','2','3'] + original1 = argument1.dup + argument2 = ['4','5','6'] + original2 = argument2.dup + result = subject.call([argument1,argument2]) + expect(argument1).to eq(original1) + expect(argument2).to eq(original2) end end diff --git a/spec/functions/count_spec.rb b/spec/functions/count_spec.rb index f8f1d48..c8d1960 100755 --- a/spec/functions/count_spec.rb +++ b/spec/functions/count_spec.rb @@ -1,31 +1,18 @@ -#! /usr/bin/env ruby -S rspec - require 'spec_helper' -describe "the count function" do - let(:scope) { PuppetlabsSpec::PuppetInternals.scope } - - it "should exist" do - expect(Puppet::Parser::Functions.function("count")).to eq("function_count") - end - - it "should raise a ArgumentError if there is more than 2 arguments" do - expect { scope.function_count(['foo', 'bar', 'baz']) }.to( raise_error(ArgumentError)) - end - - it "should be able to count arrays" do - expect(scope.function_count([["1","2","3"]])).to(eq(3)) - end - - it "should be able to count matching elements in arrays" do - expect(scope.function_count([["1", "2", "2"], "2"])).to(eq(2)) - end - - it "should not count nil or empty strings" do - expect(scope.function_count([["foo","bar",nil,""]])).to(eq(2)) - end - - it 'does not count an undefined hash key or an out of bound array index (which are both :undef)' do - expect(scope.function_count([["foo",:undef,:undef]])).to eq(1) - end +describe 'count' do + it { is_expected.not_to eq(nil) } + it { is_expected.to run.with_params().and_raise_error(ArgumentError) } + it { is_expected.to run.with_params("one").and_raise_error(ArgumentError) } + it { is_expected.to run.with_params("one", "two").and_return(1) } + it { + pending("should actually be like this, and not like above") + is_expected.to run.with_params("one", "two").and_raise_error(ArgumentError) + } + it { is_expected.to run.with_params("one", "two", "three").and_raise_error(ArgumentError) } + it { is_expected.to run.with_params(["one", "two", "three"]).and_return(3) } + it { is_expected.to run.with_params(["one", "two", "two"], "two").and_return(2) } + it { is_expected.to run.with_params(["one", nil, "two"]).and_return(2) } + it { is_expected.to run.with_params(["one", "", "two"]).and_return(2) } + it { is_expected.to run.with_params(["one", :undef, "two"]).and_return(2) } end diff --git a/spec/functions/deep_merge_spec.rb b/spec/functions/deep_merge_spec.rb index 7087904..397e048 100755 --- a/spec/functions/deep_merge_spec.rb +++ b/spec/functions/deep_merge_spec.rb @@ -1,105 +1,55 @@ -#! /usr/bin/env ruby -S rspec - require 'spec_helper' -describe Puppet::Parser::Functions.function(:deep_merge) do - let(:scope) { PuppetlabsSpec::PuppetInternals.scope } - - describe 'when calling deep_merge from puppet' do - it "should not compile when no arguments are passed" do - skip("Fails on 2.6.x, see bug #15912") if Puppet.version =~ /^2\.6\./ - Puppet[:code] = '$x = deep_merge()' - expect { - scope.compiler.compile - }.to raise_error(Puppet::ParseError, /wrong number of arguments/) - end - - it "should not compile when 1 argument is passed" do - skip("Fails on 2.6.x, see bug #15912") if Puppet.version =~ /^2\.6\./ - Puppet[:code] = "$my_hash={'one' => 1}\n$x = deep_merge($my_hash)" - expect { - scope.compiler.compile - }.to raise_error(Puppet::ParseError, /wrong number of arguments/) - end +describe 'deep_merge' do + it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } + it { is_expected.to run.with_params({ 'key' => 'value' }).and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } + it { is_expected.to run.with_params({}, '2').and_raise_error(Puppet::ParseError, /unexpected argument type String/) } + it { is_expected.to run.with_params({}, 2).and_raise_error(Puppet::ParseError, /unexpected argument type Fixnum/) } + it { is_expected.to run.with_params({}, '').and_return({}) } + it { is_expected.to run.with_params({}, {}).and_return({}) } + it { is_expected.to run.with_params({}, {}, {}).and_return({}) } + it { is_expected.to run.with_params({}, {}, {}, {}).and_return({}) } + it { is_expected.to run.with_params({'key' => 'value'}, '').and_return({'key' => 'value'}) } + it { is_expected.to run.with_params({'key1' => 'value1'}, {'key2' => 'value2' }).and_return({'key1' => 'value1', 'key2' => 'value2'}) } + + describe 'when arguments have key collisions' do + it 'should prefer values from the last hash' do + is_expected.to run \ + .with_params( + {'key1' => 'value1', 'key2' => 'value2' }, + {'key2' => 'replacement_value', 'key3' => 'value3'}) \ + .and_return( + {'key1' => 'value1', 'key2' => 'replacement_value', 'key3' => 'value3'}) + end + it { is_expected.to run \ + .with_params({'key1' => 'value1'}, {'key1' => 'value2'}, {'key1' => 'value3'}) \ + .and_return({'key1' => 'value3' }) + } end - describe 'when calling deep_merge on the scope instance' do - it 'should require all parameters are hashes' do - expect { new_hash = scope.function_deep_merge([{}, '2'])}.to raise_error(Puppet::ParseError, /unexpected argument type String/) - expect { new_hash = scope.function_deep_merge([{}, 2])}.to raise_error(Puppet::ParseError, /unexpected argument type Fixnum/) - end - - it 'should accept empty strings as puppet undef' do - expect { new_hash = scope.function_deep_merge([{}, ''])}.not_to raise_error - end - - it 'should be able to deep_merge two hashes' do - new_hash = scope.function_deep_merge([{'one' => '1', 'two' => '1'}, {'two' => '2', 'three' => '2'}]) - expect(new_hash['one']).to eq('1') - expect(new_hash['two']).to eq('2') - expect(new_hash['three']).to eq('2') - end - - it 'should deep_merge multiple hashes' do - hash = scope.function_deep_merge([{'one' => 1}, {'one' => '2'}, {'one' => '3'}]) - expect(hash['one']).to eq('3') - end - - it 'should accept empty hashes' do - expect(scope.function_deep_merge([{},{},{}])).to eq({}) - end - - it 'should deep_merge subhashes' do - hash = scope.function_deep_merge([{'one' => 1}, {'two' => 2, 'three' => { 'four' => 4 } }]) - expect(hash['one']).to eq(1) - expect(hash['two']).to eq(2) - expect(hash['three']).to eq({ 'four' => 4 }) - end - - it 'should append to subhashes' do - hash = scope.function_deep_merge([{'one' => { 'two' => 2 } }, { 'one' => { 'three' => 3 } }]) - expect(hash['one']).to eq({ 'two' => 2, 'three' => 3 }) - end - - it 'should append to subhashes 2' do - hash = scope.function_deep_merge([{'one' => 1, 'two' => 2, 'three' => { 'four' => 4 } }, {'two' => 'dos', 'three' => { 'five' => 5 } }]) - expect(hash['one']).to eq(1) - expect(hash['two']).to eq('dos') - expect(hash['three']).to eq({ 'four' => 4, 'five' => 5 }) - end - - it 'should append to subhashes 3' do - hash = scope.function_deep_merge([{ 'key1' => { 'a' => 1, 'b' => 2 }, 'key2' => { 'c' => 3 } }, { 'key1' => { 'b' => 99 } }]) - expect(hash['key1']).to eq({ 'a' => 1, 'b' => 99 }) - expect(hash['key2']).to eq({ 'c' => 3 }) - end - - it 'should not change the original hashes' do - hash1 = {'one' => { 'two' => 2 } } - hash2 = { 'one' => { 'three' => 3 } } - hash = scope.function_deep_merge([hash1, hash2]) - expect(hash1).to eq({'one' => { 'two' => 2 } }) - expect(hash2).to eq({ 'one' => { 'three' => 3 } }) - expect(hash['one']).to eq({ 'two' => 2, 'three' => 3 }) - end + describe 'when arguments have subhashes' do + it { is_expected.to run \ + .with_params({'key1' => 'value1'}, {'key2' => 'value2', 'key3' => {'subkey1' => 'value4'}}) \ + .and_return( {'key1' => 'value1', 'key2' => 'value2', 'key3' => {'subkey1' => 'value4'}}) + } + it { is_expected.to run \ + .with_params({'key1' => {'subkey1' => 'value1'}}, {'key1' => {'subkey2' => 'value2'}}) \ + .and_return( {'key1' => {'subkey1' => 'value1', 'subkey2' => 'value2'}}) + } + it { is_expected.to run \ + .with_params({'key1' => {'subkey1' => {'subsubkey1' => 'value1'}}}, {'key1' => {'subkey1' => {'subsubkey1' => 'value2'}}}) \ + .and_return( {'key1' => {'subkey1' => {'subsubkey1' => 'value2'}}}) + } + end - it 'should not change the original hashes 2' do - hash1 = {'one' => { 'two' => [1,2] } } - hash2 = { 'one' => { 'three' => 3 } } - hash = scope.function_deep_merge([hash1, hash2]) - expect(hash1).to eq({'one' => { 'two' => [1,2] } }) - expect(hash2).to eq({ 'one' => { 'three' => 3 } }) - expect(hash['one']).to eq({ 'two' => [1,2], 'three' => 3 }) - end + it 'should not change the original hashes' do + argument1 = { 'key1' => 'value1' } + original1 = argument1.dup + argument2 = { 'key2' => 'value2' } + original2 = argument2.dup - it 'should not change the original hashes 3' do - hash1 = {'one' => { 'two' => [1,2, {'two' => 2} ] } } - hash2 = { 'one' => { 'three' => 3 } } - hash = scope.function_deep_merge([hash1, hash2]) - expect(hash1).to eq({'one' => { 'two' => [1,2, {'two' => 2}] } }) - expect(hash2).to eq({ 'one' => { 'three' => 3 } }) - expect(hash['one']).to eq({ 'two' => [1,2, {'two' => 2} ], 'three' => 3 }) - expect(hash['one']['two']).to eq([1,2, {'two' => 2}]) - end + subject.call([argument1, argument2]) + expect(argument1).to eq(original1) + expect(argument2).to eq(original2) end end diff --git a/spec/functions/defined_with_params_spec.rb b/spec/functions/defined_with_params_spec.rb index 3590304..516d986 100755 --- a/spec/functions/defined_with_params_spec.rb +++ b/spec/functions/defined_with_params_spec.rb @@ -1,37 +1,26 @@ -#! /usr/bin/env ruby -S rspec require 'spec_helper' -require 'rspec-puppet' describe 'defined_with_params' do - describe 'when a resource is not specified' do + describe 'when no resource is specified' do it { is_expected.to run.with_params().and_raise_error(ArgumentError) } end describe 'when compared against a resource with no attributes' do let :pre_condition do 'user { "dan": }' end - it do - is_expected.to run.with_params('User[dan]', {}).and_return(true) - is_expected.to run.with_params('User[bob]', {}).and_return(false) - is_expected.to run.with_params('User[dan]', {'foo' => 'bar'}).and_return(false) - end + it { is_expected.to run.with_params('User[dan]', {}).and_return(true) } + it { is_expected.to run.with_params('User[bob]', {}).and_return(false) } + it { is_expected.to run.with_params('User[dan]', {'foo' => 'bar'}).and_return(false) } end describe 'when compared against a resource with attributes' do let :pre_condition do 'user { "dan": ensure => present, shell => "/bin/csh", managehome => false}' end - it do - is_expected.to run.with_params('User[dan]', {}).and_return(true) - is_expected.to run.with_params('User[dan]', '').and_return(true) - is_expected.to run.with_params('User[dan]', {'ensure' => 'present'} - ).and_return(true) - is_expected.to run.with_params('User[dan]', - {'ensure' => 'present', 'managehome' => false} - ).and_return(true) - is_expected.to run.with_params('User[dan]', - {'ensure' => 'absent', 'managehome' => false} - ).and_return(false) - end + it { is_expected.to run.with_params('User[dan]', {}).and_return(true) } + it { is_expected.to run.with_params('User[dan]', '').and_return(true) } + it { is_expected.to run.with_params('User[dan]', {'ensure' => 'present'}).and_return(true) } + it { is_expected.to run.with_params('User[dan]', {'ensure' => 'present', 'managehome' => false}).and_return(true) } + it { is_expected.to run.with_params('User[dan]', {'ensure' => 'absent', 'managehome' => false}).and_return(false) } end end diff --git a/spec/functions/delete_at_spec.rb b/spec/functions/delete_at_spec.rb index 7c20aec..0e19472 100755 --- a/spec/functions/delete_at_spec.rb +++ b/spec/functions/delete_at_spec.rb @@ -1,25 +1,28 @@ -#! /usr/bin/env ruby -S rspec require 'spec_helper' -describe "the delete_at function" do - let(:scope) { PuppetlabsSpec::PuppetInternals.scope } +describe 'delete_at' do + it { is_expected.not_to eq(nil) } + it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError) } + it { is_expected.to run.with_params('one', 1).and_raise_error(Puppet::ParseError) } + it { is_expected.to run.with_params(1, 1).and_raise_error(Puppet::ParseError) } + it { is_expected.to run.with_params(['one'], 'two').and_raise_error(Puppet::ParseError) } + it { + pending("Current implementation ignores parameters after the first two.") + is_expected.to run.with_params(['one'], 0, 1).and_raise_error(Puppet::ParseError) + } - it "should exist" do - expect(Puppet::Parser::Functions.function("delete_at")).to eq("function_delete_at") + describe 'argument validation' do + it { is_expected.to run.with_params([0, 1, 2], 3).and_raise_error(Puppet::ParseError) } end - it "should raise a ParseError if there is less than 1 arguments" do - expect { scope.function_delete_at([]) }.to( raise_error(Puppet::ParseError)) - end - - it "should delete an item at specified location from an array" do - result = scope.function_delete_at([['a','b','c'],1]) - expect(result).to(eq(['a','c'])) - end + it { is_expected.to run.with_params([0, 1, 2], 1).and_return([0, 2]) } + it { is_expected.to run.with_params([0, 1, 2], -1).and_return([0, 1]) } + it { is_expected.to run.with_params([0, 1, 2], -4).and_return([0, 1, 2]) } - it "should not change origin array passed as argument" do - origin_array = ['a','b','c','d'] - result = scope.function_delete_at([origin_array, 1]) - expect(origin_array).to(eq(['a','b','c','d'])) + it "should leave the original array intact" do + argument = [1, 2, 3] + original = argument.dup + result = subject.call([argument,2]) + expect(argument).to eq(original) end end diff --git a/spec/functions/delete_spec.rb b/spec/functions/delete_spec.rb index c8edd78..6c4747b 100755 --- a/spec/functions/delete_spec.rb +++ b/spec/functions/delete_spec.rb @@ -1,61 +1,67 @@ -#! /usr/bin/env ruby -S rspec require 'spec_helper' -describe "the delete function" do - let(:scope) { PuppetlabsSpec::PuppetInternals.scope } +describe 'delete' do + it { is_expected.not_to eq(nil) } + it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError) } + it { is_expected.to run.with_params([]).and_raise_error(Puppet::ParseError) } + it { is_expected.to run.with_params([], 'two', 'three').and_raise_error(Puppet::ParseError) } + it { is_expected.to run.with_params(1, 'two').and_raise_error(TypeError) } - it "should exist" do - expect(Puppet::Parser::Functions.function("delete")).to eq("function_delete") + describe 'deleting from an array' do + it { is_expected.to run.with_params([], '').and_return([]) } + 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'], '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']) } + it { is_expected.to run.with_params(['one', 'two', 'three', 'two'], ['one', 'two']).and_return(['three']) } end - it "should raise a ParseError if there are fewer than 2 arguments" do - expect { scope.function_delete([]) }.to(raise_error(Puppet::ParseError)) + describe 'deleting from a string' do + it { is_expected.to run.with_params('', '').and_return('') } + it { is_expected.to run.with_params('bar', '').and_return('bar') } + it { is_expected.to run.with_params('', 'bar').and_return('') } + it { is_expected.to run.with_params('bar', 'bar').and_return('') } + it { is_expected.to run.with_params('barbar', 'bar').and_return('') } + it { is_expected.to run.with_params('barfoobar', 'bar').and_return('foo') } + it { is_expected.to run.with_params('foobarbabarz', 'bar').and_return('foobaz') } + it { is_expected.to run.with_params('foobarbabarz', ['foo', 'bar']).and_return('baz') } + # this is so sick + it { is_expected.to run.with_params('barfoobar', ['barbar', 'foo']).and_return('barbar') } + it { is_expected.to run.with_params('barfoobar', ['foo', 'barbar']).and_return('') } end - it "should raise a ParseError if there are greater than 2 arguments" do - expect { scope.function_delete([[], 'foo', 'bar']) }.to(raise_error(Puppet::ParseError)) + describe 'deleting from an array' 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({}) } + it { is_expected.to run \ + .with_params({'key1' => 'value1', 'key2' => 'value2', 'key3' => 'value3'}, 'key2') \ + .and_return( {'key1' => 'value1', 'key3' => 'value3'}) + } + it { is_expected.to run \ + .with_params({'key1' => 'value1', 'key2' => 'value2', 'key3' => 'value3'}, ['key1', 'key2']) \ + .and_return( {'key3' => 'value3'}) + } end - it "should raise a TypeError if a number is passed as the first argument" do - expect { scope.function_delete([1, 'bar']) }.to(raise_error(TypeError)) + it "should leave the original array intact" do + argument1 = ['one','two','three'] + original1 = argument1.dup + result = subject.call([argument1,'two']) + expect(argument1).to eq(original1) end - - it "should delete all instances of an element from an array" do - result = scope.function_delete([['a', 'b', 'c', 'b'], 'b']) - expect(result).to(eq(['a', 'c'])) - end - - it "should delete all instances of a substring from a string" do - result = scope.function_delete(['foobarbabarz', 'bar']) - expect(result).to(eq('foobaz')) + it "should leave the original string intact" do + argument1 = 'onetwothree' + original1 = argument1.dup + result = subject.call([argument1,'two']) + expect(argument1).to eq(original1) end - - it "should delete a key from a hash" do - result = scope.function_delete([{'a' => 1, 'b' => 2, 'c' => 3}, 'b']) - expect(result).to(eq({'a' => 1, 'c' => 3})) + it "should leave the original hash intact" do + argument1 = {'key1' => 'value1', 'key2' => 'value2', 'key3' => 'value3'} + original1 = argument1.dup + result = subject.call([argument1,'key2']) + expect(argument1).to eq(original1) end - - it 'should accept an array of items to delete' do - result = scope.function_delete([{'a' => 1, 'b' => 2, 'c' => 3}, ['b', 'c']]) - expect(result).to(eq({'a' => 1})) - end - - it "should not change origin array passed as argument" do - origin_array = ['a', 'b', 'c', 'd'] - result = scope.function_delete([origin_array, 'b']) - expect(origin_array).to(eq(['a', 'b', 'c', 'd'])) - end - - it "should not change the origin string passed as argument" do - origin_string = 'foobarbabarz' - result = scope.function_delete([origin_string, 'bar']) - expect(origin_string).to(eq('foobarbabarz')) - end - - it "should not change origin hash passed as argument" do - origin_hash = {'a' => 1, 'b' => 2, 'c' => 3} - result = scope.function_delete([origin_hash, 'b']) - expect(origin_hash).to(eq({'a' => 1, 'b' => 2, 'c' => 3})) - end - end diff --git a/spec/functions/delete_undef_values_spec.rb b/spec/functions/delete_undef_values_spec.rb index dc67953..ec9fb9c 100755 --- a/spec/functions/delete_undef_values_spec.rb +++ b/spec/functions/delete_undef_values_spec.rb @@ -1,41 +1,56 @@ -#! /usr/bin/env ruby -S rspec require 'spec_helper' -describe "the delete_undef_values function" do - let(:scope) { PuppetlabsSpec::PuppetInternals.scope } - - it "should exist" do - expect(Puppet::Parser::Functions.function("delete_undef_values")).to eq("function_delete_undef_values") - end - - it "should raise a ParseError if there is less than 1 argument" do - expect { scope.function_delete_undef_values([]) }.to( raise_error(Puppet::ParseError)) - end - - it "should raise a ParseError if the argument is not Array nor Hash" do - expect { scope.function_delete_undef_values(['']) }.to( raise_error(Puppet::ParseError)) - expect { scope.function_delete_undef_values([nil]) }.to( raise_error(Puppet::ParseError)) - end - - it "should delete all undef items from Array and only these" do - result = scope.function_delete_undef_values([['a',:undef,'c','undef']]) - expect(result).to(eq(['a','c','undef'])) - end - - it "should delete all undef items from Hash and only these" do - result = scope.function_delete_undef_values([{'a'=>'A','b'=>:undef,'c'=>'C','d'=>'undef'}]) - expect(result).to(eq({'a'=>'A','c'=>'C','d'=>'undef'})) - end - - it "should not change origin array passed as argument" do - origin_array = ['a',:undef,'c','undef'] - result = scope.function_delete_undef_values([origin_array]) - expect(origin_array).to(eq(['a',:undef,'c','undef'])) +describe 'delete_undef_values' do + it { is_expected.not_to eq(nil) } + it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError) } + it { is_expected.to run.with_params(1).and_raise_error(Puppet::ParseError) } + it { is_expected.to run.with_params('one').and_raise_error(Puppet::ParseError) } + it { is_expected.to run.with_params('one', 'two').and_raise_error(Puppet::ParseError) } + + describe 'when deleting from an array' do + [ :undef, '', nil ].each do |undef_value| + describe "when undef is represented by #{undef_value.inspect}" do + before do + pending("review behaviour when being passed undef as #{undef_value.inspect}") if undef_value == '' + pending("review behaviour when being passed undef as #{undef_value.inspect}") if undef_value == nil + end + it { is_expected.to run.with_params([undef_value]).and_return([]) } + it { is_expected.to run.with_params(['one',undef_value,'two','three']).and_return(['one','two','three']) } + end + + it "should leave the original argument intact" do + argument = ['one',undef_value,'two'] + original = argument.dup + result = subject.call([argument,2]) + expect(argument).to eq(original) + end + end + + it { is_expected.to run.with_params(['undef']).and_return(['undef']) } end - it "should not change origin hash passed as argument" do - origin_hash = { 'a' => 1, 'b' => :undef, 'c' => 'undef' } - result = scope.function_delete_undef_values([origin_hash]) - expect(origin_hash).to(eq({ 'a' => 1, 'b' => :undef, 'c' => 'undef' })) + describe 'when deleting from a hash' do + [ :undef, '', nil ].each do |undef_value| + describe "when undef is represented by #{undef_value.inspect}" do + before do + pending("review behaviour when being passed undef as #{undef_value.inspect}") if undef_value == '' + pending("review behaviour when being passed undef as #{undef_value.inspect}") if undef_value == nil + end + it { is_expected.to run.with_params({'key' => undef_value}).and_return({}) } + it { is_expected.to run \ + .with_params({'key1' => 'value1', 'undef_key' => undef_value, 'key2' => 'value2'}) \ + .and_return({'key1' => 'value1', 'key2' => 'value2'}) + } + end + + it "should leave the original argument intact" do + argument = { 'key1' => 'value1', 'key2' => undef_value } + original = argument.dup + result = subject.call([argument,2]) + expect(argument).to eq(original) + end + end + + it { is_expected.to run.with_params({'key' => 'undef'}).and_return({'key' => 'undef'}) } end end diff --git a/spec/functions/delete_values_spec.rb b/spec/functions/delete_values_spec.rb index 4f4d411..12907d4 100755 --- a/spec/functions/delete_values_spec.rb +++ b/spec/functions/delete_values_spec.rb @@ -1,36 +1,37 @@ -#! /usr/bin/env ruby -S rspec require 'spec_helper' -describe "the delete_values function" do - let(:scope) { PuppetlabsSpec::PuppetInternals.scope } - - it "should exist" do - expect(Puppet::Parser::Functions.function("delete_values")).to eq("function_delete_values") - end - - it "should raise a ParseError if there are fewer than 2 arguments" do - expect { scope.function_delete_values([]) }.to( raise_error(Puppet::ParseError)) - end - - it "should raise a ParseError if there are greater than 2 arguments" do - expect { scope.function_delete_values([[], 'foo', 'bar']) }.to( raise_error(Puppet::ParseError)) - end - - it "should raise a TypeError if the argument is not a hash" do - expect { scope.function_delete_values([1,'bar']) }.to( raise_error(TypeError)) - expect { scope.function_delete_values(['foo','bar']) }.to( raise_error(TypeError)) - expect { scope.function_delete_values([[],'bar']) }.to( raise_error(TypeError)) +describe 'delete_values' do + it { is_expected.not_to eq(nil) } + it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError) } + it { is_expected.to run.with_params(1).and_raise_error(Puppet::ParseError) } + it { is_expected.to run.with_params('one').and_raise_error(Puppet::ParseError) } + it { is_expected.to run.with_params('one', 'two', 'three').and_raise_error(Puppet::ParseError) } + describe 'when the first argument is not a hash' do + it { is_expected.to run.with_params(1, 'two').and_raise_error(TypeError) } + it { is_expected.to run.with_params('one', 'two').and_raise_error(TypeError) } + it { is_expected.to run.with_params([], 'two').and_raise_error(TypeError) } end - it "should delete all instances of a value from a hash" do - result = scope.function_delete_values([{ 'a'=>'A', 'b'=>'B', 'B'=>'C', 'd'=>'B' },'B']) - expect(result).to(eq({ 'a'=>'A', 'B'=>'C' })) + describe 'when deleting from a hash' do + it { is_expected.to run.with_params({}, 'value').and_return({}) } + it { is_expected.to run \ + .with_params({'key1' => 'value1'}, 'non-existing value') \ + .and_return({'key1' => 'value1'}) + } + it { is_expected.to run \ + .with_params({'key1' => 'value1', 'key2' => 'value to delete'}, 'value to delete') \ + .and_return({'key1' => 'value1'}) + } + it { is_expected.to run \ + .with_params({'key1' => 'value1', 'key2' => 'value to delete', 'key3' => 'value to delete'}, 'value to delete') \ + .and_return({'key1' => 'value1'}) + } end - it "should not change origin hash passed as argument" do - origin_hash = { 'a' => 1, 'b' => 2, 'c' => 3 } - result = scope.function_delete_values([origin_hash, 2]) - expect(origin_hash).to(eq({ 'a' => 1, 'b' => 2, 'c' => 3 })) + it "should leave the original argument intact" do + argument = { 'key1' => 'value1', 'key2' => 'value2' } + original = argument.dup + result = subject.call([argument, 'value2']) + expect(argument).to eq(original) end - end diff --git a/spec/functions/difference_spec.rb b/spec/functions/difference_spec.rb index 24b2b1b..d5e983d 100755 --- a/spec/functions/difference_spec.rb +++ b/spec/functions/difference_spec.rb @@ -1,19 +1,21 @@ -#! /usr/bin/env ruby -S rspec require 'spec_helper' -describe "the difference function" do - let(:scope) { PuppetlabsSpec::PuppetInternals.scope } - - it "should exist" do - expect(Puppet::Parser::Functions.function("difference")).to eq("function_difference") - end - - it "should raise a ParseError if there are fewer than 2 arguments" do - expect { scope.function_difference([]) }.to( raise_error(Puppet::ParseError) ) - end - - it "should return the difference between two arrays" do - result = scope.function_difference([["a","b","c"],["b","c","d"]]) - expect(result).to(eq(["a"])) - end +describe 'difference' do + it { is_expected.not_to eq(nil) } + it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError) } + it { is_expected.to run.with_params('one').and_raise_error(Puppet::ParseError) } + it { is_expected.to run.with_params('one', 'two').and_raise_error(Puppet::ParseError) } + it { is_expected.to run.with_params('one', 'two', 'three').and_raise_error(Puppet::ParseError) } + it { is_expected.to run.with_params('one', []).and_raise_error(Puppet::ParseError) } + it { is_expected.to run.with_params([], 'two').and_raise_error(Puppet::ParseError) } + it { is_expected.to run.with_params({}, {}).and_raise_error(Puppet::ParseError) } + it { is_expected.to run.with_params([], []).and_return([]) } + it { is_expected.to run.with_params([], ['one']).and_return([]) } + it { is_expected.to run.with_params(['one'], ['one']).and_return([]) } + it { is_expected.to run.with_params(['one'], []).and_return(['one']) } + it { is_expected.to run.with_params(['one', 'two', 'three'], ['two', 'three']).and_return(['one']) } + it { is_expected.to run.with_params(['one', 'two', 'two', 'three'], ['two', 'three']).and_return(['one']) } + it { is_expected.to run.with_params(['one', 'two', 'three'], ['two', 'two', 'three']).and_return(['one']) } + it { is_expected.to run.with_params(['one', 'two', 'three'], ['two', 'three', 'four']).and_return(['one']) } + it 'should not confuse types' do is_expected.to run.with_params(['1', '2', '3'], [1, 2]).and_return(['1', '2', '3']) end end diff --git a/spec/functions/dirname_spec.rb b/spec/functions/dirname_spec.rb index 4261144..46c4c35 100755 --- a/spec/functions/dirname_spec.rb +++ b/spec/functions/dirname_spec.rb @@ -1,38 +1,13 @@ -#! /usr/bin/env ruby -S rspec require 'spec_helper' -describe "the dirname function" do - let(:scope) { PuppetlabsSpec::PuppetInternals.scope } - - it "should exist" do - expect(Puppet::Parser::Functions.function("dirname")).to eq("function_dirname") - end - - it "should raise a ParseError if there is less than 1 arguments" do - expect { scope.function_dirname([]) }.to( raise_error(Puppet::ParseError)) - end - - it "should raise a ParseError if there is more than 1 argument" do - expect { scope.function_dirname(['a', 'b']) }.to( raise_error(Puppet::ParseError)) - end - - it "should return dirname for an absolute path" do - result = scope.function_dirname(['/path/to/a/file.ext']) - expect(result).to(eq('/path/to/a')) - end - - it "should return dirname for a relative path" do - result = scope.function_dirname(['path/to/a/file.ext']) - expect(result).to(eq('path/to/a')) - end - - it "should complain about hash argument" do - expect { scope.function_dirname([{}]) }.to( raise_error(Puppet::ParseError)) - end - it "should complain about list argument" do - expect { scope.function_dirname([[]]) }.to( raise_error(Puppet::ParseError)) - end - it "should complain about numeric argument" do - expect { scope.function_dirname([2112]) }.to( raise_error(Puppet::ParseError)) - end +describe 'dirname' do + it { is_expected.not_to eq(nil) } + it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError) } + it { is_expected.to run.with_params('one', 'two').and_raise_error(Puppet::ParseError) } + it { is_expected.to run.with_params([]).and_raise_error(Puppet::ParseError) } + it { is_expected.to run.with_params({}).and_raise_error(Puppet::ParseError) } + it { is_expected.to run.with_params(1).and_raise_error(Puppet::ParseError) } + it { is_expected.to run.with_params('/path/to/a/file.ext', []).and_raise_error(Puppet::ParseError) } + it { is_expected.to run.with_params('/path/to/a/file.ext').and_return('/path/to/a') } + it { is_expected.to run.with_params('relative_path/to/a/file.ext').and_return('relative_path/to/a') } end diff --git a/spec/functions/downcase_spec.rb b/spec/functions/downcase_spec.rb index edebc44..c594560 100755 --- a/spec/functions/downcase_spec.rb +++ b/spec/functions/downcase_spec.rb @@ -1,33 +1,15 @@ -#! /usr/bin/env ruby -S rspec require 'spec_helper' -describe "the downcase function" do - let(:scope) { PuppetlabsSpec::PuppetInternals.scope } - - it "should exist" do - expect(Puppet::Parser::Functions.function("downcase")).to eq("function_downcase") - end - - it "should raise a ParseError if there is less than 1 arguments" do - expect { scope.function_downcase([]) }.to( raise_error(Puppet::ParseError)) - end - - it "should downcase a string" do - result = scope.function_downcase(["ASFD"]) - expect(result).to(eq("asfd")) - end - - it "should do nothing to a string that is already downcase" do - result = scope.function_downcase(["asdf asdf"]) - expect(result).to(eq("asdf asdf")) - end - - it "should accept objects which extend String" do - class AlsoString < String - end - - value = AlsoString.new("ASFD") - result = scope.function_downcase([value]) - result.should(eq('asfd')) - end +describe 'downcase' do + it { is_expected.not_to eq(nil) } + it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError) } + it { is_expected.to run.with_params(100).and_raise_error(Puppet::ParseError) } + it { is_expected.to run.with_params("abc").and_return("abc") } + it { is_expected.to run.with_params("Abc").and_return("abc") } + it { is_expected.to run.with_params("ABC").and_return("abc") } + + it { is_expected.to run.with_params(AlsoString.new("ABC")).and_return("abc") } + it { is_expected.to run.with_params([]).and_return([]) } + it { is_expected.to run.with_params(["ONE", "TWO"]).and_return(["one", "two"]) } + it { is_expected.to run.with_params(["One", 1, "Two"]).and_return(["one", 1, "two"]) } end diff --git a/spec/functions/empty_spec.rb b/spec/functions/empty_spec.rb index 6a97c4c..94b1c68 100755 --- a/spec/functions/empty_spec.rb +++ b/spec/functions/empty_spec.rb @@ -1,32 +1,22 @@ -#! /usr/bin/env ruby -S rspec require 'spec_helper' -describe "the empty function" do - let(:scope) { PuppetlabsSpec::PuppetInternals.scope } - it "should exist" do - expect(Puppet::Parser::Functions.function("empty")).to eq("function_empty") - end +describe 'empty' do + it { is_expected.not_to eq(nil) } + it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError) } + it { is_expected.to run.with_params(0).and_raise_error(Puppet::ParseError) } + it { + pending("Current implementation ignores parameters after the first.") + is_expected.to run.with_params('one', 'two').and_raise_error(Puppet::ParseError) + } + it { is_expected.to run.with_params('').and_return(true) } + it { is_expected.to run.with_params('one').and_return(false) } - it "should raise a ParseError if there is less than 1 arguments" do - expect { scope.function_empty([]) }.to( raise_error(Puppet::ParseError)) - end + it { is_expected.to run.with_params(AlsoString.new('')).and_return(true) } + it { is_expected.to run.with_params(AlsoString.new('one')).and_return(false) } - it "should return a true for an empty string" do - result = scope.function_empty(['']) - expect(result).to(eq(true)) - end + it { is_expected.to run.with_params([]).and_return(true) } + it { is_expected.to run.with_params(['one']).and_return(false) } - it "should return a false for a non-empty string" do - result = scope.function_empty(['asdf']) - expect(result).to(eq(false)) - end - - it "should accept objects which extend String" do - class AlsoString < String - end - - value = AlsoString.new() - result = scope.function_empty([value]) - result.should(eq(true)) - end + it { is_expected.to run.with_params({}).and_return(true) } + it { is_expected.to run.with_params({'key' => 'value'}).and_return(false) } end diff --git a/spec/functions/ensure_packages_spec.rb b/spec/functions/ensure_packages_spec.rb index 436be10..c824732 100755 --- a/spec/functions/ensure_packages_spec.rb +++ b/spec/functions/ensure_packages_spec.rb @@ -1,81 +1,36 @@ -#! /usr/bin/env ruby - require 'spec_helper' -require 'rspec-puppet' -require 'puppet_spec/compiler' describe 'ensure_packages' do - include PuppetSpec::Compiler - - before :each do - Puppet::Parser::Functions.autoloader.loadall - Puppet::Parser::Functions.function(:ensure_packages) - Puppet::Parser::Functions.function(:ensure_resource) - Puppet::Parser::Functions.function(:defined_with_params) - Puppet::Parser::Functions.function(:create_resources) - end - - let :node do Puppet::Node.new('localhost') end - let :compiler do Puppet::Parser::Compiler.new(node) end - let :scope do - if Puppet.version.to_f >= 3.0 - Puppet::Parser::Scope.new(compiler) - else - newscope = Puppet::Parser::Scope.new - newscope.compiler = compiler - newscope.source = Puppet::Resource::Type.new(:node, :localhost) - newscope - end - end - - describe 'argument handling' do - it 'fails with no arguments' do - expect { - scope.function_ensure_packages([]) - }.to raise_error(Puppet::ParseError, /0 for 1 or 2/) - end - - it 'accepts an array of values' do - scope.function_ensure_packages([['foo']]) - end - - it 'accepts a single package name as a string' do - scope.function_ensure_packages(['foo']) - end - end - - context 'given a catalog with puppet package => absent' do - let :catalog do - compile_to_catalog(<<-EOS - ensure_packages(['facter']) - package { puppet: ensure => absent } - EOS - ) - end - - it 'has no effect on Package[puppet]' do - expect(catalog.resource(:package, 'puppet')['ensure']).to eq('absent') - end - end - - context 'given a clean catalog' do - let :catalog do - compile_to_catalog('ensure_packages(["facter"])') - end - - it 'declares package resources with ensure => present' do - expect(catalog.resource(:package, 'facter')['ensure']).to eq('present') - end - end - - context 'given a clean catalog and specified defaults' do - let :catalog do - compile_to_catalog('ensure_packages(["facter"], {"provider" => "gem"})') - end - - it 'declares package resources with ensure => present' do - expect(catalog.resource(:package, 'facter')['ensure']).to eq('present') - expect(catalog.resource(:package, 'facter')['provider']).to eq('gem') + it { is_expected.not_to eq(nil) } + it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError) } + it { + pending("should not accept numbers as arguments") + is_expected.to run.with_params(1).and_raise_error(Puppet::ParseError) + } + it { + pending("should not accept numbers as arguments") + is_expected.to run.with_params(["packagename", 1]).and_raise_error(Puppet::ParseError) + } + it { is_expected.to run.with_params("packagename") } + it { is_expected.to run.with_params(["packagename1", "packagename2"]) } + + context 'given a catalog with "package { puppet: ensure => absent }"' do + let(:pre_condition) { 'package { puppet: ensure => absent }' } + + describe 'after running ensure_package("facter")' do + before { subject.call(['facter']) } + + # this lambda is required due to strangeness within rspec-puppet's expectation handling + it { expect(lambda { catalogue }).to contain_package('puppet').with_ensure('absent') } + it { expect(lambda { catalogue }).to contain_package('facter').with_ensure('present') } + end + + describe 'after running ensure_package("facter", { "provider" => "gem" })' do + before { subject.call(['facter', { "provider" => "gem" }]) } + + # this lambda is required due to strangeness within rspec-puppet's expectation handling + it { expect(lambda { catalogue }).to contain_package('puppet').with_ensure('absent').without_provider() } + it { expect(lambda { catalogue }).to contain_package('facter').with_ensure('present').with_provider("gem") } end end end diff --git a/spec/functions/ensure_resource_spec.rb b/spec/functions/ensure_resource_spec.rb index 33bcac0..c4f2cbd 100755 --- a/spec/functions/ensure_resource_spec.rb +++ b/spec/functions/ensure_resource_spec.rb @@ -1,113 +1,55 @@ -#! /usr/bin/env ruby -S rspec require 'spec_helper' -require 'rspec-puppet' -require 'puppet_spec/compiler' describe 'ensure_resource' do - include PuppetSpec::Compiler + it { is_expected.not_to eq(nil) } + it { is_expected.to run.with_params().and_raise_error(ArgumentError, /Must specify a type/) } + it { is_expected.to run.with_params('type').and_raise_error(ArgumentError, /Must specify a title/) } + it { is_expected.to run.with_params('type', 'title', {}, 'extras').and_raise_error(Puppet::ParseError) } + it { + pending("should not accept numbers as arguments") + is_expected.to run.with_params(1,2,3).and_raise_error(Puppet::ParseError) + } - before :all do - Puppet::Parser::Functions.autoloader.loadall - Puppet::Parser::Functions.function(:ensure_packages) - end - - let :node do Puppet::Node.new('localhost') end - let :compiler do Puppet::Parser::Compiler.new(node) end - let :scope do Puppet::Parser::Scope.new(compiler) end + context 'given a catalog with "user { username1: ensure => present }"' do + let(:pre_condition) { 'user { username1: ensure => present }' } - describe 'when a type or title is not specified' do - it { expect { scope.function_ensure_resource([]) }.to raise_error } - it { expect { scope.function_ensure_resource(['type']) }.to raise_error } - end - - describe 'when compared against a resource with no attributes' do - let :catalog do - compile_to_catalog(<<-EOS - user { "dan": } - ensure_resource('user', 'dan', {}) - EOS - ) - end + describe 'after running ensure_resource("user", "username1", {})' do + before { subject.call(['User', 'username1', {}]) } - it 'should contain the the ensured resources' do - expect(catalog.resource(:user, 'dan').to_s).to eq('User[dan]') + # this lambda is required due to strangeness within rspec-puppet's expectation handling + it { expect(lambda { catalogue }).to contain_user('username1').with_ensure('present') } end - end - describe 'works when compared against a resource with non-conflicting attributes' do - [ - "ensure_resource('User', 'dan', {})", - "ensure_resource('User', 'dan', '')", - "ensure_resource('User', 'dan', {'ensure' => 'present'})", - "ensure_resource('User', 'dan', {'ensure' => 'present', 'managehome' => false})" - ].each do |ensure_resource| - pp = <<-EOS - user { "dan": ensure => present, shell => "/bin/csh", managehome => false} - #{ensure_resource} - EOS + describe 'after running ensure_resource("user", "username2", {})' do + before { subject.call(['User', 'username2', {}]) } - it { expect { compile_to_catalog(pp) }.to_not raise_error } + # this lambda is required due to strangeness within rspec-puppet's expectation handling + it { expect(lambda { catalogue }).to contain_user('username1').with_ensure('present') } + it { expect(lambda { catalogue }).to contain_user('username2').without_ensure } end - end - - describe 'fails when compared against a resource with conflicting attributes' do - pp = <<-EOS - user { "dan": ensure => present, shell => "/bin/csh", managehome => false} - ensure_resource('User', 'dan', {'ensure' => 'absent', 'managehome' => false}) - EOS - - it { expect { compile_to_catalog(pp) }.to raise_error } - end - describe 'when an array of new resources are passed in' do - let :catalog do - compile_to_catalog("ensure_resource('User', ['dan', 'alex'], {})") - end + describe 'after running ensure_resource("user", ["username1", "username2"], {})' do + before { subject.call(['User', ['username1', 'username2'], {}]) } - it 'should contain the ensured resources' do - expect(catalog.resource('User[dan]').to_s).to eq('User[dan]') - expect(catalog.resource('User[alex]').to_s).to eq('User[alex]') + # this lambda is required due to strangeness within rspec-puppet's expectation handling + it { expect(lambda { catalogue }).to contain_user('username1').with_ensure('present') } + it { expect(lambda { catalogue }).to contain_user('username2').without_ensure } end - end - describe 'when an array of existing resources is compared against existing resources' do - pp = <<-EOS - user { 'dan': ensure => present; 'alex': ensure => present } - ensure_resource('User', ['dan', 'alex'], {}) - EOS + describe 'when providing already set params' do + let(:params) { { 'ensure' => 'present' } } + before { subject.call(['User', ['username2', 'username3'], params]) } - let :catalog do - compile_to_catalog(pp) + # this lambda is required due to strangeness within rspec-puppet's expectation handling + it { expect(lambda { catalogue }).to contain_user('username1').with(params) } + it { expect(lambda { catalogue }).to contain_user('username2').with(params) } end - it 'should return the existing resources' do - expect(catalog.resource('User[dan]').to_s).to eq('User[dan]') - expect(catalog.resource('User[alex]').to_s).to eq('User[alex]') - end - end - - describe 'works when compared against existing resources with attributes' do - [ - "ensure_resource('User', ['dan', 'alex'], {})", - "ensure_resource('User', ['dan', 'alex'], '')", - "ensure_resource('User', ['dan', 'alex'], {'ensure' => 'present'})", - ].each do |ensure_resource| - pp = <<-EOS - user { 'dan': ensure => present; 'alex': ensure => present } - #{ensure_resource} - EOS - - it { expect { compile_to_catalog(pp) }.to_not raise_error } + context 'when trying to add params' do + it { is_expected.to run \ + .with_params('User', 'username1', { 'ensure' => 'present', 'shell' => true }) \ + .and_raise_error(Puppet::Resource::Catalog::DuplicateResourceError, /User\[username1\] is already declared/) + } end end - - describe 'fails when compared against existing resources with conflicting attributes' do - pp = <<-EOS - user { 'dan': ensure => present; 'alex': ensure => present } - ensure_resource('User', ['dan', 'alex'], {'ensure' => 'absent'}) - EOS - - it { expect { compile_to_catalog(pp) }.to raise_error } - end - end diff --git a/spec/functions/flatten_spec.rb b/spec/functions/flatten_spec.rb index de8c66d..a4338be 100755 --- a/spec/functions/flatten_spec.rb +++ b/spec/functions/flatten_spec.rb @@ -1,27 +1,14 @@ -#! /usr/bin/env ruby -S rspec require 'spec_helper' -describe "the flatten function" do - let(:scope) { PuppetlabsSpec::PuppetInternals.scope } - it "should exist" do - expect(Puppet::Parser::Functions.function("flatten")).to eq("function_flatten") - end - - it "should raise a ParseError if there is less than 1 arguments" do - expect { scope.function_flatten([]) }.to( raise_error(Puppet::ParseError)) - end - - it "should raise a ParseError if there is more than 1 argument" do - expect { scope.function_flatten([[], []]) }.to( raise_error(Puppet::ParseError)) - end - - it "should flatten a complex data structure" do - result = scope.function_flatten([["a","b",["c",["d","e"],"f","g"]]]) - expect(result).to(eq(["a","b","c","d","e","f","g"])) - end - - it "should do nothing to a structure that is already flat" do - result = scope.function_flatten([["a","b","c","d"]]) - expect(result).to(eq(["a","b","c","d"])) - end +describe 'flatten' do + it { is_expected.not_to eq(nil) } + it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError) } + it { is_expected.to run.with_params([], []).and_raise_error(Puppet::ParseError) } + it { is_expected.to run.with_params(1).and_raise_error(Puppet::ParseError) } + it { is_expected.to run.with_params('one').and_raise_error(Puppet::ParseError) } + it { is_expected.to run.with_params([]).and_return([]) } + it { is_expected.to run.with_params(['one']).and_return(['one']) } + it { is_expected.to run.with_params([['one']]).and_return(['one']) } + it { is_expected.to run.with_params(["a","b","c","d","e","f","g"]).and_return(["a","b","c","d","e","f","g"]) } + it { is_expected.to run.with_params([["a","b",["c",["d","e"],"f","g"]]]).and_return(["a","b","c","d","e","f","g"]) } end diff --git a/spec/functions/floor_spec.rb b/spec/functions/floor_spec.rb index 12a6917..608c602 100755 --- a/spec/functions/floor_spec.rb +++ b/spec/functions/floor_spec.rb @@ -1,39 +1,12 @@ -#! /usr/bin/env ruby -S rspec - require 'spec_helper' -describe "the floor function" do - let(:scope) { PuppetlabsSpec::PuppetInternals.scope } - - it "should exist" do - expect(Puppet::Parser::Functions.function("floor")).to eq("function_floor") - end - - it "should raise a ParseError if there is less than 1 argument" do - expect { scope.function_floor([]) }.to( raise_error(Puppet::ParseError, /Wrong number of arguments/)) - end - - it "should should raise a ParseError if input isn't numeric (eg. String)" do - expect { scope.function_floor(["foo"]) }.to( raise_error(Puppet::ParseError, /Wrong argument type/)) - end - - it "should should raise a ParseError if input isn't numeric (eg. Boolean)" do - expect { scope.function_floor([true]) }.to( raise_error(Puppet::ParseError, /Wrong argument type/)) - end - - it "should return an integer when a numeric type is passed" do - result = scope.function_floor([12.4]) - expect(result.is_a?(Integer)).to(eq(true)) - end - - it "should return the input when an integer is passed" do - result = scope.function_floor([7]) - expect(result).to(eq(7)) - end - - it "should return the largest integer less than or equal to the input" do - result = scope.function_floor([3.8]) - expect(result).to(eq(3)) - end +describe 'floor' do + it { is_expected.not_to eq(nil) } + it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError) } + it { is_expected.to run.with_params("foo").and_raise_error(Puppet::ParseError) } + it { is_expected.to run.with_params([]).and_raise_error(Puppet::ParseError) } + it { is_expected.to run.with_params(34).and_return(34) } + it { is_expected.to run.with_params(-34).and_return(-34) } + it { is_expected.to run.with_params(33.1).and_return(33) } + it { is_expected.to run.with_params(-33.1).and_return(-34) } end - diff --git a/spec/functions/fqdn_rand_string_spec.rb b/spec/functions/fqdn_rand_string_spec.rb index 949d930..e407084 100644 --- a/spec/functions/fqdn_rand_string_spec.rb +++ b/spec/functions/fqdn_rand_string_spec.rb @@ -1,51 +1,25 @@ -#! /usr/bin/env ruby -S rspec require 'spec_helper' -describe "the fqdn_rand_string function" do - let(:scope) { PuppetlabsSpec::PuppetInternals.scope } - - it "should exist" do - expect(Puppet::Parser::Functions.function("fqdn_rand_string")).to eq("function_fqdn_rand_string") - end - - it "should raise an ArgumentError if there is less than 1 argument" do - expect { fqdn_rand_string() }.to( raise_error(ArgumentError, /wrong number of arguments/)) - end - - it "should raise an ArgumentError if argument 1 isn't a positive integer" do - expect { fqdn_rand_string(0) }.to( raise_error(ArgumentError, /first argument must be a positive integer/)) - expect { fqdn_rand_string(-1) }.to( raise_error(ArgumentError, /first argument must be a positive integer/)) - expect { fqdn_rand_string(0.5) }.to( raise_error(ArgumentError, /first argument must be a positive integer/)) - end - - it "provides a valid alphanumeric string when no character set is provided" do - length = 100 - string = %r{\A[a-zA-Z0-9]{#{length}}\z} - expect(fqdn_rand_string(length).match(string)).not_to eq(nil) - end - - it "provides a valid alphanumeric string when an undef character set is provided" do - length = 100 - string = %r{\A[a-zA-Z0-9]{#{length}}\z} - expect(fqdn_rand_string(length, :charset => nil).match(string)).not_to eq(nil) - end - - it "provides a valid alphanumeric string when an empty character set is provided" do - length = 100 - string = %r{\A[a-zA-Z0-9]{#{length}}\z} - expect(fqdn_rand_string(length, :charset => '').match(string)).not_to eq(nil) - end - - it "uses a provided character set" do - length = 100 - charset = '!@#$%^&*()-_=+' - string = %r{\A[#{charset}]{#{length}}\z} - expect(fqdn_rand_string(length, :charset => charset).match(string)).not_to eq(nil) - end - - it "provides a random string exactly as long as the given length" do - expect(fqdn_rand_string(10).size).to eql(10) - end +describe 'fqdn_rand_string' do + let(:default_charset) { %r{\A[a-zA-Z0-9]{100}\z} } + it { is_expected.not_to eq(nil) } + it { is_expected.to run.with_params().and_raise_error(ArgumentError, /wrong number of arguments/i) } + it { is_expected.to run.with_params(0).and_raise_error(ArgumentError, /first argument must be a positive integer/) } + it { is_expected.to run.with_params(1.5).and_raise_error(ArgumentError, /first argument must be a positive integer/) } + it { is_expected.to run.with_params(-10).and_raise_error(ArgumentError, /first argument must be a positive integer/) } + it { is_expected.to run.with_params("-10").and_raise_error(ArgumentError, /first argument must be a positive integer/) } + it { is_expected.to run.with_params("string").and_raise_error(ArgumentError, /first argument must be a positive integer/) } + it { is_expected.to run.with_params([]).and_raise_error(ArgumentError, /first argument must be a positive integer/) } + it { is_expected.to run.with_params({}).and_raise_error(ArgumentError, /first argument must be a positive integer/) } + it { is_expected.to run.with_params(1, 1).and_raise_error(ArgumentError, /second argument must be undef or a string/) } + it { is_expected.to run.with_params(1, []).and_raise_error(ArgumentError, /second argument must be undef or a string/) } + it { is_expected.to run.with_params(1, {}).and_raise_error(ArgumentError, /second argument must be undef or a string/) } + it { is_expected.to run.with_params(100).and_return(default_charset) } + it { is_expected.to run.with_params("100").and_return(default_charset) } + it { is_expected.to run.with_params(100, nil).and_return(default_charset) } + it { is_expected.to run.with_params(100, '').and_return(default_charset) } + it { is_expected.to run.with_params(100, 'a').and_return(/\Aa{100}\z/) } + it { is_expected.to run.with_params(100, 'ab').and_return(/\A[ab]{100}\z/) } it "provides the same 'random' value on subsequent calls for the same host" do expect(fqdn_rand_string(10)).to eql(fqdn_rand_string(10)) @@ -77,9 +51,9 @@ describe "the fqdn_rand_string function" do charset = args[:charset] extra = args[:extra_identifier] || [] - scope = PuppetlabsSpec::PuppetInternals.scope - scope.stubs(:[]).with("::fqdn").returns(host) - scope.stubs(:lookupvar).with("::fqdn").returns(host) + # workaround not being able to use let(:facts) because some tests need + # multiple different hostnames in one context + scope.stubs(:lookupvar).with("::fqdn", {}).returns(host) function_args = [max] if args.has_key?(:charset) or !extra.empty? diff --git a/spec/functions/fqdn_rotate_spec.rb b/spec/functions/fqdn_rotate_spec.rb index 673a8a3..fe54490 100755 --- a/spec/functions/fqdn_rotate_spec.rb +++ b/spec/functions/fqdn_rotate_spec.rb @@ -1,60 +1,65 @@ -#! /usr/bin/env ruby -S rspec require 'spec_helper' -describe "the fqdn_rotate function" do - let(:scope) { PuppetlabsSpec::PuppetInternals.scope } +describe 'fqdn_rotate' 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(0).and_raise_error(Puppet::ParseError, /Requires either array or string to work with/) } + it { is_expected.to run.with_params({}).and_raise_error(Puppet::ParseError, /Requires either array or string to work with/) } + it { + pending("Current implementation ignores parameters after the first.") + is_expected.to run.with_params("one", "two").and_raise_error(Puppet::ParseError) + } + it { is_expected.to run.with_params('').and_return('') } + it { is_expected.to run.with_params('a').and_return('a') } - it "should exist" do - expect(Puppet::Parser::Functions.function("fqdn_rotate")).to eq("function_fqdn_rotate") - end - - it "should raise a ParseError if there is less than 1 arguments" do - expect { scope.function_fqdn_rotate([]) }.to( raise_error(Puppet::ParseError)) - end + it { is_expected.to run.with_params([]).and_return([]) } + it { is_expected.to run.with_params(['a']).and_return(['a']) } it "should rotate a string and the result should be the same size" do - scope.expects(:lookupvar).with("::fqdn").returns("127.0.0.1") - result = scope.function_fqdn_rotate(["asdf"]) - expect(result.size).to(eq(4)) + expect(fqdn_rotate("asdf").size).to eq(4) end it "should rotate a string to give the same results for one host" do - scope.expects(:lookupvar).with("::fqdn").returns("127.0.0.1").twice - expect(scope.function_fqdn_rotate(["abcdefg"])).to eql(scope.function_fqdn_rotate(["abcdefg"])) + val1 = fqdn_rotate("abcdefg", :host => 'one') + val2 = fqdn_rotate("abcdefg", :host => 'one') + expect(val1).to eq(val2) end it "should rotate a string to give different values on different hosts" do - scope.expects(:lookupvar).with("::fqdn").returns("127.0.0.1") - val1 = scope.function_fqdn_rotate(["abcdefghijklmnopqrstuvwxyz01234567890987654321"]) - scope.expects(:lookupvar).with("::fqdn").returns("127.0.0.2") - val2 = scope.function_fqdn_rotate(["abcdefghijklmnopqrstuvwxyz01234567890987654321"]) - expect(val1).not_to eql(val2) + val1 = fqdn_rotate("abcdefg", :host => 'one') + val2 = fqdn_rotate("abcdefg", :host => 'two') + expect(val1).not_to eq(val2) end it "should accept objects which extend String" do - class AlsoString < String - end - - scope.expects(:lookupvar).with("::fqdn").returns("127.0.0.1") - value = AlsoString.new("asdf") - result = scope.function_fqdn_rotate([value]) - result.size.should(eq(4)) + result = fqdn_rotate(AlsoString.new('asdf')) + expect(result).to eq('dfas') end - it "should use the Puppet::Util.deterministic_rand function if available" do - scope.expects(:lookupvar).with("::fqdn").returns("127.0.0.1") + it "should use the Puppet::Util.deterministic_rand function" do if Puppet::Util.respond_to?(:deterministic_rand) Puppet::Util.expects(:deterministic_rand).with(113646079810780526294648115052177588845,4) + fqdn_rotate("asdf") + else + skip 'Puppet::Util#deterministic_rand not available' end - scope.function_fqdn_rotate(["asdf"]) end it "should not leave the global seed in a deterministic state" do - scope.expects(:lookupvar).with("::fqdn").returns("127.0.0.1").twice - scope.function_fqdn_rotate(["asdf"]) + fqdn_rotate("asdf") rand1 = rand() - scope.function_fqdn_rotate(["asdf"]) + fqdn_rotate("asdf") rand2 = rand() expect(rand1).not_to eql(rand2) end + + def fqdn_rotate(value, args = {}) + host = args[:host] || '127.0.0.1' + + # workaround not being able to use let(:facts) because some tests need + # multiple different hostnames in one context + scope.stubs(:lookupvar).with("::fqdn").returns(host) + + scope.function_fqdn_rotate([value]) + end end diff --git a/spec/functions/get_module_path_spec.rb b/spec/functions/get_module_path_spec.rb index 38ce645..b1f682f 100755 --- a/spec/functions/get_module_path_spec.rb +++ b/spec/functions/get_module_path_spec.rb @@ -1,8 +1,16 @@ -#! /usr/bin/env ruby -S rspec require 'spec_helper' -describe Puppet::Parser::Functions.function(:get_module_path) do - Internals = PuppetlabsSpec::PuppetInternals +describe 'get_module_path' do + it { is_expected.not_to eq(nil) } + 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 + class StubModule attr_reader :path def initialize(path) @@ -10,37 +18,35 @@ describe Puppet::Parser::Functions.function(:get_module_path) do end end - def scope(environment = "production") - Internals.scope(:compiler => Internals.compiler(:node => Internals.node(:environment => environment))) - end - - it 'should only allow one argument' do - expect { scope.function_get_module_path([]) }.to raise_error(Puppet::ParseError, /Wrong number of arguments, expects one/) - expect { scope.function_get_module_path(['1','2','3']) }.to raise_error(Puppet::ParseError, /Wrong number of arguments, expects one/) - end - it 'should raise an exception when the module cannot be found' do - expect { scope.function_get_module_path(['foo']) }.to raise_error(Puppet::ParseError, /Could not find module/) - end describe 'when locating a module' do let(:modulepath) { "/tmp/does_not_exist" } let(:path_of_module_foo) { StubModule.new("/tmp/does_not_exist/foo") } before(:each) { Puppet[:modulepath] = modulepath } - it 'should be able to find module paths from the modulepath setting' do - Puppet::Module.expects(:find).with('foo', 'production').returns(path_of_module_foo) - expect(scope.function_get_module_path(['foo'])).to eq(path_of_module_foo.path) - end - it 'should be able to find module paths when the modulepath is a list' do - Puppet[:modulepath] = modulepath + ":/tmp" - Puppet::Module.expects(:find).with('foo', 'production').returns(path_of_module_foo) - expect(scope.function_get_module_path(['foo'])).to eq(path_of_module_foo.path) + context 'in the default environment' do + before(:each) { Puppet::Module.expects(:find).with('foo', 'rp_env').returns(path_of_module_foo) } + + it { is_expected.to run.with_params('foo').and_return(path_of_module_foo.path) } + + context 'when the modulepath is a list' do + before(:each) { Puppet[:modulepath] = modulepath + 'tmp/something_else' } + + it { is_expected.to run.with_params('foo').and_return(path_of_module_foo.path) } + end end - it 'should respect the environment' do - skip("Disabled on Puppet 2.6.x") if Puppet.version =~ /^2\.6\b/ - Puppet.settings[:environment] = 'danstestenv' - Puppet::Module.expects(:find).with('foo', 'danstestenv').returns(path_of_module_foo) - expect(scope('danstestenv').function_get_module_path(['foo'])).to eq(path_of_module_foo.path) + + context 'in a non-default default environment' do + let(:environment) { 'test' } + before(:each) { Puppet::Module.expects(:find).with('foo', 'test').returns(path_of_module_foo) } + + it { is_expected.to run.with_params('foo').and_return(path_of_module_foo.path) } + + context 'when the modulepath is a list' do + before(:each) { Puppet[:modulepath] = modulepath + 'tmp/something_else' } + + it { is_expected.to run.with_params('foo').and_return(path_of_module_foo.path) } + end end end end diff --git a/spec/functions/getparam_spec.rb b/spec/functions/getparam_spec.rb index 833c4d4..9e3d9e4 100755 --- a/spec/functions/getparam_spec.rb +++ b/spec/functions/getparam_spec.rb @@ -1,76 +1,30 @@ -#! /usr/bin/env ruby -S rspec require 'spec_helper' -require 'rspec-puppet' -require 'puppet_spec/compiler' describe 'getparam' do - include PuppetSpec::Compiler - - before :each do - Puppet::Parser::Functions.autoloader.loadall - Puppet::Parser::Functions.function(:getparam) - end - - let :node do Puppet::Node.new('localhost') end - let :compiler do Puppet::Parser::Compiler.new(node) end - if Puppet.version.to_f >= 3.0 - let :scope do Puppet::Parser::Scope.new(compiler) end - else - let :scope do - newscope = Puppet::Parser::Scope.new - newscope.compiler = compiler - newscope.source = Puppet::Resource::Type.new(:node, :localhost) - newscope - end + it { is_expected.not_to eq(nil) } + it { is_expected.to run.with_params().and_raise_error(ArgumentError, /Must specify a reference/) } + it { is_expected.to run.with_params('User[one]').and_raise_error(ArgumentError, /Must specify name of a parameter/) } + it { is_expected.to run.with_params('User[one]', 2).and_raise_error(ArgumentError, /Must specify name of a parameter/) } + it { is_expected.to run.with_params('User[one]', []).and_raise_error(ArgumentError, /Must specify name of a parameter/) } + it { is_expected.to run.with_params('User[one]', {}).and_raise_error(ArgumentError, /Must specify name of a parameter/) } + + describe 'when compared against a user resource with no params' do + let(:pre_condition) { 'user { "one": }' } + + it { is_expected.to run.with_params('User[one]', 'ensure').and_return('') } + it { is_expected.to run.with_params('User[two]', 'ensure').and_return('') } + it { is_expected.to run.with_params('User[one]', 'shell').and_return('') } end - it "should exist" do - expect(Puppet::Parser::Functions.function("getparam")).to eq("function_getparam") - end - - describe 'when a resource is not specified' do - it { expect { scope.function_getparam([]) }.to raise_error } - it { expect { scope.function_getparam(['User[dan]']) }.to raise_error } - it { expect { scope.function_getparam(['User[dan]']) }.to raise_error } - it { expect { scope.function_getparam(['User[dan]', {}]) }.to raise_error } - # This seems to be OK because we just check for a string. - it { expect { scope.function_getparam(['User[dan]', '']) }.to_not raise_error } - end - - describe 'when compared against a resource with no params' do - let :catalog do - compile_to_catalog(<<-EOS - user { "dan": } - EOS - ) - end - - it do - expect(scope.function_getparam(['User[dan]', 'shell'])).to eq('') - end - end - - describe 'when compared against a resource with params' do - let :catalog do - compile_to_catalog(<<-EOS - user { 'dan': ensure => present, shell => '/bin/sh', managehome => false} - $test = getparam(User[dan], 'shell') - EOS - ) - end - - it do - resource = Puppet::Parser::Resource.new(:user, 'dan', {:scope => scope}) - resource.set_parameter('ensure', 'present') - resource.set_parameter('shell', '/bin/sh') - resource.set_parameter('managehome', false) - compiler.add_resource(scope, resource) + describe 'when compared against a user resource with params' do + let(:pre_condition) { 'user { "one": ensure => present, shell => "/bin/sh", managehome => false, }' } - expect(scope.function_getparam(['User[dan]', 'shell'])).to eq('/bin/sh') - expect(scope.function_getparam(['User[dan]', ''])).to eq('') - expect(scope.function_getparam(['User[dan]', 'ensure'])).to eq('present') - # TODO: Expected this to be false, figure out why we're getting '' back. - expect(scope.function_getparam(['User[dan]', 'managehome'])).to eq('') - end + it { is_expected.to run.with_params('User[one]', 'ensure').and_return('present') } + it { is_expected.to run.with_params('User[two]', 'ensure').and_return('') } + it { is_expected.to run.with_params('User[one]', 'shell').and_return('/bin/sh') } + it { + pending("both rspec-puppet as well as the function do the wrong thing here.") + is_expected.to run.with_params('User[one]', 'managehome').and_return(false) + } end end diff --git a/spec/functions/getvar_spec.rb b/spec/functions/getvar_spec.rb index 87ab9b5..37125d1 100755 --- a/spec/functions/getvar_spec.rb +++ b/spec/functions/getvar_spec.rb @@ -1,37 +1,28 @@ -#! /usr/bin/env ruby -S rspec require 'spec_helper' -describe Puppet::Parser::Functions.function(:getvar) do - let(:scope) { PuppetlabsSpec::PuppetInternals.scope } - describe 'when calling getvar from puppet' do +describe 'getvar' 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('one', 'two').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 "should not compile when no arguments are passed" do - skip("Fails on 2.6.x, see bug #15912") if Puppet.version =~ /^2\.6\./ - Puppet[:code] = '$foo = getvar()' - expect { - scope.compiler.compile - }.to raise_error(Puppet::ParseError, /wrong number of arguments/) - end + context 'given variables in namespaces' do + let(:pre_condition) { + <<-'ENDofPUPPETcode' + class site::data { $foo = 'baz' } + include site::data + ENDofPUPPETcode + } - it "should not compile when too many arguments are passed" do - skip("Fails on 2.6.x, see bug #15912") if Puppet.version =~ /^2\.6\./ - Puppet[:code] = '$foo = getvar("foo::bar", "baz")' - expect { - scope.compiler.compile - }.to raise_error(Puppet::ParseError, /wrong number of arguments/) + it { is_expected.to run.with_params('site::data::foo').and_return('baz') } + it { is_expected.to run.with_params('::site::data::foo').and_return('baz') } + + context 'with strict variable checking', :if => RSpec.configuration.strict_variables do + it { is_expected.to run.with_params('::site::data::bar').and_raise_error(ArgumentError, /undefined_variable/) } end - it "should lookup variables in other namespaces" do - skip("Fails on 2.6.x, see bug #15912") if Puppet.version =~ /^2\.6\./ - Puppet[:code] = <<-'ENDofPUPPETcode' - class site::data { $foo = 'baz' } - include site::data - $foo = getvar("site::data::foo") - if $foo != 'baz' { - fail('getvar did not return what we expect') - } - ENDofPUPPETcode - scope.compiler.compile + context 'without strict variable checking', :unless => RSpec.configuration.strict_variables do + it { is_expected.to run.with_params('::site::data::bar').and_return(nil) } end end end diff --git a/spec/functions/grep_spec.rb b/spec/functions/grep_spec.rb index 9c671dd..6e0bd6e 100755 --- a/spec/functions/grep_spec.rb +++ b/spec/functions/grep_spec.rb @@ -1,19 +1,19 @@ -#! /usr/bin/env ruby -S rspec require 'spec_helper' -describe "the grep function" do - let(:scope) { PuppetlabsSpec::PuppetInternals.scope } - - it "should exist" do - expect(Puppet::Parser::Functions.function("grep")).to eq("function_grep") - end - - it "should raise a ParseError if there is less than 1 arguments" do - expect { scope.function_grep([]) }.to( raise_error(Puppet::ParseError)) - end - - it "should grep contents from an array" do - result = scope.function_grep([["aaabbb","bbbccc","dddeee"], "bbb"]) - expect(result).to(eq(["aaabbb","bbbccc"])) - end +describe 'grep' 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('one').and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } + it { + pending("grep does not actually check this, and raises NoMethodError instead") + is_expected.to run.with_params('one', 'two').and_raise_error(Puppet::ParseError, /first argument not an array/) + } + it { + pending("grep does not actually check this, and raises NoMethodError instead") + is_expected.to run.with_params(1, 'two').and_raise_error(Puppet::ParseError, /first argument not an array/) + } + it { is_expected.to run.with_params('one', 'two', 'three').and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } + it { is_expected.to run.with_params([], 'two').and_return([]) } + it { is_expected.to run.with_params(['one', 'two', 'three'], 'two').and_return(['two']) } + it { is_expected.to run.with_params(['one', 'two', 'three'], 't(wo|hree)').and_return(['two', 'three']) } end diff --git a/spec/functions/has_interface_with_spec.rb b/spec/functions/has_interface_with_spec.rb index 23e09a9..7334d38 100755 --- a/spec/functions/has_interface_with_spec.rb +++ b/spec/functions/has_interface_with_spec.rb @@ -1,64 +1,38 @@ -#!/usr/bin/env ruby -S rspec require 'spec_helper' -describe Puppet::Parser::Functions.function(:has_interface_with) do - - let(:scope) do - PuppetlabsSpec::PuppetInternals.scope - end - - # The subject of these examples is the method itself. - subject do - function_name = Puppet::Parser::Functions.function(:has_interface_with) - scope.method(function_name) - end +describe 'has_interface_with' 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("one", "two", "three").and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } # We need to mock out the Facts so we can specify how we expect this function # to behave on different platforms. context "On Mac OS X Systems" do - before :each do - scope.stubs(:lookupvar).with("interfaces").returns('lo0,gif0,stf0,en1,p2p0,fw0,en0,vmnet1,vmnet8,utun0') - end - it 'should have loopback (lo0)' do - expect(subject.call(['lo0'])).to be_truthy - end - it 'should not have loopback (lo)' do - expect(subject.call(['lo'])).to be_falsey - end + let(:facts) { { :interfaces => 'lo0,gif0,stf0,en1,p2p0,fw0,en0,vmnet1,vmnet8,utun0' } } + it { is_expected.to run.with_params('lo0').and_return(true) } + it { is_expected.to run.with_params('lo').and_return(false) } end + context "On Linux Systems" do - before :each do - scope.stubs(:lookupvar).with("interfaces").returns('eth0,lo') - scope.stubs(:lookupvar).with("ipaddress").returns('10.0.0.1') - scope.stubs(:lookupvar).with("ipaddress_lo").returns('127.0.0.1') - scope.stubs(:lookupvar).with("ipaddress_eth0").returns('10.0.0.1') - scope.stubs(:lookupvar).with('muppet').returns('kermit') - scope.stubs(:lookupvar).with('muppet_lo').returns('mspiggy') - scope.stubs(:lookupvar).with('muppet_eth0').returns('kermit') - end - it 'should have loopback (lo)' do - expect(subject.call(['lo'])).to be_truthy - end - it 'should not have loopback (lo0)' do - expect(subject.call(['lo0'])).to be_falsey - end - it 'should have ipaddress with 127.0.0.1' do - expect(subject.call(['ipaddress', '127.0.0.1'])).to be_truthy - end - it 'should have ipaddress with 10.0.0.1' do - expect(subject.call(['ipaddress', '10.0.0.1'])).to be_truthy - end - it 'should not have ipaddress with 10.0.0.2' do - expect(subject.call(['ipaddress', '10.0.0.2'])).to be_falsey - end - it 'should have muppet named kermit' do - expect(subject.call(['muppet', 'kermit'])).to be_truthy - end - it 'should have muppet named mspiggy' do - expect(subject.call(['muppet', 'mspiggy'])).to be_truthy - end - it 'should not have muppet named bigbird' do - expect(subject.call(['muppet', 'bigbird'])).to be_falsey + let(:facts) do + { + :interfaces => 'eth0,lo', + :ipaddress => '10.0.0.1', + :ipaddress_lo => '127.0.0.1', + :ipaddress_eth0 => '10.0.0.1', + :muppet => 'kermit', + :muppet_lo => 'mspiggy', + :muppet_eth0 => 'kermit', + } end + + it { is_expected.to run.with_params('lo').and_return(true) } + it { is_expected.to run.with_params('lo0').and_return(false) } + it { is_expected.to run.with_params('ipaddress', '127.0.0.1').and_return(true) } + it { is_expected.to run.with_params('ipaddress', '10.0.0.1').and_return(true) } + it { is_expected.to run.with_params('ipaddress', '8.8.8.8').and_return(false) } + it { is_expected.to run.with_params('muppet', 'kermit').and_return(true) } + it { is_expected.to run.with_params('muppet', 'mspiggy').and_return(true) } + it { is_expected.to run.with_params('muppet', 'bigbird').and_return(false) } end end diff --git a/spec/functions/has_ip_address_spec.rb b/spec/functions/has_ip_address_spec.rb index 0df12a7..42a5a79 100755 --- a/spec/functions/has_ip_address_spec.rb +++ b/spec/functions/has_ip_address_spec.rb @@ -1,39 +1,22 @@ -#!/usr/bin/env ruby -S rspec require 'spec_helper' -describe Puppet::Parser::Functions.function(:has_ip_address) do - - let(:scope) do - PuppetlabsSpec::PuppetInternals.scope - end - - subject do - function_name = Puppet::Parser::Functions.function(:has_ip_address) - scope.method(function_name) - end +describe 'has_ip_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("one", "two").and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } context "On Linux Systems" do - before :each do - scope.stubs(:lookupvar).with('interfaces').returns('eth0,lo') - scope.stubs(:lookupvar).with('ipaddress').returns('10.0.2.15') - scope.stubs(:lookupvar).with('ipaddress_eth0').returns('10.0.2.15') - scope.stubs(:lookupvar).with('ipaddress_lo').returns('127.0.0.1') - end - - it 'should have primary address (10.0.2.15)' do - expect(subject.call(['10.0.2.15'])).to be_truthy + let(:facts) do + { + :interfaces => 'eth0,lo', + :ipaddress => '10.0.0.1', + :ipaddress_lo => '127.0.0.1', + :ipaddress_eth0 => '10.0.0.1', + } end - it 'should have lookupback address (127.0.0.1)' do - expect(subject.call(['127.0.0.1'])).to be_truthy - end - - it 'should not have other address' do - expect(subject.call(['192.1681.1.1'])).to be_falsey - end - - it 'should not have "mspiggy" on an interface' do - expect(subject.call(['mspiggy'])).to be_falsey - end + it { is_expected.to run.with_params('127.0.0.1').and_return(true) } + it { is_expected.to run.with_params('10.0.0.1').and_return(true) } + it { is_expected.to run.with_params('8.8.8.8').and_return(false) } end end diff --git a/spec/functions/has_ip_network_spec.rb b/spec/functions/has_ip_network_spec.rb index 2a2578e..7b5fe66 100755 --- a/spec/functions/has_ip_network_spec.rb +++ b/spec/functions/has_ip_network_spec.rb @@ -1,36 +1,22 @@ -#!/usr/bin/env ruby -S rspec require 'spec_helper' -describe Puppet::Parser::Functions.function(:has_ip_network) do - - let(:scope) do - PuppetlabsSpec::PuppetInternals.scope - end - - subject do - function_name = Puppet::Parser::Functions.function(:has_ip_network) - scope.method(function_name) - end +describe 'has_ip_network' 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("one", "two").and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } context "On Linux Systems" do - before :each do - scope.stubs(:lookupvar).with('interfaces').returns('eth0,lo') - scope.stubs(:lookupvar).with('network').returns(:undefined) - scope.stubs(:lookupvar).with('network_eth0').returns('10.0.2.0') - scope.stubs(:lookupvar).with('network_lo').returns('127.0.0.1') - end - - it 'should have primary network (10.0.2.0)' do - expect(subject.call(['10.0.2.0'])).to be_truthy - end - - it 'should have loopback network (127.0.0.0)' do - expect(subject.call(['127.0.0.1'])).to be_truthy + let(:facts) do + { + :interfaces => 'eth0,lo', + :network => :undefined, + :network_lo => '127.0.0.0', + :network_eth0 => '10.0.0.0', + } end - it 'should not have other network' do - expect(subject.call(['192.168.1.0'])).to be_falsey - end + it { is_expected.to run.with_params('127.0.0.0').and_return(true) } + it { is_expected.to run.with_params('10.0.0.0').and_return(true) } + it { is_expected.to run.with_params('8.8.8.0').and_return(false) } end end - diff --git a/spec/functions/has_key_spec.rb b/spec/functions/has_key_spec.rb index 6b71800..965d5a6 100755 --- a/spec/functions/has_key_spec.rb +++ b/spec/functions/has_key_spec.rb @@ -1,42 +1,15 @@ -#! /usr/bin/env ruby -S rspec require 'spec_helper' -describe Puppet::Parser::Functions.function(:has_key) do - let(:scope) { PuppetlabsSpec::PuppetInternals.scope } - - describe 'when calling has_key from puppet' do - it "should not compile when no arguments are passed" do - skip("Fails on 2.6.x, see bug #15912") if Puppet.version =~ /^2\.6\./ - Puppet[:code] = '$x = has_key()' - expect { - scope.compiler.compile - }.to raise_error(Puppet::ParseError, /wrong number of arguments/) - end - - it "should not compile when 1 argument is passed" do - skip("Fails on 2.6.x, see bug #15912") if Puppet.version =~ /^2\.6\./ - Puppet[:code] = "$x = has_key('foo')" - expect { - scope.compiler.compile - }.to raise_error(Puppet::ParseError, /wrong number of arguments/) - end - - it "should require the first value to be a Hash" do - skip("Fails on 2.6.x, see bug #15912") if Puppet.version =~ /^2\.6\./ - Puppet[:code] = "$x = has_key('foo', 'bar')" - expect { - scope.compiler.compile - }.to raise_error(Puppet::ParseError, /expects the first argument to be a hash/) - end - end - - describe 'when calling the function has_key from a scope instance' do - it 'should detect existing keys' do - expect(scope.function_has_key([{'one' => 1}, 'one'])).to be_truthy - end - - it 'should detect existing keys' do - expect(scope.function_has_key([{'one' => 1}, 'two'])).to be_falsey - end - end +describe 'has_key' 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("one").and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } + it { is_expected.to run.with_params("one", "two", "three").and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } + it { is_expected.to run.with_params("one", "two").and_raise_error(Puppet::ParseError, /expects the first argument to be a hash/) } + it { is_expected.to run.with_params(1, "two").and_raise_error(Puppet::ParseError, /expects the first argument to be a hash/) } + it { is_expected.to run.with_params([], "two").and_raise_error(Puppet::ParseError, /expects the first argument to be a hash/) } + + it { is_expected.to run.with_params({ 'key' => 'value' }, "key").and_return(true) } + it { is_expected.to run.with_params({}, "key").and_return(false) } + it { is_expected.to run.with_params({ 'key' => 'value'}, "not a key").and_return(false) } end diff --git a/spec/functions/hash_spec.rb b/spec/functions/hash_spec.rb index ec2988b..4fe99ce 100755 --- a/spec/functions/hash_spec.rb +++ b/spec/functions/hash_spec.rb @@ -1,19 +1,14 @@ -#! /usr/bin/env ruby -S rspec require 'spec_helper' -describe "the hash function" do - let(:scope) { PuppetlabsSpec::PuppetInternals.scope } - - it "should exist" do - expect(Puppet::Parser::Functions.function("hash")).to eq("function_hash") - end - - it "should raise a ParseError if there is less than 1 arguments" do - expect { scope.function_hash([]) }.to( raise_error(Puppet::ParseError)) - end - - it "should convert an array to a hash" do - result = scope.function_hash([['a',1,'b',2,'c',3]]) - expect(result).to(eq({'a'=>1,'b'=>2,'c'=>3})) - end +describe 'hash' 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 { + pending("Current implementation ignores parameters after the first.") + is_expected.to run.with_params([], 'two').and_raise_error(Puppet::ParseError, /wrong number of arguments/i) + } + it { is_expected.to run.with_params(['one']).and_raise_error(Puppet::ParseError, /Unable to compute/) } + it { is_expected.to run.with_params([]).and_return({}) } + it { is_expected.to run.with_params(['key1', 'value1']).and_return({ 'key1' => 'value1' }) } + it { is_expected.to run.with_params(['key1', 'value1', 'key2', 'value2']).and_return({ 'key1' => 'value1', 'key2' => 'value2' }) } end diff --git a/spec/functions/intersection_spec.rb b/spec/functions/intersection_spec.rb index 6361304..c0f6086 100755 --- a/spec/functions/intersection_spec.rb +++ b/spec/functions/intersection_spec.rb @@ -1,19 +1,21 @@ -#! /usr/bin/env ruby -S rspec require 'spec_helper' -describe "the intersection function" do - let(:scope) { PuppetlabsSpec::PuppetInternals.scope } - - it "should exist" do - expect(Puppet::Parser::Functions.function("intersection")).to eq("function_intersection") - end - - it "should raise a ParseError if there are fewer than 2 arguments" do - expect { scope.function_intersection([]) }.to( raise_error(Puppet::ParseError) ) - end - - it "should return the intersection of two arrays" do - result = scope.function_intersection([["a","b","c"],["b","c","d"]]) - expect(result).to(eq(["b","c"])) - end +describe 'intersection' do + it { is_expected.not_to eq(nil) } + it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError) } + it { is_expected.to run.with_params('one').and_raise_error(Puppet::ParseError) } + it { is_expected.to run.with_params('one', 'two').and_raise_error(Puppet::ParseError) } + it { is_expected.to run.with_params('one', 'two', 'three').and_raise_error(Puppet::ParseError) } + it { is_expected.to run.with_params('one', []).and_raise_error(Puppet::ParseError) } + it { is_expected.to run.with_params([], 'two').and_raise_error(Puppet::ParseError) } + it { is_expected.to run.with_params({}, {}).and_raise_error(Puppet::ParseError) } + it { is_expected.to run.with_params([], []).and_return([]) } + it { is_expected.to run.with_params([], ['one']).and_return([]) } + it { is_expected.to run.with_params(['one'], []).and_return([]) } + it { is_expected.to run.with_params(['one'], ['one']).and_return(['one']) } + it { is_expected.to run.with_params(['one', 'two', 'three'], ['two', 'three']).and_return(['two', 'three']) } + it { is_expected.to run.with_params(['one', 'two', 'two', 'three'], ['two', 'three']).and_return(['two', 'three']) } + it { is_expected.to run.with_params(['one', 'two', 'three'], ['two', 'two', 'three']).and_return(['two', 'three']) } + it { is_expected.to run.with_params(['one', 'two', 'three'], ['two', 'three', 'four']).and_return(['two', 'three']) } + it 'should not confuse types' do is_expected.to run.with_params(['1', '2', '3'], [1, 2]).and_return([]) end end diff --git a/spec/functions/is_array_spec.rb b/spec/functions/is_array_spec.rb index 94920a4..7dd21c2 100755 --- a/spec/functions/is_array_spec.rb +++ b/spec/functions/is_array_spec.rb @@ -1,29 +1,19 @@ -#! /usr/bin/env ruby -S rspec require 'spec_helper' -describe "the is_array function" do - let(:scope) { PuppetlabsSpec::PuppetInternals.scope } - - it "should exist" do - expect(Puppet::Parser::Functions.function("is_array")).to eq("function_is_array") - end - - it "should raise a ParseError if there is less than 1 arguments" do - expect { scope.function_is_array([]) }.to( raise_error(Puppet::ParseError)) - end - - it "should return true if passed an array" do - result = scope.function_is_array([[1,2,3]]) - expect(result).to(eq(true)) - end - - it "should return false if passed a hash" do - result = scope.function_is_array([{'a'=>1}]) - expect(result).to(eq(false)) - end - - it "should return false if passed a string" do - result = scope.function_is_array(["asdf"]) - expect(result).to(eq(false)) - end +describe 'is_array' 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 { + pending("Current implementation ignores parameters after the first.") + is_expected.to run.with_params([], []).and_raise_error(Puppet::ParseError, /wrong number of arguments/i) + } + it { is_expected.to run.with_params([]).and_return(true) } + it { is_expected.to run.with_params(['one']).and_return(true) } + it { is_expected.to run.with_params([1]).and_return(true) } + it { is_expected.to run.with_params([{}]).and_return(true) } + it { is_expected.to run.with_params([[]]).and_return(true) } + it { is_expected.to run.with_params('').and_return(false) } + it { is_expected.to run.with_params('one').and_return(false) } + it { is_expected.to run.with_params(1).and_return(false) } + it { is_expected.to run.with_params({}).and_return(false) } end diff --git a/spec/functions/is_bool_spec.rb b/spec/functions/is_bool_spec.rb index 4a342ba..76d619b 100755 --- a/spec/functions/is_bool_spec.rb +++ b/spec/functions/is_bool_spec.rb @@ -1,44 +1,15 @@ -#! /usr/bin/env ruby -S rspec require 'spec_helper' -describe "the is_bool function" do - let(:scope) { PuppetlabsSpec::PuppetInternals.scope } - - it "should exist" do - expect(Puppet::Parser::Functions.function("is_bool")).to eq("function_is_bool") - end - - it "should raise a ParseError if there is less than 1 arguments" do - expect { scope.function_is_bool([]) }.to( raise_error(Puppet::ParseError)) - end - - it "should return true if passed a TrueClass" do - result = scope.function_is_bool([true]) - expect(result).to(eq(true)) - end - - it "should return true if passed a FalseClass" do - result = scope.function_is_bool([false]) - expect(result).to(eq(true)) - end - - it "should return false if passed the string 'true'" do - result = scope.function_is_bool(['true']) - expect(result).to(eq(false)) - end - - it "should return false if passed the string 'false'" do - result = scope.function_is_bool(['false']) - expect(result).to(eq(false)) - end - - it "should return false if passed an array" do - result = scope.function_is_bool([["a","b"]]) - expect(result).to(eq(false)) - end - - it "should return false if passed a hash" do - result = scope.function_is_bool([{"a" => "b"}]) - expect(result).to(eq(false)) - end +describe 'is_bool' 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(true, false).and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } + it { is_expected.to run.with_params(true).and_return(true) } + it { is_expected.to run.with_params(false).and_return(true) } + it { is_expected.to run.with_params([1]).and_return(false) } + it { is_expected.to run.with_params([{}]).and_return(false) } + it { is_expected.to run.with_params([[]]).and_return(false) } + it { is_expected.to run.with_params([true]).and_return(false) } + it { is_expected.to run.with_params('true').and_return(false) } + it { is_expected.to run.with_params('false').and_return(false) } end diff --git a/spec/functions/is_domain_name_spec.rb b/spec/functions/is_domain_name_spec.rb index ef88061..c1bf0e3 100755 --- a/spec/functions/is_domain_name_spec.rb +++ b/spec/functions/is_domain_name_spec.rb @@ -1,81 +1,43 @@ -#! /usr/bin/env ruby -S rspec require 'spec_helper' -describe "the is_domain_name function" do - let(:scope) { PuppetlabsSpec::PuppetInternals.scope } - - it "should exist" do - expect(Puppet::Parser::Functions.function("is_domain_name")).to eq("function_is_domain_name") - end - - it "should raise a ParseError if there is less than 1 arguments" do - expect { scope.function_is_domain_name([]) }.to( raise_error(Puppet::ParseError)) - end - - it "should return true if a valid short domain name" do - result = scope.function_is_domain_name(["x.com"]) - expect(result).to(be_truthy) - end - - it "should return true if the domain is ." do - result = scope.function_is_domain_name(["."]) - expect(result).to(be_truthy) +describe 'is_domain_name' 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('one', 'two').and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } + it { is_expected.to run.with_params(1).and_return(false) } + it { is_expected.to run.with_params([]).and_return(false) } + it { is_expected.to run.with_params({}).and_return(false) } + it { is_expected.to run.with_params('').and_return(false) } + it { is_expected.to run.with_params('.').and_return(true) } + it { is_expected.to run.with_params('com').and_return(true) } + it { is_expected.to run.with_params('com.').and_return(true) } + it { is_expected.to run.with_params('x.com').and_return(true) } + it { is_expected.to run.with_params('x.com.').and_return(true) } + it { is_expected.to run.with_params('foo.example.com').and_return(true) } + it { is_expected.to run.with_params('foo.example.com.').and_return(true) } + it { is_expected.to run.with_params('2foo.example.com').and_return(true) } + it { is_expected.to run.with_params('2foo.example.com.').and_return(true) } + it { is_expected.to run.with_params('www.2foo.example.com').and_return(true) } + it { is_expected.to run.with_params('www.2foo.example.com.').and_return(true) } + describe 'inputs with spaces' do + it { is_expected.to run.with_params('invalid domain').and_return(false) } + end + describe 'inputs with hyphens' do + it { is_expected.to run.with_params('foo-bar.example.com').and_return(true) } + it { is_expected.to run.with_params('foo-bar.example.com.').and_return(true) } + it { is_expected.to run.with_params('www.foo-bar.example.com').and_return(true) } + it { is_expected.to run.with_params('www.foo-bar.example.com.').and_return(true) } + it { is_expected.to run.with_params('-foo.example.com').and_return(false) } + it { is_expected.to run.with_params('-foo.example.com').and_return(false) } end - - it "should return true if the domain is x.com." do - result = scope.function_is_domain_name(["x.com."]) - expect(result).to(be_truthy) - end - - it "should return true if a valid domain name" do - result = scope.function_is_domain_name(["foo.bar.com"]) - expect(result).to(be_truthy) - end - - it "should allow domain parts to start with numbers" do - result = scope.function_is_domain_name(["3foo.2bar.com"]) - expect(result).to(be_truthy) - end - - it "should allow domain to end with a dot" do - result = scope.function_is_domain_name(["3foo.2bar.com."]) - expect(result).to(be_truthy) - end - - it "should allow a single part domain" do - result = scope.function_is_domain_name(["orange"]) - expect(result).to(be_truthy) - end - - it "should return false if domain parts start with hyphens" do - result = scope.function_is_domain_name(["-3foo.2bar.com"]) - expect(result).to(be_falsey) - end - - it "should return true if domain contains hyphens" do - result = scope.function_is_domain_name(["3foo-bar.2bar-fuzz.com"]) - expect(result).to(be_truthy) - end - - it "should return false if domain name contains spaces" do - result = scope.function_is_domain_name(["not valid"]) - expect(result).to(be_falsey) - end - # Values obtained from Facter values will be frozen strings # in newer versions of Facter: - it "should not throw an exception if passed a frozen string" do - result = scope.function_is_domain_name(["my.domain.name".freeze]) - expect(result).to(be_truthy) + it { is_expected.to run.with_params('www.example.com'.freeze).and_return(true) } + describe 'top level domain must be alphabetic if there are multiple labels' do + it { is_expected.to run.with_params('2com').and_return(true) } + it { is_expected.to run.with_params('www.example.2com').and_return(false) } end - - it "should return false if top-level domain is not entirely alphabetic" do - result = scope.function_is_domain_name(["kiwi.2bar"]) - expect(result).to(be_falsey) - end - - it "should return false if domain name has the dotted-decimal form, e.g. an IPv4 address" do - result = scope.function_is_domain_name(["192.168.1.1"]) - expect(result).to(be_falsey) + describe 'IP addresses are not domain names' do + it { is_expected.to run.with_params('192.168.1.1').and_return(false) } end end diff --git a/spec/functions/is_float_spec.rb b/spec/functions/is_float_spec.rb index d926634..ffff971 100755 --- a/spec/functions/is_float_spec.rb +++ b/spec/functions/is_float_spec.rb @@ -1,33 +1,22 @@ -#! /usr/bin/env ruby -S rspec require 'spec_helper' -describe "the is_float function" do - let(:scope) { PuppetlabsSpec::PuppetInternals.scope } +describe 'is_float' 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(0.1, 0.2).and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } - it "should exist" do - expect(Puppet::Parser::Functions.function("is_float")).to eq("function_is_float") + describe 'passing a string' do + it { is_expected.to run.with_params('0.1').and_return(true) } + it { is_expected.to run.with_params('1.0').and_return(true) } + it { is_expected.to run.with_params('1').and_return(false) } + it { is_expected.to run.with_params('one').and_return(false) } + it { is_expected.to run.with_params('one 1.0').and_return(false) } + it { is_expected.to run.with_params('1.0 one').and_return(false) } end - it "should raise a ParseError if there is less than 1 arguments" do - expect { scope.function_is_float([]) }.to( raise_error(Puppet::ParseError)) - end - - it "should return true if a float" do - result = scope.function_is_float(["0.12"]) - expect(result).to(eq(true)) - end - - it "should return false if a string" do - result = scope.function_is_float(["asdf"]) - expect(result).to(eq(false)) - end - - it "should return false if an integer" do - result = scope.function_is_float(["3"]) - expect(result).to(eq(false)) - end - it "should return true if a float is created from an arithmetical operation" do - result = scope.function_is_float([3.2*2]) - expect(result).to(eq(true)) + describe 'passing numbers' do + it { is_expected.to run.with_params(0.1).and_return(true) } + it { is_expected.to run.with_params(1.0).and_return(true) } + it { is_expected.to run.with_params(1).and_return(false) } end end diff --git a/spec/functions/is_function_available.rb b/spec/functions/is_function_available.rb index 3a9aa1b..44f08c0 100755 --- a/spec/functions/is_function_available.rb +++ b/spec/functions/is_function_available.rb @@ -1,31 +1,9 @@ -#!/usr/bin/env ruby -S rspec require 'spec_helper' -describe "the is_function_available function" do - before :all do - Puppet::Parser::Functions.autoloader.loadall - end - - before :each do - @scope = Puppet::Parser::Scope.new - end - - it "should exist" do - expect(Puppet::Parser::Functions.function("is_function_available")).to eq("function_is_function_available") - end - - it "should raise a ParseError if there is less than 1 arguments" do - expect { @scope.function_is_function_available([]) }.to( raise_error(Puppet::ParseError)) - end - - it "should return false if a nonexistent function is passed" do - result = @scope.function_is_function_available(['jeff_mccunes_left_sock']) - expect(result).to(eq(false)) - end - - it "should return true if an available function is passed" do - result = @scope.function_is_function_available(['require']) - expect(result).to(eq(true)) - end - +describe 'is_function_available' 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('one', 'two').and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } + it { is_expected.to run.with_params('include').and_return(true) } + it { is_expected.to run.with_params('no_such_function').and_return(false) } end diff --git a/spec/functions/is_hash_spec.rb b/spec/functions/is_hash_spec.rb index a849411..c2599a0 100755 --- a/spec/functions/is_hash_spec.rb +++ b/spec/functions/is_hash_spec.rb @@ -1,29 +1,11 @@ -#! /usr/bin/env ruby -S rspec require 'spec_helper' -describe "the is_hash function" do - let(:scope) { PuppetlabsSpec::PuppetInternals.scope } - - it "should exist" do - expect(Puppet::Parser::Functions.function("is_hash")).to eq("function_is_hash") - end - - it "should raise a ParseError if there is less than 1 arguments" do - expect { scope.function_is_hash([]) }.to( raise_error(Puppet::ParseError)) - end - - it "should return true if passed a hash" do - result = scope.function_is_hash([{"a"=>1,"b"=>2}]) - expect(result).to(eq(true)) - end - - it "should return false if passed an array" do - result = scope.function_is_hash([["a","b"]]) - expect(result).to(eq(false)) - end - - it "should return false if passed a string" do - result = scope.function_is_hash(["asdf"]) - expect(result).to(eq(false)) - end +describe 'is_hash' 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('').and_return(false) } + it { is_expected.to run.with_params({}).and_return(true) } + it { is_expected.to run.with_params([]).and_return(false) } + it { is_expected.to run.with_params(1).and_return(false) } end diff --git a/spec/functions/is_integer_spec.rb b/spec/functions/is_integer_spec.rb index f0cbca8..67263c1 100755 --- a/spec/functions/is_integer_spec.rb +++ b/spec/functions/is_integer_spec.rb @@ -1,69 +1,25 @@ -#! /usr/bin/env ruby -S rspec require 'spec_helper' -describe "the is_integer function" do - let(:scope) { PuppetlabsSpec::PuppetInternals.scope } - - it "should exist" do - expect(Puppet::Parser::Functions.function("is_integer")).to eq("function_is_integer") - end - - it "should raise a ParseError if there is less than 1 arguments" do - expect { scope.function_is_integer([]) }.to( raise_error(Puppet::ParseError)) - end - - it "should return true if an integer" do - result = scope.function_is_integer(["3"]) - expect(result).to(eq(true)) - end - - it "should return true if a negative integer" do - result = scope.function_is_integer(["-7"]) - expect(result).to(eq(true)) - end - - it "should return false if a float" do - result = scope.function_is_integer(["3.2"]) - expect(result).to(eq(false)) - end - - it "should return false if a string" do - result = scope.function_is_integer(["asdf"]) - expect(result).to(eq(false)) - end - - it "should return true if an integer is created from an arithmetical operation" do - result = scope.function_is_integer([3*2]) - expect(result).to(eq(true)) - end - - it "should return false if an array" do - result = scope.function_is_numeric([["asdf"]]) - expect(result).to(eq(false)) - end - - it "should return false if a hash" do - result = scope.function_is_numeric([{"asdf" => false}]) - expect(result).to(eq(false)) - end - - it "should return false if a boolean" do - result = scope.function_is_numeric([true]) - expect(result).to(eq(false)) - end - - it "should return false if a whitespace is in the string" do - result = scope.function_is_numeric([" -1324"]) - expect(result).to(eq(false)) - end - - it "should return false if it is zero prefixed" do - result = scope.function_is_numeric(["0001234"]) - expect(result).to(eq(false)) - end - - it "should return false if it is wrapped inside an array" do - result = scope.function_is_numeric([[1234]]) - expect(result).to(eq(false)) - end +describe 'is_integer' 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(1, 2).and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } + + it { is_expected.to run.with_params(3).and_return(true) } + it { is_expected.to run.with_params('3').and_return(true) } + it { is_expected.to run.with_params(-3).and_return(true) } + it { is_expected.to run.with_params('-3').and_return(true) } + + it { is_expected.to run.with_params(3.7).and_return(false) } + it { is_expected.to run.with_params('3.7').and_return(false) } + it { is_expected.to run.with_params(-3.7).and_return(false) } + it { is_expected.to run.with_params('3.7').and_return(false) } + + it { is_expected.to run.with_params('one').and_return(false) } + it { is_expected.to run.with_params([]).and_return(false) } + it { is_expected.to run.with_params([1]).and_return(false) } + it { is_expected.to run.with_params({}).and_return(false) } + it { is_expected.to run.with_params(true).and_return(false) } + it { is_expected.to run.with_params(false).and_return(false) } + it { is_expected.to run.with_params('0001234').and_return(false) } end diff --git a/spec/functions/is_ip_address_spec.rb b/spec/functions/is_ip_address_spec.rb index c16d12b..a7a383a 100755 --- a/spec/functions/is_ip_address_spec.rb +++ b/spec/functions/is_ip_address_spec.rb @@ -1,39 +1,23 @@ -#! /usr/bin/env ruby -S rspec require 'spec_helper' -describe "the is_ip_address function" do - let(:scope) { PuppetlabsSpec::PuppetInternals.scope } - - it "should exist" do - expect(Puppet::Parser::Functions.function("is_ip_address")).to eq("function_is_ip_address") - end - - it "should raise a ParseError if there is less than 1 arguments" do - expect { scope.function_is_ip_address([]) }.to( raise_error(Puppet::ParseError)) - end - - it "should return true if an IPv4 address" do - result = scope.function_is_ip_address(["1.2.3.4"]) - expect(result).to(eq(true)) - end - - it "should return true if a full IPv6 address" do - result = scope.function_is_ip_address(["fe80:0000:cd12:d123:e2f8:47ff:fe09:dd74"]) - expect(result).to(eq(true)) - end - - it "should return true if a compressed IPv6 address" do - result = scope.function_is_ip_address(["fe00::1"]) - expect(result).to(eq(true)) - end - - it "should return false if not valid" do - result = scope.function_is_ip_address(["asdf"]) - expect(result).to(eq(false)) - end - - it "should return false if IP octets out of range" do - result = scope.function_is_ip_address(["1.1.1.300"]) - expect(result).to(eq(false)) - end +describe 'is_ip_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('1.2.3.4').and_return(true) } + it { is_expected.to run.with_params('1.2.3.255').and_return(true) } + it { is_expected.to run.with_params('1.2.3.256').and_return(false) } + it { is_expected.to run.with_params('1.2.3').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('fe00::1').and_return(true) } + it { is_expected.to run.with_params('fe80:0000:cd12:d123:e2f8:47ff:fe09:dd74').and_return(true) } + it { is_expected.to run.with_params('FE80:0000:CD12:D123:E2F8:47FF:FE09:DD74').and_return(true) } + it { is_expected.to run.with_params('fe80:0000:cd12:d123:e2f8:47ff:fe09:zzzz').and_return(false) } + it { is_expected.to run.with_params('fe80:0000:cd12:d123:e2f8:47ff:fe09').and_return(false) } + it { is_expected.to run.with_params('fe80:0000:cd12:d123:e2f8:47ff:fe09:dd74:dd74').and_return(false) } + it { is_expected.to run.with_params('').and_return(false) } + it { is_expected.to run.with_params('one').and_return(false) } + it { is_expected.to run.with_params(1).and_return(false) } + it { is_expected.to run.with_params({}).and_return(false) } + it { is_expected.to run.with_params([]).and_return(false) } end diff --git a/spec/functions/is_mac_address_spec.rb b/spec/functions/is_mac_address_spec.rb index 66edd19..5f76a91 100755 --- a/spec/functions/is_mac_address_spec.rb +++ b/spec/functions/is_mac_address_spec.rb @@ -1,29 +1,24 @@ -#! /usr/bin/env ruby -S rspec require 'spec_helper' -describe "the is_mac_address function" do - let(:scope) { PuppetlabsSpec::PuppetInternals.scope } - - it "should exist" do - expect(Puppet::Parser::Functions.function("is_mac_address")).to eq("function_is_mac_address") - end - - it "should raise a ParseError if there is less than 1 arguments" do - expect { scope.function_is_mac_address([]) }.to( raise_error(Puppet::ParseError)) - end - - it "should return true if a valid mac address" do - result = scope.function_is_mac_address(["00:a0:1f:12:7f:a0"]) - expect(result).to(eq(true)) - end - - it "should return false if octets are out of range" do - result = scope.function_is_mac_address(["00:a0:1f:12:7f:g0"]) - expect(result).to(eq(false)) - end - - it "should return false if not valid" do - result = scope.function_is_mac_address(["not valid"]) - expect(result).to(eq(false)) - end +describe 'is_mac_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('00:a0:1f:12:7f:a0').and_return(true) } + it { is_expected.to run.with_params('00:A0:1F:12:7F:A0').and_return(true) } + it { is_expected.to run.with_params('00:00:00:00:00:0g').and_return(false) } + it { is_expected.to run.with_params('').and_return(false) } + it { is_expected.to run.with_params('one').and_return(false) } + it { + pending "should properly typecheck its arguments" + is_expected.to run.with_params(1).and_return(false) + } + it { + pending "should properly typecheck its arguments" + is_expected.to run.with_params({}).and_return(false) + } + it { + pending "should properly typecheck its arguments" + is_expected.to run.with_params([]).and_return(false) + } end diff --git a/spec/functions/is_numeric_spec.rb b/spec/functions/is_numeric_spec.rb index 4176961..d0f5a6e 100755 --- a/spec/functions/is_numeric_spec.rb +++ b/spec/functions/is_numeric_spec.rb @@ -1,119 +1,28 @@ -#! /usr/bin/env ruby -S rspec require 'spec_helper' -describe "the is_numeric function" do - let(:scope) { PuppetlabsSpec::PuppetInternals.scope } - - it "should exist" do - expect(Puppet::Parser::Functions.function("is_numeric")).to eq("function_is_numeric") - end - - it "should raise a ParseError if there is less than 1 argument" do - expect { scope.function_is_numeric([]) }.to( raise_error(Puppet::ParseError)) - end - - it "should return true if an integer" do - result = scope.function_is_numeric(["3"]) - expect(result).to(eq(true)) - end - - it "should return true if a float" do - result = scope.function_is_numeric(["3.2"]) - expect(result).to(eq(true)) - end - - it "should return true if an integer is created from an arithmetical operation" do - result = scope.function_is_numeric([3*2]) - expect(result).to(eq(true)) - end - - it "should return true if a float is created from an arithmetical operation" do - result = scope.function_is_numeric([3.2*2]) - expect(result).to(eq(true)) - end - - it "should return false if a string" do - result = scope.function_is_numeric(["asdf"]) - expect(result).to(eq(false)) - end - - it "should return false if an array" do - result = scope.function_is_numeric([["asdf"]]) - expect(result).to(eq(false)) - end - - it "should return false if an array of integers" do - result = scope.function_is_numeric([[1,2,3,4]]) - expect(result).to(eq(false)) - end - - it "should return false if a hash" do - result = scope.function_is_numeric([{"asdf" => false}]) - expect(result).to(eq(false)) - end - - it "should return false if a hash with numbers in it" do - result = scope.function_is_numeric([{1 => 2}]) - expect(result).to(eq(false)) - end - - it "should return false if a boolean" do - result = scope.function_is_numeric([true]) - expect(result).to(eq(false)) - end - - it "should return true if a negative float with exponent" do - result = scope.function_is_numeric(["-342.2315e-12"]) - expect(result).to(eq(true)) - end - - it "should return false if a negative integer with whitespaces before/after the dash" do - result = scope.function_is_numeric([" - 751"]) - expect(result).to(eq(false)) - end - -# it "should return true if a hexadecimal" do -# result = scope.function_is_numeric(["0x52F8c"]) -# result.should(eq(true)) -# end -# -# it "should return true if a hexadecimal with uppercase 0X prefix" do -# result = scope.function_is_numeric(["0X52F8c"]) -# result.should(eq(true)) -# end -# -# it "should return false if a hexadecimal without a prefix" do -# result = scope.function_is_numeric(["52F8c"]) -# result.should(eq(false)) -# end -# -# it "should return true if a octal" do -# result = scope.function_is_numeric(["0751"]) -# result.should(eq(true)) -# end -# -# it "should return true if a negative hexadecimal" do -# result = scope.function_is_numeric(["-0x52F8c"]) -# result.should(eq(true)) -# end -# -# it "should return true if a negative octal" do -# result = scope.function_is_numeric(["-0751"]) -# result.should(eq(true)) -# end -# -# it "should return false if a negative octal with whitespaces before/after the dash" do -# result = scope.function_is_numeric([" - 0751"]) -# result.should(eq(false)) -# end -# -# it "should return false if a bad hexadecimal" do -# result = scope.function_is_numeric(["0x23d7g"]) -# result.should(eq(false)) -# end -# -# it "should return false if a bad octal" do -# result = scope.function_is_numeric(["0287"]) -# result.should(eq(false)) -# end +describe 'is_numeric' 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(1, 2).and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } + + it { is_expected.to run.with_params(3).and_return(true) } + it { is_expected.to run.with_params('3').and_return(true) } + it { is_expected.to run.with_params(-3).and_return(true) } + it { is_expected.to run.with_params('-3').and_return(true) } + + it { is_expected.to run.with_params(3.7).and_return(true) } + it { is_expected.to run.with_params('3.7').and_return(true) } + it { is_expected.to run.with_params(-3.7).and_return(true) } + it { is_expected.to run.with_params('3.7').and_return(true) } + + it { is_expected.to run.with_params('-342.2315e-12').and_return(true) } + + it { is_expected.to run.with_params('one').and_return(false) } + it { is_expected.to run.with_params([]).and_return(false) } + it { is_expected.to run.with_params([1]).and_return(false) } + it { is_expected.to run.with_params({}).and_return(false) } + it { is_expected.to run.with_params(true).and_return(false) } + it { is_expected.to run.with_params(false).and_return(false) } + it { is_expected.to run.with_params('0001234').and_return(false) } + it { is_expected.to run.with_params(' - 1234').and_return(false) } end diff --git a/spec/functions/is_string_spec.rb b/spec/functions/is_string_spec.rb index 6a0801a..8e459cc 100755 --- a/spec/functions/is_string_spec.rb +++ b/spec/functions/is_string_spec.rb @@ -1,34 +1,28 @@ -#! /usr/bin/env ruby -S rspec require 'spec_helper' -describe "the is_string function" do - let(:scope) { PuppetlabsSpec::PuppetInternals.scope } +describe 'is_string' 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 { + pending("Current implementation ignores parameters after the first.") + is_expected.to run.with_params('', '').and_raise_error(Puppet::ParseError, /wrong number of arguments/i) + } - it "should exist" do - expect(Puppet::Parser::Functions.function("is_string")).to eq("function_is_string") - end + it { is_expected.to run.with_params(3).and_return(false) } + it { is_expected.to run.with_params('3').and_return(false) } + it { is_expected.to run.with_params(-3).and_return(false) } + it { is_expected.to run.with_params('-3').and_return(false) } - it "should raise a ParseError if there is less than 1 arguments" do - expect { scope.function_is_string([]) }.to( raise_error(Puppet::ParseError)) - end + it { is_expected.to run.with_params(3.7).and_return(false) } + it { is_expected.to run.with_params('3.7').and_return(false) } + it { is_expected.to run.with_params(-3.7).and_return(false) } + it { is_expected.to run.with_params('3.7').and_return(false) } - it "should return true if a string" do - result = scope.function_is_string(["asdf"]) - expect(result).to(eq(true)) - end - - it "should return false if an integer" do - result = scope.function_is_string(["3"]) - expect(result).to(eq(false)) - end - - it "should return false if a float" do - result = scope.function_is_string(["3.23"]) - expect(result).to(eq(false)) - end - - it "should return false if an array" do - result = scope.function_is_string([["a","b","c"]]) - expect(result).to(eq(false)) - end + it { is_expected.to run.with_params([]).and_return(false) } + it { is_expected.to run.with_params([1]).and_return(false) } + it { is_expected.to run.with_params({}).and_return(false) } + it { is_expected.to run.with_params(true).and_return(false) } + it { is_expected.to run.with_params(false).and_return(false) } + it { is_expected.to run.with_params('one').and_return(true) } + it { is_expected.to run.with_params('0001234').and_return(true) } end diff --git a/spec/functions/join_keys_to_values_spec.rb b/spec/functions/join_keys_to_values_spec.rb index 4a9ae87..6c109d1 100755 --- a/spec/functions/join_keys_to_values_spec.rb +++ b/spec/functions/join_keys_to_values_spec.rb @@ -1,40 +1,19 @@ -#! /usr/bin/env ruby -S rspec require 'spec_helper' -describe "the join_keys_to_values function" do - let(:scope) { PuppetlabsSpec::PuppetInternals.scope } - - it "should exist" do - expect(Puppet::Parser::Functions.function("join_keys_to_values")).to eq("function_join_keys_to_values") - end - - it "should raise a ParseError if there are fewer than two arguments" do - expect { scope.function_join_keys_to_values([{}]) }.to raise_error Puppet::ParseError - end - - it "should raise a ParseError if there are greater than two arguments" do - expect { scope.function_join_keys_to_values([{}, 'foo', 'bar']) }.to raise_error Puppet::ParseError - end - - it "should raise a TypeError if the first argument is an array" do - expect { scope.function_join_keys_to_values([[1,2], ',']) }.to raise_error TypeError - end - - it "should raise a TypeError if the second argument is an array" do - expect { scope.function_join_keys_to_values([{}, [1,2]]) }.to raise_error TypeError - end - - it "should raise a TypeError if the second argument is a number" do - expect { scope.function_join_keys_to_values([{}, 1]) }.to raise_error TypeError - end - - it "should return an empty array given an empty hash" do - result = scope.function_join_keys_to_values([{}, ":"]) - expect(result).to eq([]) - end - - it "should join hash's keys to its values" do - result = scope.function_join_keys_to_values([{'a'=>1,2=>'foo',:b=>nil}, ":"]) - expect(result).to match_array(['a:1','2:foo','b:']) +describe 'join_keys_to_values' do + it { is_expected.not_to eq(nil) } + it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError, /Takes exactly two arguments/) } + it { is_expected.to run.with_params({}, '', '').and_raise_error(Puppet::ParseError, /Takes exactly two arguments/) } + it { is_expected.to run.with_params('one', '').and_raise_error(TypeError, /The first argument must be a hash/) } + it { is_expected.to run.with_params({}, 2).and_raise_error(TypeError, /The second argument must be a string/) } + + it { is_expected.to run.with_params({}, '').and_return([]) } + it { is_expected.to run.with_params({}, ':').and_return([]) } + it { is_expected.to run.with_params({ 'key' => 'value' }, '').and_return(['keyvalue']) } + it { is_expected.to run.with_params({ 'key' => 'value' }, ':').and_return(['key:value']) } + it { is_expected.to run.with_params({ 'key' => nil }, ':').and_return(['key:']) } + it 'should run join_keys_to_values(, ":") and return the proper array' do + result = subject.call([{ 'key1' => 'value1', 'key2' => 'value2' }, ':']) + expect(result.sort).to eq(['key1:value1', 'key2:value2'].sort) end end diff --git a/spec/functions/join_spec.rb b/spec/functions/join_spec.rb index 793c36f..a300571 100755 --- a/spec/functions/join_spec.rb +++ b/spec/functions/join_spec.rb @@ -1,19 +1,19 @@ -#! /usr/bin/env ruby -S rspec require 'spec_helper' -describe "the join function" do - let(:scope) { PuppetlabsSpec::PuppetInternals.scope } +describe 'join' 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 { + pending("Current implementation ignores parameters after the second.") + is_expected.to run.with_params([], '', '').and_raise_error(Puppet::ParseError, /wrong number of arguments/i) + } + it { is_expected.to run.with_params('one').and_raise_error(Puppet::ParseError, /Requires array to work with/) } + it { is_expected.to run.with_params([], 2).and_raise_error(Puppet::ParseError, /Requires string to work with/) } - it "should exist" do - expect(Puppet::Parser::Functions.function("join")).to eq("function_join") - end - - it "should raise a ParseError if there is less than 1 arguments" do - expect { scope.function_join([]) }.to( raise_error(Puppet::ParseError)) - end - - it "should join an array into a string" do - result = scope.function_join([["a","b","c"], ":"]) - expect(result).to(eq("a:b:c")) - end + it { is_expected.to run.with_params([]).and_return('') } + it { is_expected.to run.with_params([], ':').and_return('') } + it { is_expected.to run.with_params(['one']).and_return('one') } + it { is_expected.to run.with_params(['one'], ':').and_return('one') } + it { is_expected.to run.with_params(['one', 'two', 'three']).and_return('onetwothree') } + it { is_expected.to run.with_params(['one', 'two', 'three'], ':').and_return('one:two:three') } end diff --git a/spec/functions/keys_spec.rb b/spec/functions/keys_spec.rb index f2e7d42..2e009dc 100755 --- a/spec/functions/keys_spec.rb +++ b/spec/functions/keys_spec.rb @@ -1,21 +1,19 @@ -#! /usr/bin/env ruby -S rspec require 'spec_helper' -describe "the keys function" do - let(:scope) { PuppetlabsSpec::PuppetInternals.scope } - - it "should exist" do - expect(Puppet::Parser::Functions.function("keys")).to eq("function_keys") - end - - it "should raise a ParseError if there is less than 1 arguments" do - expect { scope.function_keys([]) }.to( raise_error(Puppet::ParseError)) - end - - it "should return an array of keys when given a hash" do - result = scope.function_keys([{'a'=>1, 'b'=>2}]) - # =~ performs 'array with same elements' (set) matching - # For more info see RSpec::Matchers::MatchArray - expect(result).to match_array(['a','b']) +describe 'keys' 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 { + pending("Current implementation ignores parameters after the first.") + 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, /Requires hash to work with/) } + it { is_expected.to run.with_params(1).and_raise_error(Puppet::ParseError, /Requires hash to work with/) } + it { is_expected.to run.with_params([]).and_raise_error(Puppet::ParseError, /Requires hash to work with/) } + it { is_expected.to run.with_params({}).and_return([]) } + it { is_expected.to run.with_params({ 'key' => 'value' }).and_return(['key']) } + it 'should return the array of keys' do + result = subject.call([{ 'key1' => 'value1', 'key2' => 'value2' }]) + expect(result).to match_array(['key1', 'key2']) end end diff --git a/spec/functions/loadyaml_spec.rb b/spec/functions/loadyaml_spec.rb index 4b8d406..ffc714d 100755 --- a/spec/functions/loadyaml_spec.rb +++ b/spec/functions/loadyaml_spec.rb @@ -1,31 +1,24 @@ -#! /usr/bin/env ruby -S rspec require 'spec_helper' -describe "the loadyaml function" do - include PuppetlabsSpec::Files - - let(:scope) { PuppetlabsSpec::PuppetInternals.scope } - - it "should exist" do - expect(Puppet::Parser::Functions.function("loadyaml")).to eq("function_loadyaml") - end - - it "should raise a ParseError if there is less than 1 arguments" do - expect { scope.function_loadyaml([]) }.to raise_error(Puppet::ParseError) +describe 'loadyaml' 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) } + context 'when a non-existing file is specified' do + let(:filename) { '/tmp/doesnotexist' } + before { + File.expects(:exists?).with(filename).returns(false).once + YAML.expects(:load_file).never + } + it { is_expected.to run.with_params(filename).and_return(nil) } end - - it "should return nil when file does not exist" do - yaml_file = tmpfilename ('yamlfile') - result = scope.function_loadyaml([yaml_file]) - expect(result).to(eq(nil)) - end - - it "should convert YAML file to a data structure" do - yaml_file = tmpfilename ('yamlfile') - File.open(yaml_file, 'w') do |fh| - fh.write("---\n aaa: 1\n bbb: 2\n ccc: 3\n ddd: 4\n") - end - result = scope.function_loadyaml([yaml_file]) - expect(result).to eq({"aaa" => 1, "bbb" => 2, "ccc" => 3, "ddd" => 4 }) + context 'when an existing file is specified' do + let(:filename) { '/tmp/doesexist' } + let(:data) { { 'key' => 'value' } } + before { + File.expects(:exists?).with(filename).returns(true).once + YAML.expects(:load_file).with(filename).returns(data).once + } + it { is_expected.to run.with_params(filename).and_return(data) } end end diff --git a/spec/functions/lstrip_spec.rb b/spec/functions/lstrip_spec.rb index 68cca1c..981794e 100755 --- a/spec/functions/lstrip_spec.rb +++ b/spec/functions/lstrip_spec.rb @@ -1,28 +1,34 @@ -#! /usr/bin/env ruby -S rspec require 'spec_helper' -describe "the lstrip function" do - let(:scope) { PuppetlabsSpec::PuppetInternals.scope } - - it "should exist" do - expect(Puppet::Parser::Functions.function("lstrip")).to eq("function_lstrip") - end - - it "should raise a ParseError if there is less than 1 arguments" do - expect { scope.function_lstrip([]) }.to( raise_error(Puppet::ParseError)) - end - - it "should lstrip a string" do - result = scope.function_lstrip([" asdf"]) - expect(result).to(eq('asdf')) - end - - it "should accept objects which extend String" do - class AlsoString < String - end - - value = AlsoString.new(" asdf") - result = scope.function_lstrip([value]) - result.should(eq("asdf")) - end +describe 'lstrip' 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 { + pending("Current implementation ignores parameters after the first.") + 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, /Requires either array or string to work with/) } + it { is_expected.to run.with_params(1).and_raise_error(Puppet::ParseError, /Requires either array or string to work with/) } + it { is_expected.to run.with_params('').and_return('') } + it { is_expected.to run.with_params(' ').and_return('') } + it { is_expected.to run.with_params(' ').and_return('') } + it { is_expected.to run.with_params("\t").and_return('') } + it { is_expected.to run.with_params("\t ").and_return('') } + it { is_expected.to run.with_params('one').and_return('one') } + it { is_expected.to run.with_params(' one').and_return('one') } + it { is_expected.to run.with_params(' one').and_return('one') } + it { is_expected.to run.with_params("\tone").and_return('one') } + it { is_expected.to run.with_params("\t one").and_return('one') } + it { is_expected.to run.with_params('one ').and_return('one ') } + it { is_expected.to run.with_params(' one ').and_return('one ') } + it { is_expected.to run.with_params(' one ').and_return('one ') } + it { is_expected.to run.with_params("\tone ").and_return('one ') } + it { is_expected.to run.with_params("\t one ").and_return('one ') } + it { is_expected.to run.with_params("one \t").and_return("one \t") } + it { is_expected.to run.with_params(" one \t").and_return("one \t") } + it { is_expected.to run.with_params(" one \t").and_return("one \t") } + it { is_expected.to run.with_params("\tone \t").and_return("one \t") } + it { is_expected.to run.with_params("\t one \t").and_return("one \t") } + it { is_expected.to run.with_params(' o n e ').and_return('o n e ') } + it { is_expected.to run.with_params(AlsoString.new(' one ')).and_return('one ') } end diff --git a/spec/functions/max_spec.rb b/spec/functions/max_spec.rb index c3d8a13..66fb0c8 100755 --- a/spec/functions/max_spec.rb +++ b/spec/functions/max_spec.rb @@ -1,27 +1,21 @@ -#! /usr/bin/env ruby -S rspec - require 'spec_helper' -describe "the max function" do - let(:scope) { PuppetlabsSpec::PuppetInternals.scope } - - it "should exist" do - expect(Puppet::Parser::Functions.function("max")).to eq("function_max") - end - - it "should raise a ParseError if there is less than 1 arguments" do - expect { scope.function_max([]) }.to( raise_error(Puppet::ParseError)) - end - - it "should be able to compare strings" do - expect(scope.function_max(["albatross","dog","horse"])).to(eq("horse")) - end - - it "should be able to compare numbers" do - expect(scope.function_max([6,8,4])).to(eq(8)) - end +describe 'max' 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(1).and_return(1) } + it { is_expected.to run.with_params(1, 2).and_return(2) } + it { is_expected.to run.with_params(1, 2, 3).and_return(3) } + it { is_expected.to run.with_params(3, 2, 1).and_return(3) } + it { is_expected.to run.with_params('one').and_return('one') } + it { is_expected.to run.with_params('one', 'two').and_return('two') } + it { is_expected.to run.with_params('one', 'two', 'three').and_return('two') } + it { is_expected.to run.with_params('three', 'two', 'one').and_return('two') } - it "should be able to compare a number with a stringified number" do - expect(scope.function_max([1,"2"])).to(eq("2")) + describe 'implementation artifacts' do + it { is_expected.to run.with_params(1, 'one').and_return('one') } + it { is_expected.to run.with_params('1', 'one').and_return('one') } + it { is_expected.to run.with_params('1.3e1', '1.4e0').and_return('1.4e0') } + it { is_expected.to run.with_params(1.3e1, 1.4e0).and_return(1.3e1) } end end diff --git a/spec/functions/member_spec.rb b/spec/functions/member_spec.rb index 1a1d7c6..527f887 100755 --- a/spec/functions/member_spec.rb +++ b/spec/functions/member_spec.rb @@ -1,34 +1,21 @@ -#! /usr/bin/env ruby -S rspec require 'spec_helper' -describe "the member function" do - let(:scope) { PuppetlabsSpec::PuppetInternals.scope } - - it "should exist" do - expect(Puppet::Parser::Functions.function("member")).to eq("function_member") - end - - it "should raise a ParseError if there is less than 1 arguments" do - expect { scope.function_member([]) }.to( raise_error(Puppet::ParseError)) - end - - it "should return true if a member is in an array" do - result = scope.function_member([["a","b","c"], "a"]) - expect(result).to(eq(true)) - end - - it "should return false if a member is not in an array" do - result = scope.function_member([["a","b","c"], "d"]) - expect(result).to(eq(false)) - end - - it "should return true if a member array is in an array" do - result = scope.function_member([["a","b","c"], ["a", "b"]]) - expect(result).to(eq(true)) - end - - it "should return false if a member array is not in an array" do - result = scope.function_member([["a","b","c"], ["d", "e"]]) - expect(result).to(eq(false)) - end +describe 'member' 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 { + pending("Current implementation ignores parameters after the first.") + is_expected.to run.with_params([], [], []).and_raise_error(Puppet::ParseError, /wrong number of arguments/i) + } + it { is_expected.to run.with_params([], '').and_return(false) } + it { is_expected.to run.with_params([], ['']).and_return(false) } + it { is_expected.to run.with_params([''], '').and_return(true) } + it { is_expected.to run.with_params([''], ['']).and_return(true) } + it { is_expected.to run.with_params([], 'one').and_return(false) } + it { is_expected.to run.with_params([], ['one']).and_return(false) } + it { is_expected.to run.with_params(['one'], 'one').and_return(true) } + it { is_expected.to run.with_params(['one'], ['one']).and_return(true) } + it { is_expected.to run.with_params(['one', 'two', 'three', 'four'], ['four', 'two']).and_return(true) } + it { is_expected.to run.with_params(['one', 'two', 'three', 'four'], ['four', 'five']).and_return(false) } end diff --git a/spec/functions/merge_spec.rb b/spec/functions/merge_spec.rb index 2abf976..7b53363 100755 --- a/spec/functions/merge_spec.rb +++ b/spec/functions/merge_spec.rb @@ -1,52 +1,25 @@ -#! /usr/bin/env ruby -S rspec - require 'spec_helper' -describe Puppet::Parser::Functions.function(:merge) do - let(:scope) { PuppetlabsSpec::PuppetInternals.scope } - - describe 'when calling merge from puppet' do - it "should not compile when no arguments are passed" do - skip("Fails on 2.6.x, see bug #15912") if Puppet.version =~ /^2\.6\./ - Puppet[:code] = '$x = merge()' - expect { - scope.compiler.compile - }.to raise_error(Puppet::ParseError, /wrong number of arguments/) - end - - it "should not compile when 1 argument is passed" do - skip("Fails on 2.6.x, see bug #15912") if Puppet.version =~ /^2\.6\./ - Puppet[:code] = "$my_hash={'one' => 1}\n$x = merge($my_hash)" - expect { - scope.compiler.compile - }.to raise_error(Puppet::ParseError, /wrong number of arguments/) - end - end - - describe 'when calling merge on the scope instance' do - it 'should require all parameters are hashes' do - expect { new_hash = scope.function_merge([{}, '2'])}.to raise_error(Puppet::ParseError, /unexpected argument type String/) - expect { new_hash = scope.function_merge([{}, 2])}.to raise_error(Puppet::ParseError, /unexpected argument type Fixnum/) - end - - it 'should accept empty strings as puppet undef' do - expect { new_hash = scope.function_merge([{}, ''])}.not_to raise_error - end - - it 'should be able to merge two hashes' do - new_hash = scope.function_merge([{'one' => '1', 'two' => '1'}, {'two' => '2', 'three' => '2'}]) - expect(new_hash['one']).to eq('1') - expect(new_hash['two']).to eq('2') - expect(new_hash['three']).to eq('2') - end - - it 'should merge multiple hashes' do - hash = scope.function_merge([{'one' => 1}, {'one' => '2'}, {'one' => '3'}]) - expect(hash['one']).to eq('3') - end - - it 'should accept empty hashes' do - expect(scope.function_merge([{},{},{}])).to eq({}) - end +describe 'merge' 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({}, 'two').and_raise_error(Puppet::ParseError, /unexpected argument type String/) } + it { is_expected.to run.with_params({}, 1).and_raise_error(Puppet::ParseError, /unexpected argument type Fixnum/) } + it { + pending 'should not special case this' + is_expected.to run.with_params({}).and_return({}) + } + it { is_expected.to run.with_params({}, {}).and_return({}) } + it { is_expected.to run.with_params({}, {}, {}).and_return({}) } + describe 'should accept empty strings as puppet undef' do + it { is_expected.to run.with_params({}, '').and_return({}) } end + it { is_expected.to run.with_params({ 'key' => 'value' }, {}).and_return({ 'key' => 'value' }) } + it { is_expected.to run.with_params({}, { 'key' => 'value' }).and_return({ 'key' => 'value' }) } + it { is_expected.to run.with_params({ 'key' => 'value1' }, { 'key' => 'value2' }).and_return({ 'key' => 'value2' }) } + it { + is_expected.to run \ + .with_params({ 'key1' => 'value1' }, { 'key2' => 'value2' }, { 'key3' => 'value3' }) \ + .and_return({ 'key1' => 'value1', 'key2' => 'value2', 'key3' => 'value3' }) + } end diff --git a/spec/functions/min_spec.rb b/spec/functions/min_spec.rb index 35a0890..c840a72 100755 --- a/spec/functions/min_spec.rb +++ b/spec/functions/min_spec.rb @@ -1,27 +1,21 @@ -#! /usr/bin/env ruby -S rspec - require 'spec_helper' -describe "the min function" do - let(:scope) { PuppetlabsSpec::PuppetInternals.scope } - - it "should exist" do - expect(Puppet::Parser::Functions.function("min")).to eq("function_min") - end - - it "should raise a ParseError if there is less than 1 arguments" do - expect { scope.function_min([]) }.to( raise_error(Puppet::ParseError)) - end - - it "should be able to compare strings" do - expect(scope.function_min(["albatross","dog","horse"])).to(eq("albatross")) - end - - it "should be able to compare numbers" do - expect(scope.function_min([6,8,4])).to(eq(4)) - end +describe 'min' 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(1).and_return(1) } + it { is_expected.to run.with_params(1, 2).and_return(1) } + it { is_expected.to run.with_params(1, 2, 3).and_return(1) } + it { is_expected.to run.with_params(3, 2, 1).and_return(1) } + it { is_expected.to run.with_params('one').and_return('one') } + it { is_expected.to run.with_params('one', 'two').and_return('one') } + it { is_expected.to run.with_params('one', 'two', 'three').and_return('one') } + it { is_expected.to run.with_params('three', 'two', 'one').and_return('one') } - it "should be able to compare a number with a stringified number" do - expect(scope.function_min([1,"2"])).to(eq(1)) + describe 'implementation artifacts' do + it { is_expected.to run.with_params(1, 'one').and_return(1) } + it { is_expected.to run.with_params('1', 'one').and_return('1') } + it { is_expected.to run.with_params('1.3e1', '1.4e0').and_return('1.3e1') } + it { is_expected.to run.with_params(1.3e1, 1.4e0).and_return(1.4e0) } end end diff --git a/spec/functions/num2bool_spec.rb b/spec/functions/num2bool_spec.rb index d0ba935..494afff 100755 --- a/spec/functions/num2bool_spec.rb +++ b/spec/functions/num2bool_spec.rb @@ -1,67 +1,22 @@ -#! /usr/bin/env ruby -S rspec require 'spec_helper' -describe "the num2bool function" do - let(:scope) { PuppetlabsSpec::PuppetInternals.scope } - - it "should exist" do - expect(Puppet::Parser::Functions.function("num2bool")).to eq("function_num2bool") - end - - it "should raise a ParseError if there are no arguments" do - expect { scope.function_num2bool([]) }.to( raise_error(Puppet::ParseError)) - end - - it "should raise a ParseError if there are more than 1 arguments" do - expect { scope.function_num2bool(["foo","bar"]) }.to( raise_error(Puppet::ParseError)) - end - - it "should raise a ParseError if passed something non-numeric" do - expect { scope.function_num2bool(["xyzzy"]) }.to( raise_error(Puppet::ParseError)) - end - - it "should return true if passed string 1" do - result = scope.function_num2bool(["1"]) - expect(result).to(be_truthy) - end - - it "should return true if passed string 1.5" do - result = scope.function_num2bool(["1.5"]) - expect(result).to(be_truthy) - end - - it "should return true if passed number 1" do - result = scope.function_num2bool([1]) - expect(result).to(be_truthy) - end - - it "should return false if passed string 0" do - result = scope.function_num2bool(["0"]) - expect(result).to(be_falsey) - end - - it "should return false if passed number 0" do - result = scope.function_num2bool([0]) - expect(result).to(be_falsey) - end - - it "should return false if passed string -1" do - result = scope.function_num2bool(["-1"]) - expect(result).to(be_falsey) - end - - it "should return false if passed string -1.5" do - result = scope.function_num2bool(["-1.5"]) - expect(result).to(be_falsey) - end - - it "should return false if passed number -1" do - result = scope.function_num2bool([-1]) - expect(result).to(be_falsey) - end - - it "should return false if passed float -1.5" do - result = scope.function_num2bool([-1.5]) - expect(result).to(be_falsey) - end +describe 'num2bool' 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(1, 2).and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } + it { is_expected.to run.with_params('abc').and_raise_error(Puppet::ParseError, /does not look like a number/) } + it { is_expected.to run.with_params(1).and_return(true) } + it { is_expected.to run.with_params('1').and_return(true) } + it { is_expected.to run.with_params(1.5).and_return(true) } + it { is_expected.to run.with_params('1.5').and_return(true) } + it { is_expected.to run.with_params(-1).and_return(false) } + it { is_expected.to run.with_params('-1').and_return(false) } + it { is_expected.to run.with_params(-1.5).and_return(false) } + it { is_expected.to run.with_params('-1.5').and_return(false) } + it { is_expected.to run.with_params(0).and_return(false) } + it { is_expected.to run.with_params('0').and_return(false) } + it { is_expected.to run.with_params([]).and_return(false) } + it { is_expected.to run.with_params('[]').and_raise_error(Puppet::ParseError, /does not look like a number/) } + it { is_expected.to run.with_params({}).and_return(false) } + it { is_expected.to run.with_params('{}').and_raise_error(Puppet::ParseError, /does not look like a number/) } end diff --git a/spec/functions/parsejson_spec.rb b/spec/functions/parsejson_spec.rb index 1dd41b9..436566e 100755 --- a/spec/functions/parsejson_spec.rb +++ b/spec/functions/parsejson_spec.rb @@ -1,22 +1,9 @@ -#! /usr/bin/env ruby -S rspec require 'spec_helper' -describe "the parsejson function" do - let(:scope) { PuppetlabsSpec::PuppetInternals.scope } - - it "should exist" do - expect(Puppet::Parser::Functions.function("parsejson")).to eq("function_parsejson") - end - - it "should raise a ParseError if there is less than 1 arguments" do - expect { scope.function_parsejson([]) }.to( raise_error(Puppet::ParseError)) - end - - it "should convert JSON to a data structure" do - json = <<-EOS -["aaa","bbb","ccc"] -EOS - result = scope.function_parsejson([json]) - expect(result).to(eq(['aaa','bbb','ccc'])) - end +describe 'parsejson' 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('["one"').and_raise_error(PSON::ParserError) } + it { is_expected.to run.with_params('["one", "two", "three"]').and_return(['one', 'two', 'three']) } end diff --git a/spec/functions/parseyaml_spec.rb b/spec/functions/parseyaml_spec.rb index e5f145b..fb635f8 100755 --- a/spec/functions/parseyaml_spec.rb +++ b/spec/functions/parseyaml_spec.rb @@ -1,24 +1,14 @@ -#! /usr/bin/env ruby -S rspec require 'spec_helper' -describe "the parseyaml function" do - let(:scope) { PuppetlabsSpec::PuppetInternals.scope } - - it "should exist" do - expect(Puppet::Parser::Functions.function("parseyaml")).to eq("function_parseyaml") - end - - it "should raise a ParseError if there is less than 1 arguments" do - expect { scope.function_parseyaml([]) }.to( raise_error(Puppet::ParseError)) +describe 'parseyaml' 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('["one", "two", "three"]').and_return(['one', 'two', 'three']) } + context 'when running on modern rubies', :unless => RUBY_VERSION == '1.8.7' do + it { is_expected.to run.with_params('["one"').and_raise_error(Psych::SyntaxError) } end - - it "should convert YAML to a data structure" do - yaml = <<-EOS -- aaa -- bbb -- ccc -EOS - result = scope.function_parseyaml([yaml]) - expect(result).to(eq(['aaa','bbb','ccc'])) + context 'when running on ruby 1.8.7, which does not have Psych', :if => RUBY_VERSION == '1.8.7' do + it { is_expected.to run.with_params('["one"').and_raise_error(ArgumentError) } end end diff --git a/spec/functions/pick_default_spec.rb b/spec/functions/pick_default_spec.rb index db10cc3..e2fc64a 100755 --- a/spec/functions/pick_default_spec.rb +++ b/spec/functions/pick_default_spec.rb @@ -1,58 +1,24 @@ -#!/usr/bin/env ruby -S rspec require 'spec_helper' -describe "the pick_default function" do - let(:scope) { PuppetlabsSpec::PuppetInternals.scope } - - it "should exist" do - expect(Puppet::Parser::Functions.function("pick_default")).to eq("function_pick_default") - end - - it 'should return the correct value' do - expect(scope.function_pick_default(['first', 'second'])).to eq('first') - end - - it 'should return the correct value if the first value is empty' do - expect(scope.function_pick_default(['', 'second'])).to eq('second') - end - - it 'should skip empty string values' do - expect(scope.function_pick_default(['', 'first'])).to eq('first') - end - - it 'should skip :undef values' do - expect(scope.function_pick_default([:undef, 'first'])).to eq('first') - end - - it 'should skip :undefined values' do - expect(scope.function_pick_default([:undefined, 'first'])).to eq('first') - end - - it 'should return the empty string if it is the last possibility' do - expect(scope.function_pick_default([:undef, :undefined, ''])).to eq('') - end - - it 'should return :undef if it is the last possibility' do - expect(scope.function_pick_default(['', :undefined, :undef])).to eq(:undef) - end - - it 'should return :undefined if it is the last possibility' do - expect(scope.function_pick_default([:undef, '', :undefined])).to eq(:undefined) - end - - it 'should return the empty string if it is the only possibility' do - expect(scope.function_pick_default([''])).to eq('') - end - - it 'should return :undef if it is the only possibility' do - expect(scope.function_pick_default([:undef])).to eq(:undef) - end - - it 'should return :undefined if it is the only possibility' do - expect(scope.function_pick_default([:undefined])).to eq(:undefined) - end - - it 'should error if no values are passed' do - expect { scope.function_pick_default([]) }.to raise_error(Puppet::Error, /Must receive at least one argument./) +describe 'pick_default' do + it { is_expected.not_to eq(nil) } + it { is_expected.to run.with_params().and_raise_error(Puppet::Error, /Must receive at least one argument/) } + + it { is_expected.to run.with_params('one', 'two').and_return('one') } + it { is_expected.to run.with_params('', 'two').and_return('two') } + it { is_expected.to run.with_params(:undef, 'two').and_return('two') } + it { is_expected.to run.with_params(:undefined, 'two').and_return('two') } + it { is_expected.to run.with_params(nil, 'two').and_return('two') } + + [ '', :undef, :undefined, nil, {}, [], 1, 'default' ].each do |value| + describe "when providing #{value.inspect} as default" do + it { is_expected.to run.with_params('one', value).and_return('one') } + it { is_expected.to run.with_params([], value).and_return([]) } + it { is_expected.to run.with_params({}, value).and_return({}) } + it { is_expected.to run.with_params(value, value).and_return(value) } + it { is_expected.to run.with_params(:undef, value).and_return(value) } + it { is_expected.to run.with_params(:undefined, value).and_return(value) } + it { is_expected.to run.with_params(nil, value).and_return(value) } + end end end diff --git a/spec/functions/pick_spec.rb b/spec/functions/pick_spec.rb index 8be8f58..2c7caa8 100755 --- a/spec/functions/pick_spec.rb +++ b/spec/functions/pick_spec.rb @@ -1,34 +1,12 @@ -#!/usr/bin/env ruby -S rspec require 'spec_helper' -describe "the pick function" do - let(:scope) { PuppetlabsSpec::PuppetInternals.scope } - - it "should exist" do - expect(Puppet::Parser::Functions.function("pick")).to eq("function_pick") - end - - it 'should return the correct value' do - expect(scope.function_pick(['first', 'second'])).to eq('first') - end - - it 'should return the correct value if the first value is empty' do - expect(scope.function_pick(['', 'second'])).to eq('second') - end - - it 'should remove empty string values' do - expect(scope.function_pick(['', 'first'])).to eq('first') - end - - it 'should remove :undef values' do - expect(scope.function_pick([:undef, 'first'])).to eq('first') - end - - it 'should remove :undefined values' do - expect(scope.function_pick([:undefined, 'first'])).to eq('first') - end - - it 'should error if no values are passed' do - expect { scope.function_pick([]) }.to( raise_error(Puppet::ParseError, "pick(): must receive at least one non empty value")) - end +describe 'pick' do + it { is_expected.not_to eq(nil) } + it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError, /must receive at least one non empty value/) } + it { is_expected.to run.with_params('', nil, :undef, :undefined).and_raise_error(Puppet::ParseError, /must receive at least one non empty value/) } + it { is_expected.to run.with_params('one', 'two').and_return('one') } + it { is_expected.to run.with_params('', 'two').and_return('two') } + it { is_expected.to run.with_params(:undef, 'two').and_return('two') } + it { is_expected.to run.with_params(:undefined, 'two').and_return('two') } + it { is_expected.to run.with_params(nil, 'two').and_return('two') } end diff --git a/spec/functions/prefix_spec.rb b/spec/functions/prefix_spec.rb index aec8a7d..3761022 100755 --- a/spec/functions/prefix_spec.rb +++ b/spec/functions/prefix_spec.rb @@ -1,33 +1,28 @@ -#! /usr/bin/env ruby -S rspec require 'spec_helper' -describe "the prefix function" do - let(:scope) { PuppetlabsSpec::PuppetInternals.scope } - - it "raises a ParseError if there is less than 1 arguments" do - expect { scope.function_prefix([]) }.to raise_error(Puppet::ParseError, /number of arguments/) - end - - it "raises an error if the first argument is not an array" do - expect { - scope.function_prefix([Object.new]) - }.to raise_error(Puppet::ParseError, /expected first argument to be an Array/) - end - - - it "raises an error if the second argument is not a string" do - expect { - scope.function_prefix([['first', 'second'], 42]) - }.to raise_error(Puppet::ParseError, /expected second argument to be a String/) - end - - it "returns a prefixed array" do - result = scope.function_prefix([['a','b','c'], 'p']) - expect(result).to(eq(['pa','pb','pc'])) - end - - it "returns a prefixed hash" do - result = scope.function_prefix([{'a' => 'b','b' => 'c','c' => 'd'}, 'p']) - expect(result).to(eq({'pa'=>'b','pb'=>'c','pc'=>'d'})) - end +describe 'prefix' 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 { + pending("Current implementation ignores parameters after the second.") + is_expected.to run.with_params([], 'a', '').and_raise_error(Puppet::ParseError, /wrong number of arguments/i) + } + it { is_expected.to run.with_params('', '').and_raise_error(Puppet::ParseError, /expected first argument to be an Array or a Hash/) } + it { is_expected.to run.with_params([], 2).and_raise_error(Puppet::ParseError, /expected second argument to be a String/) } + it { is_expected.to run.with_params([]).and_return([]) } + it { is_expected.to run.with_params(['one', 2]).and_return(['one', '2']) } + it { is_expected.to run.with_params([], '').and_return([]) } + it { is_expected.to run.with_params([''], '').and_return(['']) } + it { is_expected.to run.with_params(['one'], 'pre').and_return(['preone']) } + it { is_expected.to run.with_params(['one', 'two', 'three'], 'pre').and_return(['preone', 'pretwo', 'prethree']) } + it { is_expected.to run.with_params({}).and_return({}) } + it { is_expected.to run.with_params({ 'key1' => 'value1', 2 => 3}).and_return({ 'key1' => 'value1', '2' => 3 }) } + it { is_expected.to run.with_params({}, '').and_return({}) } + it { is_expected.to run.with_params({ 'key' => 'value' }, '').and_return({ 'key' => 'value' }) } + it { is_expected.to run.with_params({ 'key' => 'value' }, 'pre').and_return({ 'prekey' => 'value' }) } + it { + is_expected.to run \ + .with_params({ 'key1' => 'value1', 'key2' => 'value2', 'key3' => 'value3' }, 'pre') \ + .and_return({ 'prekey1' => 'value1', 'prekey2' => 'value2', 'prekey3' => 'value3' }) + } end diff --git a/spec/functions/private_spec.rb b/spec/functions/private_spec.rb index c90282e..a13be64 100644 --- a/spec/functions/private_spec.rb +++ b/spec/functions/private_spec.rb @@ -1,17 +1,13 @@ -#! /usr/bin/env ruby -S rspec require 'spec_helper' -describe Puppet::Parser::Functions.function(:private) do - let(:scope) { PuppetlabsSpec::PuppetInternals.scope } - - subject do - function_name = Puppet::Parser::Functions.function(:private) - scope.method(function_name) - end - +describe 'private' do it 'should issue a warning' do scope.expects(:warning).with("private() DEPRECATED: This function will cease to function on Puppet 4; please use assert_private() before upgrading to puppet 4 for backwards-compatibility, or migrate to the new parser's typing system.") - subject.call [] + begin + subject.call [] + rescue + # ignore this + end end context "when called from inside module" do diff --git a/spec/functions/pw_hash_spec.rb b/spec/functions/pw_hash_spec.rb index 3378090..df5348c 100644 --- a/spec/functions/pw_hash_spec.rb +++ b/spec/functions/pw_hash_spec.rb @@ -1,96 +1,69 @@ -#! /usr/bin/env ruby -S rspec require 'spec_helper' -describe "the pw_hash function" do +describe 'pw_hash' do - before :all do - @enhanced_salts_supported = RUBY_PLATFORM == 'java' - end - - let(:scope) { PuppetlabsSpec::PuppetInternals.scope } - - it "should exist" do - expect(Puppet::Parser::Functions.function("pw_hash")).to eq("function_pw_hash") - end + it { is_expected.not_to eq(nil) } - it "should raise an ArgumentError if there are less than 3 arguments" do - expect { scope.function_pw_hash([]) }.to( raise_error(ArgumentError, /[Ww]rong number of arguments/) ) - expect { scope.function_pw_hash(['password']) }.to( raise_error(ArgumentError, /[Ww]rong number of arguments/) ) - expect { scope.function_pw_hash(['password', 'sha-512']) }.to( raise_error(ArgumentError, /[Ww]rong number of arguments/) ) + context 'when there are less than 3 arguments' do + it { is_expected.to run.with_params().and_raise_error(ArgumentError, /wrong number of arguments/i) } + it { is_expected.to run.with_params('password').and_raise_error(ArgumentError, /wrong number of arguments/i) } + it { is_expected.to run.with_params('password', 'sha-256').and_raise_error(ArgumentError, /wrong number of arguments/i) } end - it "should raise an ArgumentError if there are more than 3 arguments" do - expect { scope.function_pw_hash(['password', 'sha-512', 'salt', 5]) }.to( raise_error(ArgumentError, /[Ww]rong number of arguments/) ) + context 'when there are more than 3 arguments' do + it { is_expected.to run.with_params('password', 'sha-256', 'salt', 'extra').and_raise_error(ArgumentError, /wrong number of arguments/i) } + it { is_expected.to run.with_params('password', 'sha-256', 'salt', 'extra', 'extra').and_raise_error(ArgumentError, /wrong number of arguments/i) } end - it "should raise an ArgumentError if the first argument is not a string" do - expect { scope.function_pw_hash([['password'], 'sha-512', 'salt']) }.to( raise_error(ArgumentError, /first argument must be a string/) ) - # in Puppet 3, numbers are passed as strings, so we can't test that + context 'when the first argument is not a string' do + it { is_expected.to run.with_params([], 'sha-256', 'salt').and_raise_error(ArgumentError, /first argument must be a string/) } + it { is_expected.to run.with_params({}, 'sha-256', 'salt').and_raise_error(ArgumentError, /first argument must be a string/) } + it { is_expected.to run.with_params(1, 'sha-256', 'salt').and_raise_error(ArgumentError, /first argument must be a string/) } + it { is_expected.to run.with_params(true, 'sha-256', 'salt').and_raise_error(ArgumentError, /first argument must be a string/) } end - it "should return nil if the first argument is empty" do - expect(scope.function_pw_hash(['', 'sha-512', 'salt'])).to eq(nil) + context 'when the first argument is undefined' do + it { is_expected.to run.with_params('', 'sha-256', 'salt').and_return(nil) } + it { is_expected.to run.with_params(nil, 'sha-256', 'salt').and_return(nil) } end - it "should return nil if the first argument is undef" do - expect(scope.function_pw_hash([nil, 'sha-512', 'salt'])).to eq(nil) + context 'when the second argument is not a string' do + it { is_expected.to run.with_params('password', [], 'salt').and_raise_error(ArgumentError, /second argument must be a string/) } + it { is_expected.to run.with_params('password', {}, 'salt').and_raise_error(ArgumentError, /second argument must be a string/) } + it { is_expected.to run.with_params('password', 1, 'salt').and_raise_error(ArgumentError, /second argument must be a string/) } + it { is_expected.to run.with_params('password', true, 'salt').and_raise_error(ArgumentError, /second argument must be a string/) } end - it "should raise an ArgumentError if the second argument is an invalid hash type" do - expect { scope.function_pw_hash(['', 'invalid', 'salt']) }.to( raise_error(ArgumentError, /not a valid hash type/) ) + context 'when the second argument is not one of the supported hashing algorithms' do + it { is_expected.to run.with_params('password', 'no such algo', 'salt').and_raise_error(ArgumentError, /is not a valid hash type/) } end - it "should raise an ArgumentError if the second argument is not a string" do - expect { scope.function_pw_hash(['', [], 'salt']) }.to( raise_error(ArgumentError, /second argument must be a string/) ) + context 'when the third argument is not a string' do + it { is_expected.to run.with_params('password', 'sha-256', []).and_raise_error(ArgumentError, /third argument must be a string/) } + it { is_expected.to run.with_params('password', 'sha-256', {}).and_raise_error(ArgumentError, /third argument must be a string/) } + it { is_expected.to run.with_params('password', 'sha-256', 1).and_raise_error(ArgumentError, /third argument must be a string/) } + it { is_expected.to run.with_params('password', 'sha-256', true).and_raise_error(ArgumentError, /third argument must be a string/) } end - it "should raise an ArgumentError if the third argument is not a string" do - expect { scope.function_pw_hash(['password', 'sha-512', ['salt']]) }.to( raise_error(ArgumentError, /third argument must be a string/) ) - # in Puppet 3, numbers are passed as strings, so we can't test that + context 'when the third argument is empty' do + it { is_expected.to run.with_params('password', 'sha-512', '').and_raise_error(ArgumentError, /third argument must not be empty/) } end - it "should raise an ArgumentError if the third argument is empty" do - expect { scope.function_pw_hash(['password', 'sha-512', '']) }.to( raise_error(ArgumentError, /third argument must not be empty/) ) + context 'when the third argument contains invalid characters' do + it { is_expected.to run.with_params('password', 'sha-512', 'one%').and_raise_error(ArgumentError, /characters in salt must be in the set/) } end - it "should raise an ArgumentError if the third argument has invalid characters" do - expect { scope.function_pw_hash(['password', 'sha-512', '%']) }.to( raise_error(ArgumentError, /characters in salt must be in the set/) ) - end + context 'when running on a platform with a weak String#crypt implementation' do + before(:each) { allow_any_instance_of(String).to receive(:crypt).with('$1$1').and_return('a bad hash') } - it "should fail on platforms with weak implementations of String#crypt" do - String.any_instance.expects(:crypt).with('$1$1').returns('$1SoNol0Ye6Xk') - expect { scope.function_pw_hash(['password', 'sha-512', 'salt']) }.to( raise_error(Puppet::ParseError, /system does not support enhanced salts/) ) + it { is_expected.to run.with_params('password', 'sha-512', 'salt').and_raise_error(Puppet::ParseError, /system does not support enhanced salts/) } end - if @enhanced_salts_supported + if RUBY_PLATFORM == 'java' or 'test'.crypt('$1$1') == '$1$1$Bp8CU9Oujr9SSEw53WV6G.' describe "on systems with enhanced salts support" do - it "should return a hashed password" do - result = scope.function_pw_hash(['password', 'sha-512', 'salt']) - expect(result).to eql('$6$salt$IxDD3jeSOb5eB1CX5LBsqZFVkJdido3OUILO5Ifz5iwMuTS4XMS130MTSuDDl3aCI6WouIL9AjRbLCelDCy.g.') - end - - it "should use the specified salt" do - result = scope.function_pw_hash(['password', 'sha-512', 'salt']) - expect(result).to match('salt') - end - - it "should use the specified hash type" do - resultmd5 = scope.function_pw_hash(['password', 'md5', 'salt']) - resultsha256 = scope.function_pw_hash(['password', 'sha-256', 'salt']) - resultsha512 = scope.function_pw_hash(['password', 'sha-512', 'salt']) - - expect(resultmd5).to eql('$1$salt$qJH7.N4xYta3aEG/dfqo/0') - expect(resultsha256).to eql('$5$salt$Gcm6FsVtF/Qa77ZKD.iwsJlCVPY0XSMgLJL0Hnww/c1') - expect(resultsha512).to eql('$6$salt$IxDD3jeSOb5eB1CX5LBsqZFVkJdido3OUILO5Ifz5iwMuTS4XMS130MTSuDDl3aCI6WouIL9AjRbLCelDCy.g.') - end - - it "should generate a valid hash" do - password_hash = scope.function_pw_hash(['password', 'sha-512', 'salt']) - - hash_parts = password_hash.match(%r{\A\$(.*)\$([a-zA-Z0-9./]+)\$([a-zA-Z0-9./]+)\z}) - - expect(hash_parts).not_to eql(nil) - end + it { is_expected.to run.with_params('password', 'md5', 'salt').and_return('$1$salt$qJH7.N4xYta3aEG/dfqo/0') } + it { is_expected.to run.with_params('password', 'sha-256', 'salt').and_return('$5$salt$Gcm6FsVtF/Qa77ZKD.iwsJlCVPY0XSMgLJL0Hnww/c1') } + it { is_expected.to run.with_params('password', 'sha-512', 'salt').and_return('$6$salt$IxDD3jeSOb5eB1CX5LBsqZFVkJdido3OUILO5Ifz5iwMuTS4XMS130MTSuDDl3aCI6WouIL9AjRbLCelDCy.g.') } end end end diff --git a/spec/functions/range_spec.rb b/spec/functions/range_spec.rb index f18b89e..492cad4 100755 --- a/spec/functions/range_spec.rb +++ b/spec/functions/range_spec.rb @@ -1,93 +1,118 @@ -#! /usr/bin/env ruby -S rspec require 'spec_helper' -describe "the range function" do - let(:scope) { PuppetlabsSpec::PuppetInternals.scope } +describe 'range' do + it { is_expected.not_to eq(nil) } - it "exists" do - expect(Puppet::Parser::Functions.function("range")).to eq("function_range") + describe 'signature validation in puppet3', :unless => RSpec.configuration.puppet_future do + it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } + it { + pending("Current implementation ignores parameters after the third.") + is_expected.to run.with_params(1, 2, 3, 4).and_raise_error(Puppet::ParseError, /wrong number of arguments/i) + } + it { is_expected.to run.with_params('1..2..3').and_raise_error(Puppet::ParseError, /Unable to compute range/i) } + it { is_expected.to run.with_params('').and_raise_error(Puppet::ParseError, /Unknown range format/i) } end - it "raises a ParseError if there is less than 1 arguments" do - expect { scope.function_range([]) }.to raise_error Puppet::ParseError, /Wrong number of arguments.*0 for 1/ + describe 'signature validation in puppet4', :if => RSpec.configuration.puppet_future do + it { pending "the puppet 4 implementation"; is_expected.to run.with_params().and_raise_error(ArgumentError) } + it { pending "the puppet 4 implementation"; is_expected.to run.with_params('').and_raise_error(ArgumentError) } + it { pending "the puppet 4 implementation"; is_expected.to run.with_params({}).and_raise_error(ArgumentError) } + it { pending "the puppet 4 implementation"; is_expected.to run.with_params([]).and_raise_error(ArgumentError) } + it { pending "the puppet 4 implementation"; is_expected.to run.with_params(true).and_raise_error(ArgumentError) } + it { pending "the puppet 4 implementation"; is_expected.to run.with_params(true).and_raise_error(ArgumentError) } + it { is_expected.to run.with_params(1, 2, 'foo').and_raise_error(ArgumentError) } + it { pending "the puppet 4 implementation"; is_expected.to run.with_params(1, 2, []).and_raise_error(ArgumentError) } + it { pending "the puppet 4 implementation"; is_expected.to run.with_params(1, 2, {}).and_raise_error(ArgumentError) } + it { pending "the puppet 4 implementation"; is_expected.to run.with_params(1, 2, true).and_raise_error(ArgumentError) } + it { pending "the puppet 4 implementation"; is_expected.to run.with_params(1, 2, 3, 4).and_raise_error(ArgumentError) } + it { pending "the puppet 4 implementation"; is_expected.to run.with_params('1..2..3').and_raise_error(ArgumentError) } end - describe 'with a letter range' do - it "returns a letter range" do - result = scope.function_range(["a","d"]) - expect(result).to eq ['a','b','c','d'] - end - - it "returns a letter range given a step of 1" do - result = scope.function_range(["a","d","1"]) - expect(result).to eq ['a','b','c','d'] - end - - it "returns a stepped letter range" do - result = scope.function_range(["a","d","2"]) - expect(result).to eq ['a','c'] - end - - it "returns a stepped letter range given a negative step" do - result = scope.function_range(["a","d","-2"]) - expect(result).to eq ['a','c'] - end + context 'with characters as bounds' do + it { is_expected.to run.with_params('d', 'a').and_return([]) } + it { is_expected.to run.with_params('a', 'a').and_return(['a']) } + it { is_expected.to run.with_params('a', 'b').and_return(['a', 'b']) } + it { is_expected.to run.with_params('a', 'd').and_return(['a', 'b', 'c', 'd']) } + it { is_expected.to run.with_params('a', 'd', 1).and_return(['a', 'b', 'c', 'd']) } + it { is_expected.to run.with_params('a', 'd', '1').and_return(['a', 'b', 'c', 'd']) } + it { is_expected.to run.with_params('a', 'd', 2).and_return(['a', 'c']) } + it { is_expected.to run.with_params('a', 'd', -2).and_return(['a', 'c']) } + it { is_expected.to run.with_params('a', 'd', 3).and_return(['a', 'd']) } + it { is_expected.to run.with_params('a', 'd', 4).and_return(['a']) } end - describe 'with a number range' do - it "returns a number range" do - result = scope.function_range(["1","4"]) - expect(result).to eq [1,2,3,4] - end + context 'with strings as bounds' do + it { is_expected.to run.with_params('onea', 'oned').and_return(['onea', 'oneb', 'onec', 'oned']) } + it { is_expected.to run.with_params('two', 'one').and_return([]) } + it { is_expected.to run.with_params('true', 'false').and_return([]) } + it { is_expected.to run.with_params('false', 'true').and_return(['false']) } + end - it "returns a number range given a step of 1" do - result = scope.function_range(["1","4","1"]) - expect(result).to eq [1,2,3,4] - end + context 'with integers as bounds' do + it { is_expected.to run.with_params(4, 1).and_return([]) } + it { is_expected.to run.with_params(1, 1).and_return([1]) } + it { is_expected.to run.with_params(1, 2).and_return([1, 2]) } + it { is_expected.to run.with_params(1, 4).and_return([1, 2, 3, 4]) } + it { is_expected.to run.with_params(1, 4, 1).and_return([1, 2, 3, 4]) } + it { is_expected.to run.with_params(1, 4, '1').and_return([1, 2, 3, 4]) } + it { is_expected.to run.with_params(1, 4, 2).and_return([1, 3]) } + it { is_expected.to run.with_params(1, 4, -2).and_return([1, 3]) } + it { is_expected.to run.with_params(1, 4, 3).and_return([1, 4]) } + it { is_expected.to run.with_params(1, 4, 4).and_return([1]) } + end - it "returns a stepped number range" do - result = scope.function_range(["1","4","2"]) - expect(result).to eq [1,3] - end + context 'with integers as strings as bounds' do + it { is_expected.to run.with_params('4', '1').and_return([]) } + it { is_expected.to run.with_params('1', '1').and_return([1]) } + it { is_expected.to run.with_params('1', '2').and_return([1, 2]) } + it { is_expected.to run.with_params('1', '4').and_return([1, 2, 3, 4]) } + it { is_expected.to run.with_params('1', '4', 1).and_return([1, 2, 3, 4]) } + it { is_expected.to run.with_params('1', '4', '1').and_return([1, 2, 3, 4]) } + it { is_expected.to run.with_params('1', '4', 2).and_return([1, 3]) } + it { is_expected.to run.with_params('1', '4', -2).and_return([1, 3]) } + it { is_expected.to run.with_params('1', '4', 3).and_return([1, 4]) } + it { is_expected.to run.with_params('1', '4', 4).and_return([1]) } + end - it "returns a stepped number range given a negative step" do - result = scope.function_range(["1","4","-2"]) - expect(result).to eq [1,3] - end + context 'with prefixed numbers as strings as bounds' do + it { is_expected.to run.with_params('host01', 'host04').and_return(['host01', 'host02', 'host03', 'host04']) } + it { is_expected.to run.with_params('01', '04').and_return([1, 2, 3, 4]) } end - describe 'with a numeric-like string range' do - it "works with padded hostname like strings" do - expected = ("host01".."host10").to_a - expect(scope.function_range(["host01","host10"])).to eq expected - end + context 'with dash-range syntax' do + it { is_expected.to run.with_params('4-1').and_return([]) } + it { is_expected.to run.with_params('1-1').and_return([1]) } + it { is_expected.to run.with_params('1-2').and_return([1, 2]) } + it { is_expected.to run.with_params('1-4').and_return([1, 2, 3, 4]) } + end - it "coerces zero padded digits to integers" do - expected = (0..10).to_a - expect(scope.function_range(["00", "10"])).to eq expected - end + context 'with two-dot-range syntax' do + it { is_expected.to run.with_params('4..1').and_return([]) } + it { is_expected.to run.with_params('1..1').and_return([1]) } + it { is_expected.to run.with_params('1..2').and_return([1, 2]) } + it { is_expected.to run.with_params('1..4').and_return([1, 2, 3, 4]) } end - describe 'with a ruby-like range' do - it "returns a number range" do - result = scope.function_range(["1..4"]) - expect(result).to eq [1,2,3,4] - end + context 'with three-dot-range syntax' do + it { is_expected.to run.with_params('4...1').and_return([]) } + it { is_expected.to run.with_params('1...1').and_return([]) } + it { is_expected.to run.with_params('1...2').and_return([1]) } + it { is_expected.to run.with_params('1...3').and_return([1, 2]) } + it { is_expected.to run.with_params('1...5').and_return([1, 2, 3, 4]) } end - describe 'with a numeric range' do - it "returns a range of numbers" do - expected = (1..10).to_a - expect(scope.function_range([1,10])).to eq expected - end - it "returns a range of numbers with step parameter" do - expected = (1..10).step(2).to_a - expect(scope.function_range([1,10,2])).to eq expected - end - it "works with mixed numeric like strings and numeric arguments" do - expected = (1..10).to_a - expect(scope.function_range(['1',10])).to eq expected - expect(scope.function_range([1,'10'])).to eq expected - end + describe 'when passing mixed arguments as bounds' do + it { + pending('these bounds should not be allowed as ruby will OOM hard. e.g. `(\'host0\'..\'hosta\').to_a` has 3239930 elements on ruby 1.9, adding more \'0\'s and \'a\'s increases that exponentially') + is_expected.to run.with_params('0', 'a').and_raise_error(Puppet::ParseError, /cannot interpolate between numeric and non-numeric bounds/) + } + it { + pending('these bounds should not be allowed as ruby will OOM hard. e.g. `(\'host0\'..\'hosta\').to_a` has 3239930 elements on ruby 1.9, adding more \'0\'s and \'a\'s increases that exponentially') + is_expected.to run.with_params(0, 'a').and_raise_error(Puppet::ParseError, /cannot interpolate between numeric and non-numeric bounds/) + } + it { + pending('these bounds should not be allowed as ruby will OOM hard. e.g. `(\'host0\'..\'hosta\').to_a` has 3239930 elements on ruby 1.9, adding more \'0\'s and \'a\'s increases that exponentially') + is_expected.to run.with_params('h0', 'ha').and_raise_error(Puppet::ParseError, /cannot interpolate between numeric and non-numeric bounds/) + } end end diff --git a/spec/functions/reject_spec.rb b/spec/functions/reject_spec.rb index 88a992e..4863050 100755 --- a/spec/functions/reject_spec.rb +++ b/spec/functions/reject_spec.rb @@ -1,20 +1,19 @@ -#!/usr/bin/env ruby - require 'spec_helper' -describe "the reject function" do - let(:scope) { PuppetlabsSpec::PuppetInternals.scope } - - it "should exist" do - expect(Puppet::Parser::Functions.function("reject")).to eq("function_reject") - end - - it "should raise a ParseError if there is less than 1 arguments" do - expect { scope.function_reject([]) }.to( raise_error(Puppet::ParseError)) - end +describe 'reject' 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([], 'pattern', 'extra').and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } - it "should reject contents from an array" do - result = scope.function_reject([["1111", "aaabbb","bbbccc","dddeee"], "bbb"]) - expect(result).to(eq(["1111", "dddeee"])) - end + it { + pending("reject does not actually check this, and raises NoMethodError instead") + is_expected.to run.with_params('one', 'two').and_raise_error(Puppet::ParseError, /first argument not an array/) + } + it { + pending("reject does not actually check this, and raises NoMethodError instead") + is_expected.to run.with_params(1, 'two').and_raise_error(Puppet::ParseError, /first argument not an array/) + } + it { is_expected.to run.with_params([], 'two').and_return([]) } + it { is_expected.to run.with_params(['one', 'two', 'three'], 'two').and_return(['one', 'three']) } + it { is_expected.to run.with_params(['one', 'two', 'three'], 't(wo|hree)').and_return(['one']) } end diff --git a/spec/functions/reverse_spec.rb b/spec/functions/reverse_spec.rb index 1f04794..e00dee9 100755 --- a/spec/functions/reverse_spec.rb +++ b/spec/functions/reverse_spec.rb @@ -1,28 +1,31 @@ -#! /usr/bin/env ruby -S rspec require 'spec_helper' -describe "the reverse function" do - let(:scope) { PuppetlabsSpec::PuppetInternals.scope } +describe 'reverse' 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 { + pending("Current implementation ignores parameters after the first.") + is_expected.to run.with_params([], 'extra').and_raise_error(Puppet::ParseError, /wrong number of arguments/i) + } + it { is_expected.to run.with_params(1).and_raise_error(Puppet::ParseError, /Requires either array or string to work/) } + it { is_expected.to run.with_params({}).and_raise_error(Puppet::ParseError, /Requires either array or string to work/) } + it { is_expected.to run.with_params(true).and_raise_error(Puppet::ParseError, /Requires either array or string to work/) } + it { is_expected.to run.with_params([]).and_return([]) } + it { is_expected.to run.with_params(['a']).and_return(['a']) } + it { is_expected.to run.with_params(['one']).and_return(['one']) } + it { is_expected.to run.with_params(['one', 'two', 'three']).and_return(['three', 'two', 'one']) } + it { is_expected.to run.with_params(['one', 'two', 'three', 'four']).and_return(['four', 'three', 'two', 'one']) } - it "should exist" do - expect(Puppet::Parser::Functions.function("reverse")).to eq("function_reverse") - end - - it "should raise a ParseError if there is less than 1 arguments" do - expect { scope.function_reverse([]) }.to( raise_error(Puppet::ParseError)) - end + it { is_expected.to run.with_params('').and_return('') } + it { is_expected.to run.with_params('a').and_return('a') } + it { is_expected.to run.with_params('abc').and_return('cba') } + it { is_expected.to run.with_params('abcd').and_return('dcba') } - it "should reverse a string" do - result = scope.function_reverse(["asdfghijkl"]) - expect(result).to(eq('lkjihgfdsa')) - end - - it "should accept objects which extend String" do - class AlsoString < String + context 'when using a class extending String' do + it 'should call its reverse method' do + value = AlsoString.new('asdfghjkl') + value.expects(:reverse).returns('foo') + expect(subject).to run.with_params(value).and_return('foo') end - - value = AlsoString.new('asdfghjkl') - result = scope.function_reverse([value]) - result.should(eq('lkjhgfdsa')) end end diff --git a/spec/functions/rstrip_spec.rb b/spec/functions/rstrip_spec.rb index f6b4838..d2efac8 100755 --- a/spec/functions/rstrip_spec.rb +++ b/spec/functions/rstrip_spec.rb @@ -1,33 +1,34 @@ -#! /usr/bin/env ruby -S rspec require 'spec_helper' -describe "the rstrip function" do - let(:scope) { PuppetlabsSpec::PuppetInternals.scope } - - it "should exist" do - expect(Puppet::Parser::Functions.function("rstrip")).to eq("function_rstrip") - end - - it "should raise a ParseError if there is less than 1 arguments" do - expect { scope.function_rstrip([]) }.to( raise_error(Puppet::ParseError)) - end - - it "should rstrip a string" do - result = scope.function_rstrip(["asdf "]) - expect(result).to(eq('asdf')) - end - - it "should rstrip each element in an array" do - result = scope.function_rstrip([["a ","b ", "c "]]) - expect(result).to(eq(['a','b','c'])) - end - - it "should accept objects which extend String" do - class AlsoString < String - end - - value = AlsoString.new('asdf ') - result = scope.function_rstrip([value]) - result.should(eq('asdf')) - end +describe 'rstrip' 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 { + pending("Current implementation ignores parameters after the first.") + 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, /Requires either array or string to work with/) } + it { is_expected.to run.with_params(1).and_raise_error(Puppet::ParseError, /Requires either array or string to work with/) } + it { is_expected.to run.with_params('').and_return('') } + it { is_expected.to run.with_params(' ').and_return('') } + it { is_expected.to run.with_params(' ').and_return('') } + it { is_expected.to run.with_params("\t").and_return('') } + it { is_expected.to run.with_params("\t ").and_return('') } + it { is_expected.to run.with_params('one').and_return('one') } + it { is_expected.to run.with_params(' one').and_return(' one') } + it { is_expected.to run.with_params(' one').and_return(' one') } + it { is_expected.to run.with_params("\tone").and_return("\tone") } + it { is_expected.to run.with_params("\t one").and_return("\t one") } + it { is_expected.to run.with_params('one ').and_return('one') } + it { is_expected.to run.with_params(' one ').and_return(' one') } + it { is_expected.to run.with_params(' one ').and_return(' one') } + it { is_expected.to run.with_params("\tone ").and_return("\tone") } + it { is_expected.to run.with_params("\t one ").and_return("\t one") } + it { is_expected.to run.with_params("one\t").and_return('one') } + it { is_expected.to run.with_params(" one\t").and_return(' one') } + it { is_expected.to run.with_params(" one\t").and_return(' one') } + it { is_expected.to run.with_params("\tone\t").and_return("\tone") } + it { is_expected.to run.with_params("\t one\t").and_return("\t one") } + it { is_expected.to run.with_params(' o n e ').and_return(' o n e') } + it { is_expected.to run.with_params(AlsoString.new(' one ')).and_return(' one') } end diff --git a/spec/functions/shuffle_spec.rb b/spec/functions/shuffle_spec.rb index a62c1fb..ebc3a73 100755 --- a/spec/functions/shuffle_spec.rb +++ b/spec/functions/shuffle_spec.rb @@ -1,33 +1,33 @@ -#! /usr/bin/env ruby -S rspec require 'spec_helper' -describe "the shuffle function" do - let(:scope) { PuppetlabsSpec::PuppetInternals.scope } +describe 'shuffle' 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 { + pending("Current implementation ignores parameters after the first.") + is_expected.to run.with_params([], 'extra').and_raise_error(Puppet::ParseError, /wrong number of arguments/i) + } + it { is_expected.to run.with_params(1).and_raise_error(Puppet::ParseError, /Requires either array or string to work/) } + it { is_expected.to run.with_params({}).and_raise_error(Puppet::ParseError, /Requires either array or string to work/) } + it { is_expected.to run.with_params(true).and_raise_error(Puppet::ParseError, /Requires either array or string to work/) } - it "should exist" do - expect(Puppet::Parser::Functions.function("shuffle")).to eq("function_shuffle") - end - - it "should raise a ParseError if there is less than 1 arguments" do - expect { scope.function_shuffle([]) }.to( raise_error(Puppet::ParseError)) - end + context 'when running with a specific seed' do + # make tests deterministic + before(:each) { srand(2) } - it "should shuffle a string and the result should be the same size" do - result = scope.function_shuffle(["asdf"]) - expect(result.size).to(eq(4)) - end + it { is_expected.to run.with_params([]).and_return([]) } + it { is_expected.to run.with_params(['a']).and_return(['a']) } + it { is_expected.to run.with_params(['one']).and_return(['one']) } + it { is_expected.to run.with_params(['one', 'two', 'three']).and_return(['two', 'one', 'three']) } + it { is_expected.to run.with_params(['one', 'two', 'three', 'four']).and_return(['four', 'three', 'two', 'one']) } - it "should shuffle a string but the sorted contents should still be the same" do - result = scope.function_shuffle(["adfs"]) - expect(result.split("").sort.join("")).to(eq("adfs")) - end + it { is_expected.to run.with_params('').and_return('') } + it { is_expected.to run.with_params('a').and_return('a') } + it { is_expected.to run.with_params('abc').and_return('bac') } + it { is_expected.to run.with_params('abcd').and_return('dcba') } - it "should accept objects which extend String" do - class AlsoString < String + context 'when using a class extending String' do + it { is_expected.to run.with_params(AlsoString.new('asdfghjkl')).and_return('lkhdsfajg') } end - - value = AlsoString.new('asdf') - result = scope.function_shuffle([value]) - result.size.should(eq(4)) end end diff --git a/spec/functions/size_spec.rb b/spec/functions/size_spec.rb index 18eb48f..6b64866 100755 --- a/spec/functions/size_spec.rb +++ b/spec/functions/size_spec.rb @@ -1,24 +1,32 @@ -#! /usr/bin/env ruby -S rspec require 'spec_helper' -describe "the size function" do - let(:scope) { PuppetlabsSpec::PuppetInternals.scope } +describe 'size' 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 { + pending("Current implementation ignores parameters after the first.") + is_expected.to run.with_params([], 'extra').and_raise_error(Puppet::ParseError, /wrong number of arguments/i) + } + it { is_expected.to run.with_params(1).and_raise_error(Puppet::ParseError, /Unknown type given/) } + it { is_expected.to run.with_params({}).and_raise_error(Puppet::ParseError, /Unknown type given/) } + it { is_expected.to run.with_params(true).and_raise_error(Puppet::ParseError, /Unknown type given/) } + it { is_expected.to run.with_params('1').and_raise_error(Puppet::ParseError, /Requires either string or array to work/) } + it { is_expected.to run.with_params('1.0').and_raise_error(Puppet::ParseError, /Requires either string or array to work/) } + it { is_expected.to run.with_params([]).and_return(0) } + it { is_expected.to run.with_params(['a']).and_return(1) } + it { is_expected.to run.with_params(['one', 'two', 'three']).and_return(3) } + it { is_expected.to run.with_params(['one', 'two', 'three', 'four']).and_return(4) } - it "should exist" do - expect(Puppet::Parser::Functions.function("size")).to eq("function_size") - end - - it "should raise a ParseError if there is less than 1 arguments" do - expect { scope.function_size([]) }.to( raise_error(Puppet::ParseError)) - end - - it "should return the size of a string" do - result = scope.function_size(["asdf"]) - expect(result).to(eq(4)) - end + it { is_expected.to run.with_params('').and_return(0) } + it { is_expected.to run.with_params('a').and_return(1) } + it { is_expected.to run.with_params('abc').and_return(3) } + it { is_expected.to run.with_params('abcd').and_return(4) } - it "should return the size of an array" do - result = scope.function_size([["a","b","c"]]) - expect(result).to(eq(3)) + context 'when using a class extending String' do + it 'should call its size method' do + value = AlsoString.new('asdfghjkl') + value.expects(:size).returns('foo') + expect(subject).to run.with_params(value).and_return('foo') + end end end diff --git a/spec/functions/sort_spec.rb b/spec/functions/sort_spec.rb index 4c2a66c..9abd039 100755 --- a/spec/functions/sort_spec.rb +++ b/spec/functions/sort_spec.rb @@ -1,24 +1,24 @@ -#! /usr/bin/env ruby -S rspec require 'spec_helper' -describe "the sort function" do - let(:scope) { PuppetlabsSpec::PuppetInternals.scope } - - it "should exist" do - expect(Puppet::Parser::Functions.function("sort")).to eq("function_sort") - end - - it "should raise a ParseError if there is not 1 arguments" do - expect { scope.function_sort(['','']) }.to( raise_error(Puppet::ParseError)) +describe 'sort' 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) } + it { is_expected.to run.with_params([], 'extra').and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } + it { pending('stricter input checking'); is_expected.to run.with_params({}).and_raise_error(Puppet::ParseError, /requires string or array/) } + it { pending('stricter input checking'); is_expected.to run.with_params(1).and_raise_error(Puppet::ParseError, /requires string or array/) } + it { pending('stricter input checking'); is_expected.to run.with_params(true).and_raise_error(Puppet::ParseError, /requires string or array/) } end - it "should sort an array" do - result = scope.function_sort([["a","c","b"]]) - expect(result).to(eq(['a','b','c'])) + context 'when called with an array' do + it { is_expected.to run.with_params([]).and_return([]) } + it { is_expected.to run.with_params(['a']).and_return(['a']) } + it { is_expected.to run.with_params(['c', 'b', 'a']).and_return(['a', 'b', 'c']) } end - it "should sort a string" do - result = scope.function_sort(["acb"]) - expect(result).to(eq('abc')) + context 'when called with a string' do + it { is_expected.to run.with_params('').and_return('') } + it { is_expected.to run.with_params('a').and_return('a') } + it { is_expected.to run.with_params('cbda').and_return('abcd') } end end diff --git a/spec/functions/squeeze_spec.rb b/spec/functions/squeeze_spec.rb index cd0eb37..7f09c30 100755 --- a/spec/functions/squeeze_spec.rb +++ b/spec/functions/squeeze_spec.rb @@ -1,24 +1,44 @@ -#! /usr/bin/env ruby -S rspec require 'spec_helper' -describe "the squeeze function" do - let(:scope) { PuppetlabsSpec::PuppetInternals.scope } +describe 'squeeze' 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(1).and_raise_error(NoMethodError) } + it { is_expected.to run.with_params({}).and_raise_error(NoMethodError) } + it { is_expected.to run.with_params(true).and_raise_error(NoMethodError) } - it "should exist" do - expect(Puppet::Parser::Functions.function("squeeze")).to eq("function_squeeze") + context 'when squeezing a single string' do + it { is_expected.to run.with_params('').and_return('') } + it { is_expected.to run.with_params('a').and_return('a') } + it { is_expected.to run.with_params('aaaaaaaaa').and_return('a') } + it { is_expected.to run.with_params('aaaaaaaaa', 'a').and_return('a') } + it { is_expected.to run.with_params('aaaaaaaaabbbbbbbbbbcccccccccc', 'b-c').and_return('aaaaaaaaabc') } end - it "should raise a ParseError if there is less than 2 arguments" do - expect { scope.function_squeeze([]) }.to( raise_error(Puppet::ParseError)) + context 'when squeezing values in an array' do + it { + is_expected.to run \ + .with_params(['', 'a', 'aaaaaaaaa', 'aaaaaaaaabbbbbbbbbbcccccccccc']) \ + .and_return( ['', 'a', 'a', 'abc']) + } + it { + is_expected.to run \ + .with_params(['', 'a', 'aaaaaaaaa', 'aaaaaaaaabbbbbbbbbbcccccccccc'], 'a') \ + .and_return( ['', 'a', 'a', 'abbbbbbbbbbcccccccccc']) + } + it { + is_expected.to run \ + .with_params(['', 'a', 'aaaaaaaaa', 'aaaaaaaaabbbbbbbbbbcccccccccc'], 'b-c') \ + .and_return( ['', 'a', 'aaaaaaaaa', 'aaaaaaaaabc']) + } end - it "should squeeze a string" do - result = scope.function_squeeze(["aaabbbbcccc"]) - expect(result).to(eq('abc')) - end - - it "should squeeze all elements in an array" do - result = scope.function_squeeze([["aaabbbbcccc","dddfff"]]) - expect(result).to(eq(['abc','df'])) + context 'when using a class extending String' do + it 'should call its squeeze method' do + value = AlsoString.new('aaaaaaaaa') + value.expects(:squeeze).returns('foo') + expect(subject).to run.with_params(value).and_return('foo') + end end end diff --git a/spec/functions/str2bool_spec.rb b/spec/functions/str2bool_spec.rb index 1d205d7..3b439b2 100755 --- a/spec/functions/str2bool_spec.rb +++ b/spec/functions/str2bool_spec.rb @@ -1,31 +1,23 @@ -#! /usr/bin/env ruby -S rspec require 'spec_helper' -describe "the str2bool function" do - let(:scope) { PuppetlabsSpec::PuppetInternals.scope } +describe 'str2bool' 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 { + pending("Current implementation ignores parameters after the first.") + is_expected.to run.with_params('true', 'extra').and_raise_error(Puppet::ParseError, /wrong number of arguments/i) + } + it { is_expected.to run.with_params('one').and_raise_error(Puppet::ParseError, /Unknown type of boolean given/) } - it "should exist" do - expect(Puppet::Parser::Functions.function("str2bool")).to eq("function_str2bool") + describe 'when testing values that mean "true"' do + [ '1', 't', 'y', 'true', 'yes', true ].each do |value| + it { is_expected.to run.with_params(value).and_return(true) } + end end - it "should raise a ParseError if there is less than 1 arguments" do - expect { scope.function_str2bool([]) }.to( raise_error(Puppet::ParseError)) - end - - it "should convert string 'true' to true" do - result = scope.function_str2bool(["true"]) - expect(result).to(eq(true)) - end - - it "should convert string 'undef' to false" do - result = scope.function_str2bool(["undef"]) - expect(result).to(eq(false)) - end - - it "should return the boolean it was called with" do - result = scope.function_str2bool([true]) - expect(result).to(eq(true)) - result = scope.function_str2bool([false]) - expect(result).to(eq(false)) + describe 'when testing values that mean "false"' do + [ '', '0', 'f', 'n', 'false', 'no', false, 'undef', 'undefined' ].each do |value| + it { is_expected.to run.with_params(value).and_return(false) } + end end end diff --git a/spec/functions/str2saltedsha512_spec.rb b/spec/functions/str2saltedsha512_spec.rb index ab7f57f..2e1e818 100755 --- a/spec/functions/str2saltedsha512_spec.rb +++ b/spec/functions/str2saltedsha512_spec.rb @@ -1,45 +1,17 @@ -#! /usr/bin/env ruby -S rspec require 'spec_helper' -describe "the str2saltedsha512 function" do - let(:scope) { PuppetlabsSpec::PuppetInternals.scope } +describe 'str2saltedsha512' 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('password', 2).and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } + it { is_expected.to run.with_params(1).and_raise_error(Puppet::ParseError, /Requires a String argument/) } - it "should exist" do - expect(Puppet::Parser::Functions.function("str2saltedsha512")).to eq("function_str2saltedsha512") - end - - it "should raise a ParseError if there is less than 1 argument" do - expect { scope.function_str2saltedsha512([]) }.to( raise_error(Puppet::ParseError) ) - end - - it "should raise a ParseError if there is more than 1 argument" do - expect { scope.function_str2saltedsha512(['foo', 'bar', 'baz']) }.to( raise_error(Puppet::ParseError) ) - end - - it "should return a salted-sha512 password hash 136 characters in length" do - result = scope.function_str2saltedsha512(["password"]) - expect(result.length).to(eq(136)) - end - - it "should raise an error if you pass a non-string password" do - expect { scope.function_str2saltedsha512([1234]) }.to( raise_error(Puppet::ParseError) ) - end - - it "should generate a valid password" do - # Allow the function to generate a password based on the string 'password' - password_hash = scope.function_str2saltedsha512(["password"]) - - # Separate the Salt and Password from the Password Hash - salt = password_hash[0..7] - password = password_hash[8..-1] - - # Convert the Salt and Password from Hex to Binary Data - str_salt = Array(salt.lines).pack('H*') - str_password = Array(password.lines).pack('H*') + context 'when running with a specific seed' do + # make tests deterministic + before(:each) { srand(2) } - # Combine the Binary Salt with 'password' and compare the end result - saltedpass = Digest::SHA512.digest(str_salt + 'password') - result = (str_salt + saltedpass).unpack('H*')[0] - expect(result).to eq(password_hash) + it { is_expected.to run.with_params('').and_return('0f8a612f4eeed08e47b3875d00f33c5688f7926298f2d9b5fe19d1323f910bc78b6f7b5892596d2fabaa65e7a8d99b3768c102610cf0432c4827eee01f09451e3fae4f7a') } + it { is_expected.to run.with_params('password').and_return('0f8a612f43134376566c5707718d600effcfb17581fc9d3fa64d7f447dfda317c174ffdb498d2c5bd5c2075dab41c9d7ada5afbdc6b55354980eb5ba61802371e6b64956') } + it { is_expected.to run.with_params('verylongpassword').and_return('0f8a612f7a448537540e062daa8621f9bae326ca8ccb899e1bdb10e7c218cebfceae2530b856662565fdc4d81e986fc50cfbbc46d50436610ed9429ff5e43f2c45b5d039') } end end diff --git a/spec/functions/strftime_spec.rb b/spec/functions/strftime_spec.rb index ebec54b..e76774a 100755 --- a/spec/functions/strftime_spec.rb +++ b/spec/functions/strftime_spec.rb @@ -1,9 +1,6 @@ -#! /usr/bin/env ruby -S rspec require 'spec_helper' -describe "the strftime function" do - let(:scope) { PuppetlabsSpec::PuppetInternals.scope } - +describe 'strftime' do it "should exist" do expect(Puppet::Parser::Functions.function("strftime")).to eq("function_strftime") end diff --git a/spec/functions/strip_spec.rb b/spec/functions/strip_spec.rb index 4ac8daf..689b6dd 100755 --- a/spec/functions/strip_spec.rb +++ b/spec/functions/strip_spec.rb @@ -1,27 +1,34 @@ -#! /usr/bin/env ruby -S rspec require 'spec_helper' -describe "the strip function" do - let(:scope) { PuppetlabsSpec::PuppetInternals.scope } - it "should exist" do - expect(Puppet::Parser::Functions.function("strip")).to eq("function_strip") - end - - it "should raise a ParseError if there is less than 1 arguments" do - expect { scope.function_strip([]) }.to( raise_error(Puppet::ParseError)) - end - - it "should strip a string" do - result = scope.function_strip([" ab cd "]) - expect(result).to(eq('ab cd')) - end - - it "should accept objects which extend String" do - class AlsoString < String - end - - value = AlsoString.new(' as df ') - result = scope.function_strip([value]) - result.should(eq('as df')) - end +describe 'strip' 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 { + pending("Current implementation ignores parameters after the first.") + 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, /Requires either array or string to work with/) } + it { is_expected.to run.with_params(1).and_raise_error(Puppet::ParseError, /Requires either array or string to work with/) } + it { is_expected.to run.with_params('').and_return('') } + it { is_expected.to run.with_params(' ').and_return('') } + it { is_expected.to run.with_params(' ').and_return('') } + it { is_expected.to run.with_params("\t").and_return('') } + it { is_expected.to run.with_params("\t ").and_return('') } + it { is_expected.to run.with_params('one').and_return('one') } + it { is_expected.to run.with_params(' one').and_return('one') } + it { is_expected.to run.with_params(' one').and_return('one') } + it { is_expected.to run.with_params("\tone").and_return('one') } + it { is_expected.to run.with_params("\t one").and_return('one') } + it { is_expected.to run.with_params('one ').and_return('one') } + it { is_expected.to run.with_params(' one ').and_return('one') } + it { is_expected.to run.with_params(' one ').and_return('one') } + it { is_expected.to run.with_params("\tone ").and_return('one') } + it { is_expected.to run.with_params("\t one ").and_return('one') } + it { is_expected.to run.with_params("one \t").and_return('one') } + it { is_expected.to run.with_params(" one \t").and_return('one') } + it { is_expected.to run.with_params(" one \t").and_return('one') } + it { is_expected.to run.with_params("\tone \t").and_return('one') } + it { is_expected.to run.with_params("\t one \t").and_return('one') } + it { is_expected.to run.with_params(' o n e ').and_return('o n e') } + it { is_expected.to run.with_params(AlsoString.new(' one ')).and_return('one') } end diff --git a/spec/functions/suffix_spec.rb b/spec/functions/suffix_spec.rb index c7783c6..b48a4eb 100755 --- a/spec/functions/suffix_spec.rb +++ b/spec/functions/suffix_spec.rb @@ -1,27 +1,44 @@ -#! /usr/bin/env ruby -S rspec require 'spec_helper' -describe "the suffix function" do - let(:scope) { PuppetlabsSpec::PuppetInternals.scope } - - it "raises a ParseError if there is less than 1 arguments" do - expect { scope.function_suffix([]) }.to raise_error(Puppet::ParseError, /number of arguments/) - end - - it "raises an error if the first argument is not an array" do - expect { - scope.function_suffix([Object.new]) - }.to raise_error(Puppet::ParseError, /expected first argument to be an Array/) - end - - it "raises an error if the second argument is not a string" do - expect { - scope.function_suffix([['first', 'second'], 42]) - }.to raise_error(Puppet::ParseError, /expected second argument to be a String/) - end - - it "returns a suffixed array" do - result = scope.function_suffix([['a','b','c'], 'p']) - expect(result).to(eq(['ap','bp','cp'])) - end +describe 'suffix' 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 { + pending("Current implementation ignores parameters after the second.") + is_expected.to run.with_params([], 'a', '').and_raise_error(Puppet::ParseError, /wrong number of arguments/i) + } + it { is_expected.to run.with_params('', '').and_raise_error(Puppet::ParseError, /expected first argument to be an Array/) } + it { is_expected.to run.with_params([], 2).and_raise_error(Puppet::ParseError, /expected second argument to be a String/) } + it { is_expected.to run.with_params([]).and_return([]) } + it { is_expected.to run.with_params(['one', 2]).and_return(['one', '2']) } + it { is_expected.to run.with_params([], '').and_return([]) } + it { is_expected.to run.with_params([''], '').and_return(['']) } + it { is_expected.to run.with_params(['one'], 'post').and_return(['onepost']) } + it { is_expected.to run.with_params(['one', 'two', 'three'], 'post').and_return(['onepost', 'twopost', 'threepost']) } + it { + pending("implementation of Hash functionality matching prefix") + is_expected.to run.with_params({}).and_return({}) + } + it { + pending("implementation of Hash functionality matching prefix") + is_expected.to run.with_params({ 'key1' => 'value1', 2 => 3}).and_return({ 'key1' => 'value1', '2' => 3 }) + } + it { + pending("implementation of Hash functionality matching prefix") + is_expected.to run.with_params({}, '').and_return({}) + } + it { + pending("implementation of Hash functionality matching prefix") + is_expected.to run.with_params({ 'key' => 'value' }, '').and_return({ 'key' => 'value' }) + } + it { + pending("implementation of Hash functionality matching prefix") + is_expected.to run.with_params({ 'key' => 'value' }, 'post').and_return({ 'keypost' => 'value' }) + } + it { + pending("implementation of Hash functionality matching prefix") + is_expected.to run \ + .with_params({ 'key1' => 'value1', 'key2' => 'value2', 'key3' => 'value3' }, 'pre') \ + .and_return({ 'key1post' => 'value1', 'key2post' => 'value2', 'key3post' => 'value3' }) + } end diff --git a/spec/functions/swapcase_spec.rb b/spec/functions/swapcase_spec.rb index 791d1df..c175a15 100755 --- a/spec/functions/swapcase_spec.rb +++ b/spec/functions/swapcase_spec.rb @@ -1,28 +1,40 @@ -#! /usr/bin/env ruby -S rspec require 'spec_helper' -describe "the swapcase function" do - let(:scope) { PuppetlabsSpec::PuppetInternals.scope } - - it "should exist" do - expect(Puppet::Parser::Functions.function("swapcase")).to eq("function_swapcase") - end - - it "should raise a ParseError if there is less than 1 arguments" do - expect { scope.function_swapcase([]) }.to( raise_error(Puppet::ParseError)) +describe 'swapcase' 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 { + pending("Current implementation ignores parameters after the first.") + is_expected.to run.with_params('a', '').and_raise_error(Puppet::ParseError, /wrong number of arguments/i) + } + it { is_expected.to run.with_params(1).and_raise_error(Puppet::ParseError, /Requires either array or string to work/) } + it { is_expected.to run.with_params({}).and_raise_error(Puppet::ParseError, /Requires either array or string to work/) } + it { is_expected.to run.with_params(true).and_raise_error(Puppet::ParseError, /Requires either array or string to work/) } + describe 'with strings as inputs' do + it { is_expected.to run.with_params('').and_return('') } + it { is_expected.to run.with_params('one').and_return('ONE') } + it { is_expected.to run.with_params('ONE').and_return('one') } + it { is_expected.to run.with_params('oNe').and_return('OnE') } end - - it "should swapcase a string" do - result = scope.function_swapcase(["aaBBccDD"]) - expect(result).to(eq('AAbbCCdd')) + describe 'with arrays as inputs' do + it { is_expected.to run.with_params([]).and_return([]) } + describe 'only containing strings' do + it { is_expected.to run.with_params(['']).and_return(['']) } + it { is_expected.to run.with_params(['one']).and_return(['ONE']) } + it { is_expected.to run.with_params(['ONE']).and_return(['one']) } + it { is_expected.to run.with_params(['oNe']).and_return(['OnE']) } + it { is_expected.to run.with_params(['one', 'ONE']).and_return(['ONE', 'one']) } + it { is_expected.to run.with_params(['ONE', 'OnE']).and_return(['one', 'oNe']) } + it { is_expected.to run.with_params(['oNe', 'one']).and_return(['OnE', 'ONE']) } + end + describe 'containing mixed types' do + it { is_expected.to run.with_params(['OnE', {}]).and_return(['oNe', {}]) } + it { is_expected.to run.with_params(['OnE', 1]).and_return(['oNe', 1]) } + it { is_expected.to run.with_params(['OnE', []]).and_return(['oNe', []]) } + it { is_expected.to run.with_params(['OnE', ['two']]).and_return(['oNe', ['two']]) } + end end - it "should accept objects which extend String" do - class AlsoString < String - end - - value = AlsoString.new("aaBBccDD") - result = scope.function_swapcase([value]) - result.should(eq("AAbbCCdd")) + is_expected.to run.with_params(AlsoString.new("OnE")).and_return('oNe') end end diff --git a/spec/functions/time_spec.rb b/spec/functions/time_spec.rb index 6e22515..2875e25 100755 --- a/spec/functions/time_spec.rb +++ b/spec/functions/time_spec.rb @@ -1,29 +1,28 @@ -#! /usr/bin/env ruby -S rspec require 'spec_helper' -describe "the time function" do - let(:scope) { PuppetlabsSpec::PuppetInternals.scope } +describe 'time' do + it { is_expected.not_to eq(nil) } + it { is_expected.to run.with_params('a', '').and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } - it "should exist" do - expect(Puppet::Parser::Functions.function("time")).to eq("function_time") - end - - it "should raise a ParseError if there is more than 2 arguments" do - expect { scope.function_time(['','']) }.to( raise_error(Puppet::ParseError)) - end + context 'when running at a specific time' do + before(:each) { + # get a value before stubbing the function + test_time = Time.utc(2006, 10, 13, 8, 15, 11, '+01:00') + Time.expects(:new).with().returns(test_time).once + } + it { is_expected.to run.with_params().and_return(1160727311) } + it { is_expected.to run.with_params('').and_return(1160727311) } + it { is_expected.to run.with_params([]).and_return(1160727311) } + it { is_expected.to run.with_params({}).and_return(1160727311) } + it { is_expected.to run.with_params('foo').and_return(1160727311) } + it { is_expected.to run.with_params('UTC').and_return(1160727311) } - it "should return a number" do - result = scope.function_time([]) - expect(result).to be_an(Integer) - end - - it "should be higher then when I wrote this test" do - result = scope.function_time([]) - expect(result).to(be > 1311953157) - end + context 'when running on modern rubies', :unless => RUBY_VERSION == '1.8.7' do + it { is_expected.to run.with_params('America/Los_Angeles').and_return(1160727311) } + end - it "should be lower then 1.5 trillion" do - result = scope.function_time([]) - expect(result).to(be < 1500000000) + context 'when running on ruby 1.8.7, which garbles the TZ', :if => RUBY_VERSION == '1.8.7' do + it { is_expected.to run.with_params('America/Los_Angeles').and_return(1160702111) } + end end end diff --git a/spec/functions/to_bytes_spec.rb b/spec/functions/to_bytes_spec.rb index 0f6ade9..2be23ff 100755 --- a/spec/functions/to_bytes_spec.rb +++ b/spec/functions/to_bytes_spec.rb @@ -1,83 +1,72 @@ -#! /usr/bin/env ruby -S rspec - require 'spec_helper' -describe "the to_bytes function" do - let(:scope) { PuppetlabsSpec::PuppetInternals.scope } - - it "should exist" do - expect(Puppet::Parser::Functions.function("to_bytes")).to eq("function_to_bytes") - end - - it "should raise a ParseError if there is less than 1 arguments" do - expect { scope.function_to_bytes([]) }.to( raise_error(Puppet::ParseError)) - end - - it "should convert kB to B" do - result = scope.function_to_bytes(["4 kB"]) - expect(result).to(eq(4096)) - end - - it "should convert MB to B" do - result = scope.function_to_bytes(["4 MB"]) - expect(result).to(eq(4194304)) - end - - it "should convert GB to B" do - result = scope.function_to_bytes(["4 GB"]) - expect(result).to(eq(4294967296)) - end - - it "should convert TB to B" do - result = scope.function_to_bytes(["4 TB"]) - expect(result).to(eq(4398046511104)) - end - - it "should convert PB to B" do - result = scope.function_to_bytes(["4 PB"]) - expect(result).to(eq(4503599627370496)) - end - - it "should convert PB to B" do - result = scope.function_to_bytes(["4 EB"]) - expect(result).to(eq(4611686018427387904)) - end - - it "should work without B in unit" do - result = scope.function_to_bytes(["4 k"]) - expect(result).to(eq(4096)) - end - - it "should work without a space before unit" do - result = scope.function_to_bytes(["4k"]) - expect(result).to(eq(4096)) - end - - it "should work without a unit" do - result = scope.function_to_bytes(["5678"]) - expect(result).to(eq(5678)) - end - - it "should convert fractions" do - result = scope.function_to_bytes(["1.5 kB"]) - expect(result).to(eq(1536)) - end - - it "should convert scientific notation" do - result = scope.function_to_bytes(["1.5e2 B"]) - expect(result).to(eq(150)) - end - - it "should do nothing with a positive number" do - result = scope.function_to_bytes([5678]) - expect(result).to(eq(5678)) - end - - it "should should raise a ParseError if input isn't a number" do - expect { scope.function_to_bytes(["foo"]) }.to( raise_error(Puppet::ParseError)) - end - - it "should should raise a ParseError if prefix is unknown" do - expect { scope.function_to_bytes(["5 uB"]) }.to( raise_error(Puppet::ParseError)) +describe 'to_bytes' 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('1', 'extras').and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } + it { is_expected.to run.with_params([]).and_raise_error(TypeError, /(can't convert|no implicit conversion of) Array (in)?to String/) } + it { is_expected.to run.with_params({}).and_raise_error(TypeError, /(can't convert|no implicit conversion of) Hash (in)?to String/) } + it { is_expected.to run.with_params(true).and_raise_error(TypeError, /(can't convert|no implicit conversion of) (TrueClass|true) (in)?to String/) } + + describe 'when passing numbers' do + it { is_expected.to run.with_params(0).and_return(0) } + it { is_expected.to run.with_params(1).and_return(1) } + it { is_expected.to run.with_params(-1).and_return(-1) } + it { is_expected.to run.with_params(1.1).and_return(1.1) } + it { is_expected.to run.with_params(-1.1).and_return(-1.1) } + end + + describe 'when passing numbers as strings' do + describe 'without a unit' do + it { is_expected.to run.with_params('1').and_return(1) } + it { is_expected.to run.with_params('-1').and_return(-1) } + # these are so wrong + it { is_expected.to run.with_params('1.1').and_return(1) } + it { is_expected.to run.with_params('-1.1').and_return(-1) } + end + + describe 'with a unit' do + it { is_expected.to run.with_params('1k').and_return(1024) } + it { is_expected.to run.with_params('-1kB').and_return(-1024) } + it { is_expected.to run.with_params('1k').and_return(1024) } + it { is_expected.to run.with_params('1M').and_return(1024*1024) } + it { is_expected.to run.with_params('1G').and_return(1024*1024*1024) } + it { is_expected.to run.with_params('1T').and_return(1024*1024*1024*1024) } + it { is_expected.to run.with_params('1P').and_return(1024*1024*1024*1024*1024) } + it { is_expected.to run.with_params('1E').and_return(1024*1024*1024*1024*1024*1024) } + it { is_expected.to run.with_params('1.5e3M').and_return(1572864000) } + + it { is_expected.to run.with_params('4k').and_return(4*1024) } + it { is_expected.to run.with_params('-4kB').and_return(4*-1024) } + it { is_expected.to run.with_params('4k').and_return(4*1024) } + it { is_expected.to run.with_params('4M').and_return(4*1024*1024) } + it { is_expected.to run.with_params('4G').and_return(4*1024*1024*1024) } + it { is_expected.to run.with_params('4T').and_return(4*1024*1024*1024*1024) } + it { is_expected.to run.with_params('4P').and_return(4*1024*1024*1024*1024*1024) } + it { is_expected.to run.with_params('4E').and_return(4*1024*1024*1024*1024*1024*1024) } + + # these are so wrong + it { is_expected.to run.with_params('1.0001 k').and_return(1024) } + it { is_expected.to run.with_params('-1.0001 kB').and_return(-1024) } + end + + describe 'with a unknown unit' do + it { is_expected.to run.with_params('1KB').and_raise_error(Puppet::ParseError, /Unknown prefix/) } + it { is_expected.to run.with_params('1K').and_raise_error(Puppet::ParseError, /Unknown prefix/) } + it { is_expected.to run.with_params('1mb').and_raise_error(Puppet::ParseError, /Unknown prefix/) } + it { is_expected.to run.with_params('1m').and_raise_error(Puppet::ParseError, /Unknown prefix/) } + it { is_expected.to run.with_params('1%').and_raise_error(Puppet::ParseError, /Unknown prefix/) } + it { is_expected.to run.with_params('1 p').and_raise_error(Puppet::ParseError, /Unknown prefix/) } + end + end + + # these are so wrong + describe 'when passing random stuff' do + it { is_expected.to run.with_params('-1....1').and_return(-1) } + it { is_expected.to run.with_params('-1.e.e.e.1').and_return(-1) } + it { is_expected.to run.with_params('-1+1').and_return(-1) } + it { is_expected.to run.with_params('1-1').and_return(1) } + it { is_expected.to run.with_params('1 kaboom').and_return(1024) } + it { is_expected.to run.with_params('kaboom').and_return(0) } end end diff --git a/spec/functions/type3x_spec.rb b/spec/functions/type3x_spec.rb index d21236a..c3eb1de 100644 --- a/spec/functions/type3x_spec.rb +++ b/spec/functions/type3x_spec.rb @@ -1,8 +1,6 @@ -#! /usr/bin/env ruby -S rspec require 'spec_helper' -describe "the type3x function" do - let(:scope) { PuppetlabsSpec::PuppetInternals.scope } +describe 'type3x' do it "should exist" do expect(Puppet::Parser::Functions.function("type3x")).to eq("function_type3x") end diff --git a/spec/functions/type_of_spec.rb b/spec/functions/type_of_spec.rb index b823460..f770990 100644 --- a/spec/functions/type_of_spec.rb +++ b/spec/functions/type_of_spec.rb @@ -1,13 +1,23 @@ -#! /usr/bin/env ruby -S rspec - require 'spec_helper' -describe 'type_of', :if => Puppet.version.to_f >= 4.0 do - it 'gives the type of a string' do - expect(subject.call_function('type_of', 'hello world')).to be_kind_of(Puppet::Pops::Types::PStringType) +if ENV["FUTURE_PARSER"] == 'yes' + describe 'type_of' do + pending 'teach rspec-puppet to load future-only functions under 3.7.5' end +end + +if Puppet.version.to_f >= 4.0 + describe 'type_of' do + it { is_expected.not_to eq(nil) } + it { is_expected.to run.with_params().and_raise_error(ArgumentError) } + it { is_expected.to run.with_params('', '').and_raise_error(ArgumentError) } + + it 'gives the type of a string' do + expect(subject.call({}, 'hello world')).to be_kind_of(Puppet::Pops::Types::PStringType) + end - it 'gives the type of an integer' do - expect(subject.call_function('type_of', 5)).to be_kind_of(Puppet::Pops::Types::PIntegerType) + it 'gives the type of an integer' do + expect(subject.call({}, 5)).to be_kind_of(Puppet::Pops::Types::PIntegerType) + end end end diff --git a/spec/functions/type_spec.rb b/spec/functions/type_spec.rb index b683fcf..4288df0 100755 --- a/spec/functions/type_spec.rb +++ b/spec/functions/type_spec.rb @@ -1,8 +1,6 @@ -#! /usr/bin/env ruby -S rspec require 'spec_helper' -describe "the type function" do - let(:scope) { PuppetlabsSpec::PuppetInternals.scope } +describe 'type' do it "should exist" do expect(Puppet::Parser::Functions.function("type")).to eq("function_type") end diff --git a/spec/functions/union_spec.rb b/spec/functions/union_spec.rb index 706f4cb..970e1fe 100755 --- a/spec/functions/union_spec.rb +++ b/spec/functions/union_spec.rb @@ -1,19 +1,23 @@ -#! /usr/bin/env ruby -S rspec require 'spec_helper' -describe "the union function" do - let(:scope) { PuppetlabsSpec::PuppetInternals.scope } - - it "should exist" do - expect(Puppet::Parser::Functions.function("union")).to eq("function_union") - end - - it "should raise a ParseError if there are fewer than 2 arguments" do - expect { scope.function_union([]) }.to( raise_error(Puppet::ParseError) ) +describe 'union' do + describe 'argument checking' 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('one').and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } + it { is_expected.to run.with_params('one', 'two', 'three').and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } + it { is_expected.to run.with_params('one', []).and_raise_error(Puppet::ParseError, /Requires 2 arrays/) } + it { is_expected.to run.with_params([], 'two').and_raise_error(Puppet::ParseError, /Requires 2 arrays/) } + it { is_expected.to run.with_params({}, {}).and_raise_error(Puppet::ParseError, /Requires 2 arrays/) } end - it "should join two arrays together" do - result = scope.function_union([["a","b","c"],["b","c","d"]]) - expect(result).to(eq(["a","b","c","d"])) - end + it { is_expected.to run.with_params([], []).and_return([]) } + it { is_expected.to run.with_params([], ['one']).and_return(['one']) } + it { is_expected.to run.with_params(['one'], []).and_return(['one']) } + it { is_expected.to run.with_params(['one'], ['one']).and_return(['one']) } + it { is_expected.to run.with_params(['one'], ['two']).and_return(['one', 'two']) } + it { is_expected.to run.with_params(['one', 'two', 'three'], ['two', 'three']).and_return(['one', 'two', 'three']) } + it { is_expected.to run.with_params(['one', 'two', 'two', 'three'], ['two', 'three']).and_return(['one', 'two', 'three']) } + it { is_expected.to run.with_params(['one', 'two', 'three'], ['two', 'two', 'three']).and_return(['one', 'two', 'three']) } + it 'should not confuse types' do is_expected.to run.with_params(['1', '2', '3'], [1, 2]).and_return(['1', '2', '3', 1, 2]) end end diff --git a/spec/functions/unique_spec.rb b/spec/functions/unique_spec.rb index 7cd3a56..24257a0 100755 --- a/spec/functions/unique_spec.rb +++ b/spec/functions/unique_spec.rb @@ -1,33 +1,27 @@ -#! /usr/bin/env ruby -S rspec require 'spec_helper' -describe "the unique function" do - let(:scope) { PuppetlabsSpec::PuppetInternals.scope } - - it "should exist" do - expect(Puppet::Parser::Functions.function("unique")).to eq("function_unique") - end - - it "should raise a ParseError if there is less than 1 arguments" do - expect { scope.function_unique([]) }.to( raise_error(Puppet::ParseError)) +describe 'unique' 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) } + it { + pending("Current implementation ignores parameters after the first.") + is_expected.to run.with_params([], 'extra').and_raise_error(Puppet::ParseError, /wrong number of arguments/i) + } + it { is_expected.to run.with_params({}).and_raise_error(Puppet::ParseError, /Requires either array or string to work/) } + it { is_expected.to run.with_params(1).and_raise_error(Puppet::ParseError, /Requires either array or string to work/) } + it { is_expected.to run.with_params(true).and_raise_error(Puppet::ParseError, /Requires either array or string to work/) } end - it "should remove duplicate elements in a string" do - result = scope.function_unique(["aabbc"]) - expect(result).to(eq('abc')) + context 'when called with an array' do + it { is_expected.to run.with_params([]).and_return([]) } + it { is_expected.to run.with_params(['a']).and_return(['a']) } + it { is_expected.to run.with_params(['a', 'b', 'a']).and_return(['a', 'b']) } end - it "should remove duplicate elements in an array" do - result = scope.function_unique([["a","a","b","b","c"]]) - expect(result).to(eq(['a','b','c'])) - end - - it "should accept objects which extend String" do - class AlsoString < String - end - - value = AlsoString.new('aabbc') - result = scope.function_unique([value]) - result.should(eq('abc')) + context 'when called with a string' do + it { is_expected.to run.with_params('').and_return('') } + it { is_expected.to run.with_params('a').and_return('a') } + it { is_expected.to run.with_params('aaba').and_return('ab') } end end diff --git a/spec/functions/upcase_spec.rb b/spec/functions/upcase_spec.rb index 0689099..3b7b02d 100755 --- a/spec/functions/upcase_spec.rb +++ b/spec/functions/upcase_spec.rb @@ -1,58 +1,26 @@ -#! /usr/bin/env ruby -S rspec require 'spec_helper' -describe "the upcase function" do - let(:scope) { PuppetlabsSpec::PuppetInternals.scope } - - it "should exist" do - expect(Puppet::Parser::Functions.function("upcase")).to eq("function_upcase") - end - - it "should raise a ParseError if there is less than 1 arguments" do - expect { scope.function_upcase([]) }.to(raise_error(Puppet::ParseError)) +describe 'upcase' 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) } + it { is_expected.to run.with_params('', '').and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } + it { is_expected.to run.with_params(1).and_raise_error(Puppet::ParseError, /Requires an array, hash or object that responds to upcase/) } + it { is_expected.to run.with_params([1]).and_raise_error(Puppet::ParseError, /Requires an array, hash or object that responds to upcase/) } end - it "should upcase a string" do - result = scope.function_upcase(["abc"]) - expect(result).to(eq('ABC')) + describe 'normal string handling' do + it { is_expected.to run.with_params("abc").and_return("ABC") } + it { is_expected.to run.with_params("Abc").and_return("ABC") } + it { is_expected.to run.with_params("ABC").and_return("ABC") } end - it "should do nothing if a string is already upcase" do - result = scope.function_upcase(["ABC"]) - expect(result).to(eq('ABC')) + describe 'handling classes derived from String' do + it { is_expected.to run.with_params(AlsoString.new("ABC")).and_return("ABC") } end - it "should accept objects which extend String" do - class AlsoString < String - end - - value = AlsoString.new('abc') - result = scope.function_upcase([value]) - result.should(eq('ABC')) - end - - it 'should accept hashes and return uppercase' do - expect( - scope.function_upcase([{'test' => %w(this that and other thing)}]) - ).to eq({'TEST' => %w(THIS THAT AND OTHER THING)}) - end - - if :test.respond_to?(:upcase) - it 'should accept hashes of symbols' do - expect( - scope.function_upcase([{:test => [:this, :that, :other]}]) - ).to eq({:TEST => [:THIS, :THAT, :OTHER]}) - end - it 'should return upcase symbol' do - expect( - scope.function_upcase([:test]) - ).to eq(:TEST) - end - it 'should return mixed objects in upcease' do - expect( - scope.function_upcase([[:test, 'woot']]) - ).to eq([:TEST, 'WOOT']) - - end + describe 'strings in arrays handling' do + it { is_expected.to run.with_params([]).and_return([]) } + it { is_expected.to run.with_params(["One", "twO"]).and_return(["ONE", "TWO"]) } end end diff --git a/spec/functions/uriescape_spec.rb b/spec/functions/uriescape_spec.rb index d0f37de..f05ec08 100755 --- a/spec/functions/uriescape_spec.rb +++ b/spec/functions/uriescape_spec.rb @@ -1,40 +1,36 @@ -#! /usr/bin/env ruby -S rspec require 'spec_helper' -describe "the uriescape function" do - let(:scope) { PuppetlabsSpec::PuppetInternals.scope } - - it "should exist" do - expect(Puppet::Parser::Functions.function("uriescape")).to eq("function_uriescape") - end - - it "should raise a ParseError if there is less than 1 arguments" do - expect { scope.function_uriescape([]) }.to( raise_error(Puppet::ParseError)) - end - - it "should uriescape a string" do - result = scope.function_uriescape([":/?#[]@!$&'()*+,;= \"{}"]) - expect(result).to(eq(':/?%23[]@!$&\'()*+,;=%20%22%7B%7D')) +describe 'uriescape' 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) } + it { + pending("Current implementation ignores parameters after the first.") + is_expected.to run.with_params('', '').and_raise_error(Puppet::ParseError, /wrong number of arguments/i) + } + it { is_expected.to run.with_params(1).and_raise_error(Puppet::ParseError, /Requires either array or string to work/) } + it { is_expected.to run.with_params({}).and_raise_error(Puppet::ParseError, /Requires either array or string to work/) } + it { is_expected.to run.with_params(true).and_raise_error(Puppet::ParseError, /Requires either array or string to work/) } end - it "should uriescape an array of strings, while not touching up nonstrings" do - teststring = ":/?#[]@!$&'()*+,;= \"{}" - expectstring = ':/?%23[]@!$&\'()*+,;=%20%22%7B%7D' - result = scope.function_uriescape([[teststring, teststring, 1]]) - expect(result).to(eq([expectstring, expectstring, 1])) - end - - it "should do nothing if a string is already safe" do - result = scope.function_uriescape(["ABCdef"]) - expect(result).to(eq('ABCdef')) + describe 'handling normal strings' do + it 'should call ruby\'s URI.escape function' do + URI.expects(:escape).with('uri_string').returns('escaped_uri_string').once + is_expected.to run.with_params('uri_string').and_return('escaped_uri_string') + end end - it "should accept objects which extend String" do - class AlsoString < String + describe 'handling classes derived from String' do + it 'should call ruby\'s URI.escape function' do + uri_string = AlsoString.new('uri_string') + URI.expects(:escape).with(uri_string).returns('escaped_uri_string').once + is_expected.to run.with_params(uri_string).and_return("escaped_uri_string") end + end - value = AlsoString.new('abc') - result = scope.function_uriescape([value]) - result.should(eq('abc')) + describe 'strings in arrays handling' do + it { is_expected.to run.with_params([]).and_return([]) } + it { is_expected.to run.with_params(["one}", "two"]).and_return(["one%7D", "two"]) } + it { is_expected.to run.with_params(["one}", 1, true, {}, "two"]).and_return(["one%7D", 1, true, {}, "two"]) } end end diff --git a/spec/functions/validate_absolute_path_spec.rb b/spec/functions/validate_absolute_path_spec.rb index 36c836b..4a8404d 100755 --- a/spec/functions/validate_absolute_path_spec.rb +++ b/spec/functions/validate_absolute_path_spec.rb @@ -1,67 +1,32 @@ -#! /usr/bin/env ruby -S rspec require 'spec_helper' -describe Puppet::Parser::Functions.function(:validate_absolute_path) do - let(:scope) { PuppetlabsSpec::PuppetInternals.scope } - - # The subject of these examples is the method itself. - subject do - # This makes sure the function is loaded within each test - function_name = Puppet::Parser::Functions.function(:validate_absolute_path) - scope.method(function_name) +describe 'validate_absolute_path' 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 Paths" do - def self.valid_paths - %w{ - C:/ - C:\\ - C:\\WINDOWS\\System32 - C:/windows/system32 - X:/foo/bar - X:\\foo\\bar - /var/tmp - /var/lib/puppet - /var/opt/../lib/puppet - } - end - - context "Without Puppet::Util.absolute_path? (e.g. Puppet <= 2.6)" do - before :each do - # The intent here is to mock Puppet to behave like Puppet 2.6 does. - # Puppet 2.6 does not have the absolute_path? method. This is only a - # convenience test, stdlib should be run with the Puppet 2.6.x in the - # $LOAD_PATH in addition to 2.7.x and master. - Puppet::Util.expects(:respond_to?).with(:absolute_path?).returns(false) - end - valid_paths.each do |path| - it "validate_absolute_path(#{path.inspect}) should not fail" do - expect { subject.call [path] }.not_to raise_error - end - end - valid_paths do - it "validate_absolute_path(#{valid_paths.inspect}) should not fail" do - expect { subject.call [valid_paths] }.not_to raise_error - end - end - end - - context "Puppet without mocking" do - valid_paths.each do |path| - it "validate_absolute_path(#{path.inspect}) should not fail" do - expect { subject.call [path] }.not_to raise_error - end - end - valid_paths do - it "validate_absolute_path(#{valid_paths.inspect}) should not fail" do - expect { subject.call [valid_paths] }.not_to raise_error - end - end + describe "valid paths handling" do + %w{ + C:/ + C:\\ + C:\\WINDOWS\\System32 + C:/windows/system32 + X:/foo/bar + X:\\foo\\bar + \\\\host\\windows + //host/windows + / + /var/tmp + /var/opt/../lib/puppet + }.each do |path| + it { is_expected.to run.with_params(path) } + it { is_expected.to run.with_params(['/tmp', path]) } end end - describe 'Invalid paths' do - context 'Garbage inputs' do + describe 'invalid path handling' do + context 'garbage inputs' do [ nil, [ nil ], @@ -70,33 +35,26 @@ describe Puppet::Parser::Functions.function(:validate_absolute_path) do { }, '', ].each do |path| - it "validate_absolute_path(#{path.inspect}) should fail" do - expect { subject.call [path] }.to raise_error Puppet::ParseError - end + it { is_expected.to run.with_params(path).and_raise_error(Puppet::ParseError, /is not an absolute path/) } + it { is_expected.to run.with_params([path]).and_raise_error(Puppet::ParseError, /is not an absolute path/) } + it { is_expected.to run.with_params(['/tmp', path]).and_raise_error(Puppet::ParseError, /is not an absolute path/) } end end - context 'Relative paths' do - def self.rel_paths - %w{ - relative1 - . - .. - ./foo - ../foo - etc/puppetlabs/puppet - opt/puppet/bin - } - end - rel_paths.each do |path| - it "validate_absolute_path(#{path.inspect}) should fail" do - expect { subject.call [path] }.to raise_error Puppet::ParseError - end - end - rel_paths do - it "validate_absolute_path(#{rel_paths.inspect}) should fail" do - expect { subject.call [rel_paths] }.to raise_error Puppet::ParseError - end + context 'relative paths' do + %w{ + relative1 + . + .. + ./foo + ../foo + etc/puppetlabs/puppet + opt/puppet/bin + relative\\windows + }.each do |path| + it { is_expected.to run.with_params(path).and_raise_error(Puppet::ParseError, /is not an absolute path/) } + it { is_expected.to run.with_params([path]).and_raise_error(Puppet::ParseError, /is not an absolute path/) } + it { is_expected.to run.with_params(['/tmp', path]).and_raise_error(Puppet::ParseError, /is not an absolute path/) } end end end diff --git a/spec/functions/validate_array_spec.rb b/spec/functions/validate_array_spec.rb index 4b31cfd..4ee7754 100755 --- a/spec/functions/validate_array_spec.rb +++ b/spec/functions/validate_array_spec.rb @@ -1,38 +1,27 @@ -#! /usr/bin/env ruby -S rspec - require 'spec_helper' -describe Puppet::Parser::Functions.function(:validate_array) do - let(:scope) { PuppetlabsSpec::PuppetInternals.scope } - describe 'when calling validate_array from puppet' do - - %w{ true false }.each do |the_string| - it "should not compile when #{the_string} is a string" do - Puppet[:code] = "validate_array('#{the_string}')" - expect { scope.compiler.compile }.to raise_error(Puppet::ParseError, /is not an Array/) - end +describe 'validate_array' 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) } - it "should not compile when #{the_string} is a bare word" do - Puppet[:code] = "validate_array(#{the_string})" - expect { scope.compiler.compile }.to raise_error(Puppet::ParseError, /is not an Array/) - end + describe 'valid inputs' do + it { is_expected.to run.with_params([]) } + it { is_expected.to run.with_params(['one']) } + it { is_expected.to run.with_params([], ['two']) } + it { is_expected.to run.with_params(['one'], ['two']) } end - it "should compile when multiple array arguments are passed" do - Puppet[:code] = <<-'ENDofPUPPETcode' - $foo = [ ] - $bar = [ 'one', 'two' ] - validate_array($foo, $bar) - ENDofPUPPETcode - scope.compiler.compile - end - - it "should not compile when an undef variable is passed" do - Puppet[:code] = <<-'ENDofPUPPETcode' - $foo = undef - validate_array($foo) - ENDofPUPPETcode - expect { scope.compiler.compile }.to raise_error(Puppet::ParseError, /is not an Array/) + describe 'invalid inputs' do + it { is_expected.to run.with_params({}).and_raise_error(Puppet::ParseError, /is not an Array/) } + it { is_expected.to run.with_params(1).and_raise_error(Puppet::ParseError, /is not an Array/) } + it { is_expected.to run.with_params(true).and_raise_error(Puppet::ParseError, /is not an Array/) } + it { is_expected.to run.with_params('one').and_raise_error(Puppet::ParseError, /is not an Array/) } + it { is_expected.to run.with_params([], {}).and_raise_error(Puppet::ParseError, /is not an Array/) } + it { is_expected.to run.with_params([], 1).and_raise_error(Puppet::ParseError, /is not an Array/) } + it { is_expected.to run.with_params([], true).and_raise_error(Puppet::ParseError, /is not an Array/) } + it { is_expected.to run.with_params([], 'one').and_raise_error(Puppet::ParseError, /is not an Array/) } end end end + diff --git a/spec/functions/validate_augeas_spec.rb b/spec/functions/validate_augeas_spec.rb index 99523ab..4236649 100755 --- a/spec/functions/validate_augeas_spec.rb +++ b/spec/functions/validate_augeas_spec.rb @@ -1,49 +1,29 @@ -#! /usr/bin/env ruby -S rspec require 'spec_helper' -describe Puppet::Parser::Functions.function(:validate_augeas), :if => Puppet.features.augeas? do - let(:scope) { PuppetlabsSpec::PuppetInternals.scope } - - # The subject of these examplres is the method itself. - subject do - # This makes sure the function is loaded within each test - function_name = Puppet::Parser::Functions.function(:validate_augeas) - scope.method(function_name) - end - - context 'Using Puppet::Parser::Scope.new' do - - describe 'Garbage inputs' do - inputs = [ - [ nil ], - [ [ nil ] ], - [ { 'foo' => 'bar' } ], - [ { } ], - [ '' ], - [ "one", "one", "MSG to User", "4th arg" ], - ] - - inputs.each do |input| - it "validate_augeas(#{input.inspect}) should fail" do - expect { subject.call [input] }.to raise_error Puppet::ParseError - end - end +describe 'validate_augeas' do + unless Puppet.features.augeas? + skip "ruby-augeas not installed" + else + 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) } + it { is_expected.to run.with_params('').and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } + it { is_expected.to run.with_params('', '', [], '', 'extra').and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } + it { is_expected.to run.with_params('one', 'one', 'MSG to User', '4th arg').and_raise_error(NoMethodError) } end - describe 'Valid inputs' do + describe 'valid inputs' do inputs = [ [ "root:x:0:0:root:/root:/bin/bash\n", 'Passwd.lns' ], [ "proc /proc proc nodev,noexec,nosuid 0 0\n", 'Fstab.lns'], ] inputs.each do |input| - it "validate_augeas(#{input.inspect}) should not fail" do - expect { subject.call input }.not_to raise_error - end + it { is_expected.to run.with_params(*input) } end end - describe "Valid inputs which should raise an exception without a message" do + describe 'valid inputs which fail augeas validation' do # The intent here is to make sure valid inputs raise exceptions when they # don't specify an error message to display. This is the behvior in # 2.2.x and prior. @@ -53,13 +33,11 @@ describe Puppet::Parser::Functions.function(:validate_augeas), :if => Puppet.fea ] inputs.each do |input| - it "validate_augeas(#{input.inspect}) should fail" do - expect { subject.call input }.to raise_error /validate_augeas.*?matched less than it should/ - end + it { is_expected.to run.with_params(*input).and_raise_error(Puppet::ParseError, /validate_augeas.*?matched less than it should/) } end end - describe "Nicer Error Messages" do + describe "when specifying nice error messages" do # The intent here is to make sure the function returns the 4th argument # in the exception thrown inputs = [ @@ -68,35 +46,29 @@ describe Puppet::Parser::Functions.function(:validate_augeas), :if => Puppet.fea ] inputs.each do |input| - it "validate_augeas(#{input.inspect}) should fail" do - expect { subject.call input }.to raise_error /#{input[3]}/ - end + it { is_expected.to run.with_params(*input).and_raise_error(Puppet::ParseError, /#{input[3]}/) } end end - describe "Passing simple unit tests" do + describe "matching additional tests" do inputs = [ [ "root:x:0:0:root:/root:/bin/bash\n", 'Passwd.lns', ['$file/foobar']], [ "root:x:0:0:root:/root:/bin/bash\n", 'Passwd.lns', ['$file/root/shell[.="/bin/sh"]', 'foobar']], ] inputs.each do |input| - it "validate_augeas(#{input.inspect}) should fail" do - expect { subject.call input }.not_to raise_error - end + it { is_expected.to run.with_params(*input) } end end - describe "Failing simple unit tests" do + describe "failing additional tests" do inputs = [ [ "foobar:x:0:0:root:/root:/bin/bash\n", 'Passwd.lns', ['$file/foobar']], [ "root:x:0:0:root:/root:/bin/sh\n", 'Passwd.lns', ['$file/root/shell[.="/bin/sh"]', 'foobar']], ] inputs.each do |input| - it "validate_augeas(#{input.inspect}) should fail" do - expect { subject.call input }.to raise_error /testing path/ - end + it { is_expected.to run.with_params(*input).and_raise_error(Puppet::ParseError, /testing path/) } end end end diff --git a/spec/functions/validate_bool_spec.rb b/spec/functions/validate_bool_spec.rb index a352d3b..d9cdf57 100755 --- a/spec/functions/validate_bool_spec.rb +++ b/spec/functions/validate_bool_spec.rb @@ -1,51 +1,25 @@ -#! /usr/bin/env ruby -S rspec - require 'spec_helper' -describe Puppet::Parser::Functions.function(:validate_bool) do - let(:scope) { PuppetlabsSpec::PuppetInternals.scope } - describe 'when calling validate_bool from puppet' do - - %w{ true false }.each do |the_string| - - it "should not compile when #{the_string} is a string" do - Puppet[:code] = "validate_bool('#{the_string}')" - expect { scope.compiler.compile }.to raise_error(Puppet::ParseError, /is not a boolean/) - end - - it "should compile when #{the_string} is a bare word" do - Puppet[:code] = "validate_bool(#{the_string})" - scope.compiler.compile - end - - end - - it "should not compile when an arbitrary string is passed" do - Puppet[:code] = 'validate_bool("jeff and dan are awesome")' - expect { scope.compiler.compile }.to raise_error(Puppet::ParseError, /is not a boolean/) - end - - it "should not compile when no arguments are passed" do - Puppet[:code] = 'validate_bool()' - expect { scope.compiler.compile }.to raise_error(Puppet::ParseError, /wrong number of arguments/) - end +describe 'validate_bool' 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 - it "should compile when multiple boolean arguments are passed" do - Puppet[:code] = <<-'ENDofPUPPETcode' - $foo = true - $bar = false - validate_bool($foo, $bar, true, false) - ENDofPUPPETcode - scope.compiler.compile - end + describe 'acceptable values' do + it { is_expected.to run.with_params(true) } + it { is_expected.to run.with_params(false) } + it { is_expected.to run.with_params(true, false, false, true) } + end - it "should compile when multiple boolean arguments are passed" do - Puppet[:code] = <<-'ENDofPUPPETcode' - $foo = true - $bar = false - validate_bool($foo, $bar, true, false, 'jeff') - ENDofPUPPETcode - expect { scope.compiler.compile }.to raise_error(Puppet::ParseError, /is not a boolean/) - end + describe 'validation failures' do + it { is_expected.to run.with_params('one').and_raise_error(Puppet::ParseError, /is not a boolean/) } + it { is_expected.to run.with_params(true, 'one').and_raise_error(Puppet::ParseError, /is not a boolean/) } + it { is_expected.to run.with_params('one', false).and_raise_error(Puppet::ParseError, /is not a boolean/) } + it { is_expected.to run.with_params("true").and_raise_error(Puppet::ParseError, /is not a boolean/) } + it { is_expected.to run.with_params("false").and_raise_error(Puppet::ParseError, /is not a boolean/) } + it { is_expected.to run.with_params(true, "false").and_raise_error(Puppet::ParseError, /is not a boolean/) } + it { is_expected.to run.with_params("true", false).and_raise_error(Puppet::ParseError, /is not a boolean/) } + it { is_expected.to run.with_params("true", false, false, false, false, false).and_raise_error(Puppet::ParseError, /is not a boolean/) } end end diff --git a/spec/functions/validate_cmd_spec.rb b/spec/functions/validate_cmd_spec.rb index 7cb9782..ab0cbc9 100755 --- a/spec/functions/validate_cmd_spec.rb +++ b/spec/functions/validate_cmd_spec.rb @@ -1,85 +1,35 @@ -#! /usr/bin/env ruby -S rspec require 'spec_helper' -TESTEXE = File.exists?('/usr/bin/test') ? '/usr/bin/test' : '/bin/test' -TOUCHEXE = File.exists?('/usr/bin/touch') ? '/usr/bin/touch' : '/bin/touch' - -describe Puppet::Parser::Functions.function(:validate_cmd) do - let(:scope) { PuppetlabsSpec::PuppetInternals.scope } - - subject do - function_name = Puppet::Parser::Functions.function(:validate_cmd) - scope.method(function_name) +describe 'validate_cmd' do + let(:touch) { File.exists?('/usr/bin/touch') ? '/usr/bin/touch' : '/bin/touch' } + + 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) } + it { is_expected.to run.with_params('').and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } + it { is_expected.to run.with_params('', '', '', 'extra').and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } + it { + pending('should implement stricter type checking') + is_expected.to run.with_params([], '', '').and_raise_error(Puppet::ParseError, /content must be a string/) + } + it { + pending('should implement stricter type checking') + is_expected.to run.with_params('', [], '').and_raise_error(Puppet::ParseError, /checkscript must be a string/) + } + it { + pending('should implement stricter type checking') + is_expected.to run.with_params('', '', []).and_raise_error(Puppet::ParseError, /custom error message must be a string/) + } end - context 'with no % placeholder' do - describe "with an explicit failure message" do - it "prints the failure message on error" do - expect { - subject.call ['', '/bin/false', 'failure message!'] - }.to raise_error Puppet::ParseError, /failure message!/ - end - end - - describe "on validation failure" do - it "includes the command error output" do - expect { - subject.call ['', "#{TOUCHEXE} /cant/touch/this"] - }.to raise_error Puppet::ParseError, /(cannot touch|o such file or)/ - end - - it "includes the command return value" do - expect { - subject.call ['', '/cant/run/this'] - }.to raise_error Puppet::ParseError, /returned 1\b/ - end - end - - describe "when performing actual validation" do - it "can positively validate file content" do - expect { subject.call ["non-empty", "#{TESTEXE} -s"] }.to_not raise_error - end - - it "can negatively validate file content" do - expect { - subject.call ["", "#{TESTEXE} -s"] - }.to raise_error Puppet::ParseError, /failed to validate.*test -s/ - end + context 'when validation fails' do + context 'with % placeholder' do + it { is_expected.to run.with_params('', "#{touch} % /no/such/file").and_raise_error(Puppet::ParseError, /Execution of '#{touch} \S+ \/no\/such\/file' returned 1:.*(cannot touch|o such file or)/) } + it { is_expected.to run.with_params('', "#{touch} % /no/such/file", 'custom error').and_raise_error(Puppet::ParseError, /custom error/) } end - end - - context 'with % placeholder' do - describe "with an explicit failure message" do - it "prints the failure message on error" do - expect { - subject.call ['', '/bin/false % -f', 'failure message!'] - }.to raise_error Puppet::ParseError, /failure message!/ - end - end - describe "on validation failure" do - it "includes the command error output" do - expect { - subject.call ['', "#{TOUCHEXE} /cant/touch/this"] - }.to raise_error Puppet::ParseError, /(cannot touch|o such file or)/ - end - - it "includes the command return value" do - expect { - subject.call ['', '/cant/run/this % -z'] - }.to raise_error Puppet::ParseError, /Execution of '\/cant\/run\/this .+ -z' returned 1/ - end - end - - describe "when performing actual validation" do - it "can positively validate file content" do - expect { subject.call ["non-empty", "#{TESTEXE} -s %"] }.to_not raise_error - end - - it "can negatively validate file content" do - expect { - subject.call ["", "#{TESTEXE} -s %"] - }.to raise_error Puppet::ParseError, /failed to validate.*test -s/ - end + context 'without % placeholder' do + it { is_expected.to run.with_params('', "#{touch} /no/such/file").and_raise_error(Puppet::ParseError, /Execution of '#{touch} \/no\/such\/file \S+' returned 1:.*(cannot touch|o such file or)/) } + it { is_expected.to run.with_params('', "#{touch} /no/such/file", 'custom error').and_raise_error(Puppet::ParseError, /custom error/) } end end end diff --git a/spec/functions/validate_hash_spec.rb b/spec/functions/validate_hash_spec.rb index a0c35c2..2e8e59f 100755 --- a/spec/functions/validate_hash_spec.rb +++ b/spec/functions/validate_hash_spec.rb @@ -1,43 +1,26 @@ -#! /usr/bin/env ruby -S rspec - require 'spec_helper' -describe Puppet::Parser::Functions.function(:validate_hash) do - let(:scope) { PuppetlabsSpec::PuppetInternals.scope } - - describe 'when calling validate_hash from puppet' do - - %w{ true false }.each do |the_string| - - it "should not compile when #{the_string} is a string" do - Puppet[:code] = "validate_hash('#{the_string}')" - expect { scope.compiler.compile }.to raise_error(Puppet::ParseError, /is not a Hash/) - end - - it "should not compile when #{the_string} is a bare word" do - Puppet[:code] = "validate_hash(#{the_string})" - expect { scope.compiler.compile }.to raise_error(Puppet::ParseError, /is not a Hash/) - end +describe 'validate_hash' 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) } + describe 'valid inputs' do + it { is_expected.to run.with_params({}) } + it { is_expected.to run.with_params({'key' => 'value'}) } + it { is_expected.to run.with_params({}, {'key' => 'value'}) } + it { is_expected.to run.with_params({'key1' => 'value1'}, {'key2' => 'value2'}) } end - it "should compile when multiple hash arguments are passed" do - Puppet[:code] = <<-'ENDofPUPPETcode' - $foo = {} - $bar = { 'one' => 'two' } - validate_hash($foo, $bar) - ENDofPUPPETcode - scope.compiler.compile + describe 'invalid inputs' do + it { is_expected.to run.with_params([]).and_raise_error(Puppet::ParseError, /is not a Hash/) } + it { is_expected.to run.with_params(1).and_raise_error(Puppet::ParseError, /is not a Hash/) } + it { is_expected.to run.with_params(true).and_raise_error(Puppet::ParseError, /is not a Hash/) } + it { is_expected.to run.with_params('one').and_raise_error(Puppet::ParseError, /is not a Hash/) } + it { is_expected.to run.with_params({}, []).and_raise_error(Puppet::ParseError, /is not a Hash/) } + it { is_expected.to run.with_params({}, 1).and_raise_error(Puppet::ParseError, /is not a Hash/) } + it { is_expected.to run.with_params({}, true).and_raise_error(Puppet::ParseError, /is not a Hash/) } + it { is_expected.to run.with_params({}, 'one').and_raise_error(Puppet::ParseError, /is not a Hash/) } end - - it "should not compile when an undef variable is passed" do - Puppet[:code] = <<-'ENDofPUPPETcode' - $foo = undef - validate_hash($foo) - ENDofPUPPETcode - expect { scope.compiler.compile }.to raise_error(Puppet::ParseError, /is not a Hash/) - end - end - end diff --git a/spec/functions/validate_integer_spec.rb b/spec/functions/validate_integer_spec.rb index e95da6a..4c0a9d7 100755 --- a/spec/functions/validate_integer_spec.rb +++ b/spec/functions/validate_integer_spec.rb @@ -1,224 +1,90 @@ -#! /usr/bin/env ruby -S rspec - require 'spec_helper' -describe Puppet::Parser::Functions.function(:validate_integer) do - let(:scope) { PuppetlabsSpec::PuppetInternals.scope } - - describe 'when calling validate_integer from puppet without any argument or to many' do - it "should not compile when no argument is passed" do - Puppet[:code] = "validate_integer()" - expect { scope.compiler.compile }.to raise_error(Puppet::ParseError, /Wrong number of arguments/) - end - it "should not compile when more than three arguments are passed" do - Puppet[:code] = "validate_integer(1, 1, 1, 1)" - expect { scope.compiler.compile }.to raise_error(Puppet::ParseError, /Wrong number of arguments/) - end - end - - describe 'when calling validate_integer from puppet only with input' do - %w{ 1 -1 }.each do |the_number| - it "should compile when #{the_number} is an encapsulated integer" do - Puppet[:code] = "validate_integer('#{the_number}')" - scope.compiler.compile - end - it "should compile when #{the_number} is an bare integer" do - Puppet[:code] = "validate_integer(#{the_number})" - scope.compiler.compile - end - end - - %w{ [1,2,3,4,5] ['1','2','3','4','5'] }.each do |the_number| - it "should compile when multiple Integer arguments are passed in an Array" do - Puppet[:code] = "validate_integer(#{the_number})" - scope.compiler.compile - end - end - - %w{ true false iAmAString 1test 7.0 -7.0 }.each do |the_number| - it "should not compile when #{the_number} is in a string" do - Puppet[:code] = "validate_integer('#{the_number}')" - expect { scope.compiler.compile }.to raise_error(Puppet::ParseError, /to be an Integer/) - end - - it "should not compile when #{the_number} is a bare word" do - Puppet[:code] = "validate_integer(#{the_number})" - expect { scope.compiler.compile }.to raise_error - end - end - - it "should not compile when an Integer is part of a larger String" do - Puppet[:code] = "validate_integer('1 test')" - expect { scope.compiler.compile }.to raise_error(Puppet::ParseError, /to be an Integer/) - end +describe 'validate_integer' 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) } + it { is_expected.to run.with_params(1, 2, 3, 4).and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } - it "should not compile when an Array with a non-Integer value is passed" do - Puppet[:code] = "validate_integer([1, '-7.0'])" - expect { scope.compiler.compile }.to raise_error(Puppet::ParseError, /at array position 1 to be an Integer/) + [ true, 'true', false, 'false', 'iAmAString', '1test', '1 test', 'test 1', 'test 1 test', 7.0, -7.0, {}, { 'key' => 'value' }, { 1=> 2 }, '', :undef , 'x'].each do |invalid| + it { is_expected.to run.with_params(invalid).and_raise_error(Puppet::ParseError, /to be an Integer/) } + it { is_expected.to run.with_params(invalid, 10).and_raise_error(Puppet::ParseError, /to be an Integer/) } + it { is_expected.to run.with_params(invalid, 10, -10).and_raise_error(Puppet::ParseError, /to be an Integer/) } + it { is_expected.to run.with_params([0, 1, 2, invalid, 3, 4], 10, -10).and_raise_error(Puppet::ParseError, /to be an Integer/) } end - it "should not compile when a Hash is passed" do - Puppet[:code] = "validate_integer({ 1 => 2 })" - expect { scope.compiler.compile }.to raise_error(Puppet::ParseError, /to be an Integer or Array/) + context 'when running on modern rubies', :unless => RUBY_VERSION == '1.8.7' do + it { is_expected.to run.with_params([0, 1, 2, {1=>2}, 3, 4], 10, -10).and_raise_error(Puppet::ParseError, /to be an Integer/) } end - it "should not compile when a Hash is passed as Array" do - Puppet[:code] = "validate_integer([{ 1 => 2 }])" - expect { scope.compiler.compile }.to raise_error(Puppet::ParseError, /to be an Integer/) + context 'when running on ruby, which munges hashes weirdly', :if => RUBY_VERSION == '1.8.7' do + it { is_expected.to run.with_params([0, 1, 2, {1=>2}, 3, 4], 10, -10).and_raise_error(Puppet::ParseError) } + it { is_expected.to run.with_params([0, 1, 2, {0=>2}, 3, 4], 10, -10).and_raise_error(Puppet::ParseError) } end - it "should not compile when an explicitly undef variable is passed" do - Puppet[:code] = <<-'ENDofPUPPETcode' - $foo = undef - validate_integer($foo) - ENDofPUPPETcode - expect { scope.compiler.compile }.to raise_error(Puppet::ParseError, /to be an Integer/) - end + it { is_expected.to run.with_params(1, '').and_raise_error(Puppet::ParseError, /to be unset or an Integer/) } + it { is_expected.to run.with_params(1, 2, '').and_raise_error(Puppet::ParseError, /to be unset or an Integer/) } + it { is_expected.to run.with_params(1, 2, 3).and_raise_error(Puppet::ParseError, /second argument to be larger than third argument/) } + end - it "should not compile when an undefined variable is passed" do - Puppet[:code] = <<-'ENDofPUPPETcode' - validate_integer($foobarbazishouldnotexist) - ENDofPUPPETcode - expect { scope.compiler.compile }.to raise_error(Puppet::ParseError, /to be an Integer/) - end + context 'with no range constraints' do + it { is_expected.to run.with_params(1) } + it { is_expected.to run.with_params(-1) } + it { is_expected.to run.with_params('1') } + it { is_expected.to run.with_params('-1') } + it { is_expected.to run.with_params([1, 2, 3, 4]) } + it { is_expected.to run.with_params([1, '2', '3', 4]) } end - describe 'when calling validate_integer from puppet with input and a maximum' do - max = 10 - %w{ 1 -1 }.each do |the_number| - it "should compile when #{the_number} is lower than a maximum of #{max}" do - Puppet[:code] = "validate_integer(#{the_number},#{max})" - scope.compiler.compile + context "with a maximum limit of 10" do + describe 'rejects numbers greater than the limit' do + it { is_expected.to run.with_params(11, 10).and_raise_error(Puppet::ParseError, /to be smaller or equal/) } + it { is_expected.to run.with_params(100, 10).and_raise_error(Puppet::ParseError, /to be smaller or equal/) } + it { is_expected.to run.with_params(2**65, 10).and_raise_error(Puppet::ParseError, /to be smaller or equal/) } + it { is_expected.to run.with_params([1,2,10,100], 10).and_raise_error(Puppet::ParseError, /to be smaller or equal/) } + end + + describe 'accepts numbers less or equal to the limit' do + it { is_expected.to run.with_params(10, 10) } + it { is_expected.to run.with_params(1, 10) } + it { is_expected.to run.with_params(-1, 10) } + it { is_expected.to run.with_params('1', 10) } + it { is_expected.to run.with_params('-1', 10) } + it { is_expected.to run.with_params([1, 2, 3, 4], 10) } + it { is_expected.to run.with_params([1, '2', '3', 4], 10) } + end + + context "with a minimum limit of -10" do + describe 'rejects numbers greater than the upper limit' do + it { is_expected.to run.with_params(11, 10, -10).and_raise_error(Puppet::ParseError, /to be smaller or equal/) } + it { is_expected.to run.with_params(100, 10, -10).and_raise_error(Puppet::ParseError, /to be smaller or equal/) } + it { is_expected.to run.with_params(2**65, 10, -10).and_raise_error(Puppet::ParseError, /to be smaller or equal/) } + it { is_expected.to run.with_params([1,2,10,100], 10, -10).and_raise_error(Puppet::ParseError, /to be smaller or equal/) } end - end - it "should compile when an Integer is equal the maximum" do - Puppet[:code] = "validate_integer(#{max},#{max})" - scope.compiler.compile - end - - it "should not compile when #{max+1} is greater than a maximum of #{max}" do - Puppet[:code] = "validate_integer(#{max+1},#{max})" - expect { scope.compiler.compile }.to raise_error(Puppet::ParseError, /to be smaller or equal to/) - end - - %w{ [-10,1,2,3,4,5,10] ['-10','1','2','3','4','5','10'] }.each do |the_number| - it "should compile when each element of #{the_number} is lower than a maximum of #{max}" do - Puppet[:code] = "validate_integer(#{the_number},#{max})" - scope.compiler.compile + describe 'rejects numbers smaller than the lower limit' do + it { is_expected.to run.with_params(-11, 10, -10).and_raise_error(Puppet::ParseError, /to be greater or equal/) } + it { is_expected.to run.with_params(-100, 10, -10).and_raise_error(Puppet::ParseError, /to be greater or equal/) } + it { is_expected.to run.with_params(-2**65, 10, -10).and_raise_error(Puppet::ParseError, /to be greater or equal/) } + it { is_expected.to run.with_params([-10, 1,2,10,-100], 10, -10).and_raise_error(Puppet::ParseError, /to be greater or equal/) } end - end - - it "should not compile when an element of an Array [-10,1,2,3,4,5,#{max+1}] is greater than a maximum of #{max}" do - Puppet[:code] = "validate_integer([-10,1,2,3,4,5,#{max+1}],#{max})" - expect { scope.compiler.compile }.to raise_error(Puppet::ParseError, /to be smaller or equal to/) - end - %w{ true false iAmAString 1test 7.0 -7.0 }.each do |the_max| - it "should not compile when a non-Integer maximum #{the_max}, encapsulated in a String, is passed" do - Puppet[:code] = "validate_integer(1,'#{the_max}')" - expect { scope.compiler.compile }.to raise_error(Puppet::ParseError, /to be unset or an Integer/) + describe 'accepts numbers between and including the limits' do + it { is_expected.to run.with_params(10, 10, -10) } + it { is_expected.to run.with_params(-10, 10, -10) } + it { is_expected.to run.with_params(1, 10, -10) } + it { is_expected.to run.with_params(-1, 10, -10) } + it { is_expected.to run.with_params('1', 10, -10) } + it { is_expected.to run.with_params('-1', 10, -10) } + it { is_expected.to run.with_params([1, 2, 3, 4], 10, -10) } + it { is_expected.to run.with_params([1, '2', '3', 4], 10, -10) } end - - it "should not compile when a non-Integer maximum #{the_max} bare word is passed" do - Puppet[:code] = "validate_integer(1,#{the_max})" - expect { scope.compiler.compile }.to raise_error - end - end - - it "should not compile when an explicitly undefined variable is passed as maximum and no minimum is passed" do - Puppet[:code] = <<-'ENDofPUPPETcode' - $foo = undef - validate_integer(10, $foo) - ENDofPUPPETcode - expect { scope.compiler.compile }.to raise_error(Puppet::ParseError, /to be unset or an Integer/) - end - it "should not compile when an explicitly undef is passed as maximum and no minimum is passed" do - Puppet[:code] = "validate_integer(10, undef)" - expect { scope.compiler.compile }.to raise_error(Puppet::ParseError, /to be unset or an Integer/) - end - it "should not compile when an empty string is passed as maximum and no minimum is passed" do - Puppet[:code] = "validate_integer(10, '')" - expect { scope.compiler.compile }.to raise_error(Puppet::ParseError, /to be unset or an Integer/) - end - it "should not compile when an undefined variable for a maximum is passed" do - Puppet[:code] = "validate_integer(10, $foobarbazishouldnotexist)" - expect { scope.compiler.compile }.to raise_error(Puppet::ParseError, /to be unset or an Integer/) end end - describe 'when calling validate_integer from puppet with input, a maximum and a minimum' do - it "should not compile when a minimum larger than maximum is passed" do - Puppet[:code] = "validate_integer(1,1,2)" - expect { scope.compiler.compile }.to raise_error(Puppet::ParseError, /second argument to be larger than third argument/) - end + it { is_expected.to run.with_params(10, 10, 10) } - max = 10 - min = -10 - %w{ 1 -1 }.each do |the_number| - it "should compile when each element of #{the_number} is within a range from #{min} to #{max}" do - Puppet[:code] = "validate_integer(#{the_number},#{max},#{min})" - scope.compiler.compile - end - end - - it "should compile when an Integer is equal the minimum" do - Puppet[:code] = "validate_integer(#{min},#{max},#{min})" - scope.compiler.compile - end - - it "should compile when an Integer is equal the minimum and maximum" do - Puppet[:code] = "validate_integer(#{max},#{max},#{max})" - scope.compiler.compile - end - - it "should compile when an empty maximum is passed and the Integer is greater than the minimum" do - Puppet[:code] = "validate_integer(#{max},'',#{min})" - scope.compiler.compile - end - it "should compile when an explicitly undefined maximum is passed and the Integer is greater than the minimum" do - Puppet[:code] = "validate_integer(#{max},undef,#{min})" - scope.compiler.compile - end - it "should compile when an explicitly undefined variable is passed for maximum and the Integer is greater than the minimum" do - Puppet[:code] = <<-"ENDofPUPPETcode" - $foo = undef - validate_integer(#{max}, $foo, #{min}) - ENDofPUPPETcode - scope.compiler.compile - end - it "should not compile when no maximum value is given and the Integer is greater than the minimum" do - Puppet[:code] = "validate_integer(#{max},,#{min})" - expect { scope.compiler.compile }.to raise_error(Puppet::Error, /Syntax error at ','/) - end - - it "should not compile when #{min-1} is lower than a minimum of #{min}" do - Puppet[:code] = "validate_integer(#{min-1},#{max},#{min})" - expect { scope.compiler.compile }.to raise_error(Puppet::ParseError, /to be greater or equal to/) - end - - %w{ [-10,1,2,3,4,5,10] ['-10','1','2','3','4','5','10'] }.each do |the_number| - it "should compile when each element of #{the_number} is within a range from #{min} to #{max}" do - Puppet[:code] = "validate_integer(#{the_number},#{max},#{min})" - scope.compiler.compile - end - end - - it "should not compile when an element of an Array [#{min-1},1,2,3,4,5,10] is lower than a minimum of #{min}" do - Puppet[:code] = "validate_integer([#{min-1},1,2,3,4,5,10],#{max},#{min})" - expect { scope.compiler.compile }.to raise_error(Puppet::ParseError, /to be greater or equal to/) - end - - %w{ true false iAmAString 1test 7.0 -7.0 }.each do |the_min| - it "should not compile when a non-Integer minimum #{the_min}, encapsulated in a String, is passed" do - Puppet[:code] = "validate_integer(1,#{max},'#{the_min}')" - expect { scope.compiler.compile }.to raise_error(Puppet::ParseError, /to be unset or an Integer/) - end - - it "should not compile when a non-Integer minimum #{the_min} bare word is passed" do - Puppet[:code] = "validate_integer(1,#{max},#{the_min})" - expect { scope.compiler.compile }.to raise_error - end - end + describe 'empty upper limit is interpreted as infinity' do + it { is_expected.to run.with_params(11, '', 10) } end end diff --git a/spec/functions/validate_ipv4_address_spec.rb b/spec/functions/validate_ipv4_address_spec.rb index 27ea4fe..b6170d4 100755 --- a/spec/functions/validate_ipv4_address_spec.rb +++ b/spec/functions/validate_ipv4_address_spec.rb @@ -1,62 +1,40 @@ -#! /usr/bin/env ruby -S rspec - -require "spec_helper" - -describe Puppet::Parser::Functions.function(:validate_ipv4_address) do - let(:scope) { PuppetlabsSpec::PuppetInternals.scope } - - describe "when calling validate_ipv4_address from puppet" do - describe "when given IPv4 address strings" do - it "should compile with one argument" do - Puppet[:code] = "validate_ipv4_address('1.2.3.4')" - scope.compiler.compile - end - - it "should compile with multiple arguments" do - Puppet[:code] = "validate_ipv4_address('1.2.3.4', '5.6.7.8')" - scope.compiler.compile - end - end - - describe "when given an IPv6 address" do - it "should not compile" do - Puppet[:code] = "validate_ipv4_address('3ffe:505')" - expect { - scope.compiler.compile - }.to raise_error(Puppet::ParseError, /not a valid IPv4 address/) - end - end - - describe "when given other strings" do - it "should not compile" do - Puppet[:code] = "validate_ipv4_address('hello', 'world')" - expect { - scope.compiler.compile - }.to raise_error(Puppet::ParseError, /not a valid IPv4 address/) - end - end - - describe "when given numbers" do - it "should not compile" do - Puppet[:code] = "validate_ipv4_address(1, 2)" - expect { scope.compiler.compile }.to raise_error - end - end - - describe "when given booleans" do - it "should not compile" do - Puppet[:code] = "validate_ipv4_address(true, false)" - expect { - scope.compiler.compile - }.to raise_error(Puppet::ParseError, /is not a string/) +require 'spec_helper' + +describe 'validate_ipv4_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) } + + describe 'valid inputs' do + it { is_expected.to run.with_params('0.0.0.0') } + it { is_expected.to run.with_params('8.8.8.8') } + it { is_expected.to run.with_params('127.0.0.1') } + it { is_expected.to run.with_params('10.10.10.10') } + it { is_expected.to run.with_params('194.232.104.150') } + it { is_expected.to run.with_params('244.24.24.24') } + it { is_expected.to run.with_params('255.255.255.255') } + it { is_expected.to run.with_params('1.2.3.4', '5.6.7.8') } + context 'with netmasks' do + it { is_expected.to run.with_params('8.8.8.8/0') } + it { is_expected.to run.with_params('8.8.8.8/16') } + it { is_expected.to run.with_params('8.8.8.8/32') } + it { is_expected.to run.with_params('8.8.8.8/255.255.0.0') } end end - it "should not compile when no arguments are passed" do - Puppet[:code] = "validate_ipv4_address()" - expect { - scope.compiler.compile - }.to raise_error(Puppet::ParseError, /wrong number of arguments/) + 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 IPv4/) } + it { is_expected.to run.with_params('0.0.0').and_raise_error(Puppet::ParseError, /is not a valid IPv4/) } + it { is_expected.to run.with_params('0.0.0.256').and_raise_error(Puppet::ParseError, /is not a valid IPv4/) } + it { is_expected.to run.with_params('0.0.0.0.0').and_raise_error(Puppet::ParseError, /is not a valid IPv4/) } + it { is_expected.to run.with_params('affe::beef').and_raise_error(Puppet::ParseError, /is not a valid IPv4/) } + it { is_expected.to run.with_params('1.2.3.4', {}).and_raise_error(Puppet::ParseError, /is not a string/) } + it { is_expected.to run.with_params('1.2.3.4', 1).and_raise_error(Puppet::ParseError, /is not a string/) } + it { is_expected.to run.with_params('1.2.3.4', true).and_raise_error(Puppet::ParseError, /is not a string/) } + it { is_expected.to run.with_params('1.2.3.4', 'one').and_raise_error(Puppet::ParseError, /is not a valid IPv4/) } end end end diff --git a/spec/functions/validate_ipv6_address_spec.rb b/spec/functions/validate_ipv6_address_spec.rb index e87b372..7aaf006 100755 --- a/spec/functions/validate_ipv6_address_spec.rb +++ b/spec/functions/validate_ipv6_address_spec.rb @@ -1,65 +1,32 @@ -#! /usr/bin/env ruby -S rspec - -require "spec_helper" - -describe Puppet::Parser::Functions.function(:validate_ipv6_address) do - let(:scope) { PuppetlabsSpec::PuppetInternals.scope } - - describe "when calling validate_ipv6_address from puppet" do - describe "when given IPv6 address strings" do - it "should compile with one argument" do - Puppet[:code] = "validate_ipv6_address('3ffe:0505:0002::')" - scope.compiler.compile - end - - it "should compile with multiple arguments" do - Puppet[:code] = "validate_ipv6_address('3ffe:0505:0002::', '3ffe:0505:0001::')" - scope.compiler.compile - end - end - - describe "when given an ipv4 address" do - it "should not compile" do - Puppet[:code] = "validate_ipv6_address('1.2.3.4')" - expect { - scope.compiler.compile - }.to raise_error(Puppet::ParseError, /not a valid IPv6 address/) - end +require 'spec_helper' + +describe 'validate_ipv6_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) } + + describe 'valid inputs' do + it { is_expected.to run.with_params('3ffe:0505:0002::') } + it { is_expected.to run.with_params('3ffe:0505:0002::', '3ffe:0505:0002::2') } + it { is_expected.to run.with_params('::1/64') } + it { is_expected.to run.with_params('fe80::a00:27ff:fe94:44d6/64') } end - describe "when given other strings" do - it "should not compile" do - Puppet[:code] = "validate_ipv6_address('hello', 'world')" - expect { - scope.compiler.compile - }.to raise_error(Puppet::ParseError, /not a valid IPv6 address/) + 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(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 IPv6/) } + it { is_expected.to run.with_params('0.0.0').and_raise_error(Puppet::ParseError, /is not a valid IPv6/) } + it { is_expected.to run.with_params('0.0.0.256').and_raise_error(Puppet::ParseError, /is not a valid IPv6/) } + it { is_expected.to run.with_params('0.0.0.0.0').and_raise_error(Puppet::ParseError, /is not a valid IPv6/) } + it { is_expected.to run.with_params('affe:beef').and_raise_error(Puppet::ParseError, /is not a valid IPv6/) } + it { is_expected.to run.with_params('::1', {}).and_raise_error(Puppet::ParseError, /is not a string/) } + it { is_expected.to run.with_params('::1', true).and_raise_error(Puppet::ParseError, /is not a string/) } + it { is_expected.to run.with_params('::1', 'one').and_raise_error(Puppet::ParseError, /is not a valid IPv6/) } + context 'unless running on ruby 1.8.7', :if => RUBY_VERSION != '1.8.7' do + it { is_expected.to run.with_params(1).and_raise_error(Puppet::ParseError, /is not a string/) } + it { is_expected.to run.with_params('::1', 1).and_raise_error(Puppet::ParseError, /is not a string/) } end end - - # 1.8.7 is EOL'd and also absolutely insane about ipv6 - unless RUBY_VERSION == '1.8.7' - describe "when given numbers" do - it "should not compile" do - Puppet[:code] = "validate_ipv6_address(1, 2)" - expect { scope.compiler.compile }.to raise_error - end - end - end - - describe "when given booleans" do - it "should not compile" do - Puppet[:code] = "validate_ipv6_address(true, false)" - expect { - scope.compiler.compile - }.to raise_error(Puppet::ParseError, /is not a string/) - end - end - - it "should not compile when no arguments are passed" do - Puppet[:code] = "validate_ipv6_address()" - expect { - scope.compiler.compile - }.to raise_error(Puppet::ParseError, /wrong number of arguments/) - end end end diff --git a/spec/functions/validate_numeric_spec.rb b/spec/functions/validate_numeric_spec.rb index c99d879..9b8eb0e 100755 --- a/spec/functions/validate_numeric_spec.rb +++ b/spec/functions/validate_numeric_spec.rb @@ -1,222 +1,89 @@ -#! /usr/bin/env ruby -S rspec - require 'spec_helper' -describe Puppet::Parser::Functions.function(:validate_numeric) do - let(:scope) { PuppetlabsSpec::PuppetInternals.scope } - - describe 'when calling validate_numeric from puppet without any argument or to many' do - it "should not compile when no argument is passed" do - Puppet[:code] = "validate_numeric()" - expect { scope.compiler.compile }.to raise_error(Puppet::ParseError, /Wrong number of arguments/) - end - it "should not compile when more than three arguments are passed" do - Puppet[:code] = "validate_numeric(1, 1, 1, 1)" - expect { scope.compiler.compile }.to raise_error(Puppet::ParseError, /Wrong number of arguments/) - end - end - - describe 'when calling validate_numeric from puppet only with input' do - %w{ 1 -1 1.0 -1.0 }.each do |the_number| - it "should compile when #{the_number} is an encapsulated numeric" do - Puppet[:code] = "validate_numeric('#{the_number}')" - scope.compiler.compile - end - it "should compile when #{the_number} is a bare numeric" do - Puppet[:code] = "validate_numeric(#{the_number})" - scope.compiler.compile - end - end - - %w{ [1,2,3,4,5] ['1','2','3','4','5'] [1.1,2.2,3.3,4.4,5.5] ['1.1','2.2','3.3','4.4','5.5'] }.each do |the_number| - it "should compile when multiple Numeric arguments are passed in an Array" do - Puppet[:code] = "validate_numeric(#{the_number})" - scope.compiler.compile - end - end - - %w{ true false iAmAString 1test }.each do |the_number| - it "should not compile when #{the_number} is in a string" do - Puppet[:code] = "validate_numeric('#{the_number}')" - expect { scope.compiler.compile }.to raise_error(Puppet::ParseError, /to be a Numeric/) - end - - it "should not compile when #{the_number} is a bare word" do - Puppet[:code] = "validate_numeric(#{the_number})" - expect { scope.compiler.compile }.to raise_error - end - end - - it "should not compile when a Numeric is part of a larger String" do - Puppet[:code] = "validate_numeric('1.0 test')" - expect { scope.compiler.compile }.to raise_error(Puppet::ParseError, /to be a Numeric/) - end +describe 'validate_numeric' 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) } + it { is_expected.to run.with_params(1, 2, 3, 4).and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } - it "should not compile when an Array with a non-Numeric value is passed" do - Puppet[:code] = "validate_numeric([1, 'test'])" - expect { scope.compiler.compile }.to raise_error(Puppet::ParseError, /at array position 1 to be a Numeric/) + [ true, 'true', false, 'false', 'iAmAString', '1test', '1 test', 'test 1', 'test 1 test', {}, { 'key' => 'value' }, { 1=> 2 }, '', :undef , 'x'].each do |invalid| + it { is_expected.to run.with_params(invalid).and_raise_error(Puppet::ParseError, /to be a Numeric/) } + it { is_expected.to run.with_params(invalid, 10.0).and_raise_error(Puppet::ParseError, /to be a Numeric/) } + it { is_expected.to run.with_params(invalid, 10.0, -10.0).and_raise_error(Puppet::ParseError, /to be a Numeric/) } end - it "should not compile when a Hash is passed" do - Puppet[:code] = "validate_numeric({ 1 => 2 })" - expect { scope.compiler.compile }.to raise_error(Puppet::ParseError, /to be a Numeric or Array/) + context 'when running on modern rubies', :unless => RUBY_VERSION == '1.8.7' do + it { is_expected.to run.with_params([0, 1, 2, {1=>2}, 3, 4], 10, -10).and_raise_error(Puppet::ParseError, /to be a Numeric/) } end - it "should not compile when a Hash is passed in an Array" do - Puppet[:code] = "validate_numeric([{ 1 => 2 }])" - expect { scope.compiler.compile }.to raise_error(Puppet::ParseError, /to be a Numeric/) + context 'when running on ruby, which munges hashes weirdly', :if => RUBY_VERSION == '1.8.7' do + it { is_expected.to run.with_params([0, 1, 2, {1=>2}, 3, 4], 10, -10).and_raise_error(Puppet::ParseError) } + it { is_expected.to run.with_params([0, 1, 2, {0=>2}, 3, 4], 10, -10).and_raise_error(Puppet::ParseError) } end - it "should not compile when an explicitly undef variable is passed" do - Puppet[:code] = <<-'ENDofPUPPETcode' - $foo = undef - validate_numeric($foo) - ENDofPUPPETcode - expect { scope.compiler.compile }.to raise_error(Puppet::ParseError, /to be a Numeric/) - end + it { is_expected.to run.with_params(1, '').and_raise_error(Puppet::ParseError, /to be unset or a Numeric/) } + it { is_expected.to run.with_params(1, 2, '').and_raise_error(Puppet::ParseError, /to be unset or a Numeric/) } + it { is_expected.to run.with_params(1, 2, 3).and_raise_error(Puppet::ParseError, /second argument to be larger than third argument/) } + end - it "should not compile when an undefined variable is passed" do - Puppet[:code] = 'validate_numeric($foobarbazishouldnotexist)' - expect { scope.compiler.compile }.to raise_error(Puppet::ParseError, /to be a Numeric/) - end + context 'with no range constraints' do + it { is_expected.to run.with_params(1) } + it { is_expected.to run.with_params(-1) } + it { is_expected.to run.with_params('1') } + it { is_expected.to run.with_params('-1') } + it { is_expected.to run.with_params([1, 2, 3, 4]) } + it { is_expected.to run.with_params([1, '2', '3', 4]) } end - describe 'when calling validate_numeric from puppet with input and a maximum' do - max = 10 - %w{ 1 -1 1.0 -1.0 }.each do |the_number| - it "should compile when #{the_number} is lower than a maximum of #{max}" do - Puppet[:code] = "validate_numeric(#{the_number},#{max})" - scope.compiler.compile + context "with a maximum limit of 10.0" do + describe 'rejects numbers greater than the limit' do + it { is_expected.to run.with_params(11, 10.0).and_raise_error(Puppet::ParseError, /to be smaller or equal/) } + it { is_expected.to run.with_params(100, 10.0).and_raise_error(Puppet::ParseError, /to be smaller or equal/) } + it { is_expected.to run.with_params(2**65, 10.0).and_raise_error(Puppet::ParseError, /to be smaller or equal/) } + it { is_expected.to run.with_params([1,2,10.0,100], 10.0).and_raise_error(Puppet::ParseError, /to be smaller or equal/) } + end + + describe 'accepts numbers less or equal to the limit' do + it { is_expected.to run.with_params(10.0, 10.0) } + it { is_expected.to run.with_params(1, 10.0) } + it { is_expected.to run.with_params(-1, 10.0) } + it { is_expected.to run.with_params('1', 10.0) } + it { is_expected.to run.with_params('-1', 10.0) } + it { is_expected.to run.with_params([1, 2, 3, 4], 10.0) } + it { is_expected.to run.with_params([1, '2', '3', 4], 10.0) } + end + + context "with a minimum limit of -10.0" do + describe 'rejects numbers greater than the upper limit' do + it { is_expected.to run.with_params(11, 10.0, -10.0).and_raise_error(Puppet::ParseError, /to be smaller or equal/) } + it { is_expected.to run.with_params(100, 10.0, -10.0).and_raise_error(Puppet::ParseError, /to be smaller or equal/) } + it { is_expected.to run.with_params(2**65, 10.0, -10.0).and_raise_error(Puppet::ParseError, /to be smaller or equal/) } + it { is_expected.to run.with_params([1,2,10.0,100], 10.0, -10.0).and_raise_error(Puppet::ParseError, /to be smaller or equal/) } end - end - it "should compile when a Numeric is equal the maximum" do - Puppet[:code] = "validate_numeric(#{max},#{max})" - scope.compiler.compile - end - - it "should not compile when #{max+1} is greater than a maximum of #{max}" do - Puppet[:code] = "validate_numeric(#{max+1},#{max})" - expect { scope.compiler.compile }.to raise_error(Puppet::ParseError, /to be smaller or equal to/) - end - - %w{ [-10,1,2,3,4,5,10] ['-10','1','2','3','4','5','10'] }.each do |the_number| - it "should compile when each element of #{the_number} is lower than a maximum of #{max}" do - Puppet[:code] = "validate_numeric(#{the_number},#{max})" - scope.compiler.compile + describe 'rejects numbers smaller than the lower limit' do + it { is_expected.to run.with_params(-11, 10.0, -10.0).and_raise_error(Puppet::ParseError, /to be greater or equal/) } + it { is_expected.to run.with_params(-100, 10.0, -10.0).and_raise_error(Puppet::ParseError, /to be greater or equal/) } + it { is_expected.to run.with_params(-2**65, 10.0, -10.0).and_raise_error(Puppet::ParseError, /to be greater or equal/) } + it { is_expected.to run.with_params([-10.0, 1,2,10.0,-100], 10.0, -10.0).and_raise_error(Puppet::ParseError, /to be greater or equal/) } end - end - - it "should not compile when an element of an Array [-10,1,2,3,4,5,#{max+1}] is greater than a maximum of #{max}" do - Puppet[:code] = "validate_numeric([-10,1,2,3,4,5,#{max+1}],#{max})" - expect { scope.compiler.compile }.to raise_error(Puppet::ParseError, /to be smaller or equal to/) - end - %w{ true false iAmAString 1test }.each do |the_max| - it "should not compile when a non-Numeric maximum #{the_max}, encapsulated in a String, is passed" do - Puppet[:code] = "validate_numeric(1,'#{the_max}')" - expect { scope.compiler.compile }.to raise_error(Puppet::ParseError, /to be unset or a Numeric/) + describe 'accepts numbers between and including the limits' do + it { is_expected.to run.with_params(10.0, 10.0, -10.0) } + it { is_expected.to run.with_params(-10.0, 10.0, -10.0) } + it { is_expected.to run.with_params(1, 10.0, -10.0) } + it { is_expected.to run.with_params(-1, 10.0, -10.0) } + it { is_expected.to run.with_params('1', 10.0, -10.0) } + it { is_expected.to run.with_params('-1', 10.0, -10.0) } + it { is_expected.to run.with_params([1, 2, 3, 4], 10.0, -10.0) } + it { is_expected.to run.with_params([1, '2', '3', 4], 10.0, -10.0) } end - - it "should not compile when a non-Numeric maximum #{the_max} bare word is passed" do - Puppet[:code] = "validate_numeric(1,#{the_max})" - expect { scope.compiler.compile }.to raise_error - end - end - - it "should not compile when an explicitly undefined variable is passed as maximum and no minimum is passed" do - Puppet[:code] = <<-'ENDofPUPPETcode' - $foo = undef - validate_numeric(10, $foo) - ENDofPUPPETcode - expect { scope.compiler.compile }.to raise_error(Puppet::ParseError, /to be unset or a Numeric/) - end - it "should not compile when an explicitly undef is passed as maximum and no minimum is passed" do - Puppet[:code] = "validate_numeric(10, undef)" - expect { scope.compiler.compile }.to raise_error(Puppet::ParseError, /to be unset or a Numeric/) - end - it "should not compile when an empty string is passed as maximum and no minimum is passed" do - Puppet[:code] = "validate_numeric(10, '')" - expect { scope.compiler.compile }.to raise_error(Puppet::ParseError, /to be unset or a Numeric/) - end - it "should not compile when an undefined variable for a maximum is passed" do - Puppet[:code] = "validate_numeric(10, $foobarbazishouldnotexist)" - expect { scope.compiler.compile }.to raise_error(Puppet::ParseError, /to be unset or a Numeric/) end end - describe 'when calling validate_numeric from puppet with input, a maximum and a minimum' do - it "should not compile when a minimum larger than maximum is passed" do - Puppet[:code] = "validate_numeric(1,1,2)" - expect { scope.compiler.compile }.to raise_error(Puppet::ParseError, /second argument to be larger than third argument/) - end + it { is_expected.to run.with_params(10.0, 10.0, 10.0) } - max = 10 - min = -10 - %w{ 1 -1 }.each do |the_number| - it "should compile when each element of #{the_number} is within a range from #{min} to #{max}" do - Puppet[:code] = "validate_numeric(#{the_number},#{max},#{min})" - scope.compiler.compile - end - end - - it "should compile when a Numeric is equal the minimum" do - Puppet[:code] = "validate_numeric(#{min},#{max},#{min})" - scope.compiler.compile - end - - it "should compile when a Numeric is equal the minimum and maximum" do - Puppet[:code] = "validate_numeric(#{max},#{max},#{max})" - scope.compiler.compile - end - - it "should compile when an empty maximum is passed and the Numeric is greater than the minimum" do - Puppet[:code] = "validate_numeric(#{max}.1,'',#{min})" - scope.compiler.compile - end - it "should compile when an explicitly undefined maximum is passed and the Numeric is greater than the minimum" do - Puppet[:code] = "validate_numeric(#{max}.1,undef,#{min})" - scope.compiler.compile - end - it "should compile when an explicitly undefined variable is passed for maximum and the Numeric is greater than the minimum" do - Puppet[:code] = <<-"ENDofPUPPETcode" - $foo = undef - validate_numeric(#{max}.1, $foo, #{min}) - ENDofPUPPETcode - scope.compiler.compile - end - it "should not compile when no maximum value is given and the Numeric is greater than the minimum" do - Puppet[:code] = "validate_numeric(#{max}.1,,#{min})" - expect { scope.compiler.compile }.to raise_error(Puppet::Error, /Syntax error at ','/) - end - - it "should not compile when #{min-1} is lower than a minimum of #{min}" do - Puppet[:code] = "validate_numeric(#{min-1.0},#{max},#{min})" - expect { scope.compiler.compile }.to raise_error(Puppet::ParseError, /to be greater or equal to/) - end - - %w{ [-10,1,2,3,4,5,10] ['-10.0','1','2','3','4','5','10.0'] }.each do |the_number| - it "should compile when each element of #{the_number} is within a range from #{min} to #{max}" do - Puppet[:code] = "validate_numeric(#{the_number},#{max},#{min})" - scope.compiler.compile - end - end - - it "should not compile when an element of an Array [#{min-1.1},1,2,3,4,5,10.0] is lower than a minimum of #{min}" do - Puppet[:code] = "validate_numeric([#{min-1},1,2,3,4,5,10],#{max},#{min})" - expect { scope.compiler.compile }.to raise_error(Puppet::ParseError, /to be greater or equal to/) - end - - %w{ true false iAmAString 1test }.each do |the_min| - it "should not compile when a non-Numeric minimum #{the_min}, encapsulated in a String, is passed" do - Puppet[:code] = "validate_numeric(1,#{max},'#{the_min}')" - expect { scope.compiler.compile }.to raise_error(Puppet::ParseError, /to be unset or a Numeric/) - end - - it "should not compile when a non-Numeric minimum #{the_min} bare word is passed" do - Puppet[:code] = "validate_numeric(1,#{max},#{the_min})" - expect { scope.compiler.compile }.to raise_error - end - end + describe 'empty upper limit is interpreted as infinity' do + it { is_expected.to run.with_params(11, '', 10.0) } end end diff --git a/spec/functions/validate_re_spec.rb b/spec/functions/validate_re_spec.rb index d29988b..42b1049 100755 --- a/spec/functions/validate_re_spec.rb +++ b/spec/functions/validate_re_spec.rb @@ -1,77 +1,46 @@ -#! /usr/bin/env ruby -S rspec require 'spec_helper' -describe Puppet::Parser::Functions.function(:validate_re) do - let(:scope) { PuppetlabsSpec::PuppetInternals.scope } - - # The subject of these examplres is the method itself. - subject do - # This makes sure the function is loaded within each test - function_name = Puppet::Parser::Functions.function(:validate_re) - scope.method(function_name) - end - - context 'Using Puppet::Parser::Scope.new' do - - describe 'Garbage inputs' do - inputs = [ - [ nil ], - [ [ nil ] ], - [ { 'foo' => 'bar' } ], - [ { } ], - [ '' ], - [ "one", "one", "MSG to User", "4th arg" ], - ] - - inputs.each do |input| - it "validate_re(#{input.inspect}) should fail" do - expect { subject.call [input] }.to raise_error Puppet::ParseError - end - end - end - - describe 'Valid inputs' do - inputs = [ - [ '/full/path/to/something', '^/full' ], - [ '/full/path/to/something', 'full' ], - [ '/full/path/to/something', ['full', 'absent'] ], - [ '/full/path/to/something', ['full', 'absent'], 'Message to the user' ], - ] - - inputs.each do |input| - it "validate_re(#{input.inspect}) should not fail" do - expect { subject.call input }.not_to raise_error - end - end - end - describe "Valid inputs which should raise an exception without a message" do - # The intent here is to make sure valid inputs raise exceptions when they - # don't specify an error message to display. This is the behvior in - # 2.2.x and prior. - inputs = [ - [ "hello", [ "bye", "later", "adios" ] ], - [ "greetings", "salutations" ], - ] - - inputs.each do |input| - it "validate_re(#{input.inspect}) should fail" do - expect { subject.call input }.to raise_error /validate_re.*?does not match/ - end - end +describe 'validate_re' 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) } + it { is_expected.to run.with_params('').and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } + it { is_expected.to run.with_params('', '', '', 'extra').and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } + + describe 'valid inputs' do + it { is_expected.to run.with_params('', '') } + it { is_expected.to run.with_params('', ['']) } + it { is_expected.to run.with_params('', [''], 'custom error') } + it { is_expected.to run.with_params('one', '^one') } + it { is_expected.to run.with_params('one', [ '^one', '^two' ]) } + it { is_expected.to run.with_params('one', [ '^one', '^two' ], 'custom error') } end - describe "Nicer Error Messages" do - # The intent here is to make sure the function returns the 3rd argument - # in the exception thrown - inputs = [ - [ "hello", [ "bye", "later", "adios" ], "MSG to User" ], - [ "greetings", "salutations", "Error, greetings does not match salutations" ], - ] - inputs.each do |input| - it "validate_re(#{input.inspect}) should fail" do - expect { subject.call input }.to raise_error /#{input[2]}/ - end - end + describe 'invalid inputs' do + it { + pending('should implement stricter type checking') + is_expected.to run.with_params([], '').and_raise_error(Puppet::ParseError, /is not a String/) + } + it { + pending('should implement stricter type checking') + is_expected.to run.with_params('', {}).and_raise_error(Puppet::ParseError, /is not an Array/) + } + it { + pending('should implement stricter type checking') + is_expected.to run.with_params('', '', []).and_raise_error(Puppet::ParseError, /is not a String/) + } + it { + pending('should implement stricter type checking') + is_expected.to run.with_params(nil, nil).and_raise_error(Puppet::ParseError, /is not a String/) + } + it { is_expected.to run.with_params('', []).and_raise_error(Puppet::ParseError, /does not match/) } + it { is_expected.to run.with_params('one', 'two').and_raise_error(Puppet::ParseError, /does not match/) } + it { is_expected.to run.with_params('', 'two').and_raise_error(Puppet::ParseError, /does not match/) } + it { is_expected.to run.with_params('', ['two']).and_raise_error(Puppet::ParseError, /does not match/) } + it { is_expected.to run.with_params('', ['two'], 'custom error').and_raise_error(Puppet::ParseError, /custom error/) } + it { is_expected.to run.with_params('notone', '^one').and_raise_error(Puppet::ParseError, /does not match/) } + it { is_expected.to run.with_params('notone', [ '^one', '^two' ]).and_raise_error(Puppet::ParseError, /does not match/) } + it { is_expected.to run.with_params('notone', [ '^one', '^two' ], 'custom error').and_raise_error(Puppet::ParseError, /custom error/) } end end end diff --git a/spec/functions/validate_slength_spec.rb b/spec/functions/validate_slength_spec.rb index e23f61a..391f83a 100755 --- a/spec/functions/validate_slength_spec.rb +++ b/spec/functions/validate_slength_spec.rb @@ -1,67 +1,61 @@ -#! /usr/bin/env ruby -S rspec - require 'spec_helper' -describe "the validate_slength function" do - let(:scope) { PuppetlabsSpec::PuppetInternals.scope } - - it "should exist" do - expect(Puppet::Parser::Functions.function("validate_slength")).to eq("function_validate_slength") +describe 'validate_slength' 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) } + it { is_expected.to run.with_params('').and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } + it { is_expected.to run.with_params('', 2, 3, 'extra').and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } + it { is_expected.to run.with_params('', '').and_raise_error(Puppet::ParseError, /second argument to be a positive Numeric/) } + it { is_expected.to run.with_params('', -1).and_raise_error(Puppet::ParseError, /second argument to be a positive Numeric/) } + it { is_expected.to run.with_params('', 1, '').and_raise_error(Puppet::ParseError, /third argument to be unset or a positive Numeric/) } + it { is_expected.to run.with_params('', 1, -1).and_raise_error(Puppet::ParseError, /third argument to be unset or a positive Numeric/) } + it { is_expected.to run.with_params('', 1, 2).and_raise_error(Puppet::ParseError, /argument to be larger than third argument/) } end - describe "validating the input argument types" do - it "raises an error if there are less than two arguments" do - expect { scope.function_validate_slength([]) }.to raise_error Puppet::ParseError, /Wrong number of arguments/ - end - - it "raises an error if there are more than three arguments" do - expect { scope.function_validate_slength(['input', 1, 2, 3]) }.to raise_error Puppet::ParseError, /Wrong number of arguments/ - end - - it "raises an error if the first argument is not a string" do - expect { scope.function_validate_slength([Object.new, 2, 1]) }.to raise_error Puppet::ParseError, /Expected first argument.*got .*Object/ - end - - it "raises an error if the second argument cannot be cast to an Integer" do - expect { scope.function_validate_slength(['input', Object.new]) }.to raise_error Puppet::ParseError, /Expected second argument.*got .*Object/ - end - - it "raises an error if the third argument cannot be cast to an Integer" do - expect { scope.function_validate_slength(['input', 1, Object.new]) }.to raise_error Puppet::ParseError, /Expected third argument.*got .*Object/ + context "with a maximum length of 10" do + describe 'rejects strings longer than the limit' do + it { is_expected.to run.with_params('1234567890a', 10).and_raise_error(Puppet::ParseError, /Expected length/) } + it { is_expected.to run.with_params('1234567890abcdef', 10).and_raise_error(Puppet::ParseError, /Expected length/) } + it { is_expected.to run.with_params([ 'one', '1234567890abcdef' ], 10).and_raise_error(Puppet::ParseError, /Expected length/) } end - it "raises an error if the second argument is smaller than the third argument" do - expect { scope.function_validate_slength(['input', 1, 2]) }.to raise_error Puppet::ParseError, /Expected second argument to be larger than third argument/ + describe 'accepts strings shorter or equal to the limit' do + it { is_expected.to run.with_params('1234567890', 10) } + it { is_expected.to run.with_params('12345', 10) } + it { is_expected.to run.with_params([ 'one', 'two' ], 10) } end - end - - describe "validating the input string length" do - describe "when the input is a string" do - it "fails validation if the string is larger than the max length" do - expect { scope.function_validate_slength(['input', 1]) }.to raise_error Puppet::ParseError, /Expected length .* between 0 and 1, was 5/ - end - - it "fails validation if the string is less than the min length" do - expect { scope.function_validate_slength(['input', 10, 6]) }.to raise_error Puppet::ParseError, /Expected length .* between 6 and 10, was 5/ - end - it "doesn't raise an error if the string is under the max length" do - scope.function_validate_slength(['input', 10]) + context "with a minimum length of 5" do + describe 'rejects strings longer than the upper limit' do + it { is_expected.to run.with_params('1234567890a', 10, 5).and_raise_error(Puppet::ParseError, /Expected length/) } + it { is_expected.to run.with_params('1234567890abcdef', 10, 5).and_raise_error(Puppet::ParseError, /Expected length/) } end - it "doesn't raise an error if the string is equal to the max length" do - scope.function_validate_slength(['input', 5]) + describe 'rejects numbers shorter than the lower limit' do + it { is_expected.to run.with_params('one', 10, 5).and_raise_error(Puppet::ParseError, /Expected length/) } + it { is_expected.to run.with_params(['12345678', 'two'], 10, 5).and_raise_error(Puppet::ParseError, /Expected length/) } end - it "doesn't raise an error if the string is equal to the min length" do - scope.function_validate_slength(['input', 10, 5]) + describe 'accepts strings of length between and including the limits' do + it { is_expected.to run.with_params('12345', 10, 5) } + it { is_expected.to run.with_params('123456', 10, 5) } + it { is_expected.to run.with_params('1234567', 10, 5) } + it { is_expected.to run.with_params('12345678', 10, 5) } + it { is_expected.to run.with_params('123456789', 10, 5) } + it { is_expected.to run.with_params('1234567890', 10, 5) } + it { is_expected.to run.with_params(['1233456', '12345678'], 10, 5) } end end + end - describe "when the input is an array" do - it "fails validation if one of the array elements is not a string" do - expect { scope.function_validate_slength([["a", "b", Object.new], 2]) }.to raise_error Puppet::ParseError, /Expected element at array position 2 .*String, got .*Object/ - end - end + describe 'corner cases' do + it { pending('this should work'); is_expected.to run.with_params('', 0, 0) } + it { is_expected.to run.with_params('1234567890', 10, 10) } + end + + describe 'empty upper limit is interpreted as infinity' do + it { pending('not implemented'); is_expected.to run.with_params('1234567890ab', '', 10) } + it { pending('not implemented'); is_expected.to run.with_params('12345678', '', 10).and_raise_error(Puppet::ParseError, /Expected length/) } end end diff --git a/spec/functions/validate_string_spec.rb b/spec/functions/validate_string_spec.rb index 3b4fb3e..f0c500e 100755 --- a/spec/functions/validate_string_spec.rb +++ b/spec/functions/validate_string_spec.rb @@ -1,60 +1,21 @@ -#! /usr/bin/env ruby -S rspec - require 'spec_helper' -describe Puppet::Parser::Functions.function(:validate_string) do - let(:scope) { PuppetlabsSpec::PuppetInternals.scope } - - describe 'when calling validate_string from puppet' do - - %w{ foo bar baz }.each do |the_string| - - it "should compile when #{the_string} is a string" do - Puppet[:code] = "validate_string('#{the_string}')" - scope.compiler.compile - end - - it "should compile when #{the_string} is a bare word" do - Puppet[:code] = "validate_string(#{the_string})" - scope.compiler.compile - end - - end - - %w{ true false }.each do |the_string| - it "should compile when #{the_string} is a string" do - Puppet[:code] = "validate_string('#{the_string}')" - scope.compiler.compile - end - - it "should not compile when #{the_string} is a bare word" do - Puppet[:code] = "validate_string(#{the_string})" - expect { scope.compiler.compile }.to raise_error(Puppet::ParseError, /is not a string/) - end - end - - it "should compile when multiple string arguments are passed" do - Puppet[:code] = <<-'ENDofPUPPETcode' - $foo = '' - $bar = 'two' - validate_string($foo, $bar) - ENDofPUPPETcode - scope.compiler.compile - end +describe 'validate_string' 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) } - it "should compile when an explicitly undef variable is passed (NOTE THIS MAY NOT BE DESIRABLE)" do - Puppet[:code] = <<-'ENDofPUPPETcode' - $foo = undef - validate_string($foo) - ENDofPUPPETcode - scope.compiler.compile + describe 'valid inputs' do + it { is_expected.to run.with_params('') } + it { is_expected.to run.with_params('one') } + it { is_expected.to run.with_params('one', 'two') } end - it "should compile when an undefined variable is passed (NOTE THIS MAY NOT BE DESIRABLE)" do - Puppet[:code] = <<-'ENDofPUPPETcode' - validate_string($foobarbazishouldnotexist) - ENDofPUPPETcode - scope.compiler.compile + 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({}).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/) } end end end diff --git a/spec/functions/values_at_spec.rb b/spec/functions/values_at_spec.rb index 86e3c31..a8348f3 100755 --- a/spec/functions/values_at_spec.rb +++ b/spec/functions/values_at_spec.rb @@ -1,38 +1,49 @@ -#! /usr/bin/env ruby -S rspec require 'spec_helper' -describe "the values_at function" do - let(:scope) { PuppetlabsSpec::PuppetInternals.scope } - - it "should exist" do - expect(Puppet::Parser::Functions.function("values_at")).to eq("function_values_at") - end - - it "should raise a ParseError if there is less than 1 arguments" do - expect { scope.function_values_at([]) }.to( raise_error(Puppet::ParseError)) - end - - it "should raise a ParseError if you try to use a range where stop is greater then start" do - expect { scope.function_values_at([['a','b'],["3-1"]]) }.to( raise_error(Puppet::ParseError)) - end - - it "should return a value at from an array" do - result = scope.function_values_at([['a','b','c'],"1"]) - expect(result).to(eq(['b'])) - end - - it "should return a value at from an array when passed a range" do - result = scope.function_values_at([['a','b','c'],"0-1"]) - expect(result).to(eq(['a','b'])) +describe 'values_at' 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) } + it { is_expected.to run.with_params([]).and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } + it { + pending("Current implementation ignores parameters after the first two.") + is_expected.to run.with_params([], 0, 1).and_raise_error(Puppet::ParseError, /wrong number of arguments/i) + } + it { is_expected.to run.with_params('', 1).and_raise_error(Puppet::ParseError, /Requires array/i) } + it { is_expected.to run.with_params({}, 1).and_raise_error(Puppet::ParseError, /Requires array/i) } + it { is_expected.to run.with_params(true, 1).and_raise_error(Puppet::ParseError, /Requires array/i) } + it { is_expected.to run.with_params(1, 1).and_raise_error(Puppet::ParseError, /Requires array/i) } + it { is_expected.to run.with_params([0,1,2], 'two').and_raise_error(Puppet::ParseError, /Unknown format of given index/) } + it { is_expected.to run.with_params([0,1,2], []).and_raise_error(Puppet::ParseError, /provide at least one positive index/) } + it { is_expected.to run.with_params([0,1,2], '-1-1').and_raise_error(Puppet::ParseError, /Unknown format of given index/) } + it { is_expected.to run.with_params([0,1,2], '2-1').and_raise_error(Puppet::ParseError, /Stop index in given indices range is smaller than the start index/) } end - it "should return chosen values from an array when passed number of indexes" do - result = scope.function_values_at([['a','b','c'],["0","2"]]) - expect(result).to(eq(['a','c'])) + context 'when requesting a single item' do + it { is_expected.to run.with_params([0, 1, 2], -1).and_raise_error(Puppet::ParseError, /Unknown format of given index/) } + it { is_expected.to run.with_params([0, 1, 2], 0).and_return([0]) } + it { is_expected.to run.with_params([0, 1, 2], 1).and_return([1]) } + it { is_expected.to run.with_params([0, 1, 2], [1]).and_return([1]) } + it { is_expected.to run.with_params([0, 1, 2], '1').and_return([1]) } + it { is_expected.to run.with_params([0, 1, 2], '1-1').and_return([1]) } + it { is_expected.to run.with_params([0, 1, 2], 2).and_return([2]) } + it { is_expected.to run.with_params([0, 1, 2], 3).and_raise_error(Puppet::ParseError, /index exceeds array size/) } end - it "should return chosen values from an array when passed ranges and multiple indexes" do - result = scope.function_values_at([['a','b','c','d','e','f','g'],["0","2","4-5"]]) - expect(result).to(eq(['a','c','e','f'])) + context 'when requesting multiple items' do + it { is_expected.to run.with_params([0, 1, 2], [1, -1]).and_raise_error(Puppet::ParseError, /Unknown format of given index/) } + it { is_expected.to run.with_params([0, 1, 2], [0, 2]).and_return([0, 2]) } + it { is_expected.to run.with_params([0, 1, 2], ['0-2', 1, 2]).and_return([0, 1, 2, 1, 2]) } + it { is_expected.to run.with_params([0, 1, 2], [3, 2]).and_raise_error(Puppet::ParseError, /index exceeds array size/) } + + describe 'different range syntaxes' do + it { is_expected.to run.with_params([0, 1, 2], '0-2').and_return([0, 1, 2]) } + it { is_expected.to run.with_params([0, 1, 2], '0..2').and_return([0, 1, 2]) } + it { is_expected.to run.with_params([0, 1, 2], '0...2').and_return([0, 1]) } + it { + pending('fix this bounds check') + is_expected.to run.with_params([0, 1, 2], '0...3').and_return([0, 1, 2]) + } + end end end diff --git a/spec/functions/values_spec.rb b/spec/functions/values_spec.rb index 08d21b0..4abf0bd 100755 --- a/spec/functions/values_spec.rb +++ b/spec/functions/values_spec.rb @@ -1,31 +1,19 @@ -#! /usr/bin/env ruby -S rspec require 'spec_helper' -describe "the values function" do - let(:scope) { PuppetlabsSpec::PuppetInternals.scope } - - it "should exist" do - expect(Puppet::Parser::Functions.function("values")).to eq("function_values") - end - - it "should raise a ParseError if there is less than 1 arguments" do - expect { scope.function_values([]) }.to( raise_error(Puppet::ParseError)) - end - - it "should return values from a hash" do - result = scope.function_values([{'a'=>'1','b'=>'2','c'=>'3'}]) - # =~ is the RSpec::Matchers::MatchArray matcher. - # A.K.A. "array with same elements" (multiset) matching - expect(result).to match_array(%w{ 1 2 3 }) - end - - it "should return a multiset" do - result = scope.function_values([{'a'=>'1','b'=>'3','c'=>'3'}]) - expect(result).to match_array(%w{ 1 3 3 }) - expect(result).not_to match_array(%w{ 1 3 }) - end - - it "should raise a ParseError unless a Hash is provided" do - expect { scope.function_values([['a','b','c']]) }.to( raise_error(Puppet::ParseError)) +describe 'values' 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 { + pending("Current implementation ignores parameters after the first.") + is_expected.to run.with_params({}, 'extra').and_raise_error(Puppet::ParseError, /wrong number of arguments/i) + } + it { is_expected.to run.with_params('').and_raise_error(Puppet::ParseError, /Requires hash to work with/) } + it { is_expected.to run.with_params(1).and_raise_error(Puppet::ParseError, /Requires hash to work with/) } + it { is_expected.to run.with_params([]).and_raise_error(Puppet::ParseError, /Requires hash to work with/) } + it { is_expected.to run.with_params({}).and_return([]) } + it { is_expected.to run.with_params({ 'key' => 'value' }).and_return(['value']) } + it 'should return the array of values' do + result = subject.call([{ 'key1' => 'value1', 'key2' => 'value2', 'duplicate_value_key' => 'value2' }]) + expect(result).to match_array(['value1', 'value2', 'value2']) end end diff --git a/spec/functions/zip_spec.rb b/spec/functions/zip_spec.rb index f265fce..abca7ee 100755 --- a/spec/functions/zip_spec.rb +++ b/spec/functions/zip_spec.rb @@ -1,31 +1,15 @@ -#! /usr/bin/env ruby -S rspec require 'spec_helper' -describe "the zip function" do - let(:scope) { PuppetlabsSpec::PuppetInternals.scope } - - it "should raise a ParseError if there is less than 1 arguments" do - expect { scope.function_zip([]) }.to( raise_error(Puppet::ParseError)) - end - - it "should be able to zip an array" do - result = scope.function_zip([['1','2','3'],['4','5','6']]) - expect(result).to(eq([["1", "4"], ["2", "5"], ["3", "6"]])) - result = scope.function_zip([['1','2','3'],['4','5','6'], false]) - result.should(eq([["1", "4"], ["2", "5"], ["3", "6"]])) - end - - it "should be able to zip an array and flatten" do - result = scope.function_zip([['1','2','3'],['4','5','6'], true]) - result.should(eq(["1", "4", "2", "5", "3", "6"])) - end - - it "should accept objects which extend String for the second argument" do - class AlsoString < String - end - - value = AlsoString.new('false') - result = scope.function_zip([['1','2','3'],['4','5','6'],value]) - result.should(eq([["1", "4"], ["2", "5"], ["3", "6"]])) - end +describe 'zip' 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 { + pending("Current implementation ignores parameters after the third.") + is_expected.to run.with_params([], [], true, []).and_raise_error(Puppet::ParseError, /wrong number of arguments/i) + } + it { is_expected.to run.with_params([], []).and_return([]) } + it { is_expected.to run.with_params([1,2,3], [4,5,6]).and_return([[1,4], [2,5], [3,6]]) } + it { is_expected.to run.with_params([1,2,3], [4,5,6], false).and_return([[1,4], [2,5], [3,6]]) } + it { is_expected.to run.with_params([1,2,3], [4,5,6], true).and_return([1, 4, 2, 5, 3, 6]) } end diff --git a/spec/puppetlabs_spec_helper_clone.rb b/spec/puppetlabs_spec_helper_clone.rb new file mode 100644 index 0000000..6a94a3b --- /dev/null +++ b/spec/puppetlabs_spec_helper_clone.rb @@ -0,0 +1,34 @@ +#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 /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 + diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index be392fd..f941c1c 100755 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -18,11 +18,17 @@ require 'puppet_spec/matchers' require 'puppet_spec/database' 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 @@ -35,8 +41,6 @@ RSpec.configure do |config| Facter.clear Facter.clear_messages - Puppet[:parser] = 'future' if ENV['FUTURE_PARSER'] == 'yes' - RSpec::Mocks.setup end @@ -45,3 +49,7 @@ RSpec.configure do |config| RSpec::Mocks.teardown end end + +# Helper class to test handling of arguments which are derived from string +class AlsoString < String +end diff --git a/spec/unit/facter/util/puppet_settings_spec.rb b/spec/unit/facter/util/puppet_settings_spec.rb index c06137d..c278b79 100755 --- a/spec/unit/facter/util/puppet_settings_spec.rb +++ b/spec/unit/facter/util/puppet_settings_spec.rb @@ -25,6 +25,7 @@ describe Facter::Util::PuppetSettings do before :each do Puppet.expects(:[]).with(:vardir).returns vardir end + it 'should yield to the block' do subject.with_puppet { Puppet[:vardir] } end -- cgit v1.2.3 From 18d4c21418e8d188ae659a92ff3a8df04d711f6a Mon Sep 17 00:00:00 2001 From: David Schmitt Date: Mon, 1 Jun 2015 12:21:59 +0100 Subject: Remove unused puppet_spec code This is copied and changed code from an older version of puppet's internal test setup code. It does not work with puppet4. --- spec/lib/puppet_spec/compiler.rb | 48 ---------------- spec/lib/puppet_spec/database.rb | 30 ---------- spec/lib/puppet_spec/files.rb | 61 -------------------- spec/lib/puppet_spec/fixtures.rb | 29 ---------- spec/lib/puppet_spec/matchers.rb | 121 --------------------------------------- spec/lib/puppet_spec/modules.rb | 27 --------- spec/lib/puppet_spec/pops.rb | 17 ------ spec/lib/puppet_spec/scope.rb | 15 ----- spec/lib/puppet_spec/settings.rb | 16 ------ spec/lib/puppet_spec/verbose.rb | 10 ---- spec/spec_helper.rb | 6 -- 11 files changed, 380 deletions(-) delete mode 100755 spec/lib/puppet_spec/compiler.rb delete mode 100755 spec/lib/puppet_spec/database.rb delete mode 100755 spec/lib/puppet_spec/files.rb delete mode 100755 spec/lib/puppet_spec/fixtures.rb delete mode 100755 spec/lib/puppet_spec/matchers.rb delete mode 100755 spec/lib/puppet_spec/modules.rb delete mode 100755 spec/lib/puppet_spec/pops.rb delete mode 100755 spec/lib/puppet_spec/scope.rb delete mode 100755 spec/lib/puppet_spec/settings.rb delete mode 100755 spec/lib/puppet_spec/verbose.rb diff --git a/spec/lib/puppet_spec/compiler.rb b/spec/lib/puppet_spec/compiler.rb deleted file mode 100755 index 1f322ca..0000000 --- a/spec/lib/puppet_spec/compiler.rb +++ /dev/null @@ -1,48 +0,0 @@ -#! /usr/bin/env ruby -S rspec -module PuppetSpec::Compiler - def compile_to_catalog(string, node = Puppet::Node.new('foonode')) - Puppet[:code] = string - Puppet[:parser] = 'future' if ENV['FUTURE_PARSER'] == 'yes' - Puppet::Parser::Compiler.compile(node) - end - - def compile_to_ral(manifest) - catalog = compile_to_catalog(manifest) - ral = catalog.to_ral - ral.finalize - ral - end - - def compile_to_relationship_graph(manifest, prioritizer = Puppet::Graph::SequentialPrioritizer.new) - ral = compile_to_ral(manifest) - graph = Puppet::Graph::RelationshipGraph.new(prioritizer) - graph.populate_from(ral) - graph - end - - if Puppet.version.to_f >= 3.3 - def apply_compiled_manifest(manifest, prioritizer = Puppet::Graph::SequentialPrioritizer.new) - transaction = Puppet::Transaction.new(compile_to_ral(manifest), - Puppet::Transaction::Report.new("apply"), - prioritizer) - transaction.evaluate - transaction.report.finalize_report - - transaction - end - else - def apply_compiled_manifest(manifest) - transaction = Puppet::Transaction.new(compile_to_ral(manifest), Puppet::Transaction::Report.new("apply")) - transaction.evaluate - transaction.report.finalize_report - - transaction - end - end - - def order_resources_traversed_in(relationships) - order_seen = [] - relationships.traverse { |resource| order_seen << resource.ref } - order_seen - end -end diff --git a/spec/lib/puppet_spec/database.rb b/spec/lib/puppet_spec/database.rb deleted file mode 100755 index f5c2341..0000000 --- a/spec/lib/puppet_spec/database.rb +++ /dev/null @@ -1,30 +0,0 @@ -#! /usr/bin/env ruby -S rspec -# This just makes some nice things available at global scope, and for setup of -# tests to use a real fake database, rather than a fake stubs-that-don't-work -# version of the same. Fun times. -def sqlite? - if $sqlite.nil? - begin - require 'sqlite3' - $sqlite = true - rescue LoadError - $sqlite = false - end - end - $sqlite -end - -def can_use_scratch_database? - sqlite? and Puppet.features.rails? -end - - -# This is expected to be called in your `before :each` block, and will get you -# ready to roll with a serious database and all. Cleanup is handled -# automatically for you. Nothing to do there. -def setup_scratch_database - Puppet[:dbadapter] = 'sqlite3' - Puppet[:dblocation] = ':memory:' - Puppet[:railslog] = PuppetSpec::Files.tmpfile('storeconfigs.log') - Puppet::Rails.init -end diff --git a/spec/lib/puppet_spec/files.rb b/spec/lib/puppet_spec/files.rb deleted file mode 100755 index 71b38ff..0000000 --- a/spec/lib/puppet_spec/files.rb +++ /dev/null @@ -1,61 +0,0 @@ -#! /usr/bin/env ruby -S rspec -require 'fileutils' -require 'tempfile' -require 'tmpdir' -require 'pathname' - -# A support module for testing files. -module PuppetSpec::Files - def self.cleanup - $global_tempfiles ||= [] - while path = $global_tempfiles.pop do - begin - Dir.unstub(:entries) - FileUtils.rm_rf path, :secure => true - rescue Errno::ENOENT - # nothing to do - end - end - end - - def make_absolute(path) PuppetSpec::Files.make_absolute(path) end - def self.make_absolute(path) - path = File.expand_path(path) - path[0] = 'c' if Puppet.features.microsoft_windows? - path - end - - def tmpfile(name, dir = nil) PuppetSpec::Files.tmpfile(name, dir) end - def self.tmpfile(name, dir = nil) - # Generate a temporary file, just for the name... - source = dir ? Tempfile.new(name, dir) : Tempfile.new(name) - path = source.path - source.close! - - record_tmp(File.expand_path(path)) - - path - end - - def file_containing(name, contents) PuppetSpec::Files.file_containing(name, contents) end - def self.file_containing(name, contents) - file = tmpfile(name) - File.open(file, 'wb') { |f| f.write(contents) } - file - end - - def tmpdir(name) PuppetSpec::Files.tmpdir(name) end - def self.tmpdir(name) - dir = Dir.mktmpdir(name) - - record_tmp(dir) - - dir - end - - def self.record_tmp(tmp) - # ...record it for cleanup, - $global_tempfiles ||= [] - $global_tempfiles << tmp - end -end diff --git a/spec/lib/puppet_spec/fixtures.rb b/spec/lib/puppet_spec/fixtures.rb deleted file mode 100755 index 81e9775..0000000 --- a/spec/lib/puppet_spec/fixtures.rb +++ /dev/null @@ -1,29 +0,0 @@ -#! /usr/bin/env ruby -S rspec -module PuppetSpec::Fixtures - def fixtures(*rest) - File.join(PuppetSpec::FIXTURE_DIR, *rest) - end - def my_fixture_dir - callers = caller - while line = callers.shift do - next unless found = line.match(%r{/spec/(.*)_spec\.rb:}) - return fixtures(found[1]) - end - fail "sorry, I couldn't work out your path from the caller stack!" - end - def my_fixture(name) - file = File.join(my_fixture_dir, name) - unless File.readable? file then - fail Puppet::DevError, "fixture '#{name}' for #{my_fixture_dir} is not readable" - end - return file - end - def my_fixtures(glob = '*', flags = 0) - files = Dir.glob(File.join(my_fixture_dir, glob), flags) - unless files.length > 0 then - fail Puppet::DevError, "fixture '#{glob}' for #{my_fixture_dir} had no files!" - end - block_given? and files.each do |file| yield file end - files - end -end diff --git a/spec/lib/puppet_spec/matchers.rb b/spec/lib/puppet_spec/matchers.rb deleted file mode 100755 index 093d77c..0000000 --- a/spec/lib/puppet_spec/matchers.rb +++ /dev/null @@ -1,121 +0,0 @@ -#! /usr/bin/env ruby -S rspec -require 'stringio' - -######################################################################## -# Backward compatibility for Jenkins outdated environment. -module RSpec - module Matchers - module BlockAliases - alias_method :to, :should unless method_defined? :to - alias_method :to_not, :should_not unless method_defined? :to_not - alias_method :not_to, :should_not unless method_defined? :not_to - end - end -end - - -######################################################################## -# Custom matchers... -RSpec::Matchers.define :have_matching_element do |expected| - match do |actual| - actual.any? { |item| item =~ expected } - end -end - - -RSpec::Matchers.define :exit_with do |expected| - actual = nil - match do |block| - begin - block.call - rescue SystemExit => e - actual = e.status - end - actual and actual == expected - end - failure_message_for_should do |block| - "expected exit with code #{expected} but " + - (actual.nil? ? " exit was not called" : "we exited with #{actual} instead") - end - failure_message_for_should_not do |block| - "expected that exit would not be called with #{expected}" - end - description do - "expect exit with #{expected}" - end -end - -class HavePrintedMatcher - attr_accessor :expected, :actual - - def initialize(expected) - case expected - when String, Regexp - @expected = expected - else - @expected = expected.to_s - end - end - - def matches?(block) - begin - $stderr = $stdout = StringIO.new - $stdout.set_encoding('UTF-8') if $stdout.respond_to?(:set_encoding) - block.call - $stdout.rewind - @actual = $stdout.read - ensure - $stdout = STDOUT - $stderr = STDERR - end - - if @actual then - case @expected - when String - @actual.include? @expected - when Regexp - @expected.match @actual - end - else - false - end - end - - def failure_message_for_should - if @actual.nil? then - "expected #{@expected.inspect}, but nothing was printed" - else - "expected #{@expected.inspect} to be printed; got:\n#{@actual}" - end - end - - def failure_message_for_should_not - "expected #{@expected.inspect} to not be printed; got:\n#{@actual}" - end - - def description - "expect #{@expected.inspect} to be printed" - end -end - -def have_printed(what) - HavePrintedMatcher.new(what) -end - -RSpec::Matchers.define :equal_attributes_of do |expected| - match do |actual| - actual.instance_variables.all? do |attr| - actual.instance_variable_get(attr) == expected.instance_variable_get(attr) - end - end -end - -RSpec::Matchers.define :be_one_of do |*expected| - match do |actual| - expected.include? actual - end - - failure_message_for_should do |actual| - "expected #{actual.inspect} to be one of #{expected.map(&:inspect).join(' or ')}" - end -end diff --git a/spec/lib/puppet_spec/modules.rb b/spec/lib/puppet_spec/modules.rb deleted file mode 100755 index 910c6d9..0000000 --- a/spec/lib/puppet_spec/modules.rb +++ /dev/null @@ -1,27 +0,0 @@ -#! /usr/bin/env ruby -S rspec -module PuppetSpec::Modules - class << self - def create(name, dir, options = {}) - module_dir = File.join(dir, name) - FileUtils.mkdir_p(module_dir) - - environment = options[:environment] - - if metadata = options[:metadata] - metadata[:source] ||= 'github' - metadata[:author] ||= 'puppetlabs' - metadata[:version] ||= '9.9.9' - metadata[:license] ||= 'to kill' - metadata[:dependencies] ||= [] - - metadata[:name] = "#{metadata[:author]}/#{name}" - - File.open(File.join(module_dir, 'metadata.json'), 'w') do |f| - f.write(metadata.to_pson) - end - end - - Puppet::Module.new(name, module_dir, environment) - end - end -end diff --git a/spec/lib/puppet_spec/pops.rb b/spec/lib/puppet_spec/pops.rb deleted file mode 100755 index e056a52..0000000 --- a/spec/lib/puppet_spec/pops.rb +++ /dev/null @@ -1,17 +0,0 @@ -#! /usr/bin/env ruby -S rspec -module PuppetSpec::Pops - extend RSpec::Matchers::DSL - - # Checks if an Acceptor has a specific issue in its list of diagnostics - matcher :have_issue do |expected| - match do |actual| - actual.diagnostics.index { |i| i.issue == expected } != nil - end - failure_message_for_should do |actual| - "expected Acceptor[#{actual.diagnostics.collect { |i| i.issue.issue_code }.join(',')}] to contain issue #{expected.issue_code}" - end - failure_message_for_should_not do |actual| - "expected Acceptor[#{actual.diagnostics.collect { |i| i.issue.issue_code }.join(',')}] to not contain issue #{expected.issue_code}" - end - end -end diff --git a/spec/lib/puppet_spec/scope.rb b/spec/lib/puppet_spec/scope.rb deleted file mode 100755 index 3847ede..0000000 --- a/spec/lib/puppet_spec/scope.rb +++ /dev/null @@ -1,15 +0,0 @@ -#! /usr/bin/env ruby -S rspec - -module PuppetSpec::Scope - # Initialize a new scope suitable for testing. - # - def create_test_scope_for_node(node_name) - node = Puppet::Node.new(node_name) - compiler = Puppet::Parser::Compiler.new(node) - scope = Puppet::Parser::Scope.new(compiler) - scope.source = Puppet::Resource::Type.new(:node, node_name) - scope.parent = compiler.topscope - scope - end - -end \ No newline at end of file diff --git a/spec/lib/puppet_spec/settings.rb b/spec/lib/puppet_spec/settings.rb deleted file mode 100755 index 8ddcb97..0000000 --- a/spec/lib/puppet_spec/settings.rb +++ /dev/null @@ -1,16 +0,0 @@ -#! /usr/bin/env ruby -S rspec -module PuppetSpec::Settings - - # It would probably be preferable to refactor defaults.rb such that the real definitions of - # these settings were available as a variable, which was then accessible for use during tests. - # However, I'm not doing that yet because I don't want to introduce any additional moving parts - # to this already very large changeset. - # Would be nice to clean this up later. --cprice 2012-03-20 - TEST_APP_DEFAULT_DEFINITIONS = { - :name => { :default => "test", :desc => "name" }, - :logdir => { :type => :directory, :default => "test", :desc => "logdir" }, - :confdir => { :type => :directory, :default => "test", :desc => "confdir" }, - :vardir => { :type => :directory, :default => "test", :desc => "vardir" }, - :rundir => { :type => :directory, :default => "test", :desc => "rundir" }, - } -end diff --git a/spec/lib/puppet_spec/verbose.rb b/spec/lib/puppet_spec/verbose.rb deleted file mode 100755 index b2683df..0000000 --- a/spec/lib/puppet_spec/verbose.rb +++ /dev/null @@ -1,10 +0,0 @@ -#! /usr/bin/env ruby -S rspec -# Support code for running stuff with warnings disabled. -module Kernel - def with_verbose_disabled - verbose, $VERBOSE = $VERBOSE, nil - result = yield - $VERBOSE = verbose - return result - end -end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index f941c1c..416036b 100755 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -10,12 +10,6 @@ end require 'puppet' require 'rspec-puppet' require 'puppetlabs_spec_helper/module_spec_helper' -require 'puppet_spec/verbose' -require 'puppet_spec/files' -require 'puppet_spec/settings' -require 'puppet_spec/fixtures' -require 'puppet_spec/matchers' -require 'puppet_spec/database' require 'monkey_patches/alias_should_to_must' require 'mocha/api' #require 'puppetlabs_spec_helper/module_spec_helper' -- cgit v1.2.3 From 601f681787c8d6c02bb3566b8cefde289377be0e Mon Sep 17 00:00:00 2001 From: Eli Young Date: Thu, 28 May 2015 18:15:05 -0700 Subject: fqdn_rotate: Don't use the value itself as part of the random seed Previously, the random number generator was seeded with the array or string to be rotated in addition to any values specifically provided for seeding. This behavior is potentially insecure in that it allows an attacker who can modify the source data to choose the post-shuffle order. --- lib/puppet/parser/functions/fqdn_rotate.rb | 2 +- spec/acceptance/fqdn_rotate_spec.rb | 2 +- spec/functions/fqdn_rotate_spec.rb | 6 +----- 3 files changed, 3 insertions(+), 7 deletions(-) diff --git a/lib/puppet/parser/functions/fqdn_rotate.rb b/lib/puppet/parser/functions/fqdn_rotate.rb index d9741a0..e1a50e6 100644 --- a/lib/puppet/parser/functions/fqdn_rotate.rb +++ b/lib/puppet/parser/functions/fqdn_rotate.rb @@ -11,7 +11,7 @@ Rotates an array a random number of times based on a nodes fqdn. raise(Puppet::ParseError, "fqdn_rotate(): Wrong number of arguments " + "given (#{arguments.size} for 1)") if arguments.size < 1 - value = arguments[0] + value = arguments.shift require 'digest/md5' unless value.is_a?(Array) || value.is_a?(String) diff --git a/spec/acceptance/fqdn_rotate_spec.rb b/spec/acceptance/fqdn_rotate_spec.rb index 753068b..366d027 100755 --- a/spec/acceptance/fqdn_rotate_spec.rb +++ b/spec/acceptance/fqdn_rotate_spec.rb @@ -36,7 +36,7 @@ describe 'fqdn_rotate function', :unless => UNSUPPORTED_PLATFORMS.include?(fact( EOS apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/fqdn_rotate is \["c", "d", "a", "b"\]/) + expect(r.stdout).to match(/fqdn_rotate is \["d", "a", "b", "c"\]/) end end end diff --git a/spec/functions/fqdn_rotate_spec.rb b/spec/functions/fqdn_rotate_spec.rb index fe54490..6c76781 100755 --- a/spec/functions/fqdn_rotate_spec.rb +++ b/spec/functions/fqdn_rotate_spec.rb @@ -5,10 +5,6 @@ describe 'fqdn_rotate' do it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } it { is_expected.to run.with_params(0).and_raise_error(Puppet::ParseError, /Requires either array or string to work with/) } it { is_expected.to run.with_params({}).and_raise_error(Puppet::ParseError, /Requires either array or string to work with/) } - it { - pending("Current implementation ignores parameters after the first.") - is_expected.to run.with_params("one", "two").and_raise_error(Puppet::ParseError) - } it { is_expected.to run.with_params('').and_return('') } it { is_expected.to run.with_params('a').and_return('a') } @@ -38,7 +34,7 @@ describe 'fqdn_rotate' do it "should use the Puppet::Util.deterministic_rand function" do if Puppet::Util.respond_to?(:deterministic_rand) - Puppet::Util.expects(:deterministic_rand).with(113646079810780526294648115052177588845,4) + Puppet::Util.expects(:deterministic_rand).with(44489829212339698569024999901561968770,4) fqdn_rotate("asdf") else skip 'Puppet::Util#deterministic_rand not available' -- cgit v1.2.3 From d7c846035321774e824e3424f59cb24703fcfb2a Mon Sep 17 00:00:00 2001 From: Eli Young Date: Mon, 1 Jun 2015 16:09:47 -0700 Subject: fqdn_rotate: Improve documentation --- README.markdown | 15 ++++++++++++++- lib/puppet/parser/functions/fqdn_rotate.rb | 24 +++++++++++++++--------- 2 files changed, 29 insertions(+), 10 deletions(-) diff --git a/README.markdown b/README.markdown index c140af4..8ed3d9b 100644 --- a/README.markdown +++ b/README.markdown @@ -259,7 +259,20 @@ fqdn_rand_string(10, '', 'custom seed') #### `fqdn_rotate` -Rotates an array a random number of times, based on a node's fqdn. *Type*: rvalue. +Rotates an array or string a random number of times, combining the `$fqdn` fact and an optional seed for repeatable randomness. + +*Usage:* +~~~ +fqdn_rotate(VALUE, [SEED]) +~~~ +*Examples:* +~~~ +fqdn_rotate(['a', 'b', 'c', 'd']) +fqdn_rotate('abcd') +fqdn_rotate([1, 2, 3], 'custom seed') +~~~ + +*Type*: rvalue. #### `get_module_path` diff --git a/lib/puppet/parser/functions/fqdn_rotate.rb b/lib/puppet/parser/functions/fqdn_rotate.rb index e1a50e6..b66431d 100644 --- a/lib/puppet/parser/functions/fqdn_rotate.rb +++ b/lib/puppet/parser/functions/fqdn_rotate.rb @@ -2,16 +2,23 @@ # fqdn_rotate.rb # -module Puppet::Parser::Functions - newfunction(:fqdn_rotate, :type => :rvalue, :doc => <<-EOS -Rotates an array a random number of times based on a nodes fqdn. - EOS - ) do |arguments| +Puppet::Parser::Functions.newfunction( + :fqdn_rotate, + :type => :rvalue, + :doc => "Usage: `fqdn_rotate(VALUE, [SEED])`. VALUE is required and + must be an array or a string. SEED is optional and may be any number + or string. + + Rotates VALUE a random number of times, combining the `$fqdn` fact and + the value of SEED for repeatable randomness. (That is, each node will + get a different random rotation from this function, but a given node's + result will be the same every time unless its hostname changes.) Adding + a SEED can be useful if you need more than one unrelated rotation.") do |args| raise(Puppet::ParseError, "fqdn_rotate(): Wrong number of arguments " + - "given (#{arguments.size} for 1)") if arguments.size < 1 + "given (#{args.size} for 1)") if args.size < 1 - value = arguments.shift + value = args.shift require 'digest/md5' unless value.is_a?(Array) || value.is_a?(String) @@ -31,7 +38,7 @@ Rotates an array a random number of times based on a nodes fqdn. elements = result.size - seed = Digest::MD5.hexdigest([lookupvar('::fqdn'),arguments].join(':')).hex + seed = Digest::MD5.hexdigest([lookupvar('::fqdn'),args].join(':')).hex # deterministic_rand() was added in Puppet 3.2.0; reimplement if necessary if Puppet::Util.respond_to?(:deterministic_rand) offset = Puppet::Util.deterministic_rand(seed, elements).to_i @@ -51,7 +58,6 @@ Rotates an array a random number of times based on a nodes fqdn. result = string ? result.join : result return result - end end # vim: set ts=2 sw=2 et : -- cgit v1.2.3 From b436216fe68c11d67cc15aec83ce0f1eeb7ededf Mon Sep 17 00:00:00 2001 From: Eli Young Date: Mon, 1 Jun 2015 16:29:39 -0700 Subject: fqdn_rotate: Add tests for custom seeds --- spec/functions/fqdn_rotate_spec.rb | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/spec/functions/fqdn_rotate_spec.rb b/spec/functions/fqdn_rotate_spec.rb index 6c76781..db7a717 100755 --- a/spec/functions/fqdn_rotate_spec.rb +++ b/spec/functions/fqdn_rotate_spec.rb @@ -21,6 +21,18 @@ describe 'fqdn_rotate' do expect(val1).to eq(val2) end + it "allows extra arguments to control the random rotation on a single host" do + val1 = fqdn_rotate("abcdefg", :extra_identifier => [1, "different", "host"]) + val2 = fqdn_rotate("abcdefg", :extra_identifier => [2, "different", "host"]) + expect(val1).not_to eq(val2) + end + + it "considers the same host and same extra arguments to have the same random rotation" do + val1 = fqdn_rotate("abcdefg", :extra_identifier => [1, "same", "host"]) + val2 = fqdn_rotate("abcdefg", :extra_identifier => [1, "same", "host"]) + expect(val1).to eq(val2) + end + it "should rotate a string to give different values on different hosts" do val1 = fqdn_rotate("abcdefg", :host => 'one') val2 = fqdn_rotate("abcdefg", :host => 'two') @@ -51,11 +63,13 @@ describe 'fqdn_rotate' do def fqdn_rotate(value, args = {}) host = args[:host] || '127.0.0.1' + extra = args[:extra_identifier] || [] # workaround not being able to use let(:facts) because some tests need # multiple different hostnames in one context scope.stubs(:lookupvar).with("::fqdn").returns(host) - scope.function_fqdn_rotate([value]) + function_args = [value] + extra + scope.function_fqdn_rotate(function_args) end end -- cgit v1.2.3 From 1d6da9674ec9a48ded8c6a9ec57bce5659759cec Mon Sep 17 00:00:00 2001 From: David Schmitt Date: Tue, 2 Jun 2015 12:21:25 +0100 Subject: Gemfile: specify minimum rspec-puppet version Only 2.2 contains all the features we're currently using. Documenting that in the Gemfile should make that clear. --- Gemfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile b/Gemfile index e35a729..64c9066 100644 --- a/Gemfile +++ b/Gemfile @@ -13,7 +13,7 @@ end group :development, :unit_tests do gem 'rake', '~> 10.1.0', :require => false gem 'rspec', '~> 3.1.0', :require => false - gem 'rspec-puppet', :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 -- cgit v1.2.3 From 84279e90abdd7f67a4cce28a3adf899d2b752018 Mon Sep 17 00:00:00 2001 From: Eli Young Date: Mon, 1 Jun 2015 16:46:08 -0700 Subject: fqdn_rotate: Add acceptance tests for custom seeds --- spec/acceptance/fqdn_rotate_spec.rb | 42 +++++++++++++++++++++++++++++++++++-- 1 file changed, 40 insertions(+), 2 deletions(-) diff --git a/spec/acceptance/fqdn_rotate_spec.rb b/spec/acceptance/fqdn_rotate_spec.rb index 366d027..f1a15d3 100755 --- a/spec/acceptance/fqdn_rotate_spec.rb +++ b/spec/acceptance/fqdn_rotate_spec.rb @@ -27,7 +27,7 @@ describe 'fqdn_rotate function', :unless => UNSUPPORTED_PLATFORMS.include?(fact( shell("mkdir -p '#{facts_d}'") end end - it 'fqdn_rotates floats' do + it 'rotates arrays' do shell("echo fqdn=fakehost.localdomain > '#{facts_d}/fqdn.txt'") pp = <<-EOS $a = ['a','b','c','d'] @@ -39,9 +39,47 @@ describe 'fqdn_rotate function', :unless => UNSUPPORTED_PLATFORMS.include?(fact( expect(r.stdout).to match(/fqdn_rotate is \["d", "a", "b", "c"\]/) end end + it 'rotates arrays with custom seeds' do + shell("echo fqdn=fakehost.localdomain > '#{facts_d}/fqdn.txt'") + pp = <<-EOS + $a = ['a','b','c','d'] + $s = 'seed' + $o = fqdn_rotate($a, $s) + notice(inline_template('fqdn_rotate is <%= @o.inspect %>')) + EOS + + apply_manifest(pp, :catch_failures => true) do |r| + expect(r.stdout).to match(/fqdn_rotate is \["c", "d", "a", "b"\]/) + end + end + it 'rotates strings' do + shell("echo fqdn=fakehost.localdomain > '#{facts_d}/fqdn.txt'") + pp = <<-EOS + $a = 'abcd' + $o = fqdn_rotate($a) + notice(inline_template('fqdn_rotate is <%= @o.inspect %>')) + EOS + + apply_manifest(pp, :catch_failures => true) do |r| + expect(r.stdout).to match(/fqdn_rotate is "dabc"/) + end + end + it 'rotates strings with custom seeds' do + shell("echo fqdn=fakehost.localdomain > '#{facts_d}/fqdn.txt'") + pp = <<-EOS + $a = 'abcd' + $s = 'seed' + $o = fqdn_rotate($a, $s) + notice(inline_template('fqdn_rotate is <%= @o.inspect %>')) + EOS + + apply_manifest(pp, :catch_failures => true) do |r| + expect(r.stdout).to match(/fqdn_rotate is "cdab"/) + end + end end describe 'failure' do it 'handles improper argument counts' - it 'handles non-numbers' + it 'handles invalid arguments' end end -- cgit v1.2.3 From 98c2f283b0ad4c3017dd4189a4a44d4af37f9f2b Mon Sep 17 00:00:00 2001 From: Eli Young Date: Mon, 1 Jun 2015 16:46:26 -0700 Subject: fqdn_rand_string: Add acceptance tests for custom charsets --- spec/acceptance/fqdn_rand_string_spec.rb | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/spec/acceptance/fqdn_rand_string_spec.rb b/spec/acceptance/fqdn_rand_string_spec.rb index 8fe1a69..881cff3 100644 --- a/spec/acceptance/fqdn_rand_string_spec.rb +++ b/spec/acceptance/fqdn_rand_string_spec.rb @@ -39,6 +39,19 @@ describe 'fqdn_rand_string function', :unless => UNSUPPORTED_PLATFORMS.include?( expect(r.stdout).to match(/fqdn_rand_string is "7oDp0KOr1b"/) end end + it 'generates random alphanumeric strings with custom charsets' do + shell("echo fqdn=fakehost.localdomain > '#{facts_d}/fqdn.txt'") + pp = <<-eos + $l = 10 + $c = '0123456789' + $o = fqdn_rand_string($l, $c) + notice(inline_template('fqdn_rand_string is <%= @o.inspect %>')) + eos + + apply_manifest(pp, :catch_failures => true) do |r| + expect(r.stdout).to match(/fqdn_rand_string is "7203048515"/) + end + end it 'generates random alphanumeric strings with custom seeds' do shell("echo fqdn=fakehost.localdomain > '#{facts_d}/fqdn.txt'") pp = <<-eos @@ -52,6 +65,20 @@ describe 'fqdn_rand_string function', :unless => UNSUPPORTED_PLATFORMS.include?( expect(r.stdout).to match(/fqdn_rand_string is "3HS4mbuI3E"/) end end + it 'generates random alphanumeric strings with custom charsets and seeds' do + shell("echo fqdn=fakehost.localdomain > '#{facts_d}/fqdn.txt'") + pp = <<-eos + $l = 10 + $c = '0123456789' + $s = 'seed' + $o = fqdn_rand_string($l, $c, $s) + notice(inline_template('fqdn_rand_string is <%= @o.inspect %>')) + eos + + apply_manifest(pp, :catch_failures => true) do |r| + expect(r.stdout).to match(/fqdn_rand_string is "3104058232"/) + end + end end describe 'failure' do it 'handles improper argument counts' -- cgit v1.2.3 From 84f49d3a1c39890cb2c905ecff3cf1f51ca7a3f3 Mon Sep 17 00:00:00 2001 From: Kylo Ginsberg Date: Tue, 2 Jun 2015 15:32:52 -0700 Subject: (doc) Fix spelling of camelcase in CHANGELOG.md --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index eef0473..7c33314 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -90,7 +90,7 @@ backwards-compatible with the stdlib 3 series. It adds two new functions, one bu #### Features - New `bool2str()` function -- New `camalcase()` function +- New `camelcase()` function #### Bugfixes - Fix `has_interface_with()` when interfaces fact is nil -- cgit v1.2.3 From 650216e5334d6bbcfad3d1ac51868b39f40363bd Mon Sep 17 00:00:00 2001 From: Jonathan Tripathy Date: Thu, 4 Jun 2015 14:21:00 +0100 Subject: Updated travisci file to remove allow_failures on Puppet4 --- .travis.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 7268682..6fad7a4 100644 --- a/.travis.yml +++ b/.travis.yml @@ -17,8 +17,5 @@ matrix: env: PUPPET_GEM_VERSION="~> 3.0" FUTURE_PARSER="yes" - rvm: 2.1.6 env: PUPPET_GEM_VERSION="~> 4.0" STRICT_VARIABLES="yes" - allow_failures: - - rvm: 2.1.6 - env: PUPPET_GEM_VERSION="~> 4.0" STRICT_VARIABLES="yes" notifications: email: false -- cgit v1.2.3 From ad4ca4cc3486b0eaaa813595907521ce35c970ce Mon Sep 17 00:00:00 2001 From: Hunter Haugen Date: Thu, 4 Jun 2015 09:40:52 -0700 Subject: Fix time() on 1.8.7 The time() function takes an argument of a timezone, and always returns time in epoch format. The epoch format is the number of seconds that have elapsed since January 1, 1970 (midnight UTC/GMT), not counting leap seconds. This means that it is universally the same regardless of timezones. I don't know what the timezone argument is supposed to do, and it is not documented. So lets just make 1.8.7 work like > 1.8.7 --- lib/puppet/parser/functions/time.rb | 5 +++-- spec/functions/time_spec.rb | 11 ++--------- 2 files changed, 5 insertions(+), 11 deletions(-) diff --git a/lib/puppet/parser/functions/time.rb b/lib/puppet/parser/functions/time.rb index 0cddaf8..c574747 100644 --- a/lib/puppet/parser/functions/time.rb +++ b/lib/puppet/parser/functions/time.rb @@ -33,13 +33,14 @@ Will return something like: 1311972653 ENV['TZ'] = time_zone - time = local_time.localtime + result = local_time.localtime.strftime('%s') ENV['TZ'] = original_zone + else + result = time.localtime.strftime('%s') end # Calling Time#to_i on a receiver changes it. Trust me I am the Doctor. - result = time.strftime('%s') result = result.to_i return result diff --git a/spec/functions/time_spec.rb b/spec/functions/time_spec.rb index 2875e25..d157939 100755 --- a/spec/functions/time_spec.rb +++ b/spec/functions/time_spec.rb @@ -7,7 +7,7 @@ describe 'time' do context 'when running at a specific time' do before(:each) { # get a value before stubbing the function - test_time = Time.utc(2006, 10, 13, 8, 15, 11, '+01:00') + test_time = Time.utc(2006, 10, 13, 8, 15, 11) Time.expects(:new).with().returns(test_time).once } it { is_expected.to run.with_params().and_return(1160727311) } @@ -16,13 +16,6 @@ describe 'time' do it { is_expected.to run.with_params({}).and_return(1160727311) } it { is_expected.to run.with_params('foo').and_return(1160727311) } it { is_expected.to run.with_params('UTC').and_return(1160727311) } - - context 'when running on modern rubies', :unless => RUBY_VERSION == '1.8.7' do - it { is_expected.to run.with_params('America/Los_Angeles').and_return(1160727311) } - end - - context 'when running on ruby 1.8.7, which garbles the TZ', :if => RUBY_VERSION == '1.8.7' do - it { is_expected.to run.with_params('America/Los_Angeles').and_return(1160702111) } - end + it { is_expected.to run.with_params('America/New_York').and_return(1160727311) } end end -- cgit v1.2.3 From 212c498df32bf14879deac77b2ae7dca927a3c39 Mon Sep 17 00:00:00 2001 From: Tomas Doran Date: Fri, 5 Jun 2015 12:40:46 +0100 Subject: Also catch :undefined_variable as thrown by future parser --- lib/puppet/parser/functions/getvar.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/puppet/parser/functions/getvar.rb b/lib/puppet/parser/functions/getvar.rb index fb336b6..ae9c869 100644 --- a/lib/puppet/parser/functions/getvar.rb +++ b/lib/puppet/parser/functions/getvar.rb @@ -20,7 +20,9 @@ module Puppet::Parser::Functions end begin - self.lookupvar("#{args[0]}") + catch(:undefined_variable) do + self.lookupvar("#{args[0]}") + end rescue Puppet::ParseError # Eat the exception if strict_variables = true is set end -- cgit v1.2.3 From a41cfbd043fb1772f6dc3c1aeef6fcd9978a19dc Mon Sep 17 00:00:00 2001 From: Justin Stoller Date: Mon, 8 Jun 2015 21:43:36 -0700 Subject: (maint) update PUPPET_VERSION default to be 3.8.1 --- spec/spec_helper_acceptance.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/spec_helper_acceptance.rb b/spec/spec_helper_acceptance.rb index 79b1390..3d9574b 100755 --- a/spec/spec_helper_acceptance.rb +++ b/spec/spec_helper_acceptance.rb @@ -6,7 +6,7 @@ UNSUPPORTED_PLATFORMS = [] unless ENV['RS_PROVISION'] == 'no' or ENV['BEAKER_provision'] == 'no' foss_opts = { :default_action => 'gem_install', - :version => (ENV['PUPPET_VERSION'] ? ENV['PUPPET_VERSION'] : '3.7.2'), + :version => (ENV['PUPPET_VERSION'] || '3.8.1'), } if default.is_pe?; then install_pe; else install_puppet( foss_opts ); end -- cgit v1.2.3 From c9e093f8d3d31f73b021e247f940c1f60be9c1e1 Mon Sep 17 00:00:00 2001 From: David Schmitt Date: Fri, 12 Jun 2015 14:42:09 +0100 Subject: (maint) getvar: update spec to match implementation --- spec/functions/getvar_spec.rb | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/spec/functions/getvar_spec.rb b/spec/functions/getvar_spec.rb index 37125d1..6ab137e 100755 --- a/spec/functions/getvar_spec.rb +++ b/spec/functions/getvar_spec.rb @@ -16,13 +16,6 @@ describe 'getvar' do it { is_expected.to run.with_params('site::data::foo').and_return('baz') } it { is_expected.to run.with_params('::site::data::foo').and_return('baz') } - - context 'with strict variable checking', :if => RSpec.configuration.strict_variables do - it { is_expected.to run.with_params('::site::data::bar').and_raise_error(ArgumentError, /undefined_variable/) } - end - - context 'without strict variable checking', :unless => RSpec.configuration.strict_variables do - it { is_expected.to run.with_params('::site::data::bar').and_return(nil) } - end + it { is_expected.to run.with_params('::site::data::bar').and_return(nil) } end end -- cgit v1.2.3 From 771320a8305a7e2cad427f52fcca576dc63e4f37 Mon Sep 17 00:00:00 2001 From: David Schmitt Date: Thu, 18 Jun 2015 14:49:28 +0100 Subject: Document puppet 4 compatability in 4.6 --- README.markdown | 1 + metadata.json | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/README.markdown b/README.markdown index 8ed3d9b..4fab8c8 100644 --- a/README.markdown +++ b/README.markdown @@ -1019,6 +1019,7 @@ Versions | Puppet 2.6 | Puppet 2.7 | Puppet 3.x | Puppet 4.x | **stdlib 2.x** | **yes** | **yes** | no | no **stdlib 3.x** | no | **yes** | **yes** | no **stdlib 4.x** | no | **yes** | **yes** | no +**stdlib 4.6+** | no | **yes** | **yes** | **yes** **stdlib 5.x** | no | no | **yes** | **yes** **stdlib 5.x**: When released, stdlib 5.x will drop support for Puppet 2.7.x. Please see [this discussion](https://github.com/puppetlabs/puppetlabs-stdlib/pull/176#issuecomment-30251414). diff --git a/metadata.json b/metadata.json index 51b73f7..21e063f 100644 --- a/metadata.json +++ b/metadata.json @@ -103,7 +103,7 @@ }, { "name": "puppet", - "version_requirement": ">=2.7.20 <4.0.0" + "version_requirement": ">=2.7.20 <5.0.0" } ], "description": "Standard Library for Puppet Modules", -- cgit v1.2.3 From 5381dbd4b464e743bed36f6b653bddc4df688dde Mon Sep 17 00:00:00 2001 From: Morgan Haskel Date: Fri, 19 Jun 2015 14:29:42 -0700 Subject: AIO uses puppet 4 so should return true for is_future_parser_enabled --- spec/spec_helper_acceptance.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/spec/spec_helper_acceptance.rb b/spec/spec_helper_acceptance.rb index 3d9574b..39d2d52 100755 --- a/spec/spec_helper_acceptance.rb +++ b/spec/spec_helper_acceptance.rb @@ -43,7 +43,9 @@ RSpec.configure do |c| end def is_future_parser_enabled? - if default[:default_apply_opts] + if default[:type] == 'aio' + return true + elsif default[:default_apply_opts] return default[:default_apply_opts][:parser] == 'future' end return false -- cgit v1.2.3 From a6dcb23f8988b16799d23a2f1001de704538cff4 Mon Sep 17 00:00:00 2001 From: Drew Fisher Date: Fri, 19 Jun 2015 17:14:21 -0600 Subject: Add support for Solaris 12 --- metadata.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/metadata.json b/metadata.json index 51b73f7..eb06d5b 100644 --- a/metadata.json +++ b/metadata.json @@ -71,7 +71,8 @@ "operatingsystem": "Solaris", "operatingsystemrelease": [ "10", - "11" + "11", + "12" ] }, { -- cgit v1.2.3 From e96a818782c944b4b1af5417d0bcffc08e95aadc Mon Sep 17 00:00:00 2001 From: Mathias Klette Date: Wed, 24 Jun 2015 14:58:48 +0200 Subject: catch and rescue from looking up non-existent facts when looking for 'kind' facter (2.x) only provides facts without interface suffix for * ipaddress * netmask 'macaddress' and 'network' facts will always have the related interface name appended. in turns lookupvar throws errors when strict_variables is enabled. --- lib/puppet/parser/functions/has_interface_with.rb | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/lib/puppet/parser/functions/has_interface_with.rb b/lib/puppet/parser/functions/has_interface_with.rb index 3691524..e762798 100644 --- a/lib/puppet/parser/functions/has_interface_with.rb +++ b/lib/puppet/parser/functions/has_interface_with.rb @@ -38,8 +38,11 @@ has_interface_with("lo") => true # Bug with 3.7.1 - 3.7.3 when using future parser throws :undefined_variable # https://tickets.puppetlabs.com/browse/PUP-3597 factval = nil - catch :undefined_variable do - factval = lookupvar(kind) + begin + catch :undefined_variable do + factval = lookupvar(kind) + end + rescue Puppet::ParseError # Eat the exception if strict_variables = true is set end if factval == value return true -- cgit v1.2.3 From c64ecfb0c39b633675269ab02f323f7eb486dad4 Mon Sep 17 00:00:00 2001 From: Alexander Fisher Date: Mon, 6 Jul 2015 17:03:49 +0100 Subject: Add validate_slength's optional 3rd arg to README --- README.markdown | 4 +++- lib/puppet/parser/functions/validate_slength.rb | 6 ++---- spec/functions/validate_slength_spec.rb | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/README.markdown b/README.markdown index 8ed3d9b..4dcdc2e 100644 --- a/README.markdown +++ b/README.markdown @@ -938,13 +938,14 @@ test, and the second argument should be a stringified regular expression (withou #### `validate_slength` -Validates that the first argument is a string (or an array of strings), and is less than or equal to the length of the second argument. It fails if the first argument is not a string or array of strings, or if arg 2 is not convertable to a number. +Validates that the first argument is a string (or an array of strings), and is less than or equal to the length of the second argument. It fails if the first argument is not a string or array of strings, or if arg 2 is not convertable to a number. Optionally, a minimum string length can be given as the third argument. The following values pass: ~~~ validate_slength("discombobulate",17) validate_slength(["discombobulate","moo"],17) + validate_slength(["discombobulate","moo"],17,3) ~~~ The following values fail: @@ -952,6 +953,7 @@ Validates that the first argument is a string (or an array of strings), and is l ~~~ validate_slength("discombobulate",1) validate_slength(["discombobulate","thermometer"],5) + validate_slength(["discombobulate","moo"],17,10) ~~~ *Type*: statement. diff --git a/lib/puppet/parser/functions/validate_slength.rb b/lib/puppet/parser/functions/validate_slength.rb index 7d534f3..47c7d4a 100644 --- a/lib/puppet/parser/functions/validate_slength.rb +++ b/lib/puppet/parser/functions/validate_slength.rb @@ -3,7 +3,7 @@ module Puppet::Parser::Functions newfunction(:validate_slength, :doc => <<-'ENDHEREDOC') do |args| Validate that the first argument is a string (or an array of strings), and less/equal to than the length of the second argument. An optional third - parameter can be given a the minimum length. It fails if the first + parameter can be given the minimum length. It fails if the first argument is not a string or array of strings, and if arg 2 and arg 3 are not convertable to a number. @@ -43,9 +43,7 @@ module Puppet::Parser::Functions min_length = 0 end - if min_length > max_length - raise Puppet::ParseError, "validate_slength(): Expected second argument to be larger than third argument" - end + raise Puppet::ParseError, "validate_slength(): Expected second argument to be equal to or larger than third argument" unless max_length >= min_length validator = lambda do |str| unless str.length <= max_length and str.length >= min_length diff --git a/spec/functions/validate_slength_spec.rb b/spec/functions/validate_slength_spec.rb index 391f83a..5a8fa6a 100755 --- a/spec/functions/validate_slength_spec.rb +++ b/spec/functions/validate_slength_spec.rb @@ -10,7 +10,7 @@ describe 'validate_slength' do it { is_expected.to run.with_params('', -1).and_raise_error(Puppet::ParseError, /second argument to be a positive Numeric/) } it { is_expected.to run.with_params('', 1, '').and_raise_error(Puppet::ParseError, /third argument to be unset or a positive Numeric/) } it { is_expected.to run.with_params('', 1, -1).and_raise_error(Puppet::ParseError, /third argument to be unset or a positive Numeric/) } - it { is_expected.to run.with_params('', 1, 2).and_raise_error(Puppet::ParseError, /argument to be larger than third argument/) } + it { is_expected.to run.with_params('', 1, 2).and_raise_error(Puppet::ParseError, /argument to be equal to or larger than third argument/) } end context "with a maximum length of 10" do -- cgit v1.2.3 From 224b644003f99d83e53654af74f4002133545d55 Mon Sep 17 00:00:00 2001 From: Morgan Haskel Date: Thu, 9 Jul 2015 17:11:10 -0700 Subject: Use puppet_install_helper --- Gemfile | 5 +++-- spec/spec_helper_acceptance.rb | 22 ++-------------------- 2 files changed, 5 insertions(+), 22 deletions(-) diff --git a/Gemfile b/Gemfile index 64c9066..fbb9a25 100644 --- a/Gemfile +++ b/Gemfile @@ -32,9 +32,10 @@ group :system_tests do if beaker_rspec_version gem 'beaker-rspec', *location_for(beaker_rspec_version) else - gem 'beaker-rspec', :require => false + gem 'beaker-rspec', :require => false end - gem 'serverspec', :require => false + gem 'serverspec', :require => false + gem 'beaker-puppet_install_helper', :require => false end facterversion = ENV['GEM_FACTER_VERSION'] || ENV['FACTER_GEM_VERSION'] diff --git a/spec/spec_helper_acceptance.rb b/spec/spec_helper_acceptance.rb index 39d2d52..7b09a38 100755 --- a/spec/spec_helper_acceptance.rb +++ b/spec/spec_helper_acceptance.rb @@ -1,28 +1,10 @@ #! /usr/bin/env ruby -S rspec require 'beaker-rspec' +require 'beaker/puppet_install_helper' UNSUPPORTED_PLATFORMS = [] -unless ENV['RS_PROVISION'] == 'no' or ENV['BEAKER_provision'] == 'no' - foss_opts = { - :default_action => 'gem_install', - :version => (ENV['PUPPET_VERSION'] || '3.8.1'), - } - - if default.is_pe?; then install_pe; else install_puppet( foss_opts ); end - - hosts.each do |host| - if host['platform'] !~ /windows/i - if host.is_pe? - on host, 'mkdir -p /etc/puppetlabs/facter/facts.d' - else - on host, "/bin/touch #{host['puppetpath']}/hiera.yaml" - on host, "mkdir -p #{host['distmoduledir']}" - on host, 'mkdir -p /etc/facter/facts.d' - end - end - end -end +run_puppet_install_helper RSpec.configure do |c| # Project root -- cgit v1.2.3 From f485e6e2eb1d2ffa8c16402249bec96e0886b86b Mon Sep 17 00:00:00 2001 From: Garrett Honeycutt Date: Sun, 12 Jul 2015 20:11:36 -0400 Subject: Clarify that third argument to ensure_resource() is a hash --- README.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.markdown b/README.markdown index 3d1e663..7eed5d7 100644 --- a/README.markdown +++ b/README.markdown @@ -212,7 +212,7 @@ Takes a list of packages and only installs them if they don't already exist. It #### `ensure_resource` -Takes a resource type, title, and a list of attributes that describe a resource. +Takes a resource type, title, and a hash of attributes that describe the resource(s). ~~~ user { 'dan': -- cgit v1.2.3 From 14709d625b840da1919b5cd8933b73fb771e547b Mon Sep 17 00:00:00 2001 From: tphoney Date: Thu, 9 Jul 2015 15:13:00 +0100 Subject: prep work for 4.7.0 add new improvements puppet4 changes for testing --- CHANGELOG.md | 29 +++++++++++++++++++++++++++++ examples/file_line.pp | 9 +++++++++ examples/has_interface_with.pp | 10 ++++++++++ examples/has_ip_address.pp | 3 +++ examples/has_ip_network.pp | 4 ++++ examples/init.pp | 1 + metadata.json | 2 +- tests/file_line.pp | 9 --------- tests/has_interface_with.pp | 10 ---------- tests/has_ip_address.pp | 3 --- tests/has_ip_network.pp | 4 ---- tests/init.pp | 1 - 12 files changed, 57 insertions(+), 28 deletions(-) create mode 100644 examples/file_line.pp create mode 100644 examples/has_interface_with.pp create mode 100644 examples/has_ip_address.pp create mode 100644 examples/has_ip_network.pp create mode 100644 examples/init.pp delete mode 100644 tests/file_line.pp delete mode 100644 tests/has_interface_with.pp delete mode 100644 tests/has_ip_address.pp delete mode 100644 tests/has_ip_network.pp delete mode 100644 tests/init.pp diff --git a/CHANGELOG.md b/CHANGELOG.md index 7c33314..7343cef 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,32 @@ +##2015-06-22 - Supported Release 4.7.0 +###Summary + +Adds Solaris 12 support along with improved Puppet 4 support. There are significant test improvements, and some minor fixes. + +####Features +- Add support for Solaris 12 + +####Bugfixes +- Fix for AIO Puppet 4 +- Fix time for ruby 1.8.7 +- Specify rspec-puppet version +- range() fix for typeerror and missing functionality +- Fix pw_hash() on JRuby < 1.7.17 +- fqdn_rand_string: fix argument error message +- catch and rescue from looking up non-existent facts +- Use puppet_install_helper, for Puppet 4 + +####Improvements +- Enforce support for Puppet 4 testing +- fqdn_rotate/fqdn_rand_string acceptance tests and implementation +- Simplify mac address regex +- validate_integer, validate_numeric: explicitely reject hashes in arrays +- Readme edits +- Remove all the pops stuff for rspec-puppet +- Sync via modulesync +- Add validate_slength optional 3rd arg +- Move tests directory to examples directory + ##2015-04-14 - Supported Release 4.6.0 ###Summary diff --git a/examples/file_line.pp b/examples/file_line.pp new file mode 100644 index 0000000..eea693e --- /dev/null +++ b/examples/file_line.pp @@ -0,0 +1,9 @@ +# This is a simple smoke test +# of the file_line resource type. +file { '/tmp/dansfile': + ensure => present +}-> +file_line { 'dans_line': + line => 'dan is awesome', + path => '/tmp/dansfile', +} diff --git a/examples/has_interface_with.pp b/examples/has_interface_with.pp new file mode 100644 index 0000000..e1f1353 --- /dev/null +++ b/examples/has_interface_with.pp @@ -0,0 +1,10 @@ +include stdlib +info('has_interface_with(\'lo\'):', has_interface_with('lo')) +info('has_interface_with(\'loX\'):', has_interface_with('loX')) +info('has_interface_with(\'ipaddress\', \'127.0.0.1\'):', has_interface_with('ipaddress', '127.0.0.1')) +info('has_interface_with(\'ipaddress\', \'127.0.0.100\'):', has_interface_with('ipaddress', '127.0.0.100')) +info('has_interface_with(\'network\', \'127.0.0.0\'):', has_interface_with('network', '127.0.0.0')) +info('has_interface_with(\'network\', \'128.0.0.0\'):', has_interface_with('network', '128.0.0.0')) +info('has_interface_with(\'netmask\', \'255.0.0.0\'):', has_interface_with('netmask', '255.0.0.0')) +info('has_interface_with(\'netmask\', \'256.0.0.0\'):', has_interface_with('netmask', '256.0.0.0')) + diff --git a/examples/has_ip_address.pp b/examples/has_ip_address.pp new file mode 100644 index 0000000..8429a88 --- /dev/null +++ b/examples/has_ip_address.pp @@ -0,0 +1,3 @@ +include stdlib +info('has_ip_address(\'192.168.1.256\'):', has_ip_address('192.168.1.256')) +info('has_ip_address(\'127.0.0.1\'):', has_ip_address('127.0.0.1')) diff --git a/examples/has_ip_network.pp b/examples/has_ip_network.pp new file mode 100644 index 0000000..a15d8c0 --- /dev/null +++ b/examples/has_ip_network.pp @@ -0,0 +1,4 @@ +include stdlib +info('has_ip_network(\'127.0.0.0\'):', has_ip_network('127.0.0.0')) +info('has_ip_network(\'128.0.0.0\'):', has_ip_network('128.0.0.0')) + diff --git a/examples/init.pp b/examples/init.pp new file mode 100644 index 0000000..9675d83 --- /dev/null +++ b/examples/init.pp @@ -0,0 +1 @@ +include stdlib diff --git a/metadata.json b/metadata.json index 3254497..5c20ade 100644 --- a/metadata.json +++ b/metadata.json @@ -1,6 +1,6 @@ { "name": "puppetlabs-stdlib", - "version": "4.6.0", + "version": "4.7.0", "author": "puppetlabs", "summary": "Standard library of resources for Puppet modules.", "license": "Apache-2.0", diff --git a/tests/file_line.pp b/tests/file_line.pp deleted file mode 100644 index eea693e..0000000 --- a/tests/file_line.pp +++ /dev/null @@ -1,9 +0,0 @@ -# This is a simple smoke test -# of the file_line resource type. -file { '/tmp/dansfile': - ensure => present -}-> -file_line { 'dans_line': - line => 'dan is awesome', - path => '/tmp/dansfile', -} diff --git a/tests/has_interface_with.pp b/tests/has_interface_with.pp deleted file mode 100644 index e1f1353..0000000 --- a/tests/has_interface_with.pp +++ /dev/null @@ -1,10 +0,0 @@ -include stdlib -info('has_interface_with(\'lo\'):', has_interface_with('lo')) -info('has_interface_with(\'loX\'):', has_interface_with('loX')) -info('has_interface_with(\'ipaddress\', \'127.0.0.1\'):', has_interface_with('ipaddress', '127.0.0.1')) -info('has_interface_with(\'ipaddress\', \'127.0.0.100\'):', has_interface_with('ipaddress', '127.0.0.100')) -info('has_interface_with(\'network\', \'127.0.0.0\'):', has_interface_with('network', '127.0.0.0')) -info('has_interface_with(\'network\', \'128.0.0.0\'):', has_interface_with('network', '128.0.0.0')) -info('has_interface_with(\'netmask\', \'255.0.0.0\'):', has_interface_with('netmask', '255.0.0.0')) -info('has_interface_with(\'netmask\', \'256.0.0.0\'):', has_interface_with('netmask', '256.0.0.0')) - diff --git a/tests/has_ip_address.pp b/tests/has_ip_address.pp deleted file mode 100644 index 8429a88..0000000 --- a/tests/has_ip_address.pp +++ /dev/null @@ -1,3 +0,0 @@ -include stdlib -info('has_ip_address(\'192.168.1.256\'):', has_ip_address('192.168.1.256')) -info('has_ip_address(\'127.0.0.1\'):', has_ip_address('127.0.0.1')) diff --git a/tests/has_ip_network.pp b/tests/has_ip_network.pp deleted file mode 100644 index a15d8c0..0000000 --- a/tests/has_ip_network.pp +++ /dev/null @@ -1,4 +0,0 @@ -include stdlib -info('has_ip_network(\'127.0.0.0\'):', has_ip_network('127.0.0.0')) -info('has_ip_network(\'128.0.0.0\'):', has_ip_network('128.0.0.0')) - diff --git a/tests/init.pp b/tests/init.pp deleted file mode 100644 index 9675d83..0000000 --- a/tests/init.pp +++ /dev/null @@ -1 +0,0 @@ -include stdlib -- cgit v1.2.3 From 939aceffad5c9eafbab336e4e5e7477a97154e41 Mon Sep 17 00:00:00 2001 From: Dan Offord Date: Mon, 20 Jul 2015 17:55:52 +0100 Subject: Fix documentation error in upcase The documentation example shows an incorrect response when using the function, this PR corrects the example to agree with what the function actually does. --- lib/puppet/parser/functions/upcase.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/puppet/parser/functions/upcase.rb b/lib/puppet/parser/functions/upcase.rb index 0226a88..44b3bcd 100644 --- a/lib/puppet/parser/functions/upcase.rb +++ b/lib/puppet/parser/functions/upcase.rb @@ -12,7 +12,7 @@ Converts a string or an array of strings to uppercase. Will return: - ASDF + ABCD EOS ) do |arguments| -- cgit v1.2.3 From 78e8c73671d0d3b69b2999094ec3af638327f7c0 Mon Sep 17 00:00:00 2001 From: Travis Fields Date: Mon, 20 Jul 2015 14:35:57 -0700 Subject: (maint) Fix test to not assume is_pe fact on > 4.0.0 puppet --- spec/acceptance/fqdn_rand_string_spec.rb | 3 ++- spec/acceptance/fqdn_rotate_spec.rb | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/spec/acceptance/fqdn_rand_string_spec.rb b/spec/acceptance/fqdn_rand_string_spec.rb index 881cff3..fec3c93 100644 --- a/spec/acceptance/fqdn_rand_string_spec.rb +++ b/spec/acceptance/fqdn_rand_string_spec.rb @@ -4,7 +4,8 @@ require 'spec_helper_acceptance' describe 'fqdn_rand_string function', :unless => UNSUPPORTED_PLATFORMS.include?(fact('operatingsystem')) do describe 'success' do let(:facts_d) do - if fact('is_pe', '--puppet') == "true" + puppet_version = (on default, puppet('--version')).output.chomp + if puppet_version < '4.0.0' && fact('is_pe', '--puppet') == "true" if fact('osfamily') =~ /windows/i if fact('kernelmajversion').to_f < 6.0 'c:/documents and settings/all users/application data/puppetlabs/facter/facts.d' diff --git a/spec/acceptance/fqdn_rotate_spec.rb b/spec/acceptance/fqdn_rotate_spec.rb index f1a15d3..556c609 100755 --- a/spec/acceptance/fqdn_rotate_spec.rb +++ b/spec/acceptance/fqdn_rotate_spec.rb @@ -4,7 +4,8 @@ require 'spec_helper_acceptance' describe 'fqdn_rotate function', :unless => UNSUPPORTED_PLATFORMS.include?(fact('operatingsystem')) do describe 'success' do let(:facts_d) do - if fact('is_pe', '--puppet') == "true" + puppet_version = (on default, puppet('--version')).output.chomp + if puppet_version < '4.0.0' && fact('is_pe', '--puppet') == "true" if fact('osfamily') =~ /windows/i if fact('kernelmajversion').to_f < 6.0 'C:/Documents and Settings/All Users/Application Data/PuppetLabs/facter/facts.d' -- cgit v1.2.3 From 615227918a72c54c2064b81183fc98f4abd513d4 Mon Sep 17 00:00:00 2001 From: Hunter Haugen Date: Tue, 21 Jul 2015 14:43:34 -0700 Subject: disable pw_hash test on sles, as it only supports md5 --- spec/acceptance/pw_hash_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/acceptance/pw_hash_spec.rb b/spec/acceptance/pw_hash_spec.rb index eddb782..cd4cb87 100644 --- a/spec/acceptance/pw_hash_spec.rb +++ b/spec/acceptance/pw_hash_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper_acceptance' # Windows and OS X do not have useful implementations of crypt(3) -describe 'pw_hash function', :unless => (UNSUPPORTED_PLATFORMS + ['windows', 'Darwin']).include?(fact('operatingsystem')) do +describe 'pw_hash function', :unless => (UNSUPPORTED_PLATFORMS + ['windows', 'Darwin', 'SLES']).include?(fact('operatingsystem')) do describe 'success' do it 'hashes passwords' do pp = <<-EOS -- cgit v1.2.3 From 5c79107863a42a9d347637146f0c0f728f9b92ad Mon Sep 17 00:00:00 2001 From: gcmalloc Date: Tue, 21 Jul 2015 19:25:27 +0200 Subject: adding support for hash in the size function --- README.markdown | 2 +- lib/puppet/parser/functions/size.rb | 8 +++----- spec/functions/size_spec.rb | 9 ++++++--- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/README.markdown b/README.markdown index 7eed5d7..eef538a 100644 --- a/README.markdown +++ b/README.markdown @@ -578,7 +578,7 @@ Randomizes the order of a string or array elements. *Type*: rvalue. #### `size` -Returns the number of elements in a string or an array. *Type*: rvalue. +Returns the number of elements in a string, an array or a hash. *Type*: rvalue. #### `sort` diff --git a/lib/puppet/parser/functions/size.rb b/lib/puppet/parser/functions/size.rb index cc207e3..0d6cc96 100644 --- a/lib/puppet/parser/functions/size.rb +++ b/lib/puppet/parser/functions/size.rb @@ -2,11 +2,9 @@ # size.rb # -# TODO(Krzysztof Wilczynski): Support for hashes would be nice too ... - module Puppet::Parser::Functions newfunction(:size, :type => :rvalue, :doc => <<-EOS -Returns the number of elements in a string or array. +Returns the number of elements in a string, an array or a hash EOS ) do |arguments| @@ -29,13 +27,13 @@ Returns the number of elements in a string or array. Float(item) raise(Puppet::ParseError, 'size(): Requires either ' + - 'string or array to work with') + 'string, array or hash to work with') rescue ArgumentError result = item.size end - elsif item.is_a?(Array) + elsif item.is_a?(Array) || item.is_a?(Hash) result = item.size else raise(Puppet::ParseError, 'size(): Unknown type given') diff --git a/spec/functions/size_spec.rb b/spec/functions/size_spec.rb index 6b64866..c0047ee 100755 --- a/spec/functions/size_spec.rb +++ b/spec/functions/size_spec.rb @@ -8,15 +8,18 @@ describe 'size' do is_expected.to run.with_params([], 'extra').and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } it { is_expected.to run.with_params(1).and_raise_error(Puppet::ParseError, /Unknown type given/) } - it { is_expected.to run.with_params({}).and_raise_error(Puppet::ParseError, /Unknown type given/) } it { is_expected.to run.with_params(true).and_raise_error(Puppet::ParseError, /Unknown type given/) } - it { is_expected.to run.with_params('1').and_raise_error(Puppet::ParseError, /Requires either string or array to work/) } - it { is_expected.to run.with_params('1.0').and_raise_error(Puppet::ParseError, /Requires either string or array to work/) } + it { is_expected.to run.with_params('1').and_raise_error(Puppet::ParseError, /Requires either string, array or hash to work/) } + it { is_expected.to run.with_params('1.0').and_raise_error(Puppet::ParseError, /Requires either string, array or hash to work/) } it { is_expected.to run.with_params([]).and_return(0) } it { is_expected.to run.with_params(['a']).and_return(1) } it { is_expected.to run.with_params(['one', 'two', 'three']).and_return(3) } it { is_expected.to run.with_params(['one', 'two', 'three', 'four']).and_return(4) } + it { is_expected.to run.with_params({}).and_return(0) } + it { is_expected.to run.with_params({'1' => '2'}).and_return(1) } + it { is_expected.to run.with_params({'1' => '2', '4' => '4'}).and_return(2) } + it { is_expected.to run.with_params('').and_return(0) } it { is_expected.to run.with_params('a').and_return(1) } it { is_expected.to run.with_params('abc').and_return(3) } -- cgit v1.2.3 From 24b1cd78db93d14a8f9d27ce0f3ab09884892fe4 Mon Sep 17 00:00:00 2001 From: David Schmitt Date: Wed, 22 Jul 2015 12:21:31 +0100 Subject: (maint) Remove failing acceptance test for ensure_packages This only duplicates what's already being tested in ensure_packages_spec.rb but doesn't work on all our supported platforms. --- spec/acceptance/ensure_packages_spec.rb | 22 ---------------------- 1 file changed, 22 deletions(-) delete mode 100755 spec/acceptance/ensure_packages_spec.rb diff --git a/spec/acceptance/ensure_packages_spec.rb b/spec/acceptance/ensure_packages_spec.rb deleted file mode 100755 index aedcfb5..0000000 --- a/spec/acceptance/ensure_packages_spec.rb +++ /dev/null @@ -1,22 +0,0 @@ -#! /usr/bin/env ruby -S rspec -require 'spec_helper_acceptance' - -describe 'ensure_packages function', :unless => fact('osfamily') =~ /windows/i do - describe 'success' do - it 'ensure_packages a package' do - apply_manifest('package { "rake": ensure => absent, provider => "gem", }') - pp = <<-EOS - $a = "rake" - ensure_packages($a,{'provider' => 'gem'}) - EOS - - apply_manifest(pp, :expect_changes => true) - end - it 'ensures a package already declared' - it 'takes defaults arguments' - end - describe 'failure' do - it 'handles no arguments' - it 'handles non strings' - end -end -- cgit v1.2.3 From a8d7563a441834ba5e4b9029c9446bb8f41f0921 Mon Sep 17 00:00:00 2001 From: David Schmitt Date: Wed, 22 Jul 2015 17:30:39 +0100 Subject: (main) clean up fqdn_rand acceptance tests to work on windows --- spec/acceptance/fqdn_rand_string_spec.rb | 112 +++++++++++++------------------ spec/acceptance/fqdn_rotate_spec.rb | 108 ++++++++++++----------------- spec/spec_helper_acceptance.rb | 35 ++++++++++ 3 files changed, 123 insertions(+), 132 deletions(-) diff --git a/spec/acceptance/fqdn_rand_string_spec.rb b/spec/acceptance/fqdn_rand_string_spec.rb index fec3c93..9c6d701 100644 --- a/spec/acceptance/fqdn_rand_string_spec.rb +++ b/spec/acceptance/fqdn_rand_string_spec.rb @@ -3,81 +3,59 @@ require 'spec_helper_acceptance' describe 'fqdn_rand_string function', :unless => UNSUPPORTED_PLATFORMS.include?(fact('operatingsystem')) do describe 'success' do - let(:facts_d) do - puppet_version = (on default, puppet('--version')).output.chomp - if puppet_version < '4.0.0' && fact('is_pe', '--puppet') == "true" - if fact('osfamily') =~ /windows/i - if fact('kernelmajversion').to_f < 6.0 - 'c:/documents and settings/all users/application data/puppetlabs/facter/facts.d' - else - 'c:/programdata/puppetlabs/facter/facts.d' - end - else - '/etc/puppetlabs/facter/facts.d' - end - else - '/etc/facter/facts.d' - end - end - after :each do - shell("if [ -f '#{facts_d}/fqdn.txt' ] ; then rm '#{facts_d}/fqdn.txt' ; fi") - end - before :each do - #no need to create on windows, pe creates by default - if fact('osfamily') !~ /windows/i - shell("mkdir -p '#{facts_d}'") + include_context "with faked facts" + context "when the FQDN is 'fakehost.localdomain'" do + before :each do + fake_fact("fqdn", "fakehost.localdomain") end - end - it 'generates random alphanumeric strings' do - shell("echo fqdn=fakehost.localdomain > '#{facts_d}/fqdn.txt'") - pp = <<-eos - $l = 10 - $o = fqdn_rand_string($l) - notice(inline_template('fqdn_rand_string is <%= @o.inspect %>')) - eos - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/fqdn_rand_string is "7oDp0KOr1b"/) + it 'generates random alphanumeric strings' do + pp = <<-eos + $l = 10 + $o = fqdn_rand_string($l) + notice(inline_template('fqdn_rand_string is <%= @o.inspect %>')) + eos + + apply_manifest(pp, :catch_failures => true) do |r| + expect(r.stdout).to match(/fqdn_rand_string is "7oDp0KOr1b"/) + end end - end - it 'generates random alphanumeric strings with custom charsets' do - shell("echo fqdn=fakehost.localdomain > '#{facts_d}/fqdn.txt'") - pp = <<-eos - $l = 10 - $c = '0123456789' - $o = fqdn_rand_string($l, $c) - notice(inline_template('fqdn_rand_string is <%= @o.inspect %>')) - eos + it 'generates random alphanumeric strings with custom charsets' do + pp = <<-eos + $l = 10 + $c = '0123456789' + $o = fqdn_rand_string($l, $c) + notice(inline_template('fqdn_rand_string is <%= @o.inspect %>')) + eos - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/fqdn_rand_string is "7203048515"/) + apply_manifest(pp, :catch_failures => true) do |r| + expect(r.stdout).to match(/fqdn_rand_string is "7203048515"/) + end end - end - it 'generates random alphanumeric strings with custom seeds' do - shell("echo fqdn=fakehost.localdomain > '#{facts_d}/fqdn.txt'") - pp = <<-eos - $l = 10 - $s = 'seed' - $o = fqdn_rand_string($l, undef, $s) - notice(inline_template('fqdn_rand_string is <%= @o.inspect %>')) - eos + it 'generates random alphanumeric strings with custom seeds' do + pp = <<-eos + $l = 10 + $s = 'seed' + $o = fqdn_rand_string($l, undef, $s) + notice(inline_template('fqdn_rand_string is <%= @o.inspect %>')) + eos - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/fqdn_rand_string is "3HS4mbuI3E"/) + apply_manifest(pp, :catch_failures => true) do |r| + expect(r.stdout).to match(/fqdn_rand_string is "3HS4mbuI3E"/) + end end - end - it 'generates random alphanumeric strings with custom charsets and seeds' do - shell("echo fqdn=fakehost.localdomain > '#{facts_d}/fqdn.txt'") - pp = <<-eos - $l = 10 - $c = '0123456789' - $s = 'seed' - $o = fqdn_rand_string($l, $c, $s) - notice(inline_template('fqdn_rand_string is <%= @o.inspect %>')) - eos + it 'generates random alphanumeric strings with custom charsets and seeds' do + pp = <<-eos + $l = 10 + $c = '0123456789' + $s = 'seed' + $o = fqdn_rand_string($l, $c, $s) + notice(inline_template('fqdn_rand_string is <%= @o.inspect %>')) + eos - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/fqdn_rand_string is "3104058232"/) + apply_manifest(pp, :catch_failures => true) do |r| + expect(r.stdout).to match(/fqdn_rand_string is "3104058232"/) + end end end end diff --git a/spec/acceptance/fqdn_rotate_spec.rb b/spec/acceptance/fqdn_rotate_spec.rb index 556c609..404351f 100755 --- a/spec/acceptance/fqdn_rotate_spec.rb +++ b/spec/acceptance/fqdn_rotate_spec.rb @@ -3,79 +3,57 @@ require 'spec_helper_acceptance' describe 'fqdn_rotate function', :unless => UNSUPPORTED_PLATFORMS.include?(fact('operatingsystem')) do describe 'success' do - let(:facts_d) do - puppet_version = (on default, puppet('--version')).output.chomp - if puppet_version < '4.0.0' && fact('is_pe', '--puppet') == "true" - if fact('osfamily') =~ /windows/i - if fact('kernelmajversion').to_f < 6.0 - 'C:/Documents and Settings/All Users/Application Data/PuppetLabs/facter/facts.d' - else - 'C:/ProgramData/PuppetLabs/facter/facts.d' - end - else - '/etc/puppetlabs/facter/facts.d' - end - else - '/etc/facter/facts.d' - end - end - after :each do - shell("if [ -f '#{facts_d}/fqdn.txt' ] ; then rm '#{facts_d}/fqdn.txt' ; fi") - end - before :each do - #No need to create on windows, PE creates by default - if fact('osfamily') !~ /windows/i - shell("mkdir -p '#{facts_d}'") + include_context "with faked facts" + context "when the FQDN is 'fakehost.localdomain'" do + before :each do + fake_fact("fqdn", "fakehost.localdomain") end - end - it 'rotates arrays' do - shell("echo fqdn=fakehost.localdomain > '#{facts_d}/fqdn.txt'") - pp = <<-EOS - $a = ['a','b','c','d'] - $o = fqdn_rotate($a) - notice(inline_template('fqdn_rotate is <%= @o.inspect %>')) - EOS - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/fqdn_rotate is \["d", "a", "b", "c"\]/) + it 'rotates arrays' do + pp = <<-EOS + $a = ['a','b','c','d'] + $o = fqdn_rotate($a) + notice(inline_template('fqdn_rotate is <%= @o.inspect %>')) + EOS + + apply_manifest(pp, :catch_failures => true) do |r| + expect(r.stdout).to match(/fqdn_rotate is \["d", "a", "b", "c"\]/) + end end - end - it 'rotates arrays with custom seeds' do - shell("echo fqdn=fakehost.localdomain > '#{facts_d}/fqdn.txt'") - pp = <<-EOS - $a = ['a','b','c','d'] - $s = 'seed' - $o = fqdn_rotate($a, $s) - notice(inline_template('fqdn_rotate is <%= @o.inspect %>')) - EOS + it 'rotates arrays with custom seeds' do + pp = <<-EOS + $a = ['a','b','c','d'] + $s = 'seed' + $o = fqdn_rotate($a, $s) + notice(inline_template('fqdn_rotate is <%= @o.inspect %>')) + EOS - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/fqdn_rotate is \["c", "d", "a", "b"\]/) + apply_manifest(pp, :catch_failures => true) do |r| + expect(r.stdout).to match(/fqdn_rotate is \["c", "d", "a", "b"\]/) + end end - end - it 'rotates strings' do - shell("echo fqdn=fakehost.localdomain > '#{facts_d}/fqdn.txt'") - pp = <<-EOS - $a = 'abcd' - $o = fqdn_rotate($a) - notice(inline_template('fqdn_rotate is <%= @o.inspect %>')) - EOS + it 'rotates strings' do + pp = <<-EOS + $a = 'abcd' + $o = fqdn_rotate($a) + notice(inline_template('fqdn_rotate is <%= @o.inspect %>')) + EOS - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/fqdn_rotate is "dabc"/) + apply_manifest(pp, :catch_failures => true) do |r| + expect(r.stdout).to match(/fqdn_rotate is "dabc"/) + end end - end - it 'rotates strings with custom seeds' do - shell("echo fqdn=fakehost.localdomain > '#{facts_d}/fqdn.txt'") - pp = <<-EOS - $a = 'abcd' - $s = 'seed' - $o = fqdn_rotate($a, $s) - notice(inline_template('fqdn_rotate is <%= @o.inspect %>')) - EOS + it 'rotates strings with custom seeds' do + pp = <<-EOS + $a = 'abcd' + $s = 'seed' + $o = fqdn_rotate($a, $s) + notice(inline_template('fqdn_rotate is <%= @o.inspect %>')) + EOS - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/fqdn_rotate is "cdab"/) + apply_manifest(pp, :catch_failures => true) do |r| + expect(r.stdout).to match(/fqdn_rotate is "cdab"/) + end end end end diff --git a/spec/spec_helper_acceptance.rb b/spec/spec_helper_acceptance.rb index 7b09a38..6f7f8e1 100755 --- a/spec/spec_helper_acceptance.rb +++ b/spec/spec_helper_acceptance.rb @@ -1,6 +1,7 @@ #! /usr/bin/env ruby -S rspec require 'beaker-rspec' require 'beaker/puppet_install_helper' +require 'rubygems' UNSUPPORTED_PLATFORMS = [] @@ -32,3 +33,37 @@ def is_future_parser_enabled? end return false end + +RSpec.shared_context "with faked facts" do + let(:facts_d) do + puppet_version = (on default, puppet('--version')).output.chomp + if Gem::Version(puppet_version) < Gem::Version('4.0.0') && fact('is_pe', '--puppet') == "true" + if fact('osfamily') =~ /windows/i + if fact('kernelmajversion').to_f < 6.0 + 'C:/Documents and Settings/All Users/Application Data/PuppetLabs/facter/facts.d' + else + 'C:/ProgramData/PuppetLabs/facter/facts.d' + end + else + '/etc/puppetlabs/facter/facts.d' + end + else + '/etc/facter/facts.d' + end + end + + before :each do + #No need to create on windows, PE creates by default + if fact('osfamily') !~ /windows/i + shell("mkdir -p '#{facts_d}'") + end + end + + after :each do + shell("rm -f '#{facts_d}/fqdn.txt'") + end + + def fake_fact(name, value) + shell("echo #{name}=#{value} > '#{facts_d}/#{name}.txt'") + end +end -- cgit v1.2.3 From c7403a4e050352b6b6dd98a2626aa90490884ca1 Mon Sep 17 00:00:00 2001 From: Ewoud Kohl van Wijngaarden Date: Sat, 25 Jul 2015 13:34:31 +0200 Subject: Style fixes --- examples/file_line.pp | 4 ++-- examples/has_interface_with.pp | 3 +-- examples/has_ip_address.pp | 2 +- examples/has_ip_network.pp | 3 +-- examples/init.pp | 2 +- manifests/init.pp | 2 +- 6 files changed, 7 insertions(+), 9 deletions(-) diff --git a/examples/file_line.pp b/examples/file_line.pp index eea693e..85b1325 100644 --- a/examples/file_line.pp +++ b/examples/file_line.pp @@ -1,8 +1,8 @@ # This is a simple smoke test # of the file_line resource type. file { '/tmp/dansfile': - ensure => present -}-> + ensure => file, +} -> file_line { 'dans_line': line => 'dan is awesome', path => '/tmp/dansfile', diff --git a/examples/has_interface_with.pp b/examples/has_interface_with.pp index e1f1353..a578dd2 100644 --- a/examples/has_interface_with.pp +++ b/examples/has_interface_with.pp @@ -1,4 +1,4 @@ -include stdlib +include ::stdlib info('has_interface_with(\'lo\'):', has_interface_with('lo')) info('has_interface_with(\'loX\'):', has_interface_with('loX')) info('has_interface_with(\'ipaddress\', \'127.0.0.1\'):', has_interface_with('ipaddress', '127.0.0.1')) @@ -7,4 +7,3 @@ info('has_interface_with(\'network\', \'127.0.0.0\'):', has_interface_with('netw info('has_interface_with(\'network\', \'128.0.0.0\'):', has_interface_with('network', '128.0.0.0')) info('has_interface_with(\'netmask\', \'255.0.0.0\'):', has_interface_with('netmask', '255.0.0.0')) info('has_interface_with(\'netmask\', \'256.0.0.0\'):', has_interface_with('netmask', '256.0.0.0')) - diff --git a/examples/has_ip_address.pp b/examples/has_ip_address.pp index 8429a88..594143d 100644 --- a/examples/has_ip_address.pp +++ b/examples/has_ip_address.pp @@ -1,3 +1,3 @@ -include stdlib +include ::stdlib info('has_ip_address(\'192.168.1.256\'):', has_ip_address('192.168.1.256')) info('has_ip_address(\'127.0.0.1\'):', has_ip_address('127.0.0.1')) diff --git a/examples/has_ip_network.pp b/examples/has_ip_network.pp index a15d8c0..1f1130d 100644 --- a/examples/has_ip_network.pp +++ b/examples/has_ip_network.pp @@ -1,4 +1,3 @@ -include stdlib +include ::stdlib info('has_ip_network(\'127.0.0.0\'):', has_ip_network('127.0.0.0')) info('has_ip_network(\'128.0.0.0\'):', has_ip_network('128.0.0.0')) - diff --git a/examples/init.pp b/examples/init.pp index 9675d83..ad27972 100644 --- a/examples/init.pp +++ b/examples/init.pp @@ -1 +1 @@ -include stdlib +include ::stdlib diff --git a/manifests/init.pp b/manifests/init.pp index 87ea975..9ea22a7 100644 --- a/manifests/init.pp +++ b/manifests/init.pp @@ -14,5 +14,5 @@ # Requires: nothing # class stdlib { - include stdlib::stages + include ::stdlib::stages } -- cgit v1.2.3 From 44c4bad392e627ed6394a4a5e93ae85cd4c4ca50 Mon Sep 17 00:00:00 2001 From: David Schmitt Date: Thu, 30 Jul 2015 10:46:38 +0100 Subject: (maint) use puppet's utility function instead of API that's not available on all rubies --- spec/spec_helper_acceptance.rb | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/spec/spec_helper_acceptance.rb b/spec/spec_helper_acceptance.rb index 6f7f8e1..03ff993 100755 --- a/spec/spec_helper_acceptance.rb +++ b/spec/spec_helper_acceptance.rb @@ -1,7 +1,6 @@ #! /usr/bin/env ruby -S rspec require 'beaker-rspec' require 'beaker/puppet_install_helper' -require 'rubygems' UNSUPPORTED_PLATFORMS = [] @@ -37,7 +36,7 @@ end RSpec.shared_context "with faked facts" do let(:facts_d) do puppet_version = (on default, puppet('--version')).output.chomp - if Gem::Version(puppet_version) < Gem::Version('4.0.0') && fact('is_pe', '--puppet') == "true" + if Puppet::Util::Package.versioncmp(puppet_version, '4.0.0') < 0 && fact('is_pe', '--puppet') == "true" if fact('osfamily') =~ /windows/i if fact('kernelmajversion').to_f < 6.0 'C:/Documents and Settings/All Users/Application Data/PuppetLabs/facter/facts.d' -- cgit v1.2.3 From 35e92645f727f02ef9ace8948154079bc0fff05a Mon Sep 17 00:00:00 2001 From: Raymond Maika Date: Thu, 30 Jul 2015 14:05:39 -0400 Subject: (MODULES-2024) Adding replace attribute to file_line --- README.markdown | 1 + lib/puppet/provider/file_line/ruby.rb | 31 +++++++++----- lib/puppet/type/file_line.rb | 6 +++ spec/unit/puppet/provider/file_line/ruby_spec.rb | 51 ++++++++++++++++++++++++ spec/unit/puppet/type/file_line_spec.rb | 3 ++ 5 files changed, 81 insertions(+), 11 deletions(-) diff --git a/README.markdown b/README.markdown index eef538a..090bb09 100644 --- a/README.markdown +++ b/README.markdown @@ -99,6 +99,7 @@ All parameters are optional, unless otherwise noted. * `multiple`: Determines if `match` and/or `after` can change multiple lines. If set to false, an exception will be raised if more than one line matches. Valid options: 'true', 'false'. Default: Undefined. * `name`: Sets the name to use as the identity of the resource. This is necessary if you want the resource namevar to differ from the supplied `title` of the resource. Valid options: String. Default: Undefined. * `path`: **Required.** Defines the file in which Puppet will ensure the line specified by `line`. Must be an absolute path to the file. +* `replace`: Defines whether the resource will overwrite an existing line that matches the `match` parameter. If set to false and a line is found matching the `match` param, the line will not be placed in the file. Valid options: true, false, yes, no. Default: true ### Functions diff --git a/lib/puppet/provider/file_line/ruby.rb b/lib/puppet/provider/file_line/ruby.rb index c58e27e..ea1d44d 100644 --- a/lib/puppet/provider/file_line/ruby.rb +++ b/lib/puppet/provider/file_line/ruby.rb @@ -1,17 +1,23 @@ Puppet::Type.type(:file_line).provide(:ruby) do def exists? - lines.find do |line| - line.chomp == resource[:line].chomp + if !resource[:replace] and count_matches(match_regex) > 0 + true + else + lines.find do |line| + line.chomp == resource[:line].chomp + end end end def create - if resource[:match] - handle_create_with_match - elsif resource[:after] - handle_create_with_after - else - append_line + unless !resource[:replace] and count_matches(match_regex) > 0 + if resource[:match] + handle_create_with_match + elsif resource[:after] + handle_create_with_after + else + append_line + end end end @@ -32,10 +38,13 @@ Puppet::Type.type(:file_line).provide(:ruby) do @lines ||= File.readlines(resource[:path]) end + def match_regex + resource[:match] ? Regexp.new(resource[:match]) : nil + end + def handle_create_with_match() - regex = resource[:match] ? Regexp.new(resource[:match]) : nil regex_after = resource[:after] ? Regexp.new(resource[:after]) : nil - match_count = count_matches(regex) + match_count = count_matches(match_regex) if match_count > 1 && resource[:multiple].to_s != 'true' raise Puppet::Error, "More than one line in file '#{resource[:path]}' matches pattern '#{resource[:match]}'" @@ -43,7 +52,7 @@ Puppet::Type.type(:file_line).provide(:ruby) do File.open(resource[:path], 'w') do |fh| lines.each do |l| - fh.puts(regex.match(l) ? resource[:line] : l) + fh.puts(match_regex.match(l) ? resource[:line] : l) if (match_count == 0 and regex_after) if regex_after.match(l) fh.puts(resource[:line]) diff --git a/lib/puppet/type/file_line.rb b/lib/puppet/type/file_line.rb index 29f9538..190105c 100644 --- a/lib/puppet/type/file_line.rb +++ b/lib/puppet/type/file_line.rb @@ -1,3 +1,4 @@ +require 'puppet/parameter/boolean' Puppet::Type.newtype(:file_line) do desc <<-EOT @@ -78,6 +79,11 @@ Puppet::Type.newtype(:file_line) do end end + newparam(:replace, :boolean => true, :parent => Puppet::Parameter::Boolean) do + desc 'If true, replace line that matches. If false, do not write line if a match is found' + defaultto true + end + # Autorequire the file resource if it's being managed autorequire(:file) do self[:path] diff --git a/spec/unit/puppet/provider/file_line/ruby_spec.rb b/spec/unit/puppet/provider/file_line/ruby_spec.rb index 8fe3932..5eff09a 100755 --- a/spec/unit/puppet/provider/file_line/ruby_spec.rb +++ b/spec/unit/puppet/provider/file_line/ruby_spec.rb @@ -36,7 +36,58 @@ describe provider_class do expect(File.read(tmpfile).chomp).to eq('foo') end end + context 'when using replace' do + before :each do + # TODO: these should be ported over to use the PuppetLabs spec_helper + # file fixtures once the following pull request has been merged: + # https://github.com/puppetlabs/puppetlabs-stdlib/pull/73/files + tmp = Tempfile.new('tmp') + @tmpfile = tmp.path + tmp.close! + @resource = Puppet::Type::File_line.new( + { + :name => 'foo', + :path => @tmpfile, + :line => 'foo = bar', + :match => '^foo\s*=.*$', + :replace => false, + } + ) + @provider = provider_class.new(@resource) + end + it 'should not replace the matching line' do + File.open(@tmpfile, 'w') do |fh| + fh.write("foo1\nfoo=blah\nfoo2\nfoo3") + end + expect(@provider.exists?).to be_truthy + @provider.create + expect(File.read(@tmpfile).chomp).to eql("foo1\nfoo=blah\nfoo2\nfoo3") + end + + it 'should append the line if no matches are found' do + File.open(@tmpfile, 'w') do |fh| + fh.write("foo1\nfoo2") + end + expect(@provider.exists?).to be_nil + @provider.create + expect(File.read(@tmpfile).chomp).to eql("foo1\nfoo2\nfoo = bar") + end + + it 'should raise an error with invalid values' do + expect { + @resource = Puppet::Type::File_line.new( + { + :name => 'foo', + :path => @tmpfile, + :line => 'foo = bar', + :match => '^foo\s*=.*$', + :replace => 'asgadga', + } + ) + }.to raise_error(Puppet::Error, /Invalid value "asgadga"\. Valid values are true, false, yes, no\./) + end + end context "when matching" do before :each do # TODO: these should be ported over to use the PuppetLabs spec_helper diff --git a/spec/unit/puppet/type/file_line_spec.rb b/spec/unit/puppet/type/file_line_spec.rb index 410d0bf..58c88e3 100755 --- a/spec/unit/puppet/type/file_line_spec.rb +++ b/spec/unit/puppet/type/file_line_spec.rb @@ -49,6 +49,9 @@ describe Puppet::Type.type(:file_line) do it 'should default to ensure => present' do expect(file_line[:ensure]).to eq :present end + it 'should default to replace => true' do + expect(file_line[:replace]).to eq true + end it "should autorequire the file it manages" do catalog = Puppet::Resource::Catalog.new -- cgit v1.2.3 From aca29129cb0fada02cd4590eba30b560dc08ac64 Mon Sep 17 00:00:00 2001 From: Zee Alexander Date: Thu, 30 Jul 2015 15:11:26 -0700 Subject: Remove colorful language from module. --- README.markdown | 2 +- lib/puppet/parser/functions/validate_integer.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.markdown b/README.markdown index 090bb09..9f40e28 100644 --- a/README.markdown +++ b/README.markdown @@ -889,7 +889,7 @@ Validates that the first argument is an integer (or an array of integers). Abort * Plus all of the above, but any combination of values passed as strings ('false' or "false"). * Plus all of the above, but with incorrect combinations of negative integer values. - * Plus all of the above, but with non-integer crap in arrays or maximum / minimum argument. + * Plus all of the above, but with non-integer items in arrays or maximum / minimum argument. *Type*: statement. diff --git a/lib/puppet/parser/functions/validate_integer.rb b/lib/puppet/parser/functions/validate_integer.rb index 95da0c4..a950916 100644 --- a/lib/puppet/parser/functions/validate_integer.rb +++ b/lib/puppet/parser/functions/validate_integer.rb @@ -49,7 +49,7 @@ module Puppet::Parser::Functions Plus all of the above, but any combination of values passed as strings ('false' or "false"). Plus all of the above, but with incorrect combinations of negative integer values. - Plus all of the above, but with non-integer crap in arrays or maximum / minimum argument. + Plus all of the above, but with non-integer items in arrays or maximum / minimum argument. ENDHEREDOC -- cgit v1.2.3 From f411ee7119cab1277baffee2fe2b2f978f402072 Mon Sep 17 00:00:00 2001 From: Spencer Krum Date: Thu, 9 Jul 2015 10:53:56 -0700 Subject: Add load_metadata_json function This function loads the metadata.json into a puppet variable. This enables a number of neat things such as: * Which version of the module am I using? 2.x? 3.x? * Which author of the module am I using? puppetlabs? example42? --- README.markdown | 11 +++++++++++ lib/puppet/parser/functions/load_module_metadata.rb | 16 ++++++++++++++++ spec/functions/load_module_metadata.rb | 16 ++++++++++++++++ 3 files changed, 43 insertions(+) create mode 100644 lib/puppet/parser/functions/load_module_metadata.rb create mode 100755 spec/functions/load_module_metadata.rb diff --git a/README.markdown b/README.markdown index 7eed5d7..9853da8 100644 --- a/README.markdown +++ b/README.markdown @@ -449,6 +449,17 @@ Loads a YAML file containing an array, string, or hash, and returns the data in *Type*: rvalue. +#### `load_module_metadata` + +Loads the metadata.json of a target module. Can be used to determine module version and authorship for dynamic support of modules. + + ~~~ + $metadata = load_module_metadata('archive') + notify { $metadata['author']: } + ~~~ + +*Type*: rvalue. + #### `lstrip` Strips spaces to the left of a string. *Type*: rvalue. diff --git a/lib/puppet/parser/functions/load_module_metadata.rb b/lib/puppet/parser/functions/load_module_metadata.rb new file mode 100644 index 0000000..0664a23 --- /dev/null +++ b/lib/puppet/parser/functions/load_module_metadata.rb @@ -0,0 +1,16 @@ +module Puppet::Parser::Functions + newfunction(:load_module_metadata, :type => :rvalue, :doc => <<-EOT + EOT + ) do |args| + raise(Puppet::ParseError, "load_module_metadata(): Wrong number of arguments, expects one") unless args.size == 1 + mod = args[0] + module_path = function_get_module_path([mod]) + metadata_json = File.join(module_path, 'metadata.json') + + raise(Puppet::ParseError, "load_module_metadata(): No metadata.json file for module #{mod}") unless File.exists?(metadata_json) + + metadata = PSON.load(File.read(metadata_json)) + + return metadata + end +end diff --git a/spec/functions/load_module_metadata.rb b/spec/functions/load_module_metadata.rb new file mode 100755 index 0000000..ba542eb --- /dev/null +++ b/spec/functions/load_module_metadata.rb @@ -0,0 +1,16 @@ +require 'spec_helper' + +describe 'load_module_metadata' 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("one", "two").and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } + + it "should json parse the file" do + allow(scope).to receive(:function_get_module_path).with(['science']).and_return('/path/to/module/') + allow(File).to receive(:exists?).with(/metadata.json/).and_return(true) + allow(File).to receive(:read).with(/metadata.json/).and_return('{"name": "spencer-science"}') + + result = subject.call(['science']) + expect(result['name']).to eq('spencer-science') + end +end -- cgit v1.2.3 From a7adcda803abe82e6a16e2410c10d58abedbd82d Mon Sep 17 00:00:00 2001 From: Dominic Cleal Date: Tue, 4 Aug 2015 09:59:53 +0100 Subject: (MODULES-2316) Change file_type boolean parameter to symbols Puppet's boolean parameter type is only available in Puppet 3.3 and higher, so change file_type's new "replace" parameter to a regular parameter with true and false as possible values. This matches the existing "multiple" parameter. --- lib/puppet/provider/file_line/ruby.rb | 4 ++-- lib/puppet/type/file_line.rb | 4 ++-- spec/unit/puppet/provider/file_line/ruby_spec.rb | 2 +- spec/unit/puppet/type/file_line_spec.rb | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/puppet/provider/file_line/ruby.rb b/lib/puppet/provider/file_line/ruby.rb index ea1d44d..d4cdfec 100644 --- a/lib/puppet/provider/file_line/ruby.rb +++ b/lib/puppet/provider/file_line/ruby.rb @@ -1,6 +1,6 @@ Puppet::Type.type(:file_line).provide(:ruby) do def exists? - if !resource[:replace] and count_matches(match_regex) > 0 + if resource[:replace].to_s != 'true' and count_matches(match_regex) > 0 true else lines.find do |line| @@ -10,7 +10,7 @@ Puppet::Type.type(:file_line).provide(:ruby) do end def create - unless !resource[:replace] and count_matches(match_regex) > 0 + unless resource[:replace].to_s != 'true' and count_matches(match_regex) > 0 if resource[:match] handle_create_with_match elsif resource[:after] diff --git a/lib/puppet/type/file_line.rb b/lib/puppet/type/file_line.rb index 190105c..4a96ba7 100644 --- a/lib/puppet/type/file_line.rb +++ b/lib/puppet/type/file_line.rb @@ -1,4 +1,3 @@ -require 'puppet/parameter/boolean' Puppet::Type.newtype(:file_line) do desc <<-EOT @@ -79,8 +78,9 @@ Puppet::Type.newtype(:file_line) do end end - newparam(:replace, :boolean => true, :parent => Puppet::Parameter::Boolean) do + newparam(:replace) do desc 'If true, replace line that matches. If false, do not write line if a match is found' + newvalues(true, false) defaultto true end diff --git a/spec/unit/puppet/provider/file_line/ruby_spec.rb b/spec/unit/puppet/provider/file_line/ruby_spec.rb index 5eff09a..792391a 100755 --- a/spec/unit/puppet/provider/file_line/ruby_spec.rb +++ b/spec/unit/puppet/provider/file_line/ruby_spec.rb @@ -85,7 +85,7 @@ describe provider_class do :replace => 'asgadga', } ) - }.to raise_error(Puppet::Error, /Invalid value "asgadga"\. Valid values are true, false, yes, no\./) + }.to raise_error(Puppet::Error, /Invalid value "asgadga"\. Valid values are true, false\./) end end context "when matching" do diff --git a/spec/unit/puppet/type/file_line_spec.rb b/spec/unit/puppet/type/file_line_spec.rb index 58c88e3..f1430f2 100755 --- a/spec/unit/puppet/type/file_line_spec.rb +++ b/spec/unit/puppet/type/file_line_spec.rb @@ -50,7 +50,7 @@ describe Puppet::Type.type(:file_line) do expect(file_line[:ensure]).to eq :present end it 'should default to replace => true' do - expect(file_line[:replace]).to eq true + expect(file_line[:replace]).to eq :true end it "should autorequire the file it manages" do -- cgit v1.2.3 From 9bacf14ca24283a94883523064603babcd7046d3 Mon Sep 17 00:00:00 2001 From: Johnson Earls Date: Thu, 6 Aug 2015 13:00:11 -0700 Subject: allow `match` parameter to influence `ensure => absent` behavior. Split the `destroy` method of the file_type::ruby provider into two private methods: `handle_destroy_line` which is the same as the previous `destroy` method, and `handle_destroy_with_match` which will destroy any line which matches the `match` parameter, raising an error if multiple lines match and the `multiple` parameter is not `true`. This new behavior is only used if the new boolean parameter `match_for_absence` is `true` (it defaults to `false`). --- lib/puppet/provider/file_line/ruby.rb | 26 ++++++- lib/puppet/type/file_line.rb | 22 ++++++ spec/unit/puppet/provider/file_line/ruby_spec.rb | 96 ++++++++++++++++++++++++ 3 files changed, 141 insertions(+), 3 deletions(-) diff --git a/lib/puppet/provider/file_line/ruby.rb b/lib/puppet/provider/file_line/ruby.rb index d4cdfec..aab6fe2 100644 --- a/lib/puppet/provider/file_line/ruby.rb +++ b/lib/puppet/provider/file_line/ruby.rb @@ -22,9 +22,10 @@ Puppet::Type.type(:file_line).provide(:ruby) do end def destroy - local_lines = lines - File.open(resource[:path],'w') do |fh| - fh.write(local_lines.reject{|l| l.chomp == resource[:line] }.join('')) + if resource[:match_for_absence].to_s == 'true' and resource[:match] + handle_destroy_with_match + else + handle_destroy_line end end @@ -93,6 +94,25 @@ Puppet::Type.type(:file_line).provide(:ruby) do lines.select{|l| l.match(regex)}.size end + def handle_destroy_with_match + match_count = count_matches(match_regex) + if match_count > 1 && resource[:multiple].to_s != 'true' + raise Puppet::Error, "More than one line in file '#{resource[:path]}' matches pattern '#{resource[:match]}'" + end + + local_lines = lines + File.open(resource[:path],'w') do |fh| + fh.write(local_lines.reject{|l| match_regex.match(l) }.join('')) + end + end + + def handle_destroy_line + local_lines = lines + File.open(resource[:path],'w') do |fh| + fh.write(local_lines.reject{|l| l.chomp == resource[:line] }.join('')) + end + end + ## # append the line to the file. # diff --git a/lib/puppet/type/file_line.rb b/lib/puppet/type/file_line.rb index 4a96ba7..446f103 100644 --- a/lib/puppet/type/file_line.rb +++ b/lib/puppet/type/file_line.rb @@ -34,6 +34,20 @@ Puppet::Type.newtype(:file_line) do In this code example match will look for a line beginning with export followed by HTTP_PROXY and replace it with the value in line. + Match Example With `ensure => absent`: + + file_line { 'bashrc_proxy': + ensure => absent, + path => '/etc/bashrc', + line => 'export HTTP_PROXY=http://squid.puppetlabs.vm:3128', + match => '^export\ HTTP_PROXY\=', + match_for_absence => true, + } + + In this code example match will look for a line beginning with export + followed by HTTP_PROXY and delete it. If multiple lines match, an + error will be raised unless the `multiple => true` parameter is set. + **Autorequires:** If Puppet is managing the file that will contain the line being managed, the file_line resource will autorequire that file. @@ -55,6 +69,14 @@ Puppet::Type.newtype(:file_line) do ' match an exception will be raised. ' end + newparam(:match_for_absence) do + desc 'An optional value to determine if match should be applied when ensure => absent.' + + ' If set to true and match is set, the line that matches match will be deleted.' + + ' If set to false (the default), match is ignored when ensure => absent.' + newvalues(true, false) + defaultto false + end + newparam(:multiple) do desc 'An optional value to determine if match can change multiple lines.' + ' If set to false, an exception will be raised if more than one line matches' diff --git a/spec/unit/puppet/provider/file_line/ruby_spec.rb b/spec/unit/puppet/provider/file_line/ruby_spec.rb index 792391a..23e649c 100755 --- a/spec/unit/puppet/provider/file_line/ruby_spec.rb +++ b/spec/unit/puppet/provider/file_line/ruby_spec.rb @@ -341,4 +341,100 @@ describe provider_class do expect(File.read(@tmpfile)).to eql("foo1\nfoo2\n") end end + + context "when removing with a match" do + before :each do + # TODO: these should be ported over to use the PuppetLabs spec_helper + # file fixtures once the following pull request has been merged: + # https://github.com/puppetlabs/puppetlabs-stdlib/pull/73/files + tmp = Tempfile.new('tmp') + @tmpfile = tmp.path + tmp.close! + @resource = Puppet::Type::File_line.new( + { + :name => 'foo', + :path => @tmpfile, + :line => 'foo2', + :ensure => 'absent', + :match => 'o$', + :match_for_absence => true, + } + ) + @provider = provider_class.new(@resource) + end + + it 'should remove one line if it matches' do + File.open(@tmpfile, 'w') do |fh| + fh.write("foo1\nfoo\nfoo2") + end + @provider.destroy + expect(File.read(@tmpfile)).to eql("foo1\nfoo2") + end + + it 'should raise an error if more than one line matches' do + File.open(@tmpfile, 'w') do |fh| + fh.write("foo1\nfoo\nfoo2\nfoo\nfoo") + end + expect { @provider.destroy }.to raise_error(Puppet::Error, /More than one line/) + end + + it 'should remove multiple lines if :multiple is true' do + @resource = Puppet::Type::File_line.new( + { + :name => 'foo', + :path => @tmpfile, + :line => 'foo2', + :ensure => 'absent', + :match => 'o$', + :multiple => true, + :match_for_absence => true, + } + ) + @provider = provider_class.new(@resource) + File.open(@tmpfile, 'w') do |fh| + fh.write("foo1\nfoo\nfoo2\nfoo\nfoo") + end + @provider.destroy + expect(File.read(@tmpfile)).to eql("foo1\nfoo2\n") + end + + it 'should ignore the match if match_for_absense is not specified' do + @resource = Puppet::Type::File_line.new( + { + :name => 'foo', + :path => @tmpfile, + :line => 'foo2', + :ensure => 'absent', + :match => 'o$', + } + ) + @provider = provider_class.new(@resource) + File.open(@tmpfile, 'w') do |fh| + fh.write("foo1\nfoo\nfoo2") + end + @provider.destroy + expect(File.read(@tmpfile)).to eql("foo1\nfoo\n") + end + + it 'should ignore the match if match_for_absense is false' do + @resource = Puppet::Type::File_line.new( + { + :name => 'foo', + :path => @tmpfile, + :line => 'foo2', + :ensure => 'absent', + :match => 'o$', + :match_for_absence => false, + } + ) + @provider = provider_class.new(@resource) + File.open(@tmpfile, 'w') do |fh| + fh.write("foo1\nfoo\nfoo2") + end + @provider.destroy + expect(File.read(@tmpfile)).to eql("foo1\nfoo\n") + end + + end + end -- cgit v1.2.3 From dfa98b89f7a5513cccc5a4ded4b119dee39d1a59 Mon Sep 17 00:00:00 2001 From: Hunter Haugen Date: Mon, 10 Aug 2015 16:15:54 -0700 Subject: Prep 4.8.0 --- CHANGELOG.md | 13 +++++++++++++ metadata.json | 2 +- spec/acceptance/ensure_resource_spec.rb | 2 +- spec/spec_helper_acceptance.rb | 14 ++++++-------- 4 files changed, 21 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7343cef..1daa5f0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,16 @@ +## 2015-08-10 - Supported Release 4.8.0 +### Summary +This release adds a function for reading metadata.json from any module, and expands file\_line's abilities. + +#### Features +- New parameter `replace` on `file_line` +- New function `load_module_metadata()` to load metadata.json and return the content as a hash. +- Added hash support to `size()` + +#### Bugfixes +- Fix various docs typos +- Fix `file_line` resource on puppet < 3.3 + ##2015-06-22 - Supported Release 4.7.0 ###Summary diff --git a/metadata.json b/metadata.json index 5c20ade..dab84e5 100644 --- a/metadata.json +++ b/metadata.json @@ -1,6 +1,6 @@ { "name": "puppetlabs-stdlib", - "version": "4.7.0", + "version": "4.8.0", "author": "puppetlabs", "summary": "Standard library of resources for Puppet modules.", "license": "Apache-2.0", diff --git a/spec/acceptance/ensure_resource_spec.rb b/spec/acceptance/ensure_resource_spec.rb index 1cee53d..fe619a9 100755 --- a/spec/acceptance/ensure_resource_spec.rb +++ b/spec/acceptance/ensure_resource_spec.rb @@ -1,7 +1,7 @@ #! /usr/bin/env ruby -S rspec require 'spec_helper_acceptance' -describe 'ensure_resource function', :unless => fact('osfamily') =~ /windows/i do +describe 'ensure_resource function', :unless => fact('osfamily') =~ /(windows|Suse)/i do describe 'success' do it 'ensure_resource a package' do apply_manifest('package { "rake": ensure => absent, provider => "gem", }') diff --git a/spec/spec_helper_acceptance.rb b/spec/spec_helper_acceptance.rb index 03ff993..406fcb6 100755 --- a/spec/spec_helper_acceptance.rb +++ b/spec/spec_helper_acceptance.rb @@ -35,15 +35,13 @@ end RSpec.shared_context "with faked facts" do let(:facts_d) do - puppet_version = (on default, puppet('--version')).output.chomp - if Puppet::Util::Package.versioncmp(puppet_version, '4.0.0') < 0 && fact('is_pe', '--puppet') == "true" - if fact('osfamily') =~ /windows/i - if fact('kernelmajversion').to_f < 6.0 - 'C:/Documents and Settings/All Users/Application Data/PuppetLabs/facter/facts.d' - else - 'C:/ProgramData/PuppetLabs/facter/facts.d' - end + if fact('osfamily') =~ /windows/i + if fact('kernelmajversion').to_f < 6.0 + 'C:/Documents and Settings/All Users/Application Data/PuppetLabs/facter/facts.d' else + 'C:/ProgramData/PuppetLabs/facter/facts.d' + end + elsif fact('is_pe', '--puppet') == "true" '/etc/puppetlabs/facter/facts.d' end else -- cgit v1.2.3 From 0a58b9382c9cb5eb74519219dfe0cce1dd814993 Mon Sep 17 00:00:00 2001 From: Hunter Haugen Date: Tue, 11 Aug 2015 08:29:48 -0700 Subject: Fix extraneous end --- spec/spec_helper_acceptance.rb | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/spec/spec_helper_acceptance.rb b/spec/spec_helper_acceptance.rb index 406fcb6..5556cbf 100755 --- a/spec/spec_helper_acceptance.rb +++ b/spec/spec_helper_acceptance.rb @@ -42,8 +42,7 @@ RSpec.shared_context "with faked facts" do 'C:/ProgramData/PuppetLabs/facter/facts.d' end elsif fact('is_pe', '--puppet') == "true" - '/etc/puppetlabs/facter/facts.d' - end + '/etc/puppetlabs/facter/facts.d' else '/etc/facter/facts.d' end -- cgit v1.2.3 From 9baca7f7556e1db3722e992244f98e54aef41309 Mon Sep 17 00:00:00 2001 From: Hunter Haugen Date: Tue, 11 Aug 2015 16:23:06 -0700 Subject: Sometimes this exits 1 --- spec/spec_helper_acceptance.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/spec_helper_acceptance.rb b/spec/spec_helper_acceptance.rb index 5556cbf..67a6e33 100755 --- a/spec/spec_helper_acceptance.rb +++ b/spec/spec_helper_acceptance.rb @@ -56,7 +56,7 @@ RSpec.shared_context "with faked facts" do end after :each do - shell("rm -f '#{facts_d}/fqdn.txt'") + shell("rm -f '#{facts_d}/fqdn.txt'", :acceptable_exit_codes => [0,1]) end def fake_fact(name, value) -- cgit v1.2.3 From 57275061ab63f26c0fc08361cb0d838708b1003c Mon Sep 17 00:00:00 2001 From: Hunter Haugen Date: Tue, 11 Aug 2015 19:52:43 -0700 Subject: Add puppet_version back to spec_helper --- spec/spec_helper_acceptance.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/spec/spec_helper_acceptance.rb b/spec/spec_helper_acceptance.rb index 67a6e33..f784112 100755 --- a/spec/spec_helper_acceptance.rb +++ b/spec/spec_helper_acceptance.rb @@ -35,13 +35,14 @@ end RSpec.shared_context "with faked facts" do let(:facts_d) do + puppet_version = (on default, puppet('--version')).output.chomp if fact('osfamily') =~ /windows/i if fact('kernelmajversion').to_f < 6.0 'C:/Documents and Settings/All Users/Application Data/PuppetLabs/facter/facts.d' else 'C:/ProgramData/PuppetLabs/facter/facts.d' end - elsif fact('is_pe', '--puppet') == "true" + elsif Puppet::Util::Package.versioncmp(puppet_version, '4.0.0') < 0 and fact('is_pe', '--puppet') == "true" '/etc/puppetlabs/facter/facts.d' else '/etc/facter/facts.d' -- cgit v1.2.3 From 4cbe846750c40dec57c55dbe6382dfa57c4d79af Mon Sep 17 00:00:00 2001 From: Nigel Gibbs Date: Fri, 14 Aug 2015 09:33:46 +0100 Subject: (MODULES-2410) Add new functions dos2unix and unix2dos --- CHANGELOG.md | 14 ++++++++++++ README.markdown | 36 +++++++++++++++++++++++------ lib/puppet/parser/functions/dos2unix.rb | 15 +++++++++++++ lib/puppet/parser/functions/unix2dos.rb | 15 +++++++++++++ spec/functions/dos2unix_spec.rb | 40 +++++++++++++++++++++++++++++++++ spec/functions/unix2dos_spec.rb | 40 +++++++++++++++++++++++++++++++++ 6 files changed, 153 insertions(+), 7 deletions(-) create mode 100644 lib/puppet/parser/functions/dos2unix.rb create mode 100644 lib/puppet/parser/functions/unix2dos.rb create mode 100644 spec/functions/dos2unix_spec.rb create mode 100644 spec/functions/unix2dos_spec.rb diff --git a/CHANGELOG.md b/CHANGELOG.md index 1daa5f0..3b35d01 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,17 @@ +##2015-08-13 - Supported Release 4.8.1 +###Summary + +Adds some new functions. + +####Features +- Add new functions: `dos2unix` and `unix2dos` + +####Bugfixes +- n/a + +####Improvements +- n/a + ## 2015-08-10 - Supported Release 4.8.0 ### Summary This release adds a function for reading metadata.json from any module, and expands file\_line's abilities. diff --git a/README.markdown b/README.markdown index 594a55f..f949dca 100644 --- a/README.markdown +++ b/README.markdown @@ -199,6 +199,19 @@ Returns the difference between two arrays. The returned array is a copy of the o Returns the `dirname` of a path. For example, `dirname('/path/to/a/file.ext')` returns '/path/to/a'. *Type*: rvalue. +#### `dos2unix` + +Returns the Unix version of the given string. Very useful when using a File resource with a cross-platform template. *Type*: rvalue. + +~~~ +file{$config_file: + ensure => file, + content => dos2unix(template('my_module/settings.conf.erb')), +} +~~~ + +See also [unix2dos](#unix2dos). + #### `downcase` Converts the case of a string or of all strings in an array to lowercase. *Type*: rvalue. @@ -471,7 +484,7 @@ Returns the highest value of all arguments. Requires at least one argument. *Typ #### `member` -This function determines if a variable is a member of an array. The variable can be either a string, array, or fixnum. For example, `member(['a','b'], 'b')` and `member(['a','b','c'], ['b','c'])` return 'true', while `member(['a','b'], 'c')` and `member(['a','b','c'], ['c','d'])` return 'false'. *Note*: This function does not support nested arrays. If the first argument contains nested arrays, it will not recurse through them. +This function determines if a variable is a member of an array. The variable can be either a string, array, or fixnum. For example, `member(['a','b'], 'b')` and `member(['a','b','c'], ['b','c'])` return 'true', while `member(['a','b'], 'c')` and `member(['a','b','c'], ['c','d'])` return 'false'. *Note*: This function does not support nested arrays. If the first argument contains nested arrays, it will not recurse through them. *Type*: rvalue. @@ -520,7 +533,7 @@ From a list of values, returns the first value that is not undefined or an empty #### `prefix` Applies a prefix to all elements in an array, or to the keys in a hash. -For example: +For example: * `prefix(['a','b','c'], 'p')` returns ['pa','pb','pc'] * `prefix({'a'=>'b','b'=>'c','c'=>'d'}, 'p')` returns {'pa'=>'b','pb'=>'c','pc'=>'d'}. @@ -697,6 +710,19 @@ Returns a union of two arrays, without duplicates. For example, `union(["a","b", Removes duplicates from strings and arrays. For example, `unique("aabbcc")` returns 'abc', and `unique(["a","a","b","b","c","c"])` returns ["a","b","c"]. *Type*: rvalue. +#### `unix2dos` + +Returns the DOS version of the given string. Very useful when using a File resource with a cross-platform template. *Type*: rvalue. + +~~~ +file{$config_file: + ensure => file, + content => unix2dos(template('my_module/settings.conf.erb')), +} +~~~ + +See also [dos2unix](#dos2unix). + #### `upcase` Converts an object, array or hash of objects that respond to upcase to uppercase. For example, `upcase('abcd')` returns 'ABCD'. *Type*: rvalue. @@ -1002,7 +1028,7 @@ Instead, use: #### `values` -Returns the values of a given hash. For example, given `$hash = {'a'=1, 'b'=2, 'c'=3} values($hash)` returns [1,2,3]. +Returns the values of a given hash. For example, given `$hash = {'a'=1, 'b'=2, 'c'=3} values($hash)` returns [1,2,3]. *Type*: rvalue. @@ -1048,7 +1074,3 @@ To report or research a bug with any part of this module, please go to ##Contributors The list of contributors can be found at: https://github.com/puppetlabs/puppetlabs-stdlib/graphs/contributors - - - - diff --git a/lib/puppet/parser/functions/dos2unix.rb b/lib/puppet/parser/functions/dos2unix.rb new file mode 100644 index 0000000..ccac899 --- /dev/null +++ b/lib/puppet/parser/functions/dos2unix.rb @@ -0,0 +1,15 @@ +# Custom Puppet function to convert dos to unix format +module Puppet::Parser::Functions + newfunction(:dos2unix, :type => :rvalue, :arity => 1, :doc => <<-EOS + Returns the Unix version of the given string. + Takes a single string argument. + EOS + ) do |arguments| + + unless arguments[0].is_a?(String) + raise(Puppet::ParseError, 'dos2unix(): Requires string as argument') + end + + arguments[0].gsub(/\r\n/, "\n") + end +end diff --git a/lib/puppet/parser/functions/unix2dos.rb b/lib/puppet/parser/functions/unix2dos.rb new file mode 100644 index 0000000..0bd9cd1 --- /dev/null +++ b/lib/puppet/parser/functions/unix2dos.rb @@ -0,0 +1,15 @@ +# Custom Puppet function to convert unix to dos format +module Puppet::Parser::Functions + newfunction(:unix2dos, :type => :rvalue, :arity => 1, :doc => <<-EOS + Returns the DOS version of the given string. + Takes a single string argument. + EOS + ) do |arguments| + + unless arguments[0].is_a?(String) + raise(Puppet::ParseError, 'unix2dos(): Requires string as argument') + end + + arguments[0].gsub(/\r*\n/, "\r\n") + end +end diff --git a/spec/functions/dos2unix_spec.rb b/spec/functions/dos2unix_spec.rb new file mode 100644 index 0000000..9c84703 --- /dev/null +++ b/spec/functions/dos2unix_spec.rb @@ -0,0 +1,40 @@ +require 'spec_helper' + +describe 'dos2unix' do + context 'Checking parameter validity' do + it { is_expected.not_to eq(nil) } + it do + is_expected.to run.with_params.and_raise_error(ArgumentError, /Wrong number of arguments/) + end + it do + is_expected.to run.with_params('one', 'two').and_raise_error(ArgumentError, /Wrong number of arguments/) + end + it do + is_expected.to run.with_params([]).and_raise_error(Puppet::ParseError) + end + it do + is_expected.to run.with_params({}).and_raise_error(Puppet::ParseError) + end + it do + is_expected.to run.with_params(1).and_raise_error(Puppet::ParseError) + end + end + + context 'Converting from dos to unix format' do + sample_text = "Hello\r\nWorld\r\n" + desired_output = "Hello\nWorld\n" + + it 'should output unix format' do + should run.with_params(sample_text).and_return(desired_output) + end + end + + context 'Converting from unix to unix format' do + sample_text = "Hello\nWorld\n" + desired_output = "Hello\nWorld\n" + + it 'should output unix format' do + should run.with_params(sample_text).and_return(desired_output) + end + end +end diff --git a/spec/functions/unix2dos_spec.rb b/spec/functions/unix2dos_spec.rb new file mode 100644 index 0000000..8537a26 --- /dev/null +++ b/spec/functions/unix2dos_spec.rb @@ -0,0 +1,40 @@ +require 'spec_helper' + +describe 'unix2dos' do + context 'Checking parameter validity' do + it { is_expected.not_to eq(nil) } + it do + is_expected.to run.with_params.and_raise_error(ArgumentError, /Wrong number of arguments/) + end + it do + is_expected.to run.with_params('one', 'two').and_raise_error(ArgumentError, /Wrong number of arguments/) + end + it do + is_expected.to run.with_params([]).and_raise_error(Puppet::ParseError) + end + it do + is_expected.to run.with_params({}).and_raise_error(Puppet::ParseError) + end + it do + is_expected.to run.with_params(1).and_raise_error(Puppet::ParseError) + end + end + + context 'Converting from unix to dos format' do + sample_text = "Hello\nWorld\n" + desired_output = "Hello\r\nWorld\r\n" + + it 'should output dos format' do + should run.with_params(sample_text).and_return(desired_output) + end + end + + context 'Converting from dos to dos format' do + sample_text = "Hello\r\nWorld\r\n" + desired_output = "Hello\r\nWorld\r\n" + + it 'should output dos format' do + should run.with_params(sample_text).and_return(desired_output) + end + end +end -- cgit v1.2.3 From 66e118a92aa480739f62e4675ed80c79ef80619c Mon Sep 17 00:00:00 2001 From: Ben Ford Date: Wed, 19 Aug 2015 08:31:36 -0700 Subject: Add a service_provider fact This returns the default provider Puppet will choose to manage services on this system by instantiating a dummy service resource type and returning the provider chosen. Co-Authored-By: Simon Fraser University --- lib/facter/service_provider.rb | 14 ++++++++++++ spec/unit/facter/service_provider_spec.rb | 37 +++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+) create mode 100644 lib/facter/service_provider.rb create mode 100644 spec/unit/facter/service_provider_spec.rb diff --git a/lib/facter/service_provider.rb b/lib/facter/service_provider.rb new file mode 100644 index 0000000..54db937 --- /dev/null +++ b/lib/facter/service_provider.rb @@ -0,0 +1,14 @@ +# Fact: service_provider +# +# Purpose: Returns the default provider Puppet will choose to manage services +# on this system +# +# Resolution: Instantiates a dummy service resource and return the provider +# +# Caveats: +# +Facter.add(:service_provider) do + setcode do + Puppet::Type.type(:service).newservice(:name => 'dummy')[:provider].to_s + end +end diff --git a/spec/unit/facter/service_provider_spec.rb b/spec/unit/facter/service_provider_spec.rb new file mode 100644 index 0000000..ad8a5fc --- /dev/null +++ b/spec/unit/facter/service_provider_spec.rb @@ -0,0 +1,37 @@ +#! /usr/bin/env ruby -S rspec +require 'spec_helper' +require 'puppet/type' +require 'puppet/type/service' + +describe 'service_provider', :type => :fact do + before { Facter.clear } + after { Facter.clear } + + context "macosx" do + it "should return launchd" do + provider = Puppet::Type.type(:service).provider(:launchd) + Puppet::Type.type(:service).stubs(:defaultprovider).returns provider + + expect(Facter.fact(:service_provider).value).to eq('launchd') + end + end + + context "systemd" do + it "should return systemd" do + provider = Puppet::Type.type(:service).provider(:systemd) + Puppet::Type.type(:service).stubs(:defaultprovider).returns provider + + expect(Facter.fact(:service_provider).value).to eq('systemd') + end + end + + context "redhat" do + it "should return redhat" do + provider = Puppet::Type.type(:service).provider(:redhat) + Puppet::Type.type(:service).stubs(:defaultprovider).returns provider + + expect(Facter.fact(:service_provider).value).to eq('redhat') + end + end + +end -- cgit v1.2.3 From 1d9189d860f28067b72093cbe4027cf49b7d612c Mon Sep 17 00:00:00 2001 From: Jetroid Date: Mon, 24 Aug 2015 12:01:29 +0100 Subject: (MODULE-2456) Modify union to accept more than two arrays Add spec tests to test the new functionality: *Case for 3 arrays. *Case for 4 arrays. Modify README to note new functionality. This is for issue MODULE-2456, follow the precedent of MODULE-444. This change allows union to be much more useful, unioning many arrays in one line rather than in n lines. Additionally, as this is only added functionality, and does not affect the 2 array case that all modules currently using array are using, it should not affect any existing modules utilizing union. This is now useful, for example, for merging many arrays of resources (eg: packages.) to generate just one list with no duplicates, to avoid duplicate resource declarations. --- README.markdown | 2 +- lib/puppet/parser/functions/union.rb | 17 ++++++----------- spec/acceptance/union_spec.rb | 5 +++-- spec/functions/union_spec.rb | 9 +++++---- 4 files changed, 15 insertions(+), 18 deletions(-) diff --git a/README.markdown b/README.markdown index f949dca..e71241f 100644 --- a/README.markdown +++ b/README.markdown @@ -704,7 +704,7 @@ Returns the literal type when passed a value. Requires the new parser. Useful fo #### `union` -Returns a union of two arrays, without duplicates. For example, `union(["a","b","c"],["b","c","d"])` returns ["a","b","c","d"]. +Returns a union of two or more arrays, without duplicates. For example, `union(["a","b","c"],["b","c","d"])` returns ["a","b","c","d"]. #### `unique` diff --git a/lib/puppet/parser/functions/union.rb b/lib/puppet/parser/functions/union.rb index c91bb80..6c5bb83 100644 --- a/lib/puppet/parser/functions/union.rb +++ b/lib/puppet/parser/functions/union.rb @@ -4,7 +4,7 @@ module Puppet::Parser::Functions newfunction(:union, :type => :rvalue, :doc => <<-EOS -This function returns a union of two arrays. +This function returns a union of two or more arrays. *Examples:* @@ -14,20 +14,15 @@ Would return: ["a","b","c","d"] EOS ) do |arguments| - # Two arguments are required + # Check that 2 or more arguments have been given ... raise(Puppet::ParseError, "union(): Wrong number of arguments " + - "given (#{arguments.size} for 2)") if arguments.size != 2 + "given (#{arguments.size} for < 2)") if arguments.size < 2 - first = arguments[0] - second = arguments[1] - - unless first.is_a?(Array) && second.is_a?(Array) - raise(Puppet::ParseError, 'union(): Requires 2 arrays') + arguments.each do |argument| + raise(Puppet::ParseError, 'union(): Every parameter must be an array') unless argument.is_a?(Array) end - result = first | second - - return result + arguments.reduce(:|) end end diff --git a/spec/acceptance/union_spec.rb b/spec/acceptance/union_spec.rb index 6db8d0c..160fd7b 100755 --- a/spec/acceptance/union_spec.rb +++ b/spec/acceptance/union_spec.rb @@ -6,9 +6,10 @@ describe 'union function', :unless => UNSUPPORTED_PLATFORMS.include?(fact('opera it 'unions arrays' do pp = <<-EOS $a = ["the","public"] - $b = ["art","galleries"] + $b = ["art"] + $c = ["galleries"] # Anagram: Large picture halls, I bet - $o = union($a,$b) + $o = union($a,$b,$c) notice(inline_template('union is <%= @o.inspect %>')) EOS diff --git a/spec/functions/union_spec.rb b/spec/functions/union_spec.rb index 970e1fe..cfd38b6 100755 --- a/spec/functions/union_spec.rb +++ b/spec/functions/union_spec.rb @@ -5,10 +5,9 @@ describe 'union' 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('one').and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } - it { is_expected.to run.with_params('one', 'two', 'three').and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } - it { is_expected.to run.with_params('one', []).and_raise_error(Puppet::ParseError, /Requires 2 arrays/) } - it { is_expected.to run.with_params([], 'two').and_raise_error(Puppet::ParseError, /Requires 2 arrays/) } - it { is_expected.to run.with_params({}, {}).and_raise_error(Puppet::ParseError, /Requires 2 arrays/) } + it { is_expected.to run.with_params('one', []).and_raise_error(Puppet::ParseError, /Every parameter must be an array/) } + it { is_expected.to run.with_params([], 'two').and_raise_error(Puppet::ParseError, /Every parameter must be an array/) } + it { is_expected.to run.with_params({}, {}).and_raise_error(Puppet::ParseError, /Every parameter must be an array/) } end it { is_expected.to run.with_params([], []).and_return([]) } @@ -19,5 +18,7 @@ describe 'union' do it { is_expected.to run.with_params(['one', 'two', 'three'], ['two', 'three']).and_return(['one', 'two', 'three']) } it { is_expected.to run.with_params(['one', 'two', 'two', 'three'], ['two', 'three']).and_return(['one', 'two', 'three']) } it { is_expected.to run.with_params(['one', 'two', 'three'], ['two', 'two', 'three']).and_return(['one', 'two', 'three']) } + it { is_expected.to run.with_params(['one', 'two'], ['two', 'three'], ['one', 'three']).and_return(['one', 'two', 'three']) } + it { is_expected.to run.with_params(['one', 'two'], ['three', 'four'], ['one', 'two', 'three'], ['four']).and_return(['one', 'two', 'three', 'four']) } it 'should not confuse types' do is_expected.to run.with_params(['1', '2', '3'], [1, 2]).and_return(['1', '2', '3', 1, 2]) end end -- cgit v1.2.3 From aa23894dd3e3259f73b0e0999b8b183988696a81 Mon Sep 17 00:00:00 2001 From: David Schmitt Date: Mon, 24 Aug 2015 20:12:14 +0100 Subject: (MAINT) improve base64 unit tests --- spec/functions/base64_spec.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/spec/functions/base64_spec.rb b/spec/functions/base64_spec.rb index 42512b3..c529e9e 100755 --- a/spec/functions/base64_spec.rb +++ b/spec/functions/base64_spec.rb @@ -10,6 +10,7 @@ describe 'base64' do it { is_expected.to run.with_params("encode", 2).and_raise_error(Puppet::ParseError, /second argument must be a string/) } it { is_expected.to run.with_params("encode", "thestring").and_return("dGhlc3RyaW5n\n") } + it { is_expected.to run.with_params("encode", "a very long string that will cause the base64 encoder to produce output with multiple lines").and_return("YSB2ZXJ5IGxvbmcgc3RyaW5nIHRoYXQgd2lsbCBjYXVzZSB0aGUgYmFzZTY0\nIGVuY29kZXIgdG8gcHJvZHVjZSBvdXRwdXQgd2l0aCBtdWx0aXBsZSBsaW5l\ncw==\n") } it { is_expected.to run.with_params("decode", "dGhlc3RyaW5n").and_return("thestring") } it { is_expected.to run.with_params("decode", "dGhlc3RyaW5n\n").and_return("thestring") } end -- cgit v1.2.3 From ba345abfb75e0d6840a174f4d6c9b1967105385d Mon Sep 17 00:00:00 2001 From: Jetroid Date: Tue, 25 Aug 2015 10:35:57 +0100 Subject: Add consistent *Type* information Remove trailing whitespace Two functions had not been given any *Type* information. This commit fixes that. --- README.markdown | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/README.markdown b/README.markdown index e71241f..591c27b 100644 --- a/README.markdown +++ b/README.markdown @@ -532,10 +532,10 @@ From a list of values, returns the first value that is not undefined or an empty #### `prefix` -Applies a prefix to all elements in an array, or to the keys in a hash. +Applies a prefix to all elements in an array, or to the keys in a hash. For example: * `prefix(['a','b','c'], 'p')` returns ['pa','pb','pc'] -* `prefix({'a'=>'b','b'=>'c','c'=>'d'}, 'p')` returns {'pa'=>'b','pb'=>'c','pc'=>'d'}. +* `prefix({'a'=>'b','b'=>'c','c'=>'d'}, 'p')` returns {'pa'=>'b','pb'=>'c','pc'=>'d'}. *Type*: rvalue. @@ -573,6 +573,8 @@ The second argument to this function is which type of hash to use. It will be co The third argument to this function is the salt to use. +*Type*: rvalue. + **Note:** this uses the Puppet master's implementation of crypt(3). If your environment contains several different operating systems, ensure that they are compatible before using this function. #### `range` @@ -704,7 +706,7 @@ Returns the literal type when passed a value. Requires the new parser. Useful fo #### `union` -Returns a union of two or more arrays, without duplicates. For example, `union(["a","b","c"],["b","c","d"])` returns ["a","b","c","d"]. +Returns a union of two or more arrays, without duplicates. For example, `union(["a","b","c"],["b","c","d"])` returns ["a","b","c","d"]. *Type*: rvalue. #### `unique` -- cgit v1.2.3 From eb948c4a0dc36790c5444fc236b0154c3d716c58 Mon Sep 17 00:00:00 2001 From: Dmitry Ilyin Date: Mon, 24 Aug 2015 22:00:18 +0300 Subject: [MODULES-2462] Improve parseyaml function * Add default value support Second argument will be returned if yaml cannot be parsed instead of false value * Update tests --- README.markdown | 2 + lib/puppet/parser/functions/parsejson.rb | 23 +++++----- lib/puppet/parser/functions/parseyaml.rb | 20 +++++---- spec/acceptance/parsejson_spec.rb | 17 ++++++-- spec/acceptance/parseyaml_spec.rb | 19 +++++--- spec/functions/parsejson_spec.rb | 65 +++++++++++++++++++++++++--- spec/functions/parseyaml_spec.rb | 74 ++++++++++++++++++++++++++++---- 7 files changed, 178 insertions(+), 42 deletions(-) diff --git a/README.markdown b/README.markdown index 8ed3d9b..2f84a24 100644 --- a/README.markdown +++ b/README.markdown @@ -490,10 +490,12 @@ Converts a number or a string representation of a number into a true boolean. Ze #### `parsejson` Converts a string of JSON into the correct Puppet structure. *Type*: rvalue. +The optional second argument will be returned if the data was not correct. #### `parseyaml` Converts a string of YAML into the correct Puppet structure. *Type*: rvalue. +The optional second argument will be returned if the data was not correct. #### `pick` diff --git a/lib/puppet/parser/functions/parsejson.rb b/lib/puppet/parser/functions/parsejson.rb index a9a16a4..f822fc4 100644 --- a/lib/puppet/parser/functions/parsejson.rb +++ b/lib/puppet/parser/functions/parsejson.rb @@ -3,21 +3,22 @@ # module Puppet::Parser::Functions - newfunction(:parsejson, :type => :rvalue, :doc => <<-EOS -This function accepts JSON as a string and converts into the correct Puppet -structure. - EOS + newfunction(:parsejson, :type => :rvalue, :arity => -2, :doc => <<-EOS +This function accepts JSON as a string and converts it into the correct +Puppet structure. + +The optional second argument can be used to pass a default value that will +be returned if the parsing of YAML string have failed. + EOS ) do |arguments| + raise ArgumentError, 'Wrong number of arguments. 1 or 2 arguments should be provided.' unless arguments.length >= 1 - if (arguments.size != 1) then - raise(Puppet::ParseError, "parsejson(): Wrong number of arguments "+ - "given #{arguments.size} for 1") + begin + PSON::load(arguments[0]) || arguments[1] + rescue Exception + arguments[1] end - json = arguments[0] - - # PSON is natively available in puppet - PSON.load(json) end end diff --git a/lib/puppet/parser/functions/parseyaml.rb b/lib/puppet/parser/functions/parseyaml.rb index 53d54fa..d38b3ef 100644 --- a/lib/puppet/parser/functions/parseyaml.rb +++ b/lib/puppet/parser/functions/parseyaml.rb @@ -3,20 +3,22 @@ # module Puppet::Parser::Functions - newfunction(:parseyaml, :type => :rvalue, :doc => <<-EOS + newfunction(:parseyaml, :type => :rvalue, :arity => -2, :doc => <<-EOS This function accepts YAML as a string and converts it into the correct Puppet structure. - EOS - ) do |arguments| - - if (arguments.size != 1) then - raise(Puppet::ParseError, "parseyaml(): Wrong number of arguments "+ - "given #{arguments.size} for 1") - end +The optional second argument can be used to pass a default value that will +be returned if the parsing of YAML string have failed. + EOS + ) do |arguments| + raise ArgumentError, 'Wrong number of arguments. 1 or 2 arguments should be provided.' unless arguments.length >= 1 require 'yaml' - YAML::load(arguments[0]) + begin + YAML::load(arguments[0]) || arguments[1] + rescue Exception + arguments[1] + end end end diff --git a/spec/acceptance/parsejson_spec.rb b/spec/acceptance/parsejson_spec.rb index 5097810..d0feabd 100755 --- a/spec/acceptance/parsejson_spec.rb +++ b/spec/acceptance/parsejson_spec.rb @@ -16,19 +16,28 @@ describe 'parsejson function', :unless => UNSUPPORTED_PLATFORMS.include?(fact('o end end end + describe 'failure' do it 'raises error on incorrect json' do pp = <<-EOS $a = '{"hunter": "washere", "tests": "passing",}' - $ao = parsejson($a) + $ao = parsejson($a, {'tests' => 'using the default value'}) notice(inline_template('a is <%= @ao.inspect %>')) EOS - apply_manifest(pp, :expect_failures => true) do |r| - expect(r.stderr).to match(/expected next name/) + apply_manifest(pp, :catch_failures => true) do |r| + expect(r.stdout).to match(/tests are "using the default value"/) end end - it 'raises error on incorrect number of arguments' + it 'raises error on incorrect number of arguments' do + pp = <<-EOS + $o = parsejson() + EOS + + apply_manifest(pp, :expect_failures => true) do |r| + expect(r.stderr).to match(/wrong number of arguments/i) + end + end end end diff --git a/spec/acceptance/parseyaml_spec.rb b/spec/acceptance/parseyaml_spec.rb index 5819837..7946de0 100755 --- a/spec/acceptance/parseyaml_spec.rb +++ b/spec/acceptance/parseyaml_spec.rb @@ -16,20 +16,29 @@ describe 'parseyaml function', :unless => UNSUPPORTED_PLATFORMS.include?(fact('o end end end + describe 'failure' do - it 'raises error on incorrect yaml' do + it 'returns the default value on incorrect yaml' do pp = <<-EOS $a = "---\nhunter: washere\ntests: passing\n:" - $o = parseyaml($a) + $o = parseyaml($a, {'tests' => 'using the default value'}) $tests = $o['tests'] notice(inline_template('tests are <%= @tests.inspect %>')) EOS - apply_manifest(pp, :expect_failures => true) do |r| - expect(r.stderr).to match(/(syntax error|did not find expected key)/) + apply_manifest(pp, :catch_failures => true) do |r| + expect(r.stdout).to match(/tests are "using the default value"/) end end - it 'raises error on incorrect number of arguments' + it 'raises error on incorrect number of arguments' do + pp = <<-EOS + $o = parseyaml() + EOS + + apply_manifest(pp, :expect_failures => true) do |r| + expect(r.stderr).to match(/wrong number of arguments/i) + end + end end end diff --git a/spec/functions/parsejson_spec.rb b/spec/functions/parsejson_spec.rb index 436566e..5bea8af 100755 --- a/spec/functions/parsejson_spec.rb +++ b/spec/functions/parsejson_spec.rb @@ -1,9 +1,64 @@ require 'spec_helper' describe 'parsejson' 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('["one"').and_raise_error(PSON::ParserError) } - it { is_expected.to run.with_params('["one", "two", "three"]').and_return(['one', 'two', 'three']) } + it 'should exist' do + is_expected.not_to eq(nil) + end + + it 'should raise an error if called without any arguments' do + is_expected.to run.with_params(). + and_raise_error(/wrong number of arguments/i) + end + + context 'with correct JSON data' do + + it 'should be able to parse a JSON data with a Hash' do + is_expected.to run.with_params('{"a":"1","b":"2"}'). + and_return({'a'=>'1', 'b'=>'2'}) + end + + it 'should be able to parse a JSON data with an Array' do + is_expected.to run.with_params('["a","b","c"]'). + and_return(['a', 'b', 'c']) + end + + it 'should be able to parse empty JSON values' do + is_expected.to run.with_params('[]'). + and_return([]) + is_expected.to run.with_params('{}'). + and_return({}) + end + + it 'should be able to parse a JSON data with a mixed structure' do + is_expected.to run.with_params('{"a":"1","b":2,"c":{"d":[true,false]}}'). + and_return({'a' =>'1', 'b' => 2, 'c' => { 'd' => [true, false] } }) + end + + it 'should not return the default value if the data was parsed correctly' do + is_expected.to run.with_params('{"a":"1"}', 'default_value'). + and_return({'a' => '1'}) + end + + end + + context 'with incorrect YAML data' do + it 'should return "nil" if a default value should be returned but is not provided' do + is_expected.to run.with_params(''). + and_return(nil) + end + + it 'should support a structure for a default value' do + is_expected.to run.with_params('', {'a' => '1'}). + and_return({'a' => '1'}) + end + + ['', 1, 1.2, nil, true, false, [], {}, :yaml].each do |value| + it "should return the default value for an incorrect #{value.inspect} (#{value.class}) parameter" do + is_expected.to run.with_params(value, 'default_value'). + and_return('default_value') + end + end + + end + end diff --git a/spec/functions/parseyaml_spec.rb b/spec/functions/parseyaml_spec.rb index fb635f8..492a1c9 100755 --- a/spec/functions/parseyaml_spec.rb +++ b/spec/functions/parseyaml_spec.rb @@ -1,14 +1,72 @@ require 'spec_helper' describe 'parseyaml' 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('["one", "two", "three"]').and_return(['one', 'two', 'three']) } - context 'when running on modern rubies', :unless => RUBY_VERSION == '1.8.7' do - it { is_expected.to run.with_params('["one"').and_raise_error(Psych::SyntaxError) } + it 'should exist' do + is_expected.not_to eq(nil) end - context 'when running on ruby 1.8.7, which does not have Psych', :if => RUBY_VERSION == '1.8.7' do - it { is_expected.to run.with_params('["one"').and_raise_error(ArgumentError) } + + it 'should raise an error if called without any arguments' do + is_expected.to run.with_params(). + and_raise_error(/wrong number of arguments/i) + end + + context 'with correct YAML data' do + it 'should be able to parse a YAML data with a String' do + is_expected.to run.with_params('--- just a string'). + and_return('just a string') + is_expected.to run.with_params('just a string'). + and_return('just a string') + end + + it 'should be able to parse a YAML data with a Hash' do + is_expected.to run.with_params("---\na: '1'\nb: '2'\n"). + and_return({'a' => '1', 'b' => '2'}) + end + + it 'should be able to parse a YAML data with an Array' do + is_expected.to run.with_params("---\n- a\n- b\n- c\n"). + and_return(['a', 'b', 'c']) + end + + it 'should be able to parse a YAML data with a mixed structure' do + is_expected.to run.with_params("---\na: '1'\nb: 2\nc:\n d:\n - :a\n - true\n - false\n"). + and_return({'a' => '1', 'b' => 2, 'c' => {'d' => [:a, true, false]}}) + end + + it 'should not return the default value if the data was parsed correctly' do + is_expected.to run.with_params("---\na: '1'\n", 'default_value'). + and_return({'a' => '1'}) + end + end + + context 'with incorrect YAML data' do + it 'should return "nil" if a default value should be returned but is not provided' do + is_expected.to run.with_params(''). + and_return(nil) + end + + it 'should support a structure for a default value' do + is_expected.to run.with_params('', {'a' => '1'}). + and_return({'a' => '1'}) + end + + [1, 1.2, nil, true, false, [], {}, :yaml].each do |value| + it "should return the default value for an incorrect #{value.inspect} (#{value.class}) parameter" do + is_expected.to run.with_params(value, 'default_value'). + and_return('default_value') + end + end + + context 'when running on modern rubies', :unless => RUBY_VERSION == '1.8.7' do + ['---', '...', '*8', ''].each do |value| + it "should return the default value for an incorrect #{value.inspect} string parameter" do + is_expected.to run.with_params(value, 'default_value'). + and_return('default_value') + end + end + end + + end + end -- cgit v1.2.3 From 2d4f5aa4d943e27ffeae524469f9c6eb18ce64d8 Mon Sep 17 00:00:00 2001 From: fhats Date: Thu, 27 Aug 2015 10:40:20 +0100 Subject: Adds a convert_base function, which can convert numbers between bases Squashed, improved docs, updated error handling and unit tests by David S. --- README.markdown | 6 +++++ lib/puppet/parser/functions/convert_base.rb | 35 +++++++++++++++++++++++++++++ spec/functions/convert_base_spec.rb | 24 ++++++++++++++++++++ 3 files changed, 65 insertions(+) create mode 100644 lib/puppet/parser/functions/convert_base.rb create mode 100644 spec/functions/convert_base_spec.rb diff --git a/README.markdown b/README.markdown index 591c27b..ccbceab 100644 --- a/README.markdown +++ b/README.markdown @@ -155,6 +155,12 @@ Appends the contents of multiple arrays onto the first array given. For example: * `concat(['1','2','3'],'4',['5','6','7'])` returns ['1','2','3','4','5','6','7']. *Type*: rvalue. +#### `convert_base` + +Converts a given integer or base 10 string representing an integer to a specified base, as a string. For example: + * `convert_base(5, 2)` results in: '101' + * `convert_base('254', '16')` results in: 'fe' + #### `count` If called with only an array, it counts the number of elements that are **not** nil/undef. If called with a second argument, counts the number of elements in an array that matches the second argument. *Type*: rvalue. diff --git a/lib/puppet/parser/functions/convert_base.rb b/lib/puppet/parser/functions/convert_base.rb new file mode 100644 index 0000000..0fcbafe --- /dev/null +++ b/lib/puppet/parser/functions/convert_base.rb @@ -0,0 +1,35 @@ +module Puppet::Parser::Functions + + newfunction(:convert_base, :type => :rvalue, :arity => 2, :doc => <<-'ENDHEREDOC') do |args| + + Converts a given integer or base 10 string representing an integer to a specified base, as a string. + + Usage: + + $binary_repr = convert_base(5, 2) # $binary_repr is now set to "101" + $hex_repr = convert_base("254", "16") # $hex_repr is now set to "fe" + + ENDHEREDOC + + raise Puppet::ParseError, ("convert_base(): First argument must be either a string or an integer") unless (args[0].is_a?(Integer) or args[0].is_a?(String)) + raise Puppet::ParseError, ("convert_base(): Second argument must be either a string or an integer") unless (args[1].is_a?(Integer) or args[1].is_a?(String)) + + if args[0].is_a?(String) + raise Puppet::ParseError, ("convert_base(): First argument must be an integer or a string corresponding to an integer in base 10") unless args[0] =~ /^[0-9]+$/ + end + + if args[1].is_a?(String) + raise Puppet::ParseError, ("convert_base(): First argument must be an integer or a string corresponding to an integer in base 10") unless args[1] =~ /^[0-9]+$/ + end + + number_to_convert = args[0] + new_base = args[1] + + number_to_convert = number_to_convert.to_i() + new_base = new_base.to_i() + + raise Puppet::ParseError, ("convert_base(): base must be at least 2 and must not be greater than 36") unless new_base >= 2 and new_base <= 36 + + return number_to_convert.to_s(new_base) + end +end diff --git a/spec/functions/convert_base_spec.rb b/spec/functions/convert_base_spec.rb new file mode 100644 index 0000000..8ab2284 --- /dev/null +++ b/spec/functions/convert_base_spec.rb @@ -0,0 +1,24 @@ +require 'spec_helper' + +describe 'convert_base' do + it { is_expected.not_to eq(nil) } + it { is_expected.to run.with_params().and_raise_error(ArgumentError) } + it { is_expected.to run.with_params("asdf").and_raise_error(ArgumentError) } + it { is_expected.to run.with_params("asdf","moo","cow").and_raise_error(ArgumentError) } + it { is_expected.to run.with_params(["1"],"2").and_raise_error(Puppet::ParseError, /argument must be either a string or an integer/) } + it { is_expected.to run.with_params("1",["2"]).and_raise_error(Puppet::ParseError, /argument must be either a string or an integer/) } + it { is_expected.to run.with_params("1",1).and_raise_error(Puppet::ParseError, /base must be at least 2 and must not be greater than 36/) } + it { is_expected.to run.with_params("1",37).and_raise_error(Puppet::ParseError, /base must be at least 2 and must not be greater than 36/) } + + it "should raise a ParseError if argument 1 is a string that does not correspond to an integer in base 10" do + is_expected.to run.with_params("ten",6).and_raise_error(Puppet::ParseError, /argument must be an integer or a string corresponding to an integer in base 10/) + end + + it "should raise a ParseError if argument 2 is a string and does not correspond to an integer in base 10" do + is_expected.to run.with_params(100,"hex").and_raise_error(Puppet::ParseError, /argument must be an integer or a string corresponding to an integer in base 10/) + end + + it { is_expected.to run.with_params("11",'16').and_return('b') } + it { is_expected.to run.with_params("35",'36').and_return('z') } + it { is_expected.to run.with_params(5, 2).and_return('101') } +end -- cgit v1.2.3 From 6c2a003f2139a482f92f245ce1d49830be13c5f1 Mon Sep 17 00:00:00 2001 From: Jon Fautley Date: Thu, 27 Aug 2015 14:53:02 +0100 Subject: (MODULES-2478) Support root_home fact on AIX through "lsuser" command Squashed, and amended test for comment lines. --- lib/facter/root_home.rb | 13 +++++++++++++ spec/fixtures/lsuser/root | 2 ++ spec/unit/facter/root_home_spec.rb | 13 +++++++++++++ 3 files changed, 28 insertions(+) create mode 100644 spec/fixtures/lsuser/root diff --git a/lib/facter/root_home.rb b/lib/facter/root_home.rb index b4f87ff..ee3ffa8 100644 --- a/lib/facter/root_home.rb +++ b/lib/facter/root_home.rb @@ -30,3 +30,16 @@ Facter.add(:root_home) do hash['dir'].strip end end + +Facter.add(:root_home) do + confine :kernel => :aix + root_home = nil + setcode do + str = Facter::Util::Resolution.exec("lsuser -C -a home root") + str && str.split("\n").each do |line| + next if line =~ /^#/ + root_home = line.split(/:/)[1] + end + root_home + end +end diff --git a/spec/fixtures/lsuser/root b/spec/fixtures/lsuser/root new file mode 100644 index 0000000..afd59ca --- /dev/null +++ b/spec/fixtures/lsuser/root @@ -0,0 +1,2 @@ +#name:home +root:/root diff --git a/spec/unit/facter/root_home_spec.rb b/spec/unit/facter/root_home_spec.rb index 98fe141..ac5160a 100755 --- a/spec/unit/facter/root_home_spec.rb +++ b/spec/unit/facter/root_home_spec.rb @@ -49,4 +49,17 @@ describe 'root_home', :type => :fact do end end + context "aix" do + before do + Facter.fact(:kernel).stubs(:value).returns("AIX") + Facter.fact(:osfamily).stubs(:value).returns("AIX") + end + let(:expected_root_home) { "/root" } + sample_lsuser = File.read(fixtures('lsuser','root')) + + it "should return /root" do + Facter::Util::Resolution.stubs(:exec).with("lsuser -C -a home root").returns(sample_lsuser) + expect(Facter.fact(:root_home).value).to eq(expected_root_home) + end + end end -- cgit v1.2.3 From 823a352f0f47d4481844bb6b6a6c00224ed556b8 Mon Sep 17 00:00:00 2001 From: Dmitry Ilyin Date: Tue, 1 Sep 2015 21:39:16 +0300 Subject: Add a new function "try_get_value" * Extracts a value from a deeply-nested data structure * Returns default if a value could not be extracted --- README.markdown | 34 +++++++++ lib/puppet/parser/functions/try_get_value.rb | 77 +++++++++++++++++++++ spec/acceptance/try_get_value_spec.rb | 47 +++++++++++++ spec/functions/try_get_value_spec.rb | 100 +++++++++++++++++++++++++++ 4 files changed, 258 insertions(+) create mode 100644 lib/puppet/parser/functions/try_get_value.rb create mode 100755 spec/acceptance/try_get_value_spec.rb create mode 100644 spec/functions/try_get_value_spec.rb diff --git a/README.markdown b/README.markdown index 8ed3d9b..22bece8 100644 --- a/README.markdown +++ b/README.markdown @@ -669,6 +669,40 @@ Returns the current Unix epoch time as an integer. For example, `time()` returns Converts the argument into bytes, for example "4 kB" becomes "4096". Takes a single string value as an argument. *Type*: rvalue. +#### `try_get_value` + +*Type*: rvalue. + +Looks up into a complex structure of arrays and hashes and returns a value +or the default value if nothing was found. + +Key can contain slashes to describe path components. The function will go down +the structure and try to extract the required value. + +$data = { + 'a' => { + 'b' => [ + 'b1', + 'b2', + 'b3', + ] + } +} + +$value = try_get_value($data, 'a/b/2', 'not_found', '/') +=> $value = 'b3' + +a -> first hash key +b -> second hash key +2 -> array index starting with 0 + +not_found -> (optional) will be returned if there is no value or the path did not match. Defaults to nil. +/ -> (optional) path delimiter. Defaults to '/'. + +In addition to the required "key" argument, "try_get_value" accepts default +argument. It will be returned if no value was found or a path component is +missing. And the fourth argument can set a variable path separator. + #### `type3x` Returns a string description of the type when passed a value. Type can be a string, array, hash, float, integer, or boolean. This function will be removed when Puppet 3 support is dropped and the new type system can be used. *Type*: rvalue. diff --git a/lib/puppet/parser/functions/try_get_value.rb b/lib/puppet/parser/functions/try_get_value.rb new file mode 100644 index 0000000..0c19fd9 --- /dev/null +++ b/lib/puppet/parser/functions/try_get_value.rb @@ -0,0 +1,77 @@ +module Puppet::Parser::Functions + newfunction( + :try_get_value, + :type => :rvalue, + :arity => -2, + :doc => <<-eos +Looks up into a complex structure of arrays and hashes and returns a value +or the default value if nothing was found. + +Key can contain slashes to describe path components. The function will go down +the structure and try to extract the required value. + +$data = { + 'a' => { + 'b' => [ + 'b1', + 'b2', + 'b3', + ] + } +} + +$value = try_get_value($data, 'a/b/2', 'not_found', '/') +=> $value = 'b3' + +a -> first hash key +b -> second hash key +2 -> array index starting with 0 + +not_found -> (optional) will be returned if there is no value or the path did not match. Defaults to nil. +/ -> (optional) path delimiter. Defaults to '/'. + +In addition to the required "key" argument, "try_get_value" accepts default +argument. It will be returned if no value was found or a path component is +missing. And the fourth argument can set a variable path separator. + eos + ) do |args| + path_lookup = lambda do |data, path, default| + debug "Try_get_value: #{path.inspect} from: #{data.inspect}" + if data.nil? + debug "Try_get_value: no data, return default: #{default.inspect}" + break default + end + unless path.is_a? Array + debug "Try_get_value: wrong path, return default: #{default.inspect}" + break default + end + unless path.any? + debug "Try_get_value: value found, return data: #{data.inspect}" + break data + end + unless data.is_a? Hash or data.is_a? Array + debug "Try_get_value: incorrect data, return default: #{default.inspect}" + break default + end + + key = path.shift + if data.is_a? Array + begin + key = Integer key + rescue ArgumentError + debug "Try_get_value: non-numeric path for an array, return default: #{default.inspect}" + break default + end + end + path_lookup.call data[key], path, default + end + + data = args[0] + path = args[1] || '' + default = args[2] + separator = args[3] || '/' + + path = path.split separator + path_lookup.call data, path, default + end +end diff --git a/spec/acceptance/try_get_value_spec.rb b/spec/acceptance/try_get_value_spec.rb new file mode 100755 index 0000000..46b1c4d --- /dev/null +++ b/spec/acceptance/try_get_value_spec.rb @@ -0,0 +1,47 @@ +#! /usr/bin/env ruby -S rspec +require 'spec_helper_acceptance' + +describe 'try_get_value function', :unless => UNSUPPORTED_PLATFORMS.include?(fact('operatingsystem')) do + describe 'success' do + it 'try_get_valuees a value' do + pp = <<-EOS + $data = { + 'a' => { 'b' => 'passing'} + } + + $tests = try_get_value($a, 'a/b') + notice(inline_template('tests are <%= @tests.inspect %>')) + EOS + + apply_manifest(pp, :catch_failures => true) do |r| + expect(r.stdout).to match(/tests are "passing"/) + end + end + end + describe 'failure' do + it 'uses a default value' do + pp = <<-EOS + $data = { + 'a' => { 'b' => 'passing'} + } + + $tests = try_get_value($a, 'c/d', 'using the default value') + notice(inline_template('tests are <%= @tests.inspect %>')) + EOS + + apply_manifest(pp, :expect_failures => true) do |r| + expect(r.stdout).to match(/using the default value/) + end + end + + it 'raises error on incorrect number of arguments' do + pp = <<-EOS + $o = try_get_value() + EOS + + apply_manifest(pp, :expect_failures => true) do |r| + expect(r.stderr).to match(/wrong number of arguments/i) + end + end + end +end diff --git a/spec/functions/try_get_value_spec.rb b/spec/functions/try_get_value_spec.rb new file mode 100644 index 0000000..38c0efd --- /dev/null +++ b/spec/functions/try_get_value_spec.rb @@ -0,0 +1,100 @@ +require 'spec_helper' + +describe 'try_get_value' do + + let(:data) do + { + 'a' => { + 'g' => '2', + 'e' => [ + 'f0', + 'f1', + { + 'x' => { + 'y' => 'z' + } + }, + 'f3', + ] + }, + 'b' => true, + 'c' => false, + 'd' => '1', + } + end + + context 'single values' do + it 'should exist' do + is_expected.not_to eq(nil) + end + + it 'should be able to return a single value' do + is_expected.to run.with_params('test').and_return('test') + end + + it 'should use the default value if data is a single value and path is present' do + is_expected.to run.with_params('test', 'path', 'default').and_return('default') + end + + it 'should return default if there is no data' do + is_expected.to run.with_params(nil, nil, 'default').and_return('default') + end + + it 'should be able to use data structures as default values' do + is_expected.to run.with_params('test', 'path', data).and_return(data) + end + end + + context 'structure values' do + it 'should be able to extracts a single hash value' do + is_expected.to run.with_params(data, 'd', 'default').and_return('1') + end + + it 'should be able to extract a deeply nested hash value' do + is_expected.to run.with_params(data, 'a/g', 'default').and_return('2') + end + + it 'should return the default value if the path is not found' do + is_expected.to run.with_params(data, 'missing', 'default').and_return('default') + end + + it 'should return the default value if the path is too long' do + is_expected.to run.with_params(data, 'a/g/c/d', 'default').and_return('default') + end + + it 'should support an array index in the path' do + is_expected.to run.with_params(data, 'a/e/1', 'default').and_return('f1') + end + + it 'should return the default value if an array index is not a number' do + is_expected.to run.with_params(data, 'a/b/c', 'default').and_return('default') + end + + it 'should return the default value if and index is out of array length' do + is_expected.to run.with_params(data, 'a/e/5', 'default').and_return('default') + end + + it 'should be able to path though both arrays and hashes' do + is_expected.to run.with_params(data, 'a/e/2/x/y', 'default').and_return('z') + end + + it 'should be able to return "true" value' do + is_expected.to run.with_params(data, 'b', 'default').and_return(true) + is_expected.to run.with_params(data, 'm', true).and_return(true) + end + + it 'should be able to return "false" value' do + is_expected.to run.with_params(data, 'c', 'default').and_return(false) + is_expected.to run.with_params(data, 'm', false).and_return(false) + end + + it 'should return "nil" if value is not found and no default value is provided' do + is_expected.to run.with_params(data, 'a/1').and_return(nil) + end + + it 'should be able to use a custom path separator' do + is_expected.to run.with_params(data, 'a::g', 'default', '::').and_return('2') + is_expected.to run.with_params(data, 'a::c', 'default', '::').and_return('default') + end + end +end -- cgit v1.2.3 From 5ef5c6629fee2eecba0389eab3c3ce2f3d57d0f4 Mon Sep 17 00:00:00 2001 From: David Schmitt Date: Wed, 2 Sep 2015 13:34:15 +0100 Subject: (MAINT) fix up try_get_value acceptance test --- spec/acceptance/try_get_value_spec.rb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/spec/acceptance/try_get_value_spec.rb b/spec/acceptance/try_get_value_spec.rb index 46b1c4d..c0bf38a 100755 --- a/spec/acceptance/try_get_value_spec.rb +++ b/spec/acceptance/try_get_value_spec.rb @@ -3,13 +3,13 @@ require 'spec_helper_acceptance' describe 'try_get_value function', :unless => UNSUPPORTED_PLATFORMS.include?(fact('operatingsystem')) do describe 'success' do - it 'try_get_valuees a value' do + it 'gets a value' do pp = <<-EOS $data = { 'a' => { 'b' => 'passing'} } - $tests = try_get_value($a, 'a/b') + $tests = try_get_value($data, 'a/b') notice(inline_template('tests are <%= @tests.inspect %>')) EOS @@ -25,11 +25,11 @@ describe 'try_get_value function', :unless => UNSUPPORTED_PLATFORMS.include?(fac 'a' => { 'b' => 'passing'} } - $tests = try_get_value($a, 'c/d', 'using the default value') + $tests = try_get_value($data, 'c/d', 'using the default value') notice(inline_template('tests are <%= @tests.inspect %>')) EOS - apply_manifest(pp, :expect_failures => true) do |r| + apply_manifest(pp, :catch_failures => true) do |r| expect(r.stdout).to match(/using the default value/) end end -- cgit v1.2.3 From 05c6587d852800cc69e3a9381ff466ac3aa630d2 Mon Sep 17 00:00:00 2001 From: Jonathan Tripathy Date: Thu, 3 Sep 2015 15:17:32 +0100 Subject: Release Prep 4.9.0 --- CHANGELOG.md | 15 +++++++++++---- metadata.json | 2 +- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3b35d01..f5bd8c7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,16 +1,23 @@ -##2015-08-13 - Supported Release 4.8.1 +##2015-09-08 - Supported Release 4.9.0 ###Summary -Adds some new functions. +This release adds new features including the new functions dos2unix, unix2dos, try_get_value, convert_base as well as other features and improvements. ####Features -- Add new functions: `dos2unix` and `unix2dos` +- (MODULES-2370) allow `match` parameter to influence `ensure => absent` behavior +- (MODULES-2410) Add new functions dos2unix and unix2dos +- (MODULE-2456) Modify union to accept more than two arrays +- Adds a convert_base function, which can convert numbers between bases +- Add a new function "try_get_value" ####Bugfixes - n/a ####Improvements -- n/a +- (MODULES-2478) Support root_home fact on AIX through "lsuser" command +- Acceptance test improvements +- Unit test improvements +- Readme improvements ## 2015-08-10 - Supported Release 4.8.0 ### Summary diff --git a/metadata.json b/metadata.json index dab84e5..2378787 100644 --- a/metadata.json +++ b/metadata.json @@ -1,6 +1,6 @@ { "name": "puppetlabs-stdlib", - "version": "4.8.0", + "version": "4.9.0", "author": "puppetlabs", "summary": "Standard library of resources for Puppet modules.", "license": "Apache-2.0", -- cgit v1.2.3 From f2f2db4795fc0e3b9387e1e6c003e8e75efde903 Mon Sep 17 00:00:00 2001 From: Corey Osman Date: Thu, 3 Sep 2015 10:31:51 -0700 Subject: accept any case of boolean strings * previously the str2bool function did not accept 'TRUE' as a bool type. This causes the function to now accept TRUE, FALSE strings as a boolean type in order to be converted to a proper boolean. * This would also cause Y,N, YES, NO to be accepted as boolean types as well. --- README.markdown | 2 +- lib/puppet/parser/functions/str2bool.rb | 8 ++++---- spec/functions/str2bool_spec.rb | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/README.markdown b/README.markdown index a880222..3cc47a5 100644 --- a/README.markdown +++ b/README.markdown @@ -623,7 +623,7 @@ Returns a new string where runs of the same character that occur in this set are #### `str2bool` -Converts a string to a boolean. This attempts to convert strings that contain values such as '1', 't', 'y', and 'yes' to 'true' and strings that contain values such as '0', 'f', 'n', and 'no' to 'false'. *Type*: rvalue. +Converts a string to a boolean regardless of case. This attempts to convert strings that contain values such as '1', 't', 'y', 'Y', 'YES','yes', and 'TRUE' to 'true' and strings that contain values such as '0', 'f','F', 'N','n', 'NO','FALSE', and 'no' to 'false'. *Type*: rvalue. #### `str2saltedsha512` diff --git a/lib/puppet/parser/functions/str2bool.rb b/lib/puppet/parser/functions/str2bool.rb index 446732e..8def131 100644 --- a/lib/puppet/parser/functions/str2bool.rb +++ b/lib/puppet/parser/functions/str2bool.rb @@ -5,8 +5,8 @@ module Puppet::Parser::Functions newfunction(:str2bool, :type => :rvalue, :doc => <<-EOS This converts a string to a boolean. This attempt to convert strings that -contain things like: y, 1, t, true to 'true' and strings that contain things -like: 0, f, n, false, no to 'false'. +contain things like: Y,y, 1, T,t, TRUE,true to 'true' and strings that contain things +like: 0, F,f, N,n, false, FALSE, no to 'false'. EOS ) do |arguments| @@ -32,8 +32,8 @@ like: 0, f, n, false, no to 'false'. # We yield false in this case. # when /^$/, '' then false # Empty string will be false ... - when /^(1|t|y|true|yes)$/ then true - when /^(0|f|n|false|no)$/ then false + when /^(1|t|y|true|yes)$/i then true + when /^(0|f|n|false|no)$/i then false when /^(undef|undefined)$/ then false # This is not likely to happen ... else raise(Puppet::ParseError, 'str2bool(): Unknown type of boolean given') diff --git a/spec/functions/str2bool_spec.rb b/spec/functions/str2bool_spec.rb index 3b439b2..7d8c47c 100755 --- a/spec/functions/str2bool_spec.rb +++ b/spec/functions/str2bool_spec.rb @@ -10,13 +10,13 @@ describe 'str2bool' do it { is_expected.to run.with_params('one').and_raise_error(Puppet::ParseError, /Unknown type of boolean given/) } describe 'when testing values that mean "true"' do - [ '1', 't', 'y', 'true', 'yes', true ].each do |value| + [ 'TRUE','1', 't', 'y', 'true', 'yes', true ].each do |value| it { is_expected.to run.with_params(value).and_return(true) } end end describe 'when testing values that mean "false"' do - [ '', '0', 'f', 'n', 'false', 'no', false, 'undef', 'undefined' ].each do |value| + [ 'FALSE','', '0', 'f', 'n', 'false', 'no', false, 'undef', 'undefined' ].each do |value| it { is_expected.to run.with_params(value).and_return(false) } end end -- cgit v1.2.3 From 411978db322cefda4e156537491b15dddbf2698f Mon Sep 17 00:00:00 2001 From: Dmitry Ilyin Date: Fri, 4 Sep 2015 19:12:21 +0300 Subject: [MAINT] Improve 'try_get_value' readme --- README.markdown | 51 +++++++++++++++++++++++++++++++++------------------ 1 file changed, 33 insertions(+), 18 deletions(-) diff --git a/README.markdown b/README.markdown index a880222..d345947 100644 --- a/README.markdown +++ b/README.markdown @@ -706,12 +706,18 @@ Converts the argument into bytes, for example "4 kB" becomes "4096". Takes a sin *Type*: rvalue. -Looks up into a complex structure of arrays and hashes and returns a value -or the default value if nothing was found. - -Key can contain slashes to describe path components. The function will go down -the structure and try to extract the required value. - +Looks up into a complex structure of arrays and hashes to extract a value by +its path in the structure. The path is a string of hash keys or array indexes +starting with zero, separated by the path separator character (default "/"). +The function will go down the structure by each path component and will try to +return the value at the end of the path. + +In addition to the required "path" argument the function accepts the default +argument. It will be returned if the path is not correct, no value was found or +a any other error have occurred. And the last argument can set the path +separator character. + +```ruby $data = { 'a' => { 'b' => [ @@ -722,19 +728,28 @@ $data = { } } -$value = try_get_value($data, 'a/b/2', 'not_found', '/') -=> $value = 'b3' - -a -> first hash key -b -> second hash key -2 -> array index starting with 0 - -not_found -> (optional) will be returned if there is no value or the path did not match. Defaults to nil. -/ -> (optional) path delimiter. Defaults to '/'. +$value = try_get_value($data, 'a/b/2') +# $value = 'b3' -In addition to the required "key" argument, "try_get_value" accepts default -argument. It will be returned if no value was found or a path component is -missing. And the fourth argument can set a variable path separator. +# with all possible options +$value = try_get_value($data, 'a/b/2', 'not_found', '/') +# $value = 'b3' + +# using the default value +$value = try_get_value($data, 'a/b/c/d', 'not_found') +# $value = 'not_found' + +# using custom separator +$value = try_get_value($data, 'a|b', [], '|') +# $value = ['b1','b2','b3'] +``` + +1. **$data** The data structure we are working with. +2. **'a/b/2'** The path string. +3. **'not_found'** The default value. It will be returned if nothing is found. + (optional, defaults to *undef*) +4. **'/'** The path separator character. + (optional, defaults to *'/'*) #### `type3x` -- cgit v1.2.3 From 00c881d0dabe77fd2401beb0d39c7386b50bb791 Mon Sep 17 00:00:00 2001 From: David Schmitt Date: Mon, 14 Sep 2015 18:26:25 +0100 Subject: (MODULES-2516) Adds an is_a() function The data type system is very hard to understand. Many people don't understand why type_of([1,2,3]) == Array will fail, but type_of([1,2,3]) <= Array passes. This does a simpler validation that doesn't rely on explicit data types. Instead, use $foo = [1,2,3] if $foo.is_a(Array) { notify { 'This is an array': } } This is based on code by Ben Ford . * Added acceptance tests * Added dispatch * Improved unit tests * Added docs to README --- README.markdown | 23 +++++++++++++++++++++++ lib/puppet/functions/is_a.rb | 32 ++++++++++++++++++++++++++++++++ spec/acceptance/is_a_spec.rb | 28 ++++++++++++++++++++++++++++ spec/functions/is_a_spec.rb | 25 +++++++++++++++++++++++++ spec/functions/type_of_spec.rb | 4 +++- 5 files changed, 111 insertions(+), 1 deletion(-) create mode 100644 lib/puppet/functions/is_a.rb create mode 100644 spec/acceptance/is_a_spec.rb create mode 100644 spec/functions/is_a_spec.rb diff --git a/README.markdown b/README.markdown index f95d37d..aeacfdc 100644 --- a/README.markdown +++ b/README.markdown @@ -403,6 +403,29 @@ Converts an array into a hash. For example, `hash(['a',1,'b',2,'c',3])` returns Returns an array an intersection of two. For example, `intersection(["a","b","c"],["b","c","d"])` returns ["b","c"]. *Type*: rvalue. +#### `is_a` + +Boolean check to determine whether a variable is of a given data type. This is equivalent to the `=~` type checks. + + ~~~ + foo = 3 + $bar = [1,2,3] + $baz = 'A string!' + + if $foo.is_a(Integer) { + notify { 'foo!': } + } + if $bar.is_a(Array) { + notify { 'bar!': } + } + if $baz.is_a(String) { + notify { 'baz!': } + } + ~~~ + +See the documentation for "The Puppet Type System" for more information about types. +See the `assert_type()` function for flexible ways to assert the type of a value. + #### `is_array` Returns 'true' if the variable passed to this function is an array. *Type*: rvalue. diff --git a/lib/puppet/functions/is_a.rb b/lib/puppet/functions/is_a.rb new file mode 100644 index 0000000..da98b03 --- /dev/null +++ b/lib/puppet/functions/is_a.rb @@ -0,0 +1,32 @@ +# Boolean check to determine whether a variable is of a given data type. This is equivalent to the `=~` type checks. +# +# @example how to check a data type +# # check a data type +# foo = 3 +# $bar = [1,2,3] +# $baz = 'A string!' +# +# if $foo.is_a(Integer) { +# notify { 'foo!': } +# } +# if $bar.is_a(Array) { +# notify { 'bar!': } +# } +# if $baz.is_a(String) { +# notify { 'baz!': } +# } +# +# See the documentation for "The Puppet Type System" for more information about types. +# See the `assert_type()` function for flexible ways to assert the type of a value. +# +Puppet::Functions.create_function(:is_a) do + dispatch :is_a do + param 'Any', :value + param 'Type', :type + end + + def is_a(value, type) + # See puppet's lib/puppet/pops/evaluator/evaluator_impl.rb eval_MatchExpression + Puppet::Pops::Types::TypeCalculator.instance?(type, value) + end +end diff --git a/spec/acceptance/is_a_spec.rb b/spec/acceptance/is_a_spec.rb new file mode 100644 index 0000000..533673c --- /dev/null +++ b/spec/acceptance/is_a_spec.rb @@ -0,0 +1,28 @@ +#! /usr/bin/env ruby -S rspec +require 'spec_helper_acceptance' + +describe 'is_a function', :unless => UNSUPPORTED_PLATFORMS.include?(fact('operatingsystem')) do + it 'should match a string' do + pp = <<-EOS + if 'hello world'.is_a(String) { + notify { 'output correct': } + } + EOS + + apply_manifest(pp, :catch_failures => true) do |r| + expect(r.stdout).to match(/Notice: output correct/) + end + end + + it 'should not match a integer as string' do + pp = <<-EOS + if 5.is_a(String) { + notify { 'output wrong': } + } + EOS + + apply_manifest(pp, :catch_failures => true) do |r| + expect(r.stdout).not_to match(/Notice: output wrong/) + end + end +end diff --git a/spec/functions/is_a_spec.rb b/spec/functions/is_a_spec.rb new file mode 100644 index 0000000..8dec13f --- /dev/null +++ b/spec/functions/is_a_spec.rb @@ -0,0 +1,25 @@ +require 'spec_helper' + +if ENV["FUTURE_PARSER"] == 'yes' + describe 'type_of' do + pending 'teach rspec-puppet to load future-only functions under 3.7.5' do + it { is_expected.not_to eq(nil) } + end + end +end + +if Puppet.version.to_f >= 4.0 + describe 'is_a' do + it { is_expected.not_to eq(nil) } + it { is_expected.to run.with_params().and_raise_error(ArgumentError) } + it { is_expected.to run.with_params('', '').and_raise_error(ArgumentError) } + + it 'succeeds when comparing a string and a string' do + is_expected.to run.with_params('hello world', String).and_return(true) + end + + it 'fails when comparing an integer and a string' do + is_expected.to run.with_params(5, String).and_return(false) + end + end +end diff --git a/spec/functions/type_of_spec.rb b/spec/functions/type_of_spec.rb index f770990..cc9ef78 100644 --- a/spec/functions/type_of_spec.rb +++ b/spec/functions/type_of_spec.rb @@ -2,7 +2,9 @@ require 'spec_helper' if ENV["FUTURE_PARSER"] == 'yes' describe 'type_of' do - pending 'teach rspec-puppet to load future-only functions under 3.7.5' + pending 'teach rspec-puppet to load future-only functions under 3.7.5' do + it { is_expected.not_to eq(nil) } + end end end -- cgit v1.2.3 From 169f8af506d4cd8299e847236632fd8511928a03 Mon Sep 17 00:00:00 2001 From: Ben Ford Date: Mon, 14 Sep 2015 11:25:38 -0700 Subject: Clarify what an empty intersection looks like. --- lib/puppet/parser/functions/intersection.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/puppet/parser/functions/intersection.rb b/lib/puppet/parser/functions/intersection.rb index 48f02e9..bfbb4ba 100644 --- a/lib/puppet/parser/functions/intersection.rb +++ b/lib/puppet/parser/functions/intersection.rb @@ -4,13 +4,13 @@ module Puppet::Parser::Functions newfunction(:intersection, :type => :rvalue, :doc => <<-EOS -This function returns an array an intersection of two. +This function returns an array of the intersection of two. *Examples:* - intersection(["a","b","c"],["b","c","d"]) + intersection(["a","b","c"],["b","c","d"]) # returns ["b","c"] + intersection(["a","b","c"],[1,2,3,4]) # returns [] (true, when evaluated as a Boolean) -Would return: ["b","c"] EOS ) do |arguments| -- cgit v1.2.3 From 55ece7815a8718507ef096db53a1e186102f1c8a Mon Sep 17 00:00:00 2001 From: David Schmitt Date: Thu, 17 Sep 2015 18:48:32 +0100 Subject: (MAINT) validate_re: Clarify docs and error message --- README.markdown | 7 +++++++ lib/puppet/parser/functions/validate_re.rb | 11 +++++++++-- spec/functions/validate_re_spec.rb | 15 +++++++++++++++ 3 files changed, 31 insertions(+), 2 deletions(-) diff --git a/README.markdown b/README.markdown index 8dd57f1..1cf7b32 100644 --- a/README.markdown +++ b/README.markdown @@ -1054,6 +1054,13 @@ test, and the second argument should be a stringified regular expression (withou validate_re($::puppetversion, '^2.7', 'The $puppetversion fact value does not match 2.7') ~~~ + Note: Compilation will also abort, if the first argument is not a String. Always use + quotes to force stringification: + + ~~~ + validate_re("${::operatingsystemmajrelease}", '^[57]$') + ~~~ + *Type*: statement. #### `validate_slength` diff --git a/lib/puppet/parser/functions/validate_re.rb b/lib/puppet/parser/functions/validate_re.rb index ca25a70..efee7f8 100644 --- a/lib/puppet/parser/functions/validate_re.rb +++ b/lib/puppet/parser/functions/validate_re.rb @@ -23,16 +23,23 @@ module Puppet::Parser::Functions validate_re($::puppetversion, '^2.7', 'The $puppetversion fact value does not match 2.7') + Note: Compilation will also abort, if the first argument is not a String. Always use + quotes to force stringification: + + validate_re("${::operatingsystemmajrelease}", '^[57]$') + ENDHEREDOC if (args.length < 2) or (args.length > 3) then - raise Puppet::ParseError, ("validate_re(): wrong number of arguments (#{args.length}; must be 2 or 3)") + raise Puppet::ParseError, "validate_re(): wrong number of arguments (#{args.length}; must be 2 or 3)" end + raise Puppet::ParseError, "validate_re(): input needs to be a String, not a #{args[0].class}" unless args[0].is_a? String + msg = args[2] || "validate_re(): #{args[0].inspect} does not match #{args[1].inspect}" # We're using a flattened array here because we can't call String#any? in # Ruby 1.9 like we can in Ruby 1.8 - raise Puppet::ParseError, (msg) unless [args[1]].flatten.any? do |re_str| + raise Puppet::ParseError, msg unless [args[1]].flatten.any? do |re_str| args[0] =~ Regexp.compile(re_str) end diff --git a/spec/functions/validate_re_spec.rb b/spec/functions/validate_re_spec.rb index 42b1049..3f90143 100755 --- a/spec/functions/validate_re_spec.rb +++ b/spec/functions/validate_re_spec.rb @@ -41,6 +41,21 @@ describe 'validate_re' do it { is_expected.to run.with_params('notone', '^one').and_raise_error(Puppet::ParseError, /does not match/) } it { is_expected.to run.with_params('notone', [ '^one', '^two' ]).and_raise_error(Puppet::ParseError, /does not match/) } it { is_expected.to run.with_params('notone', [ '^one', '^two' ], 'custom error').and_raise_error(Puppet::ParseError, /custom error/) } + + describe 'non-string inputs' do + [ + 1, # Fixnum + 3.14, # Float + nil, # NilClass + true, # TrueClass + false, # FalseClass + ["10"], # Array + :key, # Symbol + {:key=>"val"}, # Hash + ].each do |input| + it { is_expected.to run.with_params(input, '.*').and_raise_error(Puppet::ParseError, /needs to be a String/) } + end + end end end end -- cgit v1.2.3 From 799c38e14e1583e676e2b25a9c1782fd40e29fff Mon Sep 17 00:00:00 2001 From: Morgan Haskel Date: Mon, 21 Sep 2015 10:56:08 -0700 Subject: Fix backwards compatibility from #511 Maintain the old behavior in the case where the optional second parameter isn't passed. Also, adding arity is backwards incompatible since stdlib still supports 2.7, so remove that. --- lib/puppet/parser/functions/parsejson.rb | 10 +++++++--- lib/puppet/parser/functions/parseyaml.rb | 10 +++++++--- spec/acceptance/parsejson_spec.rb | 16 ++++++++++++++-- spec/acceptance/parseyaml_spec.rb | 14 ++++++++++++++ spec/functions/parsejson_spec.rb | 6 +++--- spec/functions/parseyaml_spec.rb | 17 +++++++++++++---- 6 files changed, 58 insertions(+), 15 deletions(-) diff --git a/lib/puppet/parser/functions/parsejson.rb b/lib/puppet/parser/functions/parsejson.rb index f822fc4..b4af40e 100644 --- a/lib/puppet/parser/functions/parsejson.rb +++ b/lib/puppet/parser/functions/parsejson.rb @@ -3,7 +3,7 @@ # module Puppet::Parser::Functions - newfunction(:parsejson, :type => :rvalue, :arity => -2, :doc => <<-EOS + newfunction(:parsejson, :type => :rvalue, :doc => <<-EOS This function accepts JSON as a string and converts it into the correct Puppet structure. @@ -15,8 +15,12 @@ be returned if the parsing of YAML string have failed. begin PSON::load(arguments[0]) || arguments[1] - rescue Exception - arguments[1] + rescue Exception => e + if arguments[1] + arguments[1] + else + raise e + end end end diff --git a/lib/puppet/parser/functions/parseyaml.rb b/lib/puppet/parser/functions/parseyaml.rb index d38b3ef..66d0413 100644 --- a/lib/puppet/parser/functions/parseyaml.rb +++ b/lib/puppet/parser/functions/parseyaml.rb @@ -3,7 +3,7 @@ # module Puppet::Parser::Functions - newfunction(:parseyaml, :type => :rvalue, :arity => -2, :doc => <<-EOS + newfunction(:parseyaml, :type => :rvalue, :doc => <<-EOS This function accepts YAML as a string and converts it into the correct Puppet structure. @@ -16,8 +16,12 @@ be returned if the parsing of YAML string have failed. begin YAML::load(arguments[0]) || arguments[1] - rescue Exception - arguments[1] + rescue Exception => e + if arguments[1] + arguments[1] + else + raise e + end end end diff --git a/spec/acceptance/parsejson_spec.rb b/spec/acceptance/parsejson_spec.rb index d0feabd..d0e3de8 100755 --- a/spec/acceptance/parsejson_spec.rb +++ b/spec/acceptance/parsejson_spec.rb @@ -21,12 +21,24 @@ describe 'parsejson function', :unless => UNSUPPORTED_PLATFORMS.include?(fact('o it 'raises error on incorrect json' do pp = <<-EOS $a = '{"hunter": "washere", "tests": "passing",}' - $ao = parsejson($a, {'tests' => 'using the default value'}) + $ao = parsejson($a, 'tests are using the default value') notice(inline_template('a is <%= @ao.inspect %>')) EOS apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/tests are "using the default value"/) + expect(r.stdout).to match(/tests are using the default value/) + end + end + + it 'raises error on incorrect json' do + pp = <<-EOS + $a = '{"hunter": "washere", "tests": "passing",}' + $ao = parsejson($a) + notice(inline_template('a is <%= @ao.inspect %>')) + EOS + + apply_manifest(pp, :expect_failures => true) do |r| + expect(r.stderr).to match(/expected next name/) end end diff --git a/spec/acceptance/parseyaml_spec.rb b/spec/acceptance/parseyaml_spec.rb index 7946de0..64511f1 100755 --- a/spec/acceptance/parseyaml_spec.rb +++ b/spec/acceptance/parseyaml_spec.rb @@ -31,6 +31,20 @@ describe 'parseyaml function', :unless => UNSUPPORTED_PLATFORMS.include?(fact('o end end + it 'raises error on incorrect yaml' do + pp = <<-EOS + $a = "---\nhunter: washere\ntests: passing\n:" + $o = parseyaml($a) + $tests = $o['tests'] + notice(inline_template('tests are <%= @tests.inspect %>')) + EOS + + apply_manifest(pp, :expect_failures => true) do |r| + expect(r.stderr).to match(/(syntax error|did not find expected key)/) + end + end + + it 'raises error on incorrect number of arguments' do pp = <<-EOS $o = parseyaml() diff --git a/spec/functions/parsejson_spec.rb b/spec/functions/parsejson_spec.rb index 5bea8af..a01f1f6 100755 --- a/spec/functions/parsejson_spec.rb +++ b/spec/functions/parsejson_spec.rb @@ -41,10 +41,10 @@ describe 'parsejson' do end - context 'with incorrect YAML data' do - it 'should return "nil" if a default value should be returned but is not provided' do + context 'with incorrect JSON data' do + it 'should raise an error with invalid JSON and no default' do is_expected.to run.with_params(''). - and_return(nil) + and_raise_error(PSON::ParserError) end it 'should support a structure for a default value' do diff --git a/spec/functions/parseyaml_spec.rb b/spec/functions/parseyaml_spec.rb index 492a1c9..fa947ca 100755 --- a/spec/functions/parseyaml_spec.rb +++ b/spec/functions/parseyaml_spec.rb @@ -40,12 +40,21 @@ describe 'parseyaml' do end - context 'with incorrect YAML data' do - it 'should return "nil" if a default value should be returned but is not provided' do - is_expected.to run.with_params(''). - and_return(nil) + context 'on a modern ruby', :unless => RUBY_VERSION == '1.8.7' do + it 'should raise an error with invalid YAML and no default' do + is_expected.to run.with_params('["one"'). + and_raise_error(Psych::SyntaxError) + end + end + + context 'when running on ruby 1.8.7, which does not have Psych', :if => RUBY_VERSION == '1.8.7' do + it 'should raise an error with invalid YAML and no default' do + is_expected.to run.with_params('["one"'). + and_raise_error(ArgumentError) + end end + context 'with incorrect YAML data' do it 'should support a structure for a default value' do is_expected.to run.with_params('', {'a' => '1'}). and_return({'a' => '1'}) -- cgit v1.2.3 From b20239e7963a370d4a4eefb5754ddc6a2c072ab9 Mon Sep 17 00:00:00 2001 From: Morgan Haskel Date: Mon, 21 Sep 2015 14:12:25 -0700 Subject: Update is_a acceptance tests to only run on puppet4 --- spec/acceptance/is_a_spec.rb | 38 ++++++++++++++++++++------------------ spec/spec_helper_acceptance.rb | 6 +++++- 2 files changed, 25 insertions(+), 19 deletions(-) diff --git a/spec/acceptance/is_a_spec.rb b/spec/acceptance/is_a_spec.rb index 533673c..355fd83 100644 --- a/spec/acceptance/is_a_spec.rb +++ b/spec/acceptance/is_a_spec.rb @@ -1,28 +1,30 @@ #! /usr/bin/env ruby -S rspec require 'spec_helper_acceptance' -describe 'is_a function', :unless => UNSUPPORTED_PLATFORMS.include?(fact('operatingsystem')) do - it 'should match a string' do - pp = <<-EOS - if 'hello world'.is_a(String) { - notify { 'output correct': } - } - EOS +if get_puppet_version =~ /^4/ + describe 'is_a function', :unless => UNSUPPORTED_PLATFORMS.include?(fact('operatingsystem')) do + it 'should match a string' do + pp = <<-EOS + if 'hello world'.is_a(String) { + notify { 'output correct': } + } + EOS - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/Notice: output correct/) + apply_manifest(pp, :catch_failures => true) do |r| + expect(r.stdout).to match(/Notice: output correct/) + end end - end - it 'should not match a integer as string' do - pp = <<-EOS - if 5.is_a(String) { - notify { 'output wrong': } - } - EOS + it 'should not match a integer as string' do + pp = <<-EOS + if 5.is_a(String) { + notify { 'output wrong': } + } + EOS - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).not_to match(/Notice: output wrong/) + apply_manifest(pp, :catch_failures => true) do |r| + expect(r.stdout).not_to match(/Notice: output wrong/) + end end end end diff --git a/spec/spec_helper_acceptance.rb b/spec/spec_helper_acceptance.rb index f784112..eda0d1a 100755 --- a/spec/spec_helper_acceptance.rb +++ b/spec/spec_helper_acceptance.rb @@ -33,9 +33,13 @@ def is_future_parser_enabled? return false end +def get_puppet_version + (on default, puppet('--version')).output.chomp +end + RSpec.shared_context "with faked facts" do let(:facts_d) do - puppet_version = (on default, puppet('--version')).output.chomp + puppet_version = get_puppet_version if fact('osfamily') =~ /windows/i if fact('kernelmajversion').to_f < 6.0 'C:/Documents and Settings/All Users/Application Data/PuppetLabs/facter/facts.d' -- cgit v1.2.3 From 92b068ad20b2f3a0a8ef8847eb45124a95c395d9 Mon Sep 17 00:00:00 2001 From: Helen Campbell Date: Wed, 23 Sep 2015 11:27:48 +0100 Subject: Adding update to empty function readme --- README.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.markdown b/README.markdown index 1cf7b32..27dd0a7 100644 --- a/README.markdown +++ b/README.markdown @@ -224,7 +224,7 @@ Converts the case of a string or of all strings in an array to lowercase. *Type* #### `empty` -Returns 'true' if the variable is empty. *Type*: rvalue. +Returns true if the argument is an array or hash that contains no elements, or an empty string. *Type*: rvalue. #### `ensure_packages` -- cgit v1.2.3 From ce6e8679b68f984415adc90d74083fd787234709 Mon Sep 17 00:00:00 2001 From: Adam S Date: Fri, 25 Sep 2015 17:55:21 -0700 Subject: Add package_provider fact This adds a package_provider fact for situations where we need to be able to know the client's package provider in a simple way. Situations such as: package { 'name': install_options => [] } As those tend to be package provider specific options. --- lib/facter/package_provider.rb | 17 ++++++++++++++ spec/unit/facter/package_provider_spec.rb | 37 +++++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+) create mode 100644 lib/facter/package_provider.rb create mode 100644 spec/unit/facter/package_provider_spec.rb diff --git a/lib/facter/package_provider.rb b/lib/facter/package_provider.rb new file mode 100644 index 0000000..9a4ec65 --- /dev/null +++ b/lib/facter/package_provider.rb @@ -0,0 +1,17 @@ +# Fact: package_provider +# +# Purpose: Returns the default provider Puppet will choose to manage packages +# on this system +# +# Resolution: Instantiates a dummy package resource and return the provider +# +# Caveats: +# +require 'puppet/type' +require 'puppet/type/package' + +Facter.add(:package_provider) do + setcode do + Puppet::Type.type(:package).newpackage(:name => 'dummy')[:provider].to_s + end +end diff --git a/spec/unit/facter/package_provider_spec.rb b/spec/unit/facter/package_provider_spec.rb new file mode 100644 index 0000000..d1aee94 --- /dev/null +++ b/spec/unit/facter/package_provider_spec.rb @@ -0,0 +1,37 @@ +#! /usr/bin/env ruby -S rspec +require 'spec_helper' +require 'puppet/type' +require 'puppet/type/package' + +describe 'package_provider', :type => :fact do + before { Facter.clear } + after { Facter.clear } + + context "darwin" do + it "should return pkgdmg" do + provider = Puppet::Type.type(:package).provider(:pkgdmg) + Puppet::Type.type(:package).stubs(:defaultprovider).returns provider + + expect(Facter.fact(:package_provider).value).to eq('pkgdmg') + end + end + + context "centos 7" do + it "should return yum" do + provider = Puppet::Type.type(:package).provider(:yum) + Puppet::Type.type(:package).stubs(:defaultprovider).returns provider + + expect(Facter.fact(:package_provider).value).to eq('yum') + end + end + + context "ubuntu" do + it "should return apt" do + provider = Puppet::Type.type(:package).provider(:apt) + Puppet::Type.type(:package).stubs(:defaultprovider).returns provider + + expect(Facter.fact(:package_provider).value).to eq('apt') + end + end + +end -- cgit v1.2.3 From 440245d40d90f5f5cd9d7db0131371969216e55c Mon Sep 17 00:00:00 2001 From: Adam S Date: Fri, 25 Sep 2015 17:58:05 -0700 Subject: fixup-PR#506 Speed improvements in facter resolution This is to improve speed on Facter resolution of service_provider fact that was just introduced in PR# 506. The improvements go from 280ms resolution time approx. down to 2ms resolution time approx. by adding requires statements. --- lib/facter/service_provider.rb | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/facter/service_provider.rb b/lib/facter/service_provider.rb index 54db937..a117921 100644 --- a/lib/facter/service_provider.rb +++ b/lib/facter/service_provider.rb @@ -7,6 +7,9 @@ # # Caveats: # +require 'puppet/type' +require 'puppet/type/service' + Facter.add(:service_provider) do setcode do Puppet::Type.type(:service).newservice(:name => 'dummy')[:provider].to_s -- cgit v1.2.3 From bfa21edbaeebd61b356f51a7586da64f8d5d757a Mon Sep 17 00:00:00 2001 From: David Schmitt Date: Mon, 28 Sep 2015 11:12:25 +0100 Subject: (FM-3701) Update README for is_a --- README.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.markdown b/README.markdown index 27dd0a7..f919323 100644 --- a/README.markdown +++ b/README.markdown @@ -405,7 +405,7 @@ Returns an array an intersection of two. For example, `intersection(["a","b","c" #### `is_a` -Boolean check to determine whether a variable is of a given data type. This is equivalent to the `=~` type checks. +Boolean check to determine whether a variable is of a given data type. This is equivalent to the `=~` type checks. This function is only available in Puppet 4, or when using the "future" parser. ~~~ foo = 3 -- cgit v1.2.3 From 6f1d164da6fca26d41d5962c575900dfc792f004 Mon Sep 17 00:00:00 2001 From: Roman Mueller Date: Tue, 22 Sep 2015 18:05:37 +0200 Subject: Check for numeric values as empty fails on those --- lib/puppet/parser/functions/empty.rb | 12 ++++++++---- spec/functions/empty_spec.rb | 2 +- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/lib/puppet/parser/functions/empty.rb b/lib/puppet/parser/functions/empty.rb index cca620f..b5a3cde 100644 --- a/lib/puppet/parser/functions/empty.rb +++ b/lib/puppet/parser/functions/empty.rb @@ -13,14 +13,18 @@ Returns true if the variable is empty. value = arguments[0] - unless value.is_a?(Array) || value.is_a?(Hash) || value.is_a?(String) + unless value.is_a?(Array) || value.is_a?(Hash) || value.is_a?(String) || value.is_a?(Numeric) raise(Puppet::ParseError, 'empty(): Requires either ' + - 'array, hash or string to work with') + 'array, hash, string or integer to work with') end - result = value.empty? + if value.is_a?(Numeric) + return false + else + result = value.empty? - return result + return result + end end end diff --git a/spec/functions/empty_spec.rb b/spec/functions/empty_spec.rb index 94b1c68..a3a25d6 100755 --- a/spec/functions/empty_spec.rb +++ b/spec/functions/empty_spec.rb @@ -3,11 +3,11 @@ require 'spec_helper' describe 'empty' do it { is_expected.not_to eq(nil) } it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError) } - it { is_expected.to run.with_params(0).and_raise_error(Puppet::ParseError) } it { pending("Current implementation ignores parameters after the first.") is_expected.to run.with_params('one', 'two').and_raise_error(Puppet::ParseError) } + it { is_expected.to run.with_params(0).and_return(false) } it { is_expected.to run.with_params('').and_return(true) } it { is_expected.to run.with_params('one').and_return(false) } -- cgit v1.2.3 From c7c4d41a8286ab05af65afc1207c8cea4c11ffff Mon Sep 17 00:00:00 2001 From: Helen Campbell Date: Mon, 28 Sep 2015 16:18:56 +0100 Subject: Added acceptance test and updated readme --- README.markdown | 2 +- spec/acceptance/empty_spec.rb | 14 ++++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/README.markdown b/README.markdown index f919323..d023f23 100644 --- a/README.markdown +++ b/README.markdown @@ -224,7 +224,7 @@ Converts the case of a string or of all strings in an array to lowercase. *Type* #### `empty` -Returns true if the argument is an array or hash that contains no elements, or an empty string. *Type*: rvalue. +Returns true if the argument is an array or hash that contains no elements, or an empty string. Returns false when the argument is a numerical value. *Type*: rvalue. #### `ensure_packages` diff --git a/spec/acceptance/empty_spec.rb b/spec/acceptance/empty_spec.rb index 8b46aac..2d4df90 100755 --- a/spec/acceptance/empty_spec.rb +++ b/spec/acceptance/empty_spec.rb @@ -27,6 +27,20 @@ describe 'empty function', :unless => UNSUPPORTED_PLATFORMS.include?(fact('opera } EOS + apply_manifest(pp, :catch_failures => true) do |r| + expect(r.stdout).to match(/Notice: output correct/) + end + end + it 'handles numerical values' do + pp = <<-EOS + $a = 7 + $b = false + $o = empty($a) + if $o == $b { + notify { 'output correct': } + } + EOS + apply_manifest(pp, :catch_failures => true) do |r| expect(r.stdout).to match(/Notice: output correct/) end -- cgit v1.2.3 From d73fd3c5efcdf9a60178ddf96914ab75c9214260 Mon Sep 17 00:00:00 2001 From: Martin Pfeifer Date: Tue, 13 Oct 2015 10:08:01 +0200 Subject: prevent deprecation warning about the allow_virtual parameter --- lib/facter/package_provider.rb | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/facter/package_provider.rb b/lib/facter/package_provider.rb index 9a4ec65..65a2da0 100644 --- a/lib/facter/package_provider.rb +++ b/lib/facter/package_provider.rb @@ -12,6 +12,10 @@ require 'puppet/type/package' Facter.add(:package_provider) do setcode do - Puppet::Type.type(:package).newpackage(:name => 'dummy')[:provider].to_s + if Gem::Version.new(Facter.value(:puppetversion)) >= Gem::Version.new('3.6') + Puppet::Type.type(:package).newpackage(:name => 'dummy', :allow_virtual => 'true')[:provider].to_s + else + Puppet::Type.type(:package).newpackage(:name => 'dummy')[:provider].to_s + end end end -- cgit v1.2.3 From ad173f2d0552ad9ed42950aea7df8d2b22677904 Mon Sep 17 00:00:00 2001 From: David Schmitt Date: Tue, 13 Oct 2015 15:02:04 +0100 Subject: (MODULES-2421) improve description of file_line This mostly needed extraction of the existing doc strings from the type. --- README.markdown | 66 ++++++++++++++++++++++++++++++++++---------- lib/puppet/type/file_line.rb | 11 ++++---- 2 files changed, 57 insertions(+), 20 deletions(-) diff --git a/README.markdown b/README.markdown index d023f23..b6f586e 100644 --- a/README.markdown +++ b/README.markdown @@ -76,18 +76,56 @@ The `stdlib::stages` class declares various run stages for deploying infrastruct ### Types #### `file_line` - Ensures that a given line, including whitespace at the beginning and end, is contained within a file. If the line is not contained in the given file, Puppet will add the line. Multiple resources can be declared to manage multiple lines in the same file. You can also use `match` to replace existing lines. - ~~~ - file_line { 'sudo_rule': - path => '/etc/sudoers', - line => '%sudo ALL=(ALL) ALL', - } - file_line { 'sudo_rule_nopw': - path => '/etc/sudoers', - line => '%sudonopw ALL=(ALL) NOPASSWD: ALL', - } - ~~~ +Ensures that a given line is contained within a file. The implementation +matches the full line, including whitespace at the beginning and end. If +the line is not contained in the given file, Puppet will append the line to +the end of the file to ensure the desired state. Multiple resources may +be declared to manage multiple lines in the same file. + +Example: + + file_line { 'sudo_rule': + path => '/etc/sudoers', + line => '%sudo ALL=(ALL) ALL', + } + + file_line { 'sudo_rule_nopw': + path => '/etc/sudoers', + line => '%sudonopw ALL=(ALL) NOPASSWD: ALL', + } + +In this example, Puppet will ensure both of the specified lines are +contained in the file /etc/sudoers. + +Match Example: + + file_line { 'bashrc_proxy': + ensure => present, + path => '/etc/bashrc', + line => 'export HTTP_PROXY=http://squid.puppetlabs.vm:3128', + match => '^export\ HTTP_PROXY\=', + } + +In this code example match will look for a line beginning with export +followed by HTTP_PROXY and replace it with the value in line. + +Match Example With `ensure => absent`: + + file_line { 'bashrc_proxy': + ensure => absent, + path => '/etc/bashrc', + line => 'export HTTP_PROXY=http://squid.puppetlabs.vm:3128', + match => '^export\ HTTP_PROXY\=', + match_for_absence => true, + } + +In this code example match will look for a line beginning with export +followed by HTTP_PROXY and delete it. If multiple lines match, an +error will be raised unless the `multiple => true` parameter is set. + +**Autorequires:** If Puppet is managing the file that will contain the line +being managed, the file_line resource will autorequire that file. ##### Parameters All parameters are optional, unless otherwise noted. @@ -95,13 +133,13 @@ All parameters are optional, unless otherwise noted. * `after`: Specifies the line after which Puppet will add any new lines. (Existing lines are added in place.) Valid options: String. Default: Undefined. * `ensure`: Ensures whether the resource is present. Valid options: 'present', 'absent'. Default: 'present'. * `line`: **Required.** Sets the line to be added to the file located by the `path` parameter. Valid options: String. Default: Undefined. -* `match`: Specifies a regular expression to run against existing lines in the file; if a match is found, it is replaced rather than adding a new line. Valid options: String containing a regex. Default: Undefined. +* `match`: Specifies a regular expression to run against existing lines in the file; if a match is found, it is replaced rather than adding a new line. A regex comparison is performed against the line value and if it does not match an exception will be raised. Valid options: String containing a regex. Default: Undefined. +* `match_for_absence`: An optional value to determine if match should be applied when `ensure => absent`. If set to true and match is set, the line that matches match will be deleted. If set to false (the default), match is ignored when `ensure => absent` and the value of `line` is used instead. Default: false. * `multiple`: Determines if `match` and/or `after` can change multiple lines. If set to false, an exception will be raised if more than one line matches. Valid options: 'true', 'false'. Default: Undefined. * `name`: Sets the name to use as the identity of the resource. This is necessary if you want the resource namevar to differ from the supplied `title` of the resource. Valid options: String. Default: Undefined. * `path`: **Required.** Defines the file in which Puppet will ensure the line specified by `line`. Must be an absolute path to the file. * `replace`: Defines whether the resource will overwrite an existing line that matches the `match` parameter. If set to false and a line is found matching the `match` param, the line will not be placed in the file. Valid options: true, false, yes, no. Default: true - ### Functions #### `abs` @@ -405,7 +443,7 @@ Returns an array an intersection of two. For example, `intersection(["a","b","c" #### `is_a` -Boolean check to determine whether a variable is of a given data type. This is equivalent to the `=~` type checks. This function is only available in Puppet 4, or when using the "future" parser. +Boolean check to determine whether a variable is of a given data type. This is equivalent to the `=~` type checks. This function is only available in Puppet 4, or when using the "future" parser. ~~~ foo = 3 diff --git a/lib/puppet/type/file_line.rb b/lib/puppet/type/file_line.rb index 446f103..77d3be2 100644 --- a/lib/puppet/type/file_line.rb +++ b/lib/puppet/type/file_line.rb @@ -4,7 +4,7 @@ Puppet::Type.newtype(:file_line) do Ensures that a given line is contained within a file. The implementation matches the full line, including whitespace at the beginning and end. If the line is not contained in the given file, Puppet will append the line to - the end of the file to ensure the desired state. Multiple resources may + the end of the file to ensure the desired state. Multiple resources may be declared to manage multiple lines in the same file. Example: @@ -31,7 +31,7 @@ Puppet::Type.newtype(:file_line) do match => '^export\ HTTP_PROXY\=', } - In this code example match will look for a line beginning with export + In this code example match will look for a line beginning with export followed by HTTP_PROXY and replace it with the value in line. Match Example With `ensure => absent`: @@ -50,7 +50,6 @@ Puppet::Type.newtype(:file_line) do **Autorequires:** If Puppet is managing the file that will contain the line being managed, the file_line resource will autorequire that file. - EOT ensurable do @@ -63,10 +62,10 @@ Puppet::Type.newtype(:file_line) do end newparam(:match) do - desc 'An optional ruby regular expression to run against existing lines in the file.' + + desc 'An optional ruby regular expression to run against existing lines in the file.' + ' If a match is found, we replace that line rather than adding a new line.' + - ' A regex comparisson is performed against the line value and if it does not' + - ' match an exception will be raised. ' + ' A regex comparison is performed against the line value and if it does not' + + ' match an exception will be raised.' end newparam(:match_for_absence) do -- cgit v1.2.3 From 0f8df10084c875edac521a2307ce4caf7317b636 Mon Sep 17 00:00:00 2001 From: Colleen Murphy Date: Wed, 14 Oct 2015 15:59:09 -0700 Subject: Rename load_module_metadata test path `rake spec` only finds test files that end in _spec.rb, so this test was not being run. Correct the path name so that the test runs properly. --- spec/functions/load_module_metadata.rb | 16 ---------------- spec/functions/load_module_metadata_spec.rb | 16 ++++++++++++++++ 2 files changed, 16 insertions(+), 16 deletions(-) delete mode 100755 spec/functions/load_module_metadata.rb create mode 100755 spec/functions/load_module_metadata_spec.rb diff --git a/spec/functions/load_module_metadata.rb b/spec/functions/load_module_metadata.rb deleted file mode 100755 index ba542eb..0000000 --- a/spec/functions/load_module_metadata.rb +++ /dev/null @@ -1,16 +0,0 @@ -require 'spec_helper' - -describe 'load_module_metadata' 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("one", "two").and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } - - it "should json parse the file" do - allow(scope).to receive(:function_get_module_path).with(['science']).and_return('/path/to/module/') - allow(File).to receive(:exists?).with(/metadata.json/).and_return(true) - allow(File).to receive(:read).with(/metadata.json/).and_return('{"name": "spencer-science"}') - - result = subject.call(['science']) - expect(result['name']).to eq('spencer-science') - end -end diff --git a/spec/functions/load_module_metadata_spec.rb b/spec/functions/load_module_metadata_spec.rb new file mode 100755 index 0000000..ba542eb --- /dev/null +++ b/spec/functions/load_module_metadata_spec.rb @@ -0,0 +1,16 @@ +require 'spec_helper' + +describe 'load_module_metadata' 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("one", "two").and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } + + it "should json parse the file" do + allow(scope).to receive(:function_get_module_path).with(['science']).and_return('/path/to/module/') + allow(File).to receive(:exists?).with(/metadata.json/).and_return(true) + allow(File).to receive(:read).with(/metadata.json/).and_return('{"name": "spencer-science"}') + + result = subject.call(['science']) + expect(result['name']).to eq('spencer-science') + end +end -- cgit v1.2.3 From 25410c4598d3c0029fcd05adc2e305dbf5f8d902 Mon Sep 17 00:00:00 2001 From: Colleen Murphy Date: Wed, 14 Oct 2015 16:09:05 -0700 Subject: Let load_module_metadata succeed on empty file Some modules or module versions don't have a metadata.json file, but we might still want to use the load_module_metadata function on them. The lack of a file can still give us important information. For example, it might tell us that the version of the module installed is "very old" even if we can't read the version number directly. This patch adds a parameter to let the user specify if an empty file is acceptable. To preserve backwards compatibility it does not change the current default behavior, which is to raise an error if metadata.json does not exist. --- README.markdown | 9 +++++++++ lib/puppet/parser/functions/load_module_metadata.rb | 16 ++++++++++++---- spec/functions/load_module_metadata_spec.rb | 15 ++++++++++++++- 3 files changed, 35 insertions(+), 5 deletions(-) diff --git a/README.markdown b/README.markdown index b6f586e..d86d91f 100644 --- a/README.markdown +++ b/README.markdown @@ -539,6 +539,15 @@ Loads the metadata.json of a target module. Can be used to determine module vers notify { $metadata['author']: } ~~~ +If you do not want to fail the catalog compilation if the metadata file for a module is not present: + + ~~~ + $metadata = load_module_metadata('mysql', true) + if empty($metadata) { + notify { "This module does not have a metadata.json file.": } + } + ~~~ + *Type*: rvalue. #### `lstrip` diff --git a/lib/puppet/parser/functions/load_module_metadata.rb b/lib/puppet/parser/functions/load_module_metadata.rb index 0664a23..c9b8488 100644 --- a/lib/puppet/parser/functions/load_module_metadata.rb +++ b/lib/puppet/parser/functions/load_module_metadata.rb @@ -2,14 +2,22 @@ module Puppet::Parser::Functions newfunction(:load_module_metadata, :type => :rvalue, :doc => <<-EOT EOT ) do |args| - raise(Puppet::ParseError, "load_module_metadata(): Wrong number of arguments, expects one") unless args.size == 1 + raise(Puppet::ParseError, "load_module_metadata(): Wrong number of arguments, expects one or two") unless [1,2].include?(args.size) mod = args[0] + allow_empty_metadata = args[1] module_path = function_get_module_path([mod]) metadata_json = File.join(module_path, 'metadata.json') - raise(Puppet::ParseError, "load_module_metadata(): No metadata.json file for module #{mod}") unless File.exists?(metadata_json) - - metadata = PSON.load(File.read(metadata_json)) + metadata_exists = File.exists?(metadata_json) + if metadata_exists + metadata = PSON.load(File.read(metadata_json)) + else + if allow_empty_metadata + metadata = {} + else + raise(Puppet::ParseError, "load_module_metadata(): No metadata.json file for module #{mod}") + end + end return metadata end diff --git a/spec/functions/load_module_metadata_spec.rb b/spec/functions/load_module_metadata_spec.rb index ba542eb..fe665fb 100755 --- a/spec/functions/load_module_metadata_spec.rb +++ b/spec/functions/load_module_metadata_spec.rb @@ -3,7 +3,7 @@ require 'spec_helper' describe 'load_module_metadata' 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("one", "two").and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } + it { is_expected.to run.with_params("one", "two", "three").and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } it "should json parse the file" do allow(scope).to receive(:function_get_module_path).with(['science']).and_return('/path/to/module/') @@ -13,4 +13,17 @@ describe 'load_module_metadata' do result = subject.call(['science']) expect(result['name']).to eq('spencer-science') end + + it "should fail by default if there is no metadata.json" do + allow(scope).to receive(:function_get_module_path).with(['science']).and_return('/path/to/module/') + allow(File).to receive(:exists?).with(/metadata.json/).and_return(false) + expect {subject.call(['science'])}.to raise_error(Puppet::ParseError) + end + + it "should return nil if user allows empty metadata.json" do + allow(scope).to receive(:function_get_module_path).with(['science']).and_return('/path/to/module/') + allow(File).to receive(:exists?).with(/metadata.json/).and_return(false) + result = subject.call(['science', true]) + expect(result).to eq({}) + end end -- cgit v1.2.3 From 6aa7f2db9953d81afb75a3591358ba9e0dbc6935 Mon Sep 17 00:00:00 2001 From: Jesse Lovelace Date: Thu, 15 Oct 2015 11:25:57 -0500 Subject: Add check to ensure regex does not throw for none type. Add a quick check to ensure puppetversion value is not nil and supporting test. --- lib/facter/pe_version.rb | 9 +++++++-- spec/unit/facter/pe_version_spec.rb | 12 ++++++++++++ 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/lib/facter/pe_version.rb b/lib/facter/pe_version.rb index 0cc0f64..c9f2181 100644 --- a/lib/facter/pe_version.rb +++ b/lib/facter/pe_version.rb @@ -10,8 +10,13 @@ # Facter.add("pe_version") do setcode do - pe_ver = Facter.value("puppetversion").match(/Puppet Enterprise (\d+\.\d+\.\d+)/) - pe_ver[1] if pe_ver + puppet_ver = Facter.value("puppetversion") + if puppet_ver != nil + pe_ver = puppet_ver.match(/Puppet Enterprise (\d+\.\d+\.\d+)/) + pe_ver[1] if pe_ver + else + nil + end end end diff --git a/spec/unit/facter/pe_version_spec.rb b/spec/unit/facter/pe_version_spec.rb index 4d0349e..c11a1cd 100755 --- a/spec/unit/facter/pe_version_spec.rb +++ b/spec/unit/facter/pe_version_spec.rb @@ -14,6 +14,17 @@ describe "PE Version specs" do Facter.collection.loader.load(:pe_version) end end + + context "When puppetversion is nil" do + before :each do + Facter.fact(:puppetversion).stubs(:value).returns(nil) + end + + it "pe_version is nil" do + expect(Facter.fact(:puppetversion).value).to be_nil + expect(Facter.fact(:pe_version).value).to be_nil + end + end context "If PE is installed" do %w{ 2.6.1 2.10.300 }.each do |version| @@ -73,4 +84,5 @@ describe "PE Version specs" do expect(Facter.fact(:pe_patch_version).value).to be_nil end end + end -- cgit v1.2.3 From 6de1a6e0622f69ec22c64e72fd53ec12ae8c9111 Mon Sep 17 00:00:00 2001 From: Mark McKinstry Date: Thu, 15 Oct 2015 22:22:10 -0400 Subject: add functionality to bool2str to return strings of your choice for a boolean --- README.markdown | 16 ++++++++++++++++ lib/puppet/parser/functions/bool2str.rb | 26 ++++++++++++++++++++++---- spec/functions/bool2str_spec.rb | 6 ++++++ 3 files changed, 44 insertions(+), 4 deletions(-) diff --git a/README.markdown b/README.markdown index b6f586e..0933215 100644 --- a/README.markdown +++ b/README.markdown @@ -170,6 +170,22 @@ Converts a boolean to a number. Converts values: * 'true', 't', '1', 'y', and 'yes' to 1. Requires a single boolean or string as an input. *Type*: rvalue. +#### `bool2str` + +Converts a boolean to a string using optionally supplied arguments. The optional +second and third arguments represent what true and false will be converted to +respectively. If only one argument is given, it will be converted from a boolean +to a string containing 'true' or 'false'. + +*Examples:* +~~~ +bool2str(true) => 'true' +bool2str(true, 'yes', 'no') => 'yes' +bool2str(false, 't', 'f') => 'f' +~~~ + +Requires a single boolean as input. *Type*: rvalue. + #### `capitalize` Capitalizes the first letter of a string or array of strings. Requires either a single string or an array as an input. *Type*: rvalue. diff --git a/lib/puppet/parser/functions/bool2str.rb b/lib/puppet/parser/functions/bool2str.rb index fcd3791..7e36474 100644 --- a/lib/puppet/parser/functions/bool2str.rb +++ b/lib/puppet/parser/functions/bool2str.rb @@ -4,15 +4,29 @@ module Puppet::Parser::Functions newfunction(:bool2str, :type => :rvalue, :doc => <<-EOS - Converts a boolean to a string. + Converts a boolean to a string using optionally supplied arguments. The + optional second and third arguments represent what true and false will be + converted to respectively. If only one argument is given, it will be + converted from a boolean to a string containing 'true' or 'false'. + + *Examples:* + + bool2str(true) => 'true' + bool2str(true, 'yes', 'no') => 'yes' + bool2str(false, 't', 'f') => 'f' + Requires a single boolean as an input. EOS ) do |arguments| - raise(Puppet::ParseError, "bool2str(): Wrong number of arguments " + - "given (#{arguments.size} for 1)") if arguments.size < 1 + unless arguments.size == 1 or arguments.size == 3 + raise(Puppet::ParseError, "bool2str(): Wrong number of arguments " + + "given (#{arguments.size} for 3)") + end value = arguments[0] + true_string = arguments[1] || 'true' + false_string = arguments[2] || 'false' klass = value.class # We can have either true or false, and nothing else @@ -20,7 +34,11 @@ module Puppet::Parser::Functions raise(Puppet::ParseError, 'bool2str(): Requires a boolean to work with') end - return value.to_s + unless [true_string, false_string].all?{|x| x.kind_of?(String)} + raise(Puppet::ParseError, "bool2str(): Requires strings to convert to" ) + end + + return value ? true_string : false_string end end diff --git a/spec/functions/bool2str_spec.rb b/spec/functions/bool2str_spec.rb index 8d35598..23a754b 100755 --- a/spec/functions/bool2str_spec.rb +++ b/spec/functions/bool2str_spec.rb @@ -6,6 +6,12 @@ describe 'bool2str' do [ 'true', 'false', nil, :undef, ''].each do |invalid| it { is_expected.to run.with_params(invalid).and_raise_error(Puppet::ParseError) } end + it { is_expected.to run.with_params(true, 'yes', 'no', 'maybe').and_raise_error(Puppet::ParseError) } + it { is_expected.to run.with_params(true, 'maybe').and_raise_error(Puppet::ParseError) } + it { is_expected.to run.with_params(true, 0, 1).and_raise_error(Puppet::ParseError) } it { is_expected.to run.with_params(true).and_return("true") } it { is_expected.to run.with_params(false).and_return("false") } + it { is_expected.to run.with_params(true, 'yes', 'no').and_return("yes") } + it { is_expected.to run.with_params(false, 'yes', 'no').and_return("no") } + end -- cgit v1.2.3 From 2c3c6fde98e28cc3afd7f846d3176982f39ebc39 Mon Sep 17 00:00:00 2001 From: marrero984 Date: Thu, 22 Oct 2015 13:58:57 -0700 Subject: (#2183) updated str2bool readme wording --- README.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.markdown b/README.markdown index f9c9425..67b2b17 100644 --- a/README.markdown +++ b/README.markdown @@ -711,7 +711,7 @@ Returns a new string where runs of the same character that occur in this set are #### `str2bool` -Converts a string to a boolean regardless of case. This attempts to convert strings that contain values such as '1', 't', 'y', 'Y', 'YES','yes', and 'TRUE' to 'true' and strings that contain values such as '0', 'f','F', 'N','n', 'NO','FALSE', and 'no' to 'false'. *Type*: rvalue. +Converts certain strings to a boolean. This attempts to convert strings that contain the values '1', 't', 'y', and 'yes' to 'true'. Strings that contain values '0', 'f', 'n', and 'no', or are an an empty string or undefined are converted to 'false'. Any other value will cause an error. *Type*: rvalue. #### `str2saltedsha512` -- cgit v1.2.3 From 1421aa4a87e557957bc528b63aea6748f86af120 Mon Sep 17 00:00:00 2001 From: Matt Flaschen Date: Tue, 27 Oct 2015 18:09:18 -0400 Subject: Fix capitalize docs Capitalize lower-cases the remaining characters (due to the Ruby function having this behavior); document this, and make minor wording tweaks. --- README.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.markdown b/README.markdown index 67b2b17..57a62b6 100644 --- a/README.markdown +++ b/README.markdown @@ -188,7 +188,7 @@ Requires a single boolean as input. *Type*: rvalue. #### `capitalize` -Capitalizes the first letter of a string or array of strings. Requires either a single string or an array as an input. *Type*: rvalue. +Capitalizes the first character of a string or array of strings, and lower-cases the remaining characters of each string. Requires either a single string or an array as an input. *Type*: rvalue. #### `ceiling` -- cgit v1.2.3 From 7fdc312348ff938e89f1ea3ce43d580b8979aa2d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Paris?= Date: Tue, 3 Nov 2015 17:04:10 +0100 Subject: use properly encoded characters This is more severe than it sounds. These characters make puppet fail with the following message : > Error 400 on SERVER: "\xC3" on US-ASCII --- CHANGELOG.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3b35d01..d29963c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -349,7 +349,7 @@ This is a supported release * Add an ensure\_packages function. (8a8c09e) -##### 2012-11-23 - Erik Dalén - 3.2.0 +##### 2012-11-23 - Erik Dalén - 3.2.0 * (#17797) min() and max() functions (9954133) @@ -446,7 +446,7 @@ This is a supported release * Add support for a 'match' parameter to file\_line (a06c0d8) -##### 2012-08-07 - Erik Dalén - 2.4.0 +##### 2012-08-07 - Erik Dalén - 2.4.0 * (#15872) Add to\_bytes function (247b69c) -- cgit v1.2.3 From dc9b81d87e0672ee3d39c2d7bfe14ba1c7793610 Mon Sep 17 00:00:00 2001 From: Garrett Honeycutt Date: Fri, 6 Nov 2015 12:19:21 -0500 Subject: Use absolute class name in example --- manifests/stages.pp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/manifests/stages.pp b/manifests/stages.pp index eb15fd6..7de254c 100644 --- a/manifests/stages.pp +++ b/manifests/stages.pp @@ -26,7 +26,7 @@ # Sample Usage: # # node default { -# include stdlib +# include ::stdlib # class { java: stage => 'runtime' } # } # -- cgit v1.2.3 From 99db9827412f93e5f2d74eb86f6a25cd214823ae Mon Sep 17 00:00:00 2001 From: Helen Campbell Date: Mon, 9 Nov 2015 15:14:34 +0000 Subject: pick_default addition to readme --- README.markdown | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.markdown b/README.markdown index 57a62b6..9ff242c 100644 --- a/README.markdown +++ b/README.markdown @@ -624,6 +624,10 @@ From a list of values, returns the first value that is not undefined or an empty *Type*: rvalue. +#### `pick_default` + +Will return the first value in a list of values. Contrary to the 'pick()' function, the 'pick_default()' does not fail if all arguments are empty. This allows it to use an empty value as default. *Type*: rvalue. + #### `prefix` Applies a prefix to all elements in an array, or to the keys in a hash. -- cgit v1.2.3 From 13e5d467c97deb530f99e4a82c73b1aff97c9787 Mon Sep 17 00:00:00 2001 From: Reid Vandewiele Date: Thu, 19 Nov 2015 15:29:06 -0800 Subject: (FM-3773) Fix root_home fact on AIX 5.x The -C (capital C) flag to lsuser is incorrect. It should be -c (lowercase). this commit updates the aix root_home fact to use `lsuser -c`, rather than `lsuser -C`. --- lib/facter/root_home.rb | 2 +- spec/unit/facter/root_home_spec.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/facter/root_home.rb b/lib/facter/root_home.rb index ee3ffa8..87c7657 100644 --- a/lib/facter/root_home.rb +++ b/lib/facter/root_home.rb @@ -35,7 +35,7 @@ Facter.add(:root_home) do confine :kernel => :aix root_home = nil setcode do - str = Facter::Util::Resolution.exec("lsuser -C -a home root") + str = Facter::Util::Resolution.exec("lsuser -c -a home root") str && str.split("\n").each do |line| next if line =~ /^#/ root_home = line.split(/:/)[1] diff --git a/spec/unit/facter/root_home_spec.rb b/spec/unit/facter/root_home_spec.rb index ac5160a..a5c2846 100755 --- a/spec/unit/facter/root_home_spec.rb +++ b/spec/unit/facter/root_home_spec.rb @@ -58,7 +58,7 @@ describe 'root_home', :type => :fact do sample_lsuser = File.read(fixtures('lsuser','root')) it "should return /root" do - Facter::Util::Resolution.stubs(:exec).with("lsuser -C -a home root").returns(sample_lsuser) + Facter::Util::Resolution.stubs(:exec).with("lsuser -c -a home root").returns(sample_lsuser) expect(Facter.fact(:root_home).value).to eq(expected_root_home) end end -- cgit v1.2.3 From c43924682a9078d90eafcac87f1fbf3f2c34b382 Mon Sep 17 00:00:00 2001 From: Bryan Jen Date: Fri, 20 Nov 2015 12:14:30 -0700 Subject: Fix Gemfile to work with ruby 1.8.7 --- Gemfile | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/Gemfile b/Gemfile index fbb9a25..8221514 100644 --- a/Gemfile +++ b/Gemfile @@ -11,8 +11,14 @@ def location_for(place, fake_version = nil) 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', '~> 3.1.0', :require => false gem 'rspec-puppet', '~> 2.2', :require => false gem 'mocha', :require => false # keep for its rake task for now -- cgit v1.2.3 From 7b068781a506bf7f7a78a32adbe60eec292b9326 Mon Sep 17 00:00:00 2001 From: Matt Bostock Date: Mon, 23 Nov 2015 23:45:55 +0000 Subject: Fix reference to validate_bool in IP4 function The documentation in `validate_ipv4_address` references `validate_bool`, but I believe this should read `validate_ipv4_address` instead, which makes more sense. --- lib/puppet/parser/functions/validate_ipv4_address.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/puppet/parser/functions/validate_ipv4_address.rb b/lib/puppet/parser/functions/validate_ipv4_address.rb index fc02748..97faa57 100644 --- a/lib/puppet/parser/functions/validate_ipv4_address.rb +++ b/lib/puppet/parser/functions/validate_ipv4_address.rb @@ -8,7 +8,7 @@ module Puppet::Parser::Functions $my_ip = "1.2.3.4" validate_ipv4_address($my_ip) - validate_bool("8.8.8.8", "172.16.0.1", $my_ip) + validate_ipv4_address("8.8.8.8", "172.16.0.1", $my_ip) The following values will fail, causing compilation to abort: -- cgit v1.2.3 From 01c42d5212477a3bc65ae4673b599663ca2f092b Mon Sep 17 00:00:00 2001 From: tphoney Date: Mon, 23 Nov 2015 15:00:40 +0000 Subject: 4.9.1 release prep --- CHANGELOG.md | 5 +++++ metadata.json | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f5bd8c7..2e2fffe 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +## Supported Release 4.9.1 +###Summary + +Small release for support of newer PE versions. This increments the version of PE in the metadata.json file. + ##2015-09-08 - Supported Release 4.9.0 ###Summary diff --git a/metadata.json b/metadata.json index 2378787..3f31d09 100644 --- a/metadata.json +++ b/metadata.json @@ -1,6 +1,6 @@ { "name": "puppetlabs-stdlib", - "version": "4.9.0", + "version": "4.9.1", "author": "puppetlabs", "summary": "Standard library of resources for Puppet modules.", "license": "Apache-2.0", @@ -100,7 +100,7 @@ "requirements": [ { "name": "pe", - "version_requirement": "3.x" + "version_requirement": ">= 3.0.0 < 2015.4.0" }, { "name": "puppet", -- cgit v1.2.3 From fe23e01a4b8b0cc0d9ea1a958e2be5a947fb7aed Mon Sep 17 00:00:00 2001 From: Jaume Devesa Date: Thu, 19 Nov 2015 12:47:01 +0100 Subject: Add validator for any IP address Provide a validator for IP addresses, regardless they are IPv4 or IPv6, and its documentation. --- README.markdown | 33 ++++++++++++++ lib/puppet/parser/functions/validate_ip_address.rb | 50 ++++++++++++++++++++++ spec/functions/validate_ip_address_spec.rb | 46 ++++++++++++++++++++ 3 files changed, 129 insertions(+) create mode 100644 lib/puppet/parser/functions/validate_ip_address.rb create mode 100644 spec/functions/validate_ip_address_spec.rb diff --git a/README.markdown b/README.markdown index 9ff242c..526b573 100644 --- a/README.markdown +++ b/README.markdown @@ -1079,6 +1079,39 @@ Validates that the first argument is an integer (or an array of integers). Abort *Type*: statement. +#### `validate_ip_address` + +Validates that argument is an IP address, regardless of it is an IPv4 or an IPv6 +address. It validates as well IP address with netmask. It must be an String, as +well. + +The following values will pass: + + ~~~ + validate_ip_address('0.0.0.0') + validate_ip_address('8.8.8.8') + validate_ip_address('127.0.0.1') + validate_ip_address('194.232.104.150') + validate_ip_address('3ffe:0505:0002::') + validate_ip_address('::1/64') + validate_ip_address('fe80::a00:27ff:fe94:44d6/64') + validate_ip_address('8.8.8.8/32') + ~~~ + +The following values will fail, causing compilation to abort: + + ~~~ + validate_ip_address(1) + validate_ip_address(true) + validate_ip_address(0.0.0.256) + validate_ip_address('::1', {}) + validate_ip_address('0.0.0.0.0') + validate_ip_address('3.3.3') + validate_ip_address('23.43.9.22/64') + validate_ip_address('260.2.32.43') + ~~~ + + #### `validate_numeric` Validates that the first argument is a numeric value (or an array of numeric values). Aborts catalog compilation if any of the checks fail. diff --git a/lib/puppet/parser/functions/validate_ip_address.rb b/lib/puppet/parser/functions/validate_ip_address.rb new file mode 100644 index 0000000..c0baf82 --- /dev/null +++ b/lib/puppet/parser/functions/validate_ip_address.rb @@ -0,0 +1,50 @@ +module Puppet::Parser::Functions + + newfunction(:validate_ip_address, :doc => <<-ENDHEREDOC + Validate that all values passed are valid IP addresses, + regardless they are IPv4 or IPv6 + Fail compilation if any value fails this check. + The following values will pass: + $my_ip = "1.2.3.4" + validate_ip_address($my_ip) + validate_bool("8.8.8.8", "172.16.0.1", $my_ip) + + $my_ip = "3ffe:505:2" + validate_ip_address(1) + validate_ip_address($my_ip) + validate_bool("fe80::baf6:b1ff:fe19:7507", $my_ip) + + The following values will fail, causing compilation to abort: + $some_array = [ 1, true, false, "garbage string", "3ffe:505:2" ] + validate_ip_address($some_array) + ENDHEREDOC + ) do |args| + + require "ipaddr" + rescuable_exceptions = [ ArgumentError ] + + if defined?(IPAddr::InvalidAddressError) + rescuable_exceptions << IPAddr::InvalidAddressError + end + + unless args.length > 0 then + raise Puppet::ParseError, ("validate_ip_address(): wrong number of arguments (#{args.length}; must be > 0)") + end + + args.each do |arg| + unless arg.is_a?(String) + raise Puppet::ParseError, "#{arg.inspect} is not a string." + end + + begin + unless IPAddr.new(arg).ipv4? or IPAddr.new(arg).ipv6? + raise Puppet::ParseError, "#{arg.inspect} is not a valid IP address." + end + rescue *rescuable_exceptions + raise Puppet::ParseError, "#{arg.inspect} is not a valid IP address." + end + end + + end + +end diff --git a/spec/functions/validate_ip_address_spec.rb b/spec/functions/validate_ip_address_spec.rb new file mode 100644 index 0000000..b56ce51 --- /dev/null +++ b/spec/functions/validate_ip_address_spec.rb @@ -0,0 +1,46 @@ +require 'spec_helper' + +describe 'validate_ip_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('0.0.0.0') } + it { is_expected.to run.with_params('8.8.8.8') } + it { is_expected.to run.with_params('127.0.0.1') } + it { is_expected.to run.with_params('10.10.10.10') } + it { is_expected.to run.with_params('194.232.104.150') } + it { is_expected.to run.with_params('244.24.24.24') } + it { is_expected.to run.with_params('255.255.255.255') } + it { is_expected.to run.with_params('1.2.3.4', '5.6.7.8') } + it { is_expected.to run.with_params('3ffe:0505:0002::') } + it { is_expected.to run.with_params('3ffe:0505:0002::', '3ffe:0505:0002::2') } + it { is_expected.to run.with_params('::1/64') } + it { is_expected.to run.with_params('fe80::a00:27ff:fe94:44d6/64') } + context 'with netmasks' do + it { is_expected.to run.with_params('8.8.8.8/0') } + it { is_expected.to run.with_params('8.8.8.8/16') } + it { is_expected.to run.with_params('8.8.8.8/32') } + it { is_expected.to run.with_params('8.8.8.8/255.255.0.0') } + end + 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 IP/) } + it { is_expected.to run.with_params('0.0.0').and_raise_error(Puppet::ParseError, /is not a valid IP/) } + it { is_expected.to run.with_params('0.0.0.256').and_raise_error(Puppet::ParseError, /is not a valid IP/) } + it { is_expected.to run.with_params('0.0.0.0.0').and_raise_error(Puppet::ParseError, /is not a valid IP/) } + it { is_expected.to run.with_params('1.2.3.4', {}).and_raise_error(Puppet::ParseError, /is not a string/) } + it { is_expected.to run.with_params('1.2.3.4', 1).and_raise_error(Puppet::ParseError, /is not a string/) } + it { is_expected.to run.with_params('1.2.3.4', true).and_raise_error(Puppet::ParseError, /is not a string/) } + it { is_expected.to run.with_params('1.2.3.4', 'one').and_raise_error(Puppet::ParseError, /is not a valid IP/) } + it { is_expected.to run.with_params('::1', {}).and_raise_error(Puppet::ParseError, /is not a string/) } + it { is_expected.to run.with_params('::1', true).and_raise_error(Puppet::ParseError, /is not a string/) } + it { is_expected.to run.with_params('::1', 'one').and_raise_error(Puppet::ParseError, /is not a valid IP/) } + end +end -- cgit v1.2.3 From 8aecd63378f6dc3aeafe71d91212f613aa0bb829 Mon Sep 17 00:00:00 2001 From: Kjetil Torgrim Homme Date: Tue, 8 Dec 2015 14:59:12 +0100 Subject: (#2886) seeded_rand: new function seeded_rand is needed for repeatable randomness across nodes in a cluster --- README.markdown | 6 ++++ lib/puppet/parser/functions/seeded_rand.rb | 22 +++++++++++++ spec/functions/seeded_rand_spec.rb | 53 ++++++++++++++++++++++++++++++ 3 files changed, 81 insertions(+) create mode 100644 lib/puppet/parser/functions/seeded_rand.rb create mode 100644 spec/functions/seeded_rand_spec.rb diff --git a/README.markdown b/README.markdown index 526b573..9348a3a 100644 --- a/README.markdown +++ b/README.markdown @@ -697,6 +697,12 @@ Reverses the order of a string or array. *Type*: rvalue. Strips spaces to the right of the string. *Type*: rvalue. +#### `seeded_rand` + +Takes an integer max value and a string seed value and returns a +repeatable random integer smaller than max. Like `fqdn_rand`, but +this does not add node specific data to the seed. *Type*: rvalue. + #### `shuffle` Randomizes the order of a string or array elements. *Type*: rvalue. diff --git a/lib/puppet/parser/functions/seeded_rand.rb b/lib/puppet/parser/functions/seeded_rand.rb new file mode 100644 index 0000000..44e27b8 --- /dev/null +++ b/lib/puppet/parser/functions/seeded_rand.rb @@ -0,0 +1,22 @@ +Puppet::Parser::Functions::newfunction( + :seeded_rand, + :arity => 2, + :type => :rvalue, + :doc => <<-EOS +Usage: `seeded_rand(MAX, SEED)`. MAX must be a positive integer; SEED is any string. + +Generates a random whole number greater than or equal to 0 and less +than MAX, using the value of SEED for repeatable randomness. If SEED +starts with "$fqdn:", this is behaves the same as `fqdn_rand`. + +EOS +) do |args| + require 'digest/md5' + + raise(ArgumentError, "seeded_rand(): first argument must be a positive integer") unless function_is_integer([args[0]]) and args[0].to_i > 0 + raise(ArgumentError, "seeded_rand(): second argument must be a string") unless args[1].is_a? String + + max = args[0].to_i + seed = Digest::MD5.hexdigest(args[1]).hex + Puppet::Util.deterministic_rand(seed,max) +end diff --git a/spec/functions/seeded_rand_spec.rb b/spec/functions/seeded_rand_spec.rb new file mode 100644 index 0000000..38e134e --- /dev/null +++ b/spec/functions/seeded_rand_spec.rb @@ -0,0 +1,53 @@ +require 'spec_helper' + +describe 'seeded_rand' do + it { is_expected.not_to eq(nil) } + it { is_expected.to run.with_params().and_raise_error(ArgumentError, /wrong number of arguments/i) } + it { is_expected.to run.with_params(1).and_raise_error(ArgumentError, /wrong number of arguments/i) } + it { is_expected.to run.with_params(0, '').and_raise_error(ArgumentError, /first argument must be a positive integer/) } + it { is_expected.to run.with_params(1.5, '').and_raise_error(ArgumentError, /first argument must be a positive integer/) } + it { is_expected.to run.with_params(-10, '').and_raise_error(ArgumentError, /first argument must be a positive integer/) } + it { is_expected.to run.with_params("-10", '').and_raise_error(ArgumentError, /first argument must be a positive integer/) } + it { is_expected.to run.with_params("string", '').and_raise_error(ArgumentError, /first argument must be a positive integer/) } + it { is_expected.to run.with_params([], '').and_raise_error(ArgumentError, /first argument must be a positive integer/) } + it { is_expected.to run.with_params({}, '').and_raise_error(ArgumentError, /first argument must be a positive integer/) } + it { is_expected.to run.with_params(1, 1).and_raise_error(ArgumentError, /second argument must be a string/) } + it { is_expected.to run.with_params(1, []).and_raise_error(ArgumentError, /second argument must be a string/) } + it { is_expected.to run.with_params(1, {}).and_raise_error(ArgumentError, /second argument must be a string/) } + + it "provides a random number strictly less than the given max" do + expect(seeded_rand(3, 'seed')).to satisfy {|n| n.to_i < 3 } + end + + it "provides a random number greater or equal to zero" do + expect(seeded_rand(3, 'seed')).to satisfy {|n| n.to_i >= 0 } + end + + it "provides the same 'random' value on subsequent calls for the same host" do + expect(seeded_rand(10, 'seed')).to eql(seeded_rand(10, 'seed')) + end + + it "allows seed to control the random value on a single host" do + first_random = seeded_rand(1000, 'seed1') + second_different_random = seeded_rand(1000, 'seed2') + + expect(first_random).not_to eql(second_different_random) + end + + it "should not return different values for different hosts" do + val1 = seeded_rand(1000, 'foo', :host => "first.host.com") + val2 = seeded_rand(1000, 'foo', :host => "second.host.com") + + expect(val1).to eql(val2) + end + + def seeded_rand(max, seed, args = {}) + host = args[:host] || '127.0.0.1' + + # workaround not being able to use let(:facts) because some tests need + # multiple different hostnames in one context + scope.stubs(:lookupvar).with("::fqdn", {}).returns(host) + + scope.function_seeded_rand([max, seed]) + end +end -- cgit v1.2.3 From 964e24a63799f5a9c316c14713c633f11f2e251f Mon Sep 17 00:00:00 2001 From: Helen Campbell Date: Fri, 11 Dec 2015 20:08:25 +0000 Subject: Changelog and versionbump for 4.10.0 --- CHANGELOG.md | 32 ++++++++++++++++++++++++++++++++ metadata.json | 2 +- 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 83f57f5..94a0577 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,35 @@ +##2015-12-15 - Supported Release 4.10.0 +###Summary + +Includes the addition of several new functions and considerable improvements to the existing functions, tests and documentation. Includes some bug fixes which includes compatibility, test and fact issues. + +####Features +- Adds service_provider fact +- Adds is_a() function +- Adds package_provider fact +- Adds validate_ip_address function +- Adds seeded_rand function + +####Bugfixes +- Fix backwards compatibility from an improvement to the parseyaml function +- Renaming of load_module_metadata test to include _spec.rb +- Fix root_home fact on AIX 5.x, now '-c' rather than '-C' +- Fixed Gemfile to work with ruby 1.8.7 + +####Improvements +- (MODULES-2462) Improvement of parseyaml function +- Improvement of str2bool function +- Improvement to readme +- Improvement of intersection function +- Improvement of validate_re function +- Improved speed on Facter resolution of service_provider +- empty function now handles numeric values +- Package_provider now prevents deprecation warning about the allow_virtual parameter +- load_module_metadata now succeeds on empty file +- Check added to ensure puppetversion value is not nil +- Improvement to bool2str to return a string of choice using boolean +- Improvement to naming convention in validate_ipv4_address function + ## Supported Release 4.9.1 ###Summary diff --git a/metadata.json b/metadata.json index 3f31d09..947ef9a 100644 --- a/metadata.json +++ b/metadata.json @@ -1,6 +1,6 @@ { "name": "puppetlabs-stdlib", - "version": "4.9.1", + "version": "4.10.0", "author": "puppetlabs", "summary": "Standard library of resources for Puppet modules.", "license": "Apache-2.0", -- cgit v1.2.3 From 4abc6e6e3b12a55996623ca7544a2d65bbea93d1 Mon Sep 17 00:00:00 2001 From: jbondpdx Date: Mon, 14 Dec 2015 11:19:53 -0800 Subject: edits to README --- README.markdown | 90 +++++++++++++++++++++++++++++---------------------------- 1 file changed, 46 insertions(+), 44 deletions(-) diff --git a/README.markdown b/README.markdown index 9348a3a..c073b30 100644 --- a/README.markdown +++ b/README.markdown @@ -77,10 +77,10 @@ The `stdlib::stages` class declares various run stages for deploying infrastruct #### `file_line` -Ensures that a given line is contained within a file. The implementation -matches the full line, including whitespace at the beginning and end. If -the line is not contained in the given file, Puppet will append the line to -the end of the file to ensure the desired state. Multiple resources may +Ensures that a given line is contained within a file. The implementation +matches the full line, including whitespace at the beginning and end. If +the line is not contained in the given file, Puppet appends the line to +the end of the file to ensure the desired state. Multiple resources can be declared to manage multiple lines in the same file. Example: @@ -95,8 +95,8 @@ Example: line => '%sudonopw ALL=(ALL) NOPASSWD: ALL', } -In this example, Puppet will ensure both of the specified lines are -contained in the file /etc/sudoers. +In this example, Puppet ensures that both of the specified lines are +contained in the file `/etc/sudoers`. Match Example: @@ -107,8 +107,8 @@ Match Example: match => '^export\ HTTP_PROXY\=', } -In this code example match will look for a line beginning with export -followed by HTTP_PROXY and replace it with the value in line. +In this code example, `match` looks for a line beginning with export +followed by HTTP_PROXY and replaces it with the value in line. Match Example With `ensure => absent`: @@ -120,20 +120,21 @@ Match Example With `ensure => absent`: match_for_absence => true, } -In this code example match will look for a line beginning with export +In this code example, `match` looks for a line beginning with export followed by HTTP_PROXY and delete it. If multiple lines match, an error will be raised unless the `multiple => true` parameter is set. -**Autorequires:** If Puppet is managing the file that will contain the line -being managed, the file_line resource will autorequire that file. +**Autorequires:** If Puppet is managing the file that contains the line +being managed, the `file_line` resource autorequires that file. ##### Parameters + All parameters are optional, unless otherwise noted. -* `after`: Specifies the line after which Puppet will add any new lines. (Existing lines are added in place.) Valid options: String. Default: Undefined. +* `after`: Specifies the line after which Puppet adds any new lines. (Existing lines are added in place.) Valid options: String. Default: Undefined. * `ensure`: Ensures whether the resource is present. Valid options: 'present', 'absent'. Default: 'present'. * `line`: **Required.** Sets the line to be added to the file located by the `path` parameter. Valid options: String. Default: Undefined. -* `match`: Specifies a regular expression to run against existing lines in the file; if a match is found, it is replaced rather than adding a new line. A regex comparison is performed against the line value and if it does not match an exception will be raised. Valid options: String containing a regex. Default: Undefined. +* `match`: Specifies a regular expression to run against existing lines in the file; if a match is found, it is replaced rather than adding a new line. A regex comparison is performed against the line value, and if it does not match, an exception is raised. Valid options: String containing a regex. Default: Undefined. * `match_for_absence`: An optional value to determine if match should be applied when `ensure => absent`. If set to true and match is set, the line that matches match will be deleted. If set to false (the default), match is ignored when `ensure => absent` and the value of `line` is used instead. Default: false. * `multiple`: Determines if `match` and/or `after` can change multiple lines. If set to false, an exception will be raised if more than one line matches. Valid options: 'true', 'false'. Default: Undefined. * `name`: Sets the name to use as the identity of the resource. This is necessary if you want the resource namevar to differ from the supplied `title` of the resource. Valid options: String. Default: Undefined. @@ -173,8 +174,8 @@ Converts a boolean to a number. Converts values: #### `bool2str` Converts a boolean to a string using optionally supplied arguments. The optional -second and third arguments represent what true and false will be converted to -respectively. If only one argument is given, it will be converted from a boolean +second and third arguments represent what true and false are converted to +respectively. If only one argument is given, it is converted from a boolean to a string containing 'true' or 'false'. *Examples:* @@ -188,7 +189,7 @@ Requires a single boolean as input. *Type*: rvalue. #### `capitalize` -Capitalizes the first character of a string or array of strings, and lower-cases the remaining characters of each string. Requires either a single string or an array as an input. *Type*: rvalue. +Capitalizes the first character of a string or array of strings and lowercases the remaining characters of each string. Requires either a single string or an array as an input. *Type*: rvalue. #### `ceiling` @@ -336,10 +337,13 @@ fqdn_rand_string(10, '', 'custom seed') Rotates an array or string a random number of times, combining the `$fqdn` fact and an optional seed for repeatable randomness. *Usage:* + ~~~ fqdn_rotate(VALUE, [SEED]) ~~~ + *Examples:* + ~~~ fqdn_rotate(['a', 'b', 'c', 'd']) fqdn_rotate('abcd') @@ -459,7 +463,7 @@ Returns an array an intersection of two. For example, `intersection(["a","b","c" #### `is_a` -Boolean check to determine whether a variable is of a given data type. This is equivalent to the `=~` type checks. This function is only available in Puppet 4, or when using the "future" parser. +Boolean check to determine whether a variable is of a given data type. This is equivalent to the `=~` type checks. This function is available only in Puppet 4 or in Puppet 3 with the "future" parser. ~~~ foo = 3 @@ -477,8 +481,8 @@ Boolean check to determine whether a variable is of a given data type. This is e } ~~~ -See the documentation for "The Puppet Type System" for more information about types. -See the `assert_type()` function for flexible ways to assert the type of a value. +See the [the Puppet type system](https://docs.puppetlabs.com/references/latest/type.html#about-resource-types) for more information about types. +See the [`assert_type()`](https://docs.puppetlabs.com/references/latest/function.html#asserttype) function for flexible ways to assert the type of a value. #### `is_array` @@ -555,7 +559,7 @@ Loads the metadata.json of a target module. Can be used to determine module vers notify { $metadata['author']: } ~~~ -If you do not want to fail the catalog compilation if the metadata file for a module is not present: +If you do not want to fail the catalog compilation when a module's metadata file is absent: ~~~ $metadata = load_module_metadata('mysql', true) @@ -607,12 +611,12 @@ Converts a number or a string representation of a number into a true boolean. Ze #### `parsejson` Converts a string of JSON into the correct Puppet structure. *Type*: rvalue. -The optional second argument will be returned if the data was not correct. +The optional second argument is returned if the data was not correct. #### `parseyaml` Converts a string of YAML into the correct Puppet structure. *Type*: rvalue. -The optional second argument will be returned if the data was not correct. +The optional second argument is returned if the data was not correct. #### `pick` @@ -626,7 +630,7 @@ From a list of values, returns the first value that is not undefined or an empty #### `pick_default` -Will return the first value in a list of values. Contrary to the 'pick()' function, the 'pick_default()' does not fail if all arguments are empty. This allows it to use an empty value as default. *Type*: rvalue. +Returns the first value in a list of values. Contrary to the `pick()` function, the `pick_default()` does not fail if all arguments are empty. This allows it to use an empty value as default. *Type*: rvalue. #### `prefix` @@ -700,8 +704,8 @@ Strips spaces to the right of the string. *Type*: rvalue. #### `seeded_rand` Takes an integer max value and a string seed value and returns a -repeatable random integer smaller than max. Like `fqdn_rand`, but -this does not add node specific data to the seed. *Type*: rvalue. +repeatable random integer smaller than max. Like `fqdn_rand`, but +does not add node specific data to the seed. *Type*: rvalue. #### `shuffle` @@ -721,7 +725,7 @@ Returns a new string where runs of the same character that occur in this set are #### `str2bool` -Converts certain strings to a boolean. This attempts to convert strings that contain the values '1', 't', 'y', and 'yes' to 'true'. Strings that contain values '0', 'f', 'n', and 'no', or are an an empty string or undefined are converted to 'false'. Any other value will cause an error. *Type*: rvalue. +Converts certain strings to a boolean. This attempts to convert strings that contain the values '1', 't', 'y', or 'yes' to true. Strings that contain values '0', 'f', 'n', or 'no', or that are an empty string or undefined are converted to false. Any other value causes an error. *Type*: rvalue. #### `str2saltedsha512` @@ -804,18 +808,17 @@ Converts the argument into bytes, for example "4 kB" becomes "4096". Takes a sin *Type*: rvalue. -Looks up into a complex structure of arrays and hashes to extract a value by -its path in the structure. The path is a string of hash keys or array indexes +Retrieves a value within multiple layers of hashes and arrays via a string containing a path. The path is a string of hash keys or array indexes starting with zero, separated by the path separator character (default "/"). -The function will go down the structure by each path component and will try to +The function goes through the structure by each path component and tries to return the value at the end of the path. -In addition to the required "path" argument the function accepts the default -argument. It will be returned if the path is not correct, no value was found or -a any other error have occurred. And the last argument can set the path +In addition to the required path argument, the function accepts the default +argument. It is returned if the path is not correct, if no value was found, or +if any other error has occurred. The last argument can set the path separator character. -```ruby +~~~ruby $data = { 'a' => { 'b' => [ @@ -840,7 +843,7 @@ $value = try_get_value($data, 'a/b/c/d', 'not_found') # using custom separator $value = try_get_value($data, 'a|b', [], '|') # $value = ['b1','b2','b3'] -``` +~~~ 1. **$data** The data structure we are working with. 2. **'a/b/2'** The path string. @@ -1087,9 +1090,8 @@ Validates that the first argument is an integer (or an array of integers). Abort #### `validate_ip_address` -Validates that argument is an IP address, regardless of it is an IPv4 or an IPv6 -address. It validates as well IP address with netmask. It must be an String, as -well. +Validates that the argument is an IP address, regardless of it is an IPv4 or an IPv6 +address. It also validates IP address with netmask. The argument must be given as a string. The following values will pass: @@ -1160,7 +1162,7 @@ test, and the second argument should be a stringified regular expression (withou validate_re($::puppetversion, '^2.7', 'The $puppetversion fact value does not match 2.7') ~~~ - Note: Compilation will also abort, if the first argument is not a String. Always use + Note: Compilation terminates if the first argument is not a string. Always use quotes to force stringification: ~~~ @@ -1171,7 +1173,7 @@ test, and the second argument should be a stringified regular expression (withou #### `validate_slength` -Validates that the first argument is a string (or an array of strings), and is less than or equal to the length of the second argument. It fails if the first argument is not a string or array of strings, or if arg 2 is not convertable to a number. Optionally, a minimum string length can be given as the third argument. +Validates that the first argument is a string (or an array of strings), and is less than or equal to the length of the second argument. It fails if the first argument is not a string or array of strings, or if the second argument is not convertable to a number. Optionally, a minimum string length can be given as the third argument. The following values pass: @@ -1243,7 +1245,7 @@ Finds values inside an array based on location. The first argument is the array Takes one element from first array given and merges corresponding elements from second array given. This generates a sequence of n-element arrays, where *n* is one more than the count of arguments. For example, `zip(['1','2','3'],['4','5','6'])` results in ["1", "4"], ["2", "5"], ["3", "6"]. *Type*: rvalue. -##Limitations +## Limitations As of Puppet Enterprise 3.7, the stdlib module is no longer included in PE. PE users should install the most recent release of stdlib for compatibility with Puppet modules. @@ -1259,13 +1261,13 @@ Versions | Puppet 2.6 | Puppet 2.7 | Puppet 3.x | Puppet 4.x | **stdlib 5.x**: When released, stdlib 5.x will drop support for Puppet 2.7.x. Please see [this discussion](https://github.com/puppetlabs/puppetlabs-stdlib/pull/176#issuecomment-30251414). -##Development +## Development -Puppet Labs modules on the Puppet Forge are open projects, and community contributions are essential for keeping them great. We can’t access the huge number of platforms and myriad hardware, software, and deployment configurations that Puppet is intended to serve. We want to keep it as easy as possible to contribute changes so that our modules work in your environment. There are a few guidelines that we need contributors to follow so that we can have a chance of keeping on top of things. For more information, see our [module contribution guide.](https://docs.puppetlabs.com/forge/contributing.html) +Puppet Labs modules on the Puppet Forge are open projects, and community contributions are essential for keeping them great. We can’t access the huge number of platforms and myriad hardware, software, and deployment configurations that Puppet is intended to serve. We want to keep it as easy as possible to contribute changes so that our modules work in your environment. There are a few guidelines that we need contributors to follow so that we can have a chance of keeping on top of things. For more information, see our [module contribution guide](https://docs.puppetlabs.com/forge/contributing.html). To report or research a bug with any part of this module, please go to [http://tickets.puppetlabs.com/browse/PUP](http://tickets.puppetlabs.com/browse/PUP). -##Contributors +## Contributors -The list of contributors can be found at: https://github.com/puppetlabs/puppetlabs-stdlib/graphs/contributors +The list of contributors can be found at: [https://github.com/puppetlabs/puppetlabs-stdlib/graphs/contributors](https://github.com/puppetlabs/puppetlabs-stdlib/graphs/contributors). -- cgit v1.2.3 From d00bccc96f0bad9fd312453c4d50a6a864286b74 Mon Sep 17 00:00:00 2001 From: jbondpdx Date: Mon, 14 Dec 2015 11:50:51 -0800 Subject: removing mid-line carriage returns --- README.markdown | 26 ++++++-------------------- 1 file changed, 6 insertions(+), 20 deletions(-) diff --git a/README.markdown b/README.markdown index c073b30..68de87a 100644 --- a/README.markdown +++ b/README.markdown @@ -77,11 +77,7 @@ The `stdlib::stages` class declares various run stages for deploying infrastruct #### `file_line` -Ensures that a given line is contained within a file. The implementation -matches the full line, including whitespace at the beginning and end. If -the line is not contained in the given file, Puppet appends the line to -the end of the file to ensure the desired state. Multiple resources can -be declared to manage multiple lines in the same file. +Ensures that a given line is contained within a file. The implementation matches the full line, including whitespace at the beginning and end. If the line is not contained in the given file, Puppet appends the line to the end of the file to ensure the desired state. Multiple resources can be declared to manage multiple lines in the same file. Example: @@ -610,13 +606,11 @@ Converts a number or a string representation of a number into a true boolean. Ze #### `parsejson` -Converts a string of JSON into the correct Puppet structure. *Type*: rvalue. -The optional second argument is returned if the data was not correct. +Converts a string of JSON into the correct Puppet structure. *Type*: rvalue. The optional second argument is returned if the data was not correct. #### `parseyaml` -Converts a string of YAML into the correct Puppet structure. *Type*: rvalue. -The optional second argument is returned if the data was not correct. +Converts a string of YAML into the correct Puppet structure. *Type*: rvalue. The optional second argument is returned if the data was not correct. #### `pick` @@ -703,9 +697,7 @@ Strips spaces to the right of the string. *Type*: rvalue. #### `seeded_rand` -Takes an integer max value and a string seed value and returns a -repeatable random integer smaller than max. Like `fqdn_rand`, but -does not add node specific data to the seed. *Type*: rvalue. +Takes an integer max value and a string seed value and returns a repeatable random integer smaller than max. Like `fqdn_rand`, but does not add node specific data to the seed. *Type*: rvalue. #### `shuffle` @@ -808,15 +800,9 @@ Converts the argument into bytes, for example "4 kB" becomes "4096". Takes a sin *Type*: rvalue. -Retrieves a value within multiple layers of hashes and arrays via a string containing a path. The path is a string of hash keys or array indexes -starting with zero, separated by the path separator character (default "/"). -The function goes through the structure by each path component and tries to -return the value at the end of the path. +Retrieves a value within multiple layers of hashes and arrays via a string containing a path. The path is a string of hash keys or array indexes starting with zero, separated by the path separator character (default "/"). The function goes through the structure by each path component and tries to return the value at the end of the path. -In addition to the required path argument, the function accepts the default -argument. It is returned if the path is not correct, if no value was found, or -if any other error has occurred. The last argument can set the path -separator character. +In addition to the required path argument, the function accepts the default argument. It is returned if the path is not correct, if no value was found, or if any other error has occurred. The last argument can set the path separator character. ~~~ruby $data = { -- cgit v1.2.3 From 802e3adf1660bfa9ea8bdf388cc6ea5b08d79bde Mon Sep 17 00:00:00 2001 From: jbondpdx Date: Mon, 14 Dec 2015 11:57:01 -0800 Subject: more carriage returns, no --- README.markdown | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/README.markdown b/README.markdown index 68de87a..2f46c9f 100644 --- a/README.markdown +++ b/README.markdown @@ -91,8 +91,7 @@ Example: line => '%sudonopw ALL=(ALL) NOPASSWD: ALL', } -In this example, Puppet ensures that both of the specified lines are -contained in the file `/etc/sudoers`. +In this example, Puppet ensures that both of the specified lines are contained in the file `/etc/sudoers`. Match Example: @@ -103,8 +102,7 @@ Match Example: match => '^export\ HTTP_PROXY\=', } -In this code example, `match` looks for a line beginning with export -followed by HTTP_PROXY and replaces it with the value in line. +In this code example, `match` looks for a line beginning with export followed by HTTP_PROXY and replaces it with the value in line. Match Example With `ensure => absent`: @@ -120,8 +118,7 @@ In this code example, `match` looks for a line beginning with export followed by HTTP_PROXY and delete it. If multiple lines match, an error will be raised unless the `multiple => true` parameter is set. -**Autorequires:** If Puppet is managing the file that contains the line -being managed, the `file_line` resource autorequires that file. +**Autorequires:** If Puppet is managing the file that contains the line being managed, the `file_line` resource autorequires that file. ##### Parameters @@ -169,10 +166,7 @@ Converts a boolean to a number. Converts values: #### `bool2str` -Converts a boolean to a string using optionally supplied arguments. The optional -second and third arguments represent what true and false are converted to -respectively. If only one argument is given, it is converted from a boolean -to a string containing 'true' or 'false'. +Converts a boolean to a string using optionally supplied arguments. The optional second and third arguments represent what true and false are converted to respectively. If only one argument is given, it is converted from a boolean to a string containing 'true' or 'false'. *Examples:* ~~~ -- cgit v1.2.3 From 8fcefcfdb195c964b8fdd07b84378659598f2e1e Mon Sep 17 00:00:00 2001 From: jbondpdx Date: Mon, 14 Dec 2015 13:35:23 -0800 Subject: more carriage returns --- README.markdown | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.markdown b/README.markdown index 2f46c9f..221de6e 100644 --- a/README.markdown +++ b/README.markdown @@ -1142,8 +1142,7 @@ test, and the second argument should be a stringified regular expression (withou validate_re($::puppetversion, '^2.7', 'The $puppetversion fact value does not match 2.7') ~~~ - Note: Compilation terminates if the first argument is not a string. Always use - quotes to force stringification: + Note: Compilation terminates if the first argument is not a string. Always use quotes to force stringification: ~~~ validate_re("${::operatingsystemmajrelease}", '^[57]$') -- cgit v1.2.3 From 1b048ff9d689fcd0ff8e67640598cb0a1aa00887 Mon Sep 17 00:00:00 2001 From: Corey Osman Date: Mon, 7 Dec 2015 16:38:26 -0800 Subject: adds new parser called is_absolute_path * is_absolute_path returns boolean true if the given path is absolute, returns false otherwise. * works for windows and unix --- README.markdown | 4 + lib/puppet/parser/functions/is_absolute_path.rb | 50 +++++++++++++ .../parser/functions/is_absolute_path_spec.rb | 86 ++++++++++++++++++++++ 3 files changed, 140 insertions(+) create mode 100644 lib/puppet/parser/functions/is_absolute_path.rb create mode 100644 spec/unit/puppet/parser/functions/is_absolute_path_spec.rb diff --git a/README.markdown b/README.markdown index 221de6e..a6ed1fb 100644 --- a/README.markdown +++ b/README.markdown @@ -474,6 +474,10 @@ Boolean check to determine whether a variable is of a given data type. This is e See the [the Puppet type system](https://docs.puppetlabs.com/references/latest/type.html#about-resource-types) for more information about types. See the [`assert_type()`](https://docs.puppetlabs.com/references/latest/function.html#asserttype) function for flexible ways to assert the type of a value. +#### `is_absolute_path` + +Returns 'true' if the given path is absolute. *Type*: rvalue. + #### `is_array` Returns 'true' if the variable passed to this function is an array. *Type*: rvalue. diff --git a/lib/puppet/parser/functions/is_absolute_path.rb b/lib/puppet/parser/functions/is_absolute_path.rb new file mode 100644 index 0000000..53a5445 --- /dev/null +++ b/lib/puppet/parser/functions/is_absolute_path.rb @@ -0,0 +1,50 @@ +module Puppet::Parser::Functions + newfunction(:is_absolute_path, :type => :rvalue, :arity => 1, :doc => <<-'ENDHEREDOC') do |args| + Returns boolean true if the string represents an absolute path in the filesystem. This function works + for windows and unix style paths. + + The following values will return true: + + $my_path = 'C:/Program Files (x86)/Puppet Labs/Puppet' + is_absolute_path($my_path) + $my_path2 = '/var/lib/puppet' + is_absolute_path($my_path2) + $my_path3 = ['C:/Program Files (x86)/Puppet Labs/Puppet'] + is_absolute_path($my_path3) + $my_path4 = ['/var/lib/puppet'] + is_absolute_path($my_path4) + + The following values will return false: + + is_absolute_path(true) + is_absolute_path('../var/lib/puppet') + is_absolute_path('var/lib/puppet') + $undefined = undef + is_absolute_path($undefined) + + ENDHEREDOC + + require 'puppet/util' + + path = args[0] + # This logic was borrowed from + # [lib/puppet/file_serving/base.rb](https://github.com/puppetlabs/puppet/blob/master/lib/puppet/file_serving/base.rb) + # Puppet 2.7 and beyond will have Puppet::Util.absolute_path? Fall back to a back-ported implementation otherwise. + if Puppet::Util.respond_to?(:absolute_path?) then + value = (Puppet::Util.absolute_path?(path, :posix) or Puppet::Util.absolute_path?(path, :windows)) + else + # This code back-ported from 2.7.x's lib/puppet/util.rb Puppet::Util.absolute_path? + # Determine in a platform-specific way whether a path is absolute. This + # defaults to the local platform if none is specified. + # Escape once for the string literal, and once for the regex. + slash = '[\\\\/]' + name = '[^\\\\/]+' + regexes = { + :windows => %r!^(([A-Z]:#{slash})|(#{slash}#{slash}#{name}#{slash}#{name})|(#{slash}#{slash}\?#{slash}#{name}))!i, + :posix => %r!^/! + } + value = (!!(path =~ regexes[:posix])) || (!!(path =~ regexes[:windows])) + end + value + end +end \ No newline at end of file diff --git a/spec/unit/puppet/parser/functions/is_absolute_path_spec.rb b/spec/unit/puppet/parser/functions/is_absolute_path_spec.rb new file mode 100644 index 0000000..8931208 --- /dev/null +++ b/spec/unit/puppet/parser/functions/is_absolute_path_spec.rb @@ -0,0 +1,86 @@ +require 'spec_helper' + +describe :is_absolute_path do + let(:scope) { PuppetlabsSpec::PuppetInternals.scope } + + let(:function_args) do + [] + end + + let(:function) do + scope.function_is_absolute_path(function_args) + end + + + describe 'validate arity' do + let(:function_args) do + [1,2] + end + it "should raise a ParseError if there is more than 1 arguments" do + lambda { function }.should( raise_error(ArgumentError)) + end + + end + + it "should exist" do + Puppet::Parser::Functions.function(subject).should == "function_#{subject}" + end + + # help enforce good function defination + it 'should contain arity' do + + end + + it "should raise a ParseError if there is less than 1 arguments" do + lambda { function }.should( raise_error(ArgumentError)) + end + + + describe 'should retrun true' do + let(:return_value) do + true + end + + describe 'windows' do + let(:function_args) do + ['c:\temp\test.txt'] + end + it 'should return data' do + function.should eq(return_value) + end + end + + describe 'non-windows' do + let(:function_args) do + ['/temp/test.txt'] + end + + it 'should return data' do + function.should eq(return_value) + end + end + end + + describe 'should return false' do + let(:return_value) do + false + end + describe 'windows' do + let(:function_args) do + ['..\temp\test.txt'] + end + it 'should return data' do + function.should eq(return_value) + end + end + + describe 'non-windows' do + let(:function_args) do + ['../var/lib/puppet'] + end + it 'should return data' do + function.should eq(return_value) + end + end + end +end \ No newline at end of file -- cgit v1.2.3 From 1da820e61e08e72cf69d8833c37ecb9446fcd142 Mon Sep 17 00:00:00 2001 From: Corey Osman Date: Tue, 15 Dec 2015 23:15:36 -0800 Subject: refactors the validate_absolute_path to utilize the is_absolute_path --- .../parser/functions/validate_absolute_path.rb | 24 +++------------------- 1 file changed, 3 insertions(+), 21 deletions(-) diff --git a/lib/puppet/parser/functions/validate_absolute_path.rb b/lib/puppet/parser/functions/validate_absolute_path.rb index b696680..5f85f72 100644 --- a/lib/puppet/parser/functions/validate_absolute_path.rb +++ b/lib/puppet/parser/functions/validate_absolute_path.rb @@ -40,28 +40,10 @@ module Puppet::Parser::Functions unless arg.is_a?(Array) then candidates = Array.new(1,arg) end - # iterate over all pathes within the candidates array + # iterate over all paths within the candidates array candidates.each do |path| - # This logic was borrowed from - # [lib/puppet/file_serving/base.rb](https://github.com/puppetlabs/puppet/blob/master/lib/puppet/file_serving/base.rb) - # Puppet 2.7 and beyond will have Puppet::Util.absolute_path? Fall back to a back-ported implementation otherwise. - if Puppet::Util.respond_to?(:absolute_path?) then - unless Puppet::Util.absolute_path?(path, :posix) or Puppet::Util.absolute_path?(path, :windows) - raise Puppet::ParseError, ("#{path.inspect} is not an absolute path.") - end - else - # This code back-ported from 2.7.x's lib/puppet/util.rb Puppet::Util.absolute_path? - # Determine in a platform-specific way whether a path is absolute. This - # defaults to the local platform if none is specified. - # Escape once for the string literal, and once for the regex. - slash = '[\\\\/]' - name = '[^\\\\/]+' - regexes = { - :windows => %r!^(([A-Z]:#{slash})|(#{slash}#{slash}#{name}#{slash}#{name})|(#{slash}#{slash}\?#{slash}#{name}))!i, - :posix => %r!^/!, - } - rval = (!!(path =~ regexes[:posix])) || (!!(path =~ regexes[:windows])) - rval or raise Puppet::ParseError, ("#{path.inspect} is not an absolute path.") + unless function_is_absolute_path([path]) + raise Puppet::ParseError, ("#{path.inspect} is not an absolute path.") end end end -- cgit v1.2.3 From 02965b89e558d5af98ce589da5f5687c4d613b49 Mon Sep 17 00:00:00 2001 From: David Schmitt Date: Thu, 17 Dec 2015 13:50:15 +0000 Subject: (FM-3802) make ensure_resource test of packages This ensures that the test passes independently of changes to rubygems. --- spec/acceptance/ensure_resource_spec.rb | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/spec/acceptance/ensure_resource_spec.rb b/spec/acceptance/ensure_resource_spec.rb index fe619a9..93f25dd 100755 --- a/spec/acceptance/ensure_resource_spec.rb +++ b/spec/acceptance/ensure_resource_spec.rb @@ -1,18 +1,26 @@ #! /usr/bin/env ruby -S rspec require 'spec_helper_acceptance' -describe 'ensure_resource function', :unless => fact('osfamily') =~ /(windows|Suse)/i do +describe 'ensure_resource function' do describe 'success' do - it 'ensure_resource a package' do - apply_manifest('package { "rake": ensure => absent, provider => "gem", }') + it 'ensures a resource already declared' do + apply_manifest('') pp = <<-EOS - $a = "rake" - ensure_resource('package', $a, {'provider' => 'gem'}) + notify { "test": loglevel => 'err' } + ensure_resource('notify', 'test', { 'loglevel' => 'err' }) + EOS + + apply_manifest(pp, :expect_changes => true) + end + + it 'ensures a undeclared resource' do + apply_manifest('') + pp = <<-EOS + ensure_resource('notify', 'test', { 'loglevel' => 'err' }) EOS apply_manifest(pp, :expect_changes => true) end - it 'ensures a resource already declared' it 'takes defaults arguments' end describe 'failure' do -- cgit v1.2.3 From 35b5d6bcc1c0d306eab50280b115e1e3a11671e0 Mon Sep 17 00:00:00 2001 From: David Schmitt Date: Fri, 18 Dec 2015 17:38:04 +0000 Subject: Allow package_provider fact to resolve on PE 3.x PE 3.x emits a puppetversion fact in the format "3.x.x (Puppet Enterprise 3.x.x)". This fact causes an error when invoked on PE 3.x: Could not retrieve fact='package_provider', resolution='': Malformed version number string 3.8.1 (Puppet Enterprise 3.8.1 This fix has been tested on PE 3.8.2 and should work for PE 3.3, 3.7, and 3.8. Original-fix-by: Alex Harden --- lib/facter/package_provider.rb | 2 +- spec/unit/facter/package_provider_spec.rb | 57 +++++++++++++++++-------------- 2 files changed, 33 insertions(+), 26 deletions(-) diff --git a/lib/facter/package_provider.rb b/lib/facter/package_provider.rb index 65a2da0..1a0bac9 100644 --- a/lib/facter/package_provider.rb +++ b/lib/facter/package_provider.rb @@ -12,7 +12,7 @@ require 'puppet/type/package' Facter.add(:package_provider) do setcode do - if Gem::Version.new(Facter.value(:puppetversion)) >= Gem::Version.new('3.6') + if Gem::Version.new(Facter.value(:puppetversion).split(' ')[0]) >= Gem::Version.new('3.6') Puppet::Type.type(:package).newpackage(:name => 'dummy', :allow_virtual => 'true')[:provider].to_s else Puppet::Type.type(:package).newpackage(:name => 'dummy')[:provider].to_s diff --git a/spec/unit/facter/package_provider_spec.rb b/spec/unit/facter/package_provider_spec.rb index d1aee94..3954faf 100644 --- a/spec/unit/facter/package_provider_spec.rb +++ b/spec/unit/facter/package_provider_spec.rb @@ -7,31 +7,38 @@ describe 'package_provider', :type => :fact do before { Facter.clear } after { Facter.clear } - context "darwin" do - it "should return pkgdmg" do - provider = Puppet::Type.type(:package).provider(:pkgdmg) - Puppet::Type.type(:package).stubs(:defaultprovider).returns provider - - expect(Facter.fact(:package_provider).value).to eq('pkgdmg') - end - end - - context "centos 7" do - it "should return yum" do - provider = Puppet::Type.type(:package).provider(:yum) - Puppet::Type.type(:package).stubs(:defaultprovider).returns provider - - expect(Facter.fact(:package_provider).value).to eq('yum') + ['4.2.2', '3.7.1 (Puppet Enterprise 3.2.1)'].each do |puppetversion| + describe "on puppet ''#{puppetversion}''" do + before :each do + Facter.stubs(:value).returns puppetversion + end + + context "darwin" do + it "should return pkgdmg" do + provider = Puppet::Type.type(:package).provider(:pkgdmg) + Puppet::Type.type(:package).stubs(:defaultprovider).returns provider + + expect(Facter.fact(:package_provider).value).to eq('pkgdmg') + end + end + + context "centos 7" do + it "should return yum" do + provider = Puppet::Type.type(:package).provider(:yum) + Puppet::Type.type(:package).stubs(:defaultprovider).returns provider + + expect(Facter.fact(:package_provider).value).to eq('yum') + end + end + + context "ubuntu" do + it "should return apt" do + provider = Puppet::Type.type(:package).provider(:apt) + Puppet::Type.type(:package).stubs(:defaultprovider).returns provider + + expect(Facter.fact(:package_provider).value).to eq('apt') + end + end end end - - context "ubuntu" do - it "should return apt" do - provider = Puppet::Type.type(:package).provider(:apt) - Puppet::Type.type(:package).stubs(:defaultprovider).returns provider - - expect(Facter.fact(:package_provider).value).to eq('apt') - end - end - end -- cgit v1.2.3 From 00973036b296e20b42133712ab6492acb67dac1f Mon Sep 17 00:00:00 2001 From: tphoney Date: Wed, 30 Dec 2015 13:45:05 +0000 Subject: 4.11.0 prep --- CHANGELOG.md | 14 ++++++++++++++ metadata.json | 2 +- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 94a0577..5cb1523 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,17 @@ +## Supported Release 4.11.0 +###Summary + +Provides a new parser validate_absolute_paths, a fix to the is_package_provider fact and a test improvement. + +####Features +- Adds new parser called is_absolute_path + +####Bugfixes +- Allow package_provider fact to resolve on PE 3.x + +####Improvements +- ensures that the test passes independently of changes to rubygems for ensure_resource + ##2015-12-15 - Supported Release 4.10.0 ###Summary diff --git a/metadata.json b/metadata.json index 947ef9a..b6a370c 100644 --- a/metadata.json +++ b/metadata.json @@ -1,6 +1,6 @@ { "name": "puppetlabs-stdlib", - "version": "4.10.0", + "version": "4.11.0", "author": "puppetlabs", "summary": "Standard library of resources for Puppet modules.", "license": "Apache-2.0", -- cgit v1.2.3 From 27782242bc27dced7bed316a01c21fffd94e34f8 Mon Sep 17 00:00:00 2001 From: Michael Polenchuk Date: Wed, 18 Nov 2015 14:32:24 +0300 Subject: Add clamp function Clamp keeps value within the range. Employ of soft() makes the whole thing is independant of order. --- README.markdown | 8 ++++++++ lib/puppet/parser/functions/clamp.rb | 30 +++++++++++++++++++++++++++ spec/acceptance/clamp_spec.rb | 40 ++++++++++++++++++++++++++++++++++++ spec/functions/clamp_spec.rb | 16 +++++++++++++++ 4 files changed, 94 insertions(+) create mode 100644 lib/puppet/parser/functions/clamp.rb create mode 100755 spec/acceptance/clamp_spec.rb create mode 100644 spec/functions/clamp_spec.rb diff --git a/README.markdown b/README.markdown index 9ff242c..0931e63 100644 --- a/README.markdown +++ b/README.markdown @@ -202,6 +202,14 @@ Removes the record separator from the end of a string or an array of strings; fo Returns a new string with the last character removed. If the string ends with '\r\n', both characters are removed. Applying `chop` to an empty string returns an empty string. If you want to merely remove record separators, then you should use the `chomp` function. Requires a string or an array of strings as input. *Type*: rvalue. +#### `clamp` + +Keeps value within the range [Min, X, Max] by sort based on integer value (order of params doesn't matter). Takes strings, arrays or numerics. Strings are converted and compared numerically. Arrays of values are flattened into a list for further handling. For example: + * `clamp('24', [575, 187])` returns 187. + * `clamp(16, 88, 661)` returns 88. + * `clamp([4, 3, '99'])` returns 4. + *Type*: rvalue. + #### `concat` Appends the contents of multiple arrays onto the first array given. For example: diff --git a/lib/puppet/parser/functions/clamp.rb b/lib/puppet/parser/functions/clamp.rb new file mode 100644 index 0000000..432c7c1 --- /dev/null +++ b/lib/puppet/parser/functions/clamp.rb @@ -0,0 +1,30 @@ +# +# clamp.rb +# + +module Puppet::Parser::Functions + newfunction(:clamp, :type => :rvalue, :arity => -2, :doc => <<-EOS + Clamps value to a range. + EOS + ) do |args| + + args.flatten! + + raise(Puppet::ParseError, 'clamp(): Wrong number of arguments, ' + + 'need three to clamp') if args.size != 3 + + # check values out + args.each do |value| + case [value.class] + when [String] + raise(Puppet::ParseError, "clamp(): Required explicit numeric (#{value}:String)") unless value =~ /^\d+$/ + when [Hash] + raise(Puppet::ParseError, "clamp(): The Hash type is not allowed (#{value})") + end + end + + # convert to numeric each element + # then sort them and get a middle value + args.map{ |n| n.to_i }.sort[1] + end +end diff --git a/spec/acceptance/clamp_spec.rb b/spec/acceptance/clamp_spec.rb new file mode 100755 index 0000000..0189258 --- /dev/null +++ b/spec/acceptance/clamp_spec.rb @@ -0,0 +1,40 @@ +#! /usr/bin/env ruby -S rspec +require 'spec_helper_acceptance' + +describe 'clamp function', :unless => UNSUPPORTED_PLATFORMS.include?(fact('operatingsystem')) do + describe 'success' do + it 'clamps list of values' do + pp = <<-EOS + $x = 17 + $y = 225 + $z = 155 + $o = clamp($x, $y, $z) + if $o == $z { + notify { 'output correct': } + } + EOS + + apply_manifest(pp, :catch_failures => true) do |r| + expect(r.stdout).to match(/Notice: output correct/) + end + end + it 'clamps array of values' do + pp = <<-EOS + $a = [7, 19, 66] + $b = 19 + $o = clamp($a) + if $o == $b { + notify { 'output correct': } + } + EOS + + apply_manifest(pp, :catch_failures => true) do |r| + expect(r.stdout).to match(/Notice: output correct/) + end + end + end + describe 'failure' do + it 'handles improper argument counts' + it 'handles no arguments' + end +end diff --git a/spec/functions/clamp_spec.rb b/spec/functions/clamp_spec.rb new file mode 100644 index 0000000..3e2fe7a --- /dev/null +++ b/spec/functions/clamp_spec.rb @@ -0,0 +1,16 @@ +require 'spec_helper' + +describe 'clamp' do + it { is_expected.not_to eq(nil) } + it { is_expected.to run.with_params().and_raise_error(ArgumentError) } + it { is_expected.to run.with_params([]).and_raise_error(Puppet::ParseError) } + it { is_expected.to run.with_params(12, 88, 71, 190).and_raise_error(Puppet::ParseError, /Wrong number of arguments, need three to clamp/) } + it { is_expected.to run.with_params('12string', 88, 15).and_raise_error(Puppet::ParseError, /Required explicit numeric/) } + it { is_expected.to run.with_params(1, 2, {'a' => 55}).and_raise_error(Puppet::ParseError, /The Hash type is not allowed/) } + it { is_expected.to run.with_params('24', [575, 187]).and_return(187) } + it { is_expected.to run.with_params([4, 3, '99']).and_return(4) } + it { is_expected.to run.with_params(16, 750, 88).and_return(88) } + it { is_expected.to run.with_params([3, 873], 73).and_return(73) } + it { is_expected.to run.with_params([4], 8, 75).and_return(8) } + it { is_expected.to run.with_params([6], [31], 9911).and_return(31) } +end -- cgit v1.2.3 From 33b79f3497dac5438d78eeb817d6feee89ccf723 Mon Sep 17 00:00:00 2001 From: tphoney Date: Thu, 7 Jan 2016 10:31:17 +0000 Subject: minor tweak to 4.11.0 adding debian 8 to metadata --- CHANGELOG.md | 3 ++- metadata.json | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5cb1523..2698dde 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,10 +1,11 @@ ## Supported Release 4.11.0 ###Summary -Provides a new parser validate_absolute_paths, a fix to the is_package_provider fact and a test improvement. +Provides a validate_absolute_paths and Debian 8 support. There is a fix to the is_package_provider fact and a test improvement. ####Features - Adds new parser called is_absolute_path +- Supports Debian 8 ####Bugfixes - Allow package_provider fact to resolve on PE 3.x diff --git a/metadata.json b/metadata.json index b6a370c..a7ea0af 100644 --- a/metadata.json +++ b/metadata.json @@ -56,7 +56,8 @@ "operatingsystem": "Debian", "operatingsystemrelease": [ "6", - "7" + "7", + "8" ] }, { -- cgit v1.2.3 From 97320ab42121a10b76c642b8378c82a888148e4b Mon Sep 17 00:00:00 2001 From: Matt Bostock Date: Mon, 23 Nov 2015 23:45:23 +0000 Subject: Add a function to validate an x509 RSA key pair Add a function to validate an x509 RSA certificate and key pair, as commonly used for TLS certificates. The rationale behind this is that we store our TLS certificates and private keys in Hiera YAML files, and poor indentation or formatting in the YAML file could cause a valid certificate to be considered invalid. Will cause the Puppet run to fail if: - an invalid certificate is detected - an invalid RSA key is detected - the certificate does not match the key, i.e. the certificate has not been signed by the supplied key The test certificates I've used in the spec tests were generated using the Go standard library: $ go run $GOROOT/src/crypto/tls/generate_cert.go -host localhost Example output: ==> cache-1.router: Error: Not a valid RSA key: Neither PUB key nor PRIV key:: nested asn1 error at /var/govuk/puppet/modules/nginx/manifests/config/ssl.pp:30 on node cache-1.router.dev.gov.uk --- README.markdown | 16 +++ .../parser/functions/validate_x509_rsa_key_pair.rb | 47 +++++++ spec/functions/validate_x509_rsa_key_pair_spec.rb | 154 +++++++++++++++++++++ 3 files changed, 217 insertions(+) create mode 100644 lib/puppet/parser/functions/validate_x509_rsa_key_pair.rb create mode 100755 spec/functions/validate_x509_rsa_key_pair_spec.rb diff --git a/README.markdown b/README.markdown index 9ff242c..e126e5d 100644 --- a/README.markdown +++ b/README.markdown @@ -1182,6 +1182,22 @@ Instead, use: *Type*: statement. +#### `validate_x509_rsa_key_pair` + +Validates a PEM-formatted X.509 certificate and private key using OpenSSL. +Verifies that the certficate's signature was created from the supplied key. + +Fails catalog compilation if any value fails this check. + +Takes two arguments, the first argument must be a X.509 certificate and the +second must be an RSA private key: + + ~~~ + validate_x509_rsa_key_pair($cert, $key) + ~~~ + +*Type*: statement. + #### `values` Returns the values of a given hash. For example, given `$hash = {'a'=1, 'b'=2, 'c'=3} values($hash)` returns [1,2,3]. diff --git a/lib/puppet/parser/functions/validate_x509_rsa_key_pair.rb b/lib/puppet/parser/functions/validate_x509_rsa_key_pair.rb new file mode 100644 index 0000000..fc9f23f --- /dev/null +++ b/lib/puppet/parser/functions/validate_x509_rsa_key_pair.rb @@ -0,0 +1,47 @@ +module Puppet::Parser::Functions + + newfunction(:validate_x509_rsa_key_pair, :doc => <<-ENDHEREDOC + Validates a PEM-formatted X.509 certificate and RSA private key using + OpenSSL. Verifies that the certficate's signature was created from the + supplied key. + + Fail compilation if any value fails this check. + + validate_x509_rsa_key_pair($cert, $key) + + ENDHEREDOC + ) do |args| + + require 'openssl' + + NUM_ARGS = 2 unless defined? NUM_ARGS + + unless args.length == NUM_ARGS then + raise Puppet::ParseError, + ("validate_x509_rsa_key_pair(): wrong number of arguments (#{args.length}; must be #{NUM_ARGS})") + end + + args.each do |arg| + unless arg.is_a?(String) + raise Puppet::ParseError, "#{arg.inspect} is not a string." + end + end + + begin + cert = OpenSSL::X509::Certificate.new(args[0]) + rescue OpenSSL::X509::CertificateError => e + raise Puppet::ParseError, "Not a valid x509 certificate: #{e}" + end + + begin + key = OpenSSL::PKey::RSA.new(args[1]) + rescue OpenSSL::PKey::RSAError => e + raise Puppet::ParseError, "Not a valid RSA key: #{e}" + end + + unless cert.verify(key) + raise Puppet::ParseError, "Certificate signature does not match supplied key" + end + end + +end diff --git a/spec/functions/validate_x509_rsa_key_pair_spec.rb b/spec/functions/validate_x509_rsa_key_pair_spec.rb new file mode 100755 index 0000000..048d65e --- /dev/null +++ b/spec/functions/validate_x509_rsa_key_pair_spec.rb @@ -0,0 +1,154 @@ +require 'spec_helper' + +describe 'validate_x509_rsa_key_pair' do + + let(:valid_cert) do + < Date: Fri, 8 Jan 2016 11:01:51 +0000 Subject: Test certificate and key with a truncated middle Test a valid certificate and valid key that have had 48 characters removed from their middle, to simulate a malformed certificate and key. Suggested by @DavidS in https://github.com/puppetlabs/puppetlabs-stdlib/pull/552 --- spec/functions/validate_x509_rsa_key_pair_spec.rb | 26 +++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/spec/functions/validate_x509_rsa_key_pair_spec.rb b/spec/functions/validate_x509_rsa_key_pair_spec.rb index 048d65e..bfa7e38 100755 --- a/spec/functions/validate_x509_rsa_key_pair_spec.rb +++ b/spec/functions/validate_x509_rsa_key_pair_spec.rb @@ -97,6 +97,14 @@ EOS valid_key.gsub(/^/, ' ') end + let(:malformed_cert) do + truncate_middle(valid_cert) + end + + let(:malformed_key) do + truncate_middle(valid_key) + end + let(:bad_cert) do 'foo' end @@ -126,6 +134,14 @@ EOS it { is_expected.to run.with_params(valid_cert, valid_key_but_indented).and_raise_error(Puppet::ParseError, /Not a valid RSA key/) } end + describe 'valid certificate, malformed key' do + it { is_expected.to run.with_params(valid_cert, malformed_key).and_raise_error(Puppet::ParseError, /Not a valid RSA key/) } + end + + describe 'malformed certificate, valid key' do + it { is_expected.to run.with_params(malformed_cert, valid_key).and_raise_error(Puppet::ParseError, /Not a valid x509 certificate/) } + end + describe 'valid certificate, bad key' do it { is_expected.to run.with_params(valid_cert, bad_key).and_raise_error(Puppet::ParseError, /Not a valid RSA key/) } end @@ -151,4 +167,14 @@ EOS it { is_expected.to run.with_params("baz", true).and_raise_error(Puppet::ParseError, /is not a string/) } end end + + def truncate_middle(string) + chars_to_truncate = 48 + middle = (string.length / 2).floor + start_pos = middle - (chars_to_truncate / 2) + end_pos = middle + (chars_to_truncate / 2) + + string[start_pos...end_pos] = '' + return string + end end -- cgit v1.2.3 From 41f9319bbd96547f9c2226524918e4b748527048 Mon Sep 17 00:00:00 2001 From: Matt Bostock Date: Fri, 8 Jan 2016 11:06:57 +0000 Subject: Change order of tests to be more logical Put the tests using a valid certificate fixture together and put tests using a valid key fixture together. --- spec/functions/validate_x509_rsa_key_pair_spec.rb | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/spec/functions/validate_x509_rsa_key_pair_spec.rb b/spec/functions/validate_x509_rsa_key_pair_spec.rb index bfa7e38..eb63310 100755 --- a/spec/functions/validate_x509_rsa_key_pair_spec.rb +++ b/spec/functions/validate_x509_rsa_key_pair_spec.rb @@ -126,10 +126,6 @@ EOS end context 'bad input' do - describe 'valid but indented certificate, valid key' do - it { is_expected.to run.with_params(valid_cert_but_indented, valid_key).and_raise_error(Puppet::ParseError, /Not a valid x509 certificate/) } - end - describe 'valid certificate, valid but indented key' do it { is_expected.to run.with_params(valid_cert, valid_key_but_indented).and_raise_error(Puppet::ParseError, /Not a valid RSA key/) } end @@ -138,14 +134,18 @@ EOS it { is_expected.to run.with_params(valid_cert, malformed_key).and_raise_error(Puppet::ParseError, /Not a valid RSA key/) } end - describe 'malformed certificate, valid key' do - it { is_expected.to run.with_params(malformed_cert, valid_key).and_raise_error(Puppet::ParseError, /Not a valid x509 certificate/) } - end - describe 'valid certificate, bad key' do it { is_expected.to run.with_params(valid_cert, bad_key).and_raise_error(Puppet::ParseError, /Not a valid RSA key/) } end + describe 'valid but indented certificate, valid key' do + it { is_expected.to run.with_params(valid_cert_but_indented, valid_key).and_raise_error(Puppet::ParseError, /Not a valid x509 certificate/) } + end + + describe 'malformed certificate, valid key' do + it { is_expected.to run.with_params(malformed_cert, valid_key).and_raise_error(Puppet::ParseError, /Not a valid x509 certificate/) } + end + describe 'bad certificate, valid key' do it { is_expected.to run.with_params(bad_cert, valid_key).and_raise_error(Puppet::ParseError, /Not a valid x509 certificate/) } end -- cgit v1.2.3 From 1659d478b9981f9ef409540962e5694f7ed05172 Mon Sep 17 00:00:00 2001 From: Alec Henninger Date: Sat, 16 Jan 2016 11:55:25 -0500 Subject: Add test for basename on path with scheme --- spec/functions/basename_spec.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/spec/functions/basename_spec.rb b/spec/functions/basename_spec.rb index 0ea30e7..c84e192 100755 --- a/spec/functions/basename_spec.rb +++ b/spec/functions/basename_spec.rb @@ -10,4 +10,5 @@ describe 'basename' do it { is_expected.to run.with_params('relative_path/to/a/file.ext').and_return('file.ext') } it { is_expected.to run.with_params('/path/to/a/file.ext', '.ext').and_return('file') } it { is_expected.to run.with_params('relative_path/to/a/file.ext', '.ext').and_return('file') } + it { is_expected.to run.with_params('scheme:///path/to/a/file.ext').and_return('file.ext') } end -- cgit v1.2.3 From b7df76cf7acf5924f169e1458f0a53248fc81c08 Mon Sep 17 00:00:00 2001 From: Matt Bostock Date: Tue, 19 Jan 2016 16:22:01 +0000 Subject: Fix reference to validate_bool in function The documentation in `validate_ip_address` references `validate_bool`, but I believe this should read `validate_ip_address` instead, which makes more sense. Looks like this was copied from `validate_ipv4_address`, which I fixed in 7b068781. --- lib/puppet/parser/functions/validate_ip_address.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/puppet/parser/functions/validate_ip_address.rb b/lib/puppet/parser/functions/validate_ip_address.rb index c0baf82..64fbd75 100644 --- a/lib/puppet/parser/functions/validate_ip_address.rb +++ b/lib/puppet/parser/functions/validate_ip_address.rb @@ -7,12 +7,12 @@ module Puppet::Parser::Functions The following values will pass: $my_ip = "1.2.3.4" validate_ip_address($my_ip) - validate_bool("8.8.8.8", "172.16.0.1", $my_ip) + validate_ip_address("8.8.8.8", "172.16.0.1", $my_ip) $my_ip = "3ffe:505:2" validate_ip_address(1) validate_ip_address($my_ip) - validate_bool("fe80::baf6:b1ff:fe19:7507", $my_ip) + validate_ip_address("fe80::baf6:b1ff:fe19:7507", $my_ip) The following values will fail, causing compilation to abort: $some_array = [ 1, true, false, "garbage string", "3ffe:505:2" ] -- cgit v1.2.3 From d85aec41a3b57a13f16086cc1ff7ed2fe09602b8 Mon Sep 17 00:00:00 2001 From: Giulio Fidente Date: Fri, 22 Jan 2016 17:55:03 +0100 Subject: Add is_ipv4_address and is_ipv6_address functions These are useful when making decisions based on the type of IP address received. --- README.markdown | 8 ++++ lib/puppet/parser/functions/is_ipv4_address.rb | 28 +++++++++++ lib/puppet/parser/functions/is_ipv6_address.rb | 28 +++++++++++ spec/acceptance/is_ipv4_address_spec.rb | 52 ++++++++++++++++++++ spec/acceptance/is_ipv6_address_spec.rb | 66 ++++++++++++++++++++++++++ 5 files changed, 182 insertions(+) create mode 100644 lib/puppet/parser/functions/is_ipv4_address.rb create mode 100644 lib/puppet/parser/functions/is_ipv6_address.rb create mode 100755 spec/acceptance/is_ipv4_address_spec.rb create mode 100755 spec/acceptance/is_ipv6_address_spec.rb diff --git a/README.markdown b/README.markdown index 559a6a0..4417733 100644 --- a/README.markdown +++ b/README.markdown @@ -518,6 +518,14 @@ Returns 'true' if the variable returned to this string is an integer. *Type*: rv Returns 'true' if the string passed to this function is a valid IP address. *Type*: rvalue. +#### `is_ipv6_address` + +Returns 'true' if the string passed to this function is a valid IPv6 address. *Type*: rvalue. + +#### `is_ipv4_address` + +Returns 'true' if the string passed to this function is a valid IPv4 address. *Type*: rvalue. + #### `is_mac_address` Returns 'true' if the string passed to this function is a valid MAC address. *Type*: rvalue. diff --git a/lib/puppet/parser/functions/is_ipv4_address.rb b/lib/puppet/parser/functions/is_ipv4_address.rb new file mode 100644 index 0000000..b4861d5 --- /dev/null +++ b/lib/puppet/parser/functions/is_ipv4_address.rb @@ -0,0 +1,28 @@ +# +# is_ipv4_address.rb +# + +module Puppet::Parser::Functions + newfunction(:is_ipv4_address, :type => :rvalue, :doc => <<-EOS +Returns true if the string passed to this function is a valid IPv4 address. + EOS + ) do |arguments| + + require 'ipaddr' + + if (arguments.size != 1) then + raise(Puppet::ParseError, "is_ipv4_address(): Wrong number of arguments "+ + "given #{arguments.size} for 1") + end + + begin + ip = IPAddr.new(arguments[0]) + rescue ArgumentError + return false + end + + return ip.ipv4? + end +end + +# vim: set ts=2 sw=2 et : diff --git a/lib/puppet/parser/functions/is_ipv6_address.rb b/lib/puppet/parser/functions/is_ipv6_address.rb new file mode 100644 index 0000000..475ad50 --- /dev/null +++ b/lib/puppet/parser/functions/is_ipv6_address.rb @@ -0,0 +1,28 @@ +# +# is_ipv6_address.rb +# + +module Puppet::Parser::Functions + newfunction(:is_ipv6_address, :type => :rvalue, :doc => <<-EOS +Returns true if the string passed to this function is a valid IPv6 address. + EOS + ) do |arguments| + + require 'ipaddr' + + if (arguments.size != 1) then + raise(Puppet::ParseError, "is_ipv6_address(): Wrong number of arguments "+ + "given #{arguments.size} for 1") + end + + begin + ip = IPAddr.new(arguments[0]) + rescue ArgumentError + return false + end + + return ip.ipv6? + end +end + +# vim: set ts=2 sw=2 et : diff --git a/spec/acceptance/is_ipv4_address_spec.rb b/spec/acceptance/is_ipv4_address_spec.rb new file mode 100755 index 0000000..5dc6bf5 --- /dev/null +++ b/spec/acceptance/is_ipv4_address_spec.rb @@ -0,0 +1,52 @@ +#! /usr/bin/env ruby -S rspec +require 'spec_helper_acceptance' + +describe 'is_ipv4_address function', :unless => UNSUPPORTED_PLATFORMS.include?(fact('operatingsystem')) do + describe 'success' do + it 'is_ipv4_addresss' do + pp = <<-EOS + $a = '1.2.3.4' + $b = true + $o = is_ipv4_address($a) + if $o == $b { + notify { 'output correct': } + } + EOS + + apply_manifest(pp, :catch_failures => true) do |r| + expect(r.stdout).to match(/Notice: output correct/) + end + end + it 'is_ipv4_addresss strings' do + pp = <<-EOS + $a = "aoeu" + $b = false + $o = is_ipv4_address($a) + if $o == $b { + notify { 'output correct': } + } + EOS + + apply_manifest(pp, :catch_failures => true) do |r| + expect(r.stdout).to match(/Notice: output correct/) + end + end + it 'is_ipv4_addresss ipv4 out of range' do + pp = <<-EOS + $a = '1.2.3.400' + $b = false + $o = is_ipv4_address($a) + if $o == $b { + notify { 'output correct': } + } + EOS + + apply_manifest(pp, :catch_failures => true) do |r| + expect(r.stdout).to match(/Notice: output correct/) + end + end + end + describe 'failure' do + it 'handles improper argument counts' + end +end diff --git a/spec/acceptance/is_ipv6_address_spec.rb b/spec/acceptance/is_ipv6_address_spec.rb new file mode 100755 index 0000000..1e88be8 --- /dev/null +++ b/spec/acceptance/is_ipv6_address_spec.rb @@ -0,0 +1,66 @@ +#! /usr/bin/env ruby -S rspec +require 'spec_helper_acceptance' + +describe 'is_ipv6_address function', :unless => UNSUPPORTED_PLATFORMS.include?(fact('operatingsystem')) do + describe 'success' do + it 'is_ipv6_addresss' do + pp = <<-EOS + $a = "fe80:0000:cd12:d123:e2f8:47ff:fe09:dd74" + $b = true + $o = is_ipv6_address($a) + if $o == $b { + notify { 'output correct': } + } + EOS + + apply_manifest(pp, :catch_failures => true) do |r| + expect(r.stdout).to match(/Notice: output correct/) + end + end + it 'is_ipv6_addresss ipv6 compressed' do + pp = <<-EOS + $a = "fe00::1" + $b = true + $o = is_ipv6_address($a) + if $o == $b { + notify { 'output correct': } + } + EOS + + apply_manifest(pp, :catch_failures => true) do |r| + expect(r.stdout).to match(/Notice: output correct/) + end + end + it 'is_ipv6_addresss strings' do + pp = <<-EOS + $a = "aoeu" + $b = false + $o = is_ipv6_address($a) + if $o == $b { + notify { 'output correct': } + } + EOS + + apply_manifest(pp, :catch_failures => true) do |r| + expect(r.stdout).to match(/Notice: output correct/) + end + end + it 'is_ipv6_addresss ip out of range' do + pp = <<-EOS + $a = 'fe80:0000:cd12:d123:e2f8:47ff:fe09:gggg' + $b = false + $o = is_ipv6_address($a) + if $o == $b { + notify { 'output correct': } + } + EOS + + apply_manifest(pp, :catch_failures => true) do |r| + expect(r.stdout).to match(/Notice: output correct/) + end + end + end + describe 'failure' do + it 'handles improper argument counts' + end +end -- cgit v1.2.3 From 7ff944daa0b124dc7f423e7eda351119780eda18 Mon Sep 17 00:00:00 2001 From: David Schmitt Date: Mon, 25 Jan 2016 14:19:19 +0000 Subject: (FM-4049) Update to current msync configs [2c99161] --- .gitignore | 20 +++++++++----------- .rspec | 4 +--- .travis.yml | 12 +++++------- CONTRIBUTING.md | 6 +++--- 4 files changed, 18 insertions(+), 24 deletions(-) diff --git a/.gitignore b/.gitignore index 37c4f59..3190277 100644 --- a/.gitignore +++ b/.gitignore @@ -1,12 +1,10 @@ -/pkg/ -/Gemfile.lock -/vendor/ -/spec/fixtures/manifests/* -/spec/fixtures/modules/* -!/spec/fixtures/modules/stdlib -!/spec/fixtures/modules/stdlib/* -/.vagrant/ -/.bundle/ -/coverage/ -/.idea/ +pkg/ +Gemfile.lock +vendor/ +spec/fixtures/ +.vagrant/ +.bundle/ +coverage/ +log/ +.idea/ *.iml diff --git a/.rspec b/.rspec index 7ab5f55..16f9cdb 100644 --- a/.rspec +++ b/.rspec @@ -1,4 +1,2 @@ --color ---format -progress ---backtrace +--format documentation diff --git a/.travis.yml b/.travis.yml index 6fad7a4..160b371 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,15 +7,13 @@ script: "bundle exec rake validate && bundle exec rake lint && bundle exec rake matrix: fast_finish: true include: - - rvm: 1.8.7 + - rvm: 2.1.6 + env: PUPPET_GEM_VERSION="~> 4.0" STRICT_VARIABLES="yes" + - rvm: 2.1.5 + env: PUPPET_GEM_VERSION="~> 3.0" FUTURE_PARSER="yes" + - rvm: 2.1.5 env: PUPPET_GEM_VERSION="~> 3.0" - rvm: 1.9.3 env: PUPPET_GEM_VERSION="~> 3.0" - - rvm: 2.1.5 - env: PUPPET_GEM_VERSION="~> 3.0" - - rvm: 2.1.5 - env: PUPPET_GEM_VERSION="~> 3.0" FUTURE_PARSER="yes" - - rvm: 2.1.6 - env: PUPPET_GEM_VERSION="~> 4.0" STRICT_VARIABLES="yes" notifications: email: false diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index f1cbde4..bfeaa70 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -159,7 +159,7 @@ If you already have those gems installed, make sure they are up-to-date: With all dependencies in place and up-to-date we can now run the tests: ```shell -% rake spec +% bundle exec rake spec ``` This will execute all the [rspec tests](http://rspec-puppet.com/) tests @@ -178,8 +178,8 @@ installed on your system. You can run them by issuing the following command ```shell -% rake spec_clean -% rspec spec/acceptance +% bundle exec rake spec_clean +% bundle exec rspec spec/acceptance ``` This will now download a pre-fabricated image configured in the [default node-set](./spec/acceptance/nodesets/default.yml), -- cgit v1.2.3 From 3169a43f4c24d01c64c90ab9537da284f587c726 Mon Sep 17 00:00:00 2001 From: Maksym Melnychok Date: Mon, 8 Feb 2016 07:50:35 -0800 Subject: Add dig() function Deprecates #try_get_value() --- README.markdown | 38 ++++++++++++++++++++ lib/puppet/parser/functions/dig.rb | 54 ++++++++++++++++++++++++++++ lib/puppet/parser/functions/try_get_value.rb | 44 ++++++----------------- spec/functions/dig_spec.rb | 13 +++++++ 4 files changed, 115 insertions(+), 34 deletions(-) create mode 100644 lib/puppet/parser/functions/dig.rb create mode 100644 spec/functions/dig_spec.rb diff --git a/README.markdown b/README.markdown index 559a6a0..c2d8388 100644 --- a/README.markdown +++ b/README.markdown @@ -254,6 +254,42 @@ Deletes all instances of the undef value from an array or hash. For example, `$h Returns the difference between two arrays. The returned array is a copy of the original array, removing any items that also appear in the second array. For example, `difference(["a","b","c"],["b","c","d"])` returns ["a"]. *Type*: rvalue. +#### `dig` + +*Type*: rvalue. + +Retrieves a value within multiple layers of hashes and arrays via an array of keys containing a path. The function goes through the structure by each path component and tries to return the value at the end of the path. + +In addition to the required path argument, the function accepts the default argument. It is returned if the path is not correct, if no value was found, or if any other error has occurred. + +~~~ruby +$data = { + 'a' => { + 'b' => [ + 'b1', + 'b2', + 'b3', + ] + } +} + +$value = dig($data, ['a', 'b', 2]) +# $value = 'b3' + +# with all possible options +$value = dig($data, ['a', 'b', 2], 'not_found') +# $value = 'b3' + +# using the default value +$value = dig($data, ['a', 'b', 'c', 'd'], 'not_found') +# $value = 'not_found' +~~~ + +1. **$data** The data structure we are working with. +2. **['a', 'b', 2]** The path array. +3. **'not_found'** The default value. It will be returned if nothing is found. + (optional, defaults to *undef*) + #### `dirname` Returns the `dirname` of a path. For example, `dirname('/path/to/a/file.ext')` returns '/path/to/a'. *Type*: rvalue. @@ -806,6 +842,8 @@ Converts the argument into bytes, for example "4 kB" becomes "4096". Takes a sin *Type*: rvalue. +DEPRECATED: replaced by `dig()`. + Retrieves a value within multiple layers of hashes and arrays via a string containing a path. The path is a string of hash keys or array indexes starting with zero, separated by the path separator character (default "/"). The function goes through the structure by each path component and tries to return the value at the end of the path. In addition to the required path argument, the function accepts the default argument. It is returned if the path is not correct, if no value was found, or if any other error has occurred. The last argument can set the path separator character. diff --git a/lib/puppet/parser/functions/dig.rb b/lib/puppet/parser/functions/dig.rb new file mode 100644 index 0000000..a9aa770 --- /dev/null +++ b/lib/puppet/parser/functions/dig.rb @@ -0,0 +1,54 @@ +# +# dig.rb +# + +module Puppet::Parser::Functions + newfunction(:dig, :type => :rvalue, :doc => <<-EOS +Looks up into a complex structure of arrays and hashes and returns nil +or the default value if nothing was found. + +Path is an array of keys to be looked up in data argument. The function +will go down the structure and try to extract the required value. + +$data = { + 'a' => { + 'b' => [ + 'b1', + 'b2', + 'b3' ]}} + +$value = dig($data, ['a', 'b', '2'], 'not_found') +=> $value = 'b3' + +a -> first hash key +b -> second hash key +2 -> array index starting with 0 + +not_found -> (optional) will be returned if there is no value or the path +did not match. Defaults to nil. + +In addition to the required "path" argument, "dig" accepts default +argument. It will be returned if no value was found or a path component is +missing. And the fourth argument can set a variable path separator. + EOS + ) do |arguments| + # Two arguments are required + raise(Puppet::ParseError, "dig(): Wrong number of arguments " + + "given (#{arguments.size} for at least 2)") if arguments.size < 2 + + data, path, default = *arguments + + if !(data.is_a?(Hash) || data.is_a?(Array)) + raise(Puppet::ParseError, "dig(): first argument must be a hash or an array, " << + "given #{data.class.name}") + end + + unless path.is_a? Array + raise(Puppet::ParseError, "dig(): second argument must be an array, " << + "given #{path.class.name}") + end + + value = path.reduce(data) { |h, k| (h.is_a?(Hash) || h.is_a?(Array)) ? h[k] : break } + value.nil? ? default : value + end +end diff --git a/lib/puppet/parser/functions/try_get_value.rb b/lib/puppet/parser/functions/try_get_value.rb index 0c19fd9..fc19a23 100644 --- a/lib/puppet/parser/functions/try_get_value.rb +++ b/lib/puppet/parser/functions/try_get_value.rb @@ -4,6 +4,8 @@ module Puppet::Parser::Functions :type => :rvalue, :arity => -2, :doc => <<-eos +DEPRECATED: this function is deprecated, please use dig() instead. + Looks up into a complex structure of arrays and hashes and returns a value or the default value if nothing was found. @@ -35,43 +37,17 @@ argument. It will be returned if no value was found or a path component is missing. And the fourth argument can set a variable path separator. eos ) do |args| - path_lookup = lambda do |data, path, default| - debug "Try_get_value: #{path.inspect} from: #{data.inspect}" - if data.nil? - debug "Try_get_value: no data, return default: #{default.inspect}" - break default - end - unless path.is_a? Array - debug "Try_get_value: wrong path, return default: #{default.inspect}" - break default - end - unless path.any? - debug "Try_get_value: value found, return data: #{data.inspect}" - break data - end - unless data.is_a? Hash or data.is_a? Array - debug "Try_get_value: incorrect data, return default: #{default.inspect}" - break default - end - - key = path.shift - if data.is_a? Array - begin - key = Integer key - rescue ArgumentError - debug "Try_get_value: non-numeric path for an array, return default: #{default.inspect}" - break default - end - end - path_lookup.call data[key], path, default - end - + warning("try_get_value() DEPRECATED: this function is deprecated, please use dig() instead.") data = args[0] path = args[1] || '' default = args[2] - separator = args[3] || '/' - path = path.split separator - path_lookup.call data, path, default + if !(data.is_a?(Hash) || data.is_a?(Array)) || path == '' + return default || data + end + + separator = args[3] || '/' + path = path.split(separator).map{ |key| key =~ /^\d+$/ ? key.to_i : key } + function_dig([data, path, default]) end end diff --git a/spec/functions/dig_spec.rb b/spec/functions/dig_spec.rb new file mode 100644 index 0000000..1c5d49d --- /dev/null +++ b/spec/functions/dig_spec.rb @@ -0,0 +1,13 @@ +require 'spec_helper' + +describe 'dig' do + it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError) } + it { is_expected.to run.with_params('bad', []).and_raise_error(Puppet::ParseError) } + it { is_expected.to run.with_params({}, 'bad').and_raise_error(Puppet::ParseError) } + + it { is_expected.to run.with_params({}, []).and_return({}) } + it { is_expected.to run.with_params({"a" => "b"}, ["a"]).and_return("b") } + it { is_expected.to run.with_params({"a" => {"b" => "c"}}, ["a", "b"]).and_return("c") } + it { is_expected.to run.with_params({}, ["a", "b"], "d").and_return("d") } + it { is_expected.to run.with_params({"a" => false}, ["a"]).and_return(false) } +end -- cgit v1.2.3 From 8f037d23b22cbe9f7a5e799f705a5b89bdb10a2a Mon Sep 17 00:00:00 2001 From: David Schmitt Date: Tue, 16 Feb 2016 16:01:13 +0000 Subject: (FM-4046) Update to current msync configs [006831f] This moves all copyright statements to the NOTICE file in accordance with the ASFs guidelines on applying the Apache-2.0 license. --- .gitattributes | 5 ++ .gitignore | 1 + .travis.yml | 1 + LICENSE | 209 +++++++++++++++++++++++++++++++++++++++++++++++++++++---- NOTICE | 23 +++++++ 5 files changed, 226 insertions(+), 13 deletions(-) create mode 100644 .gitattributes create mode 100644 NOTICE diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..900ea0c --- /dev/null +++ b/.gitattributes @@ -0,0 +1,5 @@ +#This file is generated by ModuleSync, do not edit. +*.rb eol=lf +*.erb eol=lf +*.pp eol=lf +*.sh eol=lf diff --git a/.gitignore b/.gitignore index 3190277..dd126f2 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +#This file is generated by ModuleSync, do not edit. pkg/ Gemfile.lock vendor/ diff --git a/.travis.yml b/.travis.yml index 160b371..1f22c6c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,3 +1,4 @@ +#This file is generated by ModuleSync, do not edit. --- sudo: false language: ruby diff --git a/LICENSE b/LICENSE index ec0587c..d645695 100644 --- a/LICENSE +++ b/LICENSE @@ -1,19 +1,202 @@ -Copyright (C) 2011 Puppet Labs Inc -and some parts: + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ -Copyright (C) 2011 Krzysztof Wilczynski + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION -Puppet Labs can be contacted at: info@puppetlabs.com + 1. Definitions. -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. - http://www.apache.org/licenses/LICENSE-2.0 + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/NOTICE b/NOTICE new file mode 100644 index 0000000..3c8c03a --- /dev/null +++ b/NOTICE @@ -0,0 +1,23 @@ +stdlib puppet module + +Copyright (C) 2011-2016 Puppet Labs, Inc. + +and some parts: + +Copyright (C) 2011 Krzysztof Wilczynski + + +Puppet Labs can be contacted at: info@puppetlabs.com + + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. -- cgit v1.2.3 From dc64e721ee0e5e49dd3b446aa3c90dab19654c21 Mon Sep 17 00:00:00 2001 From: guessi Date: Wed, 17 Feb 2016 17:00:41 +0800 Subject: Extend Base64() function support --- README.markdown | 31 +++++++++++++++++++++++++- lib/puppet/parser/functions/base64.rb | 41 ++++++++++++++++++++++++++++++----- spec/functions/base64_spec.rb | 25 +++++++++++++++++++-- 3 files changed, 89 insertions(+), 8 deletions(-) diff --git a/README.markdown b/README.markdown index c2d8388..602eaf7 100644 --- a/README.markdown +++ b/README.markdown @@ -146,7 +146,36 @@ Converts any object to an array containing that object. Empty argument lists are #### `base64` -Converts a string to and from base64 encoding. Requires an action ('encode', 'decode') and either a plain or base64-encoded string. *Type*: rvalue. +Converts a string to and from base64 encoding. +Requires an `action` ('encode', 'decode') and either a plain or base64-encoded `string`, +and an optional `method` ('default', 'strict', 'urlsafe') + +for backward compatibility, `metohd` will be set as `default` if not specified. + +*Examples:* +~~~ +base64('encode', 'hello') +base64('encode', 'hello', 'default') +# return: "aGVsbG8=\n" + +base64('encode', 'hello', 'strict') +# return: "aGVsbG8=" + +base64('decode', 'aGVsbG8=') +base64('decode', 'aGVsbG8=\n') +base64('decode', 'aGVsbG8=', 'default') +base64('decode', 'aGVsbG8=\n', 'default') +base64('decode', 'aGVsbG8=', 'strict') +# return: "hello" + +base64('encode', 'https://puppetlabs.com', 'urlsafe') +# return: "aHR0cHM6Ly9wdXBwZXRsYWJzLmNvbQ==" + +base64('decode', 'aHR0cHM6Ly9wdXBwZXRsYWJzLmNvbQ==', 'urlsafe') +# return: "https://puppetlabs.com" +~~~ + +*Type*: rvalue. #### `basename` diff --git a/lib/puppet/parser/functions/base64.rb b/lib/puppet/parser/functions/base64.rb index 617ba31..a8998f2 100644 --- a/lib/puppet/parser/functions/base64.rb +++ b/lib/puppet/parser/functions/base64.rb @@ -6,14 +6,19 @@ module Puppet::Parser::Functions Usage: - $encodestring = base64('encode','thestring') - $decodestring = base64('decode','dGhlc3RyaW5n') + $encodestring = base64('encode', 'thestring') + $decodestring = base64('decode', 'dGhlc3RyaW5n') + + # explicitly define encode/decode method: default, strict, urlsafe + $method = 'default' + $encodestring = base64('encode', 'thestring', $method) + $decodestring = base64('decode', 'dGhlc3RyaW5n', $method) ENDHEREDOC require 'base64' - raise Puppet::ParseError, ("base64(): Wrong number of arguments (#{args.length}; must be = 2)") unless args.length == 2 + raise Puppet::ParseError, ("base64(): Wrong number of arguments (#{args.length}; must be >= 2)") unless args.length >= 2 actions = ['encode','decode'] @@ -25,11 +30,37 @@ module Puppet::Parser::Functions raise Puppet::ParseError, ("base64(): the second argument must be a string to base64") end + method = ['default','strict','urlsafe'] + + if args.length <= 2 + chosenMethod = 'default' + else + chosenMethod = args[2] + end + + unless method.include?(chosenMethod) + raise Puppet::ParseError, ("base64(): the third argument must be one of 'default', 'strict', or 'urlsafe'") + end + case args[0] when 'encode' - result = Base64.encode64(args[1]) + case chosenMethod + when 'default' + result = Base64.encode64(args[1]) + when 'strict' + result = Base64.strict_encode64(args[1]) + when 'urlsafe' + result = Base64.urlsafe_encode64(args[1]) + end when 'decode' - result = Base64.decode64(args[1]) + case chosenMethod + when 'default' + result = Base64.decode64(args[1]) + when 'strict' + result = Base64.strict_decode64(args[1]) + when 'urlsafe' + result = Base64.urlsafe_decode64(args[1]) + end end return result diff --git a/spec/functions/base64_spec.rb b/spec/functions/base64_spec.rb index c529e9e..842a37a 100755 --- a/spec/functions/base64_spec.rb +++ b/spec/functions/base64_spec.rb @@ -4,13 +4,34 @@ describe 'base64' do it { is_expected.not_to eq(nil) } it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError) } it { is_expected.to run.with_params("one").and_raise_error(Puppet::ParseError) } - it { is_expected.to run.with_params("one", "two", "three").and_raise_error(Puppet::ParseError) } it { is_expected.to run.with_params("one", "two").and_raise_error(Puppet::ParseError, /first argument must be one of/) } it { is_expected.to run.with_params("encode", ["two"]).and_raise_error(Puppet::ParseError, /second argument must be a string/) } it { is_expected.to run.with_params("encode", 2).and_raise_error(Puppet::ParseError, /second argument must be a string/) } + it { is_expected.to run.with_params("encode", "thestring", "three").and_raise_error(Puppet::ParseError, /third argument must be one of/) } + it { is_expected.to run.with_params("decode", "dGhlc3RyaW5n\n", "strict").and_raise_error(ArgumentError) } it { is_expected.to run.with_params("encode", "thestring").and_return("dGhlc3RyaW5n\n") } - it { is_expected.to run.with_params("encode", "a very long string that will cause the base64 encoder to produce output with multiple lines").and_return("YSB2ZXJ5IGxvbmcgc3RyaW5nIHRoYXQgd2lsbCBjYXVzZSB0aGUgYmFzZTY0\nIGVuY29kZXIgdG8gcHJvZHVjZSBvdXRwdXQgd2l0aCBtdWx0aXBsZSBsaW5l\ncw==\n") } it { is_expected.to run.with_params("decode", "dGhlc3RyaW5n").and_return("thestring") } it { is_expected.to run.with_params("decode", "dGhlc3RyaW5n\n").and_return("thestring") } + + it { is_expected.to run.with_params("encode", "thestring", "default").and_return("dGhlc3RyaW5n\n") } + it { is_expected.to run.with_params("decode", "dGhlc3RyaW5n", "default").and_return("thestring") } + it { is_expected.to run.with_params("decode", "dGhlc3RyaW5n\n", "default").and_return("thestring") } + + it { is_expected.to run.with_params("encode", "thestring", "strict").and_return("dGhlc3RyaW5n") } + it { is_expected.to run.with_params("decode", "dGhlc3RyaW5n", "strict").and_return("thestring") } + + it { is_expected.to run.with_params("encode", "a very long string that will cause the base64 encoder to produce output with multiple lines").and_return("YSB2ZXJ5IGxvbmcgc3RyaW5nIHRoYXQgd2lsbCBjYXVzZSB0aGUgYmFzZTY0\nIGVuY29kZXIgdG8gcHJvZHVjZSBvdXRwdXQgd2l0aCBtdWx0aXBsZSBsaW5l\ncw==\n") } + it { is_expected.to run.with_params("decode", "YSB2ZXJ5IGxvbmcgc3RyaW5nIHRoYXQgd2lsbCBjYXVzZSB0aGUgYmFzZTY0\nIGVuY29kZXIgdG8gcHJvZHVjZSBvdXRwdXQgd2l0aCBtdWx0aXBsZSBsaW5l\ncw==\n").and_return("a very long string that will cause the base64 encoder to produce output with multiple lines") } + it { is_expected.to run.with_params("decode", "YSB2ZXJ5IGxvbmcgc3RyaW5nIHRoYXQgd2lsbCBjYXVzZSB0aGUgYmFzZTY0IGVuY29kZXIgdG8gcHJvZHVjZSBvdXRwdXQgd2l0aCBtdWx0aXBsZSBsaW5lcw==").and_return("a very long string that will cause the base64 encoder to produce output with multiple lines") } + + it { is_expected.to run.with_params("encode", "a very long string that will cause the base64 encoder to produce output with multiple lines", "strict").and_return("YSB2ZXJ5IGxvbmcgc3RyaW5nIHRoYXQgd2lsbCBjYXVzZSB0aGUgYmFzZTY0IGVuY29kZXIgdG8gcHJvZHVjZSBvdXRwdXQgd2l0aCBtdWx0aXBsZSBsaW5lcw==") } + it { is_expected.to run.with_params("decode", "YSB2ZXJ5IGxvbmcgc3RyaW5nIHRoYXQgd2lsbCBjYXVzZSB0aGUgYmFzZTY0IGVuY29kZXIgdG8gcHJvZHVjZSBvdXRwdXQgd2l0aCBtdWx0aXBsZSBsaW5lcw==").and_return("a very long string that will cause the base64 encoder to produce output with multiple lines") } + it { is_expected.to run.with_params("decode", "YSB2ZXJ5IGxvbmcgc3RyaW5nIHRoYXQgd2lsbCBjYXVzZSB0aGUgYmFzZTY0IGVuY29kZXIgdG8gcHJvZHVjZSBvdXRwdXQgd2l0aCBtdWx0aXBsZSBsaW5lcw==", "strict").and_return("a very long string that will cause the base64 encoder to produce output with multiple lines") } + + it { is_expected.to run.with_params("encode", "https://www.google.com.tw/?gws_rd=ssl#q=hello+world", "urlsafe").and_return("aHR0cHM6Ly93d3cuZ29vZ2xlLmNvbS50dy8_Z3dzX3JkPXNzbCNxPWhlbGxvK3dvcmxk") } + it { is_expected.to run.with_params("decode", "aHR0cHM6Ly93d3cuZ29vZ2xlLmNvbS50dy8_Z3dzX3JkPXNzbCNxPWhlbGxvK3dvcmxk", "urlsafe").and_return("https://www.google.com.tw/?gws_rd=ssl#q=hello+world") } + + it { is_expected.to run.with_params("encode", "https://github.com/puppetlabs/puppetlabs-stdlib/pulls?utf8=%E2%9C%93&q=is%3Apr+is%3Aopen+Add", "urlsafe").and_return("aHR0cHM6Ly9naXRodWIuY29tL3B1cHBldGxhYnMvcHVwcGV0bGFicy1zdGRsaWIvcHVsbHM_dXRmOD0lRTIlOUMlOTMmcT1pcyUzQXByK2lzJTNBb3BlbitBZGQ=") } + it { is_expected.to run.with_params("decode", "aHR0cHM6Ly9naXRodWIuY29tL3B1cHBldGxhYnMvcHVwcGV0bGFicy1zdGRsaWIvcHVsbHM_dXRmOD0lRTIlOUMlOTMmcT1pcyUzQXByK2lzJTNBb3BlbitBZGQ=", "urlsafe").and_return("https://github.com/puppetlabs/puppetlabs-stdlib/pulls?utf8=%E2%9C%93&q=is%3Apr+is%3Aopen+Add") } end -- cgit v1.2.3 From 0378336f9cefea65675d03f1d7107c75cb950fb6 Mon Sep 17 00:00:00 2001 From: Emilien Macchi Date: Sun, 13 Mar 2016 18:20:49 -0400 Subject: Add enclose_ipv6 function Copy a function from puppetlabs/apache, created by Benedikt Bock by 55cc3b4e8f4bc859a1255cb57be2c7923005d822 . This function enclose IPv6 addresses in square brackets. It takes an array of ip addresses and encloses the ipv6 addresses with square brackets. Co-Authored-By: Benedikt Bock --- README.markdown | 5 ++ lib/puppet/parser/functions/enclose_ipv6.rb | 45 ++++++++++++++ .../puppet/parser/functions/enclose_ipv6_spec.rb | 69 ++++++++++++++++++++++ 3 files changed, 119 insertions(+) create mode 100644 lib/puppet/parser/functions/enclose_ipv6.rb create mode 100644 spec/unit/puppet/parser/functions/enclose_ipv6_spec.rb diff --git a/README.markdown b/README.markdown index 994c22e..c9bbdad 100644 --- a/README.markdown +++ b/README.markdown @@ -344,6 +344,11 @@ Converts the case of a string or of all strings in an array to lowercase. *Type* Returns true if the argument is an array or hash that contains no elements, or an empty string. Returns false when the argument is a numerical value. *Type*: rvalue. +#### `enclose_ipv6` + +Takes an array of ip addresses and encloses the ipv6 addresses with square +brackets. *Type*: rvalue. + #### `ensure_packages` Takes a list of packages and only installs them if they don't already exist. It optionally takes a hash as a second parameter to be passed as the third argument to the `ensure_resource()` function. *Type*: statement. diff --git a/lib/puppet/parser/functions/enclose_ipv6.rb b/lib/puppet/parser/functions/enclose_ipv6.rb new file mode 100644 index 0000000..80ffc3a --- /dev/null +++ b/lib/puppet/parser/functions/enclose_ipv6.rb @@ -0,0 +1,45 @@ +# +# enclose_ipv6.rb +# + +module Puppet::Parser::Functions + newfunction(:enclose_ipv6, :type => :rvalue, :doc => <<-EOS +Takes an array of ip addresses and encloses the ipv6 addresses with square brackets. + EOS + ) do |arguments| + + require 'ipaddr' + + rescuable_exceptions = [ ArgumentError ] + if defined?(IPAddr::InvalidAddressError) + rescuable_exceptions << IPAddr::InvalidAddressError + end + + if (arguments.size != 1) then + raise(Puppet::ParseError, "enclose_ipv6(): Wrong number of arguments "+ + "given #{arguments.size} for 1") + end + unless arguments[0].is_a?(String) or arguments[0].is_a?(Array) then + raise(Puppet::ParseError, "enclose_ipv6(): Wrong argument type "+ + "given #{arguments[0].class} expected String or Array") + end + + input = [arguments[0]].flatten.compact + result = [] + + input.each do |val| + unless val == '*' + begin + ip = IPAddr.new(val) + rescue *rescuable_exceptions + raise(Puppet::ParseError, "enclose_ipv6(): Wrong argument "+ + "given #{val} is not an ip address.") + end + val = "[#{ip.to_s}]" if ip.ipv6? + end + result << val + end + + return result.uniq + end +end diff --git a/spec/unit/puppet/parser/functions/enclose_ipv6_spec.rb b/spec/unit/puppet/parser/functions/enclose_ipv6_spec.rb new file mode 100644 index 0000000..b162127 --- /dev/null +++ b/spec/unit/puppet/parser/functions/enclose_ipv6_spec.rb @@ -0,0 +1,69 @@ +#! /usr/bin/env ruby -S rspec +require 'spec_helper' + +describe "the enclose_ipv6 function" do + let(:scope) { PuppetlabsSpec::PuppetInternals.scope } + + it "should exist" do + expect(Puppet::Parser::Functions.function("enclose_ipv6")).to eq("function_enclose_ipv6") + end + + it "should raise a ParseError if there is less than 1 arguments" do + expect { scope.function_enclose_ipv6([]) }.to( raise_error(Puppet::ParseError) ) + end + + it "should raise a ParseError if there is more than 1 arguments" do + expect { scope.function_enclose_ipv6(['argument1','argument2']) }.to( raise_error(Puppet::ParseError) ) + end + + it "should raise a ParseError when given garbage" do + expect { scope.function_enclose_ipv6(['garbage']) }.to( raise_error(Puppet::ParseError) ) + end + + it "should raise a ParseError when given something else than a string or an array" do + expect { scope.function_enclose_ipv6([['1' => '127.0.0.1']]) }.to( raise_error(Puppet::ParseError) ) + end + + it "should not raise a ParseError when given a single ip string" do + expect { scope.function_enclose_ipv6(['127.0.0.1']) }.to_not raise_error + end + + it "should not raise a ParseError when given * as ip string" do + expect { scope.function_enclose_ipv6(['*']) }.to_not raise_error + end + + it "should not raise a ParseError when given an array of ip strings" do + expect { scope.function_enclose_ipv6([['127.0.0.1','fe80::1']]) }.to_not raise_error + end + + it "should not raise a ParseError when given differently notations of ip addresses" do + expect { scope.function_enclose_ipv6([['127.0.0.1','fe80::1','[fe80::1]']]) }.to_not raise_error + end + + it "should raise a ParseError when given a wrong ipv4 address" do + expect { scope.function_enclose_ipv6(['127..0.0.1']) }.to( raise_error(Puppet::ParseError) ) + end + + it "should raise a ParseError when given a ipv4 address with square brackets" do + expect { scope.function_enclose_ipv6(['[127.0.0.1]']) }.to( raise_error(Puppet::ParseError) ) + end + + it "should raise a ParseError when given a wrong ipv6 address" do + expect { scope.function_enclose_ipv6(['fe80:::1']) }.to( raise_error(Puppet::ParseError) ) + end + + it "should embrace ipv6 adresses within an array of ip addresses" do + result = scope.function_enclose_ipv6([['127.0.0.1','fe80::1','[fe80::2]']]) + expect(result).to(eq(['127.0.0.1','[fe80::1]','[fe80::2]'])) + end + + it "should embrace a single ipv6 adresse" do + result = scope.function_enclose_ipv6(['fe80::1']) + expect(result).to(eq(['[fe80::1]'])) + end + + it "should not embrace a single ipv4 adresse" do + result = scope.function_enclose_ipv6(['127.0.0.1']) + expect(result).to(eq(['127.0.0.1'])) + end +end -- cgit v1.2.3 From 0da9ca7e4a78df49c08873f55caf7c88cdd9bc32 Mon Sep 17 00:00:00 2001 From: Nikhil Yadav Date: Thu, 10 Mar 2016 10:33:35 +0530 Subject: Add ensure_resources() function New function "ensure_resources()" to support passing hash as parameter OR from hiera backend This new function is extension of ensure_resource() which will now support to pass multiple values as hash/array OR from hiera backend variables in title argument with additional parameters needed. It will process multiple values for a resource type from the passed argument & pass each entry (type, title, params) to ensure_resource() in required format for further processing. Now user can have duplicate resource check functionality extended to multiple entries with this new function. Use: For multiple resources using hash: ensure_resources('user', {'dan' => { gid => 'mygroup', uid =>'600' } , 'alex' => { gid => 'mygroup' }}, {'ensure' =>'present'}) From Hiera Backend: userlist: dan: gid: 'mygroup' uid: '600' alex: gid: 'mygroup' Call: ensure_resources('user',hiera_hash('userlist'), {'ensure' => 'present'}) ensure_packages() Modified to also support Hash type argument for packages This modification will call newly added ensure_resources() for processing Hash as second argument. The original functionality remains same for Array type arguments. Use: hiera: packagelist: ksh: ensure: latest mlocate: {} myrpm: provider: rpm source: "/tmp/myrpm-1.0.0.x86_64.rpm" install_options: --prefix: /users/home openssl: provider: rpm source: "/tmp/openssl-1.0.1e-42.el7.x86_64.rpm" Call: ensure_packages($packagelist) --- README.markdown | 42 ++++++++++++++++++- lib/puppet/parser/functions/ensure_packages.rb | 27 +++++++++---- lib/puppet/parser/functions/ensure_resources.rb | 54 +++++++++++++++++++++++++ 3 files changed, 113 insertions(+), 10 deletions(-) create mode 100644 lib/puppet/parser/functions/ensure_resources.rb diff --git a/README.markdown b/README.markdown index 994c22e..b6ead96 100644 --- a/README.markdown +++ b/README.markdown @@ -346,7 +346,15 @@ Returns true if the argument is an array or hash that contains no elements, or a #### `ensure_packages` -Takes a list of packages and only installs them if they don't already exist. It optionally takes a hash as a second parameter to be passed as the third argument to the `ensure_resource()` function. *Type*: statement. +Takes a list of packages array/hash and only installs them if they don't already exist. It optionally takes a hash as a second parameter to be passed as the third argument to the `ensure_resource()` or `ensure_resources()` function. *Type*: statement. + +For Array: + + ensure_packages(['ksh','openssl'], {'ensure' => 'present'}) + +For Hash: + + ensure_packages({'ksh' => { enure => '20120801-1' } , 'mypackage' => { source => '/tmp/myrpm-1.0.0.x86_64.rpm', provider => "rpm" }}, {'ensure' => 'present'}) #### `ensure_resource` @@ -370,7 +378,37 @@ An array of resources can also be passed in, and each will be created with the t *Type*: statement. -#### `flatten` +#### `ensure_resources` + +Takes a resource type, title (only hash), and a hash of attributes that describe the resource(s). + +~~~ +user { 'dan': + gid => 'mygroup', + ensure => present, +} + +ensure_resources($user) +~~~ + +An hash of resources should be passed in and each will be created with the type and parameters specified if it doesn't already exist: + + ensure_resources('user', {'dan' => { gid => 'mygroup', uid => '600' } , 'alex' => { gid => 'mygroup' }}, {'ensure' => 'present'}) + +From Hiera Backend: + +~~~ +userlist: +dan: + gid: 'mygroup' +uid: '600' +alex: +gid: 'mygroup' + +ensure_resources('user', hiera_hash('userlist'), {'ensure' => 'present'}) +~~~ + +### `flatten` Flattens deeply nested arrays and returns a single flat array as a result. For example, `flatten(['a', ['b', ['c']]])` returns ['a','b','c']. *Type*: rvalue. diff --git a/lib/puppet/parser/functions/ensure_packages.rb b/lib/puppet/parser/functions/ensure_packages.rb index f1da4aa..532b702 100644 --- a/lib/puppet/parser/functions/ensure_packages.rb +++ b/lib/puppet/parser/functions/ensure_packages.rb @@ -17,18 +17,29 @@ third argument to the ensure_resource() function. raise(Puppet::ParseError, 'ensure_packages(): Requires second argument to be a Hash') end - packages = Array(arguments[0]) + if arguments[0].is_a?(Hash) + if arguments[1] + defaults = { 'ensure' => 'present' }.merge(arguments[1]) + else + defaults = { 'ensure' => 'present' } + end - if arguments[1] - defaults = { 'ensure' => 'present' }.merge(arguments[1]) + Puppet::Parser::Functions.function(:ensure_resources) + function_ensure_resources(['package', Hash(arguments[0]), defaults ]) else - defaults = { 'ensure' => 'present' } - end + packages = Array(arguments[0]) + + if arguments[1] + defaults = { 'ensure' => 'present' }.merge(arguments[1]) + else + defaults = { 'ensure' => 'present' } + end - Puppet::Parser::Functions.function(:ensure_resource) - packages.each { |package_name| - function_ensure_resource(['package', package_name, defaults ]) + Puppet::Parser::Functions.function(:ensure_resource) + packages.each { |package_name| + function_ensure_resource(['package', package_name, defaults ]) } + end end end diff --git a/lib/puppet/parser/functions/ensure_resources.rb b/lib/puppet/parser/functions/ensure_resources.rb new file mode 100644 index 0000000..30d57a8 --- /dev/null +++ b/lib/puppet/parser/functions/ensure_resources.rb @@ -0,0 +1,54 @@ +require 'puppet/parser/functions' + +Puppet::Parser::Functions.newfunction(:ensure_resources, + :type => :statement, + :doc => <<-'ENDOFDOC' +Takes a resource type, title (only hash), and a list of attributes that describe a +resource. + + user { 'dan': + gid => 'mygroup', + ensure => present, + } + +An hash of resources should be passed in and each will be created with +the type and parameters specified if it doesn't already exist. + + ensure_resources('user', {'dan' => { gid => 'mygroup', uid => '600' } , 'alex' => { gid => 'mygroup' }}, {'ensure' => 'present'}) + +From Hiera Backend: + +userlist: + dan: + gid: 'mygroup' + uid: '600' + alex: + gid: 'mygroup' + +Call: +ensure_resources('user', hiera_hash('userlist'), {'ensure' => 'present'}) + +ENDOFDOC +) do |vals| + type, title, params = vals + raise(ArgumentError, 'Must specify a type') unless type + raise(ArgumentError, 'Must specify a title') unless title + params ||= {} + + if title.is_a?(Hash) + resource_hash = Hash(title) + resources = resource_hash.keys + + Puppet::Parser::Functions.function(:ensure_resource) + resources.each { |resource_name| + if resource_hash[resource_name] + params_merged = params.merge(resource_hash[resource_name]) + else + params_merged = params + end + function_ensure_resource([ type, resource_name, params_merged ]) + } + else + raise(Puppet::ParseError, 'ensure_resources(): Requires second argument to be a Hash') + end +end -- cgit v1.2.3 From 7943b25ec1abcb1c0e86cd42cdfd3b2d3d511ee8 Mon Sep 17 00:00:00 2001 From: Bryan Jen Date: Wed, 16 Mar 2016 13:57:36 -0700 Subject: (maint) Fixes fqdn_rand_string tests Puppet 4.4.0 and later has changed fqdn_rand to use a higher ceiling (PUP-5646), the tests for fqdn_rand_string needed to be updated to reflect the new expected output. --- spec/acceptance/fqdn_rand_string_spec.rb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/spec/acceptance/fqdn_rand_string_spec.rb b/spec/acceptance/fqdn_rand_string_spec.rb index 9c6d701..065a517 100644 --- a/spec/acceptance/fqdn_rand_string_spec.rb +++ b/spec/acceptance/fqdn_rand_string_spec.rb @@ -17,7 +17,7 @@ describe 'fqdn_rand_string function', :unless => UNSUPPORTED_PLATFORMS.include?( eos apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/fqdn_rand_string is "7oDp0KOr1b"/) + expect(r.stdout).to match(/fqdn_rand_string is "(7oDp0KOr1b|9Acvnhkt4J)"/) end end it 'generates random alphanumeric strings with custom charsets' do @@ -29,7 +29,7 @@ describe 'fqdn_rand_string function', :unless => UNSUPPORTED_PLATFORMS.include?( eos apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/fqdn_rand_string is "7203048515"/) + expect(r.stdout).to match(/fqdn_rand_string is "(7203048515|2383756694)"/) end end it 'generates random alphanumeric strings with custom seeds' do @@ -41,7 +41,7 @@ describe 'fqdn_rand_string function', :unless => UNSUPPORTED_PLATFORMS.include?( eos apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/fqdn_rand_string is "3HS4mbuI3E"/) + expect(r.stdout).to match(/fqdn_rand_string is "(3HS4mbuI3E|1jJtAMs94d)"/) end end it 'generates random alphanumeric strings with custom charsets and seeds' do @@ -54,7 +54,7 @@ describe 'fqdn_rand_string function', :unless => UNSUPPORTED_PLATFORMS.include?( eos apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/fqdn_rand_string is "3104058232"/) + expect(r.stdout).to match(/fqdn_rand_string is "(3104058232|7100592312)"/) end end end -- cgit v1.2.3 From be6d4d2ffb461a131cdeba6014ca9ac02bddc9d5 Mon Sep 17 00:00:00 2001 From: Sledge Sulaweyo Date: Thu, 17 Mar 2016 07:36:44 +0100 Subject: Add check if Gem is defined On e.g. Ubuntu 12.04 LTS Gem is not there by default so i added a check to not fail in that fact if this is the case. --- lib/facter/package_provider.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/facter/package_provider.rb b/lib/facter/package_provider.rb index 1a0bac9..3a9117f 100644 --- a/lib/facter/package_provider.rb +++ b/lib/facter/package_provider.rb @@ -12,7 +12,7 @@ require 'puppet/type/package' Facter.add(:package_provider) do setcode do - if Gem::Version.new(Facter.value(:puppetversion).split(' ')[0]) >= Gem::Version.new('3.6') + if defined? Gem and Gem::Version.new(Facter.value(:puppetversion).split(' ')[0]) >= Gem::Version.new('3.6') Puppet::Type.type(:package).newpackage(:name => 'dummy', :allow_virtual => 'true')[:provider].to_s else Puppet::Type.type(:package).newpackage(:name => 'dummy')[:provider].to_s -- cgit v1.2.3 From 85ff2a28a83984c827985181d58c55ca8c524ed6 Mon Sep 17 00:00:00 2001 From: Reinhard Vicinus Date: Tue, 22 Mar 2016 15:06:31 +0100 Subject: improve suffix function to support the same feature set as prefix --- README.markdown | 7 ++++++- lib/puppet/parser/functions/suffix.rb | 24 ++++++++++++++++-------- spec/functions/suffix_spec.rb | 8 +------- 3 files changed, 23 insertions(+), 16 deletions(-) diff --git a/README.markdown b/README.markdown index e346f4f..6cedc2a 100644 --- a/README.markdown +++ b/README.markdown @@ -904,7 +904,12 @@ Removes leading and trailing whitespace from a string or from every string insid #### `suffix` -Applies a suffix to all elements in an array. For example, `suffix(['a','b','c'], 'p')` returns ['ap','bp','cp']. *Type*: rvalue. +Applies a suffix to all elements in an array, or to the keys in a hash. +For example: +* `suffix(['a','b','c'], 'p')` returns ['ap','bp','cp'] +* `suffix({'a'=>'b','b'=>'c','c'=>'d'}, 'p')` returns {'ap'=>'b','bp'=>'c','cp'=>'d'}. + +*Type*: rvalue. #### `swapcase` diff --git a/lib/puppet/parser/functions/suffix.rb b/lib/puppet/parser/functions/suffix.rb index f7792d6..2908434 100644 --- a/lib/puppet/parser/functions/suffix.rb +++ b/lib/puppet/parser/functions/suffix.rb @@ -4,7 +4,8 @@ module Puppet::Parser::Functions newfunction(:suffix, :type => :rvalue, :doc => <<-EOS -This function applies a suffix to all elements in an array. +This function applies a suffix to all elements in an array, or to the keys +in a hash. *Examples:* @@ -18,10 +19,10 @@ Will return: ['ap','bp','cp'] raise(Puppet::ParseError, "suffix(): Wrong number of arguments " + "given (#{arguments.size} for 1)") if arguments.size < 1 - array = arguments[0] + enumerable = arguments[0] - unless array.is_a?(Array) - raise Puppet::ParseError, "suffix(): expected first argument to be an Array, got #{array.inspect}" + unless enumerable.is_a?(Array) or enumerable.is_a?(Hash) + raise Puppet::ParseError, "suffix(): expected first argument to be an Array or a Hash, got #{enumerable.inspect}" end suffix = arguments[1] if arguments[1] @@ -32,10 +33,17 @@ Will return: ['ap','bp','cp'] end end - # Turn everything into string same as join would do ... - result = array.collect do |i| - i = i.to_s - suffix ? i + suffix : i + if enumerable.is_a?(Array) + # Turn everything into string same as join would do ... + result = enumerable.collect do |i| + i = i.to_s + suffix ? i + suffix : i + end + else + result = Hash[enumerable.map do |k,v| + k = k.to_s + [ suffix ? k + suffix : k, v ] + end] end return result diff --git a/spec/functions/suffix_spec.rb b/spec/functions/suffix_spec.rb index b48a4eb..efba4ab 100755 --- a/spec/functions/suffix_spec.rb +++ b/spec/functions/suffix_spec.rb @@ -16,29 +16,23 @@ describe 'suffix' do it { is_expected.to run.with_params(['one'], 'post').and_return(['onepost']) } it { is_expected.to run.with_params(['one', 'two', 'three'], 'post').and_return(['onepost', 'twopost', 'threepost']) } it { - pending("implementation of Hash functionality matching prefix") is_expected.to run.with_params({}).and_return({}) } it { - pending("implementation of Hash functionality matching prefix") is_expected.to run.with_params({ 'key1' => 'value1', 2 => 3}).and_return({ 'key1' => 'value1', '2' => 3 }) } it { - pending("implementation of Hash functionality matching prefix") is_expected.to run.with_params({}, '').and_return({}) } it { - pending("implementation of Hash functionality matching prefix") is_expected.to run.with_params({ 'key' => 'value' }, '').and_return({ 'key' => 'value' }) } it { - pending("implementation of Hash functionality matching prefix") is_expected.to run.with_params({ 'key' => 'value' }, 'post').and_return({ 'keypost' => 'value' }) } it { - pending("implementation of Hash functionality matching prefix") is_expected.to run \ - .with_params({ 'key1' => 'value1', 'key2' => 'value2', 'key3' => 'value3' }, 'pre') \ + .with_params({ 'key1' => 'value1', 'key2' => 'value2', 'key3' => 'value3' }, 'post') \ .and_return({ 'key1post' => 'value1', 'key2post' => 'value2', 'key3post' => 'value3' }) } end -- cgit v1.2.3 From eca43f41cd6718023871ba21ae93fe0f7657528f Mon Sep 17 00:00:00 2001 From: Derek McEachern Date: Thu, 24 Mar 2016 14:23:05 -0500 Subject: Fixed typo 'absense' to 'absence' --- spec/unit/puppet/provider/file_line/ruby_spec.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/unit/puppet/provider/file_line/ruby_spec.rb b/spec/unit/puppet/provider/file_line/ruby_spec.rb index 23e649c..fdeaf1a 100755 --- a/spec/unit/puppet/provider/file_line/ruby_spec.rb +++ b/spec/unit/puppet/provider/file_line/ruby_spec.rb @@ -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', -- cgit v1.2.3 From 7e408ca7970fd172822db02227935798f9ff282f Mon Sep 17 00:00:00 2001 From: Johnson Earls Date: Mon, 28 Mar 2016 20:59:27 +0000 Subject: [MODULES-2370] file_line.rb: Fix `line` attribute validation `file_line` type: During validation, do not require `line` attribute if: * `ensure` is `absent`, * `match` is not empty, * and `match_for_absence` is `true`. Also update `spec` tests to reflect this. --- lib/puppet/type/file_line.rb | 9 +++++++-- spec/unit/puppet/type/file_line_spec.rb | 7 +++++-- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/lib/puppet/type/file_line.rb b/lib/puppet/type/file_line.rb index 77d3be2..f2c6937 100644 --- a/lib/puppet/type/file_line.rb +++ b/lib/puppet/type/file_line.rb @@ -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 diff --git a/spec/unit/puppet/type/file_line_spec.rb b/spec/unit/puppet/type/file_line_spec.rb index f1430f2..48e2670 100755 --- a/spec/unit/puppet/type/file_line_spec.rb +++ b/spec/unit/puppet/type/file_line_spec.rb @@ -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 -- cgit v1.2.3 From 0cea94a82ef277092897a03446f6e6fccba90d53 Mon Sep 17 00:00:00 2001 From: Felix Frank Date: Tue, 29 Mar 2016 01:59:54 +0200 Subject: catch StandardError rather than the gratuitous Exception --- lib/facter/facter_dot_d.rb | 8 ++++---- lib/puppet/parser/functions/hash.rb | 2 +- lib/puppet/parser/functions/parsejson.rb | 2 +- lib/puppet/parser/functions/parseyaml.rb | 2 +- lib/puppet/parser/functions/validate_cmd.rb | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/lib/facter/facter_dot_d.rb b/lib/facter/facter_dot_d.rb index d85940d..5c5fb1f 100644 --- a/lib/facter/facter_dot_d.rb +++ b/lib/facter/facter_dot_d.rb @@ -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 diff --git a/lib/puppet/parser/functions/hash.rb b/lib/puppet/parser/functions/hash.rb index 8cc4823..89d0e07 100644 --- a/lib/puppet/parser/functions/hash.rb +++ b/lib/puppet/parser/functions/hash.rb @@ -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 diff --git a/lib/puppet/parser/functions/parsejson.rb b/lib/puppet/parser/functions/parsejson.rb index b4af40e..f7c2896 100644 --- a/lib/puppet/parser/functions/parsejson.rb +++ b/lib/puppet/parser/functions/parsejson.rb @@ -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 diff --git a/lib/puppet/parser/functions/parseyaml.rb b/lib/puppet/parser/functions/parseyaml.rb index 66d0413..9e84055 100644 --- a/lib/puppet/parser/functions/parseyaml.rb +++ b/lib/puppet/parser/functions/parseyaml.rb @@ -16,7 +16,7 @@ be returned if the parsing of YAML string have failed. begin YAML::load(arguments[0]) || arguments[1] - rescue Exception => e + rescue StandardError => e if arguments[1] arguments[1] else diff --git a/lib/puppet/parser/functions/validate_cmd.rb b/lib/puppet/parser/functions/validate_cmd.rb index 5df3c60..685162b 100644 --- a/lib/puppet/parser/functions/validate_cmd.rb +++ b/lib/puppet/parser/functions/validate_cmd.rb @@ -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 -- cgit v1.2.3 From e6a3436fd01eb10c75a08281d6eaa8e385ff5dd5 Mon Sep 17 00:00:00 2001 From: Bryan Jen Date: Mon, 28 Mar 2016 17:42:22 -0700 Subject: (FM-5000) Release prep for 4.12.0. --- CHANGELOG.md | 19 +++++++++++++++++++ metadata.json | 2 +- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2698dde..5d6a108 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,22 @@ +## Supported Release 4.12.0 +###Summary + +This release provides several new functions, bugfixes, and some documentation updates. + +####Features +- Adds `clamp`. This function keeps values within a specified range. +- Adds `validate_x509_rsa_key_pair`. This function validates an x509 RSA certificate and key pair. +- Adds `dig`. This function performs a deep lookup in nested hashes or arrays. +- Extends the `base64` support to fit `rfc2045` and `rfc4648`. +- Adds `is_ipv6_address` and `is_ipv4_address`. These functions validate the specified ipv4 or ipv6 addresses. +- Adds `enclose_ipv6`. This function encloses IPv6 addresses in square brackets. +- Adds `ensure_resources`. This function takes a list of resources and creates them if they don't exist. +- Extends `suffix` to support applying a suffix to keys in a hash. + +####Bugfixes +- Fixes `fqdn_rand_string` tests, since Puppet 4.4.0 and later have a higher `fqdn_rand` ceiling. +- (MODULES-3152) Adds a check to `package_provider` to prevent failures if Gem is not installed. + ## Supported Release 4.11.0 ###Summary diff --git a/metadata.json b/metadata.json index a7ea0af..514023e 100644 --- a/metadata.json +++ b/metadata.json @@ -1,6 +1,6 @@ { "name": "puppetlabs-stdlib", - "version": "4.11.0", + "version": "4.12.0", "author": "puppetlabs", "summary": "Standard library of resources for Puppet modules.", "license": "Apache-2.0", -- cgit v1.2.3 From 27458aff988aac083007a677793081568356d85d Mon Sep 17 00:00:00 2001 From: David Schmitt Date: Tue, 5 Apr 2016 14:32:06 +0100 Subject: (maint) Update to current modulesync_configs [953280c] This removes much of the assorted cruft that accumulated in the unmanaged files and moves the remaining necessary parts to spec_helper_local. --- .sync.yml | 9 ----- .travis.yml | 2 +- Gemfile | 72 +++++++++++++----------------------- Rakefile | 41 ++++++++++++++++++-- spec/puppetlabs_spec_helper_clone.rb | 34 ----------------- spec/spec.opts | 6 --- spec/spec_helper.rb | 51 +++---------------------- spec/spec_helper_local.rb | 29 +++++++++++++++ 8 files changed, 98 insertions(+), 146 deletions(-) delete mode 100644 .sync.yml delete mode 100644 spec/puppetlabs_spec_helper_clone.rb delete mode 100644 spec/spec.opts create mode 100644 spec/spec_helper_local.rb diff --git a/.sync.yml b/.sync.yml deleted file mode 100644 index 21e872e..0000000 --- a/.sync.yml +++ /dev/null @@ -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 diff --git a/.travis.yml b/.travis.yml index 1f22c6c..588fb5b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -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: diff --git a/Gemfile b/Gemfile index 8221514..e490bc9 100644 --- a/Gemfile +++ b/Gemfile @@ -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 diff --git a/Rakefile b/Rakefile index e136b8e..7e9a13d 100644 --- a/Rakefile +++ b/Rakefile @@ -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 diff --git a/spec/puppetlabs_spec_helper_clone.rb b/spec/puppetlabs_spec_helper_clone.rb deleted file mode 100644 index 6a94a3b..0000000 --- a/spec/puppetlabs_spec_helper_clone.rb +++ /dev/null @@ -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 /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 - diff --git a/spec/spec.opts b/spec/spec.opts deleted file mode 100644 index 91cd642..0000000 --- a/spec/spec.opts +++ /dev/null @@ -1,6 +0,0 @@ ---format -s ---colour ---loadby -mtime ---backtrace diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 416036b..22d5d68 100755 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -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 diff --git a/spec/spec_helper_local.rb b/spec/spec_helper_local.rb new file mode 100644 index 0000000..023a862 --- /dev/null +++ b/spec/spec_helper_local.rb @@ -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 -- cgit v1.2.3 From 3860512d5611d9c3a93f75d9594c2df43ee64acb Mon Sep 17 00:00:00 2001 From: David Schmitt Date: Tue, 5 Apr 2016 14:42:53 +0100 Subject: (maint) remove failing test This removes the failing test special casing for puppet 4. --- spec/functions/get_module_path_spec.rb | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/spec/functions/get_module_path_spec.rb b/spec/functions/get_module_path_spec.rb index b1f682f..a39e413 100755 --- a/spec/functions/get_module_path_spec.rb +++ b/spec/functions/get_module_path_spec.rb @@ -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 -- cgit v1.2.3 From 5639828bffd1beb0e44e59554e17c1a891924145 Mon Sep 17 00:00:00 2001 From: David Schmitt Date: Thu, 7 Apr 2016 11:47:42 +0100 Subject: (maint) also catch Psych::SyntaxError Psych::SyntaxError is a RuntimeException. This still needs to catch that. This was uncovered by the recent move to catch StandardError rather than the catchall Exception that was here before. --- lib/puppet/parser/functions/parseyaml.rb | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/puppet/parser/functions/parseyaml.rb b/lib/puppet/parser/functions/parseyaml.rb index 9e84055..ba9d98a 100644 --- a/lib/puppet/parser/functions/parseyaml.rb +++ b/lib/puppet/parser/functions/parseyaml.rb @@ -16,7 +16,10 @@ be returned if the parsing of YAML string have failed. begin YAML::load(arguments[0]) || arguments[1] - rescue StandardError => 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 -- cgit v1.2.3 From 44596e73da1b157ea931d5111f842e108ca203bb Mon Sep 17 00:00:00 2001 From: Alex Tomlins Date: Thu, 7 Apr 2016 22:22:17 +0100 Subject: (MODULES-3246) Fix concat with Hash arguments. 85d5ead Updated the concat function so that it wouldn't modify the original array. A side-effect of this change is that it now always calls `Array()` on the second argument. If thit is a Hash, this results in `to_a` being called on the hash, which converts it to an array or tuples. This is undesired. Update the behaviour so that it doesn't (indirectly) call `to_a` on anything, instead test for the type of the argument, wrapping it in an array if it's not already an array. --- lib/puppet/parser/functions/concat.rb | 2 +- spec/acceptance/concat_spec.rb | 14 ++++++++++++++ spec/functions/concat_spec.rb | 1 + 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/lib/puppet/parser/functions/concat.rb b/lib/puppet/parser/functions/concat.rb index 618e62d..91edb4e 100644 --- a/lib/puppet/parser/functions/concat.rb +++ b/lib/puppet/parser/functions/concat.rb @@ -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 diff --git a/spec/acceptance/concat_spec.rb b/spec/acceptance/concat_spec.rb index 06b649f..c472db6 100755 --- a/spec/acceptance/concat_spec.rb +++ b/spec/acceptance/concat_spec.rb @@ -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 diff --git a/spec/functions/concat_spec.rb b/spec/functions/concat_spec.rb index 1694d5e..eb76233 100755 --- a/spec/functions/concat_spec.rb +++ b/spec/functions/concat_spec.rb @@ -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'] -- cgit v1.2.3 From bfe6cf68b3b09f5927ec8f12f6661f45e9c1be58 Mon Sep 17 00:00:00 2001 From: Joseph Yaworski Date: Mon, 28 Mar 2016 13:18:28 -0400 Subject: Add validate_email_address function --- lib/puppet/parser/functions/is_email_address.rb | 21 +++++++++++++++ .../parser/functions/validate_email_address.rb | 31 ++++++++++++++++++++++ spec/functions/is_email_address_spec.rb | 14 ++++++++++ spec/functions/validate_email_address_spec.rb | 23 ++++++++++++++++ 4 files changed, 89 insertions(+) create mode 100644 lib/puppet/parser/functions/is_email_address.rb create mode 100644 lib/puppet/parser/functions/validate_email_address.rb create mode 100755 spec/functions/is_email_address_spec.rb create mode 100644 spec/functions/validate_email_address_spec.rb diff --git a/lib/puppet/parser/functions/is_email_address.rb b/lib/puppet/parser/functions/is_email_address.rb new file mode 100644 index 0000000..ab8d075 --- /dev/null +++ b/lib/puppet/parser/functions/is_email_address.rb @@ -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 : diff --git a/lib/puppet/parser/functions/validate_email_address.rb b/lib/puppet/parser/functions/validate_email_address.rb new file mode 100644 index 0000000..63f59a7 --- /dev/null +++ b/lib/puppet/parser/functions/validate_email_address.rb @@ -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 diff --git a/spec/functions/is_email_address_spec.rb b/spec/functions/is_email_address_spec.rb new file mode 100755 index 0000000..8b7b358 --- /dev/null +++ b/spec/functions/is_email_address_spec.rb @@ -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 diff --git a/spec/functions/validate_email_address_spec.rb b/spec/functions/validate_email_address_spec.rb new file mode 100644 index 0000000..7628383 --- /dev/null +++ b/spec/functions/validate_email_address_spec.rb @@ -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 -- cgit v1.2.3 From 0d46515b57cea60d4d5f1e4d81a75a448a7a73a8 Mon Sep 17 00:00:00 2001 From: Joseph Yaworski Date: Mon, 11 Apr 2016 22:09:24 -0400 Subject: Add support for regular expressions to delete --- README.markdown | 2 +- lib/puppet/parser/functions/delete.rb | 4 +--- spec/functions/delete_spec.rb | 7 ++++++- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/README.markdown b/README.markdown index 6cedc2a..2f5faf3 100644 --- a/README.markdown +++ b/README.markdown @@ -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` diff --git a/lib/puppet/parser/functions/delete.rb b/lib/puppet/parser/functions/delete.rb index f548b44..8435163 100644 --- a/lib/puppet/parser/functions/delete.rb +++ b/lib/puppet/parser/functions/delete.rb @@ -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 diff --git a/spec/functions/delete_spec.rb b/spec/functions/delete_spec.rb index 6c4747b..998f9a6 100755 --- a/spec/functions/delete_spec.rb +++ b/spec/functions/delete_spec.rb @@ -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 -- cgit v1.2.3 From 085035dccebbf27cf2bfd7f1d9101c746f5178a2 Mon Sep 17 00:00:00 2001 From: Bryan Jen Date: Mon, 28 Mar 2016 17:42:22 -0700 Subject: (FM-5000) Release prep for 4.12.0. --- CHANGELOG.md | 19 +++++++++++++++++++ metadata.json | 2 +- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2698dde..5d6a108 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,22 @@ +## Supported Release 4.12.0 +###Summary + +This release provides several new functions, bugfixes, and some documentation updates. + +####Features +- Adds `clamp`. This function keeps values within a specified range. +- Adds `validate_x509_rsa_key_pair`. This function validates an x509 RSA certificate and key pair. +- Adds `dig`. This function performs a deep lookup in nested hashes or arrays. +- Extends the `base64` support to fit `rfc2045` and `rfc4648`. +- Adds `is_ipv6_address` and `is_ipv4_address`. These functions validate the specified ipv4 or ipv6 addresses. +- Adds `enclose_ipv6`. This function encloses IPv6 addresses in square brackets. +- Adds `ensure_resources`. This function takes a list of resources and creates them if they don't exist. +- Extends `suffix` to support applying a suffix to keys in a hash. + +####Bugfixes +- Fixes `fqdn_rand_string` tests, since Puppet 4.4.0 and later have a higher `fqdn_rand` ceiling. +- (MODULES-3152) Adds a check to `package_provider` to prevent failures if Gem is not installed. + ## Supported Release 4.11.0 ###Summary diff --git a/metadata.json b/metadata.json index a7ea0af..514023e 100644 --- a/metadata.json +++ b/metadata.json @@ -1,6 +1,6 @@ { "name": "puppetlabs-stdlib", - "version": "4.11.0", + "version": "4.12.0", "author": "puppetlabs", "summary": "Standard library of resources for Puppet modules.", "license": "Apache-2.0", -- cgit v1.2.3 From cf171a7279417f05204e732e62acfcbaeedc5f96 Mon Sep 17 00:00:00 2001 From: tphoney Date: Fri, 15 Apr 2016 13:32:04 +0100 Subject: 4.12.0 release prep --- CHANGELOG.md | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5d6a108..7aa0a10 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,7 @@ ## Supported Release 4.12.0 ###Summary -This release provides several new functions, bugfixes, and some documentation updates. +This release provides several new functions, bugfixes, modulesync changes, and some documentation updates. ####Features - Adds `clamp`. This function keeps values within a specified range. @@ -10,12 +10,19 @@ This release provides several new functions, bugfixes, and some documentation up - Extends the `base64` support to fit `rfc2045` and `rfc4648`. - Adds `is_ipv6_address` and `is_ipv4_address`. These functions validate the specified ipv4 or ipv6 addresses. - Adds `enclose_ipv6`. This function encloses IPv6 addresses in square brackets. -- Adds `ensure_resources`. This function takes a list of resources and creates them if they don't exist. +- Adds `ensure_resources`. This function takes a list of resources and creates them if they do not exist. - Extends `suffix` to support applying a suffix to keys in a hash. +- Apply modulesync changes. +- Add validate_email_address function. +- Add support for regular expressions to delete. ####Bugfixes - Fixes `fqdn_rand_string` tests, since Puppet 4.4.0 and later have a higher `fqdn_rand` ceiling. - (MODULES-3152) Adds a check to `package_provider` to prevent failures if Gem is not installed. +- Fixes to README.md. +- Fixes catch StandardError rather than the gratuitous Exception +- Fixes file_line attribute validation. +- Fixes concat with Hash arguments. ## Supported Release 4.11.0 ###Summary -- cgit v1.2.3 From 79c871322f92bd03206ab392f9f2972f3ace97ea Mon Sep 17 00:00:00 2001 From: David Schmitt Date: Mon, 18 Apr 2016 09:46:30 +0100 Subject: (MODULES-3271) Ensure that is_email_address works on unsupported rubies --- lib/puppet/parser/functions/is_email_address.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/puppet/parser/functions/is_email_address.rb b/lib/puppet/parser/functions/is_email_address.rb index ab8d075..4fb0229 100644 --- a/lib/puppet/parser/functions/is_email_address.rb +++ b/lib/puppet/parser/functions/is_email_address.rb @@ -3,7 +3,7 @@ # module Puppet::Parser::Functions - newfunction(:is_email_address, type: :rvalue, doc: <<-EOS + 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| -- cgit v1.2.3 From ee6413b95a7b88626d0011cc2464d77ca186d832 Mon Sep 17 00:00:00 2001 From: David Schmitt Date: Wed, 13 Apr 2016 20:50:11 +0100 Subject: Update to newest modulesync_configs [9ca280f] --- .travis.yml | 17 +++++++++++++- spec/acceptance/nodesets/centos-59-x64.yml | 10 --------- spec/acceptance/nodesets/centos-6-vcloud.yml | 15 ------------- spec/acceptance/nodesets/centos-64-x64-pe.yml | 12 ---------- spec/acceptance/nodesets/centos-64-x64.yml | 10 --------- spec/acceptance/nodesets/centos-65-x64.yml | 10 --------- spec/acceptance/nodesets/centos-7-x64.yml | 10 +++++++++ spec/acceptance/nodesets/debian-8-x64.yml | 10 +++++++++ spec/acceptance/nodesets/default.yml | 12 +++++----- spec/acceptance/nodesets/docker/centos-7.yml | 12 ++++++++++ spec/acceptance/nodesets/docker/debian-8.yml | 11 +++++++++ spec/acceptance/nodesets/docker/ubuntu-14.04.yml | 12 ++++++++++ spec/acceptance/nodesets/fedora-18-x64.yml | 10 --------- spec/acceptance/nodesets/sles-11-x64.yml | 10 --------- .../nodesets/ubuntu-server-10044-x64.yml | 10 --------- .../nodesets/ubuntu-server-12042-x64.yml | 10 --------- .../acceptance/nodesets/ubuntu-server-1404-x64.yml | 11 --------- spec/acceptance/nodesets/windows-2003-i386.yml | 26 ---------------------- spec/acceptance/nodesets/windows-2003-x86_64.yml | 26 ---------------------- spec/acceptance/nodesets/windows-2008-x86_64.yml | 26 ---------------------- spec/acceptance/nodesets/windows-2008r2-x86_64.yml | 26 ---------------------- spec/acceptance/nodesets/windows-2012-x86_64.yml | 26 ---------------------- spec/acceptance/nodesets/windows-2012r2-x86_64.yml | 26 ---------------------- spec/spec_helper_acceptance.rb | 2 +- 24 files changed, 78 insertions(+), 272 deletions(-) delete mode 100644 spec/acceptance/nodesets/centos-59-x64.yml delete mode 100644 spec/acceptance/nodesets/centos-6-vcloud.yml delete mode 100644 spec/acceptance/nodesets/centos-64-x64-pe.yml delete mode 100644 spec/acceptance/nodesets/centos-64-x64.yml delete mode 100644 spec/acceptance/nodesets/centos-65-x64.yml create mode 100644 spec/acceptance/nodesets/centos-7-x64.yml create mode 100644 spec/acceptance/nodesets/debian-8-x64.yml create mode 100644 spec/acceptance/nodesets/docker/centos-7.yml create mode 100644 spec/acceptance/nodesets/docker/debian-8.yml create mode 100644 spec/acceptance/nodesets/docker/ubuntu-14.04.yml delete mode 100644 spec/acceptance/nodesets/fedora-18-x64.yml delete mode 100644 spec/acceptance/nodesets/sles-11-x64.yml delete mode 100644 spec/acceptance/nodesets/ubuntu-server-10044-x64.yml delete mode 100644 spec/acceptance/nodesets/ubuntu-server-12042-x64.yml delete mode 100644 spec/acceptance/nodesets/ubuntu-server-1404-x64.yml delete mode 100644 spec/acceptance/nodesets/windows-2003-i386.yml delete mode 100644 spec/acceptance/nodesets/windows-2003-x86_64.yml delete mode 100644 spec/acceptance/nodesets/windows-2008-x86_64.yml delete mode 100644 spec/acceptance/nodesets/windows-2008r2-x86_64.yml delete mode 100644 spec/acceptance/nodesets/windows-2012-x86_64.yml delete mode 100644 spec/acceptance/nodesets/windows-2012r2-x86_64.yml diff --git a/.travis.yml b/.travis.yml index 588fb5b..4e2c66d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,18 +3,33 @@ sudo: false language: ruby cache: bundler -bundler_args: --without system_tests script: "bundle exec rake validate lint spec" matrix: fast_finish: true include: - rvm: 2.1.6 + dist: trusty + env: PUPPET_INSTALL_TYPE=agent BEAKER_debug=true BEAKER_set=docker/ubuntu-14.04 + script: bundle exec rake beaker + services: docker + sudo: required + - rvm: 2.1.6 + dist: trusty + env: PUPPET_INSTALL_TYPE=agent BEAKER_debug=true BEAKER_set=docker/centos-7 + script: bundle exec rake beaker + services: docker + sudo: required + - rvm: 2.1.6 + bundler_args: --without system_tests env: PUPPET_GEM_VERSION="~> 4.0" STRICT_VARIABLES="yes" - rvm: 2.1.5 + bundler_args: --without system_tests env: PUPPET_GEM_VERSION="~> 3.0" FUTURE_PARSER="yes" - rvm: 2.1.5 + bundler_args: --without system_tests env: PUPPET_GEM_VERSION="~> 3.0" - rvm: 1.9.3 + bundler_args: --without system_tests env: PUPPET_GEM_VERSION="~> 3.0" notifications: email: false diff --git a/spec/acceptance/nodesets/centos-59-x64.yml b/spec/acceptance/nodesets/centos-59-x64.yml deleted file mode 100644 index 2ad90b8..0000000 --- a/spec/acceptance/nodesets/centos-59-x64.yml +++ /dev/null @@ -1,10 +0,0 @@ -HOSTS: - centos-59-x64: - roles: - - master - platform: el-5-x86_64 - box : centos-59-x64-vbox4210-nocm - box_url : http://puppet-vagrant-boxes.puppetlabs.com/centos-59-x64-vbox4210-nocm.box - hypervisor : vagrant -CONFIG: - type: git diff --git a/spec/acceptance/nodesets/centos-6-vcloud.yml b/spec/acceptance/nodesets/centos-6-vcloud.yml deleted file mode 100644 index ca9c1d3..0000000 --- a/spec/acceptance/nodesets/centos-6-vcloud.yml +++ /dev/null @@ -1,15 +0,0 @@ -HOSTS: - 'centos-6-vcloud': - roles: - - master - platform: el-6-x86_64 - hypervisor: vcloud - template: centos-6-x86_64 -CONFIG: - type: foss - ssh: - keys: "~/.ssh/id_rsa-acceptance" - datastore: instance0 - folder: Delivery/Quality Assurance/Enterprise/Dynamic - resourcepool: delivery/Quality Assurance/Enterprise/Dynamic - pooling_api: http://vcloud.delivery.puppetlabs.net/ diff --git a/spec/acceptance/nodesets/centos-64-x64-pe.yml b/spec/acceptance/nodesets/centos-64-x64-pe.yml deleted file mode 100644 index 7d9242f..0000000 --- a/spec/acceptance/nodesets/centos-64-x64-pe.yml +++ /dev/null @@ -1,12 +0,0 @@ -HOSTS: - centos-64-x64: - roles: - - master - - database - - dashboard - platform: el-6-x86_64 - box : centos-64-x64-vbox4210-nocm - box_url : http://puppet-vagrant-boxes.puppetlabs.com/centos-64-x64-vbox4210-nocm.box - hypervisor : vagrant -CONFIG: - type: pe diff --git a/spec/acceptance/nodesets/centos-64-x64.yml b/spec/acceptance/nodesets/centos-64-x64.yml deleted file mode 100644 index 05540ed..0000000 --- a/spec/acceptance/nodesets/centos-64-x64.yml +++ /dev/null @@ -1,10 +0,0 @@ -HOSTS: - centos-64-x64: - roles: - - master - platform: el-6-x86_64 - box : centos-64-x64-vbox4210-nocm - box_url : http://puppet-vagrant-boxes.puppetlabs.com/centos-64-x64-vbox4210-nocm.box - hypervisor : vagrant -CONFIG: - type: foss diff --git a/spec/acceptance/nodesets/centos-65-x64.yml b/spec/acceptance/nodesets/centos-65-x64.yml deleted file mode 100644 index 4e2cb80..0000000 --- a/spec/acceptance/nodesets/centos-65-x64.yml +++ /dev/null @@ -1,10 +0,0 @@ -HOSTS: - centos-65-x64: - roles: - - master - platform: el-6-x86_64 - box : centos-65-x64-vbox436-nocm - box_url : http://puppet-vagrant-boxes.puppetlabs.com/centos-65-x64-virtualbox-nocm.box - hypervisor : vagrant -CONFIG: - type: foss diff --git a/spec/acceptance/nodesets/centos-7-x64.yml b/spec/acceptance/nodesets/centos-7-x64.yml new file mode 100644 index 0000000..1a40c89 --- /dev/null +++ b/spec/acceptance/nodesets/centos-7-x64.yml @@ -0,0 +1,10 @@ +HOSTS: + centos-7-x64: + roles: + - agent + - default + platform: redhat-7-x86_64 + hypervisor: vagrant + box: puppetlabs/centos-7.2-64-nocm +CONFIG: + type: foss diff --git a/spec/acceptance/nodesets/debian-8-x64.yml b/spec/acceptance/nodesets/debian-8-x64.yml new file mode 100644 index 0000000..fef6e63 --- /dev/null +++ b/spec/acceptance/nodesets/debian-8-x64.yml @@ -0,0 +1,10 @@ +HOSTS: + debian-8-x64: + roles: + - agent + - default + platform: debian-8-amd64 + hypervisor: vagrant + box: puppetlabs/debian-8.2-64-nocm +CONFIG: + type: foss diff --git a/spec/acceptance/nodesets/default.yml b/spec/acceptance/nodesets/default.yml index 4e2cb80..dba339c 100644 --- a/spec/acceptance/nodesets/default.yml +++ b/spec/acceptance/nodesets/default.yml @@ -1,10 +1,10 @@ HOSTS: - centos-65-x64: + ubuntu-1404-x64: roles: - - master - platform: el-6-x86_64 - box : centos-65-x64-vbox436-nocm - box_url : http://puppet-vagrant-boxes.puppetlabs.com/centos-65-x64-virtualbox-nocm.box - hypervisor : vagrant + - agent + - default + platform: ubuntu-14.04-amd64 + hypervisor: vagrant + box: puppetlabs/ubuntu-14.04-64-nocm CONFIG: type: foss diff --git a/spec/acceptance/nodesets/docker/centos-7.yml b/spec/acceptance/nodesets/docker/centos-7.yml new file mode 100644 index 0000000..a3333aa --- /dev/null +++ b/spec/acceptance/nodesets/docker/centos-7.yml @@ -0,0 +1,12 @@ +HOSTS: + centos-7-x64: + platform: el-7-x86_64 + hypervisor: docker + image: centos:7 + docker_preserve_image: true + docker_cmd: '["/usr/sbin/init"]' + # install various tools required to get the image up to usable levels + docker_image_commands: + - 'yum install -y crontabs tar wget openssl sysvinit-tools iproute which initscripts' +CONFIG: + trace_limit: 200 diff --git a/spec/acceptance/nodesets/docker/debian-8.yml b/spec/acceptance/nodesets/docker/debian-8.yml new file mode 100644 index 0000000..df5c319 --- /dev/null +++ b/spec/acceptance/nodesets/docker/debian-8.yml @@ -0,0 +1,11 @@ +HOSTS: + debian-8-x64: + platform: debian-8-amd64 + hypervisor: docker + image: debian:8 + docker_preserve_image: true + docker_cmd: '["/sbin/init"]' + docker_image_commands: + - 'apt-get update && apt-get install -y net-tools wget locales strace lsof && echo "en_US.UTF-8 UTF-8" > /etc/locale.gen && locale-gen' +CONFIG: + trace_limit: 200 diff --git a/spec/acceptance/nodesets/docker/ubuntu-14.04.yml b/spec/acceptance/nodesets/docker/ubuntu-14.04.yml new file mode 100644 index 0000000..b1efa58 --- /dev/null +++ b/spec/acceptance/nodesets/docker/ubuntu-14.04.yml @@ -0,0 +1,12 @@ +HOSTS: + ubuntu-1404-x64: + platform: ubuntu-14.04-amd64 + hypervisor: docker + image: ubuntu:14.04 + docker_preserve_image: true + docker_cmd: '["/sbin/init"]' + docker_image_commands: + # ensure that upstart is booting correctly in the container + - 'rm /usr/sbin/policy-rc.d && rm /sbin/initctl && dpkg-divert --rename --remove /sbin/initctl && apt-get update && apt-get install -y net-tools wget && locale-gen en_US.UTF-8' +CONFIG: + trace_limit: 200 diff --git a/spec/acceptance/nodesets/fedora-18-x64.yml b/spec/acceptance/nodesets/fedora-18-x64.yml deleted file mode 100644 index 1361649..0000000 --- a/spec/acceptance/nodesets/fedora-18-x64.yml +++ /dev/null @@ -1,10 +0,0 @@ -HOSTS: - fedora-18-x64: - roles: - - master - platform: fedora-18-x86_64 - box : fedora-18-x64-vbox4210-nocm - box_url : http://puppet-vagrant-boxes.puppetlabs.com/fedora-18-x64-vbox4210-nocm.box - hypervisor : vagrant -CONFIG: - type: foss diff --git a/spec/acceptance/nodesets/sles-11-x64.yml b/spec/acceptance/nodesets/sles-11-x64.yml deleted file mode 100644 index 41abe21..0000000 --- a/spec/acceptance/nodesets/sles-11-x64.yml +++ /dev/null @@ -1,10 +0,0 @@ -HOSTS: - sles-11-x64.local: - roles: - - master - platform: sles-11-x64 - box : sles-11sp1-x64-vbox4210-nocm - box_url : http://puppet-vagrant-boxes.puppetlabs.com/sles-11sp1-x64-vbox4210-nocm.box - hypervisor : vagrant -CONFIG: - type: foss diff --git a/spec/acceptance/nodesets/ubuntu-server-10044-x64.yml b/spec/acceptance/nodesets/ubuntu-server-10044-x64.yml deleted file mode 100644 index 5ca1514..0000000 --- a/spec/acceptance/nodesets/ubuntu-server-10044-x64.yml +++ /dev/null @@ -1,10 +0,0 @@ -HOSTS: - ubuntu-server-10044-x64: - roles: - - master - platform: ubuntu-10.04-amd64 - box : ubuntu-server-10044-x64-vbox4210-nocm - box_url : http://puppet-vagrant-boxes.puppetlabs.com/ubuntu-server-10044-x64-vbox4210-nocm.box - hypervisor : vagrant -CONFIG: - type: foss diff --git a/spec/acceptance/nodesets/ubuntu-server-12042-x64.yml b/spec/acceptance/nodesets/ubuntu-server-12042-x64.yml deleted file mode 100644 index d065b30..0000000 --- a/spec/acceptance/nodesets/ubuntu-server-12042-x64.yml +++ /dev/null @@ -1,10 +0,0 @@ -HOSTS: - ubuntu-server-12042-x64: - roles: - - master - platform: ubuntu-12.04-amd64 - box : ubuntu-server-12042-x64-vbox4210-nocm - box_url : http://puppet-vagrant-boxes.puppetlabs.com/ubuntu-server-12042-x64-vbox4210-nocm.box - hypervisor : vagrant -CONFIG: - type: foss diff --git a/spec/acceptance/nodesets/ubuntu-server-1404-x64.yml b/spec/acceptance/nodesets/ubuntu-server-1404-x64.yml deleted file mode 100644 index cba1cd0..0000000 --- a/spec/acceptance/nodesets/ubuntu-server-1404-x64.yml +++ /dev/null @@ -1,11 +0,0 @@ -HOSTS: - ubuntu-server-1404-x64: - roles: - - master - platform: ubuntu-14.04-amd64 - box : puppetlabs/ubuntu-14.04-64-nocm - box_url : https://vagrantcloud.com/puppetlabs/ubuntu-14.04-64-nocm - hypervisor : vagrant -CONFIG: - log_level : debug - type: git diff --git a/spec/acceptance/nodesets/windows-2003-i386.yml b/spec/acceptance/nodesets/windows-2003-i386.yml deleted file mode 100644 index 47dadbd..0000000 --- a/spec/acceptance/nodesets/windows-2003-i386.yml +++ /dev/null @@ -1,26 +0,0 @@ -HOSTS: - ubuntu1204: - roles: - - master - - database - - dashboard - platform: ubuntu-12.04-amd64 - template: ubuntu-1204-x86_64 - hypervisor: vcloud - win2003_i386: - roles: - - agent - - default - platform: windows-2003-i386 - template: win-2003-i386 - hypervisor: vcloud -CONFIG: - nfs_server: none - ssh: - keys: "~/.ssh/id_rsa-acceptance" - consoleport: 443 - datastore: instance0 - folder: Delivery/Quality Assurance/Enterprise/Dynamic - resourcepool: delivery/Quality Assurance/Enterprise/Dynamic - pooling_api: http://vcloud.delivery.puppetlabs.net/ - pe_dir: http://neptune.puppetlabs.lan/3.2/ci-ready/ diff --git a/spec/acceptance/nodesets/windows-2003-x86_64.yml b/spec/acceptance/nodesets/windows-2003-x86_64.yml deleted file mode 100644 index 6a884bc..0000000 --- a/spec/acceptance/nodesets/windows-2003-x86_64.yml +++ /dev/null @@ -1,26 +0,0 @@ -HOSTS: - ubuntu1204: - roles: - - master - - database - - dashboard - platform: ubuntu-12.04-amd64 - template: ubuntu-1204-x86_64 - hypervisor: vcloud - win2003_x86_64: - roles: - - agent - - default - platform: windows-2003-x86_64 - template: win-2003-x86_64 - hypervisor: vcloud -CONFIG: - nfs_server: none - ssh: - keys: "~/.ssh/id_rsa-acceptance" - consoleport: 443 - datastore: instance0 - folder: Delivery/Quality Assurance/Enterprise/Dynamic - resourcepool: delivery/Quality Assurance/Enterprise/Dynamic - pooling_api: http://vcloud.delivery.puppetlabs.net/ - pe_dir: http://neptune.puppetlabs.lan/3.2/ci-ready/ diff --git a/spec/acceptance/nodesets/windows-2008-x86_64.yml b/spec/acceptance/nodesets/windows-2008-x86_64.yml deleted file mode 100644 index ae3c11d..0000000 --- a/spec/acceptance/nodesets/windows-2008-x86_64.yml +++ /dev/null @@ -1,26 +0,0 @@ -HOSTS: - ubuntu1204: - roles: - - master - - database - - dashboard - platform: ubuntu-12.04-amd64 - template: ubuntu-1204-x86_64 - hypervisor: vcloud - win2008_x86_64: - roles: - - agent - - default - platform: windows-2008-x86_64 - template: win-2008-x86_64 - hypervisor: vcloud -CONFIG: - nfs_server: none - ssh: - keys: "~/.ssh/id_rsa-acceptance" - consoleport: 443 - datastore: instance0 - folder: Delivery/Quality Assurance/Enterprise/Dynamic - resourcepool: delivery/Quality Assurance/Enterprise/Dynamic - pooling_api: http://vcloud.delivery.puppetlabs.net/ - pe_dir: http://neptune.puppetlabs.lan/3.2/ci-ready/ diff --git a/spec/acceptance/nodesets/windows-2008r2-x86_64.yml b/spec/acceptance/nodesets/windows-2008r2-x86_64.yml deleted file mode 100644 index 63923ac..0000000 --- a/spec/acceptance/nodesets/windows-2008r2-x86_64.yml +++ /dev/null @@ -1,26 +0,0 @@ -HOSTS: - ubuntu1204: - roles: - - master - - database - - dashboard - platform: ubuntu-12.04-amd64 - template: ubuntu-1204-x86_64 - hypervisor: vcloud - win2008r2: - roles: - - agent - - default - platform: windows-2008r2-x86_64 - template: win-2008r2-x86_64 - hypervisor: vcloud -CONFIG: - nfs_server: none - ssh: - keys: "~/.ssh/id_rsa-acceptance" - consoleport: 443 - datastore: instance0 - folder: Delivery/Quality Assurance/Enterprise/Dynamic - resourcepool: delivery/Quality Assurance/Enterprise/Dynamic - pooling_api: http://vcloud.delivery.puppetlabs.net/ - pe_dir: http://neptune.puppetlabs.lan/3.2/ci-ready/ diff --git a/spec/acceptance/nodesets/windows-2012-x86_64.yml b/spec/acceptance/nodesets/windows-2012-x86_64.yml deleted file mode 100644 index eaa4eca..0000000 --- a/spec/acceptance/nodesets/windows-2012-x86_64.yml +++ /dev/null @@ -1,26 +0,0 @@ -HOSTS: - ubuntu1204: - roles: - - master - - database - - dashboard - platform: ubuntu-12.04-amd64 - template: ubuntu-1204-x86_64 - hypervisor: vcloud - win2012: - roles: - - agent - - default - platform: windows-2012-x86_64 - template: win-2012-x86_64 - hypervisor: vcloud -CONFIG: - nfs_server: none - ssh: - keys: "~/.ssh/id_rsa-acceptance" - consoleport: 443 - datastore: instance0 - folder: Delivery/Quality Assurance/Enterprise/Dynamic - resourcepool: delivery/Quality Assurance/Enterprise/Dynamic - pooling_api: http://vcloud.delivery.puppetlabs.net/ - pe_dir: http://neptune.puppetlabs.lan/3.2/ci-ready/ diff --git a/spec/acceptance/nodesets/windows-2012r2-x86_64.yml b/spec/acceptance/nodesets/windows-2012r2-x86_64.yml deleted file mode 100644 index 1f0ea97..0000000 --- a/spec/acceptance/nodesets/windows-2012r2-x86_64.yml +++ /dev/null @@ -1,26 +0,0 @@ -HOSTS: - ubuntu1204: - roles: - - master - - database - - dashboard - platform: ubuntu-12.04-amd64 - template: ubuntu-1204-x86_64 - hypervisor: vcloud - win2012r2: - roles: - - agent - - default - platform: windows-2012r2-x86_64 - template: win-2012r2-x86_64 - hypervisor: vcloud -CONFIG: - nfs_server: none - ssh: - keys: "~/.ssh/id_rsa-acceptance" - consoleport: 443 - datastore: instance0 - folder: Delivery/Quality Assurance/Enterprise/Dynamic - resourcepool: delivery/Quality Assurance/Enterprise/Dynamic - pooling_api: http://vcloud.delivery.puppetlabs.net/ - pe_dir: http://neptune.puppetlabs.lan/3.2/ci-ready/ diff --git a/spec/spec_helper_acceptance.rb b/spec/spec_helper_acceptance.rb index eda0d1a..8a1907f 100755 --- a/spec/spec_helper_acceptance.rb +++ b/spec/spec_helper_acceptance.rb @@ -25,7 +25,7 @@ RSpec.configure do |c| end def is_future_parser_enabled? - if default[:type] == 'aio' + if default[:type] == 'aio' || ENV['PUPPET_INSTALL_TYPE'] == 'agent' return true elsif default[:default_apply_opts] return default[:default_apply_opts][:parser] == 'future' -- cgit v1.2.3 From 232de137f1018060b256b1f3f649be0b6d7d9952 Mon Sep 17 00:00:00 2001 From: Hunter Haugen Date: Mon, 25 Apr 2016 14:33:43 -0700 Subject: Revert "Add support for regular expressions to delete" This reverts commit 0d46515b57cea60d4d5f1e4d81a75a448a7a73a8. It introduced backwards-incompatible functionality. --- README.markdown | 2 +- lib/puppet/parser/functions/delete.rb | 4 +++- spec/functions/delete_spec.rb | 7 +------ 3 files changed, 5 insertions(+), 8 deletions(-) diff --git a/README.markdown b/README.markdown index 2f5faf3..6cedc2a 100644 --- a/README.markdown +++ b/README.markdown @@ -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. 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. +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. #### `delete_at` diff --git a/lib/puppet/parser/functions/delete.rb b/lib/puppet/parser/functions/delete.rb index 8435163..f548b44 100644 --- a/lib/puppet/parser/functions/delete.rb +++ b/lib/puppet/parser/functions/delete.rb @@ -2,6 +2,8 @@ # 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 @@ -32,7 +34,7 @@ string, or key from a hash. Array(arguments[1]).each do |item| case collection when Array, Hash - collection.delete_if { |coll_item| coll_item =~ %r{#{item}} } + collection.delete item when String collection.gsub! item, '' else diff --git a/spec/functions/delete_spec.rb b/spec/functions/delete_spec.rb index 998f9a6..6c4747b 100755 --- a/spec/functions/delete_spec.rb +++ b/spec/functions/delete_spec.rb @@ -12,7 +12,6 @@ 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']) } @@ -33,7 +32,7 @@ describe 'delete' do it { is_expected.to run.with_params('barfoobar', ['foo', 'barbar']).and_return('') } end - describe 'deleting from a hash' do + describe 'deleting from an array' 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({}) } @@ -45,10 +44,6 @@ 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 -- cgit v1.2.3 From 19752a7ff378a35f287bf5351d466a1eae399266 Mon Sep 17 00:00:00 2001 From: Hunter Haugen Date: Mon, 25 Apr 2016 14:34:21 -0700 Subject: Remove todo for delete() and update spec This spec should verify that substring matches are not removed in the future --- CHANGELOG.md | 1 - spec/functions/delete_spec.rb | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7aa0a10..2bc584b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,7 +14,6 @@ This release provides several new functions, bugfixes, modulesync changes, and s - Extends `suffix` to support applying a suffix to keys in a hash. - Apply modulesync changes. - Add validate_email_address function. -- Add support for regular expressions to delete. ####Bugfixes - Fixes `fqdn_rand_string` tests, since Puppet 4.4.0 and later have a higher `fqdn_rand` ceiling. diff --git a/spec/functions/delete_spec.rb b/spec/functions/delete_spec.rb index 6c4747b..cf696ac 100755 --- a/spec/functions/delete_spec.rb +++ b/spec/functions/delete_spec.rb @@ -13,6 +13,7 @@ describe 'delete' do 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'], 'four').and_return(['one', 'two', 'three']) } + it { is_expected.to run.with_params(['one', 'two', 'three'], 'e').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']) } it { is_expected.to run.with_params(['one', 'two', 'three', 'two'], ['one', 'two']).and_return(['three']) } -- cgit v1.2.3 From 870a272cee6889934d60c4bfd7a814bcf47011f1 Mon Sep 17 00:00:00 2001 From: Dmitry Ilyin Date: Tue, 26 Apr 2016 21:51:43 +0300 Subject: Add the default value to the "loadyaml" function This value will be returned if the is no file to load or a file could not be parsed. It's similar to the "parseyaml" function's default value. Add the "loadjson" function too --- README.markdown | 32 +++++++++++++++++++- lib/puppet/parser/functions/loadjson.rb | 34 +++++++++++++++++++++ lib/puppet/parser/functions/loadyaml.rb | 37 ++++++++++++++--------- spec/acceptance/loadjson_spec.rb | 52 +++++++++++++++++++++++++++++++++ spec/acceptance/loadyaml_spec.rb | 23 +++++++++++++++ spec/functions/loadjson_spec.rb | 38 ++++++++++++++++++++++++ spec/functions/loadyaml_spec.rb | 16 ++++++++-- 7 files changed, 214 insertions(+), 18 deletions(-) create mode 100644 lib/puppet/parser/functions/loadjson.rb create mode 100644 spec/acceptance/loadjson_spec.rb create mode 100644 spec/functions/loadjson_spec.rb diff --git a/README.markdown b/README.markdown index 6cedc2a..eff3b28 100644 --- a/README.markdown +++ b/README.markdown @@ -660,12 +660,42 @@ Returns the keys of a hash as an array. *Type*: rvalue. #### `loadyaml` -Loads a YAML file containing an array, string, or hash, and returns the data in the corresponding native data type. For example: +Loads a YAML file containing an array, string, or hash, and returns the data in the corresponding native data type. + +For example: ~~~ $myhash = loadyaml('/etc/puppet/data/myhash.yaml') ~~~ +The second parameter will be returned if the file was not found or could not be parsed. + +For example: + + ~~~ + $myhash = loadyaml('no-file.yaml', {'default'=>'value'}) + ~~~ + +*Type*: rvalue. + +#### `loadjson` + +Loads a JSON file containing an array, string, or hash, and returns the data in the corresponding native data type. + +For example: + + ~~~ + $myhash = loadjson('/etc/puppet/data/myhash.json') + ~~~ + +The second parameter will be returned if the file was not found or could not be parsed. + +For example: + + ~~~ + $myhash = loadjson('no-file.json', {'default'=>'value'}) + ~~~ + *Type*: rvalue. #### `load_module_metadata` diff --git a/lib/puppet/parser/functions/loadjson.rb b/lib/puppet/parser/functions/loadjson.rb new file mode 100644 index 0000000..3a3372b --- /dev/null +++ b/lib/puppet/parser/functions/loadjson.rb @@ -0,0 +1,34 @@ +module Puppet::Parser::Functions + newfunction(:loadjson, :type => :rvalue, :arity => -2, :doc => <<-'ENDHEREDOC') do |args| +Load a JSON file containing an array, string, or hash, and return the data +in the corresponding native data type. +The second parameter is the default value. It will be returned if the file +was not found or could not be parsed. + +For example: + + $myhash = loadjson('/etc/puppet/data/myhash.json') + $myhash = loadjson('no-file.json', {'default' => 'value'}) + ENDHEREDOC + + raise ArgumentError, 'Wrong number of arguments. 1 or 2 arguments should be provided.' unless args.length >= 1 + + if File.exists?(args[0]) + begin + content = File.read(args[0]) + PSON::load(content) || args[1] + rescue Exception => e + if args[1] + args[1] + else + raise e + end + end + else + warning("Can't load '#{args[0]}' File does not exist!") + args[1] + end + + end + +end diff --git a/lib/puppet/parser/functions/loadyaml.rb b/lib/puppet/parser/functions/loadyaml.rb index ca655f6..9696362 100644 --- a/lib/puppet/parser/functions/loadyaml.rb +++ b/lib/puppet/parser/functions/loadyaml.rb @@ -1,23 +1,32 @@ module Puppet::Parser::Functions + newfunction(:loadyaml, :type => :rvalue, :arity => -2, :doc => <<-'ENDHEREDOC') do |args| +Load a YAML file containing an array, string, or hash, and return the data +in the corresponding native data type. +The second parameter is the default value. It will be returned if the file +was not found or could not be parsed. - newfunction(:loadyaml, :type => :rvalue, :doc => <<-'ENDHEREDOC') do |args| - Load a YAML file containing an array, string, or hash, and return the data - in the corresponding native data type. +For example: - For example: + $myhash = loadyaml('/etc/puppet/data/myhash.yaml') + $myhash = loadyaml('no-file.yaml', {'default' => 'value'}) + ENDHEREDOC - $myhash = loadyaml('/etc/puppet/data/myhash.yaml') - ENDHEREDOC + raise ArgumentError, 'Wrong number of arguments. 1 or 2 arguments should be provided.' unless args.length >= 1 + require 'yaml' - unless args.length == 1 - raise Puppet::ParseError, ("loadyaml(): wrong number of arguments (#{args.length}; must be 1)") - end - - if File.exists?(args[0]) then - YAML.load_file(args[0]) + if File.exists?(args[0]) + begin + YAML::load_file(args[0]) || args[1] + rescue Exception => e + if args[1] + args[1] + else + raise e + end + end else - warning("Can't load " + args[0] + ". File does not exist!") - nil + warning("Can't load '#{args[0]}' File does not exist!") + args[1] end end diff --git a/spec/acceptance/loadjson_spec.rb b/spec/acceptance/loadjson_spec.rb new file mode 100644 index 0000000..2992c37 --- /dev/null +++ b/spec/acceptance/loadjson_spec.rb @@ -0,0 +1,52 @@ +#! /usr/bin/env ruby -S rspec +require 'spec_helper_acceptance' + +tmpdir = default.tmpdir('stdlib') + +describe 'loadjson function', :unless => UNSUPPORTED_PLATFORMS.include?(fact('operatingsystem')) do + describe 'success' do + it 'loadjsons array of values' do + shell("echo '{\"aaa\":1,\"bbb\":2,\"ccc\":3,\"ddd\":4}' > #{tmpdir}/testjson.json") + pp = <<-EOS + $o = loadjson('#{tmpdir}/testjson.json') + notice(inline_template('loadjson[aaa] is <%= @o["aaa"].inspect %>')) + notice(inline_template('loadjson[bbb] is <%= @o["bbb"].inspect %>')) + notice(inline_template('loadjson[ccc] is <%= @o["ccc"].inspect %>')) + notice(inline_template('loadjson[ddd] is <%= @o["ddd"].inspect %>')) + EOS + + apply_manifest(pp, :catch_failures => true) do |r| + expect(r.stdout).to match(/loadjson\[aaa\] is 1/) + expect(r.stdout).to match(/loadjson\[bbb\] is 2/) + expect(r.stdout).to match(/loadjson\[ccc\] is 3/) + expect(r.stdout).to match(/loadjson\[ddd\] is 4/) + end + end + + it 'returns the default value if there is no file to load' do + pp = <<-EOS + $o = loadjson('#{tmpdir}/no-file.json', {'default' => 'value'}) + notice(inline_template('loadjson[default] is <%= @o["default"].inspect %>')) + EOS + + apply_manifest(pp, :catch_failures => true) do |r| + expect(r.stdout).to match(/loadjson\[default\] is "value"/) + end + end + + it 'returns the default value if the file was parsed with an error' do + shell("echo '!' > #{tmpdir}/testjson.json") + pp = <<-EOS + $o = loadjson('#{tmpdir}/testjson.json', {'default' => 'value'}) + notice(inline_template('loadjson[default] is <%= @o["default"].inspect %>')) + EOS + + apply_manifest(pp, :catch_failures => true) do |r| + expect(r.stdout).to match(/loadjson\[default\] is "value"/) + end + end + end + describe 'failure' do + it 'fails with no arguments' + end +end diff --git a/spec/acceptance/loadyaml_spec.rb b/spec/acceptance/loadyaml_spec.rb index 1e910a9..ba3f0b7 100644 --- a/spec/acceptance/loadyaml_spec.rb +++ b/spec/acceptance/loadyaml_spec.rb @@ -26,6 +26,29 @@ describe 'loadyaml function', :unless => UNSUPPORTED_PLATFORMS.include?(fact('op expect(r.stdout).to match(/loadyaml\[ddd\] is 4/) end end + + it 'returns the default value if there is no file to load' do + pp = <<-EOS + $o = loadyaml('#{tmpdir}/no-file.yaml', {'default' => 'value'}) + notice(inline_template('loadyaml[default] is <%= @o["default"].inspect %>')) + EOS + + apply_manifest(pp, :catch_failures => true) do |r| + expect(r.stdout).to match(/loadyaml\[default\] is "value"/) + end + end + + it 'returns the default value if the file was parsed with an error' do + shell("echo '!' > #{tmpdir}/testyaml.yaml") + pp = <<-EOS + $o = loadyaml('#{tmpdir}/testyaml.yaml', {'default' => 'value'}) + notice(inline_template('loadyaml[default] is <%= @o["default"].inspect %>')) + EOS + + apply_manifest(pp, :catch_failures => true) do |r| + expect(r.stdout).to match(/loadyaml\[default\] is "value"/) + end + end end describe 'failure' do it 'fails with no arguments' diff --git a/spec/functions/loadjson_spec.rb b/spec/functions/loadjson_spec.rb new file mode 100644 index 0000000..12a9b82 --- /dev/null +++ b/spec/functions/loadjson_spec.rb @@ -0,0 +1,38 @@ +require 'spec_helper' + +describe 'loadjson' do + it { is_expected.not_to eq(nil) } + it { is_expected.to run.with_params().and_raise_error(ArgumentError, /wrong number of arguments/i) } + + context 'when a non-existing file is specified' do + let(:filename) { '/tmp/doesnotexist' } + before { + File.expects(:exists?).with(filename).returns(false).once + PSON.expects(:load).never + } + it { is_expected.to run.with_params(filename, {'default' => 'value'}).and_return({'default' => 'value'}) } + end + + context 'when an existing file is specified' do + let(:filename) { '/tmp/doesexist' } + let(:data) { { 'key' => 'value' } } + let(:json) { '{"key":"value"}' } + before { + File.expects(:exists?).with(filename).returns(true).once + File.expects(:read).with(filename).returns(json).once + PSON.expects(:load).with(json).returns(data).once + } + it { is_expected.to run.with_params(filename).and_return(data) } + end + + context 'when the file could not be parsed' do + let(:filename) { '/tmp/doesexist' } + let(:json) { '{"key":"value"}' } + before { + File.expects(:exists?).with(filename).returns(true).once + File.expects(:read).with(filename).returns(json).once + PSON.stubs(:load).with(json).once.raises StandardError, 'Something terrible have happened!' + } + it { is_expected.to run.with_params(filename, {'default' => 'value'}).and_return({'default' => 'value'}) } + end +end diff --git a/spec/functions/loadyaml_spec.rb b/spec/functions/loadyaml_spec.rb index ffc714d..9f16a1a 100755 --- a/spec/functions/loadyaml_spec.rb +++ b/spec/functions/loadyaml_spec.rb @@ -2,16 +2,17 @@ require 'spec_helper' describe 'loadyaml' 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().and_raise_error(ArgumentError, /wrong number of arguments/i) } + context 'when a non-existing file is specified' do let(:filename) { '/tmp/doesnotexist' } before { File.expects(:exists?).with(filename).returns(false).once YAML.expects(:load_file).never } - it { is_expected.to run.with_params(filename).and_return(nil) } + it { is_expected.to run.with_params(filename, {'default' => 'value'}).and_return({'default' => 'value'}) } end + context 'when an existing file is specified' do let(:filename) { '/tmp/doesexist' } let(:data) { { 'key' => 'value' } } @@ -21,4 +22,13 @@ describe 'loadyaml' do } it { is_expected.to run.with_params(filename).and_return(data) } end + + context 'when the file could not be parsed' do + let(:filename) { '/tmp/doesexist' } + before { + File.expects(:exists?).with(filename).returns(true).once + YAML.stubs(:load_file).with(filename).once.raises StandardError, 'Something terrible have happened!' + } + it { is_expected.to run.with_params(filename, {'default' => 'value'}).and_return({'default' => 'value'}) } + end end -- cgit v1.2.3 From db6e2f81b470afc3e0c2c96a47cf9e68b9c7afc7 Mon Sep 17 00:00:00 2001 From: Hunter Haugen Date: Wed, 27 Apr 2016 15:34:19 -0700 Subject: Remove hard linebreaks --- README.markdown | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/README.markdown b/README.markdown index 6cedc2a..ba1f5f8 100644 --- a/README.markdown +++ b/README.markdown @@ -146,11 +146,9 @@ Converts any object to an array containing that object. Empty argument lists are #### `base64` -Converts a string to and from base64 encoding. -Requires an `action` ('encode', 'decode') and either a plain or base64-encoded `string`, -and an optional `method` ('default', 'strict', 'urlsafe') +Converts a string to and from base64 encoding. Requires an `action` ('encode', 'decode') and either a plain or base64-encoded `string`, and an optional `method` ('default', 'strict', 'urlsafe') -for backward compatibility, `metohd` will be set as `default` if not specified. +For backward compatibility, `method` will be set as `default` if not specified. *Examples:* ~~~ @@ -346,8 +344,7 @@ Returns true if the argument is an array or hash that contains no elements, or a #### `enclose_ipv6` -Takes an array of ip addresses and encloses the ipv6 addresses with square -brackets. *Type*: rvalue. +Takes an array of ip addresses and encloses the ipv6 addresses with square brackets. *Type*: rvalue. #### `ensure_packages` -- cgit v1.2.3 From 9e1f74f3fcac4aeaccade3ea92e6cafbaf71a64f Mon Sep 17 00:00:00 2001 From: Joris Date: Thu, 28 Apr 2016 19:44:30 +0200 Subject: Expose the functions of ruby's built-in Shellwords module (#580) * Add shell_escape function, shell_join function & shell_split function --- README.markdown | 34 +++++++++++++++++++++++++++++ lib/puppet/parser/functions/shell_escape.rb | 30 +++++++++++++++++++++++++ lib/puppet/parser/functions/shell_join.rb | 31 ++++++++++++++++++++++++++ lib/puppet/parser/functions/shell_split.rb | 26 ++++++++++++++++++++++ spec/functions/shell_escape_spec.rb | 22 +++++++++++++++++++ spec/functions/shell_join_spec.rb | 23 +++++++++++++++++++ spec/functions/shell_split_spec.rb | 24 ++++++++++++++++++++ 7 files changed, 190 insertions(+) create mode 100644 lib/puppet/parser/functions/shell_escape.rb create mode 100644 lib/puppet/parser/functions/shell_join.rb create mode 100644 lib/puppet/parser/functions/shell_split.rb create mode 100644 spec/functions/shell_escape_spec.rb create mode 100644 spec/functions/shell_join_spec.rb create mode 100644 spec/functions/shell_split_spec.rb diff --git a/README.markdown b/README.markdown index 2f5faf3..9e62d1c 100644 --- a/README.markdown +++ b/README.markdown @@ -821,6 +821,40 @@ Strips spaces to the right of the string. *Type*: rvalue. Takes an integer max value and a string seed value and returns a repeatable random integer smaller than max. Like `fqdn_rand`, but does not add node specific data to the seed. *Type*: rvalue. +#### `shell_escape` + +Escapes a string so that it can be safely used in a Bourne shell command line. Note that the resulting string should be used unquoted and is not intended for use in double quotes nor in single quotes. This function behaves the same as ruby's `Shellwords.shellescape()` function, also see the [ruby documentation](http://ruby-doc.org/stdlib-2.3.0/libdoc/shellwords/rdoc/Shellwords.html#method-c-shellescape). + +*Example:* +~~~ +shell_escape('foo b"ar') => 'foo\ b\"ar' +~~~ + +*Type*: rvalue. + +#### `shell_join` + +Builds a command line string from the given array of strings. Each array item is escaped for Bourne shell. All items are +then joined together, with a single space in between. This function behaves the same as ruby's `Shellwords.shelljoin()` function, also see the [ruby documentation](http://ruby-doc.org/stdlib-2.3.0/libdoc/shellwords/rdoc/Shellwords.html#method-c-shelljoin). + +*Example:* +~~~ +shell_join(['foo bar', 'ba"z']) => 'foo\ bar ba\"z' +~~~ + +*Type*: rvalue. + +#### `shell_split` + +Splits a string into an array of tokens in the same way the Bourne shell does. This function behaves the same as ruby's `Shellwords.shellsplit()` function, also see the [ruby documentation](http://ruby-doc.org/stdlib-2.3.0/libdoc/shellwords/rdoc/Shellwords.html#method-c-shellsplit). + +*Example:* +~~~ +shell_split('foo\ bar ba\"z') => ['foo bar', 'ba"z'] +~~~ + +*Type*: rvalue. + #### `shuffle` Randomizes the order of a string or array elements. *Type*: rvalue. diff --git a/lib/puppet/parser/functions/shell_escape.rb b/lib/puppet/parser/functions/shell_escape.rb new file mode 100644 index 0000000..447fe35 --- /dev/null +++ b/lib/puppet/parser/functions/shell_escape.rb @@ -0,0 +1,30 @@ +# +# shell_escape.rb +# + +require 'shellwords' + +module Puppet::Parser::Functions + newfunction(:shell_escape, :type => :rvalue, :doc => <<-EOS +Escapes a string so that it can be safely used in a Bourne shell command line. + +Note that the resulting string should be used unquoted and is not intended for use in double quotes nor in single +quotes. + +This function behaves the same as ruby's Shellwords.shellescape() function. + EOS + ) do |arguments| + + raise(Puppet::ParseError, "shell_escape(): Wrong number of arguments " + + "given (#{arguments.size} for 1)") if arguments.size != 1 + + # explicit conversion to string is required for ruby 1.9 + string = arguments[0].to_s + + result = Shellwords.shellescape(string) + + return result + end +end + +# vim: set ts=2 sw=2 et : diff --git a/lib/puppet/parser/functions/shell_join.rb b/lib/puppet/parser/functions/shell_join.rb new file mode 100644 index 0000000..05aeb95 --- /dev/null +++ b/lib/puppet/parser/functions/shell_join.rb @@ -0,0 +1,31 @@ +# +# shell_join.rb +# + +require 'shellwords' + +module Puppet::Parser::Functions + newfunction(:shell_join, :type => :rvalue, :doc => <<-EOS +Builds a command line string from the given array of strings. Each array item is escaped for Bourne shell. All items are +then joined together, with a single space in between. + +This function behaves the same as ruby's Shellwords.shelljoin() function + EOS + ) do |arguments| + + raise(Puppet::ParseError, "shell_join(): Wrong number of arguments " + + "given (#{arguments.size} for 1)") if arguments.size != 1 + + array = arguments[0] + + raise Puppet::ParseError, ("First argument is not an Array: #{array.inspect}") unless array.is_a?(Array) + + # explicit conversion to string is required for ruby 1.9 + array = array.map { |item| item.to_s } + result = Shellwords.shelljoin(array) + + return result + end +end + +# vim: set ts=2 sw=2 et : diff --git a/lib/puppet/parser/functions/shell_split.rb b/lib/puppet/parser/functions/shell_split.rb new file mode 100644 index 0000000..0446448 --- /dev/null +++ b/lib/puppet/parser/functions/shell_split.rb @@ -0,0 +1,26 @@ +# +# shell_split.rb +# + +require 'shellwords' + +module Puppet::Parser::Functions + newfunction(:shell_split, :type => :rvalue, :doc => <<-EOS +Splits a string into an array of tokens in the same way the Bourne shell does. + +This function behaves the same as ruby's Shellwords.shellsplit() function + EOS + ) do |arguments| + + raise(Puppet::ParseError, "shell_split(): Wrong number of arguments " + + "given (#{arguments.size} for 1)") if arguments.size != 1 + + string = arguments[0].to_s + + result = Shellwords.shellsplit(string) + + return result + end +end + +# vim: set ts=2 sw=2 et : diff --git a/spec/functions/shell_escape_spec.rb b/spec/functions/shell_escape_spec.rb new file mode 100644 index 0000000..3061dec --- /dev/null +++ b/spec/functions/shell_escape_spec.rb @@ -0,0 +1,22 @@ +require 'spec_helper' + +describe 'shell_escape' do + it { is_expected.not_to eq(nil) } + + describe 'signature validation' do + it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } + it { is_expected.to run.with_params('foo', 'bar').and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } + end + + describe 'stringification' do + it { is_expected.to run.with_params(10).and_return('10') } + it { is_expected.to run.with_params(false).and_return('false') } + end + + describe 'escaping' do + it { is_expected.to run.with_params('foo').and_return('foo') } + it { is_expected.to run.with_params('foo bar').and_return('foo\ bar') } + it { is_expected.to run.with_params('~`!@#$%^&*()_+-=[]\{}|;\':",./<>?') + .and_return('\~\`\!@\#\$\%\^\&\*\(\)_\+-\=\[\]\\\\\{\}\|\;\\\':\",./\<\>\?') } + end +end diff --git a/spec/functions/shell_join_spec.rb b/spec/functions/shell_join_spec.rb new file mode 100644 index 0000000..6815f7c --- /dev/null +++ b/spec/functions/shell_join_spec.rb @@ -0,0 +1,23 @@ +require 'spec_helper' + +describe 'shell_join' do + it { is_expected.not_to eq(nil) } + + describe 'signature validation' do + it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } + it { is_expected.to run.with_params(['foo'], ['bar']).and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } + it { is_expected.to run.with_params('foo').and_raise_error(Puppet::ParseError, /is not an Array/i) } + end + + describe 'shell argument joining' do + it { is_expected.to run.with_params(['foo']).and_return('foo') } + it { is_expected.to run.with_params(['foo', 'bar']).and_return('foo bar') } + it { is_expected.to run.with_params(['foo', 'bar baz']).and_return('foo bar\ baz') } + it { is_expected.to run.with_params(['~`!@#$', '%^&*()_+-=', '[]\{}|;\':"', ',./<>?']) + .and_return('\~\`\!@\#\$ \%\^\&\*\(\)_\+-\= \[\]\\\\\{\}\|\;\\\':\" ,./\<\>\?') } + end + + describe 'stringification' do + it { is_expected.to run.with_params([10, false, 'foo']).and_return('10 false foo') } + end +end diff --git a/spec/functions/shell_split_spec.rb b/spec/functions/shell_split_spec.rb new file mode 100644 index 0000000..beeb977 --- /dev/null +++ b/spec/functions/shell_split_spec.rb @@ -0,0 +1,24 @@ +require 'spec_helper' + +describe 'shell_split' do + it { is_expected.not_to eq(nil) } + + describe 'signature validation' do + it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } + it { is_expected.to run.with_params('foo', 'bar').and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } + end + + describe 'stringification' do + it { is_expected.to run.with_params(10).and_return(['10']) } + it { is_expected.to run.with_params(false).and_return(['false']) } + end + + describe 'shell line spliting' do + it { is_expected.to run.with_params('foo').and_return(['foo']) } + it { is_expected.to run.with_params('foo bar').and_return(['foo', 'bar']) } + it { is_expected.to run.with_params('\~\`\!@\#\$\%\^\&\*\(\)_\+-\=\[\]\\\\\{\}\|\;\\\':\",./\<\>\?') + .and_return(['~`!@#$%^&*()_+-=[]\{}|;\':",./<>?']) } + it { is_expected.to run.with_params('\~\`\!@\#\$ \%\^\&\*\(\)_\+-\= \[\]\\\\\{\}\|\;\\\':\" ,./\<\>\?') + .and_return(['~`!@#$', '%^&*()_+-=', '[]\{}|;\':"', ',./<>?']) } + end +end -- cgit v1.2.3 From 420f76d8dcb307d363d30bef7cc963bff4f776fc Mon Sep 17 00:00:00 2001 From: Peter Souter Date: Wed, 27 Apr 2016 14:06:22 +0100 Subject: (MODULES-1439) Adds any2bool function * Basically a combination of `string2bool` and `num2bool` --- lib/puppet/parser/functions/any2bool.rb | 55 +++++++++++++++++++++++++++++++++ spec/functions/any2bool_spec.rb | 42 +++++++++++++++++++++++++ 2 files changed, 97 insertions(+) create mode 100644 lib/puppet/parser/functions/any2bool.rb create mode 100755 spec/functions/any2bool_spec.rb diff --git a/lib/puppet/parser/functions/any2bool.rb b/lib/puppet/parser/functions/any2bool.rb new file mode 100644 index 0000000..f0f8f83 --- /dev/null +++ b/lib/puppet/parser/functions/any2bool.rb @@ -0,0 +1,55 @@ +# +# any2bool.rb +# + +module Puppet::Parser::Functions + newfunction(:any2bool, :type => :rvalue, :doc => <<-EOS +This converts 'anything' to a boolean. In practise it does the following: + +* Strings such as Y,y,1,T,t,TRUE,yes,'true' will return true +* Strings such as 0,F,f,N,n,FALSE,no,'false' will return false +* Booleans will just return their original value +* Number (or a string representation of a number) > 0 will return true, otherwise false +* undef will return false +* Anything else will return true + EOS + ) do |arguments| + + raise(Puppet::ParseError, "any2bool(): Wrong number of arguments " + + "given (#{arguments.size} for 1)") if arguments.size < 1 + + # If argument is already Boolean, return it + if !!arguments[0] == arguments[0] + return arguments[0] + end + + arg = arguments[0] + + if arg == nil + return false + end + + if arg == :undef + return false + end + + valid_float = !!Float(arg) rescue false + + if arg.is_a?(Numeric) + return function_num2bool( [ arguments[0] ] ) + end + + if arg.is_a?(String) + if valid_float + return function_num2bool( [ arguments[0] ] ) + else + return function_str2bool( [ arguments[0] ] ) + end + end + + return true + + end +end + +# vim: set ts=2 sw=2 et : diff --git a/spec/functions/any2bool_spec.rb b/spec/functions/any2bool_spec.rb new file mode 100755 index 0000000..9d351ce --- /dev/null +++ b/spec/functions/any2bool_spec.rb @@ -0,0 +1,42 @@ +require 'spec_helper' + +describe 'any2bool' 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(true).and_return(true) } + it { is_expected.to run.with_params(false).and_return(false) } + + it { is_expected.to run.with_params('1.5').and_return(true) } + + describe 'when testing stringy values that mean "true"' do + [ 'TRUE','1', 't', 'y', 'true', 'yes'].each do |value| + it { is_expected.to run.with_params(value).and_return(true) } + end + end + + describe 'when testing stringy values that mean "false"' do + [ 'FALSE','', '0', 'f', 'n', 'false', 'no', 'undef', 'undefined', nil, :undef ].each do |value| + it { is_expected.to run.with_params(value).and_return(false) } + end + end + + describe 'when testing numeric values that mean "true"' do + [ 1,'1',1.5, '1.5'].each do |value| + it { is_expected.to run.with_params(value).and_return(true) } + end + end + + describe 'when testing numeric that mean "false"' do + [ -1, '-1', -1.5, '-1.5', '0', 0 ].each do |value| + it { is_expected.to run.with_params(value).and_return(false) } + end + end + + describe 'everything else returns true' do + [ [], {}, ['1'], [1], {:one => 1} ].each do |value| + it { is_expected.to run.with_params(value).and_return(true) } + end + end + +end -- cgit v1.2.3 From 540546b9b41745bbc4821f9966ae301dc0b5056a Mon Sep 17 00:00:00 2001 From: Joseph Yaworski Date: Tue, 12 Apr 2016 16:53:07 -0400 Subject: Use reject instead of delete_if --- README.markdown | 6 +++++- lib/puppet/parser/functions/delete.rb | 16 +++++++++------- spec/functions/delete_spec.rb | 5 +++++ 3 files changed, 19 insertions(+), 8 deletions(-) diff --git a/README.markdown b/README.markdown index 1ef6509..298b852 100644 --- a/README.markdown +++ b/README.markdown @@ -263,7 +263,11 @@ 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 by providing a full regular expression. + +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']. `delete(['ab', 'b'], 'b')` returns ['ab']. + +*Type*: rvalue. #### `delete_at` diff --git a/lib/puppet/parser/functions/delete.rb b/lib/puppet/parser/functions/delete.rb index f548b44..814e1ad 100644 --- a/lib/puppet/parser/functions/delete.rb +++ b/lib/puppet/parser/functions/delete.rb @@ -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 @@ -22,19 +20,23 @@ string, or key from a hash. delete('abracadabra', 'bra') Would return: 'acada' + + delete(['abracadabra'], '^.*bra.*$') + Would return: [] + + delete(['abracadabra'], '^.*jimbob.*$') + Would return: ['abracadabra'] EOS ) do |arguments| - if (arguments.size != 2) then - raise(Puppet::ParseError, "delete(): Wrong number of arguments "+ - "given #{arguments.size} for 2.") - end + raise(Puppet::ParseError, "delete(): Wrong number of arguments "+ + "given #{arguments.size} for 2") unless arguments.size == 2 collection = arguments[0].dup Array(arguments[1]).each do |item| case collection when Array, Hash - collection.delete item + collection.reject! { |coll_item| (coll_item =~ %r{\b#{item}\b}) } when String collection.gsub! item, '' else diff --git a/spec/functions/delete_spec.rb b/spec/functions/delete_spec.rb index cf696ac..fd2a8ad 100755 --- a/spec/functions/delete_spec.rb +++ b/spec/functions/delete_spec.rb @@ -4,6 +4,7 @@ describe 'delete' do it { is_expected.not_to eq(nil) } it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError) } it { is_expected.to run.with_params([]).and_raise_error(Puppet::ParseError) } + it { is_expected.to run.with_params([], 'two') } it { is_expected.to run.with_params([], 'two', 'three').and_raise_error(Puppet::ParseError) } it { is_expected.to run.with_params(1, 'two').and_raise_error(TypeError) } @@ -12,11 +13,15 @@ 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(['ab', 'b', 'c', 'b'], 'b').and_return(['ab', 'c']) } 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'], 'e').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']) } it { is_expected.to run.with_params(['one', 'two', 'three', 'two'], ['one', 'two']).and_return(['three']) } + it { is_expected.to run.with_params(['abracadabra'], 'abr').and_return(['abracadabra']) } + it { is_expected.to run.with_params(['abracadabra'], '^.*jimbob.*$').and_return(['abracadabra']) } end describe 'deleting from a string' do -- cgit v1.2.3 From 8f1efdad22e81c448b2c259e55d3d05a2c0040a2 Mon Sep 17 00:00:00 2001 From: bob Date: Wed, 11 May 2016 10:52:25 +0100 Subject: Add a missing s in the ensure_packages hash example --- README.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.markdown b/README.markdown index 298b852..e4efa9e 100644 --- a/README.markdown +++ b/README.markdown @@ -360,7 +360,7 @@ For Array: For Hash: - ensure_packages({'ksh' => { enure => '20120801-1' } , 'mypackage' => { source => '/tmp/myrpm-1.0.0.x86_64.rpm', provider => "rpm" }}, {'ensure' => 'present'}) + ensure_packages({'ksh' => { ensure => '20120801-1' } , 'mypackage' => { source => '/tmp/myrpm-1.0.0.x86_64.rpm', provider => "rpm" }}, {'ensure' => 'present'}) #### `ensure_resource` -- cgit v1.2.3 From f47df3b4b56c789fe406f23a42aa240d510a1244 Mon Sep 17 00:00:00 2001 From: Stephen Benjamin Date: Wed, 11 May 2016 15:52:50 -0400 Subject: (MODULES-3354) Use 1.8.7 hash in validate_email_address function --- lib/puppet/parser/functions/validate_email_address.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/puppet/parser/functions/validate_email_address.rb b/lib/puppet/parser/functions/validate_email_address.rb index 63f59a7..ddd0d25 100644 --- a/lib/puppet/parser/functions/validate_email_address.rb +++ b/lib/puppet/parser/functions/validate_email_address.rb @@ -1,5 +1,5 @@ module Puppet::Parser::Functions - newfunction(:validate_email_address, doc: <<-ENDHEREDOC + 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: -- cgit v1.2.3 From dd71c0288052dd3a96e730ff198f5c0a8d640946 Mon Sep 17 00:00:00 2001 From: Joseph Yaworski Date: Wed, 11 May 2016 13:21:24 -0400 Subject: Add a delete_regex function To maintain backwards compatibility, add a delete_regex function instead of modifying delete itself. --- README.markdown | 12 +++++-- lib/puppet/parser/functions/delete.rb | 8 +---- lib/puppet/parser/functions/delete_regex.rb | 45 ++++++++++++++++++++++++ spec/functions/delete_regex_spec.rb | 54 +++++++++++++++++++++++++++++ spec/functions/delete_spec.rb | 3 -- 5 files changed, 110 insertions(+), 12 deletions(-) create mode 100644 lib/puppet/parser/functions/delete_regex.rb create mode 100755 spec/functions/delete_regex_spec.rb diff --git a/README.markdown b/README.markdown index 6a64b79..373b08c 100644 --- a/README.markdown +++ b/README.markdown @@ -263,9 +263,9 @@ 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. Arrays and hashes may also match on regular expressions by providing a full regular expression. +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}, `delete(['abf', 'ab', 'ac'], '^ab.*')` returns ['ac']. `delete(['ab', 'b'], 'b')` returns ['ab']. +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(['ab', 'b'], 'b')` returns ['ab']. *Type*: rvalue. @@ -273,6 +273,14 @@ For example, `delete(['a','b','c','b'], 'b')` returns ['a','c']; `delete('abraca Deletes a determined indexed value from an array. For example, `delete_at(['a','b','c'], 1)` returns ['a','c']. *Type*: rvalue. +#### `delete_regex` + +Deletes all instances of a given element from an array or hash that match a provided regular expression. A string will be treated as a one-item array. + +For example, `delete_regex(['a','b','c','b'], 'b')` returns ['a','c']; `delete_regex({'a' => 1,'b' => 2,'c' => 3},['b','c'])` returns {'a'=> 1}, `delete_regex(['abf', 'ab', 'ac'], '^ab.*')` returns ['ac']. `delete_regex(['ab', 'b'], 'b')` returns ['ab']. + +*Type*: rvalue. + #### `delete_values` Deletes all instances of a given value from a hash. For example, `delete_values({'a'=>'A','b'=>'B','c'=>'C','B'=>'D'}, 'B')` returns {'a'=>'A','c'=>'C','B'=>'D'} *Type*: rvalue. diff --git a/lib/puppet/parser/functions/delete.rb b/lib/puppet/parser/functions/delete.rb index 814e1ad..466c55c 100644 --- a/lib/puppet/parser/functions/delete.rb +++ b/lib/puppet/parser/functions/delete.rb @@ -20,12 +20,6 @@ string, or key from a hash. delete('abracadabra', 'bra') Would return: 'acada' - - delete(['abracadabra'], '^.*bra.*$') - Would return: [] - - delete(['abracadabra'], '^.*jimbob.*$') - Would return: ['abracadabra'] EOS ) do |arguments| @@ -36,7 +30,7 @@ string, or key from a hash. Array(arguments[1]).each do |item| case collection when Array, Hash - collection.reject! { |coll_item| (coll_item =~ %r{\b#{item}\b}) } + collection.delete item when String collection.gsub! item, '' else diff --git a/lib/puppet/parser/functions/delete_regex.rb b/lib/puppet/parser/functions/delete_regex.rb new file mode 100644 index 0000000..d72b3e9 --- /dev/null +++ b/lib/puppet/parser/functions/delete_regex.rb @@ -0,0 +1,45 @@ +# +# delete_regex.rb +# + +module Puppet::Parser::Functions + newfunction(:delete_regex, :type => :rvalue, :doc => <<-EOS +deletes all instances of a given element that match a regular expression +from an array or key from a hash. Multiple regular expressions are assumed +to be matched as an OR. + +*Examples:* + + delete_regex(['a','b','c','b'], 'b') + Would return: ['a','c'] + + delete_regex(['a','b','c','b'], ['b', 'c']) + Would return: ['a'] + + delete_regex({'a'=>1,'b'=>2,'c'=>3}, 'b') + Would return: {'a'=>1,'c'=>3} + + delete_regex({'a'=>1,'b'=>2,'c'=>3}, '^a$') + Would return: {'b'=>2,'c'=>3} + + EOS + ) do |arguments| + + raise(Puppet::ParseError, "delete_regex(): Wrong number of arguments "+ + "given #{arguments.size} for 2") unless arguments.size == 2 + + collection = arguments[0].dup + Array(arguments[1]).each do |item| + case collection + when Array, Hash, String + collection.reject! { |coll_item| (coll_item =~ %r{\b#{item}\b}) } + else + raise(TypeError, "delete_regex(): First argument must be an Array, " + + "Hash, or String. Given an argument of class #{collection.class}.") + end + end + collection + end +end + +# vim: set ts=2 sw=2 et : diff --git a/spec/functions/delete_regex_spec.rb b/spec/functions/delete_regex_spec.rb new file mode 100755 index 0000000..f27a946 --- /dev/null +++ b/spec/functions/delete_regex_spec.rb @@ -0,0 +1,54 @@ +require 'spec_helper' + +describe 'delete_regex' do + it { is_expected.not_to eq(nil) } + it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError) } + it { is_expected.to run.with_params([]).and_raise_error(Puppet::ParseError) } + it { is_expected.to run.with_params([], 'two') } + it { is_expected.to run.with_params({}, 'two') } + it { is_expected.to run.with_params([], 'two', 'three').and_raise_error(Puppet::ParseError) } + it { is_expected.to run.with_params([], 'two', 'three', 'four').and_raise_error(Puppet::ParseError) } + it { is_expected.to run.with_params(1, 'two').and_raise_error(TypeError) } + + describe 'deleting from an array' do + it { is_expected.to run.with_params([], '').and_return([]) } + 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(['ab', 'b', 'c', 'b'], 'b').and_return(['ab', 'c']) } + 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'], 'e').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']) } + it { is_expected.to run.with_params(['abracadabra'], 'abr').and_return(['abracadabra']) } + it { is_expected.to run.with_params(['abracadabra'], '^.*jimbob.*$').and_return(['abracadabra']) } + end + + describe 'deleting from an array' 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({}) } + it { is_expected.to run \ + .with_params({'key1' => 'value1', 'key2' => 'value2', 'key3' => 'value3'}, 'key2') \ + .and_return( {'key1' => 'value1', 'key3' => 'value3'}) + } + it { is_expected.to run \ + .with_params({'key1' => 'value1', 'key2' => 'value2', 'key3' => 'value3'}, ['key1', 'key2']) \ + .and_return( {'key3' => 'value3'}) + } + end + + it "should leave the original array intact" do + argument1 = ['one','two','three'] + original1 = argument1.dup + subject.call([argument1,'two']) + expect(argument1).to eq(original1) + end + it "should leave the original hash intact" do + argument1 = {'key1' => 'value1', 'key2' => 'value2', 'key3' => 'value3'} + original1 = argument1.dup + subject.call([argument1,'key2']) + expect(argument1).to eq(original1) + end +end diff --git a/spec/functions/delete_spec.rb b/spec/functions/delete_spec.rb index fd2a8ad..b44accf 100755 --- a/spec/functions/delete_spec.rb +++ b/spec/functions/delete_spec.rb @@ -13,15 +13,12 @@ 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(['ab', 'b', 'c', 'b'], 'b').and_return(['ab', 'c']) } 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'], 'e').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']) } it { is_expected.to run.with_params(['one', 'two', 'three', 'two'], ['one', 'two']).and_return(['three']) } - it { is_expected.to run.with_params(['abracadabra'], 'abr').and_return(['abracadabra']) } - it { is_expected.to run.with_params(['abracadabra'], '^.*jimbob.*$').and_return(['abracadabra']) } end describe 'deleting from a string' do -- cgit v1.2.3 From 098e82e694704222200d42f2dd4b50ca6d9999fa Mon Sep 17 00:00:00 2001 From: tphoney Date: Tue, 28 Jun 2016 16:36:03 +0100 Subject: {maint} modulesync changes for puppet-lint 2.0.0 --- CONTRIBUTING.md | 6 ++---- Rakefile | 4 ++-- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index bfeaa70..3c3f1e7 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -208,11 +208,9 @@ review. Additional Resources ==================== -* [Getting additional help](http://puppetlabs.com/community/get-help) +* [Getting additional help](http://puppet.com/community/get-help) -* [Writing tests](http://projects.puppetlabs.com/projects/puppet/wiki/Development_Writing_Tests) - -* [Patchwork](https://patchwork.puppetlabs.com) +* [Writing tests](https://docs.puppet.com/guides/module_guides/bgtm.html#step-three-module-testing) * [General GitHub documentation](http://help.github.com/) diff --git a/Rakefile b/Rakefile index 7e9a13d..3b07e4d 100644 --- a/Rakefile +++ b/Rakefile @@ -4,11 +4,11 @@ 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_char_check') 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"] +PuppetLint.configuration.ignore_paths = ["spec/**/*.pp", "pkg/**/*.pp", "bundle/**/*", "vendor/**/*"] desc 'Generate pooler nodesets' task :gen_nodeset do -- cgit v1.2.3 From 7b1250478c513a3c02c463ec7cdd62d427957400 Mon Sep 17 00:00:00 2001 From: Bryan Jen Date: Tue, 28 Jun 2016 16:45:56 -0700 Subject: (MODULES-3507) Updates file_line path validation --- lib/puppet/type/file_line.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/puppet/type/file_line.rb b/lib/puppet/type/file_line.rb index f2c6937..a02b514 100644 --- a/lib/puppet/type/file_line.rb +++ b/lib/puppet/type/file_line.rb @@ -93,8 +93,8 @@ Puppet::Type.newtype(:file_line) do newparam(:path) do desc 'The file Puppet will ensure contains the line specified by the line parameter.' validate do |value| - unless (Puppet.features.posix? and value =~ /^\//) or (Puppet.features.microsoft_windows? and (value =~ /^.:\// or value =~ /^\/\/[^\/]+\/[^\/]+/)) - raise(Puppet::Error, "File paths must be fully qualified, not '#{value}'") + unless Puppet::Util.absolute_path?(value) + raise Puppet::Error, "File paths must be fully qualified, not '#{value}'" end end end -- cgit v1.2.3 From d401d7f252effa259b976eb30a3effd6d3600a6d Mon Sep 17 00:00:00 2001 From: tphoney Date: Wed, 29 Jun 2016 10:42:31 +0100 Subject: {maint} modulesync 0794b2c --- Rakefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Rakefile b/Rakefile index 3b07e4d..8906d23 100644 --- a/Rakefile +++ b/Rakefile @@ -4,7 +4,7 @@ require 'puppetlabs_spec_helper/rake_tasks' PuppetLint.configuration.fail_on_warnings = true PuppetLint.configuration.send('relative') -PuppetLint.configuration.send('disable_char_check') +PuppetLint.configuration.send('disable_140chars') PuppetLint.configuration.send('disable_class_inherits_from_params_class') PuppetLint.configuration.send('disable_documentation') PuppetLint.configuration.send('disable_single_quote_string_with_variables') -- cgit v1.2.3 From af875b11ff284cfe2ea95d208a614576a4342b2c Mon Sep 17 00:00:00 2001 From: David Schmitt Date: Wed, 29 Jun 2016 21:33:00 +0100 Subject: (MODULES-3543) Fix define_with_params to handle undef properly As described in PUP-6422, ensure_resources('File[/tmp/a]', { owner => undef }) would not actually create the file. This fixes it, and adds tests to prove it. --- lib/puppet/parser/functions/defined_with_params.rb | 2 +- spec/functions/defined_with_params_spec.rb | 9 +++++++++ spec/functions/ensure_resource_spec.rb | 7 +++++++ 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/lib/puppet/parser/functions/defined_with_params.rb b/lib/puppet/parser/functions/defined_with_params.rb index d7df306..ffc7241 100644 --- a/lib/puppet/parser/functions/defined_with_params.rb +++ b/lib/puppet/parser/functions/defined_with_params.rb @@ -26,7 +26,7 @@ ENDOFDOC ret = false if resource = findresource(reference.to_s) matches = params.collect do |key, value| - resource[key] == value + resource[key] == (value.eql?(:undef) ? nil : value) # eql? avoids bugs caused by monkeypatching in puppet end ret = params.empty? || !matches.include?(false) end diff --git a/spec/functions/defined_with_params_spec.rb b/spec/functions/defined_with_params_spec.rb index 516d986..e00c423 100755 --- a/spec/functions/defined_with_params_spec.rb +++ b/spec/functions/defined_with_params_spec.rb @@ -23,4 +23,13 @@ describe 'defined_with_params' do it { is_expected.to run.with_params('User[dan]', {'ensure' => 'present', 'managehome' => false}).and_return(true) } it { is_expected.to run.with_params('User[dan]', {'ensure' => 'absent', 'managehome' => false}).and_return(false) } end + + describe 'when passing undef values' do + let :pre_condition do + 'file { "/tmp/a": }' + end + + it { is_expected.to run.with_params('File[/tmp/a]', {}).and_return(true) } + it { is_expected.to run.with_params('File[/tmp/a]', { 'owner' => :undef }).and_return(true) } + end end diff --git a/spec/functions/ensure_resource_spec.rb b/spec/functions/ensure_resource_spec.rb index c4f2cbd..57b5123 100755 --- a/spec/functions/ensure_resource_spec.rb +++ b/spec/functions/ensure_resource_spec.rb @@ -28,6 +28,13 @@ describe 'ensure_resource' do it { expect(lambda { catalogue }).to contain_user('username2').without_ensure } end + describe 'after running ensure_resource("user", "username1", { "gid" => undef })' do + before { subject.call(['User', 'username1', { "gid" => :undef }]) } + + # this lambda is required due to strangeness within rspec-puppet's expectation handling + it { expect(lambda { catalogue }).to contain_user('username1').with_ensure('present') } + end + describe 'after running ensure_resource("user", ["username1", "username2"], {})' do before { subject.call(['User', ['username1', 'username2'], {}]) } -- cgit v1.2.3 From 3f86e3a731b9e1be943a55fa12bd5e32716a20ef Mon Sep 17 00:00:00 2001 From: David Schmitt Date: Thu, 30 Jun 2016 11:06:56 +0100 Subject: (MODULES-3543) Fixup defined_with_params to work on all puppet versions --- lib/puppet/parser/functions/defined_with_params.rb | 5 +++- spec/functions/defined_with_params_spec.rb | 4 +-- spec/functions/ensure_resource_spec.rb | 30 ++++++++++++++++++++-- 3 files changed, 34 insertions(+), 5 deletions(-) diff --git a/lib/puppet/parser/functions/defined_with_params.rb b/lib/puppet/parser/functions/defined_with_params.rb index ffc7241..99687ae 100644 --- a/lib/puppet/parser/functions/defined_with_params.rb +++ b/lib/puppet/parser/functions/defined_with_params.rb @@ -26,7 +26,10 @@ ENDOFDOC ret = false if resource = findresource(reference.to_s) matches = params.collect do |key, value| - resource[key] == (value.eql?(:undef) ? nil : value) # eql? avoids bugs caused by monkeypatching in puppet + # eql? avoids bugs caused by monkeypatching in puppet + resource_is_undef = resource[key].eql?(:undef) || resource[key].nil? + value_is_undef = value.eql?(:undef) || value.nil? + (resource_is_undef && value_is_undef) || (resource[key] == value) end ret = params.empty? || !matches.include?(false) end diff --git a/spec/functions/defined_with_params_spec.rb b/spec/functions/defined_with_params_spec.rb index e00c423..e2f3abe 100755 --- a/spec/functions/defined_with_params_spec.rb +++ b/spec/functions/defined_with_params_spec.rb @@ -26,10 +26,10 @@ describe 'defined_with_params' do describe 'when passing undef values' do let :pre_condition do - 'file { "/tmp/a": }' + 'file { "/tmp/a": ensure => present }' end it { is_expected.to run.with_params('File[/tmp/a]', {}).and_return(true) } - it { is_expected.to run.with_params('File[/tmp/a]', { 'owner' => :undef }).and_return(true) } + it { is_expected.to run.with_params('File[/tmp/a]', { 'ensure' => 'present', 'owner' => :undef }).and_return(true) } end end diff --git a/spec/functions/ensure_resource_spec.rb b/spec/functions/ensure_resource_spec.rb index 57b5123..9a17f5b 100755 --- a/spec/functions/ensure_resource_spec.rb +++ b/spec/functions/ensure_resource_spec.rb @@ -10,6 +10,32 @@ describe 'ensure_resource' do is_expected.to run.with_params(1,2,3).and_raise_error(Puppet::ParseError) } + context 'given an empty catalog' do + describe 'after running ensure_resource("user", "username1", {})' do + before { subject.call(['User', 'username1', {}]) } + + # this lambda is required due to strangeness within rspec-puppet's expectation handling + it { expect(lambda { catalogue }).to contain_user('username1').without_ensure } + end + + describe 'after running ensure_resource("user", "username1", { gid => undef })' do + before { subject.call(['User', 'username1', { 'gid' => :undef }]) } + + # this lambda is required due to strangeness within rspec-puppet's expectation handling + it { expect(lambda { catalogue }).to contain_user('username1').without_ensure } + it { expect(lambda { catalogue }).to contain_user('username1').without_gid } + end + + describe 'after running ensure_resource("user", "username1", { ensure => present, gid => undef })' do + before { subject.call(['User', 'username1', { 'ensure' => 'present', 'gid' => :undef }]) } + + # this lambda is required due to strangeness within rspec-puppet's expectation handling + it { expect(lambda { catalogue }).to contain_user('username1').with_ensure('present') } + it { expect(lambda { catalogue }).to contain_user('username1').without_gid } + end + + end + context 'given a catalog with "user { username1: ensure => present }"' do let(:pre_condition) { 'user { username1: ensure => present }' } @@ -28,8 +54,8 @@ describe 'ensure_resource' do it { expect(lambda { catalogue }).to contain_user('username2').without_ensure } end - describe 'after running ensure_resource("user", "username1", { "gid" => undef })' do - before { subject.call(['User', 'username1', { "gid" => :undef }]) } + describe 'after running ensure_resource("user", "username1", { gid => undef })' do + before { subject.call(['User', 'username1', { 'gid' => :undef }]) } # this lambda is required due to strangeness within rspec-puppet's expectation handling it { expect(lambda { catalogue }).to contain_user('username1').with_ensure('present') } -- cgit v1.2.3 From 5c51463c1f9e89bfd012c737c19581ac0f771926 Mon Sep 17 00:00:00 2001 From: David Schmitt Date: Thu, 30 Jun 2016 17:52:45 +0100 Subject: Fix load_module_metadata and loadjson tests to pass with fully deployed module When replacing the lib/ and manifests/ symlinks in the fixtures with a proper top-level symlink, puppet 4 starts loading the metadata.json before loading functions, which confuses these tests. Added more specific expectations, and provide data for that call. --- spec/functions/load_module_metadata_spec.rb | 43 ++++++++++-------- spec/functions/loadjson_spec.rb | 67 +++++++++++++++++------------ 2 files changed, 65 insertions(+), 45 deletions(-) diff --git a/spec/functions/load_module_metadata_spec.rb b/spec/functions/load_module_metadata_spec.rb index fe665fb..1a61e2c 100755 --- a/spec/functions/load_module_metadata_spec.rb +++ b/spec/functions/load_module_metadata_spec.rb @@ -5,25 +5,34 @@ describe 'load_module_metadata' do it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } it { is_expected.to run.with_params("one", "two", "three").and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } - it "should json parse the file" do - allow(scope).to receive(:function_get_module_path).with(['science']).and_return('/path/to/module/') - allow(File).to receive(:exists?).with(/metadata.json/).and_return(true) - allow(File).to receive(:read).with(/metadata.json/).and_return('{"name": "spencer-science"}') + describe "when calling with valid arguments" do + before :each do + if RSpec.configuration.puppet_future + allow(File).to receive(:read).with(/\/stdlib\/metadata.json/, {:encoding=>"utf-8"}).and_return('{"name": "puppetlabs-stdlib"}') + else + allow(File).to receive(:read).with(/\/stdlib\/metadata.json/).and_return('{"name": "puppetlabs-stdlib"}') + end + end + it "should json parse the file" do + allow(scope).to receive(:function_get_module_path).with(['science']).and_return('/path/to/module/') + allow(File).to receive(:exists?).with('/path/to/module/metadata.json').and_return(true) + allow(File).to receive(:read).with('/path/to/module/metadata.json').and_return('{"name": "spencer-science"}') - result = subject.call(['science']) - expect(result['name']).to eq('spencer-science') - end + result = subject.call(['science']) + expect(result['name']).to eq('spencer-science') + end - it "should fail by default if there is no metadata.json" do - allow(scope).to receive(:function_get_module_path).with(['science']).and_return('/path/to/module/') - allow(File).to receive(:exists?).with(/metadata.json/).and_return(false) - expect {subject.call(['science'])}.to raise_error(Puppet::ParseError) - end + it "should fail by default if there is no metadata.json" do + allow(scope).to receive(:function_get_module_path).with(['science']).and_return('/path/to/module/') + allow(File).to receive(:exists?).with('/path/to/module/metadata.json').and_return(false) + expect {subject.call(['science'])}.to raise_error(Puppet::ParseError) + end - it "should return nil if user allows empty metadata.json" do - allow(scope).to receive(:function_get_module_path).with(['science']).and_return('/path/to/module/') - allow(File).to receive(:exists?).with(/metadata.json/).and_return(false) - result = subject.call(['science', true]) - expect(result).to eq({}) + it "should return nil if user allows empty metadata.json" do + allow(scope).to receive(:function_get_module_path).with(['science']).and_return('/path/to/module/') + allow(File).to receive(:exists?).with('/path/to/module/metadata.json').and_return(false) + result = subject.call(['science', true]) + expect(result).to eq({}) + end end end diff --git a/spec/functions/loadjson_spec.rb b/spec/functions/loadjson_spec.rb index 12a9b82..a00dff9 100644 --- a/spec/functions/loadjson_spec.rb +++ b/spec/functions/loadjson_spec.rb @@ -4,35 +4,46 @@ describe 'loadjson' do it { is_expected.not_to eq(nil) } it { is_expected.to run.with_params().and_raise_error(ArgumentError, /wrong number of arguments/i) } - context 'when a non-existing file is specified' do - let(:filename) { '/tmp/doesnotexist' } - before { - File.expects(:exists?).with(filename).returns(false).once - PSON.expects(:load).never - } - it { is_expected.to run.with_params(filename, {'default' => 'value'}).and_return({'default' => 'value'}) } - end + describe "when calling with valid arguments" do + before :each do + if RSpec.configuration.puppet_future + allow(File).to receive(:read).with(/\/stdlib\/metadata.json/, {:encoding=>"utf-8"}).and_return('{"name": "puppetlabs-stdlib"}') + else + allow(File).to receive(:read).with(/\/stdlib\/metadata.json/).and_return('{"name": "puppetlabs-stdlib"}') + end + end - context 'when an existing file is specified' do - let(:filename) { '/tmp/doesexist' } - let(:data) { { 'key' => 'value' } } - let(:json) { '{"key":"value"}' } - before { - File.expects(:exists?).with(filename).returns(true).once - File.expects(:read).with(filename).returns(json).once - PSON.expects(:load).with(json).returns(data).once - } - it { is_expected.to run.with_params(filename).and_return(data) } - end + context 'when a non-existing file is specified' do + let(:filename) { '/tmp/doesnotexist' } + before { + allow(File).to receive(:exists?).with(filename).and_return(false).once + allow(PSON).to receive(:load).never + } + it { is_expected.to run.with_params(filename, {'default' => 'value'}).and_return({'default' => 'value'}) } + end + + context 'when an existing file is specified' do + let(:filename) { '/tmp/doesexist' } + let(:data) { { 'key' => 'value' } } + let(:json) { '{"key":"value"}' } + before { + allow(File).to receive(:exists?).with(filename).and_return(true).once + allow(File).to receive(:read).with(filename).and_return(json).once + allow(File).to receive(:read).with(filename).and_return(json).once + allow(PSON).to receive(:load).with(json).and_return(data).once + } + it { is_expected.to run.with_params(filename).and_return(data) } + end - context 'when the file could not be parsed' do - let(:filename) { '/tmp/doesexist' } - let(:json) { '{"key":"value"}' } - before { - File.expects(:exists?).with(filename).returns(true).once - File.expects(:read).with(filename).returns(json).once - PSON.stubs(:load).with(json).once.raises StandardError, 'Something terrible have happened!' - } - it { is_expected.to run.with_params(filename, {'default' => 'value'}).and_return({'default' => 'value'}) } + context 'when the file could not be parsed' do + let(:filename) { '/tmp/doesexist' } + let(:json) { '{"key":"value"}' } + before { + allow(File).to receive(:exists?).with(filename).and_return(true).once + allow(File).to receive(:read).with(filename).and_return(json).once + allow(PSON).to receive(:load).with(json).once.and_raise StandardError, 'Something terrible have happened!' + } + it { is_expected.to run.with_params(filename, {'default' => 'value'}).and_return({'default' => 'value'}) } + end end end -- cgit v1.2.3 From daa80f168f8c334b8ff220338691f3c765f162d9 Mon Sep 17 00:00:00 2001 From: David Schmitt Date: Thu, 30 Jun 2016 17:52:45 +0100 Subject: (MODULES-3435) Fix gitignore and fixtures directory This change more accurately reflects what is being ignored and what's required as fixtures. --- .gitignore | 4 +++- spec/fixtures/modules/stdlib/lib | 1 - spec/fixtures/modules/stdlib/manifests | 1 - 3 files changed, 3 insertions(+), 3 deletions(-) delete mode 120000 spec/fixtures/modules/stdlib/lib delete mode 120000 spec/fixtures/modules/stdlib/manifests diff --git a/.gitignore b/.gitignore index dd126f2..cf4e9c6 100644 --- a/.gitignore +++ b/.gitignore @@ -2,10 +2,12 @@ pkg/ Gemfile.lock vendor/ -spec/fixtures/ +spec/fixtures/manifests/site.pp +spec/fixtures/modules/* .vagrant/ .bundle/ coverage/ log/ .idea/ *.iml +tmp/ diff --git a/spec/fixtures/modules/stdlib/lib b/spec/fixtures/modules/stdlib/lib deleted file mode 120000 index b6ce6cc..0000000 --- a/spec/fixtures/modules/stdlib/lib +++ /dev/null @@ -1 +0,0 @@ -../../../../lib/ \ No newline at end of file diff --git a/spec/fixtures/modules/stdlib/manifests b/spec/fixtures/modules/stdlib/manifests deleted file mode 120000 index cdcdae0..0000000 --- a/spec/fixtures/modules/stdlib/manifests +++ /dev/null @@ -1 +0,0 @@ -../../../../manifests/ \ No newline at end of file -- cgit v1.2.3 From be70aeba33ab3ae180a93b3189747c3cfd0fce8e Mon Sep 17 00:00:00 2001 From: David Schmitt Date: Fri, 8 Jul 2016 13:17:20 +0100 Subject: (MODULES-3581) modulesync [067d08a] --- .gitignore | 7 ++++--- .sync.yml | 7 +++++++ Gemfile | 3 ++- 3 files changed, 13 insertions(+), 4 deletions(-) create mode 100644 .sync.yml diff --git a/.gitignore b/.gitignore index cf4e9c6..95f271b 100644 --- a/.gitignore +++ b/.gitignore @@ -2,12 +2,13 @@ pkg/ Gemfile.lock vendor/ -spec/fixtures/manifests/site.pp -spec/fixtures/modules/* +spec/fixtures/ .vagrant/ .bundle/ coverage/ log/ .idea/ *.iml -tmp/ +!spec/fixtures/ +spec/fixtures/manifests/site.pp +spec/fixtures/modules/* diff --git a/.sync.yml b/.sync.yml new file mode 100644 index 0000000..431b9d1 --- /dev/null +++ b/.sync.yml @@ -0,0 +1,7 @@ +--- +.gitignore: + paths: + - '!spec/fixtures/' + - 'spec/fixtures/manifests/site.pp' + - 'spec/fixtures/modules/*' + diff --git a/Gemfile b/Gemfile index e490bc9..9b5b214 100644 --- a/Gemfile +++ b/Gemfile @@ -16,10 +16,11 @@ group :development, :unit_tests do 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 + gem 'puppet-blacksmith', :require => false + gem 'rest-client', '~> 1.8.0', :require => false end group :system_tests do gem 'beaker-rspec', *location_for(ENV['BEAKER_RSPEC_VERSION'] || '>= 3.4') -- cgit v1.2.3 From a2f980d44d6703561769c5e0ef25a7f531417643 Mon Sep 17 00:00:00 2001 From: Nate Potter Date: Thu, 7 Jul 2016 21:10:22 -0700 Subject: (MODULES-3568) Move dig to dig44 and deprecate dig A new version of dig was introduced in Puppet 4.5.0 that isn't compatible with the stdlib version of dig. To maintain backwards compatibility and ensure that tests for stdlib aren't broken, this patch renames dig to dig44 and adds a deprecation warning to the stdlib dig function. --- README.markdown | 38 ++++++++++++++++++++++++ lib/puppet/parser/functions/dig.rb | 50 ++++---------------------------- lib/puppet/parser/functions/dig44.rb | 56 ++++++++++++++++++++++++++++++++++++ spec/functions/dig44_spec.rb | 44 ++++++++++++++++++++++++++++ spec/functions/dig_spec.rb | 16 +++++------ 5 files changed, 152 insertions(+), 52 deletions(-) create mode 100644 lib/puppet/parser/functions/dig44.rb create mode 100644 spec/functions/dig44_spec.rb diff --git a/README.markdown b/README.markdown index 373b08c..1368b2f 100644 --- a/README.markdown +++ b/README.markdown @@ -295,6 +295,8 @@ Returns the difference between two arrays. The returned array is a copy of the o #### `dig` +DEPRECATED: This function has been replaced in Puppet 4.5.0, use dig44() for backwards compatibility or use the new version. + *Type*: rvalue. Retrieves a value within multiple layers of hashes and arrays via an array of keys containing a path. The function goes through the structure by each path component and tries to return the value at the end of the path. @@ -324,6 +326,42 @@ $value = dig($data, ['a', 'b', 'c', 'd'], 'not_found') # $value = 'not_found' ~~~ +1. **$data** The data structure we are working with. +2. **['a', 'b', 2]** The path array. +3. **'not_found'** The default value. It will be returned if nothing is found. + (optional, defaults to *undef*) + +#### `dig44` + +*Type*: rvalue. + +Retrieves a value within multiple layers of hashes and arrays via an array of keys containing a path. The function goes through the structure by each path component and tries to return the value at the end of the path. + +In addition to the required path argument, the function accepts the default argument. It is returned if the path is not correct, if no value was found, or if any other error has occurred. + +~~~ruby +$data = { + 'a' => { + 'b' => [ + 'b1', + 'b2', + 'b3', + ] + } +} + +$value = dig44($data, ['a', 'b', 2]) +# $value = 'b3' + +# with all possible options +$value = dig44($data, ['a', 'b', 2], 'not_found') +# $value = 'b3' + +# using the default value +$value = dig44($data, ['a', 'b', 'c', 'd'], 'not_found') +# $value = 'not_found' +~~~ + 1. **$data** The data structure we are working with. 2. **['a', 'b', 2]** The path array. 3. **'not_found'** The default value. It will be returned if nothing is found. diff --git a/lib/puppet/parser/functions/dig.rb b/lib/puppet/parser/functions/dig.rb index a9aa770..34fa701 100644 --- a/lib/puppet/parser/functions/dig.rb +++ b/lib/puppet/parser/functions/dig.rb @@ -4,51 +4,13 @@ module Puppet::Parser::Functions newfunction(:dig, :type => :rvalue, :doc => <<-EOS -Looks up into a complex structure of arrays and hashes and returns nil -or the default value if nothing was found. - -Path is an array of keys to be looked up in data argument. The function -will go down the structure and try to extract the required value. - -$data = { - 'a' => { - 'b' => [ - 'b1', - 'b2', - 'b3' ]}} - -$value = dig($data, ['a', 'b', '2'], 'not_found') -=> $value = 'b3' - -a -> first hash key -b -> second hash key -2 -> array index starting with 0 - -not_found -> (optional) will be returned if there is no value or the path -did not match. Defaults to nil. - -In addition to the required "path" argument, "dig" accepts default -argument. It will be returned if no value was found or a path component is -missing. And the fourth argument can set a variable path separator. + DEPRECATED: This function has been replaced in Puppet 4.5.0, please use dig44() for backwards compatibility or use the new version. EOS - ) do |arguments| - # Two arguments are required - raise(Puppet::ParseError, "dig(): Wrong number of arguments " + - "given (#{arguments.size} for at least 2)") if arguments.size < 2 - - data, path, default = *arguments - - if !(data.is_a?(Hash) || data.is_a?(Array)) - raise(Puppet::ParseError, "dig(): first argument must be a hash or an array, " << - "given #{data.class.name}") + ) do |arguments| + warning("dig() DEPRECATED: This function has been replaced in Puppet 4.5.0, please use dig44() for backwards compatibility or use the new version.") + if ! Puppet::Parser::Functions.autoloader.loaded?(:dig44) + Puppet::Parser::Functions.autoloader.load(:dig44) end - - unless path.is_a? Array - raise(Puppet::ParseError, "dig(): second argument must be an array, " << - "given #{path.class.name}") - end - - value = path.reduce(data) { |h, k| (h.is_a?(Hash) || h.is_a?(Array)) ? h[k] : break } - value.nil? ? default : value + function_dig44(arguments) end end diff --git a/lib/puppet/parser/functions/dig44.rb b/lib/puppet/parser/functions/dig44.rb new file mode 100644 index 0000000..a7de363 --- /dev/null +++ b/lib/puppet/parser/functions/dig44.rb @@ -0,0 +1,56 @@ +# +# dig44.rb +# + +module Puppet::Parser::Functions + newfunction(:dig44, :type => :rvalue, :doc => <<-EOS +DEPRECATED: This function has been replaced in puppet 4.5.0. + +Looks up into a complex structure of arrays and hashes and returns nil +or the default value if nothing was found. + +Path is an array of keys to be looked up in data argument. The function +will go down the structure and try to extract the required value. + +$data = { + 'a' => { + 'b' => [ + 'b1', + 'b2', + 'b3' ]}} + +$value = dig44($data, ['a', 'b', '2'], 'not_found') +=> $value = 'b3' + +a -> first hash key +b -> second hash key +2 -> array index starting with 0 + +not_found -> (optional) will be returned if there is no value or the path +did not match. Defaults to nil. + +In addition to the required "path" argument, "dig44" accepts default +argument. It will be returned if no value was found or a path component is +missing. And the fourth argument can set a variable path separator. + EOS + ) do |arguments| + # Two arguments are required + raise(Puppet::ParseError, "dig44(): Wrong number of arguments " + + "given (#{arguments.size} for at least 2)") if arguments.size < 2 + + data, path, default = *arguments + + if !(data.is_a?(Hash) || data.is_a?(Array)) + raise(Puppet::ParseError, "dig44(): first argument must be a hash or an array, " << + "given #{data.class.name}") + end + + unless path.is_a? Array + raise(Puppet::ParseError, "dig44(): second argument must be an array, " << + "given #{path.class.name}") + end + + value = path.reduce(data) { |h, k| (h.is_a?(Hash) || h.is_a?(Array)) ? h[k] : break } + value.nil? ? default : value + end +end diff --git a/spec/functions/dig44_spec.rb b/spec/functions/dig44_spec.rb new file mode 100644 index 0000000..fd451ff --- /dev/null +++ b/spec/functions/dig44_spec.rb @@ -0,0 +1,44 @@ +require 'spec_helper' + +describe 'dig44' do + it "should exist" do + expect(Puppet::Parser::Functions.function("dig44")).to eq("function_dig44") + end + + it "should raise a ParseError if there are less than 2 arguments" do + expect { scope.function_dig44([]) }.to raise_error(Puppet::ParseError) + end + + it "should raise a ParseError if the first argument isn't a hash or array" do + expect { scope.function_dig44(['bad', []]) }.to raise_error(Puppet::ParseError) + end + + it "should raise a ParseError if the second argument isn't an array" do + expect { scope.function_dig44([{}, 'bad']) }.to raise_error(Puppet::ParseError) + end + + it "should return an empty hash when given empty parameters" do + result = scope.function_dig44([{}, []]) + expect(result).to(eq({})) + end + + it "should return value when given simple hash" do + result = scope.function_dig44([{"a" => "b"}, ["a"]]) + expect(result).to(eq("b")) + end + + it "should find hash values two levels deep" do + result = scope.function_dig44([{"a" => {"b" => "c"}}, ["a", "b"]]) + expect(result).to(eq("c")) + end + + it "should return default value if nothing was found" do + result = scope.function_dig44([{}, ["a", "b"], "d"]) + expect(result).to(eq("d")) + end + + it "should work on booleans as well as strings" do + result = scope.function_dig44([{"a" => false}, ["a"]]) + expect(result).to(eq(false)) + end +end diff --git a/spec/functions/dig_spec.rb b/spec/functions/dig_spec.rb index 1c5d49d..ad16fdd 100644 --- a/spec/functions/dig_spec.rb +++ b/spec/functions/dig_spec.rb @@ -1,13 +1,13 @@ require 'spec_helper' describe 'dig' do - it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError) } - it { is_expected.to run.with_params('bad', []).and_raise_error(Puppet::ParseError) } - it { is_expected.to run.with_params({}, 'bad').and_raise_error(Puppet::ParseError) } - it { is_expected.to run.with_params({}, []).and_return({}) } - it { is_expected.to run.with_params({"a" => "b"}, ["a"]).and_return("b") } - it { is_expected.to run.with_params({"a" => {"b" => "c"}}, ["a", "b"]).and_return("c") } - it { is_expected.to run.with_params({}, ["a", "b"], "d").and_return("d") } - it { is_expected.to run.with_params({"a" => false}, ["a"]).and_return(false) } + it "should exist" do + expect(Puppet::Parser::Functions.function("dig")).to eq("function_dig") + end + + it "should give a deprecation warning when called" do + scope.expects(:warning).with("dig() DEPRECATED: This function has been replaced in Puppet 4.5.0, please use dig44() for backwards compatibility or use the new version.") + scope.function_dig([{}, []]) + end end -- cgit v1.2.3 From 72d23659513517389880ba13663a1d6380d538ca Mon Sep 17 00:00:00 2001 From: tphoney Date: Tue, 5 Jul 2016 09:56:42 +0100 Subject: (MODULES-3529)add deprecation function --- README.markdown | 4 ++ lib/puppet/functions/deprecation.rb | 21 +++++++++++ spec/acceptance/deprecation_spec.rb | 75 +++++++++++++++++++++++++++++++++++++ spec/functions/deprecation_spec.rb | 51 +++++++++++++++++++++++++ 4 files changed, 151 insertions(+) create mode 100644 lib/puppet/functions/deprecation.rb create mode 100644 spec/acceptance/deprecation_spec.rb create mode 100644 spec/functions/deprecation_spec.rb diff --git a/README.markdown b/README.markdown index 373b08c..8252ab5 100644 --- a/README.markdown +++ b/README.markdown @@ -289,6 +289,10 @@ Deletes all instances of a given value from a hash. For example, `delete_values( Deletes all instances of the undef value from an array or hash. For example, `$hash = delete_undef_values({a=>'A', b=>'', c=>undef, d => false})` returns {a => 'A', b => '', d => false}. *Type*: rvalue. +#### `deprecation` + +Function to print deprecation warnings, Logs a warning once for a given key. The uniqueness key - can appear once. The msg is the message text including any positional information that is formatted by the user/caller of the method It is affected by the puppet setting 'strict', which can be set to :error (outputs as an error message), :off (no message / error is displayed) and :warning (default, outputs a warning) *Type*: String, String. + #### `difference` Returns the difference between two arrays. The returned array is a copy of the original array, removing any items that also appear in the second array. For example, `difference(["a","b","c"],["b","c","d"])` returns ["a"]. *Type*: rvalue. diff --git a/lib/puppet/functions/deprecation.rb b/lib/puppet/functions/deprecation.rb new file mode 100644 index 0000000..3b84ae5 --- /dev/null +++ b/lib/puppet/functions/deprecation.rb @@ -0,0 +1,21 @@ +# Function to print deprecation warnings, Logs a warning once for a given key. The uniqueness key - can appear once. The msg is the message text including any positional information that is formatted by the user/caller of the method It is affected by the puppet setting 'strict', which can be set to :error (outputs as an error message), :off (no message / error is displayed) and :warning (default, outputs a warning) *Type*: String, String. +# + +Puppet::Functions.create_function(:deprecation) do + dispatch :deprecation do + param 'String', :key + param 'String', :message + end + + def deprecation(key, message) + # depending on configuration setting of strict + case Puppet.settings[:strict] + when :off + # do nothing + when :error + fail("deprecation. #{key}. #{message}") + else + Puppet.warn_once('deprecation', key, message) + end + end +end diff --git a/spec/acceptance/deprecation_spec.rb b/spec/acceptance/deprecation_spec.rb new file mode 100644 index 0000000..d0d7fed --- /dev/null +++ b/spec/acceptance/deprecation_spec.rb @@ -0,0 +1,75 @@ +#! /usr/bin/env ruby -S rspec +require 'spec_helper_acceptance' +require 'shellwords' + +describe 'deprecation function' do + before :each do + FileUtils.rm_rf '/tmp/deprecation' + end + + context 'with --strict=error', if: get_puppet_version =~ /^4/ do + before :all do + pp = <<-EOS + deprecation('key', 'message') + file { '/tmp/deprecation': ensure => present } + EOS + @result = on(default, puppet('apply', '--strict=error', '-e', Shellwords.shellescape(pp)), acceptable_exit_codes: (0...256)) + end + + it "should return an error" do + expect(@result.exit_code).to eq(1) + end + + it "should show the error message" do + expect(@result.stderr).to match(/deprecation. key. message/) + end + + describe file('/tmp/deprecation') do + it { is_expected.not_to exist } + end + end + + context 'with --strict=warning', if: get_puppet_version =~ /^4/ do + before :all do + pp = <<-EOS + deprecation('key', 'message') + file { '/tmp/deprecation': ensure => present } + EOS + @result = on(default, puppet('apply', '--strict=warning', '-e', Shellwords.shellescape(pp)), acceptable_exit_codes: (0...256)) + end + + it "should not return an error" do + expect(@result.exit_code).to eq(0) + end + + it "should show the error message" do + expect(@result.stderr).to match(/Warning: message/) + end + + describe file('/tmp/deprecation') do + it { is_expected.to exist } + end + end + + context 'with --strict=off', if: get_puppet_version =~ /^4/ do + before :all do + pp = <<-EOS + deprecation('key', 'message') + file { '/tmp/deprecation': ensure => present } + EOS + @result = on(default, puppet('apply', '--strict=off', '-e', Shellwords.shellescape(pp)), acceptable_exit_codes: (0...256)) + end + + it "should not return an error" do + expect(@result.exit_code).to eq(0) + end + + it "should not show the error message" do + expect(@result.stderr).not_to match(/Warning: message/) + end + + describe file('/tmp/deprecation') do + it { is_expected.to exist } + end + end +end diff --git a/spec/functions/deprecation_spec.rb b/spec/functions/deprecation_spec.rb new file mode 100644 index 0000000..bbabe48 --- /dev/null +++ b/spec/functions/deprecation_spec.rb @@ -0,0 +1,51 @@ +require 'spec_helper' + +if ENV["FUTURE_PARSER"] == 'yes' + describe 'deprecation' do + pending 'teach rspec-puppet to load future-only functions under 3.7.5' do + it { is_expected.not_to eq(nil) } + end + end +end + +if Puppet.version.to_f >= 4.0 + describe 'deprecation' do + before(:each) { + # this is to reset the strict variable to default + Puppet.settings[:strict] = :warning + } + + it { is_expected.not_to eq(nil) } + it { is_expected.to run.with_params().and_raise_error(ArgumentError) } + + it 'should display a single warning' do + Puppet.expects(:warning).with(includes('heelo')) + is_expected.to run.with_params('key', 'heelo') + end + + it 'should display a single warning, despite multiple calls' do + Puppet.expects(:warning).with(includes('heelo')).once + is_expected.to run.with_params('key', 'heelo') + is_expected.to run.with_params('key', 'heelo') + end + + it 'should fail twice with message, with multiple calls. when strict= :error' do + Puppet.settings[:strict] = :error + Puppet.expects(:warning).with(includes('heelo')).never + is_expected.to run.with_params('key', 'heelo').and_raise_error(RuntimeError, /deprecation. key. heelo/) + is_expected.to run.with_params('key', 'heelo').and_raise_error(RuntimeError, /deprecation. key. heelo/) + end + + it 'should display nothing, despite multiple calls. strict= :off' do + Puppet.settings[:strict] = :off + Puppet.expects(:warning).with(includes('heelo')).never + is_expected.to run.with_params('key', 'heelo') + is_expected.to run.with_params('key', 'heelo') + end + + after(:all) { + # this is to reset the strict variable to default + Puppet.settings[:strict] = :warning + } + end +end -- cgit v1.2.3 From ef935bb287c54ac615f7f538a6f89190b4d2c4d7 Mon Sep 17 00:00:00 2001 From: tphoney Date: Tue, 19 Jul 2016 11:42:47 +0100 Subject: (MODULES-2143) document edge behaviour of range. --- README.markdown | 1 + lib/puppet/parser/functions/range.rb | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/README.markdown b/README.markdown index f176d98..45b4482 100644 --- a/README.markdown +++ b/README.markdown @@ -881,6 +881,7 @@ The third argument to this function is the salt to use. Extrapolates a range as an array when given in the form of '(start, stop)'. For example, `range("0", "9")` returns [0,1,2,3,4,5,6,7,8,9]. Zero-padded strings are converted to integers automatically, so `range("00", "09")` returns [0,1,2,3,4,5,6,7,8,9]. Non-integer strings are accepted; `range("a", "c")` returns ["a","b","c"], and `range("host01", "host10")` returns ["host01", "host02", ..., "host09", "host10"]. +NB Be explicit in including trailing zeros. Otherwise the underlying ruby function will fail. Passing a third argument will cause the generated range to step by that interval, e.g. `range("0", "9", "2")` returns ["0","2","4","6","8"]. diff --git a/lib/puppet/parser/functions/range.rb b/lib/puppet/parser/functions/range.rb index 2fc2113..d690df7 100644 --- a/lib/puppet/parser/functions/range.rb +++ b/lib/puppet/parser/functions/range.rb @@ -25,8 +25,8 @@ integers automatically) Will return: ["a","b","c"] range("host01", "host10") - Will return: ["host01", "host02", ..., "host09", "host10"] +NB Be explicit in including trailing zeros. Otherwise the underlying ruby function will fail. Passing a third argument will cause the generated range to step by that interval, e.g. -- cgit v1.2.3 From 41a46b67aed703cd9311aa0c4e4b18ff81a75fa8 Mon Sep 17 00:00:00 2001 From: tphoney Date: Tue, 19 Jul 2016 11:56:09 +0100 Subject: (MODULES-3306) document deep_merge --- README.markdown | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/README.markdown b/README.markdown index f176d98..24f493c 100644 --- a/README.markdown +++ b/README.markdown @@ -245,6 +245,19 @@ Converts a given integer or base 10 string representing an integer to a specifie If called with only an array, it counts the number of elements that are **not** nil/undef. If called with a second argument, counts the number of elements in an array that matches the second argument. *Type*: rvalue. +#### `deep_merge` + +Recursively merges two or more hashes together and returns the resulting hash. + $hash1 = {'one' => 1, 'two' => 2, 'three' => { 'four' => 4 } } + $hash2 = {'two' => 'dos', 'three' => { 'five' => 5 } } + $merged_hash = deep_merge($hash1, $hash2) + +The resulting hash is equivalent to: + $merged_hash = { 'one' => 1, 'two' => 'dos', 'three' => { 'four' => 4, 'five' => 5 } } + +When there is a duplicate key that is a hash, they are recursively merged. When there is a duplicate key that is not a hash, the key in the rightmost hash will "win.". +*Type*: rvalue, rvalue. + #### `defined_with_params` Takes a resource reference and an optional hash of attributes. Returns 'true' if a resource with the specified attributes has already been added to the catalog. Returns 'false' otherwise. -- cgit v1.2.3 From 1b36d540fde3f149bd2738384ad9065bd7f6c4bb Mon Sep 17 00:00:00 2001 From: tphoney Date: Tue, 19 Jul 2016 17:02:42 +0100 Subject: (modules-3407) documenting after can take a regex --- lib/puppet/type/file_line.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/puppet/type/file_line.rb b/lib/puppet/type/file_line.rb index a02b514..6f5c188 100644 --- a/lib/puppet/type/file_line.rb +++ b/lib/puppet/type/file_line.rb @@ -83,7 +83,8 @@ Puppet::Type.newtype(:file_line) do end newparam(:after) do - desc 'An optional value used to specify the line after which we will add any new lines. (Existing lines are added in place)' + desc 'An optional value used to specify the line after which we will add any new lines. (Existing lines are added in place)' + + ' This is also takes a regex.' end newparam(:line) do -- cgit v1.2.3 From 4cc560486974f00846981dbb64f5faeeec3b982f Mon Sep 17 00:00:00 2001 From: Steve Moore Date: Fri, 22 Jul 2016 15:40:22 -0400 Subject: Added the regexpescape function. --- lib/puppet/parser/functions/regexpescape.rb | 31 +++++++++++++++++++++++++ spec/functions/regexpescape_spec.rb | 36 +++++++++++++++++++++++++++++ 2 files changed, 67 insertions(+) create mode 100644 lib/puppet/parser/functions/regexpescape.rb create mode 100644 spec/functions/regexpescape_spec.rb diff --git a/lib/puppet/parser/functions/regexpescape.rb b/lib/puppet/parser/functions/regexpescape.rb new file mode 100644 index 0000000..477ee87 --- /dev/null +++ b/lib/puppet/parser/functions/regexpescape.rb @@ -0,0 +1,31 @@ +# +# regexpescape.rb +# +module Puppet::Parser::Functions + newfunction(:regexpescape, :type => :rvalue, :doc => <<-EOS + Regexp escape a string or array of strings. + Requires either a single string or an array as an input. + EOS + ) do |arguments| # rubocop:disable Style/ClosingParenthesisIndentation + raise(Puppet::ParseError, 'regexpescape(): Wrong number of arguments ' \ + "given (#{arguments.size} for 1)") if arguments.empty? + + value = arguments[0] + + unless value.is_a?(Array) || value.is_a?(String) + raise(Puppet::ParseError, 'regexpescape(): Requires either ' \ + 'array or string to work with') + end + + result = if value.is_a?(Array) + # Numbers in Puppet are often string-encoded which is troublesome ... + value.collect { |i| i.is_a?(String) ? Regexp.escape(i) : i } + else + Regexp.escape(value) + end + + return result + end +end + +# vim: set ts=2 sw=2 et : diff --git a/spec/functions/regexpescape_spec.rb b/spec/functions/regexpescape_spec.rb new file mode 100644 index 0000000..6efa847 --- /dev/null +++ b/spec/functions/regexpescape_spec.rb @@ -0,0 +1,36 @@ +require 'spec_helper' + +describe 'regexpescape' 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) } + it { + pending("Current implementation ignores parameters after the first.") + is_expected.to run.with_params('', '').and_raise_error(Puppet::ParseError, /wrong number of arguments/i) + } + it { is_expected.to run.with_params(1).and_raise_error(Puppet::ParseError, /Requires either array or string to work/) } + it { is_expected.to run.with_params({}).and_raise_error(Puppet::ParseError, /Requires either array or string to work/) } + it { is_expected.to run.with_params(true).and_raise_error(Puppet::ParseError, /Requires either array or string to work/) } + end + + describe 'handling normal strings' do + it 'should call ruby\'s Regexp.escape function' do + Regexp.expects(:escape).with('regexp_string').returns('escaped_regexp_string').once + is_expected.to run.with_params('regexp_string').and_return('escaped_regexp_string') + end + end + + describe 'handling classes derived from String' do + it 'should call ruby\'s Regexp.escape function' do + regexp_string = AlsoString.new('regexp_string') + Regexp.expects(:escape).with(regexp_string).returns('escaped_regexp_string').once + is_expected.to run.with_params(regexp_string).and_return("escaped_regexp_string") + end + end + + describe 'strings in arrays handling' do + it { is_expected.to run.with_params([]).and_return([]) } + it { is_expected.to run.with_params(['one*', "two"]).and_return(['one\*', "two"]) } + it { is_expected.to run.with_params(['one*', 1, true, {}, "two"]).and_return(['one\*', 1, true, {}, "two"]) } + end +end -- cgit v1.2.3 From db92a082c15c11d4d069a821be8aaddc5537020b Mon Sep 17 00:00:00 2001 From: Steve Moore Date: Tue, 26 Jul 2016 15:39:50 -0400 Subject: Added documentation for regexpescape function. --- README.markdown | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.markdown b/README.markdown index 158f55b..6352473 100644 --- a/README.markdown +++ b/README.markdown @@ -900,6 +900,10 @@ Passing a third argument will cause the generated range to step by that interval *Type*: rvalue. +#### `regexpescape` + +Regexp escape a string or array of strings. Requires either a single string or an array as an input. *Type*: rvalue. + #### `reject` Searches through an array and rejects all elements that match the provided regular expression. For example, `reject(['aaa','bbb','ccc','aaaddd'], 'aaa')` returns ['bbb','ccc']. *Type*: rvalue. -- cgit v1.2.3 From fded0af0c687bf4f219564dc4dfcd890f4563523 Mon Sep 17 00:00:00 2001 From: Loic Antoine-Gombeaud Date: Wed, 27 Jul 2016 12:59:23 +0200 Subject: Fix str2bool error message --- lib/puppet/parser/functions/str2bool.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/puppet/parser/functions/str2bool.rb b/lib/puppet/parser/functions/str2bool.rb index 8def131..472506d 100644 --- a/lib/puppet/parser/functions/str2bool.rb +++ b/lib/puppet/parser/functions/str2bool.rb @@ -21,7 +21,7 @@ like: 0, F,f, N,n, false, FALSE, no to 'false'. end unless string.is_a?(String) - raise(Puppet::ParseError, 'str2bool(): Requires either ' + + raise(Puppet::ParseError, 'str2bool(): Requires ' + 'string to work with') end -- cgit v1.2.3 From f7a3e16ab50f44d943553c52abb2418c85a1c970 Mon Sep 17 00:00:00 2001 From: David Schmitt Date: Wed, 27 Jul 2016 15:44:21 +0100 Subject: (MAINT) Update for modulesync_config 72d19f184 --- .gitignore | 3 ++- .travis.yml | 2 +- Gemfile | 19 ++++++++++--------- 3 files changed, 13 insertions(+), 11 deletions(-) diff --git a/.gitignore b/.gitignore index 95f271b..33bc5ff 100644 --- a/.gitignore +++ b/.gitignore @@ -2,7 +2,8 @@ pkg/ Gemfile.lock vendor/ -spec/fixtures/ +spec/fixtures/manifests/ +spec/fixtures/modules/ .vagrant/ .bundle/ coverage/ diff --git a/.travis.yml b/.travis.yml index 4e2c66d..f631db0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -19,7 +19,7 @@ matrix: script: bundle exec rake beaker services: docker sudo: required - - rvm: 2.1.6 + - rvm: 2.1.9 bundler_args: --without system_tests env: PUPPET_GEM_VERSION="~> 4.0" STRICT_VARIABLES="yes" - rvm: 2.1.5 diff --git a/Gemfile b/Gemfile index 9b5b214..c7da908 100644 --- a/Gemfile +++ b/Gemfile @@ -13,14 +13,12 @@ def location_for(place, version = nil) end group :development, :unit_tests do - gem 'json', :require => false - gem 'metadata-json-lint', :require => false - gem 'puppet_facts', :require => false - gem 'puppetlabs_spec_helper', :require => false - gem 'rspec-puppet', '>= 2.3.2', :require => false - gem 'simplecov', :require => false - gem 'puppet-blacksmith', :require => false - gem 'rest-client', '~> 1.8.0', :require => false + gem 'metadata-json-lint', :require => false + gem 'puppet_facts', :require => false + gem 'puppet-blacksmith', '>= 3.4.0', :require => false + gem 'puppetlabs_spec_helper', :require => false + gem 'rspec-puppet', '>= 2.3.2', :require => false + gem 'simplecov', :require => false end group :system_tests do gem 'beaker-rspec', *location_for(ENV['BEAKER_RSPEC_VERSION'] || '>= 3.4') @@ -31,10 +29,13 @@ group :system_tests do gem 'beaker-hostgenerator', *location_for(ENV['BEAKER_HOSTGENERATOR_VERSION']) end +# json_pure 2.0.2 added a requirement on ruby >= 2. We pin to json_pure 2.0.1 +# if using ruby 1.x +gem 'json_pure', '<=2.0.1', :require => false if RUBY_VERSION =~ /^1\./ + gem 'facter', *location_for(ENV['FACTER_GEM_VERSION']) gem 'puppet', *location_for(ENV['PUPPET_GEM_VERSION']) - if File.exists? "#{__FILE__}.local" eval(File.read("#{__FILE__}.local"), binding) end -- cgit v1.2.3 From 9031fc149ad9acc4c51ceb343864705003f93867 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Romain=20Tarti=C3=A8re?= Date: Fri, 5 Aug 2016 10:58:14 +0200 Subject: Fix markdown indentation The old indentation is weird. --- README.markdown | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/README.markdown b/README.markdown index 6352473..0666b37 100644 --- a/README.markdown +++ b/README.markdown @@ -468,11 +468,11 @@ From Hiera Backend: ~~~ userlist: -dan: - gid: 'mygroup' -uid: '600' -alex: -gid: 'mygroup' + dan: + gid: 'mygroup' + uid: '600' + alex: + gid: 'mygroup' ensure_resources('user', hiera_hash('userlist'), {'ensure' => 'present'}) ~~~ -- cgit v1.2.3 From 17a49baae33a78d6aa781aaaadafc08b43def040 Mon Sep 17 00:00:00 2001 From: Chris Edester Date: Fri, 5 Aug 2016 15:38:59 -0400 Subject: Handle array values in join_keys_to_values function --- README.markdown | 4 +++- lib/puppet/parser/functions/join_keys_to_values.rb | 15 ++++++++++++--- spec/functions/join_keys_to_values_spec.rb | 4 ++++ 3 files changed, 19 insertions(+), 4 deletions(-) diff --git a/README.markdown b/README.markdown index 0666b37..90addee 100644 --- a/README.markdown +++ b/README.markdown @@ -716,7 +716,9 @@ Joins an array into a string using a separator. For example, `join(['a','b','c'] #### `join_keys_to_values` -Joins each key of a hash to that key's corresponding value with a separator. Keys and values are cast to strings. The return value is an array in which each element is one joined key/value pair. For example, `join_keys_to_values({'a'=>1,'b'=>2}, " is ")` results in ["a is 1","b is 2"]. *Type*: rvalue. +Joins each key of a hash to that key's corresponding value with a separator. Keys are cast to strings. +If values are arrays, multiple keys are added for each element. +The return value is an array in which each element is one joined key/value pair. For example, `join_keys_to_values({'a'=>1,'b'=>[2,3]}, " is ")` results in ["a is 1","b is 2","b is 3"]. *Type*: rvalue. #### `keys` diff --git a/lib/puppet/parser/functions/join_keys_to_values.rb b/lib/puppet/parser/functions/join_keys_to_values.rb index e9924fe..e3baf9f 100644 --- a/lib/puppet/parser/functions/join_keys_to_values.rb +++ b/lib/puppet/parser/functions/join_keys_to_values.rb @@ -5,7 +5,8 @@ module Puppet::Parser::Functions newfunction(:join_keys_to_values, :type => :rvalue, :doc => <<-EOS This function joins each key of a hash to that key's corresponding value with a -separator. Keys and values are cast to strings. The return value is an array in +separator. Keys are cast to strings. If values are arrays, multiple keys +are added for each element. The return value is an array in which each element is one joined key/value pair. *Examples:* @@ -13,6 +14,10 @@ which each element is one joined key/value pair. join_keys_to_values({'a'=>1,'b'=>2}, " is ") Would result in: ["a is 1","b is 2"] + + join_keys_to_values({'a'=>1,'b'=>[2,3]}, " is ") + +Would result in: ["a is 1","b is 2","b is 3"] EOS ) do |arguments| @@ -38,8 +43,12 @@ Would result in: ["a is 1","b is 2"] # Join the keys to their values. hash.map do |k,v| - String(k) + separator + String(v) - end + if v.is_a?(Array) + v.map { |va| String(k) + separator + String(va) } + else + String(k) + separator + String(v) + end + end.flatten end end diff --git a/spec/functions/join_keys_to_values_spec.rb b/spec/functions/join_keys_to_values_spec.rb index 6c109d1..c2bae5b 100755 --- a/spec/functions/join_keys_to_values_spec.rb +++ b/spec/functions/join_keys_to_values_spec.rb @@ -16,4 +16,8 @@ describe 'join_keys_to_values' do result = subject.call([{ 'key1' => 'value1', 'key2' => 'value2' }, ':']) expect(result.sort).to eq(['key1:value1', 'key2:value2'].sort) end + it 'should run join_keys_to_values(, " ") and return the proper array' do + result = subject.call([{ 'key1' => 'value1', 'key2' => ['value2', 'value3'] }, ' ']) + expect(result.sort).to eq(['key1 value1', 'key2 value2', 'key2 value3'].sort) + end end -- cgit v1.2.3 From 6e7e69fe203e042b28aacb01301c338d55448c5f Mon Sep 17 00:00:00 2001 From: tphoney Date: Wed, 3 Aug 2016 17:06:25 +0100 Subject: (modules-3533) deprecation for 3.x number function --- .fixtures.yml | 1 + Gemfile | 4 +++- Rakefile | 6 ++++- lib/puppet/parser/functions/deprecation.rb | 15 ++++++++++++ lib/puppet/parser/functions/is_float.rb | 2 ++ lib/puppet/parser/functions/is_integer.rb | 2 ++ lib/puppet/parser/functions/is_numeric.rb | 4 ++-- lib/puppet/parser/functions/validate_integer.rb | 2 ++ lib/puppet/parser/functions/validate_numeric.rb | 2 ++ spec/aliases/float_spec.rb | 28 ++++++++++++++++++++++ spec/aliases/integer_spec.rb | 28 ++++++++++++++++++++++ spec/aliases/numeric_spec.rb | 32 +++++++++++++++++++++++++ spec/fixtures/modules/test/manifests/float.pp | 8 +++++++ spec/fixtures/modules/test/manifests/integer.pp | 8 +++++++ spec/fixtures/modules/test/manifests/numeric.pp | 8 +++++++ spec/functions/deprecation_spec.rb | 18 +++++++------- spec/functions/is_float_spec.rb | 7 ++++++ spec/functions/is_integer_spec.rb | 7 ++++++ spec/functions/is_numeric_spec.rb | 7 ++++++ spec/functions/validate_integer_spec.rb | 6 +++++ spec/functions/validate_numeric_spec.rb | 6 +++++ types/compat/float.pp | 19 +++++++++++++++ types/compat/integer.pp | 23 ++++++++++++++++++ types/compat/numeric.pp | 23 ++++++++++++++++++ 24 files changed, 254 insertions(+), 12 deletions(-) create mode 100644 lib/puppet/parser/functions/deprecation.rb create mode 100644 spec/aliases/float_spec.rb create mode 100644 spec/aliases/integer_spec.rb create mode 100644 spec/aliases/numeric_spec.rb create mode 100644 spec/fixtures/modules/test/manifests/float.pp create mode 100644 spec/fixtures/modules/test/manifests/integer.pp create mode 100644 spec/fixtures/modules/test/manifests/numeric.pp create mode 100644 types/compat/float.pp create mode 100644 types/compat/integer.pp create mode 100644 types/compat/numeric.pp diff --git a/.fixtures.yml b/.fixtures.yml index 37b7377..a28e653 100644 --- a/.fixtures.yml +++ b/.fixtures.yml @@ -1,3 +1,4 @@ fixtures: symlinks: stdlib: "#{source_dir}" + test: "#{source_dir}/spec/fixtures/test" diff --git a/Gemfile b/Gemfile index c7da908..0fc6c18 100644 --- a/Gemfile +++ b/Gemfile @@ -16,7 +16,7 @@ group :development, :unit_tests do gem 'metadata-json-lint', :require => false gem 'puppet_facts', :require => false gem 'puppet-blacksmith', '>= 3.4.0', :require => false - gem 'puppetlabs_spec_helper', :require => false + gem 'puppetlabs_spec_helper', :git => 'git://github.com/puppetlabs/puppetlabs_spec_helper.git', :ref => '157a7fd', :require => false gem 'rspec-puppet', '>= 2.3.2', :require => false gem 'simplecov', :require => false end @@ -32,6 +32,8 @@ end # json_pure 2.0.2 added a requirement on ruby >= 2. We pin to json_pure 2.0.1 # if using ruby 1.x gem 'json_pure', '<=2.0.1', :require => false if RUBY_VERSION =~ /^1\./ +# rubocop 0.42.0 requires ruby >=2 +gem 'rubocop', '0.41.2', :require => false if RUBY_VERSION =~ /^1\./ gem 'facter', *location_for(ENV['FACTER_GEM_VERSION']) gem 'puppet', *location_for(ENV['PUPPET_GEM_VERSION']) diff --git a/Rakefile b/Rakefile index 8906d23..47a671e 100644 --- a/Rakefile +++ b/Rakefile @@ -8,7 +8,11 @@ PuppetLint.configuration.send('disable_140chars') 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", "bundle/**/*", "vendor/**/*"] +PuppetLint.configuration.ignore_paths = ["spec/**/*.pp", "pkg/**/*.pp", "bundle/**/*", "vendor/**/*", "types/**/*"] + +if Puppet.version.to_f < 4.0 + PuppetSyntax.exclude_paths << "types/**/*" +end desc 'Generate pooler nodesets' task :gen_nodeset do diff --git a/lib/puppet/parser/functions/deprecation.rb b/lib/puppet/parser/functions/deprecation.rb new file mode 100644 index 0000000..5d74984 --- /dev/null +++ b/lib/puppet/parser/functions/deprecation.rb @@ -0,0 +1,15 @@ +module Puppet::Parser::Functions + newfunction(:deprecation, :type => :rvalue, :doc => <<-EOS + Function to print deprecation warnings (this is the 3.X version of it), The uniqueness key - can appear once. The msg is the message text including any positional information that is formatted by the user/caller of the method.). +EOS + ) do |arguments| + + raise(Puppet::ParseError, "deprecation: Wrong number of arguments " + + "given (#{arguments.size} for 2)") unless arguments.size == 2 + + key = arguments[0] + message = arguments[1] + + warn("deprecation. #{key}. #{message}") + end +end diff --git a/lib/puppet/parser/functions/is_float.rb b/lib/puppet/parser/functions/is_float.rb index a2da943..5233e40 100644 --- a/lib/puppet/parser/functions/is_float.rb +++ b/lib/puppet/parser/functions/is_float.rb @@ -8,6 +8,8 @@ Returns true if the variable passed to this function is a float. EOS ) do |arguments| + function_deprecation([:puppet_3_type_check, 'This method is deprecated, please use the stdlib validate_legacy function, with Stdlib::Compat::Float. There is further documentation for validate_legacy function in the README.']) + if (arguments.size != 1) then raise(Puppet::ParseError, "is_float(): Wrong number of arguments "+ "given #{arguments.size} for 1") diff --git a/lib/puppet/parser/functions/is_integer.rb b/lib/puppet/parser/functions/is_integer.rb index c03d28d..e04fd1f 100644 --- a/lib/puppet/parser/functions/is_integer.rb +++ b/lib/puppet/parser/functions/is_integer.rb @@ -13,6 +13,8 @@ If given any other argument `false` is returned. EOS ) do |arguments| + function_deprecation([:is_integer, 'This method is deprecated, please use the stdlib validate_legacy function, with Stdlib::Compat::Integer. There is further documentation for validate_legacy function in the README.']) + if (arguments.size != 1) then raise(Puppet::ParseError, "is_integer(): Wrong number of arguments "+ "given #{arguments.size} for 1") diff --git a/lib/puppet/parser/functions/is_numeric.rb b/lib/puppet/parser/functions/is_numeric.rb index e7e1d2a..2bdd353 100644 --- a/lib/puppet/parser/functions/is_numeric.rb +++ b/lib/puppet/parser/functions/is_numeric.rb @@ -24,6 +24,8 @@ Valid examples: EOS ) do |arguments| + function_deprecation([:puppet_3_type_check, 'This method is deprecated, please use the stdlib validate_legacy function, with Stdlib::Compat::Numeric. There is further documentation for validate_legacy function in the README.']) + if (arguments.size != 1) then raise(Puppet::ParseError, "is_numeric(): Wrong number of arguments "+ "given #{arguments.size} for 1") @@ -71,5 +73,3 @@ Valid examples: end end end - -# vim: set ts=2 sw=2 et : diff --git a/lib/puppet/parser/functions/validate_integer.rb b/lib/puppet/parser/functions/validate_integer.rb index a950916..f52e053 100644 --- a/lib/puppet/parser/functions/validate_integer.rb +++ b/lib/puppet/parser/functions/validate_integer.rb @@ -53,6 +53,8 @@ module Puppet::Parser::Functions ENDHEREDOC + function_deprecation([:puppet_3_type_check, 'This method is deprecated, please use the stdlib validate_legacy function, with Stdlib::Compat::Integer. There is further documentation for validate_legacy function in the README.']) + # tell the user we need at least one, and optionally up to two other parameters raise Puppet::ParseError, "validate_integer(): Wrong number of arguments; must be 1, 2 or 3, got #{args.length}" unless args.length > 0 and args.length < 4 diff --git a/lib/puppet/parser/functions/validate_numeric.rb b/lib/puppet/parser/functions/validate_numeric.rb index 3a14443..6b55f49 100644 --- a/lib/puppet/parser/functions/validate_numeric.rb +++ b/lib/puppet/parser/functions/validate_numeric.rb @@ -15,6 +15,8 @@ module Puppet::Parser::Functions ENDHEREDOC + function_deprecation([:puppet_3_type_check, 'This method is deprecated, please use the stdlib validate_legacy function, with Stdlib::Compat::Numeric. There is further documentation for validate_legacy function in the README.']) + # tell the user we need at least one, and optionally up to two other parameters raise Puppet::ParseError, "validate_numeric(): Wrong number of arguments; must be 1, 2 or 3, got #{args.length}" unless args.length > 0 and args.length < 4 diff --git a/spec/aliases/float_spec.rb b/spec/aliases/float_spec.rb new file mode 100644 index 0000000..be31e43 --- /dev/null +++ b/spec/aliases/float_spec.rb @@ -0,0 +1,28 @@ +require 'spec_helper' + +if Puppet.version.to_f >= 4.0 + describe 'test::float', type: :class do + describe 'accepts floats' do + [ + 3.7, + '3.7', + -3.7, + '-342.2315e-12', + ].each do |value| + describe value.inspect do + let(:params) {{ value: value }} + it { is_expected.to compile } + end + end + end + + describe 'rejects other values' do + [ true, 'true', false, 'false', 'iAmAString', '1test', '1 test', 'test 1', 'test 1 test', {}, { 'key' => 'value' }, { 1=> 2 }, '', :undef , 'x', 3, '3', -3, '-3'].each do |value| + describe value.inspect do + let(:params) {{ value: value }} + it { is_expected.to compile.and_raise_error(/parameter 'value' expects a value of type Float or Pattern(\[.*\]+)?/) } + end + end + end + end +end diff --git a/spec/aliases/integer_spec.rb b/spec/aliases/integer_spec.rb new file mode 100644 index 0000000..fbc8c19 --- /dev/null +++ b/spec/aliases/integer_spec.rb @@ -0,0 +1,28 @@ +require 'spec_helper' + +if Puppet.version.to_f >= 4.0 + describe 'test::integer', type: :class do + describe 'accepts integers' do + [ + 3, + '3', + -3, + '-3', + ].each do |value| + describe value.inspect do + let(:params) {{ value: value }} + it { is_expected.to compile } + end + end + end + + describe 'rejects other values' do + [ true, 'true', false, 'false', 'iAmAString', '1test', '1 test', 'test 1', 'test 1 test', {}, { 'key' => 'value' }, { 1=> 2 }, '', :undef , 'x', 3.7, '3.7',-3.7, '-342.2315e-12' ].each do |value| + describe value.inspect do + let(:params) {{ value: value }} + it { is_expected.to compile.and_raise_error(/parameter 'value' expects a value of type Integer, Pattern(\[.*\]+)?, or Array/) } + end + end + end + end +end diff --git a/spec/aliases/numeric_spec.rb b/spec/aliases/numeric_spec.rb new file mode 100644 index 0000000..9afe4ed --- /dev/null +++ b/spec/aliases/numeric_spec.rb @@ -0,0 +1,32 @@ +require 'spec_helper' + +if Puppet.version.to_f >= 4.0 + describe 'test::numeric', type: :class do + describe 'accepts numerics' do + [ + 3, + '3', + -3, + '-3', + 3.7, + '3.7', + -3.7, + '-342.2315e-12', + ].each do |value| + describe value.inspect do + let(:params) {{ value: value }} + it { is_expected.to compile } + end + end + end + + describe 'rejects other values' do + [ true, 'true', false, 'false', 'iAmAString', '1test', '1 test', 'test 1', 'test 1 test', {}, { 'key' => 'value' }, { 1=> 2 }, '', :undef , 'x' ].each do |value| + describe value.inspect do + let(:params) {{ value: value }} + it { is_expected.to compile.and_raise_error(/parameter 'value' expects a value of type Numeric, Pattern(\[.*\]+)?, or Array/) } + end + end + end + end +end diff --git a/spec/fixtures/modules/test/manifests/float.pp b/spec/fixtures/modules/test/manifests/float.pp new file mode 100644 index 0000000..03a603d --- /dev/null +++ b/spec/fixtures/modules/test/manifests/float.pp @@ -0,0 +1,8 @@ +# Class to test the Stdlib::Compat::Float type alias +class test::float( + Stdlib::Compat::Float $value, + ) { + + notice("Success") + +} diff --git a/spec/fixtures/modules/test/manifests/integer.pp b/spec/fixtures/modules/test/manifests/integer.pp new file mode 100644 index 0000000..a4f26df --- /dev/null +++ b/spec/fixtures/modules/test/manifests/integer.pp @@ -0,0 +1,8 @@ +# Class to test the Stdlib::Compat::Integer type alias +class test::integer( + Stdlib::Compat::Integer $value, + ) { + + notice("Success") + +} diff --git a/spec/fixtures/modules/test/manifests/numeric.pp b/spec/fixtures/modules/test/manifests/numeric.pp new file mode 100644 index 0000000..2657ebc --- /dev/null +++ b/spec/fixtures/modules/test/manifests/numeric.pp @@ -0,0 +1,8 @@ +# Class to test the Stdlib::Compat::Numeric type alias +class test::numeric( + Stdlib::Compat::Numeric $value, + ) { + + notice("Success") + +} diff --git a/spec/functions/deprecation_spec.rb b/spec/functions/deprecation_spec.rb index bbabe48..a596e24 100644 --- a/spec/functions/deprecation_spec.rb +++ b/spec/functions/deprecation_spec.rb @@ -1,13 +1,5 @@ require 'spec_helper' -if ENV["FUTURE_PARSER"] == 'yes' - describe 'deprecation' do - pending 'teach rspec-puppet to load future-only functions under 3.7.5' do - it { is_expected.not_to eq(nil) } - end - end -end - if Puppet.version.to_f >= 4.0 describe 'deprecation' do before(:each) { @@ -48,4 +40,14 @@ if Puppet.version.to_f >= 4.0 Puppet.settings[:strict] = :warning } end +else + describe 'deprecation' 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 'should display a single warning' do + scope.expects(:warn).with(includes('heelo')) + is_expected.to run.with_params('key', 'heelo') + end + end end diff --git a/spec/functions/is_float_spec.rb b/spec/functions/is_float_spec.rb index ffff971..267d9c6 100755 --- a/spec/functions/is_float_spec.rb +++ b/spec/functions/is_float_spec.rb @@ -2,6 +2,13 @@ require 'spec_helper' describe 'is_float' do it { is_expected.not_to eq(nil) } + + # Checking for deprecation warning + it 'should display a single deprecation' do + scope.expects(:warn).with(includes('This method is deprecated')) + is_expected.to run.with_params(3) + end + it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } it { is_expected.to run.with_params(0.1, 0.2).and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } diff --git a/spec/functions/is_integer_spec.rb b/spec/functions/is_integer_spec.rb index 67263c1..49550c7 100755 --- a/spec/functions/is_integer_spec.rb +++ b/spec/functions/is_integer_spec.rb @@ -2,6 +2,13 @@ require 'spec_helper' describe 'is_integer' do it { is_expected.not_to eq(nil) } + + # Checking for deprecation warning + it 'should display a single deprecation' do + scope.expects(:warn).with(includes('This method is deprecated')) + is_expected.to run.with_params(3) + end + it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } it { is_expected.to run.with_params(1, 2).and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } diff --git a/spec/functions/is_numeric_spec.rb b/spec/functions/is_numeric_spec.rb index d0f5a6e..b7de051 100755 --- a/spec/functions/is_numeric_spec.rb +++ b/spec/functions/is_numeric_spec.rb @@ -2,6 +2,13 @@ require 'spec_helper' describe 'is_numeric' do it { is_expected.not_to eq(nil) } + + # Checking for deprecation warning + it 'should display a single deprecation' do + scope.expects(:warn).with(includes('This method is deprecated')) + is_expected.to run.with_params(3) + end + it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } it { is_expected.to run.with_params(1, 2).and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } diff --git a/spec/functions/validate_integer_spec.rb b/spec/functions/validate_integer_spec.rb index 4c0a9d7..0eeab1e 100755 --- a/spec/functions/validate_integer_spec.rb +++ b/spec/functions/validate_integer_spec.rb @@ -1,6 +1,12 @@ require 'spec_helper' describe 'validate_integer' do + # Checking for deprecation warning + it 'should display a single deprecation' do + scope.expects(:warn).with(includes('This method is deprecated')) + is_expected.to run.with_params(3) + end + 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) } diff --git a/spec/functions/validate_numeric_spec.rb b/spec/functions/validate_numeric_spec.rb index 9b8eb0e..2e5561e 100755 --- a/spec/functions/validate_numeric_spec.rb +++ b/spec/functions/validate_numeric_spec.rb @@ -1,6 +1,12 @@ require 'spec_helper' describe 'validate_numeric' do + # Checking for deprecation warning + it 'should display a single deprecation' do + scope.expects(:warn).with(includes('This method is deprecated')) + is_expected.to run.with_params(3) + end + 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) } diff --git a/types/compat/float.pp b/types/compat/float.pp new file mode 100644 index 0000000..7f98bd2 --- /dev/null +++ b/types/compat/float.pp @@ -0,0 +1,19 @@ +# Emulate the is_float function +# The regex is what's currently used in is_float +# To keep your development moving forward, you can also add a deprecation warning using the Integer type: +# +# ```class example($value) { validate_float($value,) }``` +# +# would turn into +# +# ``` +# class example(Stdlib::Compat::Float $value) { +# validate_float($value, 10, 0) +# assert_type(Integer[0, 10], $value) |$expected, $actual| { +# warning("The 'value' parameter for the 'ntp' class has type ${actual}, but should be ${expected}.") +# } +# } +# ``` +# +# This allows you to find all places where a consumers of your code call it with unexpected values. +type Stdlib::Compat::Float = Variant[Float, Pattern[/^-?(?:(?:[1-9]\d*)|0)(?:\.\d+)(?:[eE]-?\d+)?$/]] diff --git a/types/compat/integer.pp b/types/compat/integer.pp new file mode 100644 index 0000000..e5cadb6 --- /dev/null +++ b/types/compat/integer.pp @@ -0,0 +1,23 @@ +# Emulate the is_integer and validate_integer functions +# The regex is what's currently used in is_integer +# validate_numeric also allows range checking, which cannot be mapped to the string parsing inside the function. +# For full backwards compatibility, you will need to keep the validate_numeric call around to catch everything. +# To keep your development moving forward, you can also add a deprecation warning using the Integer type: +# +# ```class example($value) { validate_integer($value, 10, 0) }``` +# +# would turn into +# +# ``` +# class example(Stdlib::Compat::Integer $value) { +# validate_numeric($value, 10, 0) +# assert_type(Integer[0, 10], $value) |$expected, $actual| { +# warning("The 'value' parameter for the 'ntp' class has type ${actual}, but should be ${expected}.") +# } +# } +# ``` +# +# > Note that you need to use Variant[Integer[0, 10], Float[0, 10]] if you want to match both integers and floating point numbers. +# +# This allows you to find all places where a consumers of your code call it with unexpected values. +type Stdlib::Compat::Integer = Variant[Integer, Pattern[/^-?(?:(?:[1-9]\d*)|0)$/], Array[Variant[Integer, Pattern[/^-?(?:(?:[1-9]\d*)|0)$/]]]] diff --git a/types/compat/numeric.pp b/types/compat/numeric.pp new file mode 100644 index 0000000..5bfc3d3 --- /dev/null +++ b/types/compat/numeric.pp @@ -0,0 +1,23 @@ +# Emulate the is_numeric and validate_numeric functions +# The regex is what's currently used in is_numeric +# validate_numeric also allows range checking, which cannot be mapped to the string parsing inside the function. +# For full backwards compatibility, you will need to keep the validate_numeric call around to catch everything. +# To keep your development moving forward, you can also add a deprecation warning using the Integer type: +# +# ```class example($value) { validate_numeric($value, 10, 0) }``` +# +# would turn into +# +# ``` +# class example(Stdlib::Compat::Numeric $value) { +# validate_numeric($value, 10, 0) +# assert_type(Integer[0, 10], $value) |$expected, $actual| { +# warning("The 'value' parameter for the 'ntp' class has type ${actual}, but should be ${expected}.") +# } +# } +# ``` +# +# > Note that you need to use Variant[Integer[0, 10], Float[0, 10]] if you want to match both integers and floating point numbers. +# +# This allows you to find all places where a consumers of your code call it with unexpected values. +type Stdlib::Compat::Numeric = Variant[Numeric, Pattern[/^-?(?:(?:[1-9]\d*)|0)(?:\.\d+)?(?:[eE]-?\d+)?$/], Array[Variant[Numeric, Pattern[/^-?(?:(?:[1-9]\d*)|0)(?:\.\d+)?(?:[eE]-?\d+)?$/]]]] -- cgit v1.2.3 From 22fbe723acd22ae3491c41beeacbc76853c6820e Mon Sep 17 00:00:00 2001 From: tphoney Date: Mon, 8 Aug 2016 17:35:13 +0100 Subject: (modules-3532) deprecate string type checks --- lib/puppet/parser/functions/is_absolute_path.rb | 4 +- lib/puppet/parser/functions/is_array.rb | 4 +- lib/puppet/parser/functions/is_bool.rb | 4 +- lib/puppet/parser/functions/is_string.rb | 2 + .../parser/functions/validate_absolute_path.rb | 2 + lib/puppet/parser/functions/validate_array.rb | 2 + lib/puppet/parser/functions/validate_bool.rb | 2 + lib/puppet/parser/functions/validate_re.rb | 3 ++ lib/puppet/parser/functions/validate_string.rb | 2 + spec/aliases/absolute_path_spec.rb | 62 ++++++++++++++++++++++ spec/aliases/array_spec.rb | 34 ++++++++++++ spec/aliases/bool_spec.rb | 32 +++++++++++ spec/aliases/string_spec.rb | 31 +++++++++++ .../modules/test/manifests/absolute_path.pp | 6 +++ spec/fixtures/modules/test/manifests/array.pp | 8 +++ spec/fixtures/modules/test/manifests/bool.pp | 8 +++ spec/fixtures/modules/test/manifests/string.pp | 8 +++ spec/functions/is_array_spec.rb | 5 ++ spec/functions/is_bool_spec.rb | 5 ++ spec/functions/is_string_spec.rb | 5 ++ spec/functions/validate_absolute_path_spec.rb | 7 +++ spec/functions/validate_array_spec.rb | 5 ++ spec/functions/validate_bool_spec.rb | 7 +++ spec/functions/validate_re_spec.rb | 6 +++ spec/functions/validate_string_spec.rb | 6 +++ types/compat/absolute_path.pp | 7 +++ types/compat/array.pp | 2 + types/compat/bool.pp | 2 + types/compat/re.pp | 3 ++ types/compat/string.pp | 2 + 30 files changed, 270 insertions(+), 6 deletions(-) create mode 100644 spec/aliases/absolute_path_spec.rb create mode 100644 spec/aliases/array_spec.rb create mode 100644 spec/aliases/bool_spec.rb create mode 100644 spec/aliases/string_spec.rb create mode 100644 spec/fixtures/modules/test/manifests/absolute_path.pp create mode 100644 spec/fixtures/modules/test/manifests/array.pp create mode 100644 spec/fixtures/modules/test/manifests/bool.pp create mode 100644 spec/fixtures/modules/test/manifests/string.pp create mode 100644 types/compat/absolute_path.pp create mode 100644 types/compat/array.pp create mode 100644 types/compat/bool.pp create mode 100644 types/compat/re.pp create mode 100644 types/compat/string.pp diff --git a/lib/puppet/parser/functions/is_absolute_path.rb b/lib/puppet/parser/functions/is_absolute_path.rb index 53a5445..2e37414 100644 --- a/lib/puppet/parser/functions/is_absolute_path.rb +++ b/lib/puppet/parser/functions/is_absolute_path.rb @@ -23,7 +23,7 @@ module Puppet::Parser::Functions is_absolute_path($undefined) ENDHEREDOC - + function_deprecation([:puppet_3_type_check, 'This method is deprecated, please use the stdlib validate_legacy function, with Stdlib::Compat::Absolute_path. There is further documentation for validate_legacy function in the README.']) require 'puppet/util' path = args[0] @@ -47,4 +47,4 @@ module Puppet::Parser::Functions end value end -end \ No newline at end of file +end diff --git a/lib/puppet/parser/functions/is_array.rb b/lib/puppet/parser/functions/is_array.rb index b39e184..d1bb58a 100644 --- a/lib/puppet/parser/functions/is_array.rb +++ b/lib/puppet/parser/functions/is_array.rb @@ -8,6 +8,8 @@ Returns true if the variable passed to this function is an array. EOS ) do |arguments| + function_deprecation([:puppet_3_type_check, 'This method is deprecated, please use the stdlib validate_legacy function, with Stdlib::Compat::Array. There is further documentation for validate_legacy function in the README.']) + raise(Puppet::ParseError, "is_array(): Wrong number of arguments " + "given (#{arguments.size} for 1)") if arguments.size < 1 @@ -18,5 +20,3 @@ Returns true if the variable passed to this function is an array. return result end end - -# vim: set ts=2 sw=2 et : diff --git a/lib/puppet/parser/functions/is_bool.rb b/lib/puppet/parser/functions/is_bool.rb index 8bbdbc8..48aaa08 100644 --- a/lib/puppet/parser/functions/is_bool.rb +++ b/lib/puppet/parser/functions/is_bool.rb @@ -8,6 +8,8 @@ Returns true if the variable passed to this function is a boolean. EOS ) do |arguments| + function_deprecation([:puppet_3_type_check, 'This method is deprecated, please use the stdlib validate_legacy function, with Stdlib::Compat::Bool. There is further documentation for validate_legacy function in the README.']) + raise(Puppet::ParseError, "is_bool(): Wrong number of arguments " + "given (#{arguments.size} for 1)") if arguments.size != 1 @@ -18,5 +20,3 @@ Returns true if the variable passed to this function is a boolean. return result end end - -# vim: set ts=2 sw=2 et : diff --git a/lib/puppet/parser/functions/is_string.rb b/lib/puppet/parser/functions/is_string.rb index f5bef04..144cf51 100644 --- a/lib/puppet/parser/functions/is_string.rb +++ b/lib/puppet/parser/functions/is_string.rb @@ -8,6 +8,8 @@ Returns true if the variable passed to this function is a string. EOS ) do |arguments| + function_deprecation([:puppet_3_type_check, 'This method is deprecated, please use the stdlib validate_legacy function, with Stdlib::Compat::String. There is further documentation for validate_legacy function in the README.']) + raise(Puppet::ParseError, "is_string(): Wrong number of arguments " + "given (#{arguments.size} for 1)") if arguments.size < 1 diff --git a/lib/puppet/parser/functions/validate_absolute_path.rb b/lib/puppet/parser/functions/validate_absolute_path.rb index 5f85f72..d5f5443 100644 --- a/lib/puppet/parser/functions/validate_absolute_path.rb +++ b/lib/puppet/parser/functions/validate_absolute_path.rb @@ -26,6 +26,8 @@ module Puppet::Parser::Functions ENDHEREDOC + function_deprecation([:puppet_3_type_check, 'This method is deprecated, please use the stdlib validate_legacy function, with Stdlib::Compat::Absolute_path. There is further documentation for validate_legacy function in the README.']) + require 'puppet/util' unless args.length > 0 then diff --git a/lib/puppet/parser/functions/validate_array.rb b/lib/puppet/parser/functions/validate_array.rb index 34b5118..97bd41d 100644 --- a/lib/puppet/parser/functions/validate_array.rb +++ b/lib/puppet/parser/functions/validate_array.rb @@ -18,6 +18,8 @@ module Puppet::Parser::Functions ENDHEREDOC + function_deprecation([:puppet_3_type_check, 'This method is deprecated, please use the stdlib validate_legacy function, with Stdlib::Compat::Array. There is further documentation for validate_legacy function in the README.']) + unless args.length > 0 then raise Puppet::ParseError, ("validate_array(): wrong number of arguments (#{args.length}; must be > 0)") end diff --git a/lib/puppet/parser/functions/validate_bool.rb b/lib/puppet/parser/functions/validate_bool.rb index 59a0805..4e52ffd 100644 --- a/lib/puppet/parser/functions/validate_bool.rb +++ b/lib/puppet/parser/functions/validate_bool.rb @@ -19,6 +19,8 @@ module Puppet::Parser::Functions ENDHEREDOC + function_deprecation([:puppet_3_type_check, 'This method is deprecated, please use the stdlib validate_legacy function, with Stdlib::Compat::Bool. There is further documentation for validate_legacy function in the README.']) + unless args.length > 0 then raise Puppet::ParseError, ("validate_bool(): wrong number of arguments (#{args.length}; must be > 0)") end diff --git a/lib/puppet/parser/functions/validate_re.rb b/lib/puppet/parser/functions/validate_re.rb index efee7f8..6bdc858 100644 --- a/lib/puppet/parser/functions/validate_re.rb +++ b/lib/puppet/parser/functions/validate_re.rb @@ -29,6 +29,9 @@ module Puppet::Parser::Functions validate_re("${::operatingsystemmajrelease}", '^[57]$') ENDHEREDOC + + function_deprecation([:puppet_3_type_check, 'This method is deprecated, please use the stdlib validate_legacy function, with Stdlib::Compat::Re. There is further documentation for validate_legacy function in the README.']) + if (args.length < 2) or (args.length > 3) then raise Puppet::ParseError, "validate_re(): wrong number of arguments (#{args.length}; must be 2 or 3)" end diff --git a/lib/puppet/parser/functions/validate_string.rb b/lib/puppet/parser/functions/validate_string.rb index c841f6a..e92a2fc 100644 --- a/lib/puppet/parser/functions/validate_string.rb +++ b/lib/puppet/parser/functions/validate_string.rb @@ -23,6 +23,8 @@ module Puppet::Parser::Functions ENDHEREDOC + function_deprecation([:puppet_3_type_check, 'This method is deprecated, please use the stdlib validate_legacy function, with Stdlib::Compat::String. There is further documentation for validate_legacy function in the README.']) + unless args.length > 0 then raise Puppet::ParseError, ("validate_string(): wrong number of arguments (#{args.length}; must be > 0)") end diff --git a/spec/aliases/absolute_path_spec.rb b/spec/aliases/absolute_path_spec.rb new file mode 100644 index 0000000..0bcdf85 --- /dev/null +++ b/spec/aliases/absolute_path_spec.rb @@ -0,0 +1,62 @@ +require 'spec_helper' + +if Puppet.version.to_f >= 4.0 + describe 'test::absolute_path', type: :class do + describe 'valid paths handling' do + %w{ + C:/ + C:\\ + C:\\WINDOWS\\System32 + C:/windows/system32 + X:/foo/bar + X:\\foo\\bar + \\\\host\\windows + //host/windows + / + /var/tmp + /var/opt/../lib/puppet + }.each do |value| + describe value.inspect do + let(:params) {{ value: value }} + it { is_expected.to compile } + end + end + end + + describe 'invalid path handling' do + context 'garbage inputs' do + [ + nil, + [ nil ], + [ nil, nil ], + { 'foo' => 'bar' }, + { }, + '', + ].each do |value| + describe value.inspect do + let(:params) {{ value: value }} + it { is_expected.to compile.and_raise_error(/parameter 'value' expects a match for Stdlib::Compat::Absolute_path/) } + end + end + end + + context 'relative paths' do + %w{ + relative1 + . + .. + ./foo + ../foo + etc/puppetlabs/puppet + opt/puppet/bin + relative\\windows + }.each do |value| + describe value.inspect do + let(:params) {{ value: value }} + it { is_expected.to compile.and_raise_error(/parameter 'value' expects a match for Stdlib::Compat::Absolute_path/) } + end + end + end + end + end +end diff --git a/spec/aliases/array_spec.rb b/spec/aliases/array_spec.rb new file mode 100644 index 0000000..8bbb8b3 --- /dev/null +++ b/spec/aliases/array_spec.rb @@ -0,0 +1,34 @@ +require 'spec_helper' + +if Puppet.version.to_f >= 4.0 + describe 'test::array', type: :class do + describe 'accepts arrays' do + [ + [], + ['one'], + [1], + [{}], + [[]], + ].each do |value| + describe value.inspect do + let(:params) {{ value: value }} + it { is_expected.to compile } + end + end + end + + describe 'rejects other values' do + [ + '', + 'one', + '1', + {}, + ].each do |value| + describe value.inspect do + let(:params) {{ value: value }} + it { is_expected.to compile.and_raise_error(/parameter 'value' expects a Stdlib::Compat::Array/) } + end + end + end + end +end diff --git a/spec/aliases/bool_spec.rb b/spec/aliases/bool_spec.rb new file mode 100644 index 0000000..f664457 --- /dev/null +++ b/spec/aliases/bool_spec.rb @@ -0,0 +1,32 @@ +require 'spec_helper' + +if Puppet.version.to_f >= 4.0 + describe 'test::bool', type: :class do + describe 'accepts booleans' do + [ + true, + false, + ].each do |value| + describe value.inspect do + let(:params) {{ value: value }} + it { is_expected.to compile } + end + end + end + + describe 'rejects other values' do + [ + [1], + [{}], + [true], + 'true', + 'false', + ].each do |value| + describe value.inspect do + let(:params) {{ value: value }} + it { is_expected.to compile.and_raise_error(/parameter 'value' expects a Stdlib::Compat::Bool/) } + end + end + end + end +end diff --git a/spec/aliases/string_spec.rb b/spec/aliases/string_spec.rb new file mode 100644 index 0000000..8e01d55 --- /dev/null +++ b/spec/aliases/string_spec.rb @@ -0,0 +1,31 @@ +require 'spec_helper' + +if Puppet.version.to_f >= 4.0 + describe 'test::string', type: :class do + describe 'accepts strings' do + [ + '', + 'one', + ].each do |value| + describe value.inspect do + let(:params) {{ value: value }} + it { is_expected.to compile } + end + end + end + + describe 'rejects other values' do + [ + [], + {}, + 1, + true, + ].each do |value| + describe value.inspect do + let(:params) {{ value: value }} + it { is_expected.to compile.and_raise_error(/parameter 'value' expects a Stdlib::Compat::String = String/) } + end + end + end + end +end diff --git a/spec/fixtures/modules/test/manifests/absolute_path.pp b/spec/fixtures/modules/test/manifests/absolute_path.pp new file mode 100644 index 0000000..d77f6bd --- /dev/null +++ b/spec/fixtures/modules/test/manifests/absolute_path.pp @@ -0,0 +1,6 @@ +# Class to test the Stdlib::Compat::Absolute_path type alias +class test::absolute_path( + Stdlib::Compat::Absolute_path $value, + ) { + notice("Success") +} diff --git a/spec/fixtures/modules/test/manifests/array.pp b/spec/fixtures/modules/test/manifests/array.pp new file mode 100644 index 0000000..84b6a5b --- /dev/null +++ b/spec/fixtures/modules/test/manifests/array.pp @@ -0,0 +1,8 @@ +# Class to test the Stdlib::Compat::Array type alias +class test::array( + Stdlib::Compat::Array $value, + ) { + + notice("Success") + +} diff --git a/spec/fixtures/modules/test/manifests/bool.pp b/spec/fixtures/modules/test/manifests/bool.pp new file mode 100644 index 0000000..ab5b5ea --- /dev/null +++ b/spec/fixtures/modules/test/manifests/bool.pp @@ -0,0 +1,8 @@ +# Class to test the Stdlib::Compat::Bool type alias +class test::bool( + Stdlib::Compat::Bool $value, + ) { + + notice("Success") + +} diff --git a/spec/fixtures/modules/test/manifests/string.pp b/spec/fixtures/modules/test/manifests/string.pp new file mode 100644 index 0000000..6508c70 --- /dev/null +++ b/spec/fixtures/modules/test/manifests/string.pp @@ -0,0 +1,8 @@ +# Class to test the Stdlib::Compat::String type alias +class test::string( + Stdlib::Compat::String $value, + ) { + + notice("Success") + +} diff --git a/spec/functions/is_array_spec.rb b/spec/functions/is_array_spec.rb index 7dd21c2..e35ca44 100755 --- a/spec/functions/is_array_spec.rb +++ b/spec/functions/is_array_spec.rb @@ -2,6 +2,11 @@ require 'spec_helper' describe 'is_array' do it { is_expected.not_to eq(nil) } + # Checking for deprecation warning + it 'should display a single deprecation' do + scope.expects(:warn).with(includes('This method is deprecated')) + is_expected.to run.with_params([]) + end it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } it { pending("Current implementation ignores parameters after the first.") diff --git a/spec/functions/is_bool_spec.rb b/spec/functions/is_bool_spec.rb index 76d619b..9569856 100755 --- a/spec/functions/is_bool_spec.rb +++ b/spec/functions/is_bool_spec.rb @@ -2,6 +2,11 @@ require 'spec_helper' describe 'is_bool' do it { is_expected.not_to eq(nil) } + # Checking for deprecation warning + it 'should display a single deprecation' do + scope.expects(:warn).with(includes('This method is deprecated')) + is_expected.to run.with_params(true) + end it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } it { is_expected.to run.with_params(true, false).and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } it { is_expected.to run.with_params(true).and_return(true) } diff --git a/spec/functions/is_string_spec.rb b/spec/functions/is_string_spec.rb index 8e459cc..8056ed4 100755 --- a/spec/functions/is_string_spec.rb +++ b/spec/functions/is_string_spec.rb @@ -2,6 +2,11 @@ require 'spec_helper' describe 'is_string' do it { is_expected.not_to eq(nil) } + # Checking for deprecation warning + it 'should display a single deprecation' do + scope.expects(:warn).with(includes('This method is deprecated')) + is_expected.to run.with_params('ha') + end it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } it { pending("Current implementation ignores parameters after the first.") diff --git a/spec/functions/validate_absolute_path_spec.rb b/spec/functions/validate_absolute_path_spec.rb index 4a8404d..ffdb2c8 100755 --- a/spec/functions/validate_absolute_path_spec.rb +++ b/spec/functions/validate_absolute_path_spec.rb @@ -1,6 +1,13 @@ require 'spec_helper' describe 'validate_absolute_path' do + # Checking for deprecation warning + it 'should display a single deprecation' do + # called twice because validate_absolute_path calls is_absolute_path + scope.expects(:warn).with(includes('This method is deprecated')).twice + is_expected.to run.with_params('c:/') + end + 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) } diff --git a/spec/functions/validate_array_spec.rb b/spec/functions/validate_array_spec.rb index 4ee7754..0ba7108 100755 --- a/spec/functions/validate_array_spec.rb +++ b/spec/functions/validate_array_spec.rb @@ -3,6 +3,11 @@ require 'spec_helper' describe 'validate_array' do describe 'signature validation' do it { is_expected.not_to eq(nil) } + # Checking for deprecation warning + it 'should display a single deprecation' do + scope.expects(:warn).with(includes('This method is deprecated')) + is_expected.to run.with_params([]) + end it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } describe 'valid inputs' do diff --git a/spec/functions/validate_bool_spec.rb b/spec/functions/validate_bool_spec.rb index d9cdf57..b0f41a8 100755 --- a/spec/functions/validate_bool_spec.rb +++ b/spec/functions/validate_bool_spec.rb @@ -1,6 +1,13 @@ require 'spec_helper' describe 'validate_bool' do + # Checking for deprecation warning + it 'should display a single deprecation' do + #called twice, because validate_bool calls is_bool + scope.expects(:warn).with(includes('This method is deprecated')).twice + is_expected.to run.with_params(true) + end + 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) } diff --git a/spec/functions/validate_re_spec.rb b/spec/functions/validate_re_spec.rb index 3f90143..f6fa931 100755 --- a/spec/functions/validate_re_spec.rb +++ b/spec/functions/validate_re_spec.rb @@ -1,6 +1,12 @@ require 'spec_helper' describe 'validate_re' do + # Checking for deprecation warning + it 'should display a single deprecation' do + scope.expects(:warn).with(includes('This method is deprecated')) + is_expected.to run.with_params('', '') + end + 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) } diff --git a/spec/functions/validate_string_spec.rb b/spec/functions/validate_string_spec.rb index f0c500e..9bfef66 100755 --- a/spec/functions/validate_string_spec.rb +++ b/spec/functions/validate_string_spec.rb @@ -1,6 +1,12 @@ require 'spec_helper' describe 'validate_string' do + # Checking for deprecation warning + it 'should display a single deprecation' do + scope.expects(:warn).with(includes('This method is deprecated')) + is_expected.to run.with_params('', '') + end + 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) } diff --git a/types/compat/absolute_path.pp b/types/compat/absolute_path.pp new file mode 100644 index 0000000..d11784e --- /dev/null +++ b/types/compat/absolute_path.pp @@ -0,0 +1,7 @@ +# Emulate the is_absolute_path and validate_absolute_path functions +# +# The first pattern is originally from is_absolute_path, which had it from 2.7.x's lib/puppet/util.rb Puppet::Util.absolute_path? +# slash = '[\\\\/]' +# name = '[^\\\\/]+' +# %r!^(([A-Z]:#{slash})|(#{slash}#{slash}#{name}#{slash}#{name})|(#{slash}#{slash}\?#{slash}#{name}))!i, +type Stdlib::Compat::Absolute_path = Variant[Pattern[/^(([a-zA-Z]:[\\\/])|([\\\/][\\\/][^\\\/]+[\\\/][^\\\/]+)|([\\\/][\\\/]\?[\\\/][^\\\/]+))/], Pattern[/^\//]] diff --git a/types/compat/array.pp b/types/compat/array.pp new file mode 100644 index 0000000..ba65dc4 --- /dev/null +++ b/types/compat/array.pp @@ -0,0 +1,2 @@ +# Emulate the is_array and validate_array functions +type Stdlib::Compat::Array = Array[Any] diff --git a/types/compat/bool.pp b/types/compat/bool.pp new file mode 100644 index 0000000..dda5f4b --- /dev/null +++ b/types/compat/bool.pp @@ -0,0 +1,2 @@ + # Emulate the is_bool and validate_bool functions + type Stdlib::Compat::Bool = Boolean diff --git a/types/compat/re.pp b/types/compat/re.pp new file mode 100644 index 0000000..e4b5f30 --- /dev/null +++ b/types/compat/re.pp @@ -0,0 +1,3 @@ +# Emulate the validate_re function +# validate_re(value, re) translates to Pattern[re], which is not directly mappable as a type alias, but can be specified as Pattern[re]. +# Therefore this needs to be translated directly. diff --git a/types/compat/string.pp b/types/compat/string.pp new file mode 100644 index 0000000..4c36e5f --- /dev/null +++ b/types/compat/string.pp @@ -0,0 +1,2 @@ +# Emulate the is_string and validate_string functions +type Stdlib::Compat::String = String -- cgit v1.2.3 From 999c267a3871c7d59513869c94c43c3477f1c6f1 Mon Sep 17 00:00:00 2001 From: Helen Campbell Date: Wed, 10 Aug 2016 14:17:16 +0100 Subject: (MAINT) move test fixture to proper location --- spec/fixtures/modules/test/manifests/absolute_path.pp | 6 ------ spec/fixtures/modules/test/manifests/array.pp | 8 -------- spec/fixtures/modules/test/manifests/bool.pp | 8 -------- spec/fixtures/modules/test/manifests/float.pp | 8 -------- spec/fixtures/modules/test/manifests/integer.pp | 8 -------- spec/fixtures/modules/test/manifests/numeric.pp | 8 -------- spec/fixtures/modules/test/manifests/string.pp | 8 -------- spec/fixtures/test/manifests/absolute_path.pp | 6 ++++++ spec/fixtures/test/manifests/array.pp | 8 ++++++++ spec/fixtures/test/manifests/bool.pp | 8 ++++++++ spec/fixtures/test/manifests/float.pp | 8 ++++++++ spec/fixtures/test/manifests/integer.pp | 8 ++++++++ spec/fixtures/test/manifests/numeric.pp | 8 ++++++++ spec/fixtures/test/manifests/string.pp | 8 ++++++++ 14 files changed, 54 insertions(+), 54 deletions(-) delete mode 100644 spec/fixtures/modules/test/manifests/absolute_path.pp delete mode 100644 spec/fixtures/modules/test/manifests/array.pp delete mode 100644 spec/fixtures/modules/test/manifests/bool.pp delete mode 100644 spec/fixtures/modules/test/manifests/float.pp delete mode 100644 spec/fixtures/modules/test/manifests/integer.pp delete mode 100644 spec/fixtures/modules/test/manifests/numeric.pp delete mode 100644 spec/fixtures/modules/test/manifests/string.pp create mode 100644 spec/fixtures/test/manifests/absolute_path.pp create mode 100644 spec/fixtures/test/manifests/array.pp create mode 100644 spec/fixtures/test/manifests/bool.pp create mode 100644 spec/fixtures/test/manifests/float.pp create mode 100644 spec/fixtures/test/manifests/integer.pp create mode 100644 spec/fixtures/test/manifests/numeric.pp create mode 100644 spec/fixtures/test/manifests/string.pp diff --git a/spec/fixtures/modules/test/manifests/absolute_path.pp b/spec/fixtures/modules/test/manifests/absolute_path.pp deleted file mode 100644 index d77f6bd..0000000 --- a/spec/fixtures/modules/test/manifests/absolute_path.pp +++ /dev/null @@ -1,6 +0,0 @@ -# Class to test the Stdlib::Compat::Absolute_path type alias -class test::absolute_path( - Stdlib::Compat::Absolute_path $value, - ) { - notice("Success") -} diff --git a/spec/fixtures/modules/test/manifests/array.pp b/spec/fixtures/modules/test/manifests/array.pp deleted file mode 100644 index 84b6a5b..0000000 --- a/spec/fixtures/modules/test/manifests/array.pp +++ /dev/null @@ -1,8 +0,0 @@ -# Class to test the Stdlib::Compat::Array type alias -class test::array( - Stdlib::Compat::Array $value, - ) { - - notice("Success") - -} diff --git a/spec/fixtures/modules/test/manifests/bool.pp b/spec/fixtures/modules/test/manifests/bool.pp deleted file mode 100644 index ab5b5ea..0000000 --- a/spec/fixtures/modules/test/manifests/bool.pp +++ /dev/null @@ -1,8 +0,0 @@ -# Class to test the Stdlib::Compat::Bool type alias -class test::bool( - Stdlib::Compat::Bool $value, - ) { - - notice("Success") - -} diff --git a/spec/fixtures/modules/test/manifests/float.pp b/spec/fixtures/modules/test/manifests/float.pp deleted file mode 100644 index 03a603d..0000000 --- a/spec/fixtures/modules/test/manifests/float.pp +++ /dev/null @@ -1,8 +0,0 @@ -# Class to test the Stdlib::Compat::Float type alias -class test::float( - Stdlib::Compat::Float $value, - ) { - - notice("Success") - -} diff --git a/spec/fixtures/modules/test/manifests/integer.pp b/spec/fixtures/modules/test/manifests/integer.pp deleted file mode 100644 index a4f26df..0000000 --- a/spec/fixtures/modules/test/manifests/integer.pp +++ /dev/null @@ -1,8 +0,0 @@ -# Class to test the Stdlib::Compat::Integer type alias -class test::integer( - Stdlib::Compat::Integer $value, - ) { - - notice("Success") - -} diff --git a/spec/fixtures/modules/test/manifests/numeric.pp b/spec/fixtures/modules/test/manifests/numeric.pp deleted file mode 100644 index 2657ebc..0000000 --- a/spec/fixtures/modules/test/manifests/numeric.pp +++ /dev/null @@ -1,8 +0,0 @@ -# Class to test the Stdlib::Compat::Numeric type alias -class test::numeric( - Stdlib::Compat::Numeric $value, - ) { - - notice("Success") - -} diff --git a/spec/fixtures/modules/test/manifests/string.pp b/spec/fixtures/modules/test/manifests/string.pp deleted file mode 100644 index 6508c70..0000000 --- a/spec/fixtures/modules/test/manifests/string.pp +++ /dev/null @@ -1,8 +0,0 @@ -# Class to test the Stdlib::Compat::String type alias -class test::string( - Stdlib::Compat::String $value, - ) { - - notice("Success") - -} diff --git a/spec/fixtures/test/manifests/absolute_path.pp b/spec/fixtures/test/manifests/absolute_path.pp new file mode 100644 index 0000000..d77f6bd --- /dev/null +++ b/spec/fixtures/test/manifests/absolute_path.pp @@ -0,0 +1,6 @@ +# Class to test the Stdlib::Compat::Absolute_path type alias +class test::absolute_path( + Stdlib::Compat::Absolute_path $value, + ) { + notice("Success") +} diff --git a/spec/fixtures/test/manifests/array.pp b/spec/fixtures/test/manifests/array.pp new file mode 100644 index 0000000..84b6a5b --- /dev/null +++ b/spec/fixtures/test/manifests/array.pp @@ -0,0 +1,8 @@ +# Class to test the Stdlib::Compat::Array type alias +class test::array( + Stdlib::Compat::Array $value, + ) { + + notice("Success") + +} diff --git a/spec/fixtures/test/manifests/bool.pp b/spec/fixtures/test/manifests/bool.pp new file mode 100644 index 0000000..ab5b5ea --- /dev/null +++ b/spec/fixtures/test/manifests/bool.pp @@ -0,0 +1,8 @@ +# Class to test the Stdlib::Compat::Bool type alias +class test::bool( + Stdlib::Compat::Bool $value, + ) { + + notice("Success") + +} diff --git a/spec/fixtures/test/manifests/float.pp b/spec/fixtures/test/manifests/float.pp new file mode 100644 index 0000000..03a603d --- /dev/null +++ b/spec/fixtures/test/manifests/float.pp @@ -0,0 +1,8 @@ +# Class to test the Stdlib::Compat::Float type alias +class test::float( + Stdlib::Compat::Float $value, + ) { + + notice("Success") + +} diff --git a/spec/fixtures/test/manifests/integer.pp b/spec/fixtures/test/manifests/integer.pp new file mode 100644 index 0000000..a4f26df --- /dev/null +++ b/spec/fixtures/test/manifests/integer.pp @@ -0,0 +1,8 @@ +# Class to test the Stdlib::Compat::Integer type alias +class test::integer( + Stdlib::Compat::Integer $value, + ) { + + notice("Success") + +} diff --git a/spec/fixtures/test/manifests/numeric.pp b/spec/fixtures/test/manifests/numeric.pp new file mode 100644 index 0000000..2657ebc --- /dev/null +++ b/spec/fixtures/test/manifests/numeric.pp @@ -0,0 +1,8 @@ +# Class to test the Stdlib::Compat::Numeric type alias +class test::numeric( + Stdlib::Compat::Numeric $value, + ) { + + notice("Success") + +} diff --git a/spec/fixtures/test/manifests/string.pp b/spec/fixtures/test/manifests/string.pp new file mode 100644 index 0000000..6508c70 --- /dev/null +++ b/spec/fixtures/test/manifests/string.pp @@ -0,0 +1,8 @@ +# Class to test the Stdlib::Compat::String type alias +class test::string( + Stdlib::Compat::String $value, + ) { + + notice("Success") + +} -- cgit v1.2.3 From adf922c28441bc95f5cbac1f0951256c080b3298 Mon Sep 17 00:00:00 2001 From: Helen Campbell Date: Wed, 10 Aug 2016 14:17:16 +0100 Subject: (WIP) Addition of validate legacy function --- README.markdown | 11 +++++ lib/puppet/functions/validate_legacy.rb | 54 +++++++++++++++++++++++++ spec/classes/validate_legacy_spec.rb | 39 ++++++++++++++++++ spec/fixtures/test/manifests/validate_legacy.pp | 18 +++++++++ 4 files changed, 122 insertions(+) create mode 100644 lib/puppet/functions/validate_legacy.rb create mode 100644 spec/classes/validate_legacy_spec.rb create mode 100644 spec/fixtures/test/manifests/validate_legacy.pp diff --git a/README.markdown b/README.markdown index 0666b37..26fe55f 100644 --- a/README.markdown +++ b/README.markdown @@ -1368,6 +1368,17 @@ The following values will fail, causing compilation to abort: ~~~ +#### `validate_legacy` + +Validates a value against both a specified type and a deprecated validation function. Silently passes if both pass, errors if one validation passes and the other does not, fails if both validations return false. +Arguments include the type to check the value against, the full name of the previous validation function, the value itself to be checked, and an unspecified amount of arguments needed for the previous validation function. + +Example: + + ~~~ + validate_legacy("Optional[String]", "validate_re", "Value to be validated", ["."]) + ~~~ + #### `validate_numeric` Validates that the first argument is a numeric value (or an array of numeric values). Aborts catalog compilation if any of the checks fail. diff --git a/lib/puppet/functions/validate_legacy.rb b/lib/puppet/functions/validate_legacy.rb new file mode 100644 index 0000000..9d7d012 --- /dev/null +++ b/lib/puppet/functions/validate_legacy.rb @@ -0,0 +1,54 @@ +Puppet::Functions.create_function(:validate_legacy, Puppet::Functions::InternalFunction) do + # The function checks a value against both the target_type (new) and the previous_validation function (old). + + dispatch :validate_legacy do + param 'Type', :target_type + param 'String', :previous_validation + param 'NotUndef', :value + optional_param 'Any', :args + end + dispatch :validate_legacy_s do + scope_param + param 'String', :type_string + param 'String', :previous_validation + param 'NotUndef', :value + optional_repeated_param 'Any', :args + end + + def validate_legacy_s(scope, type_string, *args) + t = Puppet::Pops::Types::TypeParser.new.parse(type_string, scope) + validate_legacy(t, *args) + end + + def validate_legacy(target_type, previous_validation, value, *prev_args) + if assert_type(target_type, value) + if previous_validation(previous_validation, value, *prev_args) + # Silently passes + else + Puppet.warn("Accepting previously invalid value for target_type '#{target_type}'") + end + else + inferred_type = Puppet::Pops::Types::TypeCalculator.infer_set(value) + error_msg = Puppet::Pops::Types::TypeMismatchDescriber.new.describe_mismatch(previous_validation, target_type, inferred_type) + if previous_validation(previous_validation, value, *prev_args) + Puppet.warn(error_msg) + else + call_function('fail', error_msg) + end + end + end + + def previous_validation(previous_validation, value, *prev_args) + # Call the previous validation function and catch any errors. Return true if no errors are thrown. + begin + call_function(previous_validation, value, *prev_args) + true + rescue Puppet::ParseError + false + end + end + + def assert_type(type, value) + Puppet::Pops::Types::TypeCalculator.instance?(type, value) + end +end diff --git a/spec/classes/validate_legacy_spec.rb b/spec/classes/validate_legacy_spec.rb new file mode 100644 index 0000000..ded6890 --- /dev/null +++ b/spec/classes/validate_legacy_spec.rb @@ -0,0 +1,39 @@ +require 'spec_helper' + +if Puppet.version.to_f >= 4.0 + # validate_legacy requires a proper scope to run, so we have to trigger a true compilation here, + # instead of being able to leverage the function test group. + describe 'test::validate_legacy', type: :class do + + describe 'validate_legacy passes assertion of type but not previous validation' do + let(:params) {{ type: "Optional[Integer]", prev_validation: "validate_re", value: 5, previous_arg1: ["^\\d+$", ""] }} + it { + Puppet.expects(:warn).with(includes('Accepting previously invalid value for target_type')) + is_expected.to compile + } + end + + describe 'validate_legacy passes assertion of type and previous validation' do + let(:params) {{ type: "Optional[String]", prev_validation: "validate_re", value: "5", previous_arg1: ["."] }} + it { is_expected.to compile } + end + + describe 'validate_legacy fails assertion of type and passes previous validation' do + let(:params) {{ type: "Optional[Integer]", prev_validation: "validate_re", value: "5", previous_arg1: ["."] }} + it { + Puppet.expects(:warn).with(includes('expected')) + is_expected.to compile + } + end + + describe 'validate_legacy fails assertion and fails previous validation' do + let(:params) {{ type: "Optional[Integer]", prev_validation: "validate_re", value: "5", previous_arg1: ["thisisnotright"] }} + it { is_expected.to compile.and_raise_error(/Error while evaluating a Function Call, \w* expected an \w* value, got \w*/) } + end + + describe 'validate_legacy works with multi-argument validate_ functions' do + let(:params) {{ type: "Integer", prev_validation: "validate_integer", value: 10, previous_arg1: 100, previous_arg2: 0 }} + it { is_expected.to compile } + end + end +end diff --git a/spec/fixtures/test/manifests/validate_legacy.pp b/spec/fixtures/test/manifests/validate_legacy.pp new file mode 100644 index 0000000..706df88 --- /dev/null +++ b/spec/fixtures/test/manifests/validate_legacy.pp @@ -0,0 +1,18 @@ +# Class to test stdlib validate_legacy function + +class test::validate_legacy( + $type, + $prev_validation, + $value, + $previous_arg1, + $previous_arg2 = undef, + ) { + + if $previous_arg2 == undef { + validate_legacy( $type, $prev_validation, $value, $previous_arg1 ) + } else { + validate_legacy( $type, $prev_validation, $value, $previous_arg1, $previous_arg2 ) + } + notice("Success") + +} -- cgit v1.2.3 From 6991b28db1fd216f8fa5a29e2313f207a6d14537 Mon Sep 17 00:00:00 2001 From: David Schmitt Date: Sun, 14 Aug 2016 13:46:32 +0100 Subject: (MAINT) Update ensure_resource specs This updates the test to match the new behaviour in puppet 4.6.0 --- spec/functions/ensure_resource_spec.rb | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/spec/functions/ensure_resource_spec.rb b/spec/functions/ensure_resource_spec.rb index 9a17f5b..d552f4e 100755 --- a/spec/functions/ensure_resource_spec.rb +++ b/spec/functions/ensure_resource_spec.rb @@ -4,7 +4,12 @@ describe 'ensure_resource' do it { is_expected.not_to eq(nil) } it { is_expected.to run.with_params().and_raise_error(ArgumentError, /Must specify a type/) } it { is_expected.to run.with_params('type').and_raise_error(ArgumentError, /Must specify a title/) } - it { is_expected.to run.with_params('type', 'title', {}, 'extras').and_raise_error(Puppet::ParseError) } + if Puppet.version.to_f >= 4.6 + it { is_expected.to run.with_params('type', 'title', {}, 'extras').and_raise_error(ArgumentError) } + else + it { is_expected.to run.with_params('type', 'title', {}, 'extras').and_raise_error(Puppet::ParseError) } + end + it { pending("should not accept numbers as arguments") is_expected.to run.with_params(1,2,3).and_raise_error(Puppet::ParseError) -- cgit v1.2.3 From 39148468abbd9b8af74b776eb49f0a8388fc8541 Mon Sep 17 00:00:00 2001 From: Dominic Cleal Date: Mon, 15 Aug 2016 10:39:50 +0100 Subject: (maint) Switch 3.x deprecation() to use Puppet warning logger The deprecation function was calling the `Kernel#warn` function which prints to stderr, rather than the Puppet logger. This causes problems for Puppet module tests on Travis CI, which has a cap on the amount of stdout/err permitted in its logs and also prevents users from finding the deprecation warnings when running under a Puppet master. --- lib/puppet/parser/functions/deprecation.rb | 2 +- spec/functions/deprecation_spec.rb | 2 +- spec/functions/is_array_spec.rb | 2 +- spec/functions/is_bool_spec.rb | 2 +- spec/functions/is_float_spec.rb | 2 +- spec/functions/is_integer_spec.rb | 2 +- spec/functions/is_numeric_spec.rb | 2 +- spec/functions/is_string_spec.rb | 2 +- spec/functions/validate_absolute_path_spec.rb | 2 +- spec/functions/validate_array_spec.rb | 2 +- spec/functions/validate_bool_spec.rb | 2 +- spec/functions/validate_integer_spec.rb | 2 +- spec/functions/validate_numeric_spec.rb | 2 +- spec/functions/validate_re_spec.rb | 2 +- spec/functions/validate_string_spec.rb | 2 +- 15 files changed, 15 insertions(+), 15 deletions(-) diff --git a/lib/puppet/parser/functions/deprecation.rb b/lib/puppet/parser/functions/deprecation.rb index 5d74984..fc861a6 100644 --- a/lib/puppet/parser/functions/deprecation.rb +++ b/lib/puppet/parser/functions/deprecation.rb @@ -10,6 +10,6 @@ EOS key = arguments[0] message = arguments[1] - warn("deprecation. #{key}. #{message}") + warning("deprecation. #{key}. #{message}") end end diff --git a/spec/functions/deprecation_spec.rb b/spec/functions/deprecation_spec.rb index a596e24..c213190 100644 --- a/spec/functions/deprecation_spec.rb +++ b/spec/functions/deprecation_spec.rb @@ -46,7 +46,7 @@ else it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } it 'should display a single warning' do - scope.expects(:warn).with(includes('heelo')) + scope.expects(:warning).with(includes('heelo')) is_expected.to run.with_params('key', 'heelo') end end diff --git a/spec/functions/is_array_spec.rb b/spec/functions/is_array_spec.rb index e35ca44..0a8070b 100755 --- a/spec/functions/is_array_spec.rb +++ b/spec/functions/is_array_spec.rb @@ -4,7 +4,7 @@ describe 'is_array' do it { is_expected.not_to eq(nil) } # Checking for deprecation warning it 'should display a single deprecation' do - scope.expects(:warn).with(includes('This method is deprecated')) + scope.expects(:warning).with(includes('This method is deprecated')) is_expected.to run.with_params([]) end it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } diff --git a/spec/functions/is_bool_spec.rb b/spec/functions/is_bool_spec.rb index 9569856..4550e61 100755 --- a/spec/functions/is_bool_spec.rb +++ b/spec/functions/is_bool_spec.rb @@ -4,7 +4,7 @@ describe 'is_bool' do it { is_expected.not_to eq(nil) } # Checking for deprecation warning it 'should display a single deprecation' do - scope.expects(:warn).with(includes('This method is deprecated')) + scope.expects(:warning).with(includes('This method is deprecated')) is_expected.to run.with_params(true) end it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } diff --git a/spec/functions/is_float_spec.rb b/spec/functions/is_float_spec.rb index 267d9c6..cb7e148 100755 --- a/spec/functions/is_float_spec.rb +++ b/spec/functions/is_float_spec.rb @@ -5,7 +5,7 @@ describe 'is_float' do # Checking for deprecation warning it 'should display a single deprecation' do - scope.expects(:warn).with(includes('This method is deprecated')) + scope.expects(:warning).with(includes('This method is deprecated')) is_expected.to run.with_params(3) end diff --git a/spec/functions/is_integer_spec.rb b/spec/functions/is_integer_spec.rb index 49550c7..2d68731 100755 --- a/spec/functions/is_integer_spec.rb +++ b/spec/functions/is_integer_spec.rb @@ -5,7 +5,7 @@ describe 'is_integer' do # Checking for deprecation warning it 'should display a single deprecation' do - scope.expects(:warn).with(includes('This method is deprecated')) + scope.expects(:warning).with(includes('This method is deprecated')) is_expected.to run.with_params(3) end diff --git a/spec/functions/is_numeric_spec.rb b/spec/functions/is_numeric_spec.rb index b7de051..f4ead56 100755 --- a/spec/functions/is_numeric_spec.rb +++ b/spec/functions/is_numeric_spec.rb @@ -5,7 +5,7 @@ describe 'is_numeric' do # Checking for deprecation warning it 'should display a single deprecation' do - scope.expects(:warn).with(includes('This method is deprecated')) + scope.expects(:warning).with(includes('This method is deprecated')) is_expected.to run.with_params(3) end diff --git a/spec/functions/is_string_spec.rb b/spec/functions/is_string_spec.rb index 8056ed4..4f59b63 100755 --- a/spec/functions/is_string_spec.rb +++ b/spec/functions/is_string_spec.rb @@ -4,7 +4,7 @@ describe 'is_string' do it { is_expected.not_to eq(nil) } # Checking for deprecation warning it 'should display a single deprecation' do - scope.expects(:warn).with(includes('This method is deprecated')) + scope.expects(:warning).with(includes('This method is deprecated')) is_expected.to run.with_params('ha') end it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } diff --git a/spec/functions/validate_absolute_path_spec.rb b/spec/functions/validate_absolute_path_spec.rb index ffdb2c8..dbac88f 100755 --- a/spec/functions/validate_absolute_path_spec.rb +++ b/spec/functions/validate_absolute_path_spec.rb @@ -4,7 +4,7 @@ describe 'validate_absolute_path' do # Checking for deprecation warning it 'should display a single deprecation' do # called twice because validate_absolute_path calls is_absolute_path - scope.expects(:warn).with(includes('This method is deprecated')).twice + scope.expects(:warning).with(includes('This method is deprecated')).twice is_expected.to run.with_params('c:/') end diff --git a/spec/functions/validate_array_spec.rb b/spec/functions/validate_array_spec.rb index 0ba7108..9f2e210 100755 --- a/spec/functions/validate_array_spec.rb +++ b/spec/functions/validate_array_spec.rb @@ -5,7 +5,7 @@ describe 'validate_array' do it { is_expected.not_to eq(nil) } # Checking for deprecation warning it 'should display a single deprecation' do - scope.expects(:warn).with(includes('This method is deprecated')) + scope.expects(:warning).with(includes('This method is deprecated')) is_expected.to run.with_params([]) end it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } diff --git a/spec/functions/validate_bool_spec.rb b/spec/functions/validate_bool_spec.rb index b0f41a8..724e31f 100755 --- a/spec/functions/validate_bool_spec.rb +++ b/spec/functions/validate_bool_spec.rb @@ -4,7 +4,7 @@ describe 'validate_bool' do # Checking for deprecation warning it 'should display a single deprecation' do #called twice, because validate_bool calls is_bool - scope.expects(:warn).with(includes('This method is deprecated')).twice + scope.expects(:warning).with(includes('This method is deprecated')).twice is_expected.to run.with_params(true) end diff --git a/spec/functions/validate_integer_spec.rb b/spec/functions/validate_integer_spec.rb index 0eeab1e..3ca50b2 100755 --- a/spec/functions/validate_integer_spec.rb +++ b/spec/functions/validate_integer_spec.rb @@ -3,7 +3,7 @@ require 'spec_helper' describe 'validate_integer' do # Checking for deprecation warning it 'should display a single deprecation' do - scope.expects(:warn).with(includes('This method is deprecated')) + scope.expects(:warning).with(includes('This method is deprecated')) is_expected.to run.with_params(3) end diff --git a/spec/functions/validate_numeric_spec.rb b/spec/functions/validate_numeric_spec.rb index 2e5561e..2869e5f 100755 --- a/spec/functions/validate_numeric_spec.rb +++ b/spec/functions/validate_numeric_spec.rb @@ -3,7 +3,7 @@ require 'spec_helper' describe 'validate_numeric' do # Checking for deprecation warning it 'should display a single deprecation' do - scope.expects(:warn).with(includes('This method is deprecated')) + scope.expects(:warning).with(includes('This method is deprecated')) is_expected.to run.with_params(3) end diff --git a/spec/functions/validate_re_spec.rb b/spec/functions/validate_re_spec.rb index f6fa931..4b78a2e 100755 --- a/spec/functions/validate_re_spec.rb +++ b/spec/functions/validate_re_spec.rb @@ -3,7 +3,7 @@ require 'spec_helper' describe 'validate_re' do # Checking for deprecation warning it 'should display a single deprecation' do - scope.expects(:warn).with(includes('This method is deprecated')) + scope.expects(:warning).with(includes('This method is deprecated')) is_expected.to run.with_params('', '') end diff --git a/spec/functions/validate_string_spec.rb b/spec/functions/validate_string_spec.rb index 9bfef66..ef7a1b4 100755 --- a/spec/functions/validate_string_spec.rb +++ b/spec/functions/validate_string_spec.rb @@ -3,7 +3,7 @@ require 'spec_helper' describe 'validate_string' do # Checking for deprecation warning it 'should display a single deprecation' do - scope.expects(:warn).with(includes('This method is deprecated')) + scope.expects(:warning).with(includes('This method is deprecated')) is_expected.to run.with_params('', '') end -- cgit v1.2.3 From 6d185bdaa19f698270a0df4b0a0c05618864b955 Mon Sep 17 00:00:00 2001 From: Helen Campbell Date: Tue, 16 Aug 2016 11:55:05 +0100 Subject: Deprecation of ip functions --- lib/puppet/parser/functions/is_ip_address.rb | 2 ++ lib/puppet/parser/functions/is_ipv4_address.rb | 2 ++ lib/puppet/parser/functions/is_ipv6_address.rb | 2 ++ lib/puppet/parser/functions/validate_ip_address.rb | 2 ++ .../parser/functions/validate_ipv4_address.rb | 2 ++ .../parser/functions/validate_ipv6_address.rb | 2 ++ spec/aliases/ip_address.rb | 34 ++++++++++++++++++++++ spec/aliases/ipv4_spec.rb | 32 ++++++++++++++++++++ spec/aliases/ipv6_spec.rb | 30 +++++++++++++++++++ spec/fixtures/test/manifests/ip_address.pp | 6 ++++ spec/fixtures/test/manifests/ipv4.pp | 6 ++++ spec/fixtures/test/manifests/ipv6.pp | 6 ++++ spec/functions/is_ip_address_spec.rb | 5 ++++ spec/functions/is_ipv4_address_spec.rb | 17 +++++++++++ spec/functions/is_ipv6_address_spec.rb | 17 +++++++++++ spec/functions/validate_ip_address_spec.rb | 4 +++ spec/functions/validate_ipv4_address_spec.rb | 5 ++++ spec/functions/validate_ipv6_address_spec.rb | 4 +++ types/compat/ip_address.pp | 1 + types/compat/ipv4.pp | 2 ++ types/compat/ipv6.pp | 1 + 21 files changed, 182 insertions(+) create mode 100644 spec/aliases/ip_address.rb create mode 100644 spec/aliases/ipv4_spec.rb create mode 100644 spec/aliases/ipv6_spec.rb create mode 100644 spec/fixtures/test/manifests/ip_address.pp create mode 100644 spec/fixtures/test/manifests/ipv4.pp create mode 100644 spec/fixtures/test/manifests/ipv6.pp create mode 100644 spec/functions/is_ipv4_address_spec.rb create mode 100644 spec/functions/is_ipv6_address_spec.rb create mode 100644 types/compat/ip_address.pp create mode 100644 types/compat/ipv4.pp create mode 100644 types/compat/ipv6.pp diff --git a/lib/puppet/parser/functions/is_ip_address.rb b/lib/puppet/parser/functions/is_ip_address.rb index a90adab..1901b2c 100644 --- a/lib/puppet/parser/functions/is_ip_address.rb +++ b/lib/puppet/parser/functions/is_ip_address.rb @@ -10,6 +10,8 @@ Returns true if the string passed to this function is a valid IP address. require 'ipaddr' + function_deprecation([:puppet_3_type_check, 'This method is deprecated, please use the stdlib validate_legacy function, with Stdlib::Compat::Ip_address. There is further documentation for validate_legacy function in the README.']) + if (arguments.size != 1) then raise(Puppet::ParseError, "is_ip_address(): Wrong number of arguments "+ "given #{arguments.size} for 1") diff --git a/lib/puppet/parser/functions/is_ipv4_address.rb b/lib/puppet/parser/functions/is_ipv4_address.rb index b4861d5..c90fa64 100644 --- a/lib/puppet/parser/functions/is_ipv4_address.rb +++ b/lib/puppet/parser/functions/is_ipv4_address.rb @@ -10,6 +10,8 @@ Returns true if the string passed to this function is a valid IPv4 address. require 'ipaddr' + function_deprecation([:puppet_3_type_check, 'This method is deprecated, please use the stdlib validate_legacy function, with Stdlib::Compat::Ipv4. There is further documentation for validate_legacy function in the README.']) + if (arguments.size != 1) then raise(Puppet::ParseError, "is_ipv4_address(): Wrong number of arguments "+ "given #{arguments.size} for 1") diff --git a/lib/puppet/parser/functions/is_ipv6_address.rb b/lib/puppet/parser/functions/is_ipv6_address.rb index 475ad50..aec3483 100644 --- a/lib/puppet/parser/functions/is_ipv6_address.rb +++ b/lib/puppet/parser/functions/is_ipv6_address.rb @@ -8,6 +8,8 @@ Returns true if the string passed to this function is a valid IPv6 address. EOS ) do |arguments| + function_deprecation([:puppet_3_type_check, 'This method is deprecated, please use the stdlib validate_legacy function, with Stdlib::Compat::Ipv6. There is further documentation for validate_legacy function in the README.']) + require 'ipaddr' if (arguments.size != 1) then diff --git a/lib/puppet/parser/functions/validate_ip_address.rb b/lib/puppet/parser/functions/validate_ip_address.rb index 64fbd75..3377c76 100644 --- a/lib/puppet/parser/functions/validate_ip_address.rb +++ b/lib/puppet/parser/functions/validate_ip_address.rb @@ -23,6 +23,8 @@ module Puppet::Parser::Functions require "ipaddr" rescuable_exceptions = [ ArgumentError ] + function_deprecation([:puppet_3_type_check, 'This method is deprecated, please use the stdlib validate_legacy function, with Stdlib::Compat::Ip_address. There is further documentation for validate_legacy function in the README.']) + if defined?(IPAddr::InvalidAddressError) rescuable_exceptions << IPAddr::InvalidAddressError end diff --git a/lib/puppet/parser/functions/validate_ipv4_address.rb b/lib/puppet/parser/functions/validate_ipv4_address.rb index 97faa57..fb2260c 100644 --- a/lib/puppet/parser/functions/validate_ipv4_address.rb +++ b/lib/puppet/parser/functions/validate_ipv4_address.rb @@ -18,6 +18,8 @@ module Puppet::Parser::Functions ENDHEREDOC ) do |args| + function_deprecation([:puppet_3_type_check, 'This method is deprecated, please use the stdlib validate_legacy function, with Stdlib::Compat::Ipv4. There is further documentation for validate_legacy function in the README.']) + require "ipaddr" rescuable_exceptions = [ ArgumentError ] diff --git a/lib/puppet/parser/functions/validate_ipv6_address.rb b/lib/puppet/parser/functions/validate_ipv6_address.rb index b0f2558..4dedcd6 100644 --- a/lib/puppet/parser/functions/validate_ipv6_address.rb +++ b/lib/puppet/parser/functions/validate_ipv6_address.rb @@ -19,6 +19,8 @@ module Puppet::Parser::Functions ENDHEREDOC ) do |args| + function_deprecation([:puppet_3_type_check, 'This method is deprecated, please use the stdlib validate_legacy function, with Stdlib::Compat::Ipv6. There is further documentation for validate_legacy function in the README.']) + require "ipaddr" rescuable_exceptions = [ ArgumentError ] diff --git a/spec/aliases/ip_address.rb b/spec/aliases/ip_address.rb new file mode 100644 index 0000000..036bfe5 --- /dev/null +++ b/spec/aliases/ip_address.rb @@ -0,0 +1,34 @@ +require 'spec_helper' + +if Puppet.version.to_f >= 4.0 + describe 'test::ip_address', type: :class do + describe 'accepts ipv4 and ipv6 addresses' do + [ + '224.0.0.0', + '255.255.255.255', + '0.0.0.0', + '192.88.99.0', + '2001:0db8:85a3:0000:0000:8a2e:0370:7334', + 'fa76:8765:34ac:0823:ab76:eee9:0987:1111' + ].each do |value| + describe value.inspect do + let(:params) {{ value: value }} + it { is_expected.to compile } + end + end + end + describe 'rejects other values' do + [ + 'nope', + '77', + '4.4.4', + '2001:0db8:85a3:000000:0000:8a2e:0370:7334' + ].each do |value| + describe value.inspect do + let(:params) {{ value: value }} + it { is_expected.to compile.and_raise_error(/parameter 'value' expects a match for/) } + end + end + end + end +end diff --git a/spec/aliases/ipv4_spec.rb b/spec/aliases/ipv4_spec.rb new file mode 100644 index 0000000..640618c --- /dev/null +++ b/spec/aliases/ipv4_spec.rb @@ -0,0 +1,32 @@ +require 'spec_helper' + +if Puppet.version.to_f >= 4.0 + describe 'test::ipv4', type: :class do + describe 'accepts ipv4 addresses' do + [ + '224.0.0.0', + '255.255.255.255', + '0.0.0.0', + '192.88.99.0' + ].each do |value| + describe value.inspect do + let(:params) {{ value: value }} + it { is_expected.to compile } + end + end + end + describe 'rejects other values' do + [ + 'nope', + '77', + '4.4.4', + '2001:0db8:85a3:0000:0000:8a2e:0370:73342001:0db8:85a3:0000:0000:8a2e:0370:7334' + ].each do |value| + describe value.inspect do + let(:params) {{ value: value }} + it { is_expected.to compile.and_raise_error(/parameter 'value' expects a match for Stdlib::Compat::Ipv4/) } + end + end + end + end +end diff --git a/spec/aliases/ipv6_spec.rb b/spec/aliases/ipv6_spec.rb new file mode 100644 index 0000000..688eb16 --- /dev/null +++ b/spec/aliases/ipv6_spec.rb @@ -0,0 +1,30 @@ +require 'spec_helper' + +if Puppet.version.to_f >= 4.0 + describe 'test::ipv6', type: :class do + describe 'accepts ipv6 addresses' do + [ + '2001:0db8:85a3:0000:0000:8a2e:0370:7334', + 'fa76:8765:34ac:0823:ab76:eee9:0987:1111' + ].each do |value| + describe value.inspect do + let(:params) {{ value: value }} + it { is_expected.to compile } + end + end + end + describe 'rejects other values' do + [ + 'nope', + '77', + '4.4.4', + '2000:7334' + ].each do |value| + describe value.inspect do + let(:params) {{ value: value }} + it { is_expected.to compile.and_raise_error(/parameter 'value' expects a match for Stdlib::Compat::Ipv6/) } + end + end + end + end +end diff --git a/spec/fixtures/test/manifests/ip_address.pp b/spec/fixtures/test/manifests/ip_address.pp new file mode 100644 index 0000000..bbbd804 --- /dev/null +++ b/spec/fixtures/test/manifests/ip_address.pp @@ -0,0 +1,6 @@ +# Class to test the Stdlib::Compat::Ip_address type alias +class test::ip_address( + Stdlib::Compat::Ip_address $value, + ) { + notice("Success") + } diff --git a/spec/fixtures/test/manifests/ipv4.pp b/spec/fixtures/test/manifests/ipv4.pp new file mode 100644 index 0000000..2e8022d --- /dev/null +++ b/spec/fixtures/test/manifests/ipv4.pp @@ -0,0 +1,6 @@ +# Class to test the Stdlib::Compat::Ipv4 type alias +class test::ipv4( + Stdlib::Compat::Ipv4 $value, + ) { + notice("Success") + } diff --git a/spec/fixtures/test/manifests/ipv6.pp b/spec/fixtures/test/manifests/ipv6.pp new file mode 100644 index 0000000..7912fd6 --- /dev/null +++ b/spec/fixtures/test/manifests/ipv6.pp @@ -0,0 +1,6 @@ +# Class to test the Stdlib::Compat::Ipv6 type alias +class test::ipv6( + Stdlib::Compat::Ipv6 $value, + ) { + notice("Success") +} diff --git a/spec/functions/is_ip_address_spec.rb b/spec/functions/is_ip_address_spec.rb index a7a383a..9386ca9 100755 --- a/spec/functions/is_ip_address_spec.rb +++ b/spec/functions/is_ip_address_spec.rb @@ -20,4 +20,9 @@ describe 'is_ip_address' do it { is_expected.to run.with_params(1).and_return(false) } it { is_expected.to run.with_params({}).and_return(false) } it { is_expected.to run.with_params([]).and_return(false) } + # Checking for deprecation warning + it 'should display a single deprecation' do + scope.expects(:warning).with(includes('This method is deprecated')) + is_expected.to run.with_params('1.1.1.1') + end end diff --git a/spec/functions/is_ipv4_address_spec.rb b/spec/functions/is_ipv4_address_spec.rb new file mode 100644 index 0000000..2b9fc49 --- /dev/null +++ b/spec/functions/is_ipv4_address_spec.rb @@ -0,0 +1,17 @@ +require 'spec_helper' + +describe 'is_ipv4_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('1.2.3.4').and_return(true) } + it { is_expected.to run.with_params('1.2.3.255').and_return(true) } + it { is_expected.to run.with_params('1.2.3').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('one').and_return(false) } + # Checking for deprecation warning + it 'should display a single deprecation' do + scope.expects(:warning).with(includes('This method is deprecated')) + is_expected.to run.with_params('1.1.1.1') + end +end diff --git a/spec/functions/is_ipv6_address_spec.rb b/spec/functions/is_ipv6_address_spec.rb new file mode 100644 index 0000000..e3e4734 --- /dev/null +++ b/spec/functions/is_ipv6_address_spec.rb @@ -0,0 +1,17 @@ +require 'spec_helper' + +describe 'is_ipv6_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('2001:0db8:85a3:0000:0000:8a2e:0370:7334').and_return(true) } + it { is_expected.to run.with_params('85a3:0000:0000:8a2e:0370:7334:100.100.100.100').and_return(true) } + it { is_expected.to run.with_params('1.2.3').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('one').and_return(false) } + # Checking for deprecation warning + it 'should display a single deprecation' do + scope.expects(:warning).with(includes('This method is deprecated')) + is_expected.to run.with_params('2001:0db8:85a3:0000:0000:8a2e:0370:7334') + end +end diff --git a/spec/functions/validate_ip_address_spec.rb b/spec/functions/validate_ip_address_spec.rb index b56ce51..10f6c37 100644 --- a/spec/functions/validate_ip_address_spec.rb +++ b/spec/functions/validate_ip_address_spec.rb @@ -19,6 +19,10 @@ describe 'validate_ip_address' do it { is_expected.to run.with_params('3ffe:0505:0002::', '3ffe:0505:0002::2') } it { is_expected.to run.with_params('::1/64') } it { is_expected.to run.with_params('fe80::a00:27ff:fe94:44d6/64') } + it 'should display a single deprecation' do + scope.expects(:warning).with(includes('This method is deprecated')) + is_expected.to run.with_params('1.1.1.1') + end context 'with netmasks' do it { is_expected.to run.with_params('8.8.8.8/0') } it { is_expected.to run.with_params('8.8.8.8/16') } diff --git a/spec/functions/validate_ipv4_address_spec.rb b/spec/functions/validate_ipv4_address_spec.rb index b6170d4..b67bf6f 100755 --- a/spec/functions/validate_ipv4_address_spec.rb +++ b/spec/functions/validate_ipv4_address_spec.rb @@ -5,6 +5,11 @@ describe 'validate_ipv4_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 'should display a single deprecation' do + scope.expects(:warning).with(includes('This method is deprecated')) + is_expected.to run.with_params('1.1.1.1') + end + describe 'valid inputs' do it { is_expected.to run.with_params('0.0.0.0') } it { is_expected.to run.with_params('8.8.8.8') } diff --git a/spec/functions/validate_ipv6_address_spec.rb b/spec/functions/validate_ipv6_address_spec.rb index 7aaf006..3afab56 100755 --- a/spec/functions/validate_ipv6_address_spec.rb +++ b/spec/functions/validate_ipv6_address_spec.rb @@ -10,6 +10,10 @@ describe 'validate_ipv6_address' do it { is_expected.to run.with_params('3ffe:0505:0002::', '3ffe:0505:0002::2') } it { is_expected.to run.with_params('::1/64') } it { is_expected.to run.with_params('fe80::a00:27ff:fe94:44d6/64') } + it 'should display a single deprecation' do + scope.expects(:warning).with(includes('This method is deprecated')) + is_expected.to run.with_params('3ffe:0505:0002::') + end end describe 'invalid inputs' do diff --git a/types/compat/ip_address.pp b/types/compat/ip_address.pp new file mode 100644 index 0000000..bf4c4b4 --- /dev/null +++ b/types/compat/ip_address.pp @@ -0,0 +1 @@ +type Stdlib::Compat::Ip_address = Variant[Stdlib::Compat::Ipv4, Stdlib::Compat::Ipv6] diff --git a/types/compat/ipv4.pp b/types/compat/ipv4.pp new file mode 100644 index 0000000..1d72ebd --- /dev/null +++ b/types/compat/ipv4.pp @@ -0,0 +1,2 @@ +# Emulate the validate_ipv4_address and is_ipv4_address functions +type Stdlib::Compat::Ipv4 = Pattern[/^(\d+)\.(\d+)\.(\d+)\.(\d+)$/] diff --git a/types/compat/ipv6.pp b/types/compat/ipv6.pp new file mode 100644 index 0000000..18b148d --- /dev/null +++ b/types/compat/ipv6.pp @@ -0,0 +1 @@ +type Stdlib::Compat::Ipv6 = Pattern[/^(?:(?:[\da-f]{1,4}:){7}[\da-f]{1,4}|((?:[\da-f]{1,4}:){6})(\d+)\.(\d+)\.(\d+)\.(\d+))$/] -- cgit v1.2.3 From 43d634fc85a5d1759b1dba0a858d80bca378c758 Mon Sep 17 00:00:00 2001 From: David Schmitt Date: Fri, 26 Aug 2016 09:28:58 +0200 Subject: Update modulesync_config [a3fe424] --- .rubocop.yml | 508 ++++++++++++++++++++++++++++++ .travis.yml | 9 +- Gemfile | 57 ++-- Rakefile | 8 - spec/acceptance/nodesets/centos-7-x64.yml | 2 +- 5 files changed, 546 insertions(+), 38 deletions(-) create mode 100644 .rubocop.yml diff --git a/.rubocop.yml b/.rubocop.yml new file mode 100644 index 0000000..5aadd1b --- /dev/null +++ b/.rubocop.yml @@ -0,0 +1,508 @@ +require: rubocop-rspec +AllCops: + TargetRubyVersion: 1.9 + Include: + - ./**/*.rb + Exclude: + - vendor/**/* + - .vendor/**/* + - pkg/**/* + - spec/fixtures/**/* +Lint/ConditionPosition: + Enabled: True + +Lint/ElseLayout: + Enabled: True + +Lint/UnreachableCode: + Enabled: True + +Lint/UselessComparison: + Enabled: True + +Lint/EnsureReturn: + Enabled: True + +Lint/HandleExceptions: + Enabled: True + +Lint/LiteralInCondition: + Enabled: True + +Lint/ShadowingOuterLocalVariable: + Enabled: True + +Lint/LiteralInInterpolation: + Enabled: True + +Style/HashSyntax: + Enabled: True + +Style/RedundantReturn: + Enabled: True + +Lint/AmbiguousOperator: + Enabled: True + +Lint/AssignmentInCondition: + Enabled: True + +Style/SpaceBeforeComment: + Enabled: True + +Style/AndOr: + Enabled: True + +Style/RedundantSelf: + Enabled: True + +# Method length is not necessarily an indicator of code quality +Metrics/MethodLength: + Enabled: False + +# Module length is not necessarily an indicator of code quality +Metrics/ModuleLength: + Enabled: False + +Style/WhileUntilModifier: + Enabled: True + +Lint/AmbiguousRegexpLiteral: + Enabled: True + +Lint/Eval: + Enabled: True + +Lint/BlockAlignment: + Enabled: True + +Lint/DefEndAlignment: + Enabled: True + +Lint/EndAlignment: + Enabled: True + +Lint/DeprecatedClassMethods: + Enabled: True + +Lint/Loop: + Enabled: True + +Lint/ParenthesesAsGroupedExpression: + Enabled: True + +Lint/RescueException: + Enabled: True + +Lint/StringConversionInInterpolation: + Enabled: True + +Lint/UnusedBlockArgument: + Enabled: True + +Lint/UnusedMethodArgument: + Enabled: True + +Lint/UselessAccessModifier: + Enabled: True + +Lint/UselessAssignment: + Enabled: True + +Lint/Void: + Enabled: True + +Style/AccessModifierIndentation: + Enabled: True + +Style/AccessorMethodName: + Enabled: True + +Style/Alias: + Enabled: True + +Style/AlignArray: + Enabled: True + +Style/AlignHash: + Enabled: True + +Style/AlignParameters: + Enabled: True + +Metrics/BlockNesting: + Enabled: True + +Style/AsciiComments: + Enabled: True + +Style/Attr: + Enabled: True + +Style/BracesAroundHashParameters: + Enabled: True + +Style/CaseEquality: + Enabled: True + +Style/CaseIndentation: + Enabled: True + +Style/CharacterLiteral: + Enabled: True + +Style/ClassAndModuleCamelCase: + Enabled: True + +Style/ClassAndModuleChildren: + Enabled: False + +Style/ClassCheck: + Enabled: True + +# Class length is not necessarily an indicator of code quality +Metrics/ClassLength: + Enabled: False + +Style/ClassMethods: + Enabled: True + +Style/ClassVars: + Enabled: True + +Style/WhenThen: + Enabled: True + +Style/WordArray: + Enabled: True + +Style/UnneededPercentQ: + Enabled: True + +Style/Tab: + Enabled: True + +Style/SpaceBeforeSemicolon: + Enabled: True + +Style/TrailingBlankLines: + Enabled: True + +Style/SpaceInsideBlockBraces: + Enabled: True + +Style/SpaceInsideBrackets: + Enabled: True + +Style/SpaceInsideHashLiteralBraces: + Enabled: True + +Style/SpaceInsideParens: + Enabled: True + +Style/LeadingCommentSpace: + Enabled: True + +Style/SpaceBeforeFirstArg: + Enabled: True + +Style/SpaceAfterColon: + Enabled: True + +Style/SpaceAfterComma: + Enabled: True + +Style/SpaceAfterMethodName: + Enabled: True + +Style/SpaceAfterNot: + Enabled: True + +Style/SpaceAfterSemicolon: + Enabled: True + +Style/SpaceAroundEqualsInParameterDefault: + Enabled: True + +Style/SpaceAroundOperators: + Enabled: True + +Style/SpaceBeforeBlockBraces: + Enabled: True + +Style/SpaceBeforeComma: + Enabled: True + +Style/CollectionMethods: + Enabled: True + +Style/CommentIndentation: + Enabled: True + +Style/ColonMethodCall: + Enabled: True + +Style/CommentAnnotation: + Enabled: True + +# 'Complexity' is very relative +Metrics/CyclomaticComplexity: + Enabled: False + +Style/ConstantName: + Enabled: True + +Style/Documentation: + Enabled: False + +Style/DefWithParentheses: + Enabled: True + +Style/PreferredHashMethods: + Enabled: True + +Style/DotPosition: + EnforcedStyle: trailing + +Style/DoubleNegation: + Enabled: True + +Style/EachWithObject: + Enabled: True + +Style/EmptyLineBetweenDefs: + Enabled: True + +Style/IndentArray: + Enabled: True + +Style/IndentHash: + Enabled: True + +Style/IndentationConsistency: + Enabled: True + +Style/IndentationWidth: + Enabled: True + +Style/EmptyLines: + Enabled: True + +Style/EmptyLinesAroundAccessModifier: + Enabled: True + +Style/EmptyLiteral: + Enabled: True + +# Configuration parameters: AllowURI, URISchemes. +Metrics/LineLength: + Enabled: False + +Style/MethodCallParentheses: + Enabled: True + +Style/MethodDefParentheses: + Enabled: True + +Style/LineEndConcatenation: + Enabled: True + +Style/TrailingWhitespace: + Enabled: True + +Style/StringLiterals: + Enabled: True + +Style/TrailingCommaInArguments: + Enabled: True + +Style/TrailingCommaInLiteral: + Enabled: True + +Style/GlobalVars: + Enabled: True + +Style/GuardClause: + Enabled: True + +Style/IfUnlessModifier: + Enabled: True + +Style/MultilineIfThen: + Enabled: True + +Style/NegatedIf: + Enabled: True + +Style/NegatedWhile: + Enabled: True + +Style/Next: + Enabled: True + +Style/SingleLineBlockParams: + Enabled: True + +Style/SingleLineMethods: + Enabled: True + +Style/SpecialGlobalVars: + Enabled: True + +Style/TrivialAccessors: + Enabled: True + +Style/UnlessElse: + Enabled: True + +Style/VariableInterpolation: + Enabled: True + +Style/VariableName: + Enabled: True + +Style/WhileUntilDo: + Enabled: True + +Style/EvenOdd: + Enabled: True + +Style/FileName: + Enabled: True + +Style/For: + Enabled: True + +Style/Lambda: + Enabled: True + +Style/MethodName: + Enabled: True + +Style/MultilineTernaryOperator: + Enabled: True + +Style/NestedTernaryOperator: + Enabled: True + +Style/NilComparison: + Enabled: True + +Style/FormatString: + Enabled: True + +Style/MultilineBlockChain: + Enabled: True + +Style/Semicolon: + Enabled: True + +Style/SignalException: + Enabled: True + +Style/NonNilCheck: + Enabled: True + +Style/Not: + Enabled: True + +Style/NumericLiterals: + Enabled: True + +Style/OneLineConditional: + Enabled: True + +Style/OpMethod: + Enabled: True + +Style/ParenthesesAroundCondition: + Enabled: True + +Style/PercentLiteralDelimiters: + Enabled: True + +Style/PerlBackrefs: + Enabled: True + +Style/PredicateName: + Enabled: True + +Style/RedundantException: + Enabled: True + +Style/SelfAssignment: + Enabled: True + +Style/Proc: + Enabled: True + +Style/RaiseArgs: + Enabled: True + +Style/RedundantBegin: + Enabled: True + +Style/RescueModifier: + Enabled: True + +# based on https://github.com/voxpupuli/modulesync_config/issues/168 +Style/RegexpLiteral: + EnforcedStyle: percent_r + Enabled: True + +Lint/UnderscorePrefixedVariableName: + Enabled: True + +Metrics/ParameterLists: + Enabled: False + +Lint/RequireParentheses: + Enabled: True + +Style/SpaceBeforeFirstArg: + Enabled: True + +Style/ModuleFunction: + Enabled: True + +Lint/Debugger: + Enabled: True + +Style/IfWithSemicolon: + Enabled: True + +Style/Encoding: + Enabled: True + +Style/BlockDelimiters: + Enabled: True + +Style/MultilineBlockLayout: + Enabled: True + +# 'Complexity' is very relative +Metrics/AbcSize: + Enabled: False + +# 'Complexity' is very relative +Metrics/PerceivedComplexity: + Enabled: False + +Lint/UselessAssignment: + Enabled: True + +Style/ClosingParenthesisIndentation: + Enabled: False + +# RSpec + +# We don't use rspec in this way +RSpec/DescribeClass: + Enabled: False + +# Example length is not necessarily an indicator of code quality +RSpec/ExampleLength: + Enabled: False + +RSpec/NamedSubject: + Enabled: False diff --git a/.travis.yml b/.travis.yml index f631db0..4e549bf 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,21 +7,24 @@ script: "bundle exec rake validate lint spec" matrix: fast_finish: true include: - - rvm: 2.1.6 + - rvm: 2.3.1 dist: trusty env: PUPPET_INSTALL_TYPE=agent BEAKER_debug=true BEAKER_set=docker/ubuntu-14.04 script: bundle exec rake beaker services: docker sudo: required - - rvm: 2.1.6 + - rvm: 2.3.1 dist: trusty env: PUPPET_INSTALL_TYPE=agent BEAKER_debug=true BEAKER_set=docker/centos-7 script: bundle exec rake beaker services: docker sudo: required + - rvm: 2.3.1 + bundler_args: --without system_tests + env: PUPPET_GEM_VERSION="~> 4.0" - rvm: 2.1.9 bundler_args: --without system_tests - env: PUPPET_GEM_VERSION="~> 4.0" STRICT_VARIABLES="yes" + env: PUPPET_GEM_VERSION="~> 4.0" - rvm: 2.1.5 bundler_args: --without system_tests env: PUPPET_GEM_VERSION="~> 3.0" FUTURE_PARSER="yes" diff --git a/Gemfile b/Gemfile index 0fc6c18..c97275b 100644 --- a/Gemfile +++ b/Gemfile @@ -2,41 +2,46 @@ source ENV['GEM_SOURCE'] || "https://rubygems.org" -def location_for(place, version = nil) - if place =~ /^(git[:@][^#]*)#(.*)/ - [version, { :git => $1, :branch => $2, :require => false}].compact - elsif place =~ /^file:\/\/(.*)/ - ['>= 0', { :path => File.expand_path($1), :require => false}] +def location_from_env(env, default_location = []) + if location = ENV[env] + if location =~ /^((?:git|https?)[:@][^#]*)#(.*)/ + [{ :git => $1, :branch => $2, :require => false }] + elsif location =~ /^file:\/\/(.*)/ + ['>= 0', { :path => File.expand_path($1), :require => false }] + else + [location, { :require => false }] + end else - [place, version, { :require => false}].compact + default_location end end group :development, :unit_tests do - gem 'metadata-json-lint', :require => false - gem 'puppet_facts', :require => false - gem 'puppet-blacksmith', '>= 3.4.0', :require => false - gem 'puppetlabs_spec_helper', :git => 'git://github.com/puppetlabs/puppetlabs_spec_helper.git', :ref => '157a7fd', :require => false - gem 'rspec-puppet', '>= 2.3.2', :require => false - gem 'simplecov', :require => false + gem 'metadata-json-lint' + gem 'puppet_facts' + gem 'puppet-blacksmith', '>= 3.4.0' + gem 'puppetlabs_spec_helper', '>= 1.2.1' + gem 'rspec-puppet', '>= 2.3.2' + gem 'rspec-puppet-facts' + gem 'simplecov' + gem 'parallel_tests' + gem 'rubocop', '0.41.2' if RUBY_VERSION < '2.0.0' + gem 'rubocop' if RUBY_VERSION >= '2.0.0' + gem 'rubocop-rspec', '~> 1.6' if RUBY_VERSION >= '2.3.0' + gem 'json_pure', '<= 2.0.1' if RUBY_VERSION < '2.0.0' end group :system_tests do - 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']) + gem 'beaker', *location_from_env('BEAKER_VERSION', []) if RUBY_VERSION >= '2.3.0' + gem 'beaker', *location_from_env('BEAKER_VERSION', ['< 3']) if RUBY_VERSION < '2.3.0' + gem 'beaker-rspec', *location_from_env('BEAKER_RSPEC_VERSION', ['>= 3.4']) + gem 'serverspec' + gem 'beaker-puppet_install_helper' + gem 'master_manipulator' + gem 'beaker-hostgenerator', *location_from_env('BEAKER_HOSTGENERATOR_VERSION', []) end -# json_pure 2.0.2 added a requirement on ruby >= 2. We pin to json_pure 2.0.1 -# if using ruby 1.x -gem 'json_pure', '<=2.0.1', :require => false if RUBY_VERSION =~ /^1\./ -# rubocop 0.42.0 requires ruby >=2 -gem 'rubocop', '0.41.2', :require => false if RUBY_VERSION =~ /^1\./ - -gem 'facter', *location_for(ENV['FACTER_GEM_VERSION']) -gem 'puppet', *location_for(ENV['PUPPET_GEM_VERSION']) +gem 'facter', *location_from_env('FACTER_GEM_VERSION') +gem 'puppet', *location_from_env('PUPPET_GEM_VERSION') if File.exists? "#{__FILE__}.local" eval(File.read("#{__FILE__}.local"), binding) diff --git a/Rakefile b/Rakefile index 47a671e..3e8d4cb 100644 --- a/Rakefile +++ b/Rakefile @@ -2,17 +2,9 @@ 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_140chars') -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", "bundle/**/*", "vendor/**/*", "types/**/*"] - -if Puppet.version.to_f < 4.0 - PuppetSyntax.exclude_paths << "types/**/*" -end desc 'Generate pooler nodesets' task :gen_nodeset do diff --git a/spec/acceptance/nodesets/centos-7-x64.yml b/spec/acceptance/nodesets/centos-7-x64.yml index 1a40c89..5eebdef 100644 --- a/spec/acceptance/nodesets/centos-7-x64.yml +++ b/spec/acceptance/nodesets/centos-7-x64.yml @@ -3,7 +3,7 @@ HOSTS: roles: - agent - default - platform: redhat-7-x86_64 + platform: el-7-x86_64 hypervisor: vagrant box: puppetlabs/centos-7.2-64-nocm CONFIG: -- cgit v1.2.3 From 789263cab5ca2f38face3399076f4d3be34b3d3d Mon Sep 17 00:00:00 2001 From: Dmitry Ilyin Date: Tue, 30 Aug 2016 15:12:29 -0500 Subject: Refactor dig44 function The current implementation of the dig44 function has the following problems: * Doesn't recognise Puppet4's :undef value as an empty value and doesn't return the default value. * Doesn't make a different between false and nil value and returns the default value for a non-empty false value --- lib/puppet/parser/functions/dig44.rb | 41 ++++++++---- spec/functions/dig44_spec.rb | 119 ++++++++++++++++++++++++++--------- 2 files changed, 119 insertions(+), 41 deletions(-) diff --git a/lib/puppet/parser/functions/dig44.rb b/lib/puppet/parser/functions/dig44.rb index a7de363..d703380 100644 --- a/lib/puppet/parser/functions/dig44.rb +++ b/lib/puppet/parser/functions/dig44.rb @@ -1,23 +1,30 @@ -# -# dig44.rb +# +# dig44.rb # module Puppet::Parser::Functions - newfunction(:dig44, :type => :rvalue, :doc => <<-EOS + newfunction( + :dig44, + :type => :rvalue, + :arity => -2, + :doc => <<-eos DEPRECATED: This function has been replaced in puppet 4.5.0. -Looks up into a complex structure of arrays and hashes and returns nil +Looks up into a complex structure of arrays and hashes and returns a value or the default value if nothing was found. -Path is an array of keys to be looked up in data argument. The function -will go down the structure and try to extract the required value. +Key can contain slashes to describe path components. The function will go down +the structure and try to extract the required value. $data = { 'a' => { 'b' => [ 'b1', 'b2', - 'b3' ]}} + 'b3', + ] + } +} $value = dig44($data, ['a', 'b', '2'], 'not_found') => $value = 'b3' @@ -29,18 +36,18 @@ b -> second hash key not_found -> (optional) will be returned if there is no value or the path did not match. Defaults to nil. -In addition to the required "path" argument, "dig44" accepts default +In addition to the required "key" argument, the function accepts a default argument. It will be returned if no value was found or a path component is missing. And the fourth argument can set a variable path separator. - EOS - ) do |arguments| + eos + ) do |arguments| # Two arguments are required raise(Puppet::ParseError, "dig44(): Wrong number of arguments " + "given (#{arguments.size} for at least 2)") if arguments.size < 2 data, path, default = *arguments - if !(data.is_a?(Hash) || data.is_a?(Array)) + unless data.is_a?(Hash) or data.is_a?(Array) raise(Puppet::ParseError, "dig44(): first argument must be a hash or an array, " << "given #{data.class.name}") end @@ -50,7 +57,17 @@ missing. And the fourth argument can set a variable path separator. "given #{path.class.name}") end - value = path.reduce(data) { |h, k| (h.is_a?(Hash) || h.is_a?(Array)) ? h[k] : break } + value = path.reduce(data) do |structure, key| + if structure.is_a? Hash or structure.is_a? Array + if structure.is_a? Array + key = Integer key rescue break + end + break if structure[key].nil? or structure[key] == :undef + structure[key] + else + break + end + end value.nil? ? default : value end end diff --git a/spec/functions/dig44_spec.rb b/spec/functions/dig44_spec.rb index fd451ff..4f7408d 100644 --- a/spec/functions/dig44_spec.rb +++ b/spec/functions/dig44_spec.rb @@ -1,44 +1,105 @@ require 'spec_helper' describe 'dig44' do - it "should exist" do - expect(Puppet::Parser::Functions.function("dig44")).to eq("function_dig44") + + let(:data) do + { + 'a' => { + 'g' => '2', + 'e' => [ + 'f0', + 'f1', + { + 'x' => { + 'y' => 'z' + } + }, + 'f3', + ] + }, + 'b' => true, + 'c' => false, + 'd' => '1', + 'e' => :undef, + 'f' => nil, + } end - it "should raise a ParseError if there are less than 2 arguments" do - expect { scope.function_dig44([]) }.to raise_error(Puppet::ParseError) - end + context 'single values' do + it 'should exist' do + is_expected.not_to be_nil + end - it "should raise a ParseError if the first argument isn't a hash or array" do - expect { scope.function_dig44(['bad', []]) }.to raise_error(Puppet::ParseError) - end + it 'should require two arguments' do + is_expected.to run.with_params().and_raise_error(ArgumentError) + end - it "should raise a ParseError if the second argument isn't an array" do - expect { scope.function_dig44([{}, 'bad']) }.to raise_error(Puppet::ParseError) - end + it 'should fail if the data is not a structure' do + is_expected.to run.with_params('test', []).and_raise_error(Puppet::Error) + end - it "should return an empty hash when given empty parameters" do - result = scope.function_dig44([{}, []]) - expect(result).to(eq({})) - end + it 'should fail if the path is not an array' do + is_expected.to run.with_params({}, '').and_raise_error(Puppet::Error) + end - it "should return value when given simple hash" do - result = scope.function_dig44([{"a" => "b"}, ["a"]]) - expect(result).to(eq("b")) - end + it 'should return the value if the value is string' do + is_expected.to run.with_params(data, ['d'], 'default').and_return('1') + end - it "should find hash values two levels deep" do - result = scope.function_dig44([{"a" => {"b" => "c"}}, ["a", "b"]]) - expect(result).to(eq("c")) - end + it 'should return true if the value is true' do + is_expected.to run.with_params(data, ['b'], 'default').and_return(true) + end - it "should return default value if nothing was found" do - result = scope.function_dig44([{}, ["a", "b"], "d"]) - expect(result).to(eq("d")) + it 'should return false if the value is false' do + is_expected.to run.with_params(data, ['c'], 'default').and_return(false) + end + + it 'should return the default if the value is nil' do + is_expected.to run.with_params(data, ['f'], 'default').and_return('default') + end + + it 'should return the default if the value is :undef (same as nil)' do + is_expected.to run.with_params(data, ['e'], 'default').and_return('default') + end + + it 'should return the default if the path is not found' do + is_expected.to run.with_params(data, ['missing'], 'default').and_return('default') + end end - it "should work on booleans as well as strings" do - result = scope.function_dig44([{"a" => false}, ["a"]]) - expect(result).to(eq(false)) + context 'structure values' do + + it 'should be able to extract a deeply nested hash value' do + is_expected.to run.with_params(data, %w(a g), 'default').and_return('2') + end + + it 'should return the default value if the path is too long' do + is_expected.to run.with_params(data, %w(a g c d), 'default').and_return('default') + end + + it 'should support an array index (number) in the path' do + is_expected.to run.with_params(data, ['a', 'e', 1], 'default').and_return('f1') + end + + it 'should support an array index (string) in the path' do + is_expected.to run.with_params(data, %w(a e 1), 'default').and_return('f1') + end + + it 'should return the default value if an array index is not a number' do + is_expected.to run.with_params(data, %w(a b c), 'default').and_return('default') + end + + it 'should return the default value if and index is out of array length' do + is_expected.to run.with_params(data, %w(a e 5), 'default').and_return('default') + end + + it 'should be able to path though both arrays and hashes' do + is_expected.to run.with_params(data, %w(a e 2 x y), 'default').and_return('z') + end + + it 'should return "nil" if value is not found and no default value is provided' do + is_expected.to run.with_params(data, %w(a 1)).and_return(nil) + end + end end -- cgit v1.2.3 From cf2015de88961f7290399c2416a40ed9105bc3a2 Mon Sep 17 00:00:00 2001 From: David Schmitt Date: Mon, 15 Aug 2016 13:38:46 +0100 Subject: Update documentation for validate_legacy This adds a in-depth explanation of the process to migrate to Puppet 4 data types. --- README.markdown | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/README.markdown b/README.markdown index 26fe55f..13a5b74 100644 --- a/README.markdown +++ b/README.markdown @@ -1370,6 +1370,61 @@ The following values will fail, causing compilation to abort: #### `validate_legacy` +This function supports updating modules to upgrade from Puppet 3 style argument validation (using the stdlib `validate_*` functions) to Puppet 4 data types, without breaking the world. + +##### For module users + +You are probably here, because you're receiving loads of deprecation warnings about `validate_*` functions. If you're still on Puppet 3, use the options described in [`deprecation`](#deprecation) to silence the messages for now, and avoid upgrading to module versions which already have dropped Puppet 3 support. If you're already running Puppet 4 (shipped in Puppet Enterprise 2015.2 or later), please read on to understand the required steps to fix those issues. + +The `validate_*` functions were the only way on Puppet 3 to easily check the types of class and define arguments. Additionally some of the functions provided additional helpers like [validate_numeric](#validate_numeric), which would not only allow numbers, but also arrays of numbers. Puppet 4 now allows much better defined type checking using [data types](https://docs.puppet.com/puppet/latest/reference/lang_data.html), without such surprises. To avoid breaking the world for people depending on those surprises, `validate_legacy` provides a way to make those edge-cases visible, and assist people with getting onto the clearer Puppet 4 syntax. + +Depending on the current state of development of the modules you use and the data you feed them, you'll encounter different messages: + +* "Notice: Accepting previously invalid value for target type ''": Nothing to worry, you're already using values allowed by the new type, that would have been invalid by the old validation function. This is informational only. +* "Warning: This method is deprecated, please use the stdlib validate_legacy function": The module you're using hasn't yet upgraded to validate_legacy, use the options from [deprecation()](#deprecation) to silence the warnings for now, or submit a patch with you module's developer. See below for details. +* "Warning: validate_legacy() expected value, got ": Your code is passing a value to the module that was accepted by the Puppet v3 style validation, but that will not be accepted by the next version of the module. Most often this can be fixed by removing quotes from numbers, or booleans. +* "Error: Evaluation Error: Error while evaluating a Resource Statement, Evaluation Error: Error while evaluating a Function Call, validate_legacy() expected value, got ": Your code is passing a value that is not acceptable to either the new, or the old style validation. + + + + +##### For module developers + +Many `validate_*` functions have surprising holes in their validation. For example, [validate_numeric](#validate_numeric) would not only allow numbers, but also arrays of numbers, or strings that look like numbers, without giving you any control over the specifics. Contrast that to Puppet 4 [data types](https://docs.puppet.com/puppet/latest/reference/lang_data.html) which allow you to choose between `Numeric`, `Array[Numeric]`, or `Optional[Numeric]`. To get from here to there, without leaving your users behind, the validate_legacy function will provide you with a tool to make this migration as painless as possible. + +To start out, for each parameter of your classes and defines, you'll have to decide on a new Puppet 4 data type to use. In most cases the new data type will allow a different set of values than the original `validate_*` function (which is the point of the whole exercise). The situation then looks like this: + +| | `validate_` pass | `validate_` fail | +| matches type | pass | pass, notice | +| fails type | pass, deprecated | fail | + +The code after the validation will still have to deal with all possible values for now, but users of your code can now change their manifests to only pass values that will match the new type. + +To effect those checks, given a class like this: +~~~ +class example($value) { + validate_numeric($value) +~~~ +which should only accept numbers, the resulting validation code looks like this: +~~~ +class example( + Variant[Stdlib::Compat::Numeric, Numeric] $value +) { + validate_legacy(Numeric, 'validate_numeric', $value) +~~~ + +The type of `$value` is defined as `Variant[Stdlib::Compat::Numeric, Numeric]`, which will allow any `Numeric` (the new type), and all values previously accepted by validate_numeric (through `Stdlib::Compat::Numeric`). For each `validate_*` function in stdlib, there is a matching `Stdlib::Compat::*` type that will allow the appropriate set of values through. See the documentation in the `types/` directory in the stdlib source code for caveats. + +The call to `validate_legacy` will take care of triggering the correct log or fail message for you. It requires the new type, the previous validation function name, and all arguments to that function. + +If you were previously still supporting Puppet 3, this is a breaking change. You'll need to update your `metadata.json` to not support Puppet 3 anymore in the `requirements` section, and bump the major version of your module. This should still pass all previously existing tests your module has. Do not forget to add more tests for the newly possible values. This is also a good time to start calling [`deprecation()`](#deprecation) for all parameters you always wanted to get rid of, or add additional constraints on your parameters. + +After releasing this version, you can at any time release another breaking change release where you remove all compat types, and all calls to `validate_legacy`. At this time you can also go through your code and remove all leftovers dealing with the previously possible values. + +At all times note in the CHANGELOG and the README at what stage of the process your modules currently are. + +##### Reference + Validates a value against both a specified type and a deprecated validation function. Silently passes if both pass, errors if one validation passes and the other does not, fails if both validations return false. Arguments include the type to check the value against, the full name of the previous validation function, the value itself to be checked, and an unspecified amount of arguments needed for the previous validation function. -- cgit v1.2.3 From d2296c99d003f7c4a0e2243495be584ec3a20b91 Mon Sep 17 00:00:00 2001 From: Eric Putnam Date: Thu, 1 Sep 2016 11:35:25 -0700 Subject: (MODULES-3699) fixes deprecation msg test --- spec/acceptance/deprecation_spec.rb | 58 ++++++++++++++++++++++--------------- 1 file changed, 34 insertions(+), 24 deletions(-) diff --git a/spec/acceptance/deprecation_spec.rb b/spec/acceptance/deprecation_spec.rb index d0d7fed..ea13700 100644 --- a/spec/acceptance/deprecation_spec.rb +++ b/spec/acceptance/deprecation_spec.rb @@ -1,19 +1,29 @@ #! /usr/bin/env ruby -S rspec require 'spec_helper_acceptance' -require 'shellwords' describe 'deprecation function' do - before :each do - FileUtils.rm_rf '/tmp/deprecation' + + if fact('operatingsystem') == 'windows' + test_file = 'C:/deprecation' + else + test_file = "/tmp/deprecation" + end + + # It seems that Windows needs everything to be on one line when using puppet apply -e, otherwise the manifests would be in an easier format + add_file_manifest = "\"deprecation('key', 'message') file { '#{test_file}': ensure => present, content => 'test', }\"" + remove_file_manifest = "file { '#{test_file}': ensure => absent }" + + before :all do + apply_manifest(remove_file_manifest) end context 'with --strict=error', if: get_puppet_version =~ /^4/ do before :all do - pp = <<-EOS - deprecation('key', 'message') - file { '/tmp/deprecation': ensure => present } - EOS - @result = on(default, puppet('apply', '--strict=error', '-e', Shellwords.shellescape(pp)), acceptable_exit_codes: (0...256)) + @result = on(default, puppet('apply', '--strict=error', '-e', add_file_manifest), acceptable_exit_codes: (0...256)) + end + + after :all do + apply_manifest(remove_file_manifest) end it "should return an error" do @@ -24,18 +34,18 @@ describe 'deprecation function' do expect(@result.stderr).to match(/deprecation. key. message/) end - describe file('/tmp/deprecation') do - it { is_expected.not_to exist } + describe file("#{test_file}") do + it { is_expected.not_to be_file } end end context 'with --strict=warning', if: get_puppet_version =~ /^4/ do before :all do - pp = <<-EOS - deprecation('key', 'message') - file { '/tmp/deprecation': ensure => present } - EOS - @result = on(default, puppet('apply', '--strict=warning', '-e', Shellwords.shellescape(pp)), acceptable_exit_codes: (0...256)) + @result = on(default, puppet('apply', '--strict=warning', '-e', add_file_manifest), acceptable_exit_codes: (0...256)) + end + + after :all do + apply_manifest(remove_file_manifest) end it "should not return an error" do @@ -46,18 +56,18 @@ describe 'deprecation function' do expect(@result.stderr).to match(/Warning: message/) end - describe file('/tmp/deprecation') do - it { is_expected.to exist } + describe file("#{test_file}") do + it { is_expected.to be_file } end end context 'with --strict=off', if: get_puppet_version =~ /^4/ do before :all do - pp = <<-EOS - deprecation('key', 'message') - file { '/tmp/deprecation': ensure => present } - EOS - @result = on(default, puppet('apply', '--strict=off', '-e', Shellwords.shellescape(pp)), acceptable_exit_codes: (0...256)) + @result = on(default, puppet('apply', '--strict=off', '-e', add_file_manifest), acceptable_exit_codes: (0...256)) + end + + after :all do + apply_manifest(remove_file_manifest) end it "should not return an error" do @@ -68,8 +78,8 @@ describe 'deprecation function' do expect(@result.stderr).not_to match(/Warning: message/) end - describe file('/tmp/deprecation') do - it { is_expected.to exist } + describe file("#{test_file}") do + it { is_expected.to be_file } end end end -- cgit v1.2.3 From 5ed9aaa80967f3e4a3cf4a171c9e0fe68f5a280d Mon Sep 17 00:00:00 2001 From: Dominic Cleal Date: Fri, 2 Sep 2016 10:19:44 +0100 Subject: Fix validate_legacy docs table formatting --- README.markdown | 1 + 1 file changed, 1 insertion(+) diff --git a/README.markdown b/README.markdown index 13a5b74..fc11a84 100644 --- a/README.markdown +++ b/README.markdown @@ -1395,6 +1395,7 @@ Many `validate_*` functions have surprising holes in their validation. For examp To start out, for each parameter of your classes and defines, you'll have to decide on a new Puppet 4 data type to use. In most cases the new data type will allow a different set of values than the original `validate_*` function (which is the point of the whole exercise). The situation then looks like this: | | `validate_` pass | `validate_` fail | +| ------------ | ---------------- | ---------------- | | matches type | pass | pass, notice | | fails type | pass, deprecated | fail | -- cgit v1.2.3 From 2beef9acb246257c4edfb364b4b2d6bd9c7437d3 Mon Sep 17 00:00:00 2001 From: Stephen Benjamin Date: Fri, 2 Sep 2016 09:31:02 -0400 Subject: Add facter fact for puppet_environmentpath --- lib/facter/puppet_settings.rb | 35 +++++++++++++++++++++++++++++++++++ lib/facter/puppet_vardir.rb | 26 -------------------------- 2 files changed, 35 insertions(+), 26 deletions(-) create mode 100644 lib/facter/puppet_settings.rb delete mode 100644 lib/facter/puppet_vardir.rb diff --git a/lib/facter/puppet_settings.rb b/lib/facter/puppet_settings.rb new file mode 100644 index 0000000..e6a066a --- /dev/null +++ b/lib/facter/puppet_settings.rb @@ -0,0 +1,35 @@ +# These facter facts return the value of the Puppet vardir and environment path +# settings for the node running puppet or puppet agent. The intent is to +# enable Puppet modules to automatically have insight into a place where they +# can place variable data, or for modules running on the puppet master to know +# where environments are stored. +# +# The values should be directly usable in a File resource path attribute. +# +begin + require 'facter/util/puppet_settings' +rescue LoadError => e + # puppet apply does not add module lib directories to the $LOAD_PATH (See + # #4248). It should (in the future) but for the time being we need to be + # defensive which is what this rescue block is doing. + rb_file = File.join(File.dirname(__FILE__), 'util', 'puppet_settings.rb') + load rb_file if File.exists?(rb_file) or raise e +end + + +# These will be nil if Puppet is not available. +Facter.add(:puppet_vardir) do + setcode do + Facter::Util::PuppetSettings.with_puppet do + Puppet[:vardir] + end + end +end + +Facter.add(:puppet_environmentpath) do + setcode do + Facter::Util::PuppetSettings.with_puppet do + Puppet[:environmentpath] + end + end +end diff --git a/lib/facter/puppet_vardir.rb b/lib/facter/puppet_vardir.rb deleted file mode 100644 index 0e6af40..0000000 --- a/lib/facter/puppet_vardir.rb +++ /dev/null @@ -1,26 +0,0 @@ -# This facter fact returns the value of the Puppet vardir setting for the node -# running puppet or puppet agent. The intent is to enable Puppet modules to -# automatically have insight into a place where they can place variable data, -# regardless of the node's platform. -# -# The value should be directly usable in a File resource path attribute. - - -begin - require 'facter/util/puppet_settings' -rescue LoadError => e - # puppet apply does not add module lib directories to the $LOAD_PATH (See - # #4248). It should (in the future) but for the time being we need to be - # defensive which is what this rescue block is doing. - rb_file = File.join(File.dirname(__FILE__), 'util', 'puppet_settings.rb') - load rb_file if File.exists?(rb_file) or raise e -end - -Facter.add(:puppet_vardir) do - setcode do - # This will be nil if Puppet is not available. - Facter::Util::PuppetSettings.with_puppet do - Puppet[:vardir] - end - end -end -- cgit v1.2.3 From 6c6c6d8e3448e3072d590a0782237486e46bc88d Mon Sep 17 00:00:00 2001 From: Helen Campbell Date: Tue, 23 Aug 2016 15:02:39 +0100 Subject: Deprecation function to be mutable in all cases --- lib/puppet/functions/deprecation.rb | 2 +- lib/puppet/parser/functions/deprecation.rb | 6 ++- spec/functions/deprecation_spec.rb | 4 ++ spec/functions/is_array_spec.rb | 22 ++++++-- spec/functions/is_bool_spec.rb | 23 +++++++-- spec/functions/is_float_spec.rb | 25 ++++++--- spec/functions/is_integer_spec.rb | 27 +++++++--- spec/functions/is_ip_address_spec.rb | 20 ++++++-- spec/functions/is_ipv4_address_spec.rb | 21 ++++++-- spec/functions/is_ipv6_address_spec.rb | 21 ++++++-- spec/functions/is_numeric_spec.rb | 25 ++++++--- spec/functions/is_string_spec.rb | 24 +++++++-- spec/functions/validate_absolute_path_spec.rb | 5 ++ spec/functions/validate_array_spec.rb | 5 ++ spec/functions/validate_bool_spec.rb | 5 ++ spec/functions/validate_integer_spec.rb | 5 ++ spec/functions/validate_ip_address_spec.rb | 21 ++++++-- spec/functions/validate_ipv4_address_spec.rb | 73 ++++++++++++++++----------- spec/functions/validate_ipv6_address_spec.rb | 62 ++++++++++++++--------- spec/functions/validate_numeric_spec.rb | 5 ++ spec/functions/validate_re_spec.rb | 5 ++ spec/functions/validate_string_spec.rb | 5 ++ 22 files changed, 305 insertions(+), 106 deletions(-) diff --git a/lib/puppet/functions/deprecation.rb b/lib/puppet/functions/deprecation.rb index 3b84ae5..6b7b977 100644 --- a/lib/puppet/functions/deprecation.rb +++ b/lib/puppet/functions/deprecation.rb @@ -15,7 +15,7 @@ Puppet::Functions.create_function(:deprecation) do when :error fail("deprecation. #{key}. #{message}") else - Puppet.warn_once('deprecation', key, message) + Puppet.deprecation_warning(message, key) end end end diff --git a/lib/puppet/parser/functions/deprecation.rb b/lib/puppet/parser/functions/deprecation.rb index fc861a6..e30f3a0 100644 --- a/lib/puppet/parser/functions/deprecation.rb +++ b/lib/puppet/parser/functions/deprecation.rb @@ -9,7 +9,9 @@ EOS key = arguments[0] message = arguments[1] - - warning("deprecation. #{key}. #{message}") + + if ENV['STDLIB_LOG_DEPRECATIONS'] == "true" + warning("deprecation. #{key}. #{message}") + end end end diff --git a/spec/functions/deprecation_spec.rb b/spec/functions/deprecation_spec.rb index c213190..4321c3d 100644 --- a/spec/functions/deprecation_spec.rb +++ b/spec/functions/deprecation_spec.rb @@ -42,6 +42,10 @@ if Puppet.version.to_f >= 4.0 end else describe 'deprecation' do + after(:context) do + ENV.delete('STDLIB_LOG_DEPRECATIONS') + end + ENV['STDLIB_LOG_DEPRECATIONS'] = "true" it { is_expected.not_to eq(nil) } it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } diff --git a/spec/functions/is_array_spec.rb b/spec/functions/is_array_spec.rb index 0a8070b..2350b7f 100755 --- a/spec/functions/is_array_spec.rb +++ b/spec/functions/is_array_spec.rb @@ -1,12 +1,8 @@ require 'spec_helper' describe 'is_array' do + it { is_expected.not_to eq(nil) } - # Checking for deprecation warning - it 'should display a single deprecation' do - scope.expects(:warning).with(includes('This method is deprecated')) - is_expected.to run.with_params([]) - end it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } it { pending("Current implementation ignores parameters after the first.") @@ -21,4 +17,20 @@ describe 'is_array' do it { is_expected.to run.with_params('one').and_return(false) } it { is_expected.to run.with_params(1).and_return(false) } it { is_expected.to run.with_params({}).and_return(false) } + context 'Checking for deprecation warning' do + after(:context) do + ENV.delete('STDLIB_LOG_DEPRECATIONS') + end + # Checking for deprecation warning, which should only be provoked when the env variable for it is set. + it 'should display a single deprecation' do + ENV['STDLIB_LOG_DEPRECATIONS'] = "true" + scope.expects(:warning).with(includes('This method is deprecated')) + is_expected.to run.with_params(['1.2.3.4']).and_return(true) + end + it 'should display no warning for deprecation' do + ENV['STDLIB_LOG_DEPRECATIONS'] = "false" + scope.expects(:warning).with(includes('This method is deprecated')).never + is_expected.to run.with_params(['1.2.3.4']).and_return(true) + end + end end diff --git a/spec/functions/is_bool_spec.rb b/spec/functions/is_bool_spec.rb index 4550e61..7b2173e 100755 --- a/spec/functions/is_bool_spec.rb +++ b/spec/functions/is_bool_spec.rb @@ -1,12 +1,8 @@ require 'spec_helper' describe 'is_bool' do + it { is_expected.not_to eq(nil) } - # Checking for deprecation warning - it 'should display a single deprecation' do - scope.expects(:warning).with(includes('This method is deprecated')) - is_expected.to run.with_params(true) - end it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } it { is_expected.to run.with_params(true, false).and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } it { is_expected.to run.with_params(true).and_return(true) } @@ -17,4 +13,21 @@ describe 'is_bool' do it { is_expected.to run.with_params([true]).and_return(false) } it { is_expected.to run.with_params('true').and_return(false) } it { is_expected.to run.with_params('false').and_return(false) } + context 'Checking for deprecation warning' do + after(:context) do + ENV.delete('STDLIB_LOG_DEPRECATIONS') + end + # Checking for deprecation warning, which should only be provoked when the env variable for it is set. + it 'should display a single deprecation' do + ENV['STDLIB_LOG_DEPRECATIONS'] = "true" + scope.expects(:warning).with(includes('This method is deprecated')) + is_expected.to run.with_params(true).and_return(true) + end + it 'should display no warning for deprecation' do + ENV['STDLIB_LOG_DEPRECATIONS'] = "false" + scope.expects(:warning).with(includes('This method is deprecated')).never + is_expected.to run.with_params(false).and_return(true) + end + end end + diff --git a/spec/functions/is_float_spec.rb b/spec/functions/is_float_spec.rb index cb7e148..44bdc48 100755 --- a/spec/functions/is_float_spec.rb +++ b/spec/functions/is_float_spec.rb @@ -1,13 +1,8 @@ require 'spec_helper' describe 'is_float' do - it { is_expected.not_to eq(nil) } - # Checking for deprecation warning - it 'should display a single deprecation' do - scope.expects(:warning).with(includes('This method is deprecated')) - is_expected.to run.with_params(3) - end + 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(0.1, 0.2).and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } @@ -26,4 +21,22 @@ describe 'is_float' do it { is_expected.to run.with_params(1.0).and_return(true) } it { is_expected.to run.with_params(1).and_return(false) } end + + context 'Checking for deprecation warning' do + after(:context) do + ENV.delete('STDLIB_LOG_DEPRECATIONS') + end + # Checking for deprecation warning, which should only be provoked when the env variable for it is set. + it 'should display a single deprecation' do + ENV['STDLIB_LOG_DEPRECATIONS'] = "true" + scope.expects(:warning).with(includes('This method is deprecated')) + is_expected.to run.with_params(2.2).and_return(true) + end + it 'should display no warning for deprecation' do + ENV['STDLIB_LOG_DEPRECATIONS'] = "false" + scope.expects(:warning).with(includes('This method is deprecated')).never + is_expected.to run.with_params(1.0).and_return(true) + end + end + end diff --git a/spec/functions/is_integer_spec.rb b/spec/functions/is_integer_spec.rb index 2d68731..4b5dd21 100755 --- a/spec/functions/is_integer_spec.rb +++ b/spec/functions/is_integer_spec.rb @@ -1,14 +1,9 @@ require 'spec_helper' describe 'is_integer' do + it { is_expected.not_to eq(nil) } - # Checking for deprecation warning - it 'should display a single deprecation' do - scope.expects(:warning).with(includes('This method is deprecated')) - is_expected.to run.with_params(3) - end - it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } it { is_expected.to run.with_params(1, 2).and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } @@ -16,7 +11,7 @@ describe 'is_integer' do it { is_expected.to run.with_params('3').and_return(true) } it { is_expected.to run.with_params(-3).and_return(true) } it { is_expected.to run.with_params('-3').and_return(true) } - + it { is_expected.to run.with_params(3.7).and_return(false) } it { is_expected.to run.with_params('3.7').and_return(false) } it { is_expected.to run.with_params(-3.7).and_return(false) } @@ -29,4 +24,22 @@ describe 'is_integer' do it { is_expected.to run.with_params(true).and_return(false) } it { is_expected.to run.with_params(false).and_return(false) } it { is_expected.to run.with_params('0001234').and_return(false) } + + context 'Checking for deprecation warning' do + after(:context) do + ENV.delete('STDLIB_LOG_DEPRECATIONS') + end + # Checking for deprecation warning, which should only be provoked when the env variable for it is set. + it 'should display a single deprecation' do + ENV['STDLIB_LOG_DEPRECATIONS'] = "true" + scope.expects(:warning).with(includes('This method is deprecated')) + is_expected.to run.with_params(50).and_return(true) + end + it 'should display no warning for deprecation' do + ENV['STDLIB_LOG_DEPRECATIONS'] = "false" + scope.expects(:warning).with(includes('This method is deprecated')).never + is_expected.to run.with_params(50).and_return(true) + end + end + end diff --git a/spec/functions/is_ip_address_spec.rb b/spec/functions/is_ip_address_spec.rb index 9386ca9..fc8af60 100755 --- a/spec/functions/is_ip_address_spec.rb +++ b/spec/functions/is_ip_address_spec.rb @@ -20,9 +20,21 @@ describe 'is_ip_address' do it { is_expected.to run.with_params(1).and_return(false) } it { is_expected.to run.with_params({}).and_return(false) } it { is_expected.to run.with_params([]).and_return(false) } - # Checking for deprecation warning - it 'should display a single deprecation' do - scope.expects(:warning).with(includes('This method is deprecated')) - is_expected.to run.with_params('1.1.1.1') + + context 'Checking for deprecation warning', if: Puppet.version.to_f < 4.0 do + # Checking for deprecation warning, which should only be provoked when the env variable for it is set. + it 'should display a single deprecation' do + ENV['STDLIB_LOG_DEPRECATIONS'] = "true" + scope.expects(:warning).with(includes('This method is deprecated')) + is_expected.to run.with_params('1.2.3.4').and_return(true) + end + it 'should display no warning for deprecation' do + ENV['STDLIB_LOG_DEPRECATIONS'] = "false" + scope.expects(:warning).with(includes('This method is deprecated')).never + is_expected.to run.with_params('1.2.3.4').and_return(true) + end + after(:context) do + ENV.delete('STDLIB_LOG_DEPRECATIONS') + end end end diff --git a/spec/functions/is_ipv4_address_spec.rb b/spec/functions/is_ipv4_address_spec.rb index 2b9fc49..9d53a9d 100644 --- a/spec/functions/is_ipv4_address_spec.rb +++ b/spec/functions/is_ipv4_address_spec.rb @@ -1,6 +1,7 @@ require 'spec_helper' describe 'is_ipv4_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('1.2.3.4').and_return(true) } @@ -9,9 +10,21 @@ describe 'is_ipv4_address' do 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('one').and_return(false) } - # Checking for deprecation warning - it 'should display a single deprecation' do - scope.expects(:warning).with(includes('This method is deprecated')) - is_expected.to run.with_params('1.1.1.1') + + context 'Checking for deprecation warning', if: Puppet.version.to_f < 4.0 do + after(:context) do + ENV.delete('STDLIB_LOG_DEPRECATIONS') + end + # Checking for deprecation warning, which should only be provoked when the env variable for it is set. + it 'should display a single deprecation' do + ENV['STDLIB_LOG_DEPRECATIONS'] = "true" + scope.expects(:warning).with(includes('This method is deprecated')) + is_expected.to run.with_params('1.2.3.4').and_return(true) + end + it 'should display no warning for deprecation' do + ENV['STDLIB_LOG_DEPRECATIONS'] = "false" + scope.expects(:warning).with(includes('This method is deprecated')).never + is_expected.to run.with_params('1.2.3.4').and_return(true) + end end end diff --git a/spec/functions/is_ipv6_address_spec.rb b/spec/functions/is_ipv6_address_spec.rb index e3e4734..4449fea 100644 --- a/spec/functions/is_ipv6_address_spec.rb +++ b/spec/functions/is_ipv6_address_spec.rb @@ -1,6 +1,7 @@ require 'spec_helper' describe 'is_ipv6_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('2001:0db8:85a3:0000:0000:8a2e:0370:7334').and_return(true) } @@ -9,9 +10,21 @@ describe 'is_ipv6_address' do 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('one').and_return(false) } - # Checking for deprecation warning - it 'should display a single deprecation' do - scope.expects(:warning).with(includes('This method is deprecated')) - is_expected.to run.with_params('2001:0db8:85a3:0000:0000:8a2e:0370:7334') + + context 'Checking for deprecation warning', if: Puppet.version.to_f < 4.0 do + after(:context) do + ENV.delete('STDLIB_LOG_DEPRECATIONS') + end + # Checking for deprecation warning, which should only be provoked when the env variable for it is set. + it 'should display a single deprecation' do + ENV['STDLIB_LOG_DEPRECATIONS'] = "true" + scope.expects(:warning).with(includes('This method is deprecated')) + is_expected.to run.with_params('2001:0db8:85a3:0000:0000:8a2e:0370:7334').and_return(true) + end + it 'should display no warning for deprecation' do + ENV['STDLIB_LOG_DEPRECATIONS'] = "false" + scope.expects(:warning).with(includes('This method is deprecated')).never + is_expected.to run.with_params('2001:0db8:85a3:0000:0000:8a2e:0370:7334').and_return(true) + end end end diff --git a/spec/functions/is_numeric_spec.rb b/spec/functions/is_numeric_spec.rb index f4ead56..ccfb9d8 100755 --- a/spec/functions/is_numeric_spec.rb +++ b/spec/functions/is_numeric_spec.rb @@ -1,14 +1,9 @@ require 'spec_helper' describe 'is_numeric' do + it { is_expected.not_to eq(nil) } - # Checking for deprecation warning - it 'should display a single deprecation' do - scope.expects(:warning).with(includes('This method is deprecated')) - is_expected.to run.with_params(3) - end - it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } it { is_expected.to run.with_params(1, 2).and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } @@ -32,4 +27,22 @@ describe 'is_numeric' do it { is_expected.to run.with_params(false).and_return(false) } it { is_expected.to run.with_params('0001234').and_return(false) } it { is_expected.to run.with_params(' - 1234').and_return(false) } + + context 'Checking for deprecation warning' do + after(:context) do + ENV.delete('STDLIB_LOG_DEPRECATIONS') + end + # Checking for deprecation warning, which should only be provoked when the env variable for it is set. + it 'should display a single deprecation' do + ENV['STDLIB_LOG_DEPRECATIONS'] = "true" + scope.expects(:warning).with(includes('This method is deprecated')) + is_expected.to run.with_params(7).and_return(true) + end + it 'should display no warning for deprecation' do + ENV['STDLIB_LOG_DEPRECATIONS'] = "false" + scope.expects(:warning).with(includes('This method is deprecated')).never + is_expected.to run.with_params(7).and_return(true) + end + end + end diff --git a/spec/functions/is_string_spec.rb b/spec/functions/is_string_spec.rb index 4f59b63..460d6e0 100755 --- a/spec/functions/is_string_spec.rb +++ b/spec/functions/is_string_spec.rb @@ -1,12 +1,8 @@ require 'spec_helper' describe 'is_string' do + it { is_expected.not_to eq(nil) } - # Checking for deprecation warning - it 'should display a single deprecation' do - scope.expects(:warning).with(includes('This method is deprecated')) - is_expected.to run.with_params('ha') - end it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } it { pending("Current implementation ignores parameters after the first.") @@ -30,4 +26,22 @@ describe 'is_string' do it { is_expected.to run.with_params(false).and_return(false) } it { is_expected.to run.with_params('one').and_return(true) } it { is_expected.to run.with_params('0001234').and_return(true) } + + context 'Checking for deprecation warning' do + after(:context) do + ENV.delete('STDLIB_LOG_DEPRECATIONS') + end + # Checking for deprecation warning, which should only be provoked when the env variable for it is set. + it 'should display a single deprecation' do + ENV['STDLIB_LOG_DEPRECATIONS'] = "true" + scope.expects(:warning).with(includes('This method is deprecated')) + is_expected.to run.with_params('sponge').and_return(true) + end + it 'should display no warning for deprecation' do + ENV['STDLIB_LOG_DEPRECATIONS'] = "false" + scope.expects(:warning).with(includes('This method is deprecated')).never + is_expected.to run.with_params('bob').and_return(true) + end + end + end diff --git a/spec/functions/validate_absolute_path_spec.rb b/spec/functions/validate_absolute_path_spec.rb index dbac88f..75df6bc 100755 --- a/spec/functions/validate_absolute_path_spec.rb +++ b/spec/functions/validate_absolute_path_spec.rb @@ -1,9 +1,14 @@ require 'spec_helper' describe 'validate_absolute_path' do + after(:context) do + ENV.delete('STDLIB_LOG_DEPRECATIONS') + end + # Checking for deprecation warning it 'should display a single deprecation' do # called twice because validate_absolute_path calls is_absolute_path + ENV['STDLIB_LOG_DEPRECATIONS'] = "true" scope.expects(:warning).with(includes('This method is deprecated')).twice is_expected.to run.with_params('c:/') end diff --git a/spec/functions/validate_array_spec.rb b/spec/functions/validate_array_spec.rb index 9f2e210..f395d16 100755 --- a/spec/functions/validate_array_spec.rb +++ b/spec/functions/validate_array_spec.rb @@ -1,10 +1,15 @@ require 'spec_helper' describe 'validate_array' do + describe 'signature validation' do + after(:context) do + ENV.delete('STDLIB_LOG_DEPRECATIONS') + end it { is_expected.not_to eq(nil) } # Checking for deprecation warning it 'should display a single deprecation' do + ENV['STDLIB_LOG_DEPRECATIONS'] = "true" scope.expects(:warning).with(includes('This method is deprecated')) is_expected.to run.with_params([]) end diff --git a/spec/functions/validate_bool_spec.rb b/spec/functions/validate_bool_spec.rb index 724e31f..4bd1453 100755 --- a/spec/functions/validate_bool_spec.rb +++ b/spec/functions/validate_bool_spec.rb @@ -1,9 +1,14 @@ require 'spec_helper' describe 'validate_bool' do + after(:context) do + ENV.delete('STDLIB_LOG_DEPRECATIONS') + end + # Checking for deprecation warning it 'should display a single deprecation' do #called twice, because validate_bool calls is_bool + ENV['STDLIB_LOG_DEPRECATIONS'] = "true" scope.expects(:warning).with(includes('This method is deprecated')).twice is_expected.to run.with_params(true) end diff --git a/spec/functions/validate_integer_spec.rb b/spec/functions/validate_integer_spec.rb index 3ca50b2..ffc59f8 100755 --- a/spec/functions/validate_integer_spec.rb +++ b/spec/functions/validate_integer_spec.rb @@ -1,8 +1,13 @@ require 'spec_helper' describe 'validate_integer' do + after(:context) do + ENV.delete('STDLIB_LOG_DEPRECATIONS') + end + # Checking for deprecation warning it 'should display a single deprecation' do + ENV['STDLIB_LOG_DEPRECATIONS'] = "true" scope.expects(:warning).with(includes('This method is deprecated')) is_expected.to run.with_params(3) end diff --git a/spec/functions/validate_ip_address_spec.rb b/spec/functions/validate_ip_address_spec.rb index 10f6c37..7040a8d 100644 --- a/spec/functions/validate_ip_address_spec.rb +++ b/spec/functions/validate_ip_address_spec.rb @@ -1,6 +1,7 @@ require 'spec_helper' describe 'validate_ip_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) } @@ -19,10 +20,24 @@ describe 'validate_ip_address' do it { is_expected.to run.with_params('3ffe:0505:0002::', '3ffe:0505:0002::2') } it { is_expected.to run.with_params('::1/64') } it { is_expected.to run.with_params('fe80::a00:27ff:fe94:44d6/64') } - it 'should display a single deprecation' do - scope.expects(:warning).with(includes('This method is deprecated')) - is_expected.to run.with_params('1.1.1.1') + + context 'Checking for deprecation warning', if: Puppet.version.to_f < 4.0 do + after(:context) do + ENV.delete('STDLIB_LOG_DEPRECATIONS') + end + # Checking for deprecation warning, which should only be provoked when the env variable for it is set. + it 'should display a single deprecation' do + ENV['STDLIB_LOG_DEPRECATIONS'] = "true" + scope.expects(:warning).with(includes('This method is deprecated')) + is_expected.to run.with_params('1.2.3.4') + end + it 'should display no warning for deprecation' do + ENV['STDLIB_LOG_DEPRECATIONS'] = "false" + scope.expects(:warning).with(includes('This method is deprecated')).never + is_expected.to run.with_params('1.2.3.4') + end end + context 'with netmasks' do it { is_expected.to run.with_params('8.8.8.8/0') } it { is_expected.to run.with_params('8.8.8.8/16') } diff --git a/spec/functions/validate_ipv4_address_spec.rb b/spec/functions/validate_ipv4_address_spec.rb index b67bf6f..b60dc8e 100755 --- a/spec/functions/validate_ipv4_address_spec.rb +++ b/spec/functions/validate_ipv4_address_spec.rb @@ -1,45 +1,58 @@ require 'spec_helper' describe 'validate_ipv4_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 + context 'Checking for deprecation warning', if: Puppet.version.to_f < 4.0 do + after(:context) do + ENV.delete('STDLIB_LOG_DEPRECATIONS') + end + # Checking for deprecation warning, which should only be provoked when the env variable for it is set. it 'should display a single deprecation' do + ENV['STDLIB_LOG_DEPRECATIONS'] = "true" scope.expects(:warning).with(includes('This method is deprecated')) - is_expected.to run.with_params('1.1.1.1') + is_expected.to run.with_params('1.2.3.4') end - - describe 'valid inputs' do - it { is_expected.to run.with_params('0.0.0.0') } - it { is_expected.to run.with_params('8.8.8.8') } - it { is_expected.to run.with_params('127.0.0.1') } - it { is_expected.to run.with_params('10.10.10.10') } - it { is_expected.to run.with_params('194.232.104.150') } - it { is_expected.to run.with_params('244.24.24.24') } - it { is_expected.to run.with_params('255.255.255.255') } - it { is_expected.to run.with_params('1.2.3.4', '5.6.7.8') } - context 'with netmasks' do - it { is_expected.to run.with_params('8.8.8.8/0') } - it { is_expected.to run.with_params('8.8.8.8/16') } - it { is_expected.to run.with_params('8.8.8.8/32') } - it { is_expected.to run.with_params('8.8.8.8/255.255.0.0') } - end + it 'should display no warning for deprecation' do + ENV['STDLIB_LOG_DEPRECATIONS'] = "false" + scope.expects(:warning).with(includes('This method is deprecated')).never + is_expected.to run.with_params('1.2.3.4') end + 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 IPv4/) } - it { is_expected.to run.with_params('0.0.0').and_raise_error(Puppet::ParseError, /is not a valid IPv4/) } - it { is_expected.to run.with_params('0.0.0.256').and_raise_error(Puppet::ParseError, /is not a valid IPv4/) } - it { is_expected.to run.with_params('0.0.0.0.0').and_raise_error(Puppet::ParseError, /is not a valid IPv4/) } - it { is_expected.to run.with_params('affe::beef').and_raise_error(Puppet::ParseError, /is not a valid IPv4/) } - it { is_expected.to run.with_params('1.2.3.4', {}).and_raise_error(Puppet::ParseError, /is not a string/) } - it { is_expected.to run.with_params('1.2.3.4', 1).and_raise_error(Puppet::ParseError, /is not a string/) } - it { is_expected.to run.with_params('1.2.3.4', true).and_raise_error(Puppet::ParseError, /is not a string/) } - it { is_expected.to run.with_params('1.2.3.4', 'one').and_raise_error(Puppet::ParseError, /is not a valid IPv4/) } + describe 'valid inputs' do + it { is_expected.to run.with_params('0.0.0.0') } + it { is_expected.to run.with_params('8.8.8.8') } + it { is_expected.to run.with_params('127.0.0.1') } + it { is_expected.to run.with_params('10.10.10.10') } + it { is_expected.to run.with_params('194.232.104.150') } + it { is_expected.to run.with_params('244.24.24.24') } + it { is_expected.to run.with_params('255.255.255.255') } + it { is_expected.to run.with_params('1.2.3.4', '5.6.7.8') } + context 'with netmasks' do + it { is_expected.to run.with_params('8.8.8.8/0') } + it { is_expected.to run.with_params('8.8.8.8/16') } + it { is_expected.to run.with_params('8.8.8.8/32') } + it { is_expected.to run.with_params('8.8.8.8/255.255.0.0') } end 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 IPv4/) } + it { is_expected.to run.with_params('0.0.0').and_raise_error(Puppet::ParseError, /is not a valid IPv4/) } + it { is_expected.to run.with_params('0.0.0.256').and_raise_error(Puppet::ParseError, /is not a valid IPv4/) } + it { is_expected.to run.with_params('0.0.0.0.0').and_raise_error(Puppet::ParseError, /is not a valid IPv4/) } + it { is_expected.to run.with_params('affe::beef').and_raise_error(Puppet::ParseError, /is not a valid IPv4/) } + it { is_expected.to run.with_params('1.2.3.4', {}).and_raise_error(Puppet::ParseError, /is not a string/) } + it { is_expected.to run.with_params('1.2.3.4', 1).and_raise_error(Puppet::ParseError, /is not a string/) } + it { is_expected.to run.with_params('1.2.3.4', true).and_raise_error(Puppet::ParseError, /is not a string/) } + it { is_expected.to run.with_params('1.2.3.4', 'one').and_raise_error(Puppet::ParseError, /is not a valid IPv4/) } + end end diff --git a/spec/functions/validate_ipv6_address_spec.rb b/spec/functions/validate_ipv6_address_spec.rb index 3afab56..87b535e 100755 --- a/spec/functions/validate_ipv6_address_spec.rb +++ b/spec/functions/validate_ipv6_address_spec.rb @@ -1,36 +1,50 @@ require 'spec_helper' describe 'validate_ipv6_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('3ffe:0505:0002::') } - it { is_expected.to run.with_params('3ffe:0505:0002::', '3ffe:0505:0002::2') } - it { is_expected.to run.with_params('::1/64') } - it { is_expected.to run.with_params('fe80::a00:27ff:fe94:44d6/64') } - it 'should display a single deprecation' do - scope.expects(:warning).with(includes('This method is deprecated')) - is_expected.to run.with_params('3ffe:0505:0002::') - end + context 'Checking for deprecation warning', if: Puppet.version.to_f < 4.0 do + after(:context) do + ENV.delete('STDLIB_LOG_DEPRECATIONS') + end + # Checking for deprecation warning, which should only be provoked when the env variable for it is set. + it 'should display a single deprecation' do + ENV['STDLIB_LOG_DEPRECATIONS'] = "true" + scope.expects(:warning).with(includes('This method is deprecated')) + is_expected.to run.with_params('3ffe:0505:0002::') + end + it 'should display no warning for deprecation' do + ENV['STDLIB_LOG_DEPRECATIONS'] = "false" + scope.expects(:warning).with(includes('This method is deprecated')).never + is_expected.to run.with_params('3ffe:0505:0002::') end + end + + describe 'valid inputs' do + it { is_expected.to run.with_params('3ffe:0505:0002::') } + it { is_expected.to run.with_params('3ffe:0505:0002::', '3ffe:0505:0002::2') } + it { is_expected.to run.with_params('::1/64') } + it { is_expected.to run.with_params('fe80::a00:27ff:fe94:44d6/64') } + 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(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 IPv6/) } - it { is_expected.to run.with_params('0.0.0').and_raise_error(Puppet::ParseError, /is not a valid IPv6/) } - it { is_expected.to run.with_params('0.0.0.256').and_raise_error(Puppet::ParseError, /is not a valid IPv6/) } - it { is_expected.to run.with_params('0.0.0.0.0').and_raise_error(Puppet::ParseError, /is not a valid IPv6/) } - it { is_expected.to run.with_params('affe:beef').and_raise_error(Puppet::ParseError, /is not a valid IPv6/) } - it { is_expected.to run.with_params('::1', {}).and_raise_error(Puppet::ParseError, /is not a string/) } - it { is_expected.to run.with_params('::1', true).and_raise_error(Puppet::ParseError, /is not a string/) } - it { is_expected.to run.with_params('::1', 'one').and_raise_error(Puppet::ParseError, /is not a valid IPv6/) } - context 'unless running on ruby 1.8.7', :if => RUBY_VERSION != '1.8.7' do - it { is_expected.to run.with_params(1).and_raise_error(Puppet::ParseError, /is not a string/) } - it { is_expected.to run.with_params('::1', 1).and_raise_error(Puppet::ParseError, /is not a string/) } - 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(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 IPv6/) } + it { is_expected.to run.with_params('0.0.0').and_raise_error(Puppet::ParseError, /is not a valid IPv6/) } + it { is_expected.to run.with_params('0.0.0.256').and_raise_error(Puppet::ParseError, /is not a valid IPv6/) } + it { is_expected.to run.with_params('0.0.0.0.0').and_raise_error(Puppet::ParseError, /is not a valid IPv6/) } + it { is_expected.to run.with_params('affe:beef').and_raise_error(Puppet::ParseError, /is not a valid IPv6/) } + it { is_expected.to run.with_params('::1', {}).and_raise_error(Puppet::ParseError, /is not a string/) } + it { is_expected.to run.with_params('::1', true).and_raise_error(Puppet::ParseError, /is not a string/) } + it { is_expected.to run.with_params('::1', 'one').and_raise_error(Puppet::ParseError, /is not a valid IPv6/) } + context 'unless running on ruby 1.8.7', :if => RUBY_VERSION != '1.8.7' do + it { is_expected.to run.with_params(1).and_raise_error(Puppet::ParseError, /is not a string/) } + it { is_expected.to run.with_params('::1', 1).and_raise_error(Puppet::ParseError, /is not a string/) } end end end diff --git a/spec/functions/validate_numeric_spec.rb b/spec/functions/validate_numeric_spec.rb index 2869e5f..4a65649 100755 --- a/spec/functions/validate_numeric_spec.rb +++ b/spec/functions/validate_numeric_spec.rb @@ -1,8 +1,13 @@ require 'spec_helper' describe 'validate_numeric' do + after(:context) do + ENV.delete('STDLIB_LOG_DEPRECATIONS') + end + # Checking for deprecation warning it 'should display a single deprecation' do + ENV['STDLIB_LOG_DEPRECATIONS'] = "true" scope.expects(:warning).with(includes('This method is deprecated')) is_expected.to run.with_params(3) end diff --git a/spec/functions/validate_re_spec.rb b/spec/functions/validate_re_spec.rb index 4b78a2e..2ee3f47 100755 --- a/spec/functions/validate_re_spec.rb +++ b/spec/functions/validate_re_spec.rb @@ -1,8 +1,13 @@ require 'spec_helper' describe 'validate_re' do + after(:context) do + ENV.delete('STDLIB_LOG_DEPRECATIONS') + end + # Checking for deprecation warning it 'should display a single deprecation' do + ENV['STDLIB_LOG_DEPRECATIONS'] = "true" scope.expects(:warning).with(includes('This method is deprecated')) is_expected.to run.with_params('', '') end diff --git a/spec/functions/validate_string_spec.rb b/spec/functions/validate_string_spec.rb index ef7a1b4..45d6ffc 100755 --- a/spec/functions/validate_string_spec.rb +++ b/spec/functions/validate_string_spec.rb @@ -1,8 +1,13 @@ require 'spec_helper' describe 'validate_string' do + after(:context) do + ENV.delete('STDLIB_LOG_DEPRECATIONS') + end + # Checking for deprecation warning it 'should display a single deprecation' do + ENV['STDLIB_LOG_DEPRECATIONS'] = "true" scope.expects(:warning).with(includes('This method is deprecated')) is_expected.to run.with_params('', '') end -- cgit v1.2.3 From b2d05e9b3f5da65ad3dc39b95b342e9085e52346 Mon Sep 17 00:00:00 2001 From: Helen Campbell Date: Tue, 6 Sep 2016 12:30:46 +0100 Subject: Deprecation README update --- README.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.markdown b/README.markdown index 26fe55f..aee4e90 100644 --- a/README.markdown +++ b/README.markdown @@ -304,7 +304,7 @@ Deletes all instances of the undef value from an array or hash. For example, `$h #### `deprecation` -Function to print deprecation warnings, Logs a warning once for a given key. The uniqueness key - can appear once. The msg is the message text including any positional information that is formatted by the user/caller of the method It is affected by the puppet setting 'strict', which can be set to :error (outputs as an error message), :off (no message / error is displayed) and :warning (default, outputs a warning) *Type*: String, String. +A function to print deprecation warnings, logs a warning once for a given key. The uniqueness key - can appear once. The msg is the message text including any positional information that is formatted by the user/caller of the method. It is affected by the puppet setting 'strict', which can be set to :error (outputs as an error message), :off (no message / error is displayed) and :warning (default, outputs a warning). In Puppet version less than 4.0 an environment variable can be set to decide whether or not to log deprecation warnings (ENV[STDLIB_LOG_DEPRECATION]). If this environment variable is set to true, the functions will log a warning. *Type*: String, String. #### `difference` -- cgit v1.2.3 From b63862ff43194194f7428739a32cfe13bad1e7ed Mon Sep 17 00:00:00 2001 From: Helen Campbell Date: Tue, 6 Sep 2016 15:00:07 +0100 Subject: Addition of logging with file and line numbers --- lib/puppet/functions/deprecation.rb | 8 +++++--- lib/puppet/functions/validate_legacy.rb | 4 +++- lib/puppet/parser/functions/deprecation.rb | 4 +++- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/lib/puppet/functions/deprecation.rb b/lib/puppet/functions/deprecation.rb index 6b7b977..30aeb1d 100644 --- a/lib/puppet/functions/deprecation.rb +++ b/lib/puppet/functions/deprecation.rb @@ -1,5 +1,4 @@ # Function to print deprecation warnings, Logs a warning once for a given key. The uniqueness key - can appear once. The msg is the message text including any positional information that is formatted by the user/caller of the method It is affected by the puppet setting 'strict', which can be set to :error (outputs as an error message), :off (no message / error is displayed) and :warning (default, outputs a warning) *Type*: String, String. -# Puppet::Functions.create_function(:deprecation) do dispatch :deprecation do @@ -9,13 +8,16 @@ Puppet::Functions.create_function(:deprecation) do def deprecation(key, message) # depending on configuration setting of strict + caller_infos = caller.first.split(":") case Puppet.settings[:strict] when :off # do nothing when :error - fail("deprecation. #{key}. #{message}") + err_message = "#{message} : #{caller_infos[0]} : #{caller_infos[1]}" + fail("deprecation. #{key}. #{err_message}") else - Puppet.deprecation_warning(message, key) + err_message = "#{message} : #{caller_infos[0]} : #{caller_infos[1]}" + Puppet.deprecation_warning(err_message, key) end end end diff --git a/lib/puppet/functions/validate_legacy.rb b/lib/puppet/functions/validate_legacy.rb index 9d7d012..b1066e2 100644 --- a/lib/puppet/functions/validate_legacy.rb +++ b/lib/puppet/functions/validate_legacy.rb @@ -28,8 +28,10 @@ Puppet::Functions.create_function(:validate_legacy, Puppet::Functions::InternalF Puppet.warn("Accepting previously invalid value for target_type '#{target_type}'") end else + caller_infos = caller.first.split(":") inferred_type = Puppet::Pops::Types::TypeCalculator.infer_set(value) - error_msg = Puppet::Pops::Types::TypeMismatchDescriber.new.describe_mismatch(previous_validation, target_type, inferred_type) + message = Puppet::Pops::Types::TypeMismatchDescriber.new.describe_mismatch(previous_validation, target_type, inferred_type) + error_msg = "#{message} : #{caller_infos[0]} : #{caller_infos[1]}" if previous_validation(previous_validation, value, *prev_args) Puppet.warn(error_msg) else diff --git a/lib/puppet/parser/functions/deprecation.rb b/lib/puppet/parser/functions/deprecation.rb index e30f3a0..0cb247d 100644 --- a/lib/puppet/parser/functions/deprecation.rb +++ b/lib/puppet/parser/functions/deprecation.rb @@ -11,7 +11,9 @@ EOS message = arguments[1] if ENV['STDLIB_LOG_DEPRECATIONS'] == "true" - warning("deprecation. #{key}. #{message}") + caller_infos = caller.first.split(":") + err_message = "#{message} : #{caller_infos[0]} : #{caller_infos[1]}" + warning("deprecation. #{key}. #{err_message}") end end end -- cgit v1.2.3 From 2b56ebd3e16112f8260519af0cd65a3d17fbfaeb Mon Sep 17 00:00:00 2001 From: David Schmitt Date: Mon, 5 Sep 2016 12:24:30 +0100 Subject: Fix assert_private tests to not hit the newly deprecated subject.call --- spec/functions/assert_private_spec.rb | 30 ++++++++++++------------------ 1 file changed, 12 insertions(+), 18 deletions(-) diff --git a/spec/functions/assert_private_spec.rb b/spec/functions/assert_private_spec.rb index 98f2598..355e0dd 100755 --- a/spec/functions/assert_private_spec.rb +++ b/spec/functions/assert_private_spec.rb @@ -5,31 +5,26 @@ describe 'assert_private' do it "should not fail" do scope.expects(:lookupvar).with('module_name').returns('foo') scope.expects(:lookupvar).with('caller_module_name').returns('foo') - expect { - subject.call [] - }.not_to raise_error + + is_expected.to run.with_params() end end - context "with an explicit failure message" do - it "prints the failure message on error" do + context "when called from private class" do + before :each do scope.expects(:lookupvar).with('module_name').returns('foo') scope.expects(:lookupvar).with('caller_module_name').returns('bar') - expect { - subject.call ['failure message!'] - }.to raise_error Puppet::ParseError, /failure message!/ end - end - context "when called from private class" do it "should fail with a class error message" do - scope.expects(:lookupvar).with('module_name').returns('foo') - scope.expects(:lookupvar).with('caller_module_name').returns('bar') scope.source.expects(:name).returns('foo::baz') scope.source.expects(:type).returns('hostclass') - expect { - subject.call [] - }.to raise_error Puppet::ParseError, /Class foo::baz is private/ + + is_expected.to run.with_params().and_raise_error(Puppet::ParseError, /Class foo::baz is private/) + end + + context "with an explicit failure message" do + it { is_expected.to run.with_params('failure message!').and_raise_error(Puppet::ParseError, /failure message!/) } end end @@ -39,9 +34,8 @@ describe 'assert_private' do scope.expects(:lookupvar).with('caller_module_name').returns('bar') scope.source.expects(:name).returns('foo::baz') scope.source.expects(:type).returns('definition') - expect { - subject.call [] - }.to raise_error Puppet::ParseError, /Definition foo::baz is private/ + + is_expected.to run.with_params().and_raise_error(Puppet::ParseError, /Definition foo::baz is private/) end end end -- cgit v1.2.3 From f1edd2715a755573d7578839a3efe8473b79b5c5 Mon Sep 17 00:00:00 2001 From: David Schmitt Date: Tue, 6 Sep 2016 11:18:48 +0100 Subject: (MODULES-3737) validate_legacy: refactoring * validate_legacy now accepts undef values * update the TypeMismatch message to include the original validate function name * only notice, not warn, on newly allowed values * changed previous_validation to function_name to avoid confusion with the function of the same name * use deprecation() instead of warn(), when hitting a deprecated value * prepare the tests and function for MODULES-3735 * rewrite validate_legacy tests to use new rspec-puppet * move validate_re deprecation to puppet4 only * adapt validate_re_spec --- Gemfile | 2 +- lib/puppet/functions/validate_legacy.rb | 31 +++++------ spec/classes/validate_legacy_spec.rb | 39 -------------- spec/fixtures/test/manifests/validate_legacy.pp | 18 ------- spec/functions/validate_legacy_spec.rb | 68 +++++++++++++++++++++++++ spec/functions/validate_re_spec.rb | 16 ------ 6 files changed, 85 insertions(+), 89 deletions(-) delete mode 100644 spec/classes/validate_legacy_spec.rb delete mode 100644 spec/fixtures/test/manifests/validate_legacy.pp create mode 100644 spec/functions/validate_legacy_spec.rb diff --git a/Gemfile b/Gemfile index c97275b..ecf3d06 100644 --- a/Gemfile +++ b/Gemfile @@ -21,7 +21,7 @@ group :development, :unit_tests do gem 'puppet_facts' gem 'puppet-blacksmith', '>= 3.4.0' gem 'puppetlabs_spec_helper', '>= 1.2.1' - gem 'rspec-puppet', '>= 2.3.2' + gem 'rspec-puppet', '>= 2.3.2', :git => 'https://github.com/rodjek/rspec-puppet.git', :branch => 'fb27c533e2664057fba4b73d0bd902a946abfce0' gem 'rspec-puppet-facts' gem 'simplecov' gem 'parallel_tests' diff --git a/lib/puppet/functions/validate_legacy.rb b/lib/puppet/functions/validate_legacy.rb index b1066e2..0ba6dd8 100644 --- a/lib/puppet/functions/validate_legacy.rb +++ b/lib/puppet/functions/validate_legacy.rb @@ -2,48 +2,49 @@ Puppet::Functions.create_function(:validate_legacy, Puppet::Functions::InternalF # The function checks a value against both the target_type (new) and the previous_validation function (old). dispatch :validate_legacy do + scope_param param 'Type', :target_type - param 'String', :previous_validation - param 'NotUndef', :value - optional_param 'Any', :args + param 'String', :function_name + param 'Any', :value + optional_repeated_param 'Any', :args end + dispatch :validate_legacy_s do scope_param param 'String', :type_string - param 'String', :previous_validation - param 'NotUndef', :value + param 'String', :function_name + param 'Any', :value optional_repeated_param 'Any', :args end def validate_legacy_s(scope, type_string, *args) t = Puppet::Pops::Types::TypeParser.new.parse(type_string, scope) - validate_legacy(t, *args) + validate_legacy(scope, t, *args) end - def validate_legacy(target_type, previous_validation, value, *prev_args) + def validate_legacy(scope, target_type, function_name, value, *prev_args) if assert_type(target_type, value) - if previous_validation(previous_validation, value, *prev_args) + if previous_validation(scope, function_name, value, *prev_args) # Silently passes else - Puppet.warn("Accepting previously invalid value for target_type '#{target_type}'") + Puppet.notice("Accepting previously invalid value for target type '#{target_type}'") end else caller_infos = caller.first.split(":") inferred_type = Puppet::Pops::Types::TypeCalculator.infer_set(value) - message = Puppet::Pops::Types::TypeMismatchDescriber.new.describe_mismatch(previous_validation, target_type, inferred_type) - error_msg = "#{message} : #{caller_infos[0]} : #{caller_infos[1]}" - if previous_validation(previous_validation, value, *prev_args) - Puppet.warn(error_msg) + error_msg = Puppet::Pops::Types::TypeMismatchDescriber.new.describe_mismatch("validate_legacy(#{function_name}) [#{caller_infos[0]}:#{caller_infos[1]}]", target_type, inferred_type) + if previous_validation(scope, function_name, value, *prev_args) + call_function('deprecation', 'validate_legacy', error_msg) else call_function('fail', error_msg) end end end - def previous_validation(previous_validation, value, *prev_args) + def previous_validation(scope, function_name, value, *prev_args) # Call the previous validation function and catch any errors. Return true if no errors are thrown. begin - call_function(previous_validation, value, *prev_args) + scope.send("function_#{function_name}".to_s, [value, *prev_args]) true rescue Puppet::ParseError false diff --git a/spec/classes/validate_legacy_spec.rb b/spec/classes/validate_legacy_spec.rb deleted file mode 100644 index ded6890..0000000 --- a/spec/classes/validate_legacy_spec.rb +++ /dev/null @@ -1,39 +0,0 @@ -require 'spec_helper' - -if Puppet.version.to_f >= 4.0 - # validate_legacy requires a proper scope to run, so we have to trigger a true compilation here, - # instead of being able to leverage the function test group. - describe 'test::validate_legacy', type: :class do - - describe 'validate_legacy passes assertion of type but not previous validation' do - let(:params) {{ type: "Optional[Integer]", prev_validation: "validate_re", value: 5, previous_arg1: ["^\\d+$", ""] }} - it { - Puppet.expects(:warn).with(includes('Accepting previously invalid value for target_type')) - is_expected.to compile - } - end - - describe 'validate_legacy passes assertion of type and previous validation' do - let(:params) {{ type: "Optional[String]", prev_validation: "validate_re", value: "5", previous_arg1: ["."] }} - it { is_expected.to compile } - end - - describe 'validate_legacy fails assertion of type and passes previous validation' do - let(:params) {{ type: "Optional[Integer]", prev_validation: "validate_re", value: "5", previous_arg1: ["."] }} - it { - Puppet.expects(:warn).with(includes('expected')) - is_expected.to compile - } - end - - describe 'validate_legacy fails assertion and fails previous validation' do - let(:params) {{ type: "Optional[Integer]", prev_validation: "validate_re", value: "5", previous_arg1: ["thisisnotright"] }} - it { is_expected.to compile.and_raise_error(/Error while evaluating a Function Call, \w* expected an \w* value, got \w*/) } - end - - describe 'validate_legacy works with multi-argument validate_ functions' do - let(:params) {{ type: "Integer", prev_validation: "validate_integer", value: 10, previous_arg1: 100, previous_arg2: 0 }} - it { is_expected.to compile } - end - end -end diff --git a/spec/fixtures/test/manifests/validate_legacy.pp b/spec/fixtures/test/manifests/validate_legacy.pp deleted file mode 100644 index 706df88..0000000 --- a/spec/fixtures/test/manifests/validate_legacy.pp +++ /dev/null @@ -1,18 +0,0 @@ -# Class to test stdlib validate_legacy function - -class test::validate_legacy( - $type, - $prev_validation, - $value, - $previous_arg1, - $previous_arg2 = undef, - ) { - - if $previous_arg2 == undef { - validate_legacy( $type, $prev_validation, $value, $previous_arg1 ) - } else { - validate_legacy( $type, $prev_validation, $value, $previous_arg1, $previous_arg2 ) - } - notice("Success") - -} diff --git a/spec/functions/validate_legacy_spec.rb b/spec/functions/validate_legacy_spec.rb new file mode 100644 index 0000000..45089ef --- /dev/null +++ b/spec/functions/validate_legacy_spec.rb @@ -0,0 +1,68 @@ +require 'spec_helper' + +if Puppet.version.to_f >= 4.0 + describe 'validate_legacy' do + it { is_expected.not_to eq(nil) } + it { is_expected.to run.with_params.and_raise_error(ArgumentError) } + + describe 'when passing the type assertion and passing the previous validation' do + before do + scope.expects(:function_validate_foo).with([5]).once + Puppet.expects(:notice).never + end + it 'passes without notice' do + is_expected.to run.with_params('Integer', 'validate_foo', 5) + end + end + + describe 'when passing the type assertion and failing the previous validation' do + before do + scope.expects(:function_validate_foo).with([5]).raises(Puppet::ParseError, 'foo').once + Puppet.expects(:notice).with(includes('Accepting previously invalid value for target type')) + end + it 'passes with a notice about newly accepted value' do + is_expected.to run.with_params('Integer', 'validate_foo', 5) + end + end + + describe 'when failing the type assertion and passing the previous validation' do + before do + scope.expects(:function_validate_foo).with(['5']).once + subject.func.expects(:call_function).with('deprecation', 'validate_legacy', includes('expected an Integer value')).once + end + it 'passes with a deprecation message' do + is_expected.to run.with_params('Integer', 'validate_foo', '5') + end + end + + describe 'when failing the type assertion and failing the previous validation' do + before do + scope.expects(:function_validate_foo).with(['5']).raises(Puppet::ParseError, 'foo').once + subject.func.expects(:call_function).with('fail', includes('expected an Integer value')).once + end + it 'fails with a helpful message' do + is_expected.to run.with_params('Integer', 'validate_foo', '5') + end + end + + describe 'when passing in undef' do + before do + scope.expects(:function_validate_foo).with([:undef]).once + Puppet.expects(:notice).never + end + it 'works' do + is_expected.to run.with_params('Optional[Integer]', 'validate_foo', :undef) + end + end + + describe 'when passing in multiple arguments' do + before do + scope.expects(:function_validate_foo).with([:undef, 1, 'foo']).once + Puppet.expects(:notice).never + end + it 'passes with a deprecation message' do + is_expected.to run.with_params('Optional[Integer]', 'validate_foo', :undef, 1, 'foo') + end + end + end +end diff --git a/spec/functions/validate_re_spec.rb b/spec/functions/validate_re_spec.rb index 2ee3f47..2fa9ddd 100755 --- a/spec/functions/validate_re_spec.rb +++ b/spec/functions/validate_re_spec.rb @@ -28,22 +28,6 @@ describe 'validate_re' do end describe 'invalid inputs' do - it { - pending('should implement stricter type checking') - is_expected.to run.with_params([], '').and_raise_error(Puppet::ParseError, /is not a String/) - } - it { - pending('should implement stricter type checking') - is_expected.to run.with_params('', {}).and_raise_error(Puppet::ParseError, /is not an Array/) - } - it { - pending('should implement stricter type checking') - is_expected.to run.with_params('', '', []).and_raise_error(Puppet::ParseError, /is not a String/) - } - it { - pending('should implement stricter type checking') - is_expected.to run.with_params(nil, nil).and_raise_error(Puppet::ParseError, /is not a String/) - } it { is_expected.to run.with_params('', []).and_raise_error(Puppet::ParseError, /does not match/) } it { is_expected.to run.with_params('one', 'two').and_raise_error(Puppet::ParseError, /does not match/) } it { is_expected.to run.with_params('', 'two').and_raise_error(Puppet::ParseError, /does not match/) } -- cgit v1.2.3 From 58111160708546bcbbc4f920c165fbcb47da5a0f Mon Sep 17 00:00:00 2001 From: Paula McMaw Date: Wed, 14 Sep 2016 15:28:35 +0100 Subject: Change in readme for numerical string --- README.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.markdown b/README.markdown index 5130f64..667da33 100644 --- a/README.markdown +++ b/README.markdown @@ -1437,7 +1437,7 @@ Example: #### `validate_numeric` -Validates that the first argument is a numeric value (or an array of numeric values). Aborts catalog compilation if any of the checks fail. +Validates that the first argument is a numeric value (or an array or string of numeric values). Aborts catalog compilation if any of the checks fail. The second argument is optional and passes a maximum. (All elements of) the first argument has to be less or equal to this max. -- cgit v1.2.3 From 033d0180c7a4146fc66deef3710506475efedb16 Mon Sep 17 00:00:00 2001 From: Hunter Haugen Date: Thu, 15 Sep 2016 18:14:23 +0100 Subject: Fix whitespace --- lib/puppet/parser/functions/dig44.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/puppet/parser/functions/dig44.rb b/lib/puppet/parser/functions/dig44.rb index d703380..1e7c318 100644 --- a/lib/puppet/parser/functions/dig44.rb +++ b/lib/puppet/parser/functions/dig44.rb @@ -1,5 +1,5 @@ -# -# dig44.rb +# +# dig44.rb # module Puppet::Parser::Functions -- cgit v1.2.3 From 0ec7ffa5c086c8a1c6e871b086299dd1953fa8ba Mon Sep 17 00:00:00 2001 From: Helen Campbell Date: Thu, 15 Sep 2016 11:35:38 +0100 Subject: Ensure validate functions use Puppet 4 deprecation --- lib/puppet/functions/validate_absolute_path.rb | 3 +++ lib/puppet/functions/validate_array.rb | 3 +++ lib/puppet/functions/validate_bool.rb | 3 +++ lib/puppet/functions/validate_hash.rb | 3 +++ lib/puppet/functions/validate_integer.rb | 3 +++ lib/puppet/functions/validate_ip_address.rb | 3 +++ lib/puppet/functions/validate_ipv4_address.rb | 3 +++ lib/puppet/functions/validate_ipv6_address.rb | 3 +++ lib/puppet/functions/validate_numeric.rb | 3 +++ lib/puppet/functions/validate_re.rb | 3 +++ lib/puppet/functions/validate_string.rb | 3 +++ lib/puppet_x/puppetlabs/stdlib/deprecation_gen.rb | 21 +++++++++++++++++++++ spec/acceptance/validate_array_spec.rb | 16 ++++++++-------- spec/acceptance/validate_bool_spec.rb | 16 ++++++++-------- spec/acceptance/validate_hash_spec.rb | 16 ++++++++-------- 15 files changed, 78 insertions(+), 24 deletions(-) create mode 100644 lib/puppet/functions/validate_absolute_path.rb create mode 100644 lib/puppet/functions/validate_array.rb create mode 100644 lib/puppet/functions/validate_bool.rb create mode 100644 lib/puppet/functions/validate_hash.rb create mode 100644 lib/puppet/functions/validate_integer.rb create mode 100644 lib/puppet/functions/validate_ip_address.rb create mode 100644 lib/puppet/functions/validate_ipv4_address.rb create mode 100644 lib/puppet/functions/validate_ipv6_address.rb create mode 100644 lib/puppet/functions/validate_numeric.rb create mode 100644 lib/puppet/functions/validate_re.rb create mode 100644 lib/puppet/functions/validate_string.rb create mode 100644 lib/puppet_x/puppetlabs/stdlib/deprecation_gen.rb diff --git a/lib/puppet/functions/validate_absolute_path.rb b/lib/puppet/functions/validate_absolute_path.rb new file mode 100644 index 0000000..5ae9d29 --- /dev/null +++ b/lib/puppet/functions/validate_absolute_path.rb @@ -0,0 +1,3 @@ +require 'puppet_x/puppetlabs/stdlib/deprecation_gen' +PuppetX::Puppetlabs::Stdlib.deprecation_gen("validate_absolute_path", "Stdlib::Compat::Absolute_Path") +# Puppet::Functions.create_function diff --git a/lib/puppet/functions/validate_array.rb b/lib/puppet/functions/validate_array.rb new file mode 100644 index 0000000..9155784 --- /dev/null +++ b/lib/puppet/functions/validate_array.rb @@ -0,0 +1,3 @@ +require 'puppet_x/puppetlabs/stdlib/deprecation_gen' +PuppetX::Puppetlabs::Stdlib.deprecation_gen("validate_array", "Stdlib::Compat::Array") +# Puppet::Functions.create_function diff --git a/lib/puppet/functions/validate_bool.rb b/lib/puppet/functions/validate_bool.rb new file mode 100644 index 0000000..10f6edf --- /dev/null +++ b/lib/puppet/functions/validate_bool.rb @@ -0,0 +1,3 @@ +require 'puppet_x/puppetlabs/stdlib/deprecation_gen' +PuppetX::Puppetlabs::Stdlib.deprecation_gen("validate_bool", "Stdlib::Compat::Bool") +# Puppet::Functions.create_function diff --git a/lib/puppet/functions/validate_hash.rb b/lib/puppet/functions/validate_hash.rb new file mode 100644 index 0000000..5349664 --- /dev/null +++ b/lib/puppet/functions/validate_hash.rb @@ -0,0 +1,3 @@ +require 'puppet_x/puppetlabs/stdlib/deprecation_gen' +PuppetX::Puppetlabs::Stdlib.deprecation_gen("validate_hash", "Stdlib::Compat::Hash") +# Puppet::Functions.create_function diff --git a/lib/puppet/functions/validate_integer.rb b/lib/puppet/functions/validate_integer.rb new file mode 100644 index 0000000..2c4645d --- /dev/null +++ b/lib/puppet/functions/validate_integer.rb @@ -0,0 +1,3 @@ +require 'puppet_x/puppetlabs/stdlib/deprecation_gen' +PuppetX::Puppetlabs::Stdlib.deprecation_gen("validate_integer", "Stdlib::Compat::Integer") +# Puppet::Functions.create_function diff --git a/lib/puppet/functions/validate_ip_address.rb b/lib/puppet/functions/validate_ip_address.rb new file mode 100644 index 0000000..15a710e --- /dev/null +++ b/lib/puppet/functions/validate_ip_address.rb @@ -0,0 +1,3 @@ +require 'puppet_x/puppetlabs/stdlib/deprecation_gen' +PuppetX::Puppetlabs::Stdlib.deprecation_gen("validate_ip_address", "Stdlib::Compat::Ip_Address") +# Puppet::Functions.create_function diff --git a/lib/puppet/functions/validate_ipv4_address.rb b/lib/puppet/functions/validate_ipv4_address.rb new file mode 100644 index 0000000..8e1bc59 --- /dev/null +++ b/lib/puppet/functions/validate_ipv4_address.rb @@ -0,0 +1,3 @@ +require 'puppet_x/puppetlabs/stdlib/deprecation_gen' +PuppetX::Puppetlabs::Stdlib.deprecation_gen("validate_ipv4_address", "Stdlib::Compat::Ipv4_Address") +# Puppet::Functions.create_function diff --git a/lib/puppet/functions/validate_ipv6_address.rb b/lib/puppet/functions/validate_ipv6_address.rb new file mode 100644 index 0000000..865648a --- /dev/null +++ b/lib/puppet/functions/validate_ipv6_address.rb @@ -0,0 +1,3 @@ +require 'puppet_x/puppetlabs/stdlib/deprecation_gen' +PuppetX::Puppetlabs::Stdlib.deprecation_gen("validate_ipv6_address", "Stdlib::Compat::Ipv6_address") +# Puppet::Functions.create_function diff --git a/lib/puppet/functions/validate_numeric.rb b/lib/puppet/functions/validate_numeric.rb new file mode 100644 index 0000000..0c2e1f2 --- /dev/null +++ b/lib/puppet/functions/validate_numeric.rb @@ -0,0 +1,3 @@ +require 'puppet_x/puppetlabs/stdlib/deprecation_gen' +PuppetX::Puppetlabs::Stdlib.deprecation_gen("validate_numeric", "Stdlib::Compat::Numeric") +# Puppet::Functions.create_function diff --git a/lib/puppet/functions/validate_re.rb b/lib/puppet/functions/validate_re.rb new file mode 100644 index 0000000..d63ed42 --- /dev/null +++ b/lib/puppet/functions/validate_re.rb @@ -0,0 +1,3 @@ +require 'puppet_x/puppetlabs/stdlib/deprecation_gen' +PuppetX::Puppetlabs::Stdlib.deprecation_gen("validate_re", "Stdlib::Compat::Re") +# Puppet::Functions.create_function diff --git a/lib/puppet/functions/validate_string.rb b/lib/puppet/functions/validate_string.rb new file mode 100644 index 0000000..a196f43 --- /dev/null +++ b/lib/puppet/functions/validate_string.rb @@ -0,0 +1,3 @@ +require 'puppet_x/puppetlabs/stdlib/deprecation_gen' +PuppetX::Puppetlabs::Stdlib.deprecation_gen("validate_string", "Stdlib::Compat::String") +# Puppet::Functions.create_function diff --git a/lib/puppet_x/puppetlabs/stdlib/deprecation_gen.rb b/lib/puppet_x/puppetlabs/stdlib/deprecation_gen.rb new file mode 100644 index 0000000..a3d830b --- /dev/null +++ b/lib/puppet_x/puppetlabs/stdlib/deprecation_gen.rb @@ -0,0 +1,21 @@ +# Creates a Puppet 4 function for the corresponding puppet 3 validate function, who's name will be passed as an argument, alongside the type for deprecation output purposes. +module PuppetX + module Puppetlabs + module Stdlib + def self.deprecation_gen(funct, type) + Puppet::Functions.create_function(funct, Puppet::Functions::InternalFunction) do + @@funct = funct + @@type = type + dispatch :deprecation_gen do + scope_param + optional_repeated_param 'Any', :args + end + def deprecation_gen(scope, *args) + call_function('deprecation', 'puppet_3_type_check', "This method is deprecated, please use the stdlib validate_legacy function, with #{@@type}. There is further documentation for validate_legacy function in the README.") + scope.send("function_#{@@funct}", args) + end + end + end + end + end +end diff --git a/spec/acceptance/validate_array_spec.rb b/spec/acceptance/validate_array_spec.rb index b53e98c..2f549d5 100755 --- a/spec/acceptance/validate_array_spec.rb +++ b/spec/acceptance/validate_array_spec.rb @@ -20,14 +20,14 @@ describe 'validate_array function', :unless => UNSUPPORTED_PLATFORMS.include?(fa apply_manifest(pp, :catch_failures => true) end - it 'validates a non-array' do - { - %{validate_array({'a' => 'hash' })} => "Hash", - %{validate_array('string')} => "String", - %{validate_array(false)} => "FalseClass", - %{validate_array(undef)} => "String" - }.each do |pp,type| - expect(apply_manifest(pp, :expect_failures => true).stderr).to match(/a #{type}/) + [ + %{validate_array({'a' => 'hash' })}, + %{validate_array('string')}, + %{validate_array(false)}, + %{validate_array(undef)} + ].each do |pp| + it "rejects #{pp.inspect}" do + expect(apply_manifest(pp, :expect_failures => true).stderr).to match(/is not an Array\. It looks to be a/) end end end diff --git a/spec/acceptance/validate_bool_spec.rb b/spec/acceptance/validate_bool_spec.rb index c837f08..5c52d0f 100755 --- a/spec/acceptance/validate_bool_spec.rb +++ b/spec/acceptance/validate_bool_spec.rb @@ -20,14 +20,14 @@ describe 'validate_bool function', :unless => UNSUPPORTED_PLATFORMS.include?(fac apply_manifest(pp, :catch_failures => true) end - it 'validates a non-bool' do - { - %{validate_bool('true')} => "String", - %{validate_bool('false')} => "String", - %{validate_bool([true])} => "Array", - %{validate_bool(undef)} => "String", - }.each do |pp,type| - expect(apply_manifest(pp, :expect_failures => true).stderr).to match(/a #{type}/) + [ + %{validate_bool('true')}, + %{validate_bool('false')}, + %{validate_bool([true])}, + %{validate_bool(undef)} + ].each do |pp| + it "rejects #{pp.inspect}" do + expect(apply_manifest(pp, :expect_failures => true).stderr).to match(/is not a boolean\. It looks to be a/) end end end diff --git a/spec/acceptance/validate_hash_spec.rb b/spec/acceptance/validate_hash_spec.rb index 52fb615..637df0a 100755 --- a/spec/acceptance/validate_hash_spec.rb +++ b/spec/acceptance/validate_hash_spec.rb @@ -20,14 +20,14 @@ describe 'validate_hash function', :unless => UNSUPPORTED_PLATFORMS.include?(fac apply_manifest(pp, :catch_failures => true) end - it 'validates a non-hash' do - { - %{validate_hash('{ "not" => "hash" }')} => "String", - %{validate_hash('string')} => "String", - %{validate_hash(["array"])} => "Array", - %{validate_hash(undef)} => "String", - }.each do |pp,type| - expect(apply_manifest(pp, :expect_failures => true).stderr).to match(/a #{type}/) + [ + %{validate_hash('{ "not" => "hash" }')}, + %{validate_hash('string')}, + %{validate_hash(["array"])}, + %{validate_hash(undef)} + ].each do |pp| + it "rejects #{pp.inspect}" do + expect(apply_manifest(pp, :expect_failures => true).stderr).to match(//) end end end -- cgit v1.2.3 From 69c69e750bdaee7d5eec264650551b149538de92 Mon Sep 17 00:00:00 2001 From: Helen Date: Wed, 21 Sep 2016 16:22:37 +0100 Subject: Revert "Ensure validate functions use Puppet 4 deprecation" --- lib/puppet/functions/validate_absolute_path.rb | 3 --- lib/puppet/functions/validate_array.rb | 3 --- lib/puppet/functions/validate_bool.rb | 3 --- lib/puppet/functions/validate_hash.rb | 3 --- lib/puppet/functions/validate_integer.rb | 3 --- lib/puppet/functions/validate_ip_address.rb | 3 --- lib/puppet/functions/validate_ipv4_address.rb | 3 --- lib/puppet/functions/validate_ipv6_address.rb | 3 --- lib/puppet/functions/validate_numeric.rb | 3 --- lib/puppet/functions/validate_re.rb | 3 --- lib/puppet/functions/validate_string.rb | 3 --- lib/puppet_x/puppetlabs/stdlib/deprecation_gen.rb | 21 --------------------- spec/acceptance/validate_array_spec.rb | 16 ++++++++-------- spec/acceptance/validate_bool_spec.rb | 16 ++++++++-------- spec/acceptance/validate_hash_spec.rb | 16 ++++++++-------- 15 files changed, 24 insertions(+), 78 deletions(-) delete mode 100644 lib/puppet/functions/validate_absolute_path.rb delete mode 100644 lib/puppet/functions/validate_array.rb delete mode 100644 lib/puppet/functions/validate_bool.rb delete mode 100644 lib/puppet/functions/validate_hash.rb delete mode 100644 lib/puppet/functions/validate_integer.rb delete mode 100644 lib/puppet/functions/validate_ip_address.rb delete mode 100644 lib/puppet/functions/validate_ipv4_address.rb delete mode 100644 lib/puppet/functions/validate_ipv6_address.rb delete mode 100644 lib/puppet/functions/validate_numeric.rb delete mode 100644 lib/puppet/functions/validate_re.rb delete mode 100644 lib/puppet/functions/validate_string.rb delete mode 100644 lib/puppet_x/puppetlabs/stdlib/deprecation_gen.rb diff --git a/lib/puppet/functions/validate_absolute_path.rb b/lib/puppet/functions/validate_absolute_path.rb deleted file mode 100644 index 5ae9d29..0000000 --- a/lib/puppet/functions/validate_absolute_path.rb +++ /dev/null @@ -1,3 +0,0 @@ -require 'puppet_x/puppetlabs/stdlib/deprecation_gen' -PuppetX::Puppetlabs::Stdlib.deprecation_gen("validate_absolute_path", "Stdlib::Compat::Absolute_Path") -# Puppet::Functions.create_function diff --git a/lib/puppet/functions/validate_array.rb b/lib/puppet/functions/validate_array.rb deleted file mode 100644 index 9155784..0000000 --- a/lib/puppet/functions/validate_array.rb +++ /dev/null @@ -1,3 +0,0 @@ -require 'puppet_x/puppetlabs/stdlib/deprecation_gen' -PuppetX::Puppetlabs::Stdlib.deprecation_gen("validate_array", "Stdlib::Compat::Array") -# Puppet::Functions.create_function diff --git a/lib/puppet/functions/validate_bool.rb b/lib/puppet/functions/validate_bool.rb deleted file mode 100644 index 10f6edf..0000000 --- a/lib/puppet/functions/validate_bool.rb +++ /dev/null @@ -1,3 +0,0 @@ -require 'puppet_x/puppetlabs/stdlib/deprecation_gen' -PuppetX::Puppetlabs::Stdlib.deprecation_gen("validate_bool", "Stdlib::Compat::Bool") -# Puppet::Functions.create_function diff --git a/lib/puppet/functions/validate_hash.rb b/lib/puppet/functions/validate_hash.rb deleted file mode 100644 index 5349664..0000000 --- a/lib/puppet/functions/validate_hash.rb +++ /dev/null @@ -1,3 +0,0 @@ -require 'puppet_x/puppetlabs/stdlib/deprecation_gen' -PuppetX::Puppetlabs::Stdlib.deprecation_gen("validate_hash", "Stdlib::Compat::Hash") -# Puppet::Functions.create_function diff --git a/lib/puppet/functions/validate_integer.rb b/lib/puppet/functions/validate_integer.rb deleted file mode 100644 index 2c4645d..0000000 --- a/lib/puppet/functions/validate_integer.rb +++ /dev/null @@ -1,3 +0,0 @@ -require 'puppet_x/puppetlabs/stdlib/deprecation_gen' -PuppetX::Puppetlabs::Stdlib.deprecation_gen("validate_integer", "Stdlib::Compat::Integer") -# Puppet::Functions.create_function diff --git a/lib/puppet/functions/validate_ip_address.rb b/lib/puppet/functions/validate_ip_address.rb deleted file mode 100644 index 15a710e..0000000 --- a/lib/puppet/functions/validate_ip_address.rb +++ /dev/null @@ -1,3 +0,0 @@ -require 'puppet_x/puppetlabs/stdlib/deprecation_gen' -PuppetX::Puppetlabs::Stdlib.deprecation_gen("validate_ip_address", "Stdlib::Compat::Ip_Address") -# Puppet::Functions.create_function diff --git a/lib/puppet/functions/validate_ipv4_address.rb b/lib/puppet/functions/validate_ipv4_address.rb deleted file mode 100644 index 8e1bc59..0000000 --- a/lib/puppet/functions/validate_ipv4_address.rb +++ /dev/null @@ -1,3 +0,0 @@ -require 'puppet_x/puppetlabs/stdlib/deprecation_gen' -PuppetX::Puppetlabs::Stdlib.deprecation_gen("validate_ipv4_address", "Stdlib::Compat::Ipv4_Address") -# Puppet::Functions.create_function diff --git a/lib/puppet/functions/validate_ipv6_address.rb b/lib/puppet/functions/validate_ipv6_address.rb deleted file mode 100644 index 865648a..0000000 --- a/lib/puppet/functions/validate_ipv6_address.rb +++ /dev/null @@ -1,3 +0,0 @@ -require 'puppet_x/puppetlabs/stdlib/deprecation_gen' -PuppetX::Puppetlabs::Stdlib.deprecation_gen("validate_ipv6_address", "Stdlib::Compat::Ipv6_address") -# Puppet::Functions.create_function diff --git a/lib/puppet/functions/validate_numeric.rb b/lib/puppet/functions/validate_numeric.rb deleted file mode 100644 index 0c2e1f2..0000000 --- a/lib/puppet/functions/validate_numeric.rb +++ /dev/null @@ -1,3 +0,0 @@ -require 'puppet_x/puppetlabs/stdlib/deprecation_gen' -PuppetX::Puppetlabs::Stdlib.deprecation_gen("validate_numeric", "Stdlib::Compat::Numeric") -# Puppet::Functions.create_function diff --git a/lib/puppet/functions/validate_re.rb b/lib/puppet/functions/validate_re.rb deleted file mode 100644 index d63ed42..0000000 --- a/lib/puppet/functions/validate_re.rb +++ /dev/null @@ -1,3 +0,0 @@ -require 'puppet_x/puppetlabs/stdlib/deprecation_gen' -PuppetX::Puppetlabs::Stdlib.deprecation_gen("validate_re", "Stdlib::Compat::Re") -# Puppet::Functions.create_function diff --git a/lib/puppet/functions/validate_string.rb b/lib/puppet/functions/validate_string.rb deleted file mode 100644 index a196f43..0000000 --- a/lib/puppet/functions/validate_string.rb +++ /dev/null @@ -1,3 +0,0 @@ -require 'puppet_x/puppetlabs/stdlib/deprecation_gen' -PuppetX::Puppetlabs::Stdlib.deprecation_gen("validate_string", "Stdlib::Compat::String") -# Puppet::Functions.create_function diff --git a/lib/puppet_x/puppetlabs/stdlib/deprecation_gen.rb b/lib/puppet_x/puppetlabs/stdlib/deprecation_gen.rb deleted file mode 100644 index a3d830b..0000000 --- a/lib/puppet_x/puppetlabs/stdlib/deprecation_gen.rb +++ /dev/null @@ -1,21 +0,0 @@ -# Creates a Puppet 4 function for the corresponding puppet 3 validate function, who's name will be passed as an argument, alongside the type for deprecation output purposes. -module PuppetX - module Puppetlabs - module Stdlib - def self.deprecation_gen(funct, type) - Puppet::Functions.create_function(funct, Puppet::Functions::InternalFunction) do - @@funct = funct - @@type = type - dispatch :deprecation_gen do - scope_param - optional_repeated_param 'Any', :args - end - def deprecation_gen(scope, *args) - call_function('deprecation', 'puppet_3_type_check', "This method is deprecated, please use the stdlib validate_legacy function, with #{@@type}. There is further documentation for validate_legacy function in the README.") - scope.send("function_#{@@funct}", args) - end - end - end - end - end -end diff --git a/spec/acceptance/validate_array_spec.rb b/spec/acceptance/validate_array_spec.rb index 2f549d5..b53e98c 100755 --- a/spec/acceptance/validate_array_spec.rb +++ b/spec/acceptance/validate_array_spec.rb @@ -20,14 +20,14 @@ describe 'validate_array function', :unless => UNSUPPORTED_PLATFORMS.include?(fa apply_manifest(pp, :catch_failures => true) end - [ - %{validate_array({'a' => 'hash' })}, - %{validate_array('string')}, - %{validate_array(false)}, - %{validate_array(undef)} - ].each do |pp| - it "rejects #{pp.inspect}" do - expect(apply_manifest(pp, :expect_failures => true).stderr).to match(/is not an Array\. It looks to be a/) + it 'validates a non-array' do + { + %{validate_array({'a' => 'hash' })} => "Hash", + %{validate_array('string')} => "String", + %{validate_array(false)} => "FalseClass", + %{validate_array(undef)} => "String" + }.each do |pp,type| + expect(apply_manifest(pp, :expect_failures => true).stderr).to match(/a #{type}/) end end end diff --git a/spec/acceptance/validate_bool_spec.rb b/spec/acceptance/validate_bool_spec.rb index 5c52d0f..c837f08 100755 --- a/spec/acceptance/validate_bool_spec.rb +++ b/spec/acceptance/validate_bool_spec.rb @@ -20,14 +20,14 @@ describe 'validate_bool function', :unless => UNSUPPORTED_PLATFORMS.include?(fac apply_manifest(pp, :catch_failures => true) end - [ - %{validate_bool('true')}, - %{validate_bool('false')}, - %{validate_bool([true])}, - %{validate_bool(undef)} - ].each do |pp| - it "rejects #{pp.inspect}" do - expect(apply_manifest(pp, :expect_failures => true).stderr).to match(/is not a boolean\. It looks to be a/) + it 'validates a non-bool' do + { + %{validate_bool('true')} => "String", + %{validate_bool('false')} => "String", + %{validate_bool([true])} => "Array", + %{validate_bool(undef)} => "String", + }.each do |pp,type| + expect(apply_manifest(pp, :expect_failures => true).stderr).to match(/a #{type}/) end end end diff --git a/spec/acceptance/validate_hash_spec.rb b/spec/acceptance/validate_hash_spec.rb index 637df0a..52fb615 100755 --- a/spec/acceptance/validate_hash_spec.rb +++ b/spec/acceptance/validate_hash_spec.rb @@ -20,14 +20,14 @@ describe 'validate_hash function', :unless => UNSUPPORTED_PLATFORMS.include?(fac apply_manifest(pp, :catch_failures => true) end - [ - %{validate_hash('{ "not" => "hash" }')}, - %{validate_hash('string')}, - %{validate_hash(["array"])}, - %{validate_hash(undef)} - ].each do |pp| - it "rejects #{pp.inspect}" do - expect(apply_manifest(pp, :expect_failures => true).stderr).to match(//) + it 'validates a non-hash' do + { + %{validate_hash('{ "not" => "hash" }')} => "String", + %{validate_hash('string')} => "String", + %{validate_hash(["array"])} => "Array", + %{validate_hash(undef)} => "String", + }.each do |pp,type| + expect(apply_manifest(pp, :expect_failures => true).stderr).to match(/a #{type}/) end end end -- cgit v1.2.3 From 055dbb611a60f5d8a6c184e12f8da0b85b8971dd Mon Sep 17 00:00:00 2001 From: Helen Campbell Date: Wed, 21 Sep 2016 17:28:04 +0100 Subject: Add deprecation warnings to remaining validates --- lib/puppet/parser/functions/validate_hash.rb | 2 ++ lib/puppet/parser/functions/validate_slength.rb | 2 ++ spec/functions/validate_hash_spec.rb | 12 ++++++++++++ spec/functions/validate_slength_spec.rb | 11 +++++++++++ 4 files changed, 27 insertions(+) diff --git a/lib/puppet/parser/functions/validate_hash.rb b/lib/puppet/parser/functions/validate_hash.rb index 9bdd543..800a758 100644 --- a/lib/puppet/parser/functions/validate_hash.rb +++ b/lib/puppet/parser/functions/validate_hash.rb @@ -18,6 +18,8 @@ module Puppet::Parser::Functions ENDHEREDOC + function_deprecation([:puppet_3_type_check, 'This method is deprecated, please use the stdlib validate_legacy function, with Stdlib::Compat::Hash. There is further documentation for validate_legacy function in the README.']) + unless args.length > 0 then raise Puppet::ParseError, ("validate_hash(): wrong number of arguments (#{args.length}; must be > 0)") end diff --git a/lib/puppet/parser/functions/validate_slength.rb b/lib/puppet/parser/functions/validate_slength.rb index 47c7d4a..1641e5a 100644 --- a/lib/puppet/parser/functions/validate_slength.rb +++ b/lib/puppet/parser/functions/validate_slength.rb @@ -21,6 +21,8 @@ module Puppet::Parser::Functions ENDHEREDOC + function_deprecation([:puppet_3_type_check, 'This method is deprecated, please use the stdlib validate_legacy function, with Stdlib::Compat::String[x]. There is further documentation for validate_legacy function in the README.']) + raise Puppet::ParseError, "validate_slength(): Wrong number of arguments (#{args.length}; must be 2 or 3)" unless args.length == 2 or args.length == 3 input, max_length, min_length = *args diff --git a/spec/functions/validate_hash_spec.rb b/spec/functions/validate_hash_spec.rb index 2e8e59f..7b118e2 100755 --- a/spec/functions/validate_hash_spec.rb +++ b/spec/functions/validate_hash_spec.rb @@ -5,6 +5,18 @@ describe 'validate_hash' 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) } + describe 'check for deprecation warning' do + after(:context) do + ENV.delete('STDLIB_LOG_DEPRECATIONS') + end + # Checking for deprecation warning + it 'should display a single deprecation' do + ENV['STDLIB_LOG_DEPRECATIONS'] = "true" + scope.expects(:warning).with(includes('This method is deprecated')) + is_expected.to run.with_params({'key' => 'value'}) + end + end + describe 'valid inputs' do it { is_expected.to run.with_params({}) } it { is_expected.to run.with_params({'key' => 'value'}) } diff --git a/spec/functions/validate_slength_spec.rb b/spec/functions/validate_slength_spec.rb index 5a8fa6a..2ea253c 100755 --- a/spec/functions/validate_slength_spec.rb +++ b/spec/functions/validate_slength_spec.rb @@ -1,6 +1,17 @@ require 'spec_helper' describe 'validate_slength' do + after(:context) do + ENV.delete('STDLIB_LOG_DEPRECATIONS') + end + + # Checking for deprecation warning + it 'should display a single deprecation' do + ENV['STDLIB_LOG_DEPRECATIONS'] = "true" + scope.expects(:warning).with(includes('This method is deprecated')) + is_expected.to run.with_params('1234567890', 10) + end + 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) } -- cgit v1.2.3 From 02fc7f8e4912e0def8e6717c4de38a951bf4b741 Mon Sep 17 00:00:00 2001 From: Helen Campbell Date: Mon, 26 Sep 2016 16:45:23 +0100 Subject: Remove duplicate deprecation warnings --- lib/puppet/parser/functions/validate_absolute_path.rb | 3 ++- lib/puppet/parser/functions/validate_bool.rb | 3 ++- spec/functions/validate_absolute_path_spec.rb | 3 +-- spec/functions/validate_bool_spec.rb | 3 +-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/puppet/parser/functions/validate_absolute_path.rb b/lib/puppet/parser/functions/validate_absolute_path.rb index d5f5443..15b5c57 100644 --- a/lib/puppet/parser/functions/validate_absolute_path.rb +++ b/lib/puppet/parser/functions/validate_absolute_path.rb @@ -26,7 +26,8 @@ module Puppet::Parser::Functions ENDHEREDOC - function_deprecation([:puppet_3_type_check, 'This method is deprecated, please use the stdlib validate_legacy function, with Stdlib::Compat::Absolute_path. There is further documentation for validate_legacy function in the README.']) + # The deprecation function was being called twice, as validate_absolute_path calls is_absolute_path. I have removed it from here so it only calls deprecation once within is_absolute_path. + # function_deprecation([:puppet_3_type_check, 'This method is deprecated, please use the stdlib validate_legacy function, with Stdlib::Compat::Absolute_path. There is further documentation for validate_legacy function in the README.']) require 'puppet/util' diff --git a/lib/puppet/parser/functions/validate_bool.rb b/lib/puppet/parser/functions/validate_bool.rb index 4e52ffd..e4345eb 100644 --- a/lib/puppet/parser/functions/validate_bool.rb +++ b/lib/puppet/parser/functions/validate_bool.rb @@ -19,7 +19,8 @@ module Puppet::Parser::Functions ENDHEREDOC - function_deprecation([:puppet_3_type_check, 'This method is deprecated, please use the stdlib validate_legacy function, with Stdlib::Compat::Bool. There is further documentation for validate_legacy function in the README.']) + # The deprecation function was being called twice, as validate_bool calls is_bool. I have removed it from here so it only calls deprecation once within is_bool. + # function_deprecation([:puppet_3_type_check, 'This method is deprecated, please use the stdlib validate_legacy function, with Stdlib::Compat::Bool. There is further documentation for validate_legacy function in the README.']) unless args.length > 0 then raise Puppet::ParseError, ("validate_bool(): wrong number of arguments (#{args.length}; must be > 0)") diff --git a/spec/functions/validate_absolute_path_spec.rb b/spec/functions/validate_absolute_path_spec.rb index 75df6bc..bdb55f0 100755 --- a/spec/functions/validate_absolute_path_spec.rb +++ b/spec/functions/validate_absolute_path_spec.rb @@ -7,9 +7,8 @@ describe 'validate_absolute_path' do # Checking for deprecation warning it 'should display a single deprecation' do - # called twice because validate_absolute_path calls is_absolute_path ENV['STDLIB_LOG_DEPRECATIONS'] = "true" - scope.expects(:warning).with(includes('This method is deprecated')).twice + scope.expects(:warning).with(includes('This method is deprecated')) is_expected.to run.with_params('c:/') end diff --git a/spec/functions/validate_bool_spec.rb b/spec/functions/validate_bool_spec.rb index 4bd1453..8b7e438 100755 --- a/spec/functions/validate_bool_spec.rb +++ b/spec/functions/validate_bool_spec.rb @@ -7,9 +7,8 @@ describe 'validate_bool' do # Checking for deprecation warning it 'should display a single deprecation' do - #called twice, because validate_bool calls is_bool ENV['STDLIB_LOG_DEPRECATIONS'] = "true" - scope.expects(:warning).with(includes('This method is deprecated')).twice + scope.expects(:warning).with(includes('This method is deprecated')) is_expected.to run.with_params(true) end -- cgit v1.2.3 From 970852dd317fbb2699b406dd25aeddef496a7c92 Mon Sep 17 00:00:00 2001 From: Helen Campbell Date: Mon, 3 Oct 2016 14:10:50 +0100 Subject: Addition of Puppet 4 functions --- lib/puppet/functions/validate_absolute_path.rb | 3 +++ lib/puppet/functions/validate_array.rb | 3 +++ lib/puppet/functions/validate_bool.rb | 3 +++ lib/puppet/functions/validate_hash.rb | 3 +++ lib/puppet/functions/validate_integer.rb | 3 +++ lib/puppet/functions/validate_ip_address.rb | 3 +++ lib/puppet/functions/validate_ipv4_address.rb | 3 +++ lib/puppet/functions/validate_ipv6_address.rb | 3 +++ lib/puppet/functions/validate_numeric.rb | 3 +++ lib/puppet/functions/validate_re.rb | 3 +++ lib/puppet/functions/validate_string.rb | 3 +++ lib/puppet_x/puppetlabs/stdlib/deprecation_gen.rb | 19 +++++++++++++++++++ 12 files changed, 52 insertions(+) create mode 100644 lib/puppet/functions/validate_absolute_path.rb create mode 100644 lib/puppet/functions/validate_array.rb create mode 100644 lib/puppet/functions/validate_bool.rb create mode 100644 lib/puppet/functions/validate_hash.rb create mode 100644 lib/puppet/functions/validate_integer.rb create mode 100644 lib/puppet/functions/validate_ip_address.rb create mode 100644 lib/puppet/functions/validate_ipv4_address.rb create mode 100644 lib/puppet/functions/validate_ipv6_address.rb create mode 100644 lib/puppet/functions/validate_numeric.rb create mode 100644 lib/puppet/functions/validate_re.rb create mode 100644 lib/puppet/functions/validate_string.rb create mode 100644 lib/puppet_x/puppetlabs/stdlib/deprecation_gen.rb diff --git a/lib/puppet/functions/validate_absolute_path.rb b/lib/puppet/functions/validate_absolute_path.rb new file mode 100644 index 0000000..5ae9d29 --- /dev/null +++ b/lib/puppet/functions/validate_absolute_path.rb @@ -0,0 +1,3 @@ +require 'puppet_x/puppetlabs/stdlib/deprecation_gen' +PuppetX::Puppetlabs::Stdlib.deprecation_gen("validate_absolute_path", "Stdlib::Compat::Absolute_Path") +# Puppet::Functions.create_function diff --git a/lib/puppet/functions/validate_array.rb b/lib/puppet/functions/validate_array.rb new file mode 100644 index 0000000..9155784 --- /dev/null +++ b/lib/puppet/functions/validate_array.rb @@ -0,0 +1,3 @@ +require 'puppet_x/puppetlabs/stdlib/deprecation_gen' +PuppetX::Puppetlabs::Stdlib.deprecation_gen("validate_array", "Stdlib::Compat::Array") +# Puppet::Functions.create_function diff --git a/lib/puppet/functions/validate_bool.rb b/lib/puppet/functions/validate_bool.rb new file mode 100644 index 0000000..10f6edf --- /dev/null +++ b/lib/puppet/functions/validate_bool.rb @@ -0,0 +1,3 @@ +require 'puppet_x/puppetlabs/stdlib/deprecation_gen' +PuppetX::Puppetlabs::Stdlib.deprecation_gen("validate_bool", "Stdlib::Compat::Bool") +# Puppet::Functions.create_function diff --git a/lib/puppet/functions/validate_hash.rb b/lib/puppet/functions/validate_hash.rb new file mode 100644 index 0000000..5349664 --- /dev/null +++ b/lib/puppet/functions/validate_hash.rb @@ -0,0 +1,3 @@ +require 'puppet_x/puppetlabs/stdlib/deprecation_gen' +PuppetX::Puppetlabs::Stdlib.deprecation_gen("validate_hash", "Stdlib::Compat::Hash") +# Puppet::Functions.create_function diff --git a/lib/puppet/functions/validate_integer.rb b/lib/puppet/functions/validate_integer.rb new file mode 100644 index 0000000..2c4645d --- /dev/null +++ b/lib/puppet/functions/validate_integer.rb @@ -0,0 +1,3 @@ +require 'puppet_x/puppetlabs/stdlib/deprecation_gen' +PuppetX::Puppetlabs::Stdlib.deprecation_gen("validate_integer", "Stdlib::Compat::Integer") +# Puppet::Functions.create_function diff --git a/lib/puppet/functions/validate_ip_address.rb b/lib/puppet/functions/validate_ip_address.rb new file mode 100644 index 0000000..15a710e --- /dev/null +++ b/lib/puppet/functions/validate_ip_address.rb @@ -0,0 +1,3 @@ +require 'puppet_x/puppetlabs/stdlib/deprecation_gen' +PuppetX::Puppetlabs::Stdlib.deprecation_gen("validate_ip_address", "Stdlib::Compat::Ip_Address") +# Puppet::Functions.create_function diff --git a/lib/puppet/functions/validate_ipv4_address.rb b/lib/puppet/functions/validate_ipv4_address.rb new file mode 100644 index 0000000..8e1bc59 --- /dev/null +++ b/lib/puppet/functions/validate_ipv4_address.rb @@ -0,0 +1,3 @@ +require 'puppet_x/puppetlabs/stdlib/deprecation_gen' +PuppetX::Puppetlabs::Stdlib.deprecation_gen("validate_ipv4_address", "Stdlib::Compat::Ipv4_Address") +# Puppet::Functions.create_function diff --git a/lib/puppet/functions/validate_ipv6_address.rb b/lib/puppet/functions/validate_ipv6_address.rb new file mode 100644 index 0000000..865648a --- /dev/null +++ b/lib/puppet/functions/validate_ipv6_address.rb @@ -0,0 +1,3 @@ +require 'puppet_x/puppetlabs/stdlib/deprecation_gen' +PuppetX::Puppetlabs::Stdlib.deprecation_gen("validate_ipv6_address", "Stdlib::Compat::Ipv6_address") +# Puppet::Functions.create_function diff --git a/lib/puppet/functions/validate_numeric.rb b/lib/puppet/functions/validate_numeric.rb new file mode 100644 index 0000000..0c2e1f2 --- /dev/null +++ b/lib/puppet/functions/validate_numeric.rb @@ -0,0 +1,3 @@ +require 'puppet_x/puppetlabs/stdlib/deprecation_gen' +PuppetX::Puppetlabs::Stdlib.deprecation_gen("validate_numeric", "Stdlib::Compat::Numeric") +# Puppet::Functions.create_function diff --git a/lib/puppet/functions/validate_re.rb b/lib/puppet/functions/validate_re.rb new file mode 100644 index 0000000..d63ed42 --- /dev/null +++ b/lib/puppet/functions/validate_re.rb @@ -0,0 +1,3 @@ +require 'puppet_x/puppetlabs/stdlib/deprecation_gen' +PuppetX::Puppetlabs::Stdlib.deprecation_gen("validate_re", "Stdlib::Compat::Re") +# Puppet::Functions.create_function diff --git a/lib/puppet/functions/validate_string.rb b/lib/puppet/functions/validate_string.rb new file mode 100644 index 0000000..a196f43 --- /dev/null +++ b/lib/puppet/functions/validate_string.rb @@ -0,0 +1,3 @@ +require 'puppet_x/puppetlabs/stdlib/deprecation_gen' +PuppetX::Puppetlabs::Stdlib.deprecation_gen("validate_string", "Stdlib::Compat::String") +# Puppet::Functions.create_function diff --git a/lib/puppet_x/puppetlabs/stdlib/deprecation_gen.rb b/lib/puppet_x/puppetlabs/stdlib/deprecation_gen.rb new file mode 100644 index 0000000..0d8908d --- /dev/null +++ b/lib/puppet_x/puppetlabs/stdlib/deprecation_gen.rb @@ -0,0 +1,19 @@ +# Creates a Puppet 4 function for the corresponding puppet 3 validate function, who's name will be passed as an argument, alongside the type for deprecation output purposes. +module PuppetX + module Puppetlabs + module Stdlib + def self.deprecation_gen(funct, type) + Puppet::Functions.create_function(funct, Puppet::Functions::InternalFunction) do + dispatch :deprecation_gen do + scope_param + optional_repeated_param 'Any', :args + end + define_method 'deprecation_gen' do |scope, *args| + call_function('deprecation', 'puppet_3_type_check', "This method is deprecated, please use the stdlib validate_legacy function, with #{type}. There is further documentation for validate_legacy function in the README.") + scope.send("function_#{funct}", args) + end + end + end + end + end +end -- cgit v1.2.3 From 75a35675cad0bc2fef03c74a5a3bcc28fff9f9d0 Mon Sep 17 00:00:00 2001 From: Helen Campbell Date: Mon, 3 Oct 2016 14:11:44 +0100 Subject: Acceptance test cleanup --- spec/acceptance/validate_array_spec.rb | 16 ++++++++-------- spec/acceptance/validate_bool_spec.rb | 16 ++++++++-------- spec/acceptance/validate_hash_spec.rb | 16 ++++++++-------- 3 files changed, 24 insertions(+), 24 deletions(-) diff --git a/spec/acceptance/validate_array_spec.rb b/spec/acceptance/validate_array_spec.rb index b53e98c..2f549d5 100755 --- a/spec/acceptance/validate_array_spec.rb +++ b/spec/acceptance/validate_array_spec.rb @@ -20,14 +20,14 @@ describe 'validate_array function', :unless => UNSUPPORTED_PLATFORMS.include?(fa apply_manifest(pp, :catch_failures => true) end - it 'validates a non-array' do - { - %{validate_array({'a' => 'hash' })} => "Hash", - %{validate_array('string')} => "String", - %{validate_array(false)} => "FalseClass", - %{validate_array(undef)} => "String" - }.each do |pp,type| - expect(apply_manifest(pp, :expect_failures => true).stderr).to match(/a #{type}/) + [ + %{validate_array({'a' => 'hash' })}, + %{validate_array('string')}, + %{validate_array(false)}, + %{validate_array(undef)} + ].each do |pp| + it "rejects #{pp.inspect}" do + expect(apply_manifest(pp, :expect_failures => true).stderr).to match(/is not an Array\. It looks to be a/) end end end diff --git a/spec/acceptance/validate_bool_spec.rb b/spec/acceptance/validate_bool_spec.rb index c837f08..5c52d0f 100755 --- a/spec/acceptance/validate_bool_spec.rb +++ b/spec/acceptance/validate_bool_spec.rb @@ -20,14 +20,14 @@ describe 'validate_bool function', :unless => UNSUPPORTED_PLATFORMS.include?(fac apply_manifest(pp, :catch_failures => true) end - it 'validates a non-bool' do - { - %{validate_bool('true')} => "String", - %{validate_bool('false')} => "String", - %{validate_bool([true])} => "Array", - %{validate_bool(undef)} => "String", - }.each do |pp,type| - expect(apply_manifest(pp, :expect_failures => true).stderr).to match(/a #{type}/) + [ + %{validate_bool('true')}, + %{validate_bool('false')}, + %{validate_bool([true])}, + %{validate_bool(undef)} + ].each do |pp| + it "rejects #{pp.inspect}" do + expect(apply_manifest(pp, :expect_failures => true).stderr).to match(/is not a boolean\. It looks to be a/) end end end diff --git a/spec/acceptance/validate_hash_spec.rb b/spec/acceptance/validate_hash_spec.rb index 52fb615..637df0a 100755 --- a/spec/acceptance/validate_hash_spec.rb +++ b/spec/acceptance/validate_hash_spec.rb @@ -20,14 +20,14 @@ describe 'validate_hash function', :unless => UNSUPPORTED_PLATFORMS.include?(fac apply_manifest(pp, :catch_failures => true) end - it 'validates a non-hash' do - { - %{validate_hash('{ "not" => "hash" }')} => "String", - %{validate_hash('string')} => "String", - %{validate_hash(["array"])} => "Array", - %{validate_hash(undef)} => "String", - }.each do |pp,type| - expect(apply_manifest(pp, :expect_failures => true).stderr).to match(/a #{type}/) + [ + %{validate_hash('{ "not" => "hash" }')}, + %{validate_hash('string')}, + %{validate_hash(["array"])}, + %{validate_hash(undef)} + ].each do |pp| + it "rejects #{pp.inspect}" do + expect(apply_manifest(pp, :expect_failures => true).stderr).to match(//) end end end -- cgit v1.2.3 From 8a8ebc4850abe4996056a2700a6a50ac7666a922 Mon Sep 17 00:00:00 2001 From: Helen Campbell Date: Mon, 3 Oct 2016 14:12:32 +0100 Subject: Replace :context with :all in spec tests --- spec/functions/deprecation_spec.rb | 2 +- spec/functions/is_array_spec.rb | 2 +- spec/functions/is_bool_spec.rb | 2 +- spec/functions/is_float_spec.rb | 2 +- spec/functions/is_integer_spec.rb | 2 +- spec/functions/is_ip_address_spec.rb | 2 +- spec/functions/is_ipv4_address_spec.rb | 2 +- spec/functions/is_ipv6_address_spec.rb | 2 +- spec/functions/is_numeric_spec.rb | 2 +- spec/functions/is_string_spec.rb | 2 +- spec/functions/validate_absolute_path_spec.rb | 2 +- spec/functions/validate_array_spec.rb | 2 +- spec/functions/validate_bool_spec.rb | 2 +- spec/functions/validate_hash_spec.rb | 2 +- spec/functions/validate_integer_spec.rb | 2 +- spec/functions/validate_ip_address_spec.rb | 2 +- spec/functions/validate_ipv4_address_spec.rb | 2 +- spec/functions/validate_ipv6_address_spec.rb | 2 +- spec/functions/validate_numeric_spec.rb | 2 +- spec/functions/validate_re_spec.rb | 2 +- spec/functions/validate_slength_spec.rb | 2 +- spec/functions/validate_string_spec.rb | 2 +- 22 files changed, 22 insertions(+), 22 deletions(-) diff --git a/spec/functions/deprecation_spec.rb b/spec/functions/deprecation_spec.rb index 4321c3d..9859833 100644 --- a/spec/functions/deprecation_spec.rb +++ b/spec/functions/deprecation_spec.rb @@ -42,7 +42,7 @@ if Puppet.version.to_f >= 4.0 end else describe 'deprecation' do - after(:context) do + after(:all) do ENV.delete('STDLIB_LOG_DEPRECATIONS') end ENV['STDLIB_LOG_DEPRECATIONS'] = "true" diff --git a/spec/functions/is_array_spec.rb b/spec/functions/is_array_spec.rb index 2350b7f..e89f54b 100755 --- a/spec/functions/is_array_spec.rb +++ b/spec/functions/is_array_spec.rb @@ -18,7 +18,7 @@ describe 'is_array' do it { is_expected.to run.with_params(1).and_return(false) } it { is_expected.to run.with_params({}).and_return(false) } context 'Checking for deprecation warning' do - after(:context) do + after(:all) do ENV.delete('STDLIB_LOG_DEPRECATIONS') end # Checking for deprecation warning, which should only be provoked when the env variable for it is set. diff --git a/spec/functions/is_bool_spec.rb b/spec/functions/is_bool_spec.rb index 7b2173e..d21345c 100755 --- a/spec/functions/is_bool_spec.rb +++ b/spec/functions/is_bool_spec.rb @@ -14,7 +14,7 @@ describe 'is_bool' do it { is_expected.to run.with_params('true').and_return(false) } it { is_expected.to run.with_params('false').and_return(false) } context 'Checking for deprecation warning' do - after(:context) do + after(:all) do ENV.delete('STDLIB_LOG_DEPRECATIONS') end # Checking for deprecation warning, which should only be provoked when the env variable for it is set. diff --git a/spec/functions/is_float_spec.rb b/spec/functions/is_float_spec.rb index 44bdc48..af3322e 100755 --- a/spec/functions/is_float_spec.rb +++ b/spec/functions/is_float_spec.rb @@ -23,7 +23,7 @@ describe 'is_float' do end context 'Checking for deprecation warning' do - after(:context) do + after(:all) do ENV.delete('STDLIB_LOG_DEPRECATIONS') end # Checking for deprecation warning, which should only be provoked when the env variable for it is set. diff --git a/spec/functions/is_integer_spec.rb b/spec/functions/is_integer_spec.rb index 4b5dd21..b296830 100755 --- a/spec/functions/is_integer_spec.rb +++ b/spec/functions/is_integer_spec.rb @@ -26,7 +26,7 @@ describe 'is_integer' do it { is_expected.to run.with_params('0001234').and_return(false) } context 'Checking for deprecation warning' do - after(:context) do + after(:all) do ENV.delete('STDLIB_LOG_DEPRECATIONS') end # Checking for deprecation warning, which should only be provoked when the env variable for it is set. diff --git a/spec/functions/is_ip_address_spec.rb b/spec/functions/is_ip_address_spec.rb index fc8af60..39525d7 100755 --- a/spec/functions/is_ip_address_spec.rb +++ b/spec/functions/is_ip_address_spec.rb @@ -33,7 +33,7 @@ describe 'is_ip_address' do scope.expects(:warning).with(includes('This method is deprecated')).never is_expected.to run.with_params('1.2.3.4').and_return(true) end - after(:context) do + after(:all) do ENV.delete('STDLIB_LOG_DEPRECATIONS') end end diff --git a/spec/functions/is_ipv4_address_spec.rb b/spec/functions/is_ipv4_address_spec.rb index 9d53a9d..e39d93b 100644 --- a/spec/functions/is_ipv4_address_spec.rb +++ b/spec/functions/is_ipv4_address_spec.rb @@ -12,7 +12,7 @@ describe 'is_ipv4_address' do it { is_expected.to run.with_params('one').and_return(false) } context 'Checking for deprecation warning', if: Puppet.version.to_f < 4.0 do - after(:context) do + after(:all) do ENV.delete('STDLIB_LOG_DEPRECATIONS') end # Checking for deprecation warning, which should only be provoked when the env variable for it is set. diff --git a/spec/functions/is_ipv6_address_spec.rb b/spec/functions/is_ipv6_address_spec.rb index 4449fea..acd6a87 100644 --- a/spec/functions/is_ipv6_address_spec.rb +++ b/spec/functions/is_ipv6_address_spec.rb @@ -12,7 +12,7 @@ describe 'is_ipv6_address' do it { is_expected.to run.with_params('one').and_return(false) } context 'Checking for deprecation warning', if: Puppet.version.to_f < 4.0 do - after(:context) do + after(:all) do ENV.delete('STDLIB_LOG_DEPRECATIONS') end # Checking for deprecation warning, which should only be provoked when the env variable for it is set. diff --git a/spec/functions/is_numeric_spec.rb b/spec/functions/is_numeric_spec.rb index ccfb9d8..5962d8a 100755 --- a/spec/functions/is_numeric_spec.rb +++ b/spec/functions/is_numeric_spec.rb @@ -29,7 +29,7 @@ describe 'is_numeric' do it { is_expected.to run.with_params(' - 1234').and_return(false) } context 'Checking for deprecation warning' do - after(:context) do + after(:all) do ENV.delete('STDLIB_LOG_DEPRECATIONS') end # Checking for deprecation warning, which should only be provoked when the env variable for it is set. diff --git a/spec/functions/is_string_spec.rb b/spec/functions/is_string_spec.rb index 460d6e0..e92f85c 100755 --- a/spec/functions/is_string_spec.rb +++ b/spec/functions/is_string_spec.rb @@ -28,7 +28,7 @@ describe 'is_string' do it { is_expected.to run.with_params('0001234').and_return(true) } context 'Checking for deprecation warning' do - after(:context) do + after(:all) do ENV.delete('STDLIB_LOG_DEPRECATIONS') end # Checking for deprecation warning, which should only be provoked when the env variable for it is set. diff --git a/spec/functions/validate_absolute_path_spec.rb b/spec/functions/validate_absolute_path_spec.rb index bdb55f0..9397da5 100755 --- a/spec/functions/validate_absolute_path_spec.rb +++ b/spec/functions/validate_absolute_path_spec.rb @@ -1,7 +1,7 @@ require 'spec_helper' describe 'validate_absolute_path' do - after(:context) do + after(:all) do ENV.delete('STDLIB_LOG_DEPRECATIONS') end diff --git a/spec/functions/validate_array_spec.rb b/spec/functions/validate_array_spec.rb index f395d16..409b3dc 100755 --- a/spec/functions/validate_array_spec.rb +++ b/spec/functions/validate_array_spec.rb @@ -3,7 +3,7 @@ require 'spec_helper' describe 'validate_array' do describe 'signature validation' do - after(:context) do + after(:all) do ENV.delete('STDLIB_LOG_DEPRECATIONS') end it { is_expected.not_to eq(nil) } diff --git a/spec/functions/validate_bool_spec.rb b/spec/functions/validate_bool_spec.rb index 8b7e438..3074d88 100755 --- a/spec/functions/validate_bool_spec.rb +++ b/spec/functions/validate_bool_spec.rb @@ -1,7 +1,7 @@ require 'spec_helper' describe 'validate_bool' do - after(:context) do + after(:all) do ENV.delete('STDLIB_LOG_DEPRECATIONS') end diff --git a/spec/functions/validate_hash_spec.rb b/spec/functions/validate_hash_spec.rb index 7b118e2..7533abe 100755 --- a/spec/functions/validate_hash_spec.rb +++ b/spec/functions/validate_hash_spec.rb @@ -6,7 +6,7 @@ describe 'validate_hash' do it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } describe 'check for deprecation warning' do - after(:context) do + after(:all) do ENV.delete('STDLIB_LOG_DEPRECATIONS') end # Checking for deprecation warning diff --git a/spec/functions/validate_integer_spec.rb b/spec/functions/validate_integer_spec.rb index ffc59f8..6558d00 100755 --- a/spec/functions/validate_integer_spec.rb +++ b/spec/functions/validate_integer_spec.rb @@ -1,7 +1,7 @@ require 'spec_helper' describe 'validate_integer' do - after(:context) do + after(:all) do ENV.delete('STDLIB_LOG_DEPRECATIONS') end diff --git a/spec/functions/validate_ip_address_spec.rb b/spec/functions/validate_ip_address_spec.rb index 7040a8d..0414f5e 100644 --- a/spec/functions/validate_ip_address_spec.rb +++ b/spec/functions/validate_ip_address_spec.rb @@ -22,7 +22,7 @@ describe 'validate_ip_address' do it { is_expected.to run.with_params('fe80::a00:27ff:fe94:44d6/64') } context 'Checking for deprecation warning', if: Puppet.version.to_f < 4.0 do - after(:context) do + after(:all) do ENV.delete('STDLIB_LOG_DEPRECATIONS') end # Checking for deprecation warning, which should only be provoked when the env variable for it is set. diff --git a/spec/functions/validate_ipv4_address_spec.rb b/spec/functions/validate_ipv4_address_spec.rb index b60dc8e..d221793 100755 --- a/spec/functions/validate_ipv4_address_spec.rb +++ b/spec/functions/validate_ipv4_address_spec.rb @@ -8,7 +8,7 @@ describe 'validate_ipv4_address' do end context 'Checking for deprecation warning', if: Puppet.version.to_f < 4.0 do - after(:context) do + after(:all) do ENV.delete('STDLIB_LOG_DEPRECATIONS') end # Checking for deprecation warning, which should only be provoked when the env variable for it is set. diff --git a/spec/functions/validate_ipv6_address_spec.rb b/spec/functions/validate_ipv6_address_spec.rb index 87b535e..78810d4 100755 --- a/spec/functions/validate_ipv6_address_spec.rb +++ b/spec/functions/validate_ipv6_address_spec.rb @@ -8,7 +8,7 @@ describe 'validate_ipv6_address' do end context 'Checking for deprecation warning', if: Puppet.version.to_f < 4.0 do - after(:context) do + after(:all) do ENV.delete('STDLIB_LOG_DEPRECATIONS') end # Checking for deprecation warning, which should only be provoked when the env variable for it is set. diff --git a/spec/functions/validate_numeric_spec.rb b/spec/functions/validate_numeric_spec.rb index 4a65649..4c0e24d 100755 --- a/spec/functions/validate_numeric_spec.rb +++ b/spec/functions/validate_numeric_spec.rb @@ -1,7 +1,7 @@ require 'spec_helper' describe 'validate_numeric' do - after(:context) do + after(:all) do ENV.delete('STDLIB_LOG_DEPRECATIONS') end diff --git a/spec/functions/validate_re_spec.rb b/spec/functions/validate_re_spec.rb index 2fa9ddd..3531182 100755 --- a/spec/functions/validate_re_spec.rb +++ b/spec/functions/validate_re_spec.rb @@ -1,7 +1,7 @@ require 'spec_helper' describe 'validate_re' do - after(:context) do + after(:all) do ENV.delete('STDLIB_LOG_DEPRECATIONS') end diff --git a/spec/functions/validate_slength_spec.rb b/spec/functions/validate_slength_spec.rb index 2ea253c..e4162de 100755 --- a/spec/functions/validate_slength_spec.rb +++ b/spec/functions/validate_slength_spec.rb @@ -1,7 +1,7 @@ require 'spec_helper' describe 'validate_slength' do - after(:context) do + after(:all) do ENV.delete('STDLIB_LOG_DEPRECATIONS') end diff --git a/spec/functions/validate_string_spec.rb b/spec/functions/validate_string_spec.rb index 45d6ffc..b5ce763 100755 --- a/spec/functions/validate_string_spec.rb +++ b/spec/functions/validate_string_spec.rb @@ -1,7 +1,7 @@ require 'spec_helper' describe 'validate_string' do - after(:context) do + after(:all) do ENV.delete('STDLIB_LOG_DEPRECATIONS') end -- cgit v1.2.3 From cce67b42bb6d09d4e9773b64e28c07d8a93ed088 Mon Sep 17 00:00:00 2001 From: Dominic Cleal Date: Tue, 4 Oct 2016 09:36:20 +0100 Subject: Permit undef passed as `nil` to validate_string When validate_string is called via the Puppet 4 deprecation wrappers from deprecation_gen (introduced in 970852d), `undef` is passed as `nil` where it was previously passed as `''` from the Puppet 3-style function API. This change explicitly permits a `nil` value in validate_string, and adds a test case to `is_string` which also accepts the same. Fixes test failures in apt, concat etc: Error while evaluating a Function Call, nil is not a string. It looks to be a NilClass at apt/manifests/source.pp:23:3 [..] # ./spec/fixtures/modules/stdlib/lib/puppet/parser/functions/validate_string.rb:34:in `block (2 levels) in ' # ./spec/fixtures/modules/stdlib/lib/puppet/parser/functions/validate_string.rb:32:in `each' # ./spec/fixtures/modules/stdlib/lib/puppet/parser/functions/validate_string.rb:32:in `block in ' # puppet-4.7.0/lib/puppet/parser/functions.rb:174:in `block (2 levels) in newfunction' # puppet-4.7.0/lib/puppet/util/profiler/around_profiler.rb:58:in `profile' # puppet-4.7.0/lib/puppet/util/profiler.rb:51:in `profile' # puppet-4.7.0/lib/puppet/parser/functions.rb:167:in `block in newfunction' # ./spec/fixtures/modules/stdlib/lib/puppet_x/puppetlabs/stdlib/deprecation_gen.rb:13:in `block (2 levels) in deprecation_gen' --- lib/puppet/parser/functions/validate_string.rb | 2 +- spec/acceptance/is_string_spec.rb | 11 +++++++++++ spec/acceptance/validate_string_spec.rb | 7 +++++++ spec/aliases/string_spec.rb | 3 ++- spec/functions/validate_string_spec.rb | 1 + types/compat/string.pp | 2 +- 6 files changed, 23 insertions(+), 3 deletions(-) diff --git a/lib/puppet/parser/functions/validate_string.rb b/lib/puppet/parser/functions/validate_string.rb index e92a2fc..0057fc1 100644 --- a/lib/puppet/parser/functions/validate_string.rb +++ b/lib/puppet/parser/functions/validate_string.rb @@ -30,7 +30,7 @@ module Puppet::Parser::Functions end args.each do |arg| - unless arg.is_a?(String) + unless arg.is_a?(String) || arg.nil? raise Puppet::ParseError, ("#{arg.inspect} is not a string. It looks to be a #{arg.class}") end end diff --git a/spec/acceptance/is_string_spec.rb b/spec/acceptance/is_string_spec.rb index 94d8e96..f526888 100755 --- a/spec/acceptance/is_string_spec.rb +++ b/spec/acceptance/is_string_spec.rb @@ -95,6 +95,17 @@ describe 'is_string function', :unless => UNSUPPORTED_PLATFORMS.include?(fact('o expect(r.stdout).to match(/Notice: output correct/) end end + it 'is_strings undef' do + pp = <<-EOS + $a = undef + $o = is_string($a) + notice(inline_template('is_string is <%= @o.inspect %>')) + EOS + + apply_manifest(pp, :catch_failures => true) do |r| + expect(r.stdout).to match(/is_string is true/) + end + end end describe 'failure' do it 'handles improper argument counts' diff --git a/spec/acceptance/validate_string_spec.rb b/spec/acceptance/validate_string_spec.rb index 8956f48..ae3468f 100755 --- a/spec/acceptance/validate_string_spec.rb +++ b/spec/acceptance/validate_string_spec.rb @@ -20,6 +20,13 @@ describe 'validate_string function', :unless => UNSUPPORTED_PLATFORMS.include?(f apply_manifest(pp, :catch_failures => true) end + it 'validates undef' do + pp = <<-EOS + validate_string(undef) + EOS + + apply_manifest(pp, :catch_failures => true) + end it 'validates a non-string' do { %{validate_string({ 'a' => 'hash' })} => "Hash", diff --git a/spec/aliases/string_spec.rb b/spec/aliases/string_spec.rb index 8e01d55..853b5af 100644 --- a/spec/aliases/string_spec.rb +++ b/spec/aliases/string_spec.rb @@ -6,6 +6,7 @@ if Puppet.version.to_f >= 4.0 [ '', 'one', + nil, ].each do |value| describe value.inspect do let(:params) {{ value: value }} @@ -23,7 +24,7 @@ if Puppet.version.to_f >= 4.0 ].each do |value| describe value.inspect do let(:params) {{ value: value }} - it { is_expected.to compile.and_raise_error(/parameter 'value' expects a Stdlib::Compat::String = String/) } + it { is_expected.to compile.and_raise_error(/parameter 'value' expects a String/) } end end end diff --git a/spec/functions/validate_string_spec.rb b/spec/functions/validate_string_spec.rb index b5ce763..0907ede 100755 --- a/spec/functions/validate_string_spec.rb +++ b/spec/functions/validate_string_spec.rb @@ -18,6 +18,7 @@ describe 'validate_string' do describe 'valid inputs' do it { is_expected.to run.with_params('') } + it { is_expected.to run.with_params(nil) } it { is_expected.to run.with_params('one') } it { is_expected.to run.with_params('one', 'two') } end diff --git a/types/compat/string.pp b/types/compat/string.pp index 4c36e5f..b06255d 100644 --- a/types/compat/string.pp +++ b/types/compat/string.pp @@ -1,2 +1,2 @@ # Emulate the is_string and validate_string functions -type Stdlib::Compat::String = String +type Stdlib::Compat::String = Optional[String] -- cgit v1.2.3 From 6ebb58623c49f738e2fe857974d54eb5c8638cea Mon Sep 17 00:00:00 2001 From: jbondpdx Date: Wed, 28 Sep 2016 15:22:45 +0100 Subject: MODULES-3774: stdlib validate_legacy review --- README.markdown | 67 +++++++++++++++++++++++++++++++-------------------------- 1 file changed, 37 insertions(+), 30 deletions(-) diff --git a/README.markdown b/README.markdown index 667da33..d27668b 100644 --- a/README.markdown +++ b/README.markdown @@ -304,7 +304,7 @@ Deletes all instances of the undef value from an array or hash. For example, `$h #### `deprecation` -A function to print deprecation warnings, logs a warning once for a given key. The uniqueness key - can appear once. The msg is the message text including any positional information that is formatted by the user/caller of the method. It is affected by the puppet setting 'strict', which can be set to :error (outputs as an error message), :off (no message / error is displayed) and :warning (default, outputs a warning). In Puppet version less than 4.0 an environment variable can be set to decide whether or not to log deprecation warnings (ENV[STDLIB_LOG_DEPRECATION]). If this environment variable is set to true, the functions will log a warning. *Type*: String, String. +Prints deprecation warnings and logs a warning once for a given key. The uniqueness key - can appear once. The msg is the message text, including any positional information that is formatted by the user or caller of the method. The Puppet setting 'strict' affects this function. Set 'strict' to :error to output an error message, :off to output no message or error, or :warning (default) to output a warning. In Puppet versions lower than 4.0, you can set an environment variable to decide whether or not to log deprecation warnings (`ENV[STDLIB_LOG_DEPRECATION]`). If this environment variable is set to true, the functions log a warning. *Type*: String, String. #### `difference` @@ -1370,43 +1370,59 @@ The following values will fail, causing compilation to abort: #### `validate_legacy` -This function supports updating modules to upgrade from Puppet 3 style argument validation (using the stdlib `validate_*` functions) to Puppet 4 data types, without breaking the world. +Validates a value against both a specified type and a deprecated validation function. Silently passes if both pass, errors if only one validation passes, and fails if both validations return false. -##### For module users +Accepts arguments for: +* the type to check the value against, +* the full name of the previous validation function, +* the value to be checked, +* an unspecified number of arguments needed for the previous validation function. + +Example: -You are probably here, because you're receiving loads of deprecation warnings about `validate_*` functions. If you're still on Puppet 3, use the options described in [`deprecation`](#deprecation) to silence the messages for now, and avoid upgrading to module versions which already have dropped Puppet 3 support. If you're already running Puppet 4 (shipped in Puppet Enterprise 2015.2 or later), please read on to understand the required steps to fix those issues. +``` +validate_legacy("Optional[String]", "validate_re", "Value to be validated", ["."]) +``` -The `validate_*` functions were the only way on Puppet 3 to easily check the types of class and define arguments. Additionally some of the functions provided additional helpers like [validate_numeric](#validate_numeric), which would not only allow numbers, but also arrays of numbers. Puppet 4 now allows much better defined type checking using [data types](https://docs.puppet.com/puppet/latest/reference/lang_data.html), without such surprises. To avoid breaking the world for people depending on those surprises, `validate_legacy` provides a way to make those edge-cases visible, and assist people with getting onto the clearer Puppet 4 syntax. +This function supports updating modules from Puppet 3 style argument validation (using the stdlib `validate_*` functions) to Puppet 4 data types, without breaking functionality for those depending on Puppet 3 style validation. -Depending on the current state of development of the modules you use and the data you feed them, you'll encounter different messages: +##### For module users -* "Notice: Accepting previously invalid value for target type ''": Nothing to worry, you're already using values allowed by the new type, that would have been invalid by the old validation function. This is informational only. -* "Warning: This method is deprecated, please use the stdlib validate_legacy function": The module you're using hasn't yet upgraded to validate_legacy, use the options from [deprecation()](#deprecation) to silence the warnings for now, or submit a patch with you module's developer. See below for details. -* "Warning: validate_legacy() expected value, got ": Your code is passing a value to the module that was accepted by the Puppet v3 style validation, but that will not be accepted by the next version of the module. Most often this can be fixed by removing quotes from numbers, or booleans. -* "Error: Evaluation Error: Error while evaluating a Resource Statement, Evaluation Error: Error while evaluating a Function Call, validate_legacy() expected value, got ": Your code is passing a value that is not acceptable to either the new, or the old style validation. +If you are running Puppet 4 and receiving deprecation warnings about `validate_*` functions, the `validate_legacy` function can help you find and resolve the deprecated code. +In Puppet 3, the `validate_*` functions were the only way to easily check the types of class and defined type arguments. Some of the functions provided additional helpers like [validate_numeric](#validate_numeric), which unintentionally allowed not only numbers, but also arrays of numbers. Puppet 4 allows much better defined type checking using [data types](https://docs.puppet.com/puppet/latest/reference/lang_data.html), without such unintentional effects. The `validate_legacy` function makes these differences visible and makes it easier to move to the clearer Puppet 4 syntax. +Depending on the current state of development of the modules you use and the data you feed those modules, you'll encounter different messages: +* `Notice: Accepting previously invalid value for target type ''`: This message is informational only. You're using values that are allowed by the new type, but would have been invalid by the old validation function. +* `Warning: This method is deprecated, please use the stdlib validate_legacy function`: The module has not yet upgraded to `validate_legacy`. Use the [deprecation](#deprecation) options to silence warnings for now, or submit a fix with the module's developer. See the information [for module developers](#for-module-developers) below for how to fix the issue. +* `Warning: validate_legacy() expected value, got _`: Your code passes a value that was accepted by the Puppet 3 style validation, but will not be accepted by the next version of the module. Most often, you can fix this by removing quotes from numbers or booleans. +* `Error: Evaluation Error: Error while evaluating a Resource Statement, Evaluation Error: Error while evaluating a Function Call, validate_legacy() expected value, got `: Your code passes a value that is not acceptable to either the new or the old style validation. ##### For module developers -Many `validate_*` functions have surprising holes in their validation. For example, [validate_numeric](#validate_numeric) would not only allow numbers, but also arrays of numbers, or strings that look like numbers, without giving you any control over the specifics. Contrast that to Puppet 4 [data types](https://docs.puppet.com/puppet/latest/reference/lang_data.html) which allow you to choose between `Numeric`, `Array[Numeric]`, or `Optional[Numeric]`. To get from here to there, without leaving your users behind, the validate_legacy function will provide you with a tool to make this migration as painless as possible. +Many `validate_*` functions have surprising holes in their validation. For example, [validate_numeric](#validate_numeric) allows not only numbers, but also arrays of numbers or strings that look like numbers, without giving you any control over the specifics. In contrast, Puppet 4 [data types](https://docs.puppet.com/puppet/latest/reference/lang_data.html) allows you to choose between `Numeric`, `Array[Numeric]`, or `Optional[Numeric]`. The `validate_legacy` function helps you move from Puppet 3 style validation to Puppet 4 validation without breaking functionality your module's users depend on. -To start out, for each parameter of your classes and defines, you'll have to decide on a new Puppet 4 data type to use. In most cases the new data type will allow a different set of values than the original `validate_*` function (which is the point of the whole exercise). The situation then looks like this: +For each parameter of your classes and defined types, choose a new Puppet 4 data type to use. In most cases, the new data type allows a different set of values than the original `validate_*` function. The situation then looks like this: | | `validate_` pass | `validate_` fail | | ------------ | ---------------- | ---------------- | | matches type | pass | pass, notice | | fails type | pass, deprecated | fail | -The code after the validation will still have to deal with all possible values for now, but users of your code can now change their manifests to only pass values that will match the new type. +The code after the validation still has to handle all possible values for now, but users of your code can change their manifests to pass only values that match the new type. + +For each `validate_*` function in stdlib, there is a matching `Stdlib::Compat::*` type that allows the appropriate set of values. See the documentation in the `types/` directory in the stdlib source code for caveats. + +For example, given a class that should accept only numbers, like this: -To effect those checks, given a class like this: ~~~ class example($value) { validate_numeric($value) ~~~ -which should only accept numbers, the resulting validation code looks like this: + +the resulting validation code looks like this: + ~~~ class example( Variant[Stdlib::Compat::Numeric, Numeric] $value @@ -1414,26 +1430,17 @@ class example( validate_legacy(Numeric, 'validate_numeric', $value) ~~~ -The type of `$value` is defined as `Variant[Stdlib::Compat::Numeric, Numeric]`, which will allow any `Numeric` (the new type), and all values previously accepted by validate_numeric (through `Stdlib::Compat::Numeric`). For each `validate_*` function in stdlib, there is a matching `Stdlib::Compat::*` type that will allow the appropriate set of values through. See the documentation in the `types/` directory in the stdlib source code for caveats. - -The call to `validate_legacy` will take care of triggering the correct log or fail message for you. It requires the new type, the previous validation function name, and all arguments to that function. +Here, the type of `$value` is defined as `Variant[Stdlib::Compat::Numeric, Numeric]`, which allows any `Numeric` (the new type), as well as all values previously accepted by `validate_numeric` (through `Stdlib::Compat::Numeric`). -If you were previously still supporting Puppet 3, this is a breaking change. You'll need to update your `metadata.json` to not support Puppet 3 anymore in the `requirements` section, and bump the major version of your module. This should still pass all previously existing tests your module has. Do not forget to add more tests for the newly possible values. This is also a good time to start calling [`deprecation()`](#deprecation) for all parameters you always wanted to get rid of, or add additional constraints on your parameters. +The call to `validate_legacy` takes care of triggering the correct log or fail message for you. It requires the new type, the previous validation function name, and all arguments to that function. -After releasing this version, you can at any time release another breaking change release where you remove all compat types, and all calls to `validate_legacy`. At this time you can also go through your code and remove all leftovers dealing with the previously possible values. +If your module still supported Puppet 3, this is a breaking change. Update your `metadata.json` requirements section to indicate that your module no longer supports Puppet 3, and bump the major version of your module. With this change, all existing tests for your module should still pass. Create additional tests for the new possible values. -At all times note in the CHANGELOG and the README at what stage of the process your modules currently are. +As a breaking change, this is also a good time to call [`deprecation`](#deprecation) for any parameters you want to get rid of, or to add additional constraints on your parameters. -##### Reference +After releasing this version, you can release another breaking change release where you remove all compat types and all calls to `validate_legacy`. At that time, you can also go through your code and remove any leftovers dealing with the previously possible values. -Validates a value against both a specified type and a deprecated validation function. Silently passes if both pass, errors if one validation passes and the other does not, fails if both validations return false. -Arguments include the type to check the value against, the full name of the previous validation function, the value itself to be checked, and an unspecified amount of arguments needed for the previous validation function. - -Example: - - ~~~ - validate_legacy("Optional[String]", "validate_re", "Value to be validated", ["."]) - ~~~ +Always note such changes in your CHANGELOG and README. #### `validate_numeric` -- cgit v1.2.3 From 3c12e20526b4c6c6e36f6acc103f42f7e5915477 Mon Sep 17 00:00:00 2001 From: David Schmitt Date: Tue, 4 Oct 2016 14:11:17 +0100 Subject: (MODULES-3933) Fix getparam for 'false' values This is the idiomatic version of #634, and also addresses the test failures. Original-Fix-By: Michiel Brandenburg --- lib/puppet/parser/functions/getparam.rb | 2 +- spec/functions/getparam_spec.rb | 5 +---- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/lib/puppet/parser/functions/getparam.rb b/lib/puppet/parser/functions/getparam.rb index 6d51006..0a5cbe0 100644 --- a/lib/puppet/parser/functions/getparam.rb +++ b/lib/puppet/parser/functions/getparam.rb @@ -28,7 +28,7 @@ ENDOFDOC return '' if param.empty? if resource = findresource(reference.to_s) - return resource[param] if resource[param] + return resource[param] unless resource[param].nil? end return '' diff --git a/spec/functions/getparam_spec.rb b/spec/functions/getparam_spec.rb index 9e3d9e4..e4ef9e6 100755 --- a/spec/functions/getparam_spec.rb +++ b/spec/functions/getparam_spec.rb @@ -22,9 +22,6 @@ describe 'getparam' do it { is_expected.to run.with_params('User[one]', 'ensure').and_return('present') } it { is_expected.to run.with_params('User[two]', 'ensure').and_return('') } it { is_expected.to run.with_params('User[one]', 'shell').and_return('/bin/sh') } - it { - pending("both rspec-puppet as well as the function do the wrong thing here.") - is_expected.to run.with_params('User[one]', 'managehome').and_return(false) - } + it { is_expected.to run.with_params('User[one]', 'managehome').and_return(false) } end end -- cgit v1.2.3 From 4aa519e998f2f4ce567bcaae5880800884a44bf6 Mon Sep 17 00:00:00 2001 From: Helen Campbell Date: Thu, 6 Oct 2016 14:19:14 +0100 Subject: Corrects Puppet version for compat types tests --- spec/aliases/absolute_path_spec.rb | 2 +- spec/aliases/array_spec.rb | 2 +- spec/aliases/bool_spec.rb | 2 +- spec/aliases/float_spec.rb | 2 +- spec/aliases/integer_spec.rb | 2 +- spec/aliases/ip_address.rb | 2 +- spec/aliases/ipv4_spec.rb | 2 +- spec/aliases/ipv6_spec.rb | 2 +- spec/aliases/numeric_spec.rb | 2 +- spec/aliases/string_spec.rb | 2 +- 10 files changed, 10 insertions(+), 10 deletions(-) diff --git a/spec/aliases/absolute_path_spec.rb b/spec/aliases/absolute_path_spec.rb index 0bcdf85..3fb9d12 100644 --- a/spec/aliases/absolute_path_spec.rb +++ b/spec/aliases/absolute_path_spec.rb @@ -1,6 +1,6 @@ require 'spec_helper' -if Puppet.version.to_f >= 4.0 +if Puppet.version.to_f >= 4.5 describe 'test::absolute_path', type: :class do describe 'valid paths handling' do %w{ diff --git a/spec/aliases/array_spec.rb b/spec/aliases/array_spec.rb index 8bbb8b3..d0f9877 100644 --- a/spec/aliases/array_spec.rb +++ b/spec/aliases/array_spec.rb @@ -1,6 +1,6 @@ require 'spec_helper' -if Puppet.version.to_f >= 4.0 +if Puppet.version.to_f >= 4.5 describe 'test::array', type: :class do describe 'accepts arrays' do [ diff --git a/spec/aliases/bool_spec.rb b/spec/aliases/bool_spec.rb index f664457..78c57fc 100644 --- a/spec/aliases/bool_spec.rb +++ b/spec/aliases/bool_spec.rb @@ -1,6 +1,6 @@ require 'spec_helper' -if Puppet.version.to_f >= 4.0 +if Puppet.version.to_f >= 4.5 describe 'test::bool', type: :class do describe 'accepts booleans' do [ diff --git a/spec/aliases/float_spec.rb b/spec/aliases/float_spec.rb index be31e43..cc20758 100644 --- a/spec/aliases/float_spec.rb +++ b/spec/aliases/float_spec.rb @@ -1,6 +1,6 @@ require 'spec_helper' -if Puppet.version.to_f >= 4.0 +if Puppet.version.to_f >= 4.5 describe 'test::float', type: :class do describe 'accepts floats' do [ diff --git a/spec/aliases/integer_spec.rb b/spec/aliases/integer_spec.rb index fbc8c19..260090a 100644 --- a/spec/aliases/integer_spec.rb +++ b/spec/aliases/integer_spec.rb @@ -1,6 +1,6 @@ require 'spec_helper' -if Puppet.version.to_f >= 4.0 +if Puppet.version.to_f >= 4.5 describe 'test::integer', type: :class do describe 'accepts integers' do [ diff --git a/spec/aliases/ip_address.rb b/spec/aliases/ip_address.rb index 036bfe5..664bf24 100644 --- a/spec/aliases/ip_address.rb +++ b/spec/aliases/ip_address.rb @@ -1,6 +1,6 @@ require 'spec_helper' -if Puppet.version.to_f >= 4.0 +if Puppet.version.to_f >= 4.5 describe 'test::ip_address', type: :class do describe 'accepts ipv4 and ipv6 addresses' do [ diff --git a/spec/aliases/ipv4_spec.rb b/spec/aliases/ipv4_spec.rb index 640618c..e767b45 100644 --- a/spec/aliases/ipv4_spec.rb +++ b/spec/aliases/ipv4_spec.rb @@ -1,6 +1,6 @@ require 'spec_helper' -if Puppet.version.to_f >= 4.0 +if Puppet.version.to_f >= 4.5 describe 'test::ipv4', type: :class do describe 'accepts ipv4 addresses' do [ diff --git a/spec/aliases/ipv6_spec.rb b/spec/aliases/ipv6_spec.rb index 688eb16..13d7c3e 100644 --- a/spec/aliases/ipv6_spec.rb +++ b/spec/aliases/ipv6_spec.rb @@ -1,6 +1,6 @@ require 'spec_helper' -if Puppet.version.to_f >= 4.0 +if Puppet.version.to_f >= 4.5 describe 'test::ipv6', type: :class do describe 'accepts ipv6 addresses' do [ diff --git a/spec/aliases/numeric_spec.rb b/spec/aliases/numeric_spec.rb index 9afe4ed..0e98bee 100644 --- a/spec/aliases/numeric_spec.rb +++ b/spec/aliases/numeric_spec.rb @@ -1,6 +1,6 @@ require 'spec_helper' -if Puppet.version.to_f >= 4.0 +if Puppet.version.to_f >= 4.5 describe 'test::numeric', type: :class do describe 'accepts numerics' do [ diff --git a/spec/aliases/string_spec.rb b/spec/aliases/string_spec.rb index 853b5af..8a93585 100644 --- a/spec/aliases/string_spec.rb +++ b/spec/aliases/string_spec.rb @@ -1,6 +1,6 @@ require 'spec_helper' -if Puppet.version.to_f >= 4.0 +if Puppet.version.to_f >= 4.5 describe 'test::string', type: :class do describe 'accepts strings' do [ -- cgit v1.2.3 From bcab71ded8507de4fd9f89b4dcf798b3d98ace59 Mon Sep 17 00:00:00 2001 From: Hailee Kenney Date: Thu, 6 Oct 2016 15:23:35 -0700 Subject: (MODULES-3590) Fix match_for_absence parameter Prior to this commit, due to a bug in the exists? method in the file_line provider, match_for_absence didn't work as described (or at all really). Update the exists? logic so that match_for_absence works as described. Additionally add a unit test to prevent regressions and update the documentation for the parameter to reflect the fact that it is ignored when `ensure => present`. --- README.markdown | 2 +- lib/puppet/provider/file_line/ruby.rb | 6 +++++- lib/puppet/type/file_line.rb | 3 ++- spec/unit/puppet/provider/file_line/ruby_spec.rb | 7 +++++++ 4 files changed, 15 insertions(+), 3 deletions(-) diff --git a/README.markdown b/README.markdown index d27668b..34d26a8 100644 --- a/README.markdown +++ b/README.markdown @@ -128,7 +128,7 @@ All parameters are optional, unless otherwise noted. * `ensure`: Ensures whether the resource is present. Valid options: 'present', 'absent'. Default: 'present'. * `line`: **Required.** Sets the line to be added to the file located by the `path` parameter. Valid options: String. Default: Undefined. * `match`: Specifies a regular expression to run against existing lines in the file; if a match is found, it is replaced rather than adding a new line. A regex comparison is performed against the line value, and if it does not match, an exception is raised. Valid options: String containing a regex. Default: Undefined. -* `match_for_absence`: An optional value to determine if match should be applied when `ensure => absent`. If set to true and match is set, the line that matches match will be deleted. If set to false (the default), match is ignored when `ensure => absent` and the value of `line` is used instead. Default: false. +* `match_for_absence`: An optional value to determine if match should be applied when `ensure => absent`. If set to true and match is set, the line that matches match will be deleted. If set to false (the default), match is ignored when `ensure => absent` and the value of `line` is used instead. Ignored when `ensure => present`. Default: false. * `multiple`: Determines if `match` and/or `after` can change multiple lines. If set to false, an exception will be raised if more than one line matches. Valid options: 'true', 'false'. Default: Undefined. * `name`: Sets the name to use as the identity of the resource. This is necessary if you want the resource namevar to differ from the supplied `title` of the resource. Valid options: String. Default: Undefined. * `path`: **Required.** Defines the file in which Puppet will ensure the line specified by `line`. Must be an absolute path to the file. diff --git a/lib/puppet/provider/file_line/ruby.rb b/lib/puppet/provider/file_line/ruby.rb index aab6fe2..beeb430 100644 --- a/lib/puppet/provider/file_line/ruby.rb +++ b/lib/puppet/provider/file_line/ruby.rb @@ -4,7 +4,11 @@ Puppet::Type.type(:file_line).provide(:ruby) do true else lines.find do |line| - line.chomp == resource[:line].chomp + if resource[:ensure].to_s == 'absent' and resource[:match_for_absence].to_s == 'true' + line.chomp =~ Regexp.new(resource[:match]) + else + line.chomp == resource[:line].chomp + end end end end diff --git a/lib/puppet/type/file_line.rb b/lib/puppet/type/file_line.rb index 6f5c188..7b7d44e 100644 --- a/lib/puppet/type/file_line.rb +++ b/lib/puppet/type/file_line.rb @@ -71,7 +71,8 @@ Puppet::Type.newtype(:file_line) do newparam(:match_for_absence) do desc 'An optional value to determine if match should be applied when ensure => absent.' + ' If set to true and match is set, the line that matches match will be deleted.' + - ' If set to false (the default), match is ignored when ensure => absent.' + ' If set to false (the default), match is ignored when ensure => absent.' + + ' When `ensure => present`, match_for_absence is ignored.' newvalues(true, false) defaultto false end diff --git a/spec/unit/puppet/provider/file_line/ruby_spec.rb b/spec/unit/puppet/provider/file_line/ruby_spec.rb index fdeaf1a..1f41f62 100755 --- a/spec/unit/puppet/provider/file_line/ruby_spec.rb +++ b/spec/unit/puppet/provider/file_line/ruby_spec.rb @@ -363,6 +363,13 @@ describe provider_class do @provider = provider_class.new(@resource) end + it 'should find a line to match' do + File.open(@tmpfile, 'w') do |fh| + fh.write("foo1\nfoo\nfoo2") + end + expect(@provider.exists?).to be_truthy + end + it 'should remove one line if it matches' do File.open(@tmpfile, 'w') do |fh| fh.write("foo1\nfoo\nfoo2") -- cgit v1.2.3 From a4ebae621dd4dc09d760a51b8b221a3250142789 Mon Sep 17 00:00:00 2001 From: David Schmitt Date: Fri, 7 Oct 2016 13:00:06 +0100 Subject: (FM-5703, PUP-6717) Remove the dynamic deprecation_gen This was not working when the puppet master did not have the newest stdlib version in its environment. --- lib/puppet/functions/validate_absolute_path.rb | 13 ++++++++++--- lib/puppet/functions/validate_array.rb | 13 ++++++++++--- lib/puppet/functions/validate_bool.rb | 13 ++++++++++--- lib/puppet/functions/validate_hash.rb | 13 ++++++++++--- lib/puppet/functions/validate_integer.rb | 13 ++++++++++--- lib/puppet/functions/validate_ip_address.rb | 13 ++++++++++--- lib/puppet/functions/validate_ipv4_address.rb | 13 ++++++++++--- lib/puppet/functions/validate_ipv6_address.rb | 13 ++++++++++--- lib/puppet/functions/validate_numeric.rb | 13 ++++++++++--- lib/puppet/functions/validate_re.rb | 13 ++++++++++--- lib/puppet/functions/validate_string.rb | 13 ++++++++++--- lib/puppet/parser/functions/validate_slength.rb | 2 +- lib/puppet_x/puppetlabs/stdlib/deprecation_gen.rb | 19 ------------------- 13 files changed, 111 insertions(+), 53 deletions(-) delete mode 100644 lib/puppet_x/puppetlabs/stdlib/deprecation_gen.rb diff --git a/lib/puppet/functions/validate_absolute_path.rb b/lib/puppet/functions/validate_absolute_path.rb index 5ae9d29..94f52e1 100644 --- a/lib/puppet/functions/validate_absolute_path.rb +++ b/lib/puppet/functions/validate_absolute_path.rb @@ -1,3 +1,10 @@ -require 'puppet_x/puppetlabs/stdlib/deprecation_gen' -PuppetX::Puppetlabs::Stdlib.deprecation_gen("validate_absolute_path", "Stdlib::Compat::Absolute_Path") -# Puppet::Functions.create_function +Puppet::Functions.create_function(:validate_absolute_path, Puppet::Functions::InternalFunction) do + dispatch :deprecation_gen do + scope_param + optional_repeated_param 'Any', :args + end + def deprecation_gen(scope, *args) + call_function('deprecation', 'puppet_3_type_check', "This method is deprecated, please use the stdlib validate_legacy function, with Stdlib::Compat::Absolute_Path. There is further documentation for validate_legacy function in the README.") + scope.send("function_validate_absolute_path", args) + end +end diff --git a/lib/puppet/functions/validate_array.rb b/lib/puppet/functions/validate_array.rb index 9155784..eb8f5e5 100644 --- a/lib/puppet/functions/validate_array.rb +++ b/lib/puppet/functions/validate_array.rb @@ -1,3 +1,10 @@ -require 'puppet_x/puppetlabs/stdlib/deprecation_gen' -PuppetX::Puppetlabs::Stdlib.deprecation_gen("validate_array", "Stdlib::Compat::Array") -# Puppet::Functions.create_function +Puppet::Functions.create_function(:validate_array, Puppet::Functions::InternalFunction) do + dispatch :deprecation_gen do + scope_param + optional_repeated_param 'Any', :args + end + def deprecation_gen(scope, *args) + call_function('deprecation', 'puppet_3_type_check', "This method is deprecated, please use the stdlib validate_legacy function, with Stdlib::Compat::Array. There is further documentation for validate_legacy function in the README.") + scope.send("function_validate_array", args) + end +end diff --git a/lib/puppet/functions/validate_bool.rb b/lib/puppet/functions/validate_bool.rb index 10f6edf..168775d 100644 --- a/lib/puppet/functions/validate_bool.rb +++ b/lib/puppet/functions/validate_bool.rb @@ -1,3 +1,10 @@ -require 'puppet_x/puppetlabs/stdlib/deprecation_gen' -PuppetX::Puppetlabs::Stdlib.deprecation_gen("validate_bool", "Stdlib::Compat::Bool") -# Puppet::Functions.create_function +Puppet::Functions.create_function(:validate_bool, Puppet::Functions::InternalFunction) do + dispatch :deprecation_gen do + scope_param + optional_repeated_param 'Any', :args + end + def deprecation_gen(scope, *args) + call_function('deprecation', 'puppet_3_type_check', "This method is deprecated, please use the stdlib validate_legacy function, with Stdlib::Compat::Bool. There is further documentation for validate_legacy function in the README.") + scope.send("function_validate_bool", args) + end +end diff --git a/lib/puppet/functions/validate_hash.rb b/lib/puppet/functions/validate_hash.rb index 5349664..c356ceb 100644 --- a/lib/puppet/functions/validate_hash.rb +++ b/lib/puppet/functions/validate_hash.rb @@ -1,3 +1,10 @@ -require 'puppet_x/puppetlabs/stdlib/deprecation_gen' -PuppetX::Puppetlabs::Stdlib.deprecation_gen("validate_hash", "Stdlib::Compat::Hash") -# Puppet::Functions.create_function +Puppet::Functions.create_function(:validate_hash, Puppet::Functions::InternalFunction) do + dispatch :deprecation_gen do + scope_param + optional_repeated_param 'Any', :args + end + def deprecation_gen(scope, *args) + call_function('deprecation', 'puppet_3_type_check', "This method is deprecated, please use the stdlib validate_legacy function, with Stdlib::Compat::Hash. There is further documentation for validate_legacy function in the README.") + scope.send("function_validate_hash", args) + end +end diff --git a/lib/puppet/functions/validate_integer.rb b/lib/puppet/functions/validate_integer.rb index 2c4645d..db95f1c 100644 --- a/lib/puppet/functions/validate_integer.rb +++ b/lib/puppet/functions/validate_integer.rb @@ -1,3 +1,10 @@ -require 'puppet_x/puppetlabs/stdlib/deprecation_gen' -PuppetX::Puppetlabs::Stdlib.deprecation_gen("validate_integer", "Stdlib::Compat::Integer") -# Puppet::Functions.create_function +Puppet::Functions.create_function(:validate_integer, Puppet::Functions::InternalFunction) do + dispatch :deprecation_gen do + scope_param + optional_repeated_param 'Any', :args + end + def deprecation_gen(scope, *args) + call_function('deprecation', 'puppet_3_type_check', "This method is deprecated, please use the stdlib validate_legacy function, with Stdlib::Compat::Integer. There is further documentation for validate_legacy function in the README.") + scope.send("function_validate_integer", args) + end +end diff --git a/lib/puppet/functions/validate_ip_address.rb b/lib/puppet/functions/validate_ip_address.rb index 15a710e..eaf56bb 100644 --- a/lib/puppet/functions/validate_ip_address.rb +++ b/lib/puppet/functions/validate_ip_address.rb @@ -1,3 +1,10 @@ -require 'puppet_x/puppetlabs/stdlib/deprecation_gen' -PuppetX::Puppetlabs::Stdlib.deprecation_gen("validate_ip_address", "Stdlib::Compat::Ip_Address") -# Puppet::Functions.create_function +Puppet::Functions.create_function(:validate_ip_address, Puppet::Functions::InternalFunction) do + dispatch :deprecation_gen do + scope_param + optional_repeated_param 'Any', :args + end + def deprecation_gen(scope, *args) + call_function('deprecation', 'puppet_3_type_check', "This method is deprecated, please use the stdlib validate_legacy function, with Stdlib::Compat::Ip_Address. There is further documentation for validate_legacy function in the README.") + scope.send("function_validate_ip_address", args) + end +end diff --git a/lib/puppet/functions/validate_ipv4_address.rb b/lib/puppet/functions/validate_ipv4_address.rb index 8e1bc59..6a870eb 100644 --- a/lib/puppet/functions/validate_ipv4_address.rb +++ b/lib/puppet/functions/validate_ipv4_address.rb @@ -1,3 +1,10 @@ -require 'puppet_x/puppetlabs/stdlib/deprecation_gen' -PuppetX::Puppetlabs::Stdlib.deprecation_gen("validate_ipv4_address", "Stdlib::Compat::Ipv4_Address") -# Puppet::Functions.create_function +Puppet::Functions.create_function(:validate_ipv4_address, Puppet::Functions::InternalFunction) do + dispatch :deprecation_gen do + scope_param + optional_repeated_param 'Any', :args + end + def deprecation_gen(scope, *args) + call_function('deprecation', 'puppet_3_type_check', "This method is deprecated, please use the stdlib validate_legacy function, with Stdlib::Compat::Ipv4_Address. There is further documentation for validate_legacy function in the README.") + scope.send("function_validate_ipv4_address", args) + end +end diff --git a/lib/puppet/functions/validate_ipv6_address.rb b/lib/puppet/functions/validate_ipv6_address.rb index 865648a..922a9ac 100644 --- a/lib/puppet/functions/validate_ipv6_address.rb +++ b/lib/puppet/functions/validate_ipv6_address.rb @@ -1,3 +1,10 @@ -require 'puppet_x/puppetlabs/stdlib/deprecation_gen' -PuppetX::Puppetlabs::Stdlib.deprecation_gen("validate_ipv6_address", "Stdlib::Compat::Ipv6_address") -# Puppet::Functions.create_function +Puppet::Functions.create_function(:validate_ipv6_address, Puppet::Functions::InternalFunction) do + dispatch :deprecation_gen do + scope_param + optional_repeated_param 'Any', :args + end + def deprecation_gen(scope, *args) + call_function('deprecation', 'puppet_3_type_check', "This method is deprecated, please use the stdlib validate_legacy function, with Stdlib::Compat::Ipv6_address. There is further documentation for validate_legacy function in the README.") + scope.send("function_validate_ipv6_address", args) + end +end diff --git a/lib/puppet/functions/validate_numeric.rb b/lib/puppet/functions/validate_numeric.rb index 0c2e1f2..e48bec4 100644 --- a/lib/puppet/functions/validate_numeric.rb +++ b/lib/puppet/functions/validate_numeric.rb @@ -1,3 +1,10 @@ -require 'puppet_x/puppetlabs/stdlib/deprecation_gen' -PuppetX::Puppetlabs::Stdlib.deprecation_gen("validate_numeric", "Stdlib::Compat::Numeric") -# Puppet::Functions.create_function +Puppet::Functions.create_function(:validate_numeric, Puppet::Functions::InternalFunction) do + dispatch :deprecation_gen do + scope_param + optional_repeated_param 'Any', :args + end + def deprecation_gen(scope, *args) + call_function('deprecation', 'puppet_3_type_check', "This method is deprecated, please use the stdlib validate_legacy function, with Stdlib::Compat::Numeric. There is further documentation for validate_legacy function in the README.") + scope.send("function_validate_numeric", args) + end +end diff --git a/lib/puppet/functions/validate_re.rb b/lib/puppet/functions/validate_re.rb index d63ed42..8a95077 100644 --- a/lib/puppet/functions/validate_re.rb +++ b/lib/puppet/functions/validate_re.rb @@ -1,3 +1,10 @@ -require 'puppet_x/puppetlabs/stdlib/deprecation_gen' -PuppetX::Puppetlabs::Stdlib.deprecation_gen("validate_re", "Stdlib::Compat::Re") -# Puppet::Functions.create_function +Puppet::Functions.create_function(:validate_re, Puppet::Functions::InternalFunction) do + dispatch :deprecation_gen do + scope_param + optional_repeated_param 'Any', :args + end + def deprecation_gen(scope, *args) + call_function('deprecation', 'puppet_3_type_check', "This method is deprecated, please use the stdlib validate_legacy function, with Pattern[]. There is further documentation for validate_legacy function in the README.") + scope.send("function_validate_re", args) + end +end diff --git a/lib/puppet/functions/validate_string.rb b/lib/puppet/functions/validate_string.rb index a196f43..fe4c623 100644 --- a/lib/puppet/functions/validate_string.rb +++ b/lib/puppet/functions/validate_string.rb @@ -1,3 +1,10 @@ -require 'puppet_x/puppetlabs/stdlib/deprecation_gen' -PuppetX::Puppetlabs::Stdlib.deprecation_gen("validate_string", "Stdlib::Compat::String") -# Puppet::Functions.create_function +Puppet::Functions.create_function(:validate_string, Puppet::Functions::InternalFunction) do + dispatch :deprecation_gen do + scope_param + optional_repeated_param 'Any', :args + end + def deprecation_gen(scope, *args) + call_function('deprecation', 'puppet_3_type_check', "This method is deprecated, please use the stdlib validate_legacy function, with Stdlib::Compat::String. There is further documentation for validate_legacy function in the README.") + scope.send("function_validate_string", args) + end +end diff --git a/lib/puppet/parser/functions/validate_slength.rb b/lib/puppet/parser/functions/validate_slength.rb index 1641e5a..1828f49 100644 --- a/lib/puppet/parser/functions/validate_slength.rb +++ b/lib/puppet/parser/functions/validate_slength.rb @@ -21,7 +21,7 @@ module Puppet::Parser::Functions ENDHEREDOC - function_deprecation([:puppet_3_type_check, 'This method is deprecated, please use the stdlib validate_legacy function, with Stdlib::Compat::String[x]. There is further documentation for validate_legacy function in the README.']) + function_deprecation([:puppet_3_type_check, 'This method is deprecated, please use the stdlib validate_legacy function, with String[]. There is further documentation for validate_legacy function in the README.']) raise Puppet::ParseError, "validate_slength(): Wrong number of arguments (#{args.length}; must be 2 or 3)" unless args.length == 2 or args.length == 3 diff --git a/lib/puppet_x/puppetlabs/stdlib/deprecation_gen.rb b/lib/puppet_x/puppetlabs/stdlib/deprecation_gen.rb deleted file mode 100644 index 0d8908d..0000000 --- a/lib/puppet_x/puppetlabs/stdlib/deprecation_gen.rb +++ /dev/null @@ -1,19 +0,0 @@ -# Creates a Puppet 4 function for the corresponding puppet 3 validate function, who's name will be passed as an argument, alongside the type for deprecation output purposes. -module PuppetX - module Puppetlabs - module Stdlib - def self.deprecation_gen(funct, type) - Puppet::Functions.create_function(funct, Puppet::Functions::InternalFunction) do - dispatch :deprecation_gen do - scope_param - optional_repeated_param 'Any', :args - end - define_method 'deprecation_gen' do |scope, *args| - call_function('deprecation', 'puppet_3_type_check', "This method is deprecated, please use the stdlib validate_legacy function, with #{type}. There is further documentation for validate_legacy function in the README.") - scope.send("function_#{funct}", args) - end - end - end - end - end -end -- cgit v1.2.3 From ddae9880025b6dfdc3b5a8c177548c8eb5e50a91 Mon Sep 17 00:00:00 2001 From: David Schmitt Date: Fri, 7 Oct 2016 13:00:16 +0100 Subject: (Maint) add missing validate_slength deprecation --- lib/puppet/functions/validate_slength.rb | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 lib/puppet/functions/validate_slength.rb diff --git a/lib/puppet/functions/validate_slength.rb b/lib/puppet/functions/validate_slength.rb new file mode 100644 index 0000000..2d71a14 --- /dev/null +++ b/lib/puppet/functions/validate_slength.rb @@ -0,0 +1,10 @@ +Puppet::Functions.create_function(:validate_slength, Puppet::Functions::InternalFunction) do + dispatch :deprecation_gen do + scope_param + optional_repeated_param 'Any', :args + end + def deprecation_gen(scope, *args) + call_function('deprecation', 'puppet_3_type_check', "This method is deprecated, please use the stdlib validate_legacy function, with String[]. There is further documentation for validate_legacy function in the README.") + scope.send("function_validate_slength", args) + end +end -- cgit v1.2.3 From 83539371e5b1e6ff412eda48c3a725653c506ece Mon Sep 17 00:00:00 2001 From: Helen Campbell Date: Thu, 6 Oct 2016 14:22:13 +0100 Subject: Addition of several new types --- README.markdown | 48 ++++++++++++++++++++++++--- spec/aliases/absolutepath_spec.rb | 49 ++++++++++++++++++++++++++++ spec/aliases/httpsurl_spec.rb | 40 +++++++++++++++++++++++ spec/aliases/httpurl_spec.rb | 43 ++++++++++++++++++++++++ spec/aliases/unixpath_spec.rb | 41 +++++++++++++++++++++++ spec/aliases/windowspath_spec.rb | 44 +++++++++++++++++++++++++ spec/fixtures/test/manifests/absolutepath.pp | 6 ++++ spec/fixtures/test/manifests/httpsurl.pp | 6 ++++ spec/fixtures/test/manifests/httpurl.pp | 6 ++++ spec/fixtures/test/manifests/unixpath.pp | 6 ++++ spec/fixtures/test/manifests/windowspath.pp | 6 ++++ types/absolutepath.pp | 2 ++ types/httpsurl.pp | 1 + types/httpurl.pp | 1 + types/unixpath.pp | 2 ++ types/windowspath.pp | 1 + 16 files changed, 298 insertions(+), 4 deletions(-) create mode 100644 spec/aliases/absolutepath_spec.rb create mode 100644 spec/aliases/httpsurl_spec.rb create mode 100644 spec/aliases/httpurl_spec.rb create mode 100644 spec/aliases/unixpath_spec.rb create mode 100644 spec/aliases/windowspath_spec.rb create mode 100644 spec/fixtures/test/manifests/absolutepath.pp create mode 100644 spec/fixtures/test/manifests/httpsurl.pp create mode 100644 spec/fixtures/test/manifests/httpurl.pp create mode 100644 spec/fixtures/test/manifests/unixpath.pp create mode 100644 spec/fixtures/test/manifests/windowspath.pp create mode 100644 types/absolutepath.pp create mode 100644 types/httpsurl.pp create mode 100644 types/httpurl.pp create mode 100644 types/unixpath.pp create mode 100644 types/windowspath.pp diff --git a/README.markdown b/README.markdown index d27668b..210e9f3 100644 --- a/README.markdown +++ b/README.markdown @@ -22,7 +22,7 @@ This module provides a standard library of resources for the development of Pupp * Facts * Functions * Defined resource types - * Types + * Data Types * Providers > *Note:* As of version 3.7, Puppet Enterprise no longer includes the stdlib module. If you're running Puppet Enterprise, you should install the most recent release of stdlib for compatibility with Puppet modules. @@ -73,7 +73,7 @@ The `stdlib::stages` class declares various run stages for deploying infrastruct * `stdlib::stages`: Manages a standard set of run stages for Puppet. It is managed by the stdlib class and should not be declared independently. -### Types +### Resource Types #### `file_line` @@ -134,6 +134,46 @@ All parameters are optional, unless otherwise noted. * `path`: **Required.** Defines the file in which Puppet will ensure the line specified by `line`. Must be an absolute path to the file. * `replace`: Defines whether the resource will overwrite an existing line that matches the `match` parameter. If set to false and a line is found matching the `match` param, the line will not be placed in the file. Valid options: true, false, yes, no. Default: true +### Data Types + +#### `absolutepath` + +A strict absolute path type. Uses a Variant of Unixpath and Windowspath types. + +Acceptable input examples: /usr2/username/bin:/usr/local/bin:/usr/bin:. + C:\\WINDOWS\\System32 + +#### `httpsurl` + +Matches https URLs. +Acceptable input example: https://hello.com +Unacceptable input example: httds://notquiteright.org + +#### `httpurl` + +Matches both https and http URLs. + +Acceptable input example: https://hello.com + http://hello.com +Unacceptable input example: httds://notquiteright.org + +#### `unixpath` + +Matches paths on Unix type Operating Systems. + +Acceptable input example: /usr2/username/bin:/usr/local/bin:/usr/bin:. + /var/tmp +Unacceptable input example: C:/whatever + +#### `windowspath` + +Matches paths on Windows Operating systems. + +Acceptable input example: C:\\WINDOWS\\System32 + C:\\ + \\\\host\\windows +Unacceptable input example: /usr2/username/bin:/usr/local/bin:/usr/bin:. + ### Functions #### `abs` @@ -1372,7 +1412,7 @@ The following values will fail, causing compilation to abort: Validates a value against both a specified type and a deprecated validation function. Silently passes if both pass, errors if only one validation passes, and fails if both validations return false. -Accepts arguments for: +Accepts arguments for: * the type to check the value against, * the full name of the previous validation function, * the value to be checked, @@ -1430,7 +1470,7 @@ class example( validate_legacy(Numeric, 'validate_numeric', $value) ~~~ -Here, the type of `$value` is defined as `Variant[Stdlib::Compat::Numeric, Numeric]`, which allows any `Numeric` (the new type), as well as all values previously accepted by `validate_numeric` (through `Stdlib::Compat::Numeric`). +Here, the type of `$value` is defined as `Variant[Stdlib::Compat::Numeric, Numeric]`, which allows any `Numeric` (the new type), as well as all values previously accepted by `validate_numeric` (through `Stdlib::Compat::Numeric`). The call to `validate_legacy` takes care of triggering the correct log or fail message for you. It requires the new type, the previous validation function name, and all arguments to that function. diff --git a/spec/aliases/absolutepath_spec.rb b/spec/aliases/absolutepath_spec.rb new file mode 100644 index 0000000..aa435d7 --- /dev/null +++ b/spec/aliases/absolutepath_spec.rb @@ -0,0 +1,49 @@ +require 'spec_helper' + +if Puppet.version.to_f >= 4.5 + describe 'test::absolutepath', type: :class do + describe 'valid handling' do + %w{ + /usr2/username/bin:/usr/local/bin:/usr/bin:. + C:/ + C:\\ + C:\\WINDOWS\\System32 + C:/windows/system32 + X:/foo/bar + X:\\foo\\bar + \\\\host\\windows + //host/windows + /var/tmp + /var/opt/../lib/puppet + }.each do |value| + describe value.inspect do + let(:params) {{ value: value }} + it { is_expected.to compile } + end + end + end + + describe 'invalid path handling' do + context 'garbage inputs' do + [ + nil, + [ nil ], + [ nil, nil ], + { 'foo' => 'bar' }, + { }, + '', + "*/Users//nope", + "\\Users/hc/wksp/stdlib", + "C:noslashes", + "\\var\\tmp" + ].each do |value| + describe value.inspect do + let(:params) {{ value: value }} + it { is_expected.to compile.and_raise_error(/parameter 'value' expects a match for Variant/) } + end + end + end + + end + end +end diff --git a/spec/aliases/httpsurl_spec.rb b/spec/aliases/httpsurl_spec.rb new file mode 100644 index 0000000..97ae006 --- /dev/null +++ b/spec/aliases/httpsurl_spec.rb @@ -0,0 +1,40 @@ +require 'spec_helper' + +if Puppet.version.to_f >= 4.5 + describe 'test::httpsurl', type: :class do + describe 'valid handling' do + %w{ + https://hello.com + https://notcreative.org + https://notexciting.co.uk + }.each do |value| + describe value.inspect do + let(:params) {{ value: value }} + it { is_expected.to compile } + end + end + end + + describe 'invalid path handling' do + context 'garbage inputs' do + [ + nil, + [ nil ], + [ nil, nil ], + { 'foo' => 'bar' }, + { }, + '', + "httds://notquiteright.org", + "hptts:/nah", + "https;//notrightbutclose.org" + ].each do |value| + describe value.inspect do + let(:params) {{ value: value }} + it { is_expected.to compile.and_raise_error(/parameter 'value' expects a match for Stdlib::HTTPSUrl/) } + end + end + end + + end + end +end diff --git a/spec/aliases/httpurl_spec.rb b/spec/aliases/httpurl_spec.rb new file mode 100644 index 0000000..8bd57ca --- /dev/null +++ b/spec/aliases/httpurl_spec.rb @@ -0,0 +1,43 @@ +require 'spec_helper' + +if Puppet.version.to_f >= 4.5 + describe 'test::httpurl', type: :class do + describe 'valid handling' do + %w{ + https://hello.com + https://notcreative.org + https://canstillaccepthttps.co.uk + http://anhttp.com + http://runningoutofideas.gov + http:// + }.each do |value| + describe value.inspect do + let(:params) {{ value: value }} + it { is_expected.to compile } + end + end + end + + describe 'invalid path handling' do + context 'garbage inputs' do + [ + nil, + [ nil ], + [ nil, nil ], + { 'foo' => 'bar' }, + { }, + '', + "httds://notquiteright.org", + "hptts:/nah", + "https;//notrightbutclose.org" + ].each do |value| + describe value.inspect do + let(:params) {{ value: value }} + it { is_expected.to compile.and_raise_error(/parameter 'value' expects a match for Stdlib::HTTPUrl/) } + end + end + end + + end + end +end diff --git a/spec/aliases/unixpath_spec.rb b/spec/aliases/unixpath_spec.rb new file mode 100644 index 0000000..aee161d --- /dev/null +++ b/spec/aliases/unixpath_spec.rb @@ -0,0 +1,41 @@ +require 'spec_helper' + +if Puppet.version.to_f >= 4.5 + describe 'test::unixpath', type: :class do + describe 'valid handling' do + %w{ + /usr2/username/bin:/usr/local/bin:/usr/bin:. + /var/tmp + /Users/helencampbell/workspace/puppetlabs-stdlib + }.each do |value| + describe value.inspect do + let(:params) {{ value: value }} + it { is_expected.to compile } + end + end + end + + describe 'invalid path handling' do + context 'garbage inputs' do + [ + nil, + [ nil ], + [ nil, nil ], + { 'foo' => 'bar' }, + { }, + '', + "C:/whatever", + "\\var\\tmp", + "\\Users/hc/wksp/stdlib", + "*/Users//nope" + ].each do |value| + describe value.inspect do + let(:params) {{ value: value }} + it { is_expected.to compile.and_raise_error(/parameter 'value' expects a match for Stdlib::Unixpath/) } + end + end + end + + end + end +end diff --git a/spec/aliases/windowspath_spec.rb b/spec/aliases/windowspath_spec.rb new file mode 100644 index 0000000..c13794e --- /dev/null +++ b/spec/aliases/windowspath_spec.rb @@ -0,0 +1,44 @@ +require 'spec_helper' + +if Puppet.version.to_f >= 4.5 + describe 'test::windowspath', type: :class do + describe 'valid handling' do + %w{ + C:\\ + C:\\WINDOWS\\System32 + C:/windows/system32 + X:/foo/bar + X:\\foo\\bar + \\\\host\\windows + }.each do |value| + describe value.inspect do + let(:params) {{ value: value }} + it { is_expected.to compile } + end + end + end + + describe 'invalid path handling' do + context 'garbage inputs' do + [ + nil, + [ nil ], + [ nil, nil ], + { 'foo' => 'bar' }, + { }, + '', + "httds://notquiteright.org", + "/usr2/username/bin:/usr/local/bin:/usr/bin:.", + "C;//notright/here", + "C:noslashes" + ].each do |value| + describe value.inspect do + let(:params) {{ value: value }} + it { is_expected.to compile.and_raise_error(/parameter 'value' expects a match for Stdlib::Windowspath/) } + end + end + end + + end + end +end diff --git a/spec/fixtures/test/manifests/absolutepath.pp b/spec/fixtures/test/manifests/absolutepath.pp new file mode 100644 index 0000000..8321471 --- /dev/null +++ b/spec/fixtures/test/manifests/absolutepath.pp @@ -0,0 +1,6 @@ +# Class to test the Stdlib::Absolutepath type. Not to be confused with Stdlib::Compat::Absolute_path. +class test::absolutepath( + Stdlib::Absolutepath $value, + ) { + notice("Success") +} diff --git a/spec/fixtures/test/manifests/httpsurl.pp b/spec/fixtures/test/manifests/httpsurl.pp new file mode 100644 index 0000000..9d6b92d --- /dev/null +++ b/spec/fixtures/test/manifests/httpsurl.pp @@ -0,0 +1,6 @@ +# Class to test the Stdlib::HTTPSUrl type alias +class test::httpsurl( + Stdlib::HTTPSUrl $value, + ) { + notice("Success") +} diff --git a/spec/fixtures/test/manifests/httpurl.pp b/spec/fixtures/test/manifests/httpurl.pp new file mode 100644 index 0000000..abf869e --- /dev/null +++ b/spec/fixtures/test/manifests/httpurl.pp @@ -0,0 +1,6 @@ +# Class to test the Stdlib::HTTPUrl type alias +class test::httpurl( + Stdlib::HTTPUrl $value, + ) { + notice("Success") +} diff --git a/spec/fixtures/test/manifests/unixpath.pp b/spec/fixtures/test/manifests/unixpath.pp new file mode 100644 index 0000000..9311109 --- /dev/null +++ b/spec/fixtures/test/manifests/unixpath.pp @@ -0,0 +1,6 @@ +# Class to test the Stdlib::Unixpath type alias +class test::unixpath( + Stdlib::Unixpath $value, + ) { + notice("Success") +} diff --git a/spec/fixtures/test/manifests/windowspath.pp b/spec/fixtures/test/manifests/windowspath.pp new file mode 100644 index 0000000..af93ed3 --- /dev/null +++ b/spec/fixtures/test/manifests/windowspath.pp @@ -0,0 +1,6 @@ +# Class to test the Stdlib::Windowspath type alias +class test::windowspath( + Stdlib::Windowspath $value, + ) { + notice("Success") +} diff --git a/types/absolutepath.pp b/types/absolutepath.pp new file mode 100644 index 0000000..70ec916 --- /dev/null +++ b/types/absolutepath.pp @@ -0,0 +1,2 @@ +# A strict absolutepath type +type Stdlib::Absolutepath = Variant[Stdlib::Windowspath, Stdlib::Unixpath] diff --git a/types/httpsurl.pp b/types/httpsurl.pp new file mode 100644 index 0000000..36fd30f --- /dev/null +++ b/types/httpsurl.pp @@ -0,0 +1 @@ +type Stdlib::HTTPSUrl = Pattern[/^https:\/\//] diff --git a/types/httpurl.pp b/types/httpurl.pp new file mode 100644 index 0000000..0d93a95 --- /dev/null +++ b/types/httpurl.pp @@ -0,0 +1 @@ +type Stdlib::HTTPUrl = Pattern[/^https?:\/\//] diff --git a/types/unixpath.pp b/types/unixpath.pp new file mode 100644 index 0000000..76f2c17 --- /dev/null +++ b/types/unixpath.pp @@ -0,0 +1,2 @@ +# this regex rejects any path component that is a / or a NUL +type Stdlib::Unixpath = Pattern[/^\/([^\/\0]+(\/)?)+$/] diff --git a/types/windowspath.pp b/types/windowspath.pp new file mode 100644 index 0000000..bc1ee9c --- /dev/null +++ b/types/windowspath.pp @@ -0,0 +1 @@ +type Stdlib::Windowspath = Pattern[/^(([a-zA-Z]:[\\\/])|([\\\/][\\\/][^\\\/]+[\\\/][^\\\/]+)|([\\\/][\\\/]\?[\\\/][^\\\/]+))/] -- cgit v1.2.3 From f6bd01b784d279d477f327e5da76f3c27fcf4156 Mon Sep 17 00:00:00 2001 From: Maksym Melnychok Date: Thu, 6 Oct 2016 16:36:29 +0200 Subject: Ignore :undefined_variable "reason" in getvar `catch` returns value of second argument to `throw`, which until 860a2761f334c964068038b3ef6853f08beb1df5 was `nil`, but now is non-falsey reason for error. short-circuit using return and eval to nil if `throw` was caught. --- lib/puppet/parser/functions/getvar.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/puppet/parser/functions/getvar.rb b/lib/puppet/parser/functions/getvar.rb index ae9c869..aa6edbb 100644 --- a/lib/puppet/parser/functions/getvar.rb +++ b/lib/puppet/parser/functions/getvar.rb @@ -21,8 +21,10 @@ module Puppet::Parser::Functions begin catch(:undefined_variable) do - self.lookupvar("#{args[0]}") + return self.lookupvar("#{args[0]}") end + + nil # throw was caught rescue Puppet::ParseError # Eat the exception if strict_variables = true is set end -- cgit v1.2.3 From 9debb12b2d6190045a11d2277c7b730ac5732f96 Mon Sep 17 00:00:00 2001 From: Nate Potter Date: Tue, 28 Jun 2016 20:30:41 -0700 Subject: (MODULES-3407) Clarify that 'after' in file_line accepts regex. This patch updates the README to specify that the 'after' parameter in the file_line class accepts a regular expression. --- README.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.markdown b/README.markdown index d445cc5..838a065 100644 --- a/README.markdown +++ b/README.markdown @@ -124,7 +124,7 @@ error will be raised unless the `multiple => true` parameter is set. All parameters are optional, unless otherwise noted. -* `after`: Specifies the line after which Puppet adds any new lines. (Existing lines are added in place.) Valid options: String. Default: Undefined. +* `after`: Specifies the line after which Puppet adds any new lines using a regular expression. (Existing lines are added in place.) Valid options: String containing a regex. Default: Undefined. * `ensure`: Ensures whether the resource is present. Valid options: 'present', 'absent'. Default: 'present'. * `line`: **Required.** Sets the line to be added to the file located by the `path` parameter. Valid options: String. Default: Undefined. * `match`: Specifies a regular expression to run against existing lines in the file; if a match is found, it is replaced rather than adding a new line. A regex comparison is performed against the line value, and if it does not match, an exception is raised. Valid options: String containing a regex. Default: Undefined. -- cgit v1.2.3 From e44238a9c7da7ad4a872ba86cd103becadd51b3b Mon Sep 17 00:00:00 2001 From: David Schmitt Date: Sat, 8 Oct 2016 18:10:53 +0100 Subject: Revert "Addition of logging with file and line numbers" This reverts commit b63862ff43194194f7428739a32cfe13bad1e7ed, as it would only show the irrelevant first entry of the ruby stack trace. The puppetserver log does contain the full trace information, or you can use --strict=error to cause a hard failure when hitting a deprecation. # Conflicts: # lib/puppet/functions/validate_legacy.rb --- lib/puppet/functions/deprecation.rb | 8 +++----- lib/puppet/functions/validate_legacy.rb | 3 +-- lib/puppet/parser/functions/deprecation.rb | 4 +--- 3 files changed, 5 insertions(+), 10 deletions(-) diff --git a/lib/puppet/functions/deprecation.rb b/lib/puppet/functions/deprecation.rb index 30aeb1d..6b7b977 100644 --- a/lib/puppet/functions/deprecation.rb +++ b/lib/puppet/functions/deprecation.rb @@ -1,4 +1,5 @@ # Function to print deprecation warnings, Logs a warning once for a given key. The uniqueness key - can appear once. The msg is the message text including any positional information that is formatted by the user/caller of the method It is affected by the puppet setting 'strict', which can be set to :error (outputs as an error message), :off (no message / error is displayed) and :warning (default, outputs a warning) *Type*: String, String. +# Puppet::Functions.create_function(:deprecation) do dispatch :deprecation do @@ -8,16 +9,13 @@ Puppet::Functions.create_function(:deprecation) do def deprecation(key, message) # depending on configuration setting of strict - caller_infos = caller.first.split(":") case Puppet.settings[:strict] when :off # do nothing when :error - err_message = "#{message} : #{caller_infos[0]} : #{caller_infos[1]}" - fail("deprecation. #{key}. #{err_message}") + fail("deprecation. #{key}. #{message}") else - err_message = "#{message} : #{caller_infos[0]} : #{caller_infos[1]}" - Puppet.deprecation_warning(err_message, key) + Puppet.deprecation_warning(message, key) end end end diff --git a/lib/puppet/functions/validate_legacy.rb b/lib/puppet/functions/validate_legacy.rb index 0ba6dd8..3f50459 100644 --- a/lib/puppet/functions/validate_legacy.rb +++ b/lib/puppet/functions/validate_legacy.rb @@ -30,9 +30,8 @@ Puppet::Functions.create_function(:validate_legacy, Puppet::Functions::InternalF Puppet.notice("Accepting previously invalid value for target type '#{target_type}'") end else - caller_infos = caller.first.split(":") inferred_type = Puppet::Pops::Types::TypeCalculator.infer_set(value) - error_msg = Puppet::Pops::Types::TypeMismatchDescriber.new.describe_mismatch("validate_legacy(#{function_name}) [#{caller_infos[0]}:#{caller_infos[1]}]", target_type, inferred_type) + error_msg = Puppet::Pops::Types::TypeMismatchDescriber.new.describe_mismatch("validate_legacy(#{function_name})", target_type, inferred_type) if previous_validation(scope, function_name, value, *prev_args) call_function('deprecation', 'validate_legacy', error_msg) else diff --git a/lib/puppet/parser/functions/deprecation.rb b/lib/puppet/parser/functions/deprecation.rb index 0cb247d..e30f3a0 100644 --- a/lib/puppet/parser/functions/deprecation.rb +++ b/lib/puppet/parser/functions/deprecation.rb @@ -11,9 +11,7 @@ EOS message = arguments[1] if ENV['STDLIB_LOG_DEPRECATIONS'] == "true" - caller_infos = caller.first.split(":") - err_message = "#{message} : #{caller_infos[0]} : #{caller_infos[1]}" - warning("deprecation. #{key}. #{err_message}") + warning("deprecation. #{key}. #{message}") end end end -- cgit v1.2.3 From bec521e6b79dd612a73e742d1cb6371e17ade1a9 Mon Sep 17 00:00:00 2001 From: David Schmitt Date: Sat, 8 Oct 2016 18:28:22 +0100 Subject: Update deprecation() so warnings can be disabled for CI --- README.markdown | 15 ++++++++++++++- lib/puppet/functions/deprecation.rb | 4 +++- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/README.markdown b/README.markdown index 838a065..c90c9c3 100644 --- a/README.markdown +++ b/README.markdown @@ -344,7 +344,20 @@ Deletes all instances of the undef value from an array or hash. For example, `$h #### `deprecation` -Prints deprecation warnings and logs a warning once for a given key. The uniqueness key - can appear once. The msg is the message text, including any positional information that is formatted by the user or caller of the method. The Puppet setting 'strict' affects this function. Set 'strict' to :error to output an error message, :off to output no message or error, or :warning (default) to output a warning. In Puppet versions lower than 4.0, you can set an environment variable to decide whether or not to log deprecation warnings (`ENV[STDLIB_LOG_DEPRECATION]`). If this environment variable is set to true, the functions log a warning. *Type*: String, String. +Prints deprecation warnings and logs a warning once for a given key: + +``` +deprecation(key, message) +``` + +* key: to keep the number of messages low, during the lifetime of a puppet process, only one message per key is logged. +* message: the text to be logged. + +The Puppet settings '[disable_warnings](https://docs.puppet.com/puppet/latest/reference/configuration.html#disablewarnings)', '[max_deprecations](https://docs.puppet.com/puppet/latest/reference/configuration.html#maxdeprecations)', and '[strict](https://docs.puppet.com/puppet/latest/reference/configuration.html#strict)' affect this function. Set 'strict' to `error` to fail immediately with the deprecation message, `off` to output emit no messages at all, or `warning` (default) to log all warnings. + +Additionally you can set the environment variable `STDLIB_LOG_DEPRECATION` to decide whether or not to log deprecation warnings: if this environment variable is set to `true`, the functions log a warning, if it is set to `false`, no warnings are logged. If no value is set at all, Puppet 4 will emit warnings, while Puppet 3 will not. Using this setting is especially useful for automated tests to avoid flooding your logs before you are ready to migrate. + +*Type*: String, String. #### `difference` diff --git a/lib/puppet/functions/deprecation.rb b/lib/puppet/functions/deprecation.rb index 6b7b977..a860aa2 100644 --- a/lib/puppet/functions/deprecation.rb +++ b/lib/puppet/functions/deprecation.rb @@ -15,7 +15,9 @@ Puppet::Functions.create_function(:deprecation) do when :error fail("deprecation. #{key}. #{message}") else - Puppet.deprecation_warning(message, key) + unless ENV['STDLIB_LOG_DEPRECATIONS'] == 'false' + Puppet.deprecation_warning(message, key) + end end end end -- cgit v1.2.3 From 729e076f1d5eee87c22fee1253dd6cac039f8509 Mon Sep 17 00:00:00 2001 From: David Schmitt Date: Sat, 8 Oct 2016 20:06:32 +0100 Subject: Add testcase for #665 @keymone added information on how to reproduce his issue, so here's the test case that would fail without his change. --- spec/functions/getvar_spec.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/spec/functions/getvar_spec.rb b/spec/functions/getvar_spec.rb index 6ab137e..54f1842 100755 --- a/spec/functions/getvar_spec.rb +++ b/spec/functions/getvar_spec.rb @@ -6,6 +6,8 @@ describe 'getvar' do it { is_expected.to run.with_params('one', 'two').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('$::foo').and_return(nil) } + context 'given variables in namespaces' do let(:pre_condition) { <<-'ENDofPUPPETcode' -- cgit v1.2.3 From c2dd2898f2d965614d9fa0ccc5ade57df910f800 Mon Sep 17 00:00:00 2001 From: David Schmitt Date: Mon, 10 Oct 2016 10:42:05 +0100 Subject: Release prep for 4.13.0 * Changelog & Thanks * Add known issues/version compatiblity to README * Whitespace fixes * Update version and dependency information * Fix issue tracker URL --- CHANGELOG.md | 47 +++++++++++++++++++++++++++++++++++++++++++++++ README.markdown | 31 ++++++++++++++++++------------- metadata.json | 8 ++------ 3 files changed, 67 insertions(+), 19 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2bc584b..8696b02 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,50 @@ +## Supported Release 4.13.0 +### Summary + +This version of stdlib deprecates a whole host of functions, and provides stepping stones to move to Puppet 4 type validations. Be sure to check out the new `deprecation()` and `validate_legacy()` functions to migrate off the deprecated v3-style data validations. + +Many thanks to all community contributors: bob, Dmitry Ilyin, Dominic Cleal, Joris, Joseph Yaworski, Loic Antoine-Gombeaud, Maksym Melnychok, Michiel Brandenburg, Nate Potter, Romain Tartière, Stephen Benjamin, and Steve Moore, as well as anyone contributing in the code review process and by submitting issues. + +Special thanks to [Voxpupuli's](https://voxpupuli.org/) Igor Galić for donating the puppet-tea types to kickstart this part of stdlib. + + +#### Deprecations +* `validate_absolute_path`, `validate_array`, `validate_bool`, `validate_hash`, `validate_integer`, `validate_ip_address`, `validate_ipv4_address`, `validate_ipv6_address`, `validate_numeric`, `validate_re`, `validate_slength`, `validate_string`, and their `is_` counter parts are now deprecated on Puppet 4. See the `validate_legacy()` description in the README for help on migrating away from those functions. +* The `dig` function is provided by core puppet since 4.5.0 with slightly different calling convention. The stdlib version can still be accessed as `dig44` for now. + + +#### Features +* Add Puppet 4 data types for Unix, and Windows paths, and URLs. +* Add `deprecation` function to warn users of functionality that will be removed soon. +* Add `validate_legacy` function to help with migrating to Puppet 4 data types. + +* Add `any2bool` function, a combination of of `string2bool` and `num2bool`. +* Add `delete_regex` function to delete array elements matching a regular expression. +* Add `puppet_environmentpath` fact to expose the `environmentpath` setting. +* Add `regexpescape` function to safely insert arbitrary strings into regular expressions. +* Add `shell_escape`, `shell_join`, and `shell_split` functions for safer working with shell scripts.. + +* The `delete` function now also accepts regular expressions as search term. +* The `loadyaml` function now accepts a default value, which is returned when there is an error loading the file. + +#### Bugfixes +* Fix `file_line.match_for_absence` implementation and description to actually work. (MODULES-3590) +* Fix `getparam` so that it can now also return `false`. (MODULES-3933) +* Fix the fixture setup for testing and adjust `load_module_metadata` and `loadjson` tests. +* Fix `defined_with_params` to handle `undef` correctly on all puppet versions. (PUP-6422, MODULES-3543) +* Fix `file_line.path` validation to use puppet's built in `absolute_path?` matcher. + +#### Minor Improvements +* README changes: improved descriptions of `deep_merge`, `delete`, `ensure_packages`, `file_line.after`, `range`, and `validate_numeric`. +* The `getvar` function now returns nil in all situations where the variable is not found. +* Update the `dig44` function with better `undef`, `nil`, and `false` handling. +* Better wording on `str2bool` argument validation error message. + + +### Known issues +* The `validate_legacy` function relies on internal APIs from Puppet 4.4.0 (PE 2016.1) onwards, and doesn't work on earlier versions. +* Puppet 4.5.0 (PE 2016.2) has a number of improvements around data types - especially error handling - that make working with them much nicer. + ## Supported Release 4.12.0 ###Summary diff --git a/README.markdown b/README.markdown index c90c9c3..c0b3155 100644 --- a/README.markdown +++ b/README.markdown @@ -1,6 +1,6 @@ -#stdlib +# stdlib -####Table of Contents +#### Table of Contents 1. [Overview](#overview) 2. [Module Description - What the module does and why it is useful](#module-description) @@ -10,11 +10,11 @@ 5. [Limitations - OS compatibility, etc.](#limitations) 6. [Development - Guide for contributing to the module](#development) -##Overview +## Overview Adds a standard library of resources for Puppet modules. -##Module Description +## Module Description This module provides a standard library of resources for the development of Puppet modules. Puppet modules make heavy use of this standard library. The stdlib module adds the following resources to Puppet: @@ -27,11 +27,11 @@ This module provides a standard library of resources for the development of Pupp > *Note:* As of version 3.7, Puppet Enterprise no longer includes the stdlib module. If you're running Puppet Enterprise, you should install the most recent release of stdlib for compatibility with Puppet modules. -##Setup +## Setup Installing the stdlib module adds the functions, facts, and resources of this standard library to Puppet. -##Usage +## Usage After you've installed stdlib, all of its functions, facts, and resources are available for module use or development. @@ -136,20 +136,23 @@ All parameters are optional, unless otherwise noted. ### Data Types -#### `absolutepath` +#### `Stdlib::Absolutepath` A strict absolute path type. Uses a Variant of Unixpath and Windowspath types. -Acceptable input examples: /usr2/username/bin:/usr/local/bin:/usr/bin:. +Acceptable input examples: /var/log + /usr2/username/bin:/usr/local/bin:/usr/bin:. C:\\WINDOWS\\System32 +Unacceptable input example: ../relative_path -#### `httpsurl` +#### `Stdlib::Httpsurl` Matches https URLs. + Acceptable input example: https://hello.com Unacceptable input example: httds://notquiteright.org -#### `httpurl` +#### `Stdlib::Httpurl` Matches both https and http URLs. @@ -157,7 +160,7 @@ Acceptable input example: https://hello.com http://hello.com Unacceptable input example: httds://notquiteright.org -#### `unixpath` +#### `Stdlib::Unixpath` Matches paths on Unix type Operating Systems. @@ -165,7 +168,7 @@ Acceptable input example: /usr2/username/bin:/usr/local/bin:/usr/bin:. /var/tmp Unacceptable input example: C:/whatever -#### `windowspath` +#### `Stdlib::Windowspath` Matches paths on Windows Operating systems. @@ -1439,6 +1442,8 @@ validate_legacy("Optional[String]", "validate_re", "Value to be validated", ["." This function supports updating modules from Puppet 3 style argument validation (using the stdlib `validate_*` functions) to Puppet 4 data types, without breaking functionality for those depending on Puppet 3 style validation. +> Note: This function relies on internal APIs from Puppet 4.4.0 (PE 2016.1) onwards, and doesn't work on earlier versions. + ##### For module users If you are running Puppet 4 and receiving deprecation warnings about `validate_*` functions, the `validate_legacy` function can help you find and resolve the deprecated code. @@ -1656,7 +1661,7 @@ Versions | Puppet 2.6 | Puppet 2.7 | Puppet 3.x | Puppet 4.x | Puppet Labs modules on the Puppet Forge are open projects, and community contributions are essential for keeping them great. We can’t access the huge number of platforms and myriad hardware, software, and deployment configurations that Puppet is intended to serve. We want to keep it as easy as possible to contribute changes so that our modules work in your environment. There are a few guidelines that we need contributors to follow so that we can have a chance of keeping on top of things. For more information, see our [module contribution guide](https://docs.puppetlabs.com/forge/contributing.html). To report or research a bug with any part of this module, please go to -[http://tickets.puppetlabs.com/browse/PUP](http://tickets.puppetlabs.com/browse/PUP). +[http://tickets.puppetlabs.com/browse/MODULES](http://tickets.puppetlabs.com/browse/MODULES). ## Contributors diff --git a/metadata.json b/metadata.json index 514023e..07672c3 100644 --- a/metadata.json +++ b/metadata.json @@ -1,6 +1,6 @@ { "name": "puppetlabs-stdlib", - "version": "4.12.0", + "version": "4.13.0", "author": "puppetlabs", "summary": "Standard library of resources for Puppet modules.", "license": "Apache-2.0", @@ -99,10 +99,6 @@ } ], "requirements": [ - { - "name": "pe", - "version_requirement": ">= 3.0.0 < 2015.4.0" - }, { "name": "puppet", "version_requirement": ">=2.7.20 <5.0.0" @@ -110,6 +106,6 @@ ], "description": "Standard Library for Puppet Modules", "dependencies": [ - + ] } -- cgit v1.2.3 From b112b837d5a93764cc970f7ecce3796846c02f1a Mon Sep 17 00:00:00 2001 From: David Schmitt Date: Mon, 10 Oct 2016 17:58:21 +0100 Subject: Apply workaround to hanging facter tests Apparently mocha 1.2.0 causes an endless hang on spec/unit/facter/root_home_spec.rb. Forcing an earlier version avoids this for now. --- Gemfile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Gemfile b/Gemfile index ecf3d06..0a7542d 100644 --- a/Gemfile +++ b/Gemfile @@ -22,6 +22,8 @@ group :development, :unit_tests do gem 'puppet-blacksmith', '>= 3.4.0' gem 'puppetlabs_spec_helper', '>= 1.2.1' gem 'rspec-puppet', '>= 2.3.2', :git => 'https://github.com/rodjek/rspec-puppet.git', :branch => 'fb27c533e2664057fba4b73d0bd902a946abfce0' + # the newly released mocha 1.2.0 causes hangs during spec testing. See MODULES-3958 for a long-term solution + gem 'mocha', '< 1.2.0' gem 'rspec-puppet-facts' gem 'simplecov' gem 'parallel_tests' -- cgit v1.2.3 From b92fad2b7667df836f8ca4eb92d8c8be84bd0538 Mon Sep 17 00:00:00 2001 From: David Schmitt Date: Wed, 12 Oct 2016 10:04:54 +0100 Subject: (MODULES-3961) emit more deprecation warnings This now emits one deprecation warning for each function used (but not for each call-site). Prior to this, only a single deprecation warning would have been triggered, potentially misleading users. Additionally this adds v4 deprecation stubs for the functions that were missed. --- CHANGELOG.md | 7 +++++++ lib/puppet/functions/is_absolute_path.rb | 10 ++++++++++ lib/puppet/functions/is_array.rb | 10 ++++++++++ lib/puppet/functions/is_bool.rb | 10 ++++++++++ lib/puppet/functions/is_float.rb | 10 ++++++++++ lib/puppet/functions/is_ip_address.rb | 10 ++++++++++ lib/puppet/functions/is_ipv4_address.rb | 10 ++++++++++ lib/puppet/functions/is_ipv6_address.rb | 10 ++++++++++ lib/puppet/functions/is_numeric.rb | 10 ++++++++++ lib/puppet/functions/is_string.rb | 10 ++++++++++ lib/puppet/functions/validate_absolute_path.rb | 2 +- lib/puppet/functions/validate_array.rb | 2 +- lib/puppet/functions/validate_bool.rb | 2 +- lib/puppet/functions/validate_hash.rb | 2 +- lib/puppet/functions/validate_integer.rb | 2 +- lib/puppet/functions/validate_ip_address.rb | 2 +- lib/puppet/functions/validate_ipv4_address.rb | 2 +- lib/puppet/functions/validate_ipv6_address.rb | 2 +- lib/puppet/functions/validate_numeric.rb | 2 +- lib/puppet/functions/validate_re.rb | 2 +- lib/puppet/functions/validate_slength.rb | 2 +- lib/puppet/functions/validate_string.rb | 2 +- lib/puppet/parser/functions/is_absolute_path.rb | 2 +- lib/puppet/parser/functions/is_array.rb | 2 +- lib/puppet/parser/functions/is_bool.rb | 2 +- lib/puppet/parser/functions/is_float.rb | 2 +- lib/puppet/parser/functions/is_ip_address.rb | 2 +- lib/puppet/parser/functions/is_ipv4_address.rb | 2 +- lib/puppet/parser/functions/is_ipv6_address.rb | 2 +- lib/puppet/parser/functions/is_numeric.rb | 2 +- lib/puppet/parser/functions/is_string.rb | 5 +++-- lib/puppet/parser/functions/validate_absolute_path.rb | 2 +- lib/puppet/parser/functions/validate_array.rb | 2 +- lib/puppet/parser/functions/validate_bool.rb | 2 +- lib/puppet/parser/functions/validate_hash.rb | 2 +- lib/puppet/parser/functions/validate_integer.rb | 4 ++-- lib/puppet/parser/functions/validate_ip_address.rb | 6 +++--- lib/puppet/parser/functions/validate_ipv4_address.rb | 2 +- lib/puppet/parser/functions/validate_ipv6_address.rb | 2 +- lib/puppet/parser/functions/validate_numeric.rb | 4 ++-- lib/puppet/parser/functions/validate_re.rb | 2 +- lib/puppet/parser/functions/validate_slength.rb | 2 +- lib/puppet/parser/functions/validate_string.rb | 9 +++++---- metadata.json | 2 +- 44 files changed, 141 insertions(+), 42 deletions(-) create mode 100644 lib/puppet/functions/is_absolute_path.rb create mode 100644 lib/puppet/functions/is_array.rb create mode 100644 lib/puppet/functions/is_bool.rb create mode 100644 lib/puppet/functions/is_float.rb create mode 100644 lib/puppet/functions/is_ip_address.rb create mode 100644 lib/puppet/functions/is_ipv4_address.rb create mode 100644 lib/puppet/functions/is_ipv6_address.rb create mode 100644 lib/puppet/functions/is_numeric.rb create mode 100644 lib/puppet/functions/is_string.rb diff --git a/CHANGELOG.md b/CHANGELOG.md index 8696b02..01b0a94 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## Supported Release 4.13.1 +### Summary + +This bugfix release improves the user experience around function deprecations by emitting one warning per function(-name) instead of only one deprecation overall. This allows users to identify all deprecated functions used in one agent run, with less back-and-forth. + +This release also adds additional Puppet 4 overrides for the `is_` counterparts of the deprecated functions to emit the deprecations warnings in all cases. + ## Supported Release 4.13.0 ### Summary diff --git a/lib/puppet/functions/is_absolute_path.rb b/lib/puppet/functions/is_absolute_path.rb new file mode 100644 index 0000000..0a100f8 --- /dev/null +++ b/lib/puppet/functions/is_absolute_path.rb @@ -0,0 +1,10 @@ +Puppet::Functions.create_function(:is_absolute_path, Puppet::Functions::InternalFunction) do + dispatch :deprecation_gen do + scope_param + optional_repeated_param 'Any', :args + end + def deprecation_gen(scope, *args) + call_function('deprecation', 'is_absolute_path', "This method is deprecated, please use match expressions with Stdlib::Compat::Absolute_Path instead. They are described at https://docs.puppet.com/puppet/latest/reference/lang_data_type.html#match-expressions.") + scope.send("function_is_absolute_path", args) + end +end diff --git a/lib/puppet/functions/is_array.rb b/lib/puppet/functions/is_array.rb new file mode 100644 index 0000000..0542a63 --- /dev/null +++ b/lib/puppet/functions/is_array.rb @@ -0,0 +1,10 @@ +Puppet::Functions.create_function(:is_array, Puppet::Functions::InternalFunction) do + dispatch :deprecation_gen do + scope_param + optional_repeated_param 'Any', :args + end + def deprecation_gen(scope, *args) + call_function('deprecation', 'is_array', "This method is deprecated, please use match expressions with Stdlib::Compat::Array instead. They are described at https://docs.puppet.com/puppet/latest/reference/lang_data_type.html#match-expressions.") + scope.send("function_is_array", args) + end +end diff --git a/lib/puppet/functions/is_bool.rb b/lib/puppet/functions/is_bool.rb new file mode 100644 index 0000000..ff1d462 --- /dev/null +++ b/lib/puppet/functions/is_bool.rb @@ -0,0 +1,10 @@ +Puppet::Functions.create_function(:is_bool, Puppet::Functions::InternalFunction) do + dispatch :deprecation_gen do + scope_param + optional_repeated_param 'Any', :args + end + def deprecation_gen(scope, *args) + call_function('deprecation', 'is_bool', "This method is deprecated, please use match expressions with Stdlib::Compat::Bool instead. They are described at https://docs.puppet.com/puppet/latest/reference/lang_data_type.html#match-expressions.") + scope.send("function_is_bool", args) + end +end diff --git a/lib/puppet/functions/is_float.rb b/lib/puppet/functions/is_float.rb new file mode 100644 index 0000000..b3763f2 --- /dev/null +++ b/lib/puppet/functions/is_float.rb @@ -0,0 +1,10 @@ +Puppet::Functions.create_function(:is_float, Puppet::Functions::InternalFunction) do + dispatch :deprecation_gen do + scope_param + optional_repeated_param 'Any', :args + end + def deprecation_gen(scope, *args) + call_function('deprecation', 'is_float', "This method is deprecated, please use match expressions with Stdlib::Compat::Float instead. They are described at https://docs.puppet.com/puppet/latest/reference/lang_data_type.html#match-expressions.") + scope.send("function_is_float", args) + end +end diff --git a/lib/puppet/functions/is_ip_address.rb b/lib/puppet/functions/is_ip_address.rb new file mode 100644 index 0000000..e584714 --- /dev/null +++ b/lib/puppet/functions/is_ip_address.rb @@ -0,0 +1,10 @@ +Puppet::Functions.create_function(:is_ip_address, Puppet::Functions::InternalFunction) do + dispatch :deprecation_gen do + scope_param + optional_repeated_param 'Any', :args + end + def deprecation_gen(scope, *args) + call_function('deprecation', 'is_ip_address', "This method is deprecated, please use match expressions with Stdlib::Compat::Ip_address instead. They are described at https://docs.puppet.com/puppet/latest/reference/lang_data_type.html#match-expressions.") + scope.send("function_is_ip_address", args) + end +end diff --git a/lib/puppet/functions/is_ipv4_address.rb b/lib/puppet/functions/is_ipv4_address.rb new file mode 100644 index 0000000..76c75e5 --- /dev/null +++ b/lib/puppet/functions/is_ipv4_address.rb @@ -0,0 +1,10 @@ +Puppet::Functions.create_function(:is_ipv4_address, Puppet::Functions::InternalFunction) do + dispatch :deprecation_gen do + scope_param + optional_repeated_param 'Any', :args + end + def deprecation_gen(scope, *args) + call_function('deprecation', 'is_ipv4_address', "This method is deprecated, please use match expressions with Stdlib::Compat::Ipv4 instead. They are described at https://docs.puppet.com/puppet/latest/reference/lang_data_type.html#match-expressions.") + scope.send("function_is_ipv4_address", args) + end +end diff --git a/lib/puppet/functions/is_ipv6_address.rb b/lib/puppet/functions/is_ipv6_address.rb new file mode 100644 index 0000000..dbf5282 --- /dev/null +++ b/lib/puppet/functions/is_ipv6_address.rb @@ -0,0 +1,10 @@ +Puppet::Functions.create_function(:is_ipv6_address, Puppet::Functions::InternalFunction) do + dispatch :deprecation_gen do + scope_param + optional_repeated_param 'Any', :args + end + def deprecation_gen(scope, *args) + call_function('deprecation', 'is_ipv4_address', "This method is deprecated, please use match expressions with Stdlib::Compat::Ipv6 instead. They are described at https://docs.puppet.com/puppet/latest/reference/lang_data_type.html#match-expressions.") + scope.send("function_is_ipv6_address", args) + end +end diff --git a/lib/puppet/functions/is_numeric.rb b/lib/puppet/functions/is_numeric.rb new file mode 100644 index 0000000..3a0f0cd --- /dev/null +++ b/lib/puppet/functions/is_numeric.rb @@ -0,0 +1,10 @@ +Puppet::Functions.create_function(:is_numeric, Puppet::Functions::InternalFunction) do + dispatch :deprecation_gen do + scope_param + optional_repeated_param 'Any', :args + end + def deprecation_gen(scope, *args) + call_function('deprecation', 'is_numeric', "This method is deprecated, please use match expressions with Stdlib::Compat::Numeric instead. They are described at https://docs.puppet.com/puppet/latest/reference/lang_data_type.html#match-expressions.") + scope.send("function_is_numeric", args) + end +end diff --git a/lib/puppet/functions/is_string.rb b/lib/puppet/functions/is_string.rb new file mode 100644 index 0000000..4978284 --- /dev/null +++ b/lib/puppet/functions/is_string.rb @@ -0,0 +1,10 @@ +Puppet::Functions.create_function(:is_string, Puppet::Functions::InternalFunction) do + dispatch :deprecation_gen do + scope_param + optional_repeated_param 'Any', :args + end + def deprecation_gen(scope, *args) + call_function('deprecation', 'is_string', "This method is deprecated, please use match expressions with Stdlib::Compat::String instead. They are described at https://docs.puppet.com/puppet/latest/reference/lang_data_type.html#match-expressions.") + scope.send("function_is_string", args) + end +end diff --git a/lib/puppet/functions/validate_absolute_path.rb b/lib/puppet/functions/validate_absolute_path.rb index 94f52e1..946ff31 100644 --- a/lib/puppet/functions/validate_absolute_path.rb +++ b/lib/puppet/functions/validate_absolute_path.rb @@ -4,7 +4,7 @@ Puppet::Functions.create_function(:validate_absolute_path, Puppet::Functions::In optional_repeated_param 'Any', :args end def deprecation_gen(scope, *args) - call_function('deprecation', 'puppet_3_type_check', "This method is deprecated, please use the stdlib validate_legacy function, with Stdlib::Compat::Absolute_Path. There is further documentation for validate_legacy function in the README.") + call_function('deprecation', 'validate_absolute_path', "This method is deprecated, please use the stdlib validate_legacy function, with Stdlib::Compat::Absolute_Path. There is further documentation for validate_legacy function in the README.") scope.send("function_validate_absolute_path", args) end end diff --git a/lib/puppet/functions/validate_array.rb b/lib/puppet/functions/validate_array.rb index eb8f5e5..c8553c4 100644 --- a/lib/puppet/functions/validate_array.rb +++ b/lib/puppet/functions/validate_array.rb @@ -4,7 +4,7 @@ Puppet::Functions.create_function(:validate_array, Puppet::Functions::InternalFu optional_repeated_param 'Any', :args end def deprecation_gen(scope, *args) - call_function('deprecation', 'puppet_3_type_check', "This method is deprecated, please use the stdlib validate_legacy function, with Stdlib::Compat::Array. There is further documentation for validate_legacy function in the README.") + call_function('deprecation', 'validate_array', "This method is deprecated, please use the stdlib validate_legacy function, with Stdlib::Compat::Array. There is further documentation for validate_legacy function in the README.") scope.send("function_validate_array", args) end end diff --git a/lib/puppet/functions/validate_bool.rb b/lib/puppet/functions/validate_bool.rb index 168775d..9d68cc9 100644 --- a/lib/puppet/functions/validate_bool.rb +++ b/lib/puppet/functions/validate_bool.rb @@ -4,7 +4,7 @@ Puppet::Functions.create_function(:validate_bool, Puppet::Functions::InternalFun optional_repeated_param 'Any', :args end def deprecation_gen(scope, *args) - call_function('deprecation', 'puppet_3_type_check', "This method is deprecated, please use the stdlib validate_legacy function, with Stdlib::Compat::Bool. There is further documentation for validate_legacy function in the README.") + call_function('deprecation', 'validate_bool', "This method is deprecated, please use the stdlib validate_legacy function, with Stdlib::Compat::Bool. There is further documentation for validate_legacy function in the README.") scope.send("function_validate_bool", args) end end diff --git a/lib/puppet/functions/validate_hash.rb b/lib/puppet/functions/validate_hash.rb index c356ceb..fdd8e01 100644 --- a/lib/puppet/functions/validate_hash.rb +++ b/lib/puppet/functions/validate_hash.rb @@ -4,7 +4,7 @@ Puppet::Functions.create_function(:validate_hash, Puppet::Functions::InternalFun optional_repeated_param 'Any', :args end def deprecation_gen(scope, *args) - call_function('deprecation', 'puppet_3_type_check', "This method is deprecated, please use the stdlib validate_legacy function, with Stdlib::Compat::Hash. There is further documentation for validate_legacy function in the README.") + call_function('deprecation', 'validate_hash', "This method is deprecated, please use the stdlib validate_legacy function, with Stdlib::Compat::Hash. There is further documentation for validate_legacy function in the README.") scope.send("function_validate_hash", args) end end diff --git a/lib/puppet/functions/validate_integer.rb b/lib/puppet/functions/validate_integer.rb index db95f1c..63a3523 100644 --- a/lib/puppet/functions/validate_integer.rb +++ b/lib/puppet/functions/validate_integer.rb @@ -4,7 +4,7 @@ Puppet::Functions.create_function(:validate_integer, Puppet::Functions::Internal optional_repeated_param 'Any', :args end def deprecation_gen(scope, *args) - call_function('deprecation', 'puppet_3_type_check', "This method is deprecated, please use the stdlib validate_legacy function, with Stdlib::Compat::Integer. There is further documentation for validate_legacy function in the README.") + call_function('deprecation', 'validate_integer', "This method is deprecated, please use the stdlib validate_legacy function, with Stdlib::Compat::Integer. There is further documentation for validate_legacy function in the README.") scope.send("function_validate_integer", args) end end diff --git a/lib/puppet/functions/validate_ip_address.rb b/lib/puppet/functions/validate_ip_address.rb index eaf56bb..c9c52bb 100644 --- a/lib/puppet/functions/validate_ip_address.rb +++ b/lib/puppet/functions/validate_ip_address.rb @@ -4,7 +4,7 @@ Puppet::Functions.create_function(:validate_ip_address, Puppet::Functions::Inter optional_repeated_param 'Any', :args end def deprecation_gen(scope, *args) - call_function('deprecation', 'puppet_3_type_check', "This method is deprecated, please use the stdlib validate_legacy function, with Stdlib::Compat::Ip_Address. There is further documentation for validate_legacy function in the README.") + call_function('deprecation', 'validate_ip_address', "This method is deprecated, please use the stdlib validate_legacy function, with Stdlib::Compat::Ip_Address. There is further documentation for validate_legacy function in the README.") scope.send("function_validate_ip_address", args) end end diff --git a/lib/puppet/functions/validate_ipv4_address.rb b/lib/puppet/functions/validate_ipv4_address.rb index 6a870eb..d501f7a 100644 --- a/lib/puppet/functions/validate_ipv4_address.rb +++ b/lib/puppet/functions/validate_ipv4_address.rb @@ -4,7 +4,7 @@ Puppet::Functions.create_function(:validate_ipv4_address, Puppet::Functions::Int optional_repeated_param 'Any', :args end def deprecation_gen(scope, *args) - call_function('deprecation', 'puppet_3_type_check', "This method is deprecated, please use the stdlib validate_legacy function, with Stdlib::Compat::Ipv4_Address. There is further documentation for validate_legacy function in the README.") + call_function('deprecation', 'validate_ipv4_address', "This method is deprecated, please use the stdlib validate_legacy function, with Stdlib::Compat::Ipv4_Address. There is further documentation for validate_legacy function in the README.") scope.send("function_validate_ipv4_address", args) end end diff --git a/lib/puppet/functions/validate_ipv6_address.rb b/lib/puppet/functions/validate_ipv6_address.rb index 922a9ac..aa8044f 100644 --- a/lib/puppet/functions/validate_ipv6_address.rb +++ b/lib/puppet/functions/validate_ipv6_address.rb @@ -4,7 +4,7 @@ Puppet::Functions.create_function(:validate_ipv6_address, Puppet::Functions::Int optional_repeated_param 'Any', :args end def deprecation_gen(scope, *args) - call_function('deprecation', 'puppet_3_type_check', "This method is deprecated, please use the stdlib validate_legacy function, with Stdlib::Compat::Ipv6_address. There is further documentation for validate_legacy function in the README.") + call_function('deprecation', 'validate_ipv6_address', "This method is deprecated, please use the stdlib validate_legacy function, with Stdlib::Compat::Ipv6_address. There is further documentation for validate_legacy function in the README.") scope.send("function_validate_ipv6_address", args) end end diff --git a/lib/puppet/functions/validate_numeric.rb b/lib/puppet/functions/validate_numeric.rb index e48bec4..7db5c90 100644 --- a/lib/puppet/functions/validate_numeric.rb +++ b/lib/puppet/functions/validate_numeric.rb @@ -4,7 +4,7 @@ Puppet::Functions.create_function(:validate_numeric, Puppet::Functions::Internal optional_repeated_param 'Any', :args end def deprecation_gen(scope, *args) - call_function('deprecation', 'puppet_3_type_check', "This method is deprecated, please use the stdlib validate_legacy function, with Stdlib::Compat::Numeric. There is further documentation for validate_legacy function in the README.") + call_function('deprecation', 'validate_numeric', "This method is deprecated, please use the stdlib validate_legacy function, with Stdlib::Compat::Numeric. There is further documentation for validate_legacy function in the README.") scope.send("function_validate_numeric", args) end end diff --git a/lib/puppet/functions/validate_re.rb b/lib/puppet/functions/validate_re.rb index 8a95077..ae5d9f1 100644 --- a/lib/puppet/functions/validate_re.rb +++ b/lib/puppet/functions/validate_re.rb @@ -4,7 +4,7 @@ Puppet::Functions.create_function(:validate_re, Puppet::Functions::InternalFunct optional_repeated_param 'Any', :args end def deprecation_gen(scope, *args) - call_function('deprecation', 'puppet_3_type_check', "This method is deprecated, please use the stdlib validate_legacy function, with Pattern[]. There is further documentation for validate_legacy function in the README.") + call_function('deprecation', 'validate_re', "This method is deprecated, please use the stdlib validate_legacy function, with Pattern[]. There is further documentation for validate_legacy function in the README.") scope.send("function_validate_re", args) end end diff --git a/lib/puppet/functions/validate_slength.rb b/lib/puppet/functions/validate_slength.rb index 2d71a14..c3c29a5 100644 --- a/lib/puppet/functions/validate_slength.rb +++ b/lib/puppet/functions/validate_slength.rb @@ -4,7 +4,7 @@ Puppet::Functions.create_function(:validate_slength, Puppet::Functions::Internal optional_repeated_param 'Any', :args end def deprecation_gen(scope, *args) - call_function('deprecation', 'puppet_3_type_check', "This method is deprecated, please use the stdlib validate_legacy function, with String[]. There is further documentation for validate_legacy function in the README.") + call_function('deprecation', 'validate_slength', "This method is deprecated, please use the stdlib validate_legacy function, with String[]. There is further documentation for validate_legacy function in the README.") scope.send("function_validate_slength", args) end end diff --git a/lib/puppet/functions/validate_string.rb b/lib/puppet/functions/validate_string.rb index fe4c623..9b0b731 100644 --- a/lib/puppet/functions/validate_string.rb +++ b/lib/puppet/functions/validate_string.rb @@ -4,7 +4,7 @@ Puppet::Functions.create_function(:validate_string, Puppet::Functions::InternalF optional_repeated_param 'Any', :args end def deprecation_gen(scope, *args) - call_function('deprecation', 'puppet_3_type_check', "This method is deprecated, please use the stdlib validate_legacy function, with Stdlib::Compat::String. There is further documentation for validate_legacy function in the README.") + call_function('deprecation', 'validate_string', "This method is deprecated, please use the stdlib validate_legacy function, with Stdlib::Compat::String. There is further documentation for validate_legacy function in the README.") scope.send("function_validate_string", args) end end diff --git a/lib/puppet/parser/functions/is_absolute_path.rb b/lib/puppet/parser/functions/is_absolute_path.rb index 2e37414..e64777f 100644 --- a/lib/puppet/parser/functions/is_absolute_path.rb +++ b/lib/puppet/parser/functions/is_absolute_path.rb @@ -23,7 +23,7 @@ module Puppet::Parser::Functions is_absolute_path($undefined) ENDHEREDOC - function_deprecation([:puppet_3_type_check, 'This method is deprecated, please use the stdlib validate_legacy function, with Stdlib::Compat::Absolute_path. There is further documentation for validate_legacy function in the README.']) + function_deprecation([:is_absolute_path, 'This method is deprecated, please use the stdlib validate_legacy function, with Stdlib::Compat::Absolute_path. There is further documentation for validate_legacy function in the README.']) require 'puppet/util' path = args[0] diff --git a/lib/puppet/parser/functions/is_array.rb b/lib/puppet/parser/functions/is_array.rb index d1bb58a..1d2c0fa 100644 --- a/lib/puppet/parser/functions/is_array.rb +++ b/lib/puppet/parser/functions/is_array.rb @@ -8,7 +8,7 @@ Returns true if the variable passed to this function is an array. EOS ) do |arguments| - function_deprecation([:puppet_3_type_check, 'This method is deprecated, please use the stdlib validate_legacy function, with Stdlib::Compat::Array. There is further documentation for validate_legacy function in the README.']) + function_deprecation([:is_array, 'This method is deprecated, please use the stdlib validate_legacy function, with Stdlib::Compat::Array. There is further documentation for validate_legacy function in the README.']) raise(Puppet::ParseError, "is_array(): Wrong number of arguments " + "given (#{arguments.size} for 1)") if arguments.size < 1 diff --git a/lib/puppet/parser/functions/is_bool.rb b/lib/puppet/parser/functions/is_bool.rb index 48aaa08..83d2ebe 100644 --- a/lib/puppet/parser/functions/is_bool.rb +++ b/lib/puppet/parser/functions/is_bool.rb @@ -8,7 +8,7 @@ Returns true if the variable passed to this function is a boolean. EOS ) do |arguments| - function_deprecation([:puppet_3_type_check, 'This method is deprecated, please use the stdlib validate_legacy function, with Stdlib::Compat::Bool. There is further documentation for validate_legacy function in the README.']) + function_deprecation([:is_bool, 'This method is deprecated, please use the stdlib validate_legacy function, with Stdlib::Compat::Bool. There is further documentation for validate_legacy function in the README.']) raise(Puppet::ParseError, "is_bool(): Wrong number of arguments " + "given (#{arguments.size} for 1)") if arguments.size != 1 diff --git a/lib/puppet/parser/functions/is_float.rb b/lib/puppet/parser/functions/is_float.rb index 5233e40..1186458 100644 --- a/lib/puppet/parser/functions/is_float.rb +++ b/lib/puppet/parser/functions/is_float.rb @@ -8,7 +8,7 @@ Returns true if the variable passed to this function is a float. EOS ) do |arguments| - function_deprecation([:puppet_3_type_check, 'This method is deprecated, please use the stdlib validate_legacy function, with Stdlib::Compat::Float. There is further documentation for validate_legacy function in the README.']) + function_deprecation([:is_float, 'This method is deprecated, please use the stdlib validate_legacy function, with Stdlib::Compat::Float. There is further documentation for validate_legacy function in the README.']) if (arguments.size != 1) then raise(Puppet::ParseError, "is_float(): Wrong number of arguments "+ diff --git a/lib/puppet/parser/functions/is_ip_address.rb b/lib/puppet/parser/functions/is_ip_address.rb index 1901b2c..5f1d765 100644 --- a/lib/puppet/parser/functions/is_ip_address.rb +++ b/lib/puppet/parser/functions/is_ip_address.rb @@ -10,7 +10,7 @@ Returns true if the string passed to this function is a valid IP address. require 'ipaddr' - function_deprecation([:puppet_3_type_check, 'This method is deprecated, please use the stdlib validate_legacy function, with Stdlib::Compat::Ip_address. There is further documentation for validate_legacy function in the README.']) + function_deprecation([:is_ip_address, 'This method is deprecated, please use the stdlib validate_legacy function, with Stdlib::Compat::Ip_address. There is further documentation for validate_legacy function in the README.']) if (arguments.size != 1) then raise(Puppet::ParseError, "is_ip_address(): Wrong number of arguments "+ diff --git a/lib/puppet/parser/functions/is_ipv4_address.rb b/lib/puppet/parser/functions/is_ipv4_address.rb index c90fa64..1764e61 100644 --- a/lib/puppet/parser/functions/is_ipv4_address.rb +++ b/lib/puppet/parser/functions/is_ipv4_address.rb @@ -10,7 +10,7 @@ Returns true if the string passed to this function is a valid IPv4 address. require 'ipaddr' - function_deprecation([:puppet_3_type_check, 'This method is deprecated, please use the stdlib validate_legacy function, with Stdlib::Compat::Ipv4. There is further documentation for validate_legacy function in the README.']) + function_deprecation([:is_ipv4_address, 'This method is deprecated, please use the stdlib validate_legacy function, with Stdlib::Compat::Ipv4. There is further documentation for validate_legacy function in the README.']) if (arguments.size != 1) then raise(Puppet::ParseError, "is_ipv4_address(): Wrong number of arguments "+ diff --git a/lib/puppet/parser/functions/is_ipv6_address.rb b/lib/puppet/parser/functions/is_ipv6_address.rb index aec3483..7ca4997 100644 --- a/lib/puppet/parser/functions/is_ipv6_address.rb +++ b/lib/puppet/parser/functions/is_ipv6_address.rb @@ -8,7 +8,7 @@ Returns true if the string passed to this function is a valid IPv6 address. EOS ) do |arguments| - function_deprecation([:puppet_3_type_check, 'This method is deprecated, please use the stdlib validate_legacy function, with Stdlib::Compat::Ipv6. There is further documentation for validate_legacy function in the README.']) + function_deprecation([:is_ipv6_address, 'This method is deprecated, please use the stdlib validate_legacy function, with Stdlib::Compat::Ipv6. There is further documentation for validate_legacy function in the README.']) require 'ipaddr' diff --git a/lib/puppet/parser/functions/is_numeric.rb b/lib/puppet/parser/functions/is_numeric.rb index 2bdd353..4a55225 100644 --- a/lib/puppet/parser/functions/is_numeric.rb +++ b/lib/puppet/parser/functions/is_numeric.rb @@ -24,7 +24,7 @@ Valid examples: EOS ) do |arguments| - function_deprecation([:puppet_3_type_check, 'This method is deprecated, please use the stdlib validate_legacy function, with Stdlib::Compat::Numeric. There is further documentation for validate_legacy function in the README.']) + function_deprecation([:is_numeric, 'This method is deprecated, please use the stdlib validate_legacy function, with Stdlib::Compat::Numeric. There is further documentation for validate_legacy function in the README.']) if (arguments.size != 1) then raise(Puppet::ParseError, "is_numeric(): Wrong number of arguments "+ diff --git a/lib/puppet/parser/functions/is_string.rb b/lib/puppet/parser/functions/is_string.rb index 144cf51..31ee91e 100644 --- a/lib/puppet/parser/functions/is_string.rb +++ b/lib/puppet/parser/functions/is_string.rb @@ -8,14 +8,15 @@ Returns true if the variable passed to this function is a string. EOS ) do |arguments| - function_deprecation([:puppet_3_type_check, 'This method is deprecated, please use the stdlib validate_legacy function, with Stdlib::Compat::String. There is further documentation for validate_legacy function in the README.']) + function_deprecation([:is_string, 'This method is deprecated, please use the stdlib validate_legacy function, with Stdlib::Compat::String. There is further documentation for validate_legacy function in the README.']) raise(Puppet::ParseError, "is_string(): Wrong number of arguments " + "given (#{arguments.size} for 1)") if arguments.size < 1 type = arguments[0] - result = type.is_a?(String) + # when called through the v4 API shim, undef gets translated to nil + result = type.is_a?(String) || type.nil? if result and (type == type.to_f.to_s or type == type.to_i.to_s) then return false diff --git a/lib/puppet/parser/functions/validate_absolute_path.rb b/lib/puppet/parser/functions/validate_absolute_path.rb index 15b5c57..c73f3df 100644 --- a/lib/puppet/parser/functions/validate_absolute_path.rb +++ b/lib/puppet/parser/functions/validate_absolute_path.rb @@ -27,7 +27,7 @@ module Puppet::Parser::Functions ENDHEREDOC # The deprecation function was being called twice, as validate_absolute_path calls is_absolute_path. I have removed it from here so it only calls deprecation once within is_absolute_path. - # function_deprecation([:puppet_3_type_check, 'This method is deprecated, please use the stdlib validate_legacy function, with Stdlib::Compat::Absolute_path. There is further documentation for validate_legacy function in the README.']) + # function_deprecation([:validate_absolute_path, 'This method is deprecated, please use the stdlib validate_legacy function, with Stdlib::Compat::Absolute_path. There is further documentation for validate_legacy function in the README.']) require 'puppet/util' diff --git a/lib/puppet/parser/functions/validate_array.rb b/lib/puppet/parser/functions/validate_array.rb index 97bd41d..3bf3983 100644 --- a/lib/puppet/parser/functions/validate_array.rb +++ b/lib/puppet/parser/functions/validate_array.rb @@ -18,7 +18,7 @@ module Puppet::Parser::Functions ENDHEREDOC - function_deprecation([:puppet_3_type_check, 'This method is deprecated, please use the stdlib validate_legacy function, with Stdlib::Compat::Array. There is further documentation for validate_legacy function in the README.']) + function_deprecation([:validate_array, 'This method is deprecated, please use the stdlib validate_legacy function, with Stdlib::Compat::Array. There is further documentation for validate_legacy function in the README.']) unless args.length > 0 then raise Puppet::ParseError, ("validate_array(): wrong number of arguments (#{args.length}; must be > 0)") diff --git a/lib/puppet/parser/functions/validate_bool.rb b/lib/puppet/parser/functions/validate_bool.rb index e4345eb..49075b8 100644 --- a/lib/puppet/parser/functions/validate_bool.rb +++ b/lib/puppet/parser/functions/validate_bool.rb @@ -20,7 +20,7 @@ module Puppet::Parser::Functions ENDHEREDOC # The deprecation function was being called twice, as validate_bool calls is_bool. I have removed it from here so it only calls deprecation once within is_bool. - # function_deprecation([:puppet_3_type_check, 'This method is deprecated, please use the stdlib validate_legacy function, with Stdlib::Compat::Bool. There is further documentation for validate_legacy function in the README.']) + # function_deprecation([:validate_bool, 'This method is deprecated, please use the stdlib validate_legacy function, with Stdlib::Compat::Bool. There is further documentation for validate_legacy function in the README.']) unless args.length > 0 then raise Puppet::ParseError, ("validate_bool(): wrong number of arguments (#{args.length}; must be > 0)") diff --git a/lib/puppet/parser/functions/validate_hash.rb b/lib/puppet/parser/functions/validate_hash.rb index 800a758..fcdc7e1 100644 --- a/lib/puppet/parser/functions/validate_hash.rb +++ b/lib/puppet/parser/functions/validate_hash.rb @@ -18,7 +18,7 @@ module Puppet::Parser::Functions ENDHEREDOC - function_deprecation([:puppet_3_type_check, 'This method is deprecated, please use the stdlib validate_legacy function, with Stdlib::Compat::Hash. There is further documentation for validate_legacy function in the README.']) + function_deprecation([:validate_hash, 'This method is deprecated, please use the stdlib validate_legacy function, with Stdlib::Compat::Hash. There is further documentation for validate_legacy function in the README.']) unless args.length > 0 then raise Puppet::ParseError, ("validate_hash(): wrong number of arguments (#{args.length}; must be > 0)") diff --git a/lib/puppet/parser/functions/validate_integer.rb b/lib/puppet/parser/functions/validate_integer.rb index f52e053..2ae0293 100644 --- a/lib/puppet/parser/functions/validate_integer.rb +++ b/lib/puppet/parser/functions/validate_integer.rb @@ -2,7 +2,7 @@ module Puppet::Parser::Functions newfunction(:validate_integer, :doc => <<-'ENDHEREDOC') do |args| Validate that the first argument is an integer (or an array of integers). Abort catalog compilation if any of the checks fail. - + The second argument is optional and passes a maximum. (All elements of) the first argument has to be less or equal to this max. The third argument is optional and passes a minimum. (All elements of) the first argument has to be greater or equal to this min. @@ -53,7 +53,7 @@ module Puppet::Parser::Functions ENDHEREDOC - function_deprecation([:puppet_3_type_check, 'This method is deprecated, please use the stdlib validate_legacy function, with Stdlib::Compat::Integer. There is further documentation for validate_legacy function in the README.']) + function_deprecation([:validate_integer, 'This method is deprecated, please use the stdlib validate_legacy function, with Stdlib::Compat::Integer. There is further documentation for validate_legacy function in the README.']) # tell the user we need at least one, and optionally up to two other parameters raise Puppet::ParseError, "validate_integer(): Wrong number of arguments; must be 1, 2 or 3, got #{args.length}" unless args.length > 0 and args.length < 4 diff --git a/lib/puppet/parser/functions/validate_ip_address.rb b/lib/puppet/parser/functions/validate_ip_address.rb index 3377c76..5d80cfb 100644 --- a/lib/puppet/parser/functions/validate_ip_address.rb +++ b/lib/puppet/parser/functions/validate_ip_address.rb @@ -8,12 +8,12 @@ module Puppet::Parser::Functions $my_ip = "1.2.3.4" validate_ip_address($my_ip) validate_ip_address("8.8.8.8", "172.16.0.1", $my_ip) - + $my_ip = "3ffe:505:2" validate_ip_address(1) validate_ip_address($my_ip) validate_ip_address("fe80::baf6:b1ff:fe19:7507", $my_ip) - + The following values will fail, causing compilation to abort: $some_array = [ 1, true, false, "garbage string", "3ffe:505:2" ] validate_ip_address($some_array) @@ -23,7 +23,7 @@ module Puppet::Parser::Functions require "ipaddr" rescuable_exceptions = [ ArgumentError ] - function_deprecation([:puppet_3_type_check, 'This method is deprecated, please use the stdlib validate_legacy function, with Stdlib::Compat::Ip_address. There is further documentation for validate_legacy function in the README.']) + function_deprecation([:validate_ip_address, 'This method is deprecated, please use the stdlib validate_legacy function, with Stdlib::Compat::Ip_address. There is further documentation for validate_legacy function in the README.']) if defined?(IPAddr::InvalidAddressError) rescuable_exceptions << IPAddr::InvalidAddressError diff --git a/lib/puppet/parser/functions/validate_ipv4_address.rb b/lib/puppet/parser/functions/validate_ipv4_address.rb index fb2260c..0660abd 100644 --- a/lib/puppet/parser/functions/validate_ipv4_address.rb +++ b/lib/puppet/parser/functions/validate_ipv4_address.rb @@ -18,7 +18,7 @@ module Puppet::Parser::Functions ENDHEREDOC ) do |args| - function_deprecation([:puppet_3_type_check, 'This method is deprecated, please use the stdlib validate_legacy function, with Stdlib::Compat::Ipv4. There is further documentation for validate_legacy function in the README.']) + function_deprecation([:validate_ipv4_address, 'This method is deprecated, please use the stdlib validate_legacy function, with Stdlib::Compat::Ipv4. There is further documentation for validate_legacy function in the README.']) require "ipaddr" rescuable_exceptions = [ ArgumentError ] diff --git a/lib/puppet/parser/functions/validate_ipv6_address.rb b/lib/puppet/parser/functions/validate_ipv6_address.rb index 4dedcd6..f5dd9e5 100644 --- a/lib/puppet/parser/functions/validate_ipv6_address.rb +++ b/lib/puppet/parser/functions/validate_ipv6_address.rb @@ -19,7 +19,7 @@ module Puppet::Parser::Functions ENDHEREDOC ) do |args| - function_deprecation([:puppet_3_type_check, 'This method is deprecated, please use the stdlib validate_legacy function, with Stdlib::Compat::Ipv6. There is further documentation for validate_legacy function in the README.']) + function_deprecation([:validate_ipv6_address, 'This method is deprecated, please use the stdlib validate_legacy function, with Stdlib::Compat::Ipv6. There is further documentation for validate_legacy function in the README.']) require "ipaddr" rescuable_exceptions = [ ArgumentError ] diff --git a/lib/puppet/parser/functions/validate_numeric.rb b/lib/puppet/parser/functions/validate_numeric.rb index 6b55f49..4205b30 100644 --- a/lib/puppet/parser/functions/validate_numeric.rb +++ b/lib/puppet/parser/functions/validate_numeric.rb @@ -2,7 +2,7 @@ module Puppet::Parser::Functions newfunction(:validate_numeric, :doc => <<-'ENDHEREDOC') do |args| Validate that the first argument is a numeric value (or an array of numeric values). Abort catalog compilation if any of the checks fail. - + The second argument is optional and passes a maximum. (All elements of) the first argument has to be less or equal to this max. The third argument is optional and passes a minimum. (All elements of) the first argument has to be greater or equal to this min. @@ -15,7 +15,7 @@ module Puppet::Parser::Functions ENDHEREDOC - function_deprecation([:puppet_3_type_check, 'This method is deprecated, please use the stdlib validate_legacy function, with Stdlib::Compat::Numeric. There is further documentation for validate_legacy function in the README.']) + function_deprecation([:validate_numeric, 'This method is deprecated, please use the stdlib validate_legacy function, with Stdlib::Compat::Numeric. There is further documentation for validate_legacy function in the README.']) # tell the user we need at least one, and optionally up to two other parameters raise Puppet::ParseError, "validate_numeric(): Wrong number of arguments; must be 1, 2 or 3, got #{args.length}" unless args.length > 0 and args.length < 4 diff --git a/lib/puppet/parser/functions/validate_re.rb b/lib/puppet/parser/functions/validate_re.rb index 6bdc858..0ac83dd 100644 --- a/lib/puppet/parser/functions/validate_re.rb +++ b/lib/puppet/parser/functions/validate_re.rb @@ -30,7 +30,7 @@ module Puppet::Parser::Functions ENDHEREDOC - function_deprecation([:puppet_3_type_check, 'This method is deprecated, please use the stdlib validate_legacy function, with Stdlib::Compat::Re. There is further documentation for validate_legacy function in the README.']) + function_deprecation([:validate_re, 'This method is deprecated, please use the stdlib validate_legacy function, with Stdlib::Compat::Re. There is further documentation for validate_legacy function in the README.']) if (args.length < 2) or (args.length > 3) then raise Puppet::ParseError, "validate_re(): wrong number of arguments (#{args.length}; must be 2 or 3)" diff --git a/lib/puppet/parser/functions/validate_slength.rb b/lib/puppet/parser/functions/validate_slength.rb index 1828f49..383855c 100644 --- a/lib/puppet/parser/functions/validate_slength.rb +++ b/lib/puppet/parser/functions/validate_slength.rb @@ -21,7 +21,7 @@ module Puppet::Parser::Functions ENDHEREDOC - function_deprecation([:puppet_3_type_check, 'This method is deprecated, please use the stdlib validate_legacy function, with String[]. There is further documentation for validate_legacy function in the README.']) + function_deprecation([:validate_slength, 'This method is deprecated, please use the stdlib validate_legacy function, with String[]. There is further documentation for validate_legacy function in the README.']) raise Puppet::ParseError, "validate_slength(): Wrong number of arguments (#{args.length}; must be 2 or 3)" unless args.length == 2 or args.length == 3 diff --git a/lib/puppet/parser/functions/validate_string.rb b/lib/puppet/parser/functions/validate_string.rb index 0057fc1..6675d86 100644 --- a/lib/puppet/parser/functions/validate_string.rb +++ b/lib/puppet/parser/functions/validate_string.rb @@ -13,23 +13,24 @@ module Puppet::Parser::Functions validate_string(true) validate_string([ 'some', 'array' ]) - + Note: validate_string(undef) will not fail in this version of the functions API (incl. current and future parser). Instead, use: - + if $var == undef { fail('...') } - + ENDHEREDOC - function_deprecation([:puppet_3_type_check, 'This method is deprecated, please use the stdlib validate_legacy function, with Stdlib::Compat::String. There is further documentation for validate_legacy function in the README.']) + function_deprecation([:validate_string, 'This method is deprecated, please use the stdlib validate_legacy function, with Stdlib::Compat::String. There is further documentation for validate_legacy function in the README.']) unless args.length > 0 then raise Puppet::ParseError, ("validate_string(): wrong number of arguments (#{args.length}; must be > 0)") end args.each do |arg| + # when called through the v4 API shim, undef gets translated to nil unless arg.is_a?(String) || arg.nil? raise Puppet::ParseError, ("#{arg.inspect} is not a string. It looks to be a #{arg.class}") end diff --git a/metadata.json b/metadata.json index 07672c3..8ad4eec 100644 --- a/metadata.json +++ b/metadata.json @@ -1,6 +1,6 @@ { "name": "puppetlabs-stdlib", - "version": "4.13.0", + "version": "4.13.1", "author": "puppetlabs", "summary": "Standard library of resources for Puppet modules.", "license": "Apache-2.0", -- cgit v1.2.3 From f2741dc814c1b6c10d8dd69c17aabf5bae106c17 Mon Sep 17 00:00:00 2001 From: David Schmitt Date: Wed, 12 Oct 2016 13:25:33 +0100 Subject: (MODULES-3962) Rework v4 function shims to work on puppet 3.7 and 4.0.0 This is a workaround for PUP-4438 (fixed in https://github.com/puppetlabs/puppet/commit/e01c4dc924cd963ff6630008a5200fc6a2023b08, 4.1.0, 3.8.1). It works by manually passing through the scope, instead of relying on the InternalFunction class. --- .travis.yml | 3 +++ CHANGELOG.md | 6 ++++-- lib/puppet/functions/is_absolute_path.rb | 11 ++++++++--- lib/puppet/functions/is_array.rb | 11 ++++++++--- lib/puppet/functions/is_bool.rb | 11 ++++++++--- lib/puppet/functions/is_float.rb | 11 ++++++++--- lib/puppet/functions/is_ip_address.rb | 11 ++++++++--- lib/puppet/functions/is_ipv4_address.rb | 11 ++++++++--- lib/puppet/functions/is_ipv6_address.rb | 11 ++++++++--- lib/puppet/functions/is_numeric.rb | 11 ++++++++--- lib/puppet/functions/is_string.rb | 11 ++++++++--- lib/puppet/functions/validate_absolute_path.rb | 11 ++++++++--- lib/puppet/functions/validate_array.rb | 11 ++++++++--- lib/puppet/functions/validate_bool.rb | 11 ++++++++--- lib/puppet/functions/validate_hash.rb | 11 ++++++++--- lib/puppet/functions/validate_integer.rb | 11 ++++++++--- lib/puppet/functions/validate_ip_address.rb | 11 ++++++++--- lib/puppet/functions/validate_ipv4_address.rb | 11 ++++++++--- lib/puppet/functions/validate_ipv6_address.rb | 11 ++++++++--- lib/puppet/functions/validate_legacy.rb | 16 +++++++++++----- lib/puppet/functions/validate_numeric.rb | 11 ++++++++--- lib/puppet/functions/validate_re.rb | 11 ++++++++--- lib/puppet/functions/validate_slength.rb | 11 ++++++++--- lib/puppet/functions/validate_string.rb | 11 ++++++++--- 24 files changed, 186 insertions(+), 70 deletions(-) diff --git a/.travis.yml b/.travis.yml index 4e549bf..cf44471 100644 --- a/.travis.yml +++ b/.travis.yml @@ -28,6 +28,9 @@ matrix: - rvm: 2.1.5 bundler_args: --without system_tests env: PUPPET_GEM_VERSION="~> 3.0" FUTURE_PARSER="yes" + - rvm: 2.1.5 + bundler_args: --without system_tests + env: PUPPET_GEM_VERSION="~> 3.7.0" FUTURE_PARSER="yes" - rvm: 2.1.5 bundler_args: --without system_tests env: PUPPET_GEM_VERSION="~> 3.0" diff --git a/CHANGELOG.md b/CHANGELOG.md index 01b0a94..e9f79f6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,9 +1,11 @@ ## Supported Release 4.13.1 ### Summary -This bugfix release improves the user experience around function deprecations by emitting one warning per function(-name) instead of only one deprecation overall. This allows users to identify all deprecated functions used in one agent run, with less back-and-forth. +This bugfix release addresses the `undefined method 'optional_repeated_param'` error messages seen by users of puppet 3.7. -This release also adds additional Puppet 4 overrides for the `is_` counterparts of the deprecated functions to emit the deprecations warnings in all cases. +It also improves the user experience around function deprecations by emitting one warning per function(-name) instead of only one deprecation overall. This allows users to identify all deprecated functions used in one agent run, with less back-and-forth. + +Finally, this release adds additional Puppet 4 overrides for the `is_` counterparts of the deprecated functions to emit the deprecations warnings in all cases. ## Supported Release 4.13.0 ### Summary diff --git a/lib/puppet/functions/is_absolute_path.rb b/lib/puppet/functions/is_absolute_path.rb index 0a100f8..b61064a 100644 --- a/lib/puppet/functions/is_absolute_path.rb +++ b/lib/puppet/functions/is_absolute_path.rb @@ -1,7 +1,12 @@ -Puppet::Functions.create_function(:is_absolute_path, Puppet::Functions::InternalFunction) do +Puppet::Functions.create_function(:is_absolute_path) do dispatch :deprecation_gen do - scope_param - optional_repeated_param 'Any', :args + param 'Any', :scope + repeated_param 'Any', :args + end + # Workaround PUP-4438 (fixed: https://github.com/puppetlabs/puppet/commit/e01c4dc924cd963ff6630008a5200fc6a2023b08#diff-c937cc584953271bb3d3b3c2cb141790R221) to support puppet < 4.1.0 and puppet < 3.8.1. + def call(scope, *args) + manipulated_args = [scope] + args + self.class.dispatcher.dispatch(self, scope, manipulated_args) end def deprecation_gen(scope, *args) call_function('deprecation', 'is_absolute_path', "This method is deprecated, please use match expressions with Stdlib::Compat::Absolute_Path instead. They are described at https://docs.puppet.com/puppet/latest/reference/lang_data_type.html#match-expressions.") diff --git a/lib/puppet/functions/is_array.rb b/lib/puppet/functions/is_array.rb index 0542a63..a29fe8a 100644 --- a/lib/puppet/functions/is_array.rb +++ b/lib/puppet/functions/is_array.rb @@ -1,7 +1,12 @@ -Puppet::Functions.create_function(:is_array, Puppet::Functions::InternalFunction) do +Puppet::Functions.create_function(:is_array) do dispatch :deprecation_gen do - scope_param - optional_repeated_param 'Any', :args + param 'Any', :scope + repeated_param 'Any', :args + end + # Workaround PUP-4438 (fixed: https://github.com/puppetlabs/puppet/commit/e01c4dc924cd963ff6630008a5200fc6a2023b08#diff-c937cc584953271bb3d3b3c2cb141790R221) to support puppet < 4.1.0 and puppet < 3.8.1. + def call(scope, *args) + manipulated_args = [scope] + args + self.class.dispatcher.dispatch(self, scope, manipulated_args) end def deprecation_gen(scope, *args) call_function('deprecation', 'is_array', "This method is deprecated, please use match expressions with Stdlib::Compat::Array instead. They are described at https://docs.puppet.com/puppet/latest/reference/lang_data_type.html#match-expressions.") diff --git a/lib/puppet/functions/is_bool.rb b/lib/puppet/functions/is_bool.rb index ff1d462..6e2c22b 100644 --- a/lib/puppet/functions/is_bool.rb +++ b/lib/puppet/functions/is_bool.rb @@ -1,7 +1,12 @@ -Puppet::Functions.create_function(:is_bool, Puppet::Functions::InternalFunction) do +Puppet::Functions.create_function(:is_bool) do dispatch :deprecation_gen do - scope_param - optional_repeated_param 'Any', :args + param 'Any', :scope + repeated_param 'Any', :args + end + # Workaround PUP-4438 (fixed: https://github.com/puppetlabs/puppet/commit/e01c4dc924cd963ff6630008a5200fc6a2023b08#diff-c937cc584953271bb3d3b3c2cb141790R221) to support puppet < 4.1.0 and puppet < 3.8.1. + def call(scope, *args) + manipulated_args = [scope] + args + self.class.dispatcher.dispatch(self, scope, manipulated_args) end def deprecation_gen(scope, *args) call_function('deprecation', 'is_bool', "This method is deprecated, please use match expressions with Stdlib::Compat::Bool instead. They are described at https://docs.puppet.com/puppet/latest/reference/lang_data_type.html#match-expressions.") diff --git a/lib/puppet/functions/is_float.rb b/lib/puppet/functions/is_float.rb index b3763f2..c91aa5d 100644 --- a/lib/puppet/functions/is_float.rb +++ b/lib/puppet/functions/is_float.rb @@ -1,7 +1,12 @@ -Puppet::Functions.create_function(:is_float, Puppet::Functions::InternalFunction) do +Puppet::Functions.create_function(:is_float) do dispatch :deprecation_gen do - scope_param - optional_repeated_param 'Any', :args + param 'Any', :scope + repeated_param 'Any', :args + end + # Workaround PUP-4438 (fixed: https://github.com/puppetlabs/puppet/commit/e01c4dc924cd963ff6630008a5200fc6a2023b08#diff-c937cc584953271bb3d3b3c2cb141790R221) to support puppet < 4.1.0 and puppet < 3.8.1. + def call(scope, *args) + manipulated_args = [scope] + args + self.class.dispatcher.dispatch(self, scope, manipulated_args) end def deprecation_gen(scope, *args) call_function('deprecation', 'is_float', "This method is deprecated, please use match expressions with Stdlib::Compat::Float instead. They are described at https://docs.puppet.com/puppet/latest/reference/lang_data_type.html#match-expressions.") diff --git a/lib/puppet/functions/is_ip_address.rb b/lib/puppet/functions/is_ip_address.rb index e584714..4c72037 100644 --- a/lib/puppet/functions/is_ip_address.rb +++ b/lib/puppet/functions/is_ip_address.rb @@ -1,7 +1,12 @@ -Puppet::Functions.create_function(:is_ip_address, Puppet::Functions::InternalFunction) do +Puppet::Functions.create_function(:is_ip_address) do dispatch :deprecation_gen do - scope_param - optional_repeated_param 'Any', :args + param 'Any', :scope + repeated_param 'Any', :args + end + # Workaround PUP-4438 (fixed: https://github.com/puppetlabs/puppet/commit/e01c4dc924cd963ff6630008a5200fc6a2023b08#diff-c937cc584953271bb3d3b3c2cb141790R221) to support puppet < 4.1.0 and puppet < 3.8.1. + def call(scope, *args) + manipulated_args = [scope] + args + self.class.dispatcher.dispatch(self, scope, manipulated_args) end def deprecation_gen(scope, *args) call_function('deprecation', 'is_ip_address', "This method is deprecated, please use match expressions with Stdlib::Compat::Ip_address instead. They are described at https://docs.puppet.com/puppet/latest/reference/lang_data_type.html#match-expressions.") diff --git a/lib/puppet/functions/is_ipv4_address.rb b/lib/puppet/functions/is_ipv4_address.rb index 76c75e5..97b01ae 100644 --- a/lib/puppet/functions/is_ipv4_address.rb +++ b/lib/puppet/functions/is_ipv4_address.rb @@ -1,7 +1,12 @@ -Puppet::Functions.create_function(:is_ipv4_address, Puppet::Functions::InternalFunction) do +Puppet::Functions.create_function(:is_ipv4_address) do dispatch :deprecation_gen do - scope_param - optional_repeated_param 'Any', :args + param 'Any', :scope + repeated_param 'Any', :args + end + # Workaround PUP-4438 (fixed: https://github.com/puppetlabs/puppet/commit/e01c4dc924cd963ff6630008a5200fc6a2023b08#diff-c937cc584953271bb3d3b3c2cb141790R221) to support puppet < 4.1.0 and puppet < 3.8.1. + def call(scope, *args) + manipulated_args = [scope] + args + self.class.dispatcher.dispatch(self, scope, manipulated_args) end def deprecation_gen(scope, *args) call_function('deprecation', 'is_ipv4_address', "This method is deprecated, please use match expressions with Stdlib::Compat::Ipv4 instead. They are described at https://docs.puppet.com/puppet/latest/reference/lang_data_type.html#match-expressions.") diff --git a/lib/puppet/functions/is_ipv6_address.rb b/lib/puppet/functions/is_ipv6_address.rb index dbf5282..be0c98a 100644 --- a/lib/puppet/functions/is_ipv6_address.rb +++ b/lib/puppet/functions/is_ipv6_address.rb @@ -1,7 +1,12 @@ -Puppet::Functions.create_function(:is_ipv6_address, Puppet::Functions::InternalFunction) do +Puppet::Functions.create_function(:is_ipv6_address) do dispatch :deprecation_gen do - scope_param - optional_repeated_param 'Any', :args + param 'Any', :scope + repeated_param 'Any', :args + end + # Workaround PUP-4438 (fixed: https://github.com/puppetlabs/puppet/commit/e01c4dc924cd963ff6630008a5200fc6a2023b08#diff-c937cc584953271bb3d3b3c2cb141790R221) to support puppet < 4.1.0 and puppet < 3.8.1. + def call(scope, *args) + manipulated_args = [scope] + args + self.class.dispatcher.dispatch(self, scope, manipulated_args) end def deprecation_gen(scope, *args) call_function('deprecation', 'is_ipv4_address', "This method is deprecated, please use match expressions with Stdlib::Compat::Ipv6 instead. They are described at https://docs.puppet.com/puppet/latest/reference/lang_data_type.html#match-expressions.") diff --git a/lib/puppet/functions/is_numeric.rb b/lib/puppet/functions/is_numeric.rb index 3a0f0cd..f5e9d41 100644 --- a/lib/puppet/functions/is_numeric.rb +++ b/lib/puppet/functions/is_numeric.rb @@ -1,7 +1,12 @@ -Puppet::Functions.create_function(:is_numeric, Puppet::Functions::InternalFunction) do +Puppet::Functions.create_function(:is_numeric) do dispatch :deprecation_gen do - scope_param - optional_repeated_param 'Any', :args + param 'Any', :scope + repeated_param 'Any', :args + end + # Workaround PUP-4438 (fixed: https://github.com/puppetlabs/puppet/commit/e01c4dc924cd963ff6630008a5200fc6a2023b08#diff-c937cc584953271bb3d3b3c2cb141790R221) to support puppet < 4.1.0 and puppet < 3.8.1. + def call(scope, *args) + manipulated_args = [scope] + args + self.class.dispatcher.dispatch(self, scope, manipulated_args) end def deprecation_gen(scope, *args) call_function('deprecation', 'is_numeric', "This method is deprecated, please use match expressions with Stdlib::Compat::Numeric instead. They are described at https://docs.puppet.com/puppet/latest/reference/lang_data_type.html#match-expressions.") diff --git a/lib/puppet/functions/is_string.rb b/lib/puppet/functions/is_string.rb index 4978284..a05a796 100644 --- a/lib/puppet/functions/is_string.rb +++ b/lib/puppet/functions/is_string.rb @@ -1,7 +1,12 @@ -Puppet::Functions.create_function(:is_string, Puppet::Functions::InternalFunction) do +Puppet::Functions.create_function(:is_string) do dispatch :deprecation_gen do - scope_param - optional_repeated_param 'Any', :args + param 'Any', :scope + repeated_param 'Any', :args + end + # Workaround PUP-4438 (fixed: https://github.com/puppetlabs/puppet/commit/e01c4dc924cd963ff6630008a5200fc6a2023b08#diff-c937cc584953271bb3d3b3c2cb141790R221) to support puppet < 4.1.0 and puppet < 3.8.1. + def call(scope, *args) + manipulated_args = [scope] + args + self.class.dispatcher.dispatch(self, scope, manipulated_args) end def deprecation_gen(scope, *args) call_function('deprecation', 'is_string', "This method is deprecated, please use match expressions with Stdlib::Compat::String instead. They are described at https://docs.puppet.com/puppet/latest/reference/lang_data_type.html#match-expressions.") diff --git a/lib/puppet/functions/validate_absolute_path.rb b/lib/puppet/functions/validate_absolute_path.rb index 946ff31..a3c696d 100644 --- a/lib/puppet/functions/validate_absolute_path.rb +++ b/lib/puppet/functions/validate_absolute_path.rb @@ -1,7 +1,12 @@ -Puppet::Functions.create_function(:validate_absolute_path, Puppet::Functions::InternalFunction) do +Puppet::Functions.create_function(:validate_absolute_path) do dispatch :deprecation_gen do - scope_param - optional_repeated_param 'Any', :args + param 'Any', :scope + repeated_param 'Any', :args + end + # Workaround PUP-4438 (fixed: https://github.com/puppetlabs/puppet/commit/e01c4dc924cd963ff6630008a5200fc6a2023b08#diff-c937cc584953271bb3d3b3c2cb141790R221) to support puppet < 4.1.0 and puppet < 3.8.1. + def call(scope, *args) + manipulated_args = [scope] + args + self.class.dispatcher.dispatch(self, scope, manipulated_args) end def deprecation_gen(scope, *args) call_function('deprecation', 'validate_absolute_path', "This method is deprecated, please use the stdlib validate_legacy function, with Stdlib::Compat::Absolute_Path. There is further documentation for validate_legacy function in the README.") diff --git a/lib/puppet/functions/validate_array.rb b/lib/puppet/functions/validate_array.rb index c8553c4..f59c6b4 100644 --- a/lib/puppet/functions/validate_array.rb +++ b/lib/puppet/functions/validate_array.rb @@ -1,7 +1,12 @@ -Puppet::Functions.create_function(:validate_array, Puppet::Functions::InternalFunction) do +Puppet::Functions.create_function(:validate_array) do dispatch :deprecation_gen do - scope_param - optional_repeated_param 'Any', :args + param 'Any', :scope + repeated_param 'Any', :args + end + # Workaround PUP-4438 (fixed: https://github.com/puppetlabs/puppet/commit/e01c4dc924cd963ff6630008a5200fc6a2023b08#diff-c937cc584953271bb3d3b3c2cb141790R221) to support puppet < 4.1.0 and puppet < 3.8.1. + def call(scope, *args) + manipulated_args = [scope] + args + self.class.dispatcher.dispatch(self, scope, manipulated_args) end def deprecation_gen(scope, *args) call_function('deprecation', 'validate_array', "This method is deprecated, please use the stdlib validate_legacy function, with Stdlib::Compat::Array. There is further documentation for validate_legacy function in the README.") diff --git a/lib/puppet/functions/validate_bool.rb b/lib/puppet/functions/validate_bool.rb index 9d68cc9..5cfb2ac 100644 --- a/lib/puppet/functions/validate_bool.rb +++ b/lib/puppet/functions/validate_bool.rb @@ -1,7 +1,12 @@ -Puppet::Functions.create_function(:validate_bool, Puppet::Functions::InternalFunction) do +Puppet::Functions.create_function(:validate_bool) do dispatch :deprecation_gen do - scope_param - optional_repeated_param 'Any', :args + param 'Any', :scope + repeated_param 'Any', :args + end + # Workaround PUP-4438 (fixed: https://github.com/puppetlabs/puppet/commit/e01c4dc924cd963ff6630008a5200fc6a2023b08#diff-c937cc584953271bb3d3b3c2cb141790R221) to support puppet < 4.1.0 and puppet < 3.8.1. + def call(scope, *args) + manipulated_args = [scope] + args + self.class.dispatcher.dispatch(self, scope, manipulated_args) end def deprecation_gen(scope, *args) call_function('deprecation', 'validate_bool', "This method is deprecated, please use the stdlib validate_legacy function, with Stdlib::Compat::Bool. There is further documentation for validate_legacy function in the README.") diff --git a/lib/puppet/functions/validate_hash.rb b/lib/puppet/functions/validate_hash.rb index fdd8e01..89ad9ab 100644 --- a/lib/puppet/functions/validate_hash.rb +++ b/lib/puppet/functions/validate_hash.rb @@ -1,7 +1,12 @@ -Puppet::Functions.create_function(:validate_hash, Puppet::Functions::InternalFunction) do +Puppet::Functions.create_function(:validate_hash) do dispatch :deprecation_gen do - scope_param - optional_repeated_param 'Any', :args + param 'Any', :scope + repeated_param 'Any', :args + end + # Workaround PUP-4438 (fixed: https://github.com/puppetlabs/puppet/commit/e01c4dc924cd963ff6630008a5200fc6a2023b08#diff-c937cc584953271bb3d3b3c2cb141790R221) to support puppet < 4.1.0 and puppet < 3.8.1. + def call(scope, *args) + manipulated_args = [scope] + args + self.class.dispatcher.dispatch(self, scope, manipulated_args) end def deprecation_gen(scope, *args) call_function('deprecation', 'validate_hash', "This method is deprecated, please use the stdlib validate_legacy function, with Stdlib::Compat::Hash. There is further documentation for validate_legacy function in the README.") diff --git a/lib/puppet/functions/validate_integer.rb b/lib/puppet/functions/validate_integer.rb index 63a3523..475ea0f 100644 --- a/lib/puppet/functions/validate_integer.rb +++ b/lib/puppet/functions/validate_integer.rb @@ -1,7 +1,12 @@ -Puppet::Functions.create_function(:validate_integer, Puppet::Functions::InternalFunction) do +Puppet::Functions.create_function(:validate_integer) do dispatch :deprecation_gen do - scope_param - optional_repeated_param 'Any', :args + param 'Any', :scope + repeated_param 'Any', :args + end + # Workaround PUP-4438 (fixed: https://github.com/puppetlabs/puppet/commit/e01c4dc924cd963ff6630008a5200fc6a2023b08#diff-c937cc584953271bb3d3b3c2cb141790R221) to support puppet < 4.1.0 and puppet < 3.8.1. + def call(scope, *args) + manipulated_args = [scope] + args + self.class.dispatcher.dispatch(self, scope, manipulated_args) end def deprecation_gen(scope, *args) call_function('deprecation', 'validate_integer', "This method is deprecated, please use the stdlib validate_legacy function, with Stdlib::Compat::Integer. There is further documentation for validate_legacy function in the README.") diff --git a/lib/puppet/functions/validate_ip_address.rb b/lib/puppet/functions/validate_ip_address.rb index c9c52bb..1521c08 100644 --- a/lib/puppet/functions/validate_ip_address.rb +++ b/lib/puppet/functions/validate_ip_address.rb @@ -1,7 +1,12 @@ -Puppet::Functions.create_function(:validate_ip_address, Puppet::Functions::InternalFunction) do +Puppet::Functions.create_function(:validate_ip_address) do dispatch :deprecation_gen do - scope_param - optional_repeated_param 'Any', :args + param 'Any', :scope + repeated_param 'Any', :args + end + # Workaround PUP-4438 (fixed: https://github.com/puppetlabs/puppet/commit/e01c4dc924cd963ff6630008a5200fc6a2023b08#diff-c937cc584953271bb3d3b3c2cb141790R221) to support puppet < 4.1.0 and puppet < 3.8.1. + def call(scope, *args) + manipulated_args = [scope] + args + self.class.dispatcher.dispatch(self, scope, manipulated_args) end def deprecation_gen(scope, *args) call_function('deprecation', 'validate_ip_address', "This method is deprecated, please use the stdlib validate_legacy function, with Stdlib::Compat::Ip_Address. There is further documentation for validate_legacy function in the README.") diff --git a/lib/puppet/functions/validate_ipv4_address.rb b/lib/puppet/functions/validate_ipv4_address.rb index d501f7a..fe66ab3 100644 --- a/lib/puppet/functions/validate_ipv4_address.rb +++ b/lib/puppet/functions/validate_ipv4_address.rb @@ -1,7 +1,12 @@ -Puppet::Functions.create_function(:validate_ipv4_address, Puppet::Functions::InternalFunction) do +Puppet::Functions.create_function(:validate_ipv4_address) do dispatch :deprecation_gen do - scope_param - optional_repeated_param 'Any', :args + param 'Any', :scope + repeated_param 'Any', :args + end + # Workaround PUP-4438 (fixed: https://github.com/puppetlabs/puppet/commit/e01c4dc924cd963ff6630008a5200fc6a2023b08#diff-c937cc584953271bb3d3b3c2cb141790R221) to support puppet < 4.1.0 and puppet < 3.8.1. + def call(scope, *args) + manipulated_args = [scope] + args + self.class.dispatcher.dispatch(self, scope, manipulated_args) end def deprecation_gen(scope, *args) call_function('deprecation', 'validate_ipv4_address', "This method is deprecated, please use the stdlib validate_legacy function, with Stdlib::Compat::Ipv4_Address. There is further documentation for validate_legacy function in the README.") diff --git a/lib/puppet/functions/validate_ipv6_address.rb b/lib/puppet/functions/validate_ipv6_address.rb index aa8044f..7cc3cbd 100644 --- a/lib/puppet/functions/validate_ipv6_address.rb +++ b/lib/puppet/functions/validate_ipv6_address.rb @@ -1,7 +1,12 @@ -Puppet::Functions.create_function(:validate_ipv6_address, Puppet::Functions::InternalFunction) do +Puppet::Functions.create_function(:validate_ipv6_address) do dispatch :deprecation_gen do - scope_param - optional_repeated_param 'Any', :args + param 'Any', :scope + repeated_param 'Any', :args + end + # Workaround PUP-4438 (fixed: https://github.com/puppetlabs/puppet/commit/e01c4dc924cd963ff6630008a5200fc6a2023b08#diff-c937cc584953271bb3d3b3c2cb141790R221) to support puppet < 4.1.0 and puppet < 3.8.1. + def call(scope, *args) + manipulated_args = [scope] + args + self.class.dispatcher.dispatch(self, scope, manipulated_args) end def deprecation_gen(scope, *args) call_function('deprecation', 'validate_ipv6_address', "This method is deprecated, please use the stdlib validate_legacy function, with Stdlib::Compat::Ipv6_address. There is further documentation for validate_legacy function in the README.") diff --git a/lib/puppet/functions/validate_legacy.rb b/lib/puppet/functions/validate_legacy.rb index 3f50459..c9d1f56 100644 --- a/lib/puppet/functions/validate_legacy.rb +++ b/lib/puppet/functions/validate_legacy.rb @@ -1,20 +1,26 @@ -Puppet::Functions.create_function(:validate_legacy, Puppet::Functions::InternalFunction) do +Puppet::Functions.create_function(:validate_legacy) do # The function checks a value against both the target_type (new) and the previous_validation function (old). dispatch :validate_legacy do - scope_param + param 'Any', :scope param 'Type', :target_type param 'String', :function_name param 'Any', :value - optional_repeated_param 'Any', :args + repeated_param 'Any', :args end dispatch :validate_legacy_s do - scope_param + param 'Any', :scope param 'String', :type_string param 'String', :function_name param 'Any', :value - optional_repeated_param 'Any', :args + repeated_param 'Any', :args + end + + # Workaround PUP-4438 (fixed: https://github.com/puppetlabs/puppet/commit/e01c4dc924cd963ff6630008a5200fc6a2023b08#diff-c937cc584953271bb3d3b3c2cb141790R221) to support puppet < 4.1.0 and puppet < 3.8.1. + def call(scope, *args) + manipulated_args = [scope] + args + self.class.dispatcher.dispatch(self, scope, manipulated_args) end def validate_legacy_s(scope, type_string, *args) diff --git a/lib/puppet/functions/validate_numeric.rb b/lib/puppet/functions/validate_numeric.rb index 7db5c90..3052d35 100644 --- a/lib/puppet/functions/validate_numeric.rb +++ b/lib/puppet/functions/validate_numeric.rb @@ -1,7 +1,12 @@ -Puppet::Functions.create_function(:validate_numeric, Puppet::Functions::InternalFunction) do +Puppet::Functions.create_function(:validate_numeric) do dispatch :deprecation_gen do - scope_param - optional_repeated_param 'Any', :args + param 'Any', :scope + repeated_param 'Any', :args + end + # Workaround PUP-4438 (fixed: https://github.com/puppetlabs/puppet/commit/e01c4dc924cd963ff6630008a5200fc6a2023b08#diff-c937cc584953271bb3d3b3c2cb141790R221) to support puppet < 4.1.0 and puppet < 3.8.1. + def call(scope, *args) + manipulated_args = [scope] + args + self.class.dispatcher.dispatch(self, scope, manipulated_args) end def deprecation_gen(scope, *args) call_function('deprecation', 'validate_numeric', "This method is deprecated, please use the stdlib validate_legacy function, with Stdlib::Compat::Numeric. There is further documentation for validate_legacy function in the README.") diff --git a/lib/puppet/functions/validate_re.rb b/lib/puppet/functions/validate_re.rb index ae5d9f1..19443a8 100644 --- a/lib/puppet/functions/validate_re.rb +++ b/lib/puppet/functions/validate_re.rb @@ -1,7 +1,12 @@ -Puppet::Functions.create_function(:validate_re, Puppet::Functions::InternalFunction) do +Puppet::Functions.create_function(:validate_re) do dispatch :deprecation_gen do - scope_param - optional_repeated_param 'Any', :args + param 'Any', :scope + repeated_param 'Any', :args + end + # Workaround PUP-4438 (fixed: https://github.com/puppetlabs/puppet/commit/e01c4dc924cd963ff6630008a5200fc6a2023b08#diff-c937cc584953271bb3d3b3c2cb141790R221) to support puppet < 4.1.0 and puppet < 3.8.1. + def call(scope, *args) + manipulated_args = [scope] + args + self.class.dispatcher.dispatch(self, scope, manipulated_args) end def deprecation_gen(scope, *args) call_function('deprecation', 'validate_re', "This method is deprecated, please use the stdlib validate_legacy function, with Pattern[]. There is further documentation for validate_legacy function in the README.") diff --git a/lib/puppet/functions/validate_slength.rb b/lib/puppet/functions/validate_slength.rb index c3c29a5..584232a 100644 --- a/lib/puppet/functions/validate_slength.rb +++ b/lib/puppet/functions/validate_slength.rb @@ -1,7 +1,12 @@ -Puppet::Functions.create_function(:validate_slength, Puppet::Functions::InternalFunction) do +Puppet::Functions.create_function(:validate_slength) do dispatch :deprecation_gen do - scope_param - optional_repeated_param 'Any', :args + param 'Any', :scope + repeated_param 'Any', :args + end + # Workaround PUP-4438 (fixed: https://github.com/puppetlabs/puppet/commit/e01c4dc924cd963ff6630008a5200fc6a2023b08#diff-c937cc584953271bb3d3b3c2cb141790R221) to support puppet < 4.1.0 and puppet < 3.8.1. + def call(scope, *args) + manipulated_args = [scope] + args + self.class.dispatcher.dispatch(self, scope, manipulated_args) end def deprecation_gen(scope, *args) call_function('deprecation', 'validate_slength', "This method is deprecated, please use the stdlib validate_legacy function, with String[]. There is further documentation for validate_legacy function in the README.") diff --git a/lib/puppet/functions/validate_string.rb b/lib/puppet/functions/validate_string.rb index 9b0b731..91ff004 100644 --- a/lib/puppet/functions/validate_string.rb +++ b/lib/puppet/functions/validate_string.rb @@ -1,7 +1,12 @@ -Puppet::Functions.create_function(:validate_string, Puppet::Functions::InternalFunction) do +Puppet::Functions.create_function(:validate_string) do dispatch :deprecation_gen do - scope_param - optional_repeated_param 'Any', :args + param 'Any', :scope + repeated_param 'Any', :args + end + # Workaround PUP-4438 (fixed: https://github.com/puppetlabs/puppet/commit/e01c4dc924cd963ff6630008a5200fc6a2023b08#diff-c937cc584953271bb3d3b3c2cb141790R221) to support puppet < 4.1.0 and puppet < 3.8.1. + def call(scope, *args) + manipulated_args = [scope] + args + self.class.dispatcher.dispatch(self, scope, manipulated_args) end def deprecation_gen(scope, *args) call_function('deprecation', 'validate_string', "This method is deprecated, please use the stdlib validate_legacy function, with Stdlib::Compat::String. There is further documentation for validate_legacy function in the README.") -- cgit v1.2.3 From a0f86644cd254697b4c875a7a8e34fbb1010cf3a Mon Sep 17 00:00:00 2001 From: David Schmitt Date: Wed, 12 Oct 2016 16:11:02 +0100 Subject: (MODULES-3969) Update getvar to work on ruby 1.8.7 --- lib/puppet/parser/functions/getvar.rb | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/lib/puppet/parser/functions/getvar.rb b/lib/puppet/parser/functions/getvar.rb index aa6edbb..3af8d48 100644 --- a/lib/puppet/parser/functions/getvar.rb +++ b/lib/puppet/parser/functions/getvar.rb @@ -20,11 +20,13 @@ module Puppet::Parser::Functions end begin + result = nil catch(:undefined_variable) do - return self.lookupvar("#{args[0]}") + result = self.lookupvar("#{args[0]}") end - - nil # throw was caught + + # avoid relying on incosistent behaviour around ruby return values from catch + result rescue Puppet::ParseError # Eat the exception if strict_variables = true is set end -- cgit v1.2.3 From 1d75813d626a27704242bf12810a7cb79e2b0f59 Mon Sep 17 00:00:00 2001 From: David Schmitt Date: Wed, 12 Oct 2016 16:21:22 +0100 Subject: Update CHANGELOG --- CHANGELOG.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e9f79f6..9157b2d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,13 @@ This bugfix release addresses the `undefined method 'optional_repeated_param'` e It also improves the user experience around function deprecations by emitting one warning per function(-name) instead of only one deprecation overall. This allows users to identify all deprecated functions used in one agent run, with less back-and-forth. -Finally, this release adds additional Puppet 4 overrides for the `is_` counterparts of the deprecated functions to emit the deprecations warnings in all cases. +#### Bugfixes + +* Emit deprecations warnings for each function, instead of once per process. (MODULES-3961) +* Use a universally available API for the v4 deprecation stubs of `is_*` and `validate_*`. (MODULES-3962) +* Make `getvar()` compatible to ruby 1.8.7. (MODULES-3969) +* Add v4 deprecation stubs for the `is_` counterparts of the deprecated functions to emit the deprecations warnings in all cases. + ## Supported Release 4.13.0 ### Summary -- cgit v1.2.3 From f947fce65e967fc95d71feb44b9e2a53c2b93a03 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20Mo=CC=88ding?= Date: Fri, 14 Oct 2016 16:45:13 +0200 Subject: Fix incorrect environment variable name in README The README references the environment variable `STDLIB_LOG_DEPRECATION` while the code uses `STDLIB_LOG_DEPRECATIONS` (note the trailing S). --- README.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.markdown b/README.markdown index c0b3155..b41039d 100644 --- a/README.markdown +++ b/README.markdown @@ -358,7 +358,7 @@ deprecation(key, message) The Puppet settings '[disable_warnings](https://docs.puppet.com/puppet/latest/reference/configuration.html#disablewarnings)', '[max_deprecations](https://docs.puppet.com/puppet/latest/reference/configuration.html#maxdeprecations)', and '[strict](https://docs.puppet.com/puppet/latest/reference/configuration.html#strict)' affect this function. Set 'strict' to `error` to fail immediately with the deprecation message, `off` to output emit no messages at all, or `warning` (default) to log all warnings. -Additionally you can set the environment variable `STDLIB_LOG_DEPRECATION` to decide whether or not to log deprecation warnings: if this environment variable is set to `true`, the functions log a warning, if it is set to `false`, no warnings are logged. If no value is set at all, Puppet 4 will emit warnings, while Puppet 3 will not. Using this setting is especially useful for automated tests to avoid flooding your logs before you are ready to migrate. +Additionally you can set the environment variable `STDLIB_LOG_DEPRECATIONS` to decide whether or not to log deprecation warnings: if this environment variable is set to `true`, the functions log a warning, if it is set to `false`, no warnings are logged. If no value is set at all, Puppet 4 will emit warnings, while Puppet 3 will not. Using this setting is especially useful for automated tests to avoid flooding your logs before you are ready to migrate. *Type*: String, String. -- cgit v1.2.3 From 3742bd6f464dde2c6d253d6ed3cbdbc6f671aec1 Mon Sep 17 00:00:00 2001 From: Paula McMaw Date: Tue, 25 Oct 2016 14:56:57 +0100 Subject: This is to pin ruby version to parallel_tests --- .sync.yml | 2 ++ .travis.yml | 3 --- Gemfile | 3 ++- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.sync.yml b/.sync.yml index 431b9d1..d80d54a 100644 --- a/.sync.yml +++ b/.sync.yml @@ -5,3 +5,5 @@ - 'spec/fixtures/manifests/site.pp' - 'spec/fixtures/modules/*' +spec/spec_helper.rb: + allow_deprecations: true diff --git a/.travis.yml b/.travis.yml index cf44471..4e549bf 100644 --- a/.travis.yml +++ b/.travis.yml @@ -28,9 +28,6 @@ matrix: - rvm: 2.1.5 bundler_args: --without system_tests env: PUPPET_GEM_VERSION="~> 3.0" FUTURE_PARSER="yes" - - rvm: 2.1.5 - bundler_args: --without system_tests - env: PUPPET_GEM_VERSION="~> 3.7.0" FUTURE_PARSER="yes" - rvm: 2.1.5 bundler_args: --without system_tests env: PUPPET_GEM_VERSION="~> 3.0" diff --git a/Gemfile b/Gemfile index 0a7542d..c8af871 100644 --- a/Gemfile +++ b/Gemfile @@ -26,7 +26,8 @@ group :development, :unit_tests do gem 'mocha', '< 1.2.0' gem 'rspec-puppet-facts' gem 'simplecov' - gem 'parallel_tests' + gem 'parallel_tests', '< 2.10.0' if RUBY_VERSION < '2.0.0' + gem 'parallel_tests' if RUBY_VERSION >= '2.0.0' gem 'rubocop', '0.41.2' if RUBY_VERSION < '2.0.0' gem 'rubocop' if RUBY_VERSION >= '2.0.0' gem 'rubocop-rspec', '~> 1.6' if RUBY_VERSION >= '2.3.0' -- cgit v1.2.3 From ea929418c6c539fe6aa6506e520c5fe8fe68559f Mon Sep 17 00:00:00 2001 From: David Schmitt Date: Tue, 25 Oct 2016 15:28:40 +0100 Subject: (MODULES-3980) Fix ipv4 regex validator This also updates all ipv4 tests to use the same test data for better comparability. Closes #676, #679 Fix-Originally-By: Nate Potter --- spec/aliases/ipv4_spec.rb | 14 ++------- spec/functions/is_ipv4_address_spec.rb | 20 +++++++------ spec/functions/validate_ipv4_address_spec.rb | 43 +++++++++------------------- spec/spec_helper_local.rb | 2 ++ spec/support/shared_data.rb | 38 ++++++++++++++++++++++++ types/compat/ipv4.pp | 2 +- 6 files changed, 67 insertions(+), 52 deletions(-) create mode 100644 spec/support/shared_data.rb diff --git a/spec/aliases/ipv4_spec.rb b/spec/aliases/ipv4_spec.rb index e767b45..210b4b1 100644 --- a/spec/aliases/ipv4_spec.rb +++ b/spec/aliases/ipv4_spec.rb @@ -3,12 +3,7 @@ require 'spec_helper' if Puppet.version.to_f >= 4.5 describe 'test::ipv4', type: :class do describe 'accepts ipv4 addresses' do - [ - '224.0.0.0', - '255.255.255.255', - '0.0.0.0', - '192.88.99.0' - ].each do |value| + SharedData::IPV4_PATTERNS.each do |value| describe value.inspect do let(:params) {{ value: value }} it { is_expected.to compile } @@ -16,12 +11,7 @@ if Puppet.version.to_f >= 4.5 end end describe 'rejects other values' do - [ - 'nope', - '77', - '4.4.4', - '2001:0db8:85a3:0000:0000:8a2e:0370:73342001:0db8:85a3:0000:0000:8a2e:0370:7334' - ].each do |value| + SharedData::IPV4_NEGATIVE_PATTERNS.each do |value| describe value.inspect do let(:params) {{ value: value }} it { is_expected.to compile.and_raise_error(/parameter 'value' expects a match for Stdlib::Compat::Ipv4/) } diff --git a/spec/functions/is_ipv4_address_spec.rb b/spec/functions/is_ipv4_address_spec.rb index e39d93b..985260c 100644 --- a/spec/functions/is_ipv4_address_spec.rb +++ b/spec/functions/is_ipv4_address_spec.rb @@ -1,15 +1,17 @@ require 'spec_helper' describe 'is_ipv4_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('1.2.3.4').and_return(true) } - it { is_expected.to run.with_params('1.2.3.255').and_return(true) } - it { is_expected.to run.with_params('1.2.3').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('one').and_return(false) } + + SharedData::IPV4_PATTERNS.each do |value| + it { is_expected.to run.with_params(value).and_return(true) } + end + + SharedData::IPV4_NEGATIVE_PATTERNS.each do |value| + it { is_expected.to run.with_params(value).and_return(false) } + end context 'Checking for deprecation warning', if: Puppet.version.to_f < 4.0 do after(:all) do @@ -19,12 +21,12 @@ describe 'is_ipv4_address' do it 'should display a single deprecation' do ENV['STDLIB_LOG_DEPRECATIONS'] = "true" scope.expects(:warning).with(includes('This method is deprecated')) - is_expected.to run.with_params('1.2.3.4').and_return(true) + is_expected.to run.with_params(SharedData::IPV4_PATTERNS.first).and_return(true) end it 'should display no warning for deprecation' do ENV['STDLIB_LOG_DEPRECATIONS'] = "false" scope.expects(:warning).with(includes('This method is deprecated')).never - is_expected.to run.with_params('1.2.3.4').and_return(true) + is_expected.to run.with_params(SharedData::IPV4_PATTERNS.first).and_return(true) end end end diff --git a/spec/functions/validate_ipv4_address_spec.rb b/spec/functions/validate_ipv4_address_spec.rb index d221793..6e4ca05 100755 --- a/spec/functions/validate_ipv4_address_spec.rb +++ b/spec/functions/validate_ipv4_address_spec.rb @@ -15,44 +15,27 @@ describe 'validate_ipv4_address' do it 'should display a single deprecation' do ENV['STDLIB_LOG_DEPRECATIONS'] = "true" scope.expects(:warning).with(includes('This method is deprecated')) - is_expected.to run.with_params('1.2.3.4') + is_expected.to run.with_params(SharedData::IPV4_PATTERNS.first) end it 'should display no warning for deprecation' do ENV['STDLIB_LOG_DEPRECATIONS'] = "false" scope.expects(:warning).with(includes('This method is deprecated')).never - is_expected.to run.with_params('1.2.3.4') + is_expected.to run.with_params(SharedData::IPV4_PATTERNS.first) end - end + end - describe 'valid inputs' do - it { is_expected.to run.with_params('0.0.0.0') } - it { is_expected.to run.with_params('8.8.8.8') } - it { is_expected.to run.with_params('127.0.0.1') } - it { is_expected.to run.with_params('10.10.10.10') } - it { is_expected.to run.with_params('194.232.104.150') } - it { is_expected.to run.with_params('244.24.24.24') } - it { is_expected.to run.with_params('255.255.255.255') } - it { is_expected.to run.with_params('1.2.3.4', '5.6.7.8') } - context 'with netmasks' do - it { is_expected.to run.with_params('8.8.8.8/0') } - it { is_expected.to run.with_params('8.8.8.8/16') } - it { is_expected.to run.with_params('8.8.8.8/32') } - it { is_expected.to run.with_params('8.8.8.8/255.255.0.0') } - end + SharedData::IPV4_PATTERNS.each do |value| + it { is_expected.to run.with_params(value) } + end + + SharedData::IPV4_NEGATIVE_PATTERNS.each do |value| + it { is_expected.to run.with_params(value).and_raise_error(Puppet::ParseError, /is not a valid IPv4/) } 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 IPv4/) } - it { is_expected.to run.with_params('0.0.0').and_raise_error(Puppet::ParseError, /is not a valid IPv4/) } - it { is_expected.to run.with_params('0.0.0.256').and_raise_error(Puppet::ParseError, /is not a valid IPv4/) } - it { is_expected.to run.with_params('0.0.0.0.0').and_raise_error(Puppet::ParseError, /is not a valid IPv4/) } - it { is_expected.to run.with_params('affe::beef').and_raise_error(Puppet::ParseError, /is not a valid IPv4/) } - it { is_expected.to run.with_params('1.2.3.4', {}).and_raise_error(Puppet::ParseError, /is not a string/) } - it { is_expected.to run.with_params('1.2.3.4', 1).and_raise_error(Puppet::ParseError, /is not a string/) } - it { is_expected.to run.with_params('1.2.3.4', true).and_raise_error(Puppet::ParseError, /is not a string/) } - it { is_expected.to run.with_params('1.2.3.4', 'one').and_raise_error(Puppet::ParseError, /is not a valid IPv4/) } + [ {}, [], 1, true ].each do |invalid| + it { is_expected.to run.with_params(invalid).and_raise_error(Puppet::ParseError, /is not a string/) } + it { is_expected.to run.with_params(SharedData::IPV4_PATTERNS.first, invalid).and_raise_error(Puppet::ParseError, /is not a string/) } + end end end diff --git a/spec/spec_helper_local.rb b/spec/spec_helper_local.rb index 023a862..616490c 100644 --- a/spec/spec_helper_local.rb +++ b/spec/spec_helper_local.rb @@ -1,3 +1,5 @@ +# automatically load any shared examples or contexts +Dir["./spec/support/**/*.rb"].sort.each { |f| require f } # hack to enable all the expect syntax (like allow_any_instance_of) in rspec-puppet examples RSpec::Mocks::Syntax.enable_expect(RSpec::Puppet::ManifestMatchers) diff --git a/spec/support/shared_data.rb b/spec/support/shared_data.rb new file mode 100644 index 0000000..ea9b7a0 --- /dev/null +++ b/spec/support/shared_data.rb @@ -0,0 +1,38 @@ +module SharedData + IPV4_PATTERNS = [ + '0.0.0.0', + '1.2.3.4', + '10.10.10.10', + '127.0.0.1', + '192.88.99.0', + '194.232.104.150', + '224.0.0.0', + '244.24.24.24', + '255.255.255.255', + '8.8.8.8', + '8.8.8.8/0', + '8.8.8.8/16', + '8.8.8.8/255.255.0.0', + '8.8.8.8/32', + ] + IPV4_NEGATIVE_PATTERNS = [ + '', + '0000', + '0.0.0.0.', + '0.0.0.0./0.0.0.0.', + '0.0.0.0./1', + '0.0.0.0.0', + '0.0.0.0/0.0.0.0.', + '0.0.0.256', + '0.0.0', + '1.2.3.4.5', + '1.2.3', + '10.010.10.10', + '2001:0db8:85a3:0000:0000:8a2e:0370:73342001:0db8:85a3:0000:0000:8a2e:0370:7334', + '4.4.4', + '77', + '9999.9999.9999.9999', + 'affe::beef', + 'nope', + ] +end diff --git a/types/compat/ipv4.pp b/types/compat/ipv4.pp index 1d72ebd..a0ba0d6 100644 --- a/types/compat/ipv4.pp +++ b/types/compat/ipv4.pp @@ -1,2 +1,2 @@ # Emulate the validate_ipv4_address and is_ipv4_address functions -type Stdlib::Compat::Ipv4 = Pattern[/^(\d+)\.(\d+)\.(\d+)\.(\d+)$/] +type Stdlib::Compat::Ipv4 = Pattern[/^((([0-9](?!\d)|[1-9][0-9](?!\d)|1[0-9]{2}(?!\d)|2[0-4][0-9](?!\d)|25[0-5](?!\d))[.]){3}([0-9](?!\d)|[1-9][0-9](?!\d)|1[0-9]{2}(?!\d)|2[0-4][0-9](?!\d)|25[0-5](?!\d)))(\/((([0-9](?!\d)|[1-9][0-9](?!\d)|1[0-9]{2}(?!\d)|2[0-4][0-9](?!\d)|25[0-5](?!\d))[.]){3}([0-9](?!\d)|[1-9][0-9](?!\d)|1[0-9]{2}(?!\d)|2[0-4][0-9](?!\d)|25[0-5](?!\d))|[0-9]+))?$/] -- cgit v1.2.3 From 5d1cbf33978c21f206b9757d1c8235130fdbce19 Mon Sep 17 00:00:00 2001 From: Chris Clonch Date: Mon, 24 Oct 2016 15:31:15 -0400 Subject: Remove leading spaces This corrects puppet-linting error. --- types/compat/bool.pp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/types/compat/bool.pp b/types/compat/bool.pp index dda5f4b..5d8e27e 100644 --- a/types/compat/bool.pp +++ b/types/compat/bool.pp @@ -1,2 +1,2 @@ - # Emulate the is_bool and validate_bool functions - type Stdlib::Compat::Bool = Boolean +# Emulate the is_bool and validate_bool functions +type Stdlib::Compat::Bool = Boolean -- cgit v1.2.3 From a7a947c9773fee809a48f52aef30d431a04bab3f Mon Sep 17 00:00:00 2001 From: Helen Campbell Date: Mon, 7 Nov 2016 17:31:15 +0000 Subject: Addition of 4.6 and 4.7 travis cells --- .sync.yml | 9 +++++++++ .travis.yml | 6 ++++++ 2 files changed, 15 insertions(+) diff --git a/.sync.yml b/.sync.yml index d80d54a..34cfb5f 100644 --- a/.sync.yml +++ b/.sync.yml @@ -7,3 +7,12 @@ spec/spec_helper.rb: allow_deprecations: true + +.travis.yml: + extras: +   - rvm: 2.1.9 +     env: PUPPET_GEM_VERSION="~> 4.6.0" +     bundler_args: --without system_tests +   - rvm: 2.1.9 +     env: PUPPET_GEM_VERSION="~> 4.7.0" +     bundler_args: --without system_tests diff --git a/.travis.yml b/.travis.yml index 4e549bf..0cde21d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -34,5 +34,11 @@ matrix: - rvm: 1.9.3 bundler_args: --without system_tests env: PUPPET_GEM_VERSION="~> 3.0" + - rvm: 2.1.9 + bundler_args: --without system_tests + env: PUPPET_GEM_VERSION="~> 4.6.0" + - rvm: 2.1.9 + bundler_args: --without system_tests + env: PUPPET_GEM_VERSION="~> 4.7.0" notifications: email: false -- cgit v1.2.3 From b979e34b05652cbfb4e9ca7adc29ba9a01081437 Mon Sep 17 00:00:00 2001 From: Simon Beirnaert Date: Tue, 8 Nov 2016 08:37:12 +0100 Subject: (MODULES-3829) Use .dup to duplicate classes for modification. This function otherwise fails during `puppet preview` on Puppet 3.8.X systems. --- lib/puppet/parser/functions/ensure_resources.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/puppet/parser/functions/ensure_resources.rb b/lib/puppet/parser/functions/ensure_resources.rb index 30d57a8..b3c51e6 100644 --- a/lib/puppet/parser/functions/ensure_resources.rb +++ b/lib/puppet/parser/functions/ensure_resources.rb @@ -36,7 +36,7 @@ ENDOFDOC params ||= {} if title.is_a?(Hash) - resource_hash = Hash(title) + resource_hash = title.dup resources = resource_hash.keys Puppet::Parser::Functions.function(:ensure_resource) -- cgit v1.2.3 From ef3415e6e78452bef1fe8c7891d1f2794d2b794a Mon Sep 17 00:00:00 2001 From: David Schmitt Date: Thu, 10 Nov 2016 12:22:15 +0000 Subject: Fix spec failures on puppet 4.8 These were caused by a change in the tested error message. --- spec/functions/validate_legacy_spec.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/functions/validate_legacy_spec.rb b/spec/functions/validate_legacy_spec.rb index 45089ef..50cb317 100644 --- a/spec/functions/validate_legacy_spec.rb +++ b/spec/functions/validate_legacy_spec.rb @@ -28,7 +28,7 @@ if Puppet.version.to_f >= 4.0 describe 'when failing the type assertion and passing the previous validation' do before do scope.expects(:function_validate_foo).with(['5']).once - subject.func.expects(:call_function).with('deprecation', 'validate_legacy', includes('expected an Integer value')).once + subject.func.expects(:call_function).with('deprecation', 'validate_legacy', includes('Integer')).once end it 'passes with a deprecation message' do is_expected.to run.with_params('Integer', 'validate_foo', '5') @@ -38,7 +38,7 @@ if Puppet.version.to_f >= 4.0 describe 'when failing the type assertion and failing the previous validation' do before do scope.expects(:function_validate_foo).with(['5']).raises(Puppet::ParseError, 'foo').once - subject.func.expects(:call_function).with('fail', includes('expected an Integer value')).once + subject.func.expects(:call_function).with('fail', includes('Integer')).once end it 'fails with a helpful message' do is_expected.to run.with_params('Integer', 'validate_foo', '5') -- cgit v1.2.3 From f81ba549b73f0d752be1b4185c73818f791ab2f6 Mon Sep 17 00:00:00 2001 From: Reid Vandewiele Date: Wed, 29 Jun 2016 15:54:20 +0100 Subject: Add puppet_server fact to return agent's server It is frequently useful to configure an agent to retrieve a resource from it's configured master, or make further configuration adjustments to itself based on what server it's using. Similar to the rationale for stdlib providing a puppet_vardir fact, this commit adds a puppet_server fact. Note that the closest equivalent available today is $settings::server, which returns only the MASTER's configured server, not the AGENT's. This makes $settings::server unreliable, and not useful in a multi-master deployment or a deployment involving a load balancer. --- lib/facter/puppet_settings.rb | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/lib/facter/puppet_settings.rb b/lib/facter/puppet_settings.rb index e6a066a..eac9e97 100644 --- a/lib/facter/puppet_settings.rb +++ b/lib/facter/puppet_settings.rb @@ -33,3 +33,11 @@ Facter.add(:puppet_environmentpath) do end end end + +Facter.add(:puppet_server) do + setcode do + Facter::Util::PuppetSettings.with_puppet do + Puppet[:server] + end + end +end -- cgit v1.2.3 From 6f67240657005e7bf2586ba099607cc8316746b2 Mon Sep 17 00:00:00 2001 From: Hunter Haugen Date: Wed, 9 Nov 2016 12:14:38 -0800 Subject: (MODULES-3704) Update gemfile template to be identical --- .travis.yml | 3 ++ Gemfile | 103 +++++++++++++++++++++++++++++++++++++++--------------------- 2 files changed, 71 insertions(+), 35 deletions(-) diff --git a/.travis.yml b/.travis.yml index 0cde21d..990ad45 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,6 +4,9 @@ sudo: false language: ruby cache: bundler script: "bundle exec rake validate lint spec" +#Inserting below due to the following issue: https://github.com/travis-ci/travis-ci/issues/3531#issuecomment-88311203 +before_install: + - gem update bundler matrix: fast_finish: true include: diff --git a/Gemfile b/Gemfile index c8af871..8871c66 100644 --- a/Gemfile +++ b/Gemfile @@ -2,50 +2,83 @@ source ENV['GEM_SOURCE'] || "https://rubygems.org" -def location_from_env(env, default_location = []) - if location = ENV[env] - if location =~ /^((?:git|https?)[:@][^#]*)#(.*)/ - [{ :git => $1, :branch => $2, :require => false }] - elsif location =~ /^file:\/\/(.*)/ - ['>= 0', { :path => File.expand_path($1), :require => false }] - else - [location, { :require => false }] - end +# Determines what type of gem is requested based on place_or_version. +def gem_type(place_or_version) + if place_or_version =~ /^git:/ + :git + elsif place_or_version =~ /^file:/ + :file else - default_location + :gem end end -group :development, :unit_tests do - gem 'metadata-json-lint' - gem 'puppet_facts' - gem 'puppet-blacksmith', '>= 3.4.0' - gem 'puppetlabs_spec_helper', '>= 1.2.1' - gem 'rspec-puppet', '>= 2.3.2', :git => 'https://github.com/rodjek/rspec-puppet.git', :branch => 'fb27c533e2664057fba4b73d0bd902a946abfce0' - # the newly released mocha 1.2.0 causes hangs during spec testing. See MODULES-3958 for a long-term solution - gem 'mocha', '< 1.2.0' - gem 'rspec-puppet-facts' - gem 'simplecov' - gem 'parallel_tests', '< 2.10.0' if RUBY_VERSION < '2.0.0' - gem 'parallel_tests' if RUBY_VERSION >= '2.0.0' - gem 'rubocop', '0.41.2' if RUBY_VERSION < '2.0.0' - gem 'rubocop' if RUBY_VERSION >= '2.0.0' - gem 'rubocop-rspec', '~> 1.6' if RUBY_VERSION >= '2.3.0' - gem 'json_pure', '<= 2.0.1' if RUBY_VERSION < '2.0.0' +# Find a location or specific version for a gem. place_or_version can be a +# version, which is most often used. It can also be git, which is specified as +# `git://somewhere.git#branch`. You can also use a file source location, which +# is specified as `file://some/location/on/disk`. +def location_for(place_or_version, fake_version = nil) + if place_or_version =~ /^(git[:@][^#]*)#(.*)/ + [fake_version, { :git => $1, :branch => $2, :require => false }].compact + elsif place_or_version =~ /^file:\/\/(.*)/ + ['>= 0', { :path => File.expand_path($1), :require => false }] + else + [place_or_version, { :require => false }] + end +end + +# Used for gem conditionals +supports_windows = false + +group :development do + gem 'puppet-lint', :require => false + gem 'metadata-json-lint', :require => false + gem 'puppet_facts', :require => false + gem 'puppet-blacksmith', '>= 3.4.0', :require => false, :platforms => 'ruby' + gem 'puppetlabs_spec_helper', '>= 1.2.1', :require => false + gem 'rspec-puppet', '>= 2.3.2', :require => false + gem 'rspec-puppet-facts', :require => false + gem 'mocha', '< 1.2.0', :require => false + gem 'simplecov', :require => false + gem 'parallel_tests', '< 2.10.0', :require => false if Gem::Version.new(RUBY_VERSION) < Gem::Version.new('2.0.0') + gem 'parallel_tests', :require => false if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('2.0.0') + gem 'rubocop', '0.41.2', :require => false if Gem::Version.new(RUBY_VERSION) < Gem::Version.new('2.0.0') + gem 'rubocop', :require => false if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('2.0.0') + gem 'rubocop-rspec', '~> 1.6', :require => false if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('2.3.0') + gem 'pry', :require => false + gem 'json_pure', '<= 2.0.1', :require => false if Gem::Version.new(RUBY_VERSION) < Gem::Version.new('2.0.0') end + group :system_tests do - gem 'beaker', *location_from_env('BEAKER_VERSION', []) if RUBY_VERSION >= '2.3.0' - gem 'beaker', *location_from_env('BEAKER_VERSION', ['< 3']) if RUBY_VERSION < '2.3.0' - gem 'beaker-rspec', *location_from_env('BEAKER_RSPEC_VERSION', ['>= 3.4']) - gem 'serverspec' - gem 'beaker-puppet_install_helper' - gem 'master_manipulator' - gem 'beaker-hostgenerator', *location_from_env('BEAKER_HOSTGENERATOR_VERSION', []) + gem 'beaker', *location_for(ENV['BEAKER_VERSION'] || '~> 2.20') if supports_windows + gem 'beaker', *location_for(ENV['BEAKER_VERSION']) if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('2.3.0') and ! supports_windows + gem 'beaker', *location_for(ENV['BEAKER_VERSION'] || '< 3') if Gem::Version.new(RUBY_VERSION) < Gem::Version.new('2.3.0') and ! supports_windows + gem 'beaker-pe', :require => false if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('2.3.0') + gem 'beaker-rspec', *location_for(ENV['BEAKER_RSPEC_VERSION'] || '>= 3.4') if ! supports_windows + gem 'beaker-rspec', *location_for(ENV['BEAKER_RSPEC_VERSION'] || '~> 5.1') if supports_windows + gem 'beaker-puppet_install_helper', :require => false + gem 'master_manipulator', :require => false + gem 'beaker-hostgenerator', *location_for(ENV['BEAKER_HOSTGENERATOR_VERSION']) end -gem 'facter', *location_from_env('FACTER_GEM_VERSION') -gem 'puppet', *location_from_env('PUPPET_GEM_VERSION') +gem 'puppet', *location_for(ENV['PUPPET_GEM_VERSION']) +# Only explicitly specify Facter/Hiera if a version has been specified. +# Otherwise it can lead to strange bundler behavior. If you are seeing weird +# gem resolution behavior, try setting `DEBUG_RESOLVER` environment variable +# to `1` and then run bundle install. +gem 'facter', *location_for(ENV['FACTER_GEM_VERSION']) if ENV['FACTER_GEM_VERSION'] +gem 'hiera', *location_for(ENV['HIERA_GEM_VERSION']) if ENV['HIERA_GEM_VERSION'] + + +# Evaluate Gemfile.local if it exists if File.exists? "#{__FILE__}.local" eval(File.read("#{__FILE__}.local"), binding) end + +# Evaluate ~/.gemfile if it exists +if File.exists?(File.join(Dir.home, '.gemfile')) + eval(File.read(File.join(Dir.home, '.gemfile')), binding) +end + +# vim:ft=ruby -- cgit v1.2.3 From 4f61f3cc7f3f6051536c2ef1e88e39848773b133 Mon Sep 17 00:00:00 2001 From: jbondpdx Date: Mon, 14 Nov 2016 15:12:20 -0800 Subject: MODULES-4008: clarify deprecation language --- README.markdown | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 55 insertions(+), 7 deletions(-) diff --git a/README.markdown b/README.markdown index cc29af9..821deb0 100644 --- a/README.markdown +++ b/README.markdown @@ -712,46 +712,68 @@ See the [`assert_type()`](https://docs.puppetlabs.com/references/latest/function #### `is_absolute_path` +**Deprecated. Will be removed in a future version of stdlib. See [`validate_legacy`](#validatelegacy).** + Returns 'true' if the given path is absolute. *Type*: rvalue. #### `is_array` +**Deprecated. Will be removed in a future version of stdlib. See [`validate_legacy`](#validatelegacy).** + Returns 'true' if the variable passed to this function is an array. *Type*: rvalue. #### `is_bool` +**Deprecated. Will be removed in a future version of stdlib. See [`validate_legacy`](#validatelegacy).** + Returns 'true' if the variable passed to this function is a boolean. *Type*: rvalue. #### `is_domain_name` +**Deprecated. Will be removed in a future version of stdlib. See [`validate_legacy`](#validatelegacy).** + Returns 'true' if the string passed to this function is a syntactically correct domain name. *Type*: rvalue. #### `is_float` +**Deprecated. Will be removed in a future version of stdlib. See [`validate_legacy`](#validatelegacy).** + Returns 'true' if the variable passed to this function is a float. *Type*: rvalue. #### `is_function_available` +**Deprecated. Will be removed in a future version of stdlib. See [`validate_legacy`](#validatelegacy).** + Accepts a string as an argument and determines whether the Puppet runtime has access to a function by that name. It returns 'true' if the function exists, 'false' if not. *Type*: rvalue. #### `is_hash` +**Deprecated. Will be removed in a future version of stdlib. See [`validate_legacy`](#validatelegacy).** + Returns 'true' if the variable passed to this function is a hash. *Type*: rvalue. #### `is_integer` +**Deprecated. Will be removed in a future version of stdlib. See [`validate_legacy`](#validatelegacy).** + Returns 'true' if the variable returned to this string is an integer. *Type*: rvalue. #### `is_ip_address` +**Deprecated. Will be removed in a future version of stdlib. See [`validate_legacy`](#validatelegacy).** + Returns 'true' if the string passed to this function is a valid IP address. *Type*: rvalue. #### `is_ipv6_address` +**Deprecated. Will be removed in a future version of stdlib. See [`validate_legacy`](#validatelegacy).** + Returns 'true' if the string passed to this function is a valid IPv6 address. *Type*: rvalue. #### `is_ipv4_address` +**Deprecated. Will be removed in a future version of stdlib. See [`validate_legacy`](#validatelegacy).** + Returns 'true' if the string passed to this function is a valid IPv4 address. *Type*: rvalue. #### `is_mac_address` @@ -760,10 +782,14 @@ Returns 'true' if the string passed to this function is a valid MAC address. *Ty #### `is_numeric` +**Deprecated. Will be removed in a future version of stdlib. See [`validate_legacy`](#validatelegacy).** + Returns 'true' if the variable passed to this function is a number. *Type*: rvalue. #### `is_string` +**Deprecated. Will be removed in a future version of stdlib. See [`validate_legacy`](#validatelegacy).** + Returns 'true' if the variable passed to this function is a string. *Type*: rvalue. #### `join` @@ -1228,6 +1254,8 @@ validate_absolute_path($undefined) #### `validate_array` +**Deprecated. Will be removed in a future version of stdlib. See [`validate_legacy`](#validatelegacy).** + Validates that all passed values are array data structures. Aborts catalog compilation if any value fails this check. The following values pass: @@ -1276,6 +1304,8 @@ validate_augeas($sudoerscontent, 'Sudoers.lns', [], 'Failed to validate sudoers #### `validate_bool` +**Deprecated. Will be removed in a future version of stdlib. See [`validate_legacy`](#validatelegacy).** + Validates that all passed values are either true or false. Aborts catalog compilation if any value fails this check. The following values will pass: @@ -1316,6 +1346,8 @@ validate_cmd($haproxycontent, '/usr/sbin/haproxy -f % -c', 'Haproxy failed to va #### `validate_hash` +**Deprecated. Will be removed in a future version of stdlib. See [`validate_legacy`](#validatelegacy).** + Validates that all passed values are hash data structures. Aborts catalog compilation if any value fails this check. The following values will pass: @@ -1338,6 +1370,8 @@ Validates that all passed values are hash data structures. Aborts catalog compil #### `validate_integer` +**Deprecated. Will be removed in a future version of stdlib. See [`validate_legacy`](#validatelegacy).** + Validates that the first argument is an integer (or an array of integers). Aborts catalog compilation if any of the checks fail. The second argument is optional and passes a maximum. (All elements of) the first argument has to be less or equal to this max. @@ -1396,6 +1430,8 @@ Validates that the first argument is an integer (or an array of integers). Abort #### `validate_ip_address` +**Deprecated. Will be removed in a future version of stdlib. See [`validate_legacy`](#validatelegacy).** + Validates that the argument is an IP address, regardless of it is an IPv4 or an IPv6 address. It also validates IP address with netmask. The argument must be given as a string. @@ -1444,24 +1480,28 @@ validate_legacy("Optional[String]", "validate_re", "Value to be validated", ["." This function supports updating modules from Puppet 3 style argument validation (using the stdlib `validate_*` functions) to Puppet 4 data types, without breaking functionality for those depending on Puppet 3 style validation. -> Note: This function relies on internal APIs from Puppet 4.4.0 (PE 2016.1) onwards, and doesn't work on earlier versions. +> Note: This function is compatible only with Puppet 4.4.0 (PE 2016.1) and later. ##### For module users -If you are running Puppet 4 and receiving deprecation warnings about `validate_*` functions, the `validate_legacy` function can help you find and resolve the deprecated code. +If you are running Puppet 4, the `validate_legacy` function can help you find and resolve deprecated Puppet 3 `validate_*` functions. These functions are deprecated as of stdlib version 4.13 and will be removed in a future version of stdlib. -In Puppet 3, the `validate_*` functions were the only way to easily check the types of class and defined type arguments. Some of the functions provided additional helpers like [validate_numeric](#validate_numeric), which unintentionally allowed not only numbers, but also arrays of numbers. Puppet 4 allows much better defined type checking using [data types](https://docs.puppet.com/puppet/latest/reference/lang_data.html), without such unintentional effects. The `validate_legacy` function makes these differences visible and makes it easier to move to the clearer Puppet 4 syntax. +Puppet 4 allows improved defined type checking using [data types](https://docs.puppet.com/puppet/latest/reference/lang_data.html). Data types avoid some of the problems with Puppet 3's `validate_*` functions, which could sometimes be inconsistent. For example, [validate_numeric](#validate_numeric) unintentionally allowed not only numbers, but also arrays of numbers or strings that looked like numbers. -Depending on the current state of development of the modules you use and the data you feed those modules, you'll encounter different messages: +If you run Puppet 4 and use modules with deprecated `validate_*` functions, you might encounter deprecation messages. The `validate_legacy` function makes these differences visible and makes it easier to move to the clearer Puppet 4 syntax. + +The deprecation messages you get can vary, depending on the modules and data that you use. These deprecation messages appear by default only in Puppet 4: * `Notice: Accepting previously invalid value for target type ''`: This message is informational only. You're using values that are allowed by the new type, but would have been invalid by the old validation function. * `Warning: This method is deprecated, please use the stdlib validate_legacy function`: The module has not yet upgraded to `validate_legacy`. Use the [deprecation](#deprecation) options to silence warnings for now, or submit a fix with the module's developer. See the information [for module developers](#for-module-developers) below for how to fix the issue. -* `Warning: validate_legacy() expected value, got _`: Your code passes a value that was accepted by the Puppet 3 style validation, but will not be accepted by the next version of the module. Most often, you can fix this by removing quotes from numbers or booleans. +* `Warning: validate_legacy() expected value, got _`: Your code passes a value that was accepted by the Puppet 3-style validation, but will not be accepted by the next version of the module. Most often, you can fix this by removing quotes from numbers or booleans. * `Error: Evaluation Error: Error while evaluating a Resource Statement, Evaluation Error: Error while evaluating a Function Call, validate_legacy() expected value, got `: Your code passes a value that is not acceptable to either the new or the old style validation. ##### For module developers -Many `validate_*` functions have surprising holes in their validation. For example, [validate_numeric](#validate_numeric) allows not only numbers, but also arrays of numbers or strings that look like numbers, without giving you any control over the specifics. In contrast, Puppet 4 [data types](https://docs.puppet.com/puppet/latest/reference/lang_data.html) allows you to choose between `Numeric`, `Array[Numeric]`, or `Optional[Numeric]`. The `validate_legacy` function helps you move from Puppet 3 style validation to Puppet 4 validation without breaking functionality your module's users depend on. +The `validate_legacy` function helps you move from Puppet 3 style validation to Puppet 4 validation without breaking functionality your module's users depend on. + +Moving to Puppet 4 type validation allows much better defined type checking using [data types](https://docs.puppet.com/puppet/latest/reference/lang_data.html). Many of Puppet 3's `validate_*` functions have surprising holes in their validation. For example, [validate_numeric](#validate_numeric) allows not only numbers, but also arrays of numbers or strings that look like numbers, without giving you any control over the specifics. For each parameter of your classes and defined types, choose a new Puppet 4 data type to use. In most cases, the new data type allows a different set of values than the original `validate_*` function. The situation then looks like this: @@ -1504,6 +1544,8 @@ Always note such changes in your CHANGELOG and README. #### `validate_numeric` +**Deprecated. Will be removed in a future version of stdlib. See [`validate_legacy`](#validatelegacy).** + Validates that the first argument is a numeric value (or an array or string of numeric values). Aborts catalog compilation if any of the checks fail. The second argument is optional and passes a maximum. (All elements of) the first argument has to be less or equal to this max. @@ -1520,6 +1562,8 @@ Validates that the first argument is a numeric value (or an array or string of n #### `validate_re` +**Deprecated. Will be removed in a future version of stdlib. See [`validate_legacy`](#validatelegacy).** + Performs simple validation of a string against one or more regular expressions. The first argument of this function should be the string to test, and the second argument should be a stringified regular expression (without the // delimiters) or an array of regular expressions. If none of the regular expressions match the string passed in, compilation aborts with a parse error. @@ -1554,6 +1598,8 @@ test, and the second argument should be a stringified regular expression (withou #### `validate_slength` +**Deprecated. Will be removed in a future version of stdlib. See [`validate_legacy`](#validatelegacy).** + Validates that the first argument is a string (or an array of strings), and is less than or equal to the length of the second argument. It fails if the first argument is not a string or array of strings, or if the second argument is not convertable to a number. Optionally, a minimum string length can be given as the third argument. The following values pass: @@ -1576,6 +1622,8 @@ Validates that the first argument is a string (or an array of strings), and is l #### `validate_string` +**Deprecated. Will be removed in a future version of stdlib. See [`validate_legacy`](#validatelegacy).** + Validates that all passed values are string data structures. Aborts catalog compilation if any value fails this check. The following values pass: @@ -1646,7 +1694,7 @@ Takes one element from first array given and merges corresponding elements from As of Puppet Enterprise 3.7, the stdlib module is no longer included in PE. PE users should install the most recent release of stdlib for compatibility with Puppet modules. -###Version Compatibility +### Version Compatibility Versions | Puppet 2.6 | Puppet 2.7 | Puppet 3.x | Puppet 4.x | :---------------|:-----:|:---:|:---:|:----: -- cgit v1.2.3 From 88ed19d149ccfe5e94daf714c2ec98205bb35932 Mon Sep 17 00:00:00 2001 From: Ian Norton Date: Mon, 21 Nov 2016 09:17:01 +0000 Subject: Fixing broken link to #validate_legacy docs --- README.markdown | 44 ++++++++++++++++++++++---------------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/README.markdown b/README.markdown index 821deb0..3e937b1 100644 --- a/README.markdown +++ b/README.markdown @@ -712,67 +712,67 @@ See the [`assert_type()`](https://docs.puppetlabs.com/references/latest/function #### `is_absolute_path` -**Deprecated. Will be removed in a future version of stdlib. See [`validate_legacy`](#validatelegacy).** +**Deprecated. Will be removed in a future version of stdlib. See [`validate_legacy`](#validate_legacy).** Returns 'true' if the given path is absolute. *Type*: rvalue. #### `is_array` -**Deprecated. Will be removed in a future version of stdlib. See [`validate_legacy`](#validatelegacy).** +**Deprecated. Will be removed in a future version of stdlib. See [`validate_legacy`](#validate_legacy).** Returns 'true' if the variable passed to this function is an array. *Type*: rvalue. #### `is_bool` -**Deprecated. Will be removed in a future version of stdlib. See [`validate_legacy`](#validatelegacy).** +**Deprecated. Will be removed in a future version of stdlib. See [`validate_legacy`](#validate_legacy).** Returns 'true' if the variable passed to this function is a boolean. *Type*: rvalue. #### `is_domain_name` -**Deprecated. Will be removed in a future version of stdlib. See [`validate_legacy`](#validatelegacy).** +**Deprecated. Will be removed in a future version of stdlib. See [`validate_legacy`](#validate_legacy).** Returns 'true' if the string passed to this function is a syntactically correct domain name. *Type*: rvalue. #### `is_float` -**Deprecated. Will be removed in a future version of stdlib. See [`validate_legacy`](#validatelegacy).** +**Deprecated. Will be removed in a future version of stdlib. See [`validate_legacy`](#validate_legacy).** Returns 'true' if the variable passed to this function is a float. *Type*: rvalue. #### `is_function_available` -**Deprecated. Will be removed in a future version of stdlib. See [`validate_legacy`](#validatelegacy).** +**Deprecated. Will be removed in a future version of stdlib. See [`validate_legacy`](#validate_legacy).** Accepts a string as an argument and determines whether the Puppet runtime has access to a function by that name. It returns 'true' if the function exists, 'false' if not. *Type*: rvalue. #### `is_hash` -**Deprecated. Will be removed in a future version of stdlib. See [`validate_legacy`](#validatelegacy).** +**Deprecated. Will be removed in a future version of stdlib. See [`validate_legacy`](#validate_legacy).** Returns 'true' if the variable passed to this function is a hash. *Type*: rvalue. #### `is_integer` -**Deprecated. Will be removed in a future version of stdlib. See [`validate_legacy`](#validatelegacy).** +**Deprecated. Will be removed in a future version of stdlib. See [`validate_legacy`](#validate_legacy).** Returns 'true' if the variable returned to this string is an integer. *Type*: rvalue. #### `is_ip_address` -**Deprecated. Will be removed in a future version of stdlib. See [`validate_legacy`](#validatelegacy).** +**Deprecated. Will be removed in a future version of stdlib. See [`validate_legacy`](#validate_legacy).** Returns 'true' if the string passed to this function is a valid IP address. *Type*: rvalue. #### `is_ipv6_address` -**Deprecated. Will be removed in a future version of stdlib. See [`validate_legacy`](#validatelegacy).** +**Deprecated. Will be removed in a future version of stdlib. See [`validate_legacy`](#validate_legacy).** Returns 'true' if the string passed to this function is a valid IPv6 address. *Type*: rvalue. #### `is_ipv4_address` -**Deprecated. Will be removed in a future version of stdlib. See [`validate_legacy`](#validatelegacy).** +**Deprecated. Will be removed in a future version of stdlib. See [`validate_legacy`](#validate_legacy).** Returns 'true' if the string passed to this function is a valid IPv4 address. *Type*: rvalue. @@ -782,13 +782,13 @@ Returns 'true' if the string passed to this function is a valid MAC address. *Ty #### `is_numeric` -**Deprecated. Will be removed in a future version of stdlib. See [`validate_legacy`](#validatelegacy).** +**Deprecated. Will be removed in a future version of stdlib. See [`validate_legacy`](#validate_legacy).** Returns 'true' if the variable passed to this function is a number. *Type*: rvalue. #### `is_string` -**Deprecated. Will be removed in a future version of stdlib. See [`validate_legacy`](#validatelegacy).** +**Deprecated. Will be removed in a future version of stdlib. See [`validate_legacy`](#validate_legacy).** Returns 'true' if the variable passed to this function is a string. *Type*: rvalue. @@ -1254,7 +1254,7 @@ validate_absolute_path($undefined) #### `validate_array` -**Deprecated. Will be removed in a future version of stdlib. See [`validate_legacy`](#validatelegacy).** +**Deprecated. Will be removed in a future version of stdlib. See [`validate_legacy`](#validate_legacy).** Validates that all passed values are array data structures. Aborts catalog compilation if any value fails this check. @@ -1304,7 +1304,7 @@ validate_augeas($sudoerscontent, 'Sudoers.lns', [], 'Failed to validate sudoers #### `validate_bool` -**Deprecated. Will be removed in a future version of stdlib. See [`validate_legacy`](#validatelegacy).** +**Deprecated. Will be removed in a future version of stdlib. See [`validate_legacy`](#validate_legacy).** Validates that all passed values are either true or false. Aborts catalog compilation if any value fails this check. @@ -1346,7 +1346,7 @@ validate_cmd($haproxycontent, '/usr/sbin/haproxy -f % -c', 'Haproxy failed to va #### `validate_hash` -**Deprecated. Will be removed in a future version of stdlib. See [`validate_legacy`](#validatelegacy).** +**Deprecated. Will be removed in a future version of stdlib. See [`validate_legacy`](#validate_legacy).** Validates that all passed values are hash data structures. Aborts catalog compilation if any value fails this check. @@ -1370,7 +1370,7 @@ Validates that all passed values are hash data structures. Aborts catalog compil #### `validate_integer` -**Deprecated. Will be removed in a future version of stdlib. See [`validate_legacy`](#validatelegacy).** +**Deprecated. Will be removed in a future version of stdlib. See [`validate_legacy`](#validate_legacy).** Validates that the first argument is an integer (or an array of integers). Aborts catalog compilation if any of the checks fail. @@ -1430,7 +1430,7 @@ Validates that the first argument is an integer (or an array of integers). Abort #### `validate_ip_address` -**Deprecated. Will be removed in a future version of stdlib. See [`validate_legacy`](#validatelegacy).** +**Deprecated. Will be removed in a future version of stdlib. See [`validate_legacy`](#validate_legacy).** Validates that the argument is an IP address, regardless of it is an IPv4 or an IPv6 address. It also validates IP address with netmask. The argument must be given as a string. @@ -1544,7 +1544,7 @@ Always note such changes in your CHANGELOG and README. #### `validate_numeric` -**Deprecated. Will be removed in a future version of stdlib. See [`validate_legacy`](#validatelegacy).** +**Deprecated. Will be removed in a future version of stdlib. See [`validate_legacy`](#validate_legacy).** Validates that the first argument is a numeric value (or an array or string of numeric values). Aborts catalog compilation if any of the checks fail. @@ -1562,7 +1562,7 @@ Validates that the first argument is a numeric value (or an array or string of n #### `validate_re` -**Deprecated. Will be removed in a future version of stdlib. See [`validate_legacy`](#validatelegacy).** +**Deprecated. Will be removed in a future version of stdlib. See [`validate_legacy`](#validate_legacy).** Performs simple validation of a string against one or more regular expressions. The first argument of this function should be the string to test, and the second argument should be a stringified regular expression (without the // delimiters) or an array of regular expressions. If none of the regular expressions match the string passed in, compilation aborts with a parse error. @@ -1598,7 +1598,7 @@ test, and the second argument should be a stringified regular expression (withou #### `validate_slength` -**Deprecated. Will be removed in a future version of stdlib. See [`validate_legacy`](#validatelegacy).** +**Deprecated. Will be removed in a future version of stdlib. See [`validate_legacy`](#validate_legacy).** Validates that the first argument is a string (or an array of strings), and is less than or equal to the length of the second argument. It fails if the first argument is not a string or array of strings, or if the second argument is not convertable to a number. Optionally, a minimum string length can be given as the third argument. @@ -1622,7 +1622,7 @@ Validates that the first argument is a string (or an array of strings), and is l #### `validate_string` -**Deprecated. Will be removed in a future version of stdlib. See [`validate_legacy`](#validatelegacy).** +**Deprecated. Will be removed in a future version of stdlib. See [`validate_legacy`](#validate_legacy).** Validates that all passed values are string data structures. Aborts catalog compilation if any value fails this check. -- cgit v1.2.3 From 64abfc99c6222f22ccfbb39ae9ece5ccd41fa25c Mon Sep 17 00:00:00 2001 From: Helen Campbell Date: Mon, 7 Nov 2016 14:52:12 +0000 Subject: Call site display for deprecation warnings --- lib/puppet/functions/deprecation.rb | 8 ++++++-- spec/acceptance/deprecation_spec.rb | 4 ++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/lib/puppet/functions/deprecation.rb b/lib/puppet/functions/deprecation.rb index a860aa2..7082068 100644 --- a/lib/puppet/functions/deprecation.rb +++ b/lib/puppet/functions/deprecation.rb @@ -8,15 +8,19 @@ Puppet::Functions.create_function(:deprecation) do end def deprecation(key, message) + stacktrace = Puppet::Pops::PuppetStack.stacktrace() + file = stacktrace[0] + line = stacktrace[1] + output_message = "#{message} at #{file}:#{line}" # depending on configuration setting of strict case Puppet.settings[:strict] when :off # do nothing when :error - fail("deprecation. #{key}. #{message}") + fail("deprecation. #{key}. #{output_message}") else unless ENV['STDLIB_LOG_DEPRECATIONS'] == 'false' - Puppet.deprecation_warning(message, key) + Puppet.deprecation_warning(output_message, key) end end end diff --git a/spec/acceptance/deprecation_spec.rb b/spec/acceptance/deprecation_spec.rb index ea13700..697c604 100644 --- a/spec/acceptance/deprecation_spec.rb +++ b/spec/acceptance/deprecation_spec.rb @@ -31,7 +31,7 @@ describe 'deprecation function' do end it "should show the error message" do - expect(@result.stderr).to match(/deprecation. key. message/) + expect(@result.stderr).to match(/deprecation. key. message at/) end describe file("#{test_file}") do @@ -53,7 +53,7 @@ describe 'deprecation function' do end it "should show the error message" do - expect(@result.stderr).to match(/Warning: message/) + expect(@result.stderr).to match(/Warning: message at /) end describe file("#{test_file}") do -- cgit v1.2.3 From 91847caad08faba7f3cd12badff73a3f936ff9d1 Mon Sep 17 00:00:00 2001 From: Bryan Jen Date: Mon, 21 Nov 2016 14:18:29 -0700 Subject: Revert "Call site output for deprecation warnings" --- lib/puppet/functions/deprecation.rb | 8 ++------ spec/acceptance/deprecation_spec.rb | 4 ++-- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/lib/puppet/functions/deprecation.rb b/lib/puppet/functions/deprecation.rb index 7082068..a860aa2 100644 --- a/lib/puppet/functions/deprecation.rb +++ b/lib/puppet/functions/deprecation.rb @@ -8,19 +8,15 @@ Puppet::Functions.create_function(:deprecation) do end def deprecation(key, message) - stacktrace = Puppet::Pops::PuppetStack.stacktrace() - file = stacktrace[0] - line = stacktrace[1] - output_message = "#{message} at #{file}:#{line}" # depending on configuration setting of strict case Puppet.settings[:strict] when :off # do nothing when :error - fail("deprecation. #{key}. #{output_message}") + fail("deprecation. #{key}. #{message}") else unless ENV['STDLIB_LOG_DEPRECATIONS'] == 'false' - Puppet.deprecation_warning(output_message, key) + Puppet.deprecation_warning(message, key) end end end diff --git a/spec/acceptance/deprecation_spec.rb b/spec/acceptance/deprecation_spec.rb index 697c604..ea13700 100644 --- a/spec/acceptance/deprecation_spec.rb +++ b/spec/acceptance/deprecation_spec.rb @@ -31,7 +31,7 @@ describe 'deprecation function' do end it "should show the error message" do - expect(@result.stderr).to match(/deprecation. key. message at/) + expect(@result.stderr).to match(/deprecation. key. message/) end describe file("#{test_file}") do @@ -53,7 +53,7 @@ describe 'deprecation function' do end it "should show the error message" do - expect(@result.stderr).to match(/Warning: message at /) + expect(@result.stderr).to match(/Warning: message/) end describe file("#{test_file}") do -- cgit v1.2.3 From 746c1f83984ce875d810e00788e383109fa7ab2f Mon Sep 17 00:00:00 2001 From: Helen Campbell Date: Wed, 23 Nov 2016 16:01:01 +0000 Subject: Deprecation - Use puppet stacktrace if available A previous PR (#685) was raised on this issue, however once it was merged it was discovered that Puppet 3 with future parser enabled was calling the Puppet 4 version of the deprecation function. The Puppet stacktrace is not available until Puppet 4.6, so this was breaking existing setups. The solution was to check is the stacktrace was defined, and if it was to use it as part of the message output. --- lib/puppet/functions/deprecation.rb | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/lib/puppet/functions/deprecation.rb b/lib/puppet/functions/deprecation.rb index a860aa2..39d9bc7 100644 --- a/lib/puppet/functions/deprecation.rb +++ b/lib/puppet/functions/deprecation.rb @@ -8,6 +8,12 @@ Puppet::Functions.create_function(:deprecation) do end def deprecation(key, message) + if defined? Puppet::Pops::PuppetStack.stacktrace() + stacktrace = Puppet::Pops::PuppetStack.stacktrace() + file = stacktrace[0] + line = stacktrace[1] + message = "#{message} at #{file}:#{line}" + end # depending on configuration setting of strict case Puppet.settings[:strict] when :off -- cgit v1.2.3 From c5fbd82204e9832b0d398e894003e9898adb71fc Mon Sep 17 00:00:00 2001 From: David Schmitt Date: Sun, 27 Nov 2016 17:39:07 +0000 Subject: Remove rvalue declaration from v3 deprecation() function Without this, some uses of this function do not work in puppet3. e.g. if $include_src != undef { deprecation('apt $include_src', "please use \$include => { 'src' => ${include_src} } instead") } causes Function 'deprecation' must be the value of a statement on puppet 3.8.7. --- lib/puppet/parser/functions/deprecation.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/puppet/parser/functions/deprecation.rb b/lib/puppet/parser/functions/deprecation.rb index e30f3a0..cd64fe2 100644 --- a/lib/puppet/parser/functions/deprecation.rb +++ b/lib/puppet/parser/functions/deprecation.rb @@ -1,5 +1,5 @@ module Puppet::Parser::Functions - newfunction(:deprecation, :type => :rvalue, :doc => <<-EOS + newfunction(:deprecation, :doc => <<-EOS Function to print deprecation warnings (this is the 3.X version of it), The uniqueness key - can appear once. The msg is the message text including any positional information that is formatted by the user/caller of the method.). EOS ) do |arguments| @@ -9,7 +9,7 @@ EOS key = arguments[0] message = arguments[1] - + if ENV['STDLIB_LOG_DEPRECATIONS'] == "true" warning("deprecation. #{key}. #{message}") end -- cgit v1.2.3 From e501cb1b646e9741fb6f2510a1a3a434041a4d33 Mon Sep 17 00:00:00 2001 From: Helen Campbell Date: Thu, 24 Nov 2016 16:32:15 +0000 Subject: Update deprecation tests to include future parser --- spec/acceptance/deprecation_spec.rb | 17 +++++++++++++++++ spec/functions/deprecation_spec.rb | 5 ++++- 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/spec/acceptance/deprecation_spec.rb b/spec/acceptance/deprecation_spec.rb index ea13700..7a0b34c 100644 --- a/spec/acceptance/deprecation_spec.rb +++ b/spec/acceptance/deprecation_spec.rb @@ -82,4 +82,21 @@ describe 'deprecation function' do it { is_expected.to be_file } end end + + context 'puppet 3 test', if: get_puppet_version =~ /^3/ do + before :all do + @result = on(default, puppet('apply', '--parser=future', '-e', add_file_manifest), acceptable_exit_codes: (0...256)) + end + after :all do + apply_manifest(remove_file_manifest) + end + + it "should return a deprecation error" do + expect(@result.stderr).to match(/Warning: message/) + end + it "should pass without error" do + expect(@result.exit_code).to eq(0) + end + end + end diff --git a/spec/functions/deprecation_spec.rb b/spec/functions/deprecation_spec.rb index 9859833..cee4f1c 100644 --- a/spec/functions/deprecation_spec.rb +++ b/spec/functions/deprecation_spec.rb @@ -41,11 +41,14 @@ if Puppet.version.to_f >= 4.0 } end else + # Puppet version < 4 will use these tests. describe 'deprecation' do after(:all) do ENV.delete('STDLIB_LOG_DEPRECATIONS') end - ENV['STDLIB_LOG_DEPRECATIONS'] = "true" + before(:all) do + ENV['STDLIB_LOG_DEPRECATIONS'] = "true" + end it { is_expected.not_to eq(nil) } it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } -- cgit v1.2.3 From d3bbd3cbf89cb23bce4e55c3828e17c05c4cfd70 Mon Sep 17 00:00:00 2001 From: Nick Walker Date: Thu, 1 Dec 2016 05:54:08 -0800 Subject: Indicate that the type function is preferred (#695) Prior to this commit, users coming to the type_of function would not realize that the type function in puppet does the same thing and is preferred over type_of. After this commit, we have a comment indicating the above. --- README.markdown | 2 ++ lib/puppet/functions/type_of.rb | 2 ++ 2 files changed, 4 insertions(+) diff --git a/README.markdown b/README.markdown index 3e937b1..a6b7bda 100644 --- a/README.markdown +++ b/README.markdown @@ -1190,6 +1190,8 @@ Returns a string description of the type when passed a value. Type can be a stri #### `type_of` +This function is provided for backwards compatibility but is generally not preferred over the built-in [type() function](https://docs.puppet.com/puppet/latest/reference/function.html#type) provided by Puppet. + Returns the literal type when passed a value. Requires the new parser. Useful for comparison of types with `<=` such as in `if type_of($some_value) <= Array[String] { ... }` (which is equivalent to `if $some_value =~ Array[String] { ... }`) *Type*: rvalue. #### `union` diff --git a/lib/puppet/functions/type_of.rb b/lib/puppet/functions/type_of.rb index 02cdd4d..01f1f49 100644 --- a/lib/puppet/functions/type_of.rb +++ b/lib/puppet/functions/type_of.rb @@ -10,6 +10,8 @@ # See the documentation for "The Puppet Type System" for more information about types. # See the `assert_type()` function for flexible ways to assert the type of a value. # +# The built-in type() function in puppet is generally preferred over this function +# this function is provided for backwards compatibility. Puppet::Functions.create_function(:type_of) do def type_of(value) Puppet::Pops::Types::TypeCalculator.infer_set(value) -- cgit v1.2.3 From c63f8722386e6816a2baca1f332c88f6e33e1ea1 Mon Sep 17 00:00:00 2001 From: Hunter Haugen Date: Thu, 1 Dec 2016 11:38:47 -0800 Subject: (MODULES-3631) msync Gemfile for 1.9 frozen strings --- .travis.yml | 6 ------ Gemfile | 25 +++++++++++++------------ 2 files changed, 13 insertions(+), 18 deletions(-) diff --git a/.travis.yml b/.travis.yml index 990ad45..d972387 100644 --- a/.travis.yml +++ b/.travis.yml @@ -37,11 +37,5 @@ matrix: - rvm: 1.9.3 bundler_args: --without system_tests env: PUPPET_GEM_VERSION="~> 3.0" - - rvm: 2.1.9 - bundler_args: --without system_tests - env: PUPPET_GEM_VERSION="~> 4.6.0" - - rvm: 2.1.9 - bundler_args: --without system_tests - env: PUPPET_GEM_VERSION="~> 4.7.0" notifications: email: false diff --git a/Gemfile b/Gemfile index 8871c66..8a568f6 100644 --- a/Gemfile +++ b/Gemfile @@ -32,33 +32,34 @@ supports_windows = false group :development do gem 'puppet-lint', :require => false - gem 'metadata-json-lint', :require => false + gem 'metadata-json-lint', :require => false, :platforms => 'ruby' gem 'puppet_facts', :require => false gem 'puppet-blacksmith', '>= 3.4.0', :require => false, :platforms => 'ruby' gem 'puppetlabs_spec_helper', '>= 1.2.1', :require => false gem 'rspec-puppet', '>= 2.3.2', :require => false - gem 'rspec-puppet-facts', :require => false + gem 'rspec-puppet-facts', :require => false, :platforms => 'ruby' gem 'mocha', '< 1.2.0', :require => false - gem 'simplecov', :require => false - gem 'parallel_tests', '< 2.10.0', :require => false if Gem::Version.new(RUBY_VERSION) < Gem::Version.new('2.0.0') - gem 'parallel_tests', :require => false if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('2.0.0') - gem 'rubocop', '0.41.2', :require => false if Gem::Version.new(RUBY_VERSION) < Gem::Version.new('2.0.0') - gem 'rubocop', :require => false if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('2.0.0') - gem 'rubocop-rspec', '~> 1.6', :require => false if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('2.3.0') + gem 'simplecov', :require => false, :platforms => 'ruby' + gem 'parallel_tests', '< 2.10.0', :require => false if Gem::Version.new(RUBY_VERSION.dup) < Gem::Version.new('2.0.0') + gem 'parallel_tests', :require => false if Gem::Version.new(RUBY_VERSION.dup) >= Gem::Version.new('2.0.0') + gem 'rubocop', '0.41.2', :require => false if Gem::Version.new(RUBY_VERSION.dup) < Gem::Version.new('2.0.0') + gem 'rubocop', :require => false if Gem::Version.new(RUBY_VERSION.dup) >= Gem::Version.new('2.0.0') + gem 'rubocop-rspec', '~> 1.6', :require => false if Gem::Version.new(RUBY_VERSION.dup) >= Gem::Version.new('2.3.0') gem 'pry', :require => false - gem 'json_pure', '<= 2.0.1', :require => false if Gem::Version.new(RUBY_VERSION) < Gem::Version.new('2.0.0') + gem 'json_pure', '<= 2.0.1', :require => false if Gem::Version.new(RUBY_VERSION.dup) < Gem::Version.new('2.0.0') end group :system_tests do gem 'beaker', *location_for(ENV['BEAKER_VERSION'] || '~> 2.20') if supports_windows - gem 'beaker', *location_for(ENV['BEAKER_VERSION']) if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('2.3.0') and ! supports_windows - gem 'beaker', *location_for(ENV['BEAKER_VERSION'] || '< 3') if Gem::Version.new(RUBY_VERSION) < Gem::Version.new('2.3.0') and ! supports_windows - gem 'beaker-pe', :require => false if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('2.3.0') + gem 'beaker', *location_for(ENV['BEAKER_VERSION']) if Gem::Version.new(RUBY_VERSION.dup) >= Gem::Version.new('2.3.0') and ! supports_windows + gem 'beaker', *location_for(ENV['BEAKER_VERSION'] || '< 3') if Gem::Version.new(RUBY_VERSION.dup) < Gem::Version.new('2.3.0') and ! supports_windows + gem 'beaker-pe', :require => false if Gem::Version.new(RUBY_VERSION.dup) >= Gem::Version.new('2.3.0') gem 'beaker-rspec', *location_for(ENV['BEAKER_RSPEC_VERSION'] || '>= 3.4') if ! supports_windows gem 'beaker-rspec', *location_for(ENV['BEAKER_RSPEC_VERSION'] || '~> 5.1') if supports_windows gem 'beaker-puppet_install_helper', :require => false gem 'master_manipulator', :require => false gem 'beaker-hostgenerator', *location_for(ENV['BEAKER_HOSTGENERATOR_VERSION']) + gem 'beaker-abs', *location_for(ENV['BEAKER_ABS_VERSION'] || '~> 0.1') end gem 'puppet', *location_for(ENV['PUPPET_GEM_VERSION']) -- cgit v1.2.3 From 1cd0209aec84b0135adbe6b5fc2769f0053c26f3 Mon Sep 17 00:00:00 2001 From: Hunter Haugen Date: Wed, 17 Aug 2016 10:27:54 -0700 Subject: Add pry() function from hunner-pry --- README.markdown | 14 ++++++++++++++ lib/puppet/parser/functions/pry.rb | 30 ++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+) create mode 100644 lib/puppet/parser/functions/pry.rb diff --git a/README.markdown b/README.markdown index a6b7bda..3039a2a 100644 --- a/README.markdown +++ b/README.markdown @@ -935,6 +935,20 @@ For example: *Type*: rvalue. +#### `pry` + +This function invokes a pry debugging session in the current scope object. This is useful for debugging manifest code at specific points during a compilation. Should only be used when running `puppet apply` or running a puppet master in the foreground. This requires the `pry` gem to be installed in puppet's rubygems. + +*Examples:* +```puppet +pry() +``` +Once in a pry session, some interesting commands: + +* Run `catalog` to see the contents currently compiling catalog +* Run `cd catalog` and `ls` to see catalog methods and instance variables +* Run `@resource_table` to see the current catalog resource table + #### `assert_private` Sets the current class or definition as private. Calling the class or definition from outside the current module will fail. diff --git a/lib/puppet/parser/functions/pry.rb b/lib/puppet/parser/functions/pry.rb new file mode 100644 index 0000000..c18ef7e --- /dev/null +++ b/lib/puppet/parser/functions/pry.rb @@ -0,0 +1,30 @@ +# +# pry.rb +# + +module Puppet::Parser::Functions + newfunction(:pry, :type => :statement, :doc => <<-EOS +This function invokes a pry debugging session in the current scope object. This is useful for debugging manifest code at specific points during a compilation. + +*Examples:* + + pry() + EOS + ) do |arguments| + begin + require 'pry' + rescue LoadError + raise(Puppet::Error, "pry(): Requires the 'pry' rubygem to use, but it was not found") + end + # + ## Run `catalog` to see the contents currently compiling catalog + ## Run `cd catalog` and `ls` to see catalog methods and instance variables + ## Run `@resource_table` to see the current catalog resource table + # + if $stdout.isatty + binding.pry # rubocop:disable Lint/Debugger + else + Puppet.warning 'pry(): cowardly refusing to start the debugger on a daemonized master' + end + end +end -- cgit v1.2.3 From 903d94e10527df8a288138d223e07f816422fa2c Mon Sep 17 00:00:00 2001 From: Hailee Kenney Date: Fri, 2 Dec 2016 14:21:45 +0000 Subject: (MODULES-3829) Add tests for ensure_resources Prior to this commit, we didn't have tests for the ensure_resources function (only for the ensure_resource function). This meant that we weren't catching a bug in the ensure_resources function. In order to prevent this in the future, add some tests which test the specific functionality of ensure_resources. --- spec/fixtures/test/manifests/ensure_resources.pp | 4 ++++ spec/unit/ensure_resources_spec.rb | 22 ++++++++++++++++++++++ 2 files changed, 26 insertions(+) create mode 100644 spec/fixtures/test/manifests/ensure_resources.pp create mode 100644 spec/unit/ensure_resources_spec.rb diff --git a/spec/fixtures/test/manifests/ensure_resources.pp b/spec/fixtures/test/manifests/ensure_resources.pp new file mode 100644 index 0000000..bd26002 --- /dev/null +++ b/spec/fixtures/test/manifests/ensure_resources.pp @@ -0,0 +1,4 @@ +# A helper class to test the ensure_resources function +class test::ensure_resources($resource_type, $title_hash, $attributes_hash) { + ensure_resources($resource_type, $title_hash, $attributes_hash) +} diff --git a/spec/unit/ensure_resources_spec.rb b/spec/unit/ensure_resources_spec.rb new file mode 100644 index 0000000..aea723e --- /dev/null +++ b/spec/unit/ensure_resources_spec.rb @@ -0,0 +1,22 @@ +require 'spec_helper' + +describe 'test::ensure_resources', type: :class do + let(:params) {{ resource_type: 'user', title_hash: title_param, attributes_hash: {'ensure' => 'present'} }} + + describe 'given a title hash of multiple resources' do + + let(:title_param) { {'dan' => { 'gid' => 'mygroup', 'uid' => '600' }, 'alex' => { 'gid' => 'mygroup', 'uid' => '700'}} } + + it { is_expected.to compile } + it { is_expected.to contain_user('dan').with({ 'gid' => 'mygroup', 'uid' => '600', 'ensure' => 'present'}) } + it { is_expected.to contain_user('alex').with({ 'gid' => 'mygroup', 'uid' => '700', 'ensure' => 'present'}) } + end + + describe 'given a title hash of a single resource' do + + let(:title_param) { {'dan' => { 'gid' => 'mygroup', 'uid' => '600' }} } + + it { is_expected.to compile } + it { is_expected.to contain_user('dan').with({ 'gid' => 'mygroup', 'uid' => '600', 'ensure' => 'present'}) } + end +end -- cgit v1.2.3 From 0e684d82ea1ad0f5c85b8aa0147ffec39aac8ddd Mon Sep 17 00:00:00 2001 From: Peter Souter Date: Wed, 7 Dec 2016 19:25:03 +0000 Subject: (MODULES-4188) Add FQDN UUID generation function * Generates UUID based on a given FQDN string and the DNS namespace (6ba7b810-9dad-11d1-80b4-00c04fd430c8) --- README.markdown | 9 ++++ lib/puppet/parser/functions/fqdn_uuid.rb | 92 ++++++++++++++++++++++++++++++++ spec/functions/fqdn_uuid_spec.rb | 14 +++++ 3 files changed, 115 insertions(+) create mode 100644 lib/puppet/parser/functions/fqdn_uuid.rb create mode 100644 spec/functions/fqdn_uuid_spec.rb diff --git a/README.markdown b/README.markdown index a6b7bda..627e73a 100644 --- a/README.markdown +++ b/README.markdown @@ -578,6 +578,15 @@ fqdn_rotate([1, 2, 3], 'custom seed') *Type*: rvalue. +#### `fqdn_uuid` + +Returns a rfc4122 valid version 5 UUID based on an FQDN string under the DNS namespace + + * fqdn_uuid('puppetlabs.com') returns '9c70320f-6815-5fc5-ab0f-debe68bf764c' + * fqdn_uuid('google.com') returns '64ee70a4-8cc1-5d25-abf2-dea6c79a09c8' + +*Type*: rvalue. + #### `get_module_path` Returns the absolute path of the specified module for the current environment. diff --git a/lib/puppet/parser/functions/fqdn_uuid.rb b/lib/puppet/parser/functions/fqdn_uuid.rb new file mode 100644 index 0000000..30205d0 --- /dev/null +++ b/lib/puppet/parser/functions/fqdn_uuid.rb @@ -0,0 +1,92 @@ +require 'digest/sha1' + +module Puppet::Parser::Functions + newfunction(:fqdn_uuid, :type => :rvalue, :doc => <<-END) do |args| + + Creates a UUID based on a given string, assumed to be the FQDN + + For example, to generate a UUID based on the FQDN of a system: + + Usage: + + $uuid = fqdn_uuid($::fqdn) + + The generated UUID will be the same for the given hostname + + The resulting UUID is returned on the form: + + 1d839dea-5e10-5243-88eb-e66815bd7d5c + + (u.e. without any curly braces.) + + The generated UUID is a version 5 UUID with the V5 DNS namespace: + + 6ba7b810-9dad-11d1-80b4-00c04fd430c8 + + This only supports a the V5 SHA-1 hash, using the DNS namespace. + + Please consult http://www.ietf.org/rfc/rfc4122.txt for the details on + UUID generation and example implementation. + + No verification is present at the moment as whether the domain name given + is in fact a correct fully-qualified domain name. Therefore any arbitrary + string and/or alpha-numeric value can subside for a domain name. + EOS + + END + + if args.length == 0 + raise(ArgumentError, "fqdn_uuid: No arguments given") + elsif args.length == 1 + fqdn = args[0] + else + raise(ArgumentError, "fqdn_uuid: Too many arguments given (#{args.length})") + end + + # Code lovingly taken from + # https://github.com/puppetlabs/marionette-collective/blob/master/lib/mcollective/ssl.rb + + # This is the UUID version 5 type DNS name space which is as follows: + # + # 6ba7b810-9dad-11d1-80b4-00c04fd430c8 + # + uuid_name_space_dns = [0x6b, + 0xa7, + 0xb8, + 0x10, + 0x9d, + 0xad, + 0x11, + 0xd1, + 0x80, + 0xb4, + 0x00, + 0xc0, + 0x4f, + 0xd4, + 0x30, + 0xc8 + ].map {|b| b.chr}.join + + sha1 = Digest::SHA1.new + sha1.update(uuid_name_space_dns) + sha1.update(fqdn) + + # first 16 bytes.. + bytes = sha1.digest[0, 16].bytes.to_a + + # version 5 adjustments + bytes[6] &= 0x0f + bytes[6] |= 0x50 + + # variant is DCE 1.1 + bytes[8] &= 0x3f + bytes[8] |= 0x80 + + bytes = [4, 2, 2, 2, 6].collect do |i| + bytes.slice!(0, i).pack('C*').unpack('H*') + end + + bytes.join('-') + end +end diff --git a/spec/functions/fqdn_uuid_spec.rb b/spec/functions/fqdn_uuid_spec.rb new file mode 100644 index 0000000..a2d1618 --- /dev/null +++ b/spec/functions/fqdn_uuid_spec.rb @@ -0,0 +1,14 @@ +require 'spec_helper' + +describe 'fqdn_uuid' do + + context "Invalid parameters" do + it { should run.with_params().and_raise_error(ArgumentError, /No arguments given$/) } + end + + context "given string" do + it { should run.with_params('puppetlabs.com').and_return('9c70320f-6815-5fc5-ab0f-debe68bf764c') } + it { should run.with_params('google.com').and_return('64ee70a4-8cc1-5d25-abf2-dea6c79a09c8') } + end + +end -- cgit v1.2.3 From 3312cc1f44d1acf25ce45701a74cecd647c50858 Mon Sep 17 00:00:00 2001 From: Hailee Kenney Date: Fri, 9 Dec 2016 13:17:48 +0000 Subject: (MODULES-3829) Make ensure_packages work with < 2.0 Prior to this commit, if a hash was passed in as an argument to the ensure_packages function a method of hash duplication would be used that is not supported with versions of ruby older than 2.0. In order to ensure the method is compatible with older ruby versions, switch to a different method of duplication. Additionally add tests to prevent further regressions. --- lib/puppet/parser/functions/ensure_packages.rb | 2 +- spec/functions/ensure_packages_spec.rb | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/lib/puppet/parser/functions/ensure_packages.rb b/lib/puppet/parser/functions/ensure_packages.rb index 532b702..439af1e 100644 --- a/lib/puppet/parser/functions/ensure_packages.rb +++ b/lib/puppet/parser/functions/ensure_packages.rb @@ -25,7 +25,7 @@ third argument to the ensure_resource() function. end Puppet::Parser::Functions.function(:ensure_resources) - function_ensure_resources(['package', Hash(arguments[0]), defaults ]) + function_ensure_resources(['package', arguments[0].dup, defaults ]) else packages = Array(arguments[0]) diff --git a/spec/functions/ensure_packages_spec.rb b/spec/functions/ensure_packages_spec.rb index c824732..5d97684 100755 --- a/spec/functions/ensure_packages_spec.rb +++ b/spec/functions/ensure_packages_spec.rb @@ -33,4 +33,12 @@ describe 'ensure_packages' do it { expect(lambda { catalogue }).to contain_package('facter').with_ensure('present').with_provider("gem") } end end + + context 'given hash of packages' do + before { subject.call([{"foo" => { "provider" => "rpm" }, "bar" => { "provider" => "gem" }}, { "ensure" => "present"}]) } + + # this lambda is required due to strangeness within rspec-puppet's expectation handling + it { expect(lambda { catalogue }).to contain_package('foo').with({'provider' => 'rpm', 'ensure' => 'present'}) } + it { expect(lambda { catalogue }).to contain_package('bar').with({'provider' => 'gem', 'ensure' => 'present'}) } + end end -- cgit v1.2.3 From 893b2e94abffb13a83204cd24ecff2d3bd4b919a Mon Sep 17 00:00:00 2001 From: Eric Putnam Date: Wed, 14 Dec 2016 13:29:44 -0800 Subject: gettext and spec.opts --- Gemfile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Gemfile b/Gemfile index 8a568f6..3d46720 100644 --- a/Gemfile +++ b/Gemfile @@ -47,6 +47,8 @@ group :development do gem 'rubocop-rspec', '~> 1.6', :require => false if Gem::Version.new(RUBY_VERSION.dup) >= Gem::Version.new('2.3.0') gem 'pry', :require => false gem 'json_pure', '<= 2.0.1', :require => false if Gem::Version.new(RUBY_VERSION.dup) < Gem::Version.new('2.0.0') + gem 'fast_gettext', '1.1.0', :require => false if Gem::Version.new(RUBY_VERSION.dup) < Gem::Version.new('2.1.0') + gem 'fast_gettext', :require => false if Gem::Version.new(RUBY_VERSION.dup) >= Gem::Version.new('2.1.0') end group :system_tests do -- cgit v1.2.3 From 3451bd9fdecceab9bce99570a69369737589b9e8 Mon Sep 17 00:00:00 2001 From: Michael Watters Date: Mon, 19 Dec 2016 12:23:36 -0500 Subject: Change - Update str2bool documentation Updated documentation for this function to be consistent with the function itself. --- README.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.markdown b/README.markdown index 5aea25f..a4c30b5 100644 --- a/README.markdown +++ b/README.markdown @@ -1079,7 +1079,7 @@ Returns a new string where runs of the same character that occur in this set are #### `str2bool` -Converts certain strings to a boolean. This attempts to convert strings that contain the values '1', 't', 'y', or 'yes' to true. Strings that contain values '0', 'f', 'n', or 'no', or that are an empty string or undefined are converted to false. Any other value causes an error. *Type*: rvalue. +Converts certain strings to a boolean. This attempts to convert strings that contain the values '1', 'true', 't', 'y', or 'yes' to true. Strings that contain values '0', 'false', 'f', 'n', or 'no', or that are an empty string or undefined are converted to false. Any other value causes an error. These checks are case insensitive. *Type*: rvalue. #### `str2saltedsha512` -- cgit v1.2.3 From cb42df3321ef30fc22b9b3c2d8dfff99f62add76 Mon Sep 17 00:00:00 2001 From: Eric Putnam Date: Wed, 4 Jan 2017 11:09:36 -0500 Subject: add ubuntu xenial to metadata --- metadata.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/metadata.json b/metadata.json index 8ad4eec..82078bf 100644 --- a/metadata.json +++ b/metadata.json @@ -65,7 +65,8 @@ "operatingsystemrelease": [ "10.04", "12.04", - "14.04" + "14.04", + "16.06" ] }, { -- cgit v1.2.3