diff options
| author | Jeff McCune <jeff@puppetlabs.com> | 2013-01-18 09:06:23 -0800 | 
|---|---|---|
| committer | Jeff McCune <jeff@puppetlabs.com> | 2013-01-18 09:06:23 -0800 | 
| commit | f6a63eeafa89d01a700a7eb6ba1217034535b50b (patch) | |
| tree | 92dab9c19b6cc8aa9ae7d0f01b022bcc98300337 | |
| parent | 562d3254318349cc6dd1f4482527b3dcc6d36867 (diff) | |
| parent | 6902cc582eef6eb59cd5252208eca5ac608995bd (diff) | |
| download | puppet-stdlib-f6a63eeafa89d01a700a7eb6ba1217034535b50b.tar.gz puppet-stdlib-f6a63eeafa89d01a700a7eb6ba1217034535b50b.tar.bz2  | |
Merge branch 'raphink-validate_cmd'
* raphink-validate_cmd:
  Add validate_cmd function
This merge commit closes #113
| -rw-r--r-- | lib/puppet/parser/functions/validate_cmd.rb | 41 | ||||
| -rw-r--r-- | spec/unit/puppet/parser/functions/validate_cmd_spec.rb | 81 | 
2 files changed, 122 insertions, 0 deletions
diff --git a/lib/puppet/parser/functions/validate_cmd.rb b/lib/puppet/parser/functions/validate_cmd.rb new file mode 100644 index 0000000..e7793c3 --- /dev/null +++ b/lib/puppet/parser/functions/validate_cmd.rb @@ -0,0 +1,41 @@ +module Puppet::Parser::Functions +  newfunction(:validate_cmd, :doc => <<-'ENDHEREDOC') do |args| +    Perform 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 file as last argument. 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. + +    A helpful error message can be returned like this: + +    Example: + +        validate_cmd($sudoerscontent, '/usr/sbin/visudo -c -f', 'Visudo failed to validate sudoers content') + +    ENDHEREDOC +    if (args.length < 2) or (args.length > 3) then +      raise Puppet::ParseError, ("validate_cmd(): wrong number of arguments (#{args.length}; must be 2 or 3)") +    end + +    msg = args[2] || "validate_cmd(): failed to validate content with command #{args[1].inspect}" + +    content = args[0] +    checkscript = args[1] + +    # Test content in a temporary file +    tmpfile = Tempfile.new("validate_cmd") +    tmpfile.write(content) +    tmpfile.close +    output = `#{checkscript} #{tmpfile.path} 2>&1 1>/dev/null` +    r = $? +    File.delete(tmpfile.path) +    if output +      msg += "\nOutput is:\n#{output}" +    end +    raise Puppet::ParseError, (msg) unless r == 0 +  end +end diff --git a/spec/unit/puppet/parser/functions/validate_cmd_spec.rb b/spec/unit/puppet/parser/functions/validate_cmd_spec.rb new file mode 100644 index 0000000..0730a59 --- /dev/null +++ b/spec/unit/puppet/parser/functions/validate_cmd_spec.rb @@ -0,0 +1,81 @@ +require 'spec_helper' + +describe Puppet::Parser::Functions.function(:validate_cmd) 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_cmd) +    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_cmd(#{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', '/bin/echo' ], +        [ '/full/path/to/something', '/bin/cat' ], +      ] + +      inputs.each do |input| +        it "validate_cmd(#{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", "/bin/false" ], +      ] + +      inputs.each do |input| +        it "validate_cmd(#{input.inspect}) should fail" do +          expect { subject.call input }.to raise_error /validate_cmd.*?failed to validate content with command/ +        end +      end +    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_cmd(#{input.inspect}) should fail" do +          expect { subject.call input }.to raise_error /#{input[2]}/ +        end +      end +    end + +    describe "Test output message" do +      it "validate_cmd('whatever', 'kthnksbye') should fail" do +          expect { subject.call ['whatever', 'kthnksbye'] }.to raise_error /kthnksbye.*not found/ +      end +    end +  end +end  | 
