Skip to content

Commit 5737459

Browse files
author
Helen Campbell
committed
(WIP) Addition of validate legacy function
1 parent 999c267 commit 5737459

4 files changed

Lines changed: 122 additions & 0 deletions

File tree

README.markdown

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1368,6 +1368,17 @@ The following values will fail, causing compilation to abort:
13681368
~~~
13691369

13701370

1371+
#### `validate_legacy`
1372+
1373+
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.
1374+
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.
1375+
1376+
Example:
1377+
1378+
~~~
1379+
validate_legacy("Optional[String]", "validate_re", "Value to be validated", ["."])
1380+
~~~
1381+
13711382
#### `validate_numeric`
13721383

13731384
Validates that the first argument is a numeric value (or an array of numeric values). Aborts catalog compilation if any of the checks fail.
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
Puppet::Functions.create_function(:validate_legacy, Puppet::Functions::InternalFunction) do
2+
# The function checks a value against both the target_type (new) and the previous_validation function (old).
3+
4+
dispatch :validate_legacy do
5+
param 'Type', :target_type
6+
param 'String', :previous_validation
7+
param 'NotUndef', :value
8+
optional_param 'Any', :args
9+
end
10+
dispatch :validate_legacy_s do
11+
scope_param
12+
param 'String', :type_string
13+
param 'String', :previous_validation
14+
param 'NotUndef', :value
15+
optional_param 'Any', :args
16+
end
17+
18+
def validate_legacy_s(scope, type_string, *args)
19+
t = Puppet::Pops::Types::TypeParser.new.parse(type_string, scope)
20+
validate_legacy(t, *args)
21+
end
22+
23+
def validate_legacy(target_type, previous_validation, value, *prev_args)
24+
if assert_type(target_type, value)
25+
if previous_validation(previous_validation, value, *prev_args)
26+
# Silently passes
27+
else
28+
Puppet.warn("Accepting previously invalid value for target_type '#{target_type}'")
29+
end
30+
else
31+
inferred_type = Puppet::Pops::Types::TypeCalculator.infer_set(value)
32+
error_msg = Puppet::Pops::Types::TypeMismatchDescriber.new.describe_mismatch(previous_validation, target_type, inferred_type)
33+
if previous_validation(previous_validation, value, *prev_args)
34+
Puppet.warn(error_msg)
35+
else
36+
call_function('fail', error_msg)
37+
end
38+
end
39+
end
40+
41+
def previous_validation(previous_validation, value, *prev_args)
42+
# Call the previous validation function and catch any errors. Return true if no errors are thrown.
43+
begin
44+
call_function(previous_validation, value, *prev_args)
45+
true
46+
rescue Puppet::ParseError
47+
false
48+
end
49+
end
50+
51+
def assert_type(type, value)
52+
Puppet::Pops::Types::TypeCalculator.instance?(type, value)
53+
end
54+
end
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
require 'spec_helper'
2+
3+
if Puppet.version.to_f >= 4.0
4+
# validate_legacy requires a proper scope to run, so we have to trigger a true compilation here,
5+
# instead of being able to leverage the function test group.
6+
describe 'test::validate_legacy', type: :class do
7+
8+
describe 'validate_legacy passes assertion of type but not previous validation' do
9+
let(:params) {{ type: "Optional[Integer]", prev_validation: "validate_re", value: 5, previous_arg1: ["^\\d+$", ""] }}
10+
it {
11+
Puppet.expects(:warn).with(includes('Accepting previously invalid value for target_type'))
12+
is_expected.to compile
13+
}
14+
end
15+
16+
describe 'validate_legacy passes assertion of type and previous validation' do
17+
let(:params) {{ type: "Optional[String]", prev_validation: "validate_re", value: "5", previous_arg1: ["."] }}
18+
it { is_expected.to compile }
19+
end
20+
21+
describe 'validate_legacy fails assertion of type and passes previous validation' do
22+
let(:params) {{ type: "Optional[Integer]", prev_validation: "validate_re", value: "5", previous_arg1: ["."] }}
23+
it {
24+
Puppet.expects(:warn).with(includes('expected'))
25+
is_expected.to compile
26+
}
27+
end
28+
29+
describe 'validate_legacy fails assertion and fails previous validation' do
30+
let(:params) {{ type: "Optional[Integer]", prev_validation: "validate_re", value: "5", previous_arg1: ["thisisnotright"] }}
31+
it { is_expected.to compile.and_raise_error(/Error while evaluating a Function Call, \w* expected an \w* value, got \w*/) }
32+
end
33+
34+
describe 'validate_legacy works with multi-argument validate_ functions' do
35+
let(:params) {{ type: "Integer", prev_validation: "validate_integer", value: 10, previous_arg1: 0, previous_arg2: 100 }}
36+
it { is_expected.to compile }
37+
end
38+
end
39+
end
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# Class to test stdlib validate_legacy function
2+
3+
class test::validate_legacy(
4+
$type,
5+
$prev_validation,
6+
$value,
7+
$previous_arg1,
8+
$previous_arg2 = undef,
9+
) {
10+
11+
if $previous_arg2 == undef {
12+
validate_legacy( $type, $prev_validation, $value, $previous_arg1 )
13+
} else {
14+
validate_legacy( $type, $prev_validation, $value, $previous_arg1, $previous_arg2 )
15+
}
16+
notice("Success")
17+
18+
}

0 commit comments

Comments
 (0)