hiera 1.3.4 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/LICENSE +1 -1
- data/README.md +47 -10
- data/bin/hiera +48 -31
- data/lib/hiera.rb +55 -3
- data/lib/hiera/backend.rb +124 -37
- data/lib/hiera/backend/json_backend.rb +9 -7
- data/lib/hiera/backend/yaml_backend.rb +9 -7
- data/lib/hiera/config.rb +1 -3
- data/lib/hiera/interpolate.rb +52 -16
- data/lib/hiera/util.rb +5 -5
- data/lib/hiera/version.rb +1 -1
- data/spec/spec_helper.rb +12 -0
- data/spec/unit/backend/json_backend_spec.rb +9 -9
- data/spec/unit/backend/yaml_backend_spec.rb +20 -15
- data/spec/unit/backend_spec.rb +186 -32
- data/spec/unit/config_spec.rb +15 -0
- data/spec/unit/fixtures/interpolate/config/hiera.yaml +6 -0
- data/spec/unit/fixtures/interpolate/data/niltest.yaml +2 -0
- data/spec/unit/fixtures/interpolate/data/recursive.yaml +3 -0
- data/spec/unit/fixtures/override/config/hiera.yaml +5 -0
- data/spec/unit/fixtures/override/data/alternate.yaml +1 -0
- data/spec/unit/fixtures/override/data/common.yaml +2 -0
- data/spec/unit/interpolate_spec.rb +36 -0
- data/spec/unit/util_spec.rb +4 -4
- metadata +17 -3
@@ -9,8 +9,9 @@ class Hiera
|
|
9
9
|
@cache = cache || Filecache.new
|
10
10
|
end
|
11
11
|
|
12
|
-
def lookup(key, scope, order_override, resolution_type)
|
12
|
+
def lookup(key, scope, order_override, resolution_type, context)
|
13
13
|
answer = nil
|
14
|
+
found = false
|
14
15
|
|
15
16
|
Hiera.debug("Looking up #{key} in JSON backend")
|
16
17
|
|
@@ -27,28 +28,29 @@ class Hiera
|
|
27
28
|
|
28
29
|
next if data.empty?
|
29
30
|
next unless data.include?(key)
|
31
|
+
found = true
|
30
32
|
|
31
33
|
# for array resolution we just append to the array whatever
|
32
34
|
# we find, we then goes onto the next file and keep adding to
|
33
35
|
# the array
|
34
36
|
#
|
35
37
|
# for priority searches we break after the first found data item
|
36
|
-
new_answer = Backend.parse_answer(data[key], scope)
|
37
|
-
case resolution_type
|
38
|
+
new_answer = Backend.parse_answer(data[key], scope, {}, context)
|
39
|
+
case resolution_type.is_a?(Hash) ? :hash : resolution_type
|
38
40
|
when :array
|
39
|
-
raise Exception, "Hiera type mismatch: expected Array and got #{new_answer.class}" unless new_answer.kind_of? Array or new_answer.kind_of? String
|
41
|
+
raise Exception, "Hiera type mismatch for key '#{key}': expected Array and got #{new_answer.class}" unless new_answer.kind_of? Array or new_answer.kind_of? String
|
40
42
|
answer ||= []
|
41
43
|
answer << new_answer
|
42
44
|
when :hash
|
43
|
-
raise Exception, "Hiera type mismatch: expected Hash and got #{new_answer.class}" unless new_answer.kind_of? Hash
|
45
|
+
raise Exception, "Hiera type mismatch for key '#{key}': expected Hash and got #{new_answer.class}" unless new_answer.kind_of? Hash
|
44
46
|
answer ||= {}
|
45
|
-
answer = Backend.merge_answer(new_answer,answer)
|
47
|
+
answer = Backend.merge_answer(new_answer, answer, resolution_type)
|
46
48
|
else
|
47
49
|
answer = new_answer
|
48
50
|
break
|
49
51
|
end
|
50
52
|
end
|
51
|
-
|
53
|
+
throw :no_such_key unless found
|
52
54
|
return answer
|
53
55
|
end
|
54
56
|
end
|
@@ -8,8 +8,9 @@ class Hiera
|
|
8
8
|
@cache = cache || Filecache.new
|
9
9
|
end
|
10
10
|
|
11
|
-
def lookup(key, scope, order_override, resolution_type)
|
11
|
+
def lookup(key, scope, order_override, resolution_type, context)
|
12
12
|
answer = nil
|
13
|
+
found = false
|
13
14
|
|
14
15
|
Hiera.debug("Looking up #{key} in YAML backend")
|
15
16
|
|
@@ -20,6 +21,7 @@ class Hiera
|
|
20
21
|
|
21
22
|
next if data.empty?
|
22
23
|
next unless data.include?(key)
|
24
|
+
found = true
|
23
25
|
|
24
26
|
# Extra logging that we found the key. This can be outputted
|
25
27
|
# multiple times if the resolution type is array or hash but that
|
@@ -32,22 +34,22 @@ class Hiera
|
|
32
34
|
# the array
|
33
35
|
#
|
34
36
|
# for priority searches we break after the first found data item
|
35
|
-
new_answer = Backend.parse_answer(data[key], scope)
|
36
|
-
case resolution_type
|
37
|
+
new_answer = Backend.parse_answer(data[key], scope, {}, context)
|
38
|
+
case resolution_type.is_a?(Hash) ? :hash : resolution_type
|
37
39
|
when :array
|
38
|
-
raise Exception, "Hiera type mismatch: expected Array and got #{new_answer.class}" unless new_answer.kind_of? Array or new_answer.kind_of? String
|
40
|
+
raise Exception, "Hiera type mismatch for key '#{key}': expected Array and got #{new_answer.class}" unless new_answer.kind_of? Array or new_answer.kind_of? String
|
39
41
|
answer ||= []
|
40
42
|
answer << new_answer
|
41
43
|
when :hash
|
42
|
-
raise Exception, "Hiera type mismatch: expected Hash and got #{new_answer.class}" unless new_answer.kind_of? Hash
|
44
|
+
raise Exception, "Hiera type mismatch for key '#{key}': expected Hash and got #{new_answer.class}" unless new_answer.kind_of? Hash
|
43
45
|
answer ||= {}
|
44
|
-
answer = Backend.merge_answer(new_answer,answer)
|
46
|
+
answer = Backend.merge_answer(new_answer, answer, resolution_type)
|
45
47
|
else
|
46
48
|
answer = new_answer
|
47
49
|
break
|
48
50
|
end
|
49
51
|
end
|
50
|
-
|
52
|
+
throw :no_such_key unless found
|
51
53
|
return answer
|
52
54
|
end
|
53
55
|
|
data/lib/hiera/config.rb
CHANGED
@@ -54,9 +54,7 @@ class Hiera::Config
|
|
54
54
|
begin
|
55
55
|
require "deep_merge"
|
56
56
|
rescue LoadError
|
57
|
-
Hiera
|
58
|
-
Hiera.warn "Must have 'deep_merge' gem installed."
|
59
|
-
@config[:merge_behavior] = :native
|
57
|
+
raise Hiera::Error, "Must have 'deep_merge' gem installed for the configured merge_behavior."
|
60
58
|
end
|
61
59
|
end
|
62
60
|
end
|
data/lib/hiera/interpolate.rb
CHANGED
@@ -1,30 +1,57 @@
|
|
1
1
|
require 'hiera/backend'
|
2
2
|
require 'hiera/recursive_guard'
|
3
3
|
|
4
|
+
|
5
|
+
class Hiera::InterpolationInvalidValue < StandardError; end
|
6
|
+
|
4
7
|
class Hiera::Interpolate
|
5
8
|
class << self
|
6
9
|
INTERPOLATION = /%\{([^\}]*)\}/
|
7
|
-
METHOD_INTERPOLATION = /%\{(scope|hiera)\(['"]([^"']*)["']\)\}/
|
10
|
+
METHOD_INTERPOLATION = /%\{(scope|hiera|literal|alias)\(['"]([^"']*)["']\)\}/
|
8
11
|
|
9
|
-
def interpolate(data, scope, extra_data)
|
12
|
+
def interpolate(data, scope, extra_data, context)
|
10
13
|
if data.is_a?(String)
|
11
14
|
# Wrapping do_interpolation in a gsub block ensures we process
|
12
15
|
# each interpolation site in isolation using separate recursion guards.
|
16
|
+
context ||= {}
|
17
|
+
new_context = context.clone
|
18
|
+
new_context[:recurse_guard] ||= Hiera::RecursiveGuard.new
|
13
19
|
data.gsub(INTERPOLATION) do |match|
|
14
|
-
do_interpolation(match,
|
20
|
+
interp_val = do_interpolation(match, scope, extra_data, new_context)
|
21
|
+
|
22
|
+
# Get interp method in case we are aliasing
|
23
|
+
if data.is_a?(String) && (match = data.match(INTERPOLATION))
|
24
|
+
interpolate_method, key = get_interpolation_method_and_key(data)
|
25
|
+
else
|
26
|
+
interpolate_method = nil
|
27
|
+
end
|
28
|
+
|
29
|
+
if ( (interpolate_method == :alias_interpolate) and (!interp_val.is_a?(String)) )
|
30
|
+
if data.match("^#{INTERPOLATION}$")
|
31
|
+
return interp_val
|
32
|
+
else
|
33
|
+
raise Hiera::InterpolationInvalidValue, "Cannot call alias in the string context"
|
34
|
+
end
|
35
|
+
else
|
36
|
+
interp_val
|
37
|
+
end
|
15
38
|
end
|
16
39
|
else
|
17
40
|
data
|
18
41
|
end
|
19
42
|
end
|
20
43
|
|
21
|
-
def do_interpolation(data,
|
44
|
+
def do_interpolation(data, scope, extra_data, context)
|
22
45
|
if data.is_a?(String) && (match = data.match(INTERPOLATION))
|
23
46
|
interpolation_variable = match[1]
|
24
|
-
recurse_guard.check(interpolation_variable) do
|
47
|
+
context[:recurse_guard].check(interpolation_variable) do
|
25
48
|
interpolate_method, key = get_interpolation_method_and_key(data)
|
26
|
-
interpolated_data = send(interpolate_method, data, key, scope, extra_data)
|
27
|
-
|
49
|
+
interpolated_data = send(interpolate_method, data, key, scope, extra_data, context)
|
50
|
+
|
51
|
+
# Halt recursion if we encounter a literal.
|
52
|
+
return interpolated_data if interpolate_method == :literal_interpolate
|
53
|
+
|
54
|
+
do_interpolation(interpolated_data, scope, extra_data, context)
|
28
55
|
end
|
29
56
|
else
|
30
57
|
data
|
@@ -37,6 +64,8 @@ class Hiera::Interpolate
|
|
37
64
|
case match[1]
|
38
65
|
when 'hiera' then [:hiera_interpolate, match[2]]
|
39
66
|
when 'scope' then [:scope_interpolate, match[2]]
|
67
|
+
when 'literal' then [:literal_interpolate, match[2]]
|
68
|
+
when 'alias' then [:alias_interpolate, match[2]]
|
40
69
|
end
|
41
70
|
elsif (match = data.match(INTERPOLATION))
|
42
71
|
[:scope_interpolate, match[1]]
|
@@ -44,19 +73,26 @@ class Hiera::Interpolate
|
|
44
73
|
end
|
45
74
|
private :get_interpolation_method_and_key
|
46
75
|
|
47
|
-
def scope_interpolate(data, key, scope, extra_data)
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
end
|
52
|
-
|
53
|
-
value
|
76
|
+
def scope_interpolate(data, key, scope, extra_data, context)
|
77
|
+
segments = key.split('.')
|
78
|
+
catch(:no_such_key) { return Hiera::Backend.qualified_lookup(segments, scope) }
|
79
|
+
catch(:no_such_key) { Hiera::Backend.qualified_lookup(segments, extra_data) }
|
54
80
|
end
|
55
81
|
private :scope_interpolate
|
56
82
|
|
57
|
-
def hiera_interpolate(data, key, scope, extra_data)
|
58
|
-
Hiera::Backend.lookup(key, nil, scope,
|
83
|
+
def hiera_interpolate(data, key, scope, extra_data, context)
|
84
|
+
Hiera::Backend.lookup(key, nil, scope, context[:order_override], :priority, context)
|
59
85
|
end
|
60
86
|
private :hiera_interpolate
|
87
|
+
|
88
|
+
def literal_interpolate(data, key, scope, extra_data, context)
|
89
|
+
key
|
90
|
+
end
|
91
|
+
private :literal_interpolate
|
92
|
+
|
93
|
+
def alias_interpolate(data, key, scope, extra_data, context)
|
94
|
+
Hiera::Backend.lookup(key, nil, scope, context[:order_override], :priority, context)
|
95
|
+
end
|
96
|
+
private :alias_interpolate
|
61
97
|
end
|
62
98
|
end
|
data/lib/hiera/util.rb
CHANGED
@@ -9,7 +9,7 @@ class Hiera
|
|
9
9
|
|
10
10
|
def microsoft_windows?
|
11
11
|
return false unless file_alt_separator
|
12
|
-
|
12
|
+
|
13
13
|
begin
|
14
14
|
require 'win32/dir'
|
15
15
|
true
|
@@ -21,17 +21,17 @@ class Hiera
|
|
21
21
|
|
22
22
|
def config_dir
|
23
23
|
if microsoft_windows?
|
24
|
-
File.join(common_appdata, 'PuppetLabs', '
|
24
|
+
File.join(common_appdata, 'PuppetLabs', 'code')
|
25
25
|
else
|
26
|
-
'/etc'
|
26
|
+
'/etc/puppetlabs/code'
|
27
27
|
end
|
28
28
|
end
|
29
29
|
|
30
30
|
def var_dir
|
31
31
|
if microsoft_windows?
|
32
|
-
File.join(common_appdata, 'PuppetLabs', '
|
32
|
+
File.join(common_appdata, 'PuppetLabs', 'code', 'hieradata')
|
33
33
|
else
|
34
|
-
'/
|
34
|
+
'/etc/puppetlabs/code/hieradata'
|
35
35
|
end
|
36
36
|
end
|
37
37
|
|
data/lib/hiera/version.rb
CHANGED
data/spec/spec_helper.rb
CHANGED
@@ -9,6 +9,13 @@ require 'tmpdir'
|
|
9
9
|
RSpec.configure do |config|
|
10
10
|
config.mock_with :mocha
|
11
11
|
|
12
|
+
if Hiera::Util.microsoft_windows? && RUBY_VERSION =~ /^1\./
|
13
|
+
require 'win32console'
|
14
|
+
config.output_stream = $stdout
|
15
|
+
config.error_stream = $stderr
|
16
|
+
config.formatters.each { |f| f.instance_variable_set(:@output, $stdout) }
|
17
|
+
end
|
18
|
+
|
12
19
|
config.after :suite do
|
13
20
|
# Log the spec order to a file, but only if the LOG_SPEC_ORDER environment variable is
|
14
21
|
# set. This should be enabled on Jenkins runs, as it can be used with Nick L.'s bisect
|
@@ -21,6 +28,11 @@ RSpec.configure do |config|
|
|
21
28
|
end
|
22
29
|
end
|
23
30
|
|
31
|
+
# So everyone else doesn't have to include this base constant.
|
32
|
+
module HieraSpec
|
33
|
+
FIXTURE_DIR = File.join(dir = File.expand_path(File.dirname(__FILE__)), 'unit', 'fixtures') unless defined?(FIXTURE_DIR)
|
34
|
+
end
|
35
|
+
|
24
36
|
# In ruby 1.8.5 Dir does not have mktmpdir defined, so this monkey patches
|
25
37
|
# Dir to include the 1.8.7 definition of that method if it isn't already defined.
|
26
38
|
# Method definition borrowed from ruby-1.8.7-p357/lib/ruby/1.8/tmpdir.rb
|
@@ -25,7 +25,7 @@ class Hiera
|
|
25
25
|
Backend.expects(:datafile).with(:json, {}, "one", "json").returns(nil)
|
26
26
|
Backend.expects(:datafile).with(:json, {}, "two", "json").returns(nil)
|
27
27
|
|
28
|
-
@backend.lookup("key", {}, nil, :priority)
|
28
|
+
expect { @backend.lookup("key", {}, nil, :priority, nil) }.to throw_symbol(:no_such_key)
|
29
29
|
end
|
30
30
|
|
31
31
|
it "should retain the data types found in data files" do
|
@@ -35,9 +35,9 @@ class Hiera
|
|
35
35
|
|
36
36
|
@cache.expects(:read_file).with("/nonexisting/one.json", Hash).returns({"stringval" => "string", "boolval" => true, "numericval" => 1}).times(3)
|
37
37
|
|
38
|
-
@backend.lookup("stringval", {}, nil, :priority).should == "string"
|
39
|
-
@backend.lookup("boolval", {}, nil, :priority).should == true
|
40
|
-
@backend.lookup("numericval", {}, nil, :priority).should == 1
|
38
|
+
@backend.lookup("stringval", {}, nil, :priority, nil).should == "string"
|
39
|
+
@backend.lookup("boolval", {}, nil, :priority, nil).should == true
|
40
|
+
@backend.lookup("numericval", {}, nil, :priority, nil).should == 1
|
41
41
|
end
|
42
42
|
|
43
43
|
it "should pick data earliest source that has it for priority searches" do
|
@@ -49,12 +49,12 @@ class Hiera
|
|
49
49
|
File.stubs(:exist?).with("/nonexisting/one.json").returns(true)
|
50
50
|
@cache.expects(:read_file).with("/nonexisting/one.json", Hash).returns({"key" => "test_%{rspec}"})
|
51
51
|
|
52
|
-
@backend.lookup("key", scope, nil, :priority).should == "test_test"
|
52
|
+
@backend.lookup("key", scope, nil, :priority, nil).should == "test_test"
|
53
53
|
end
|
54
54
|
|
55
55
|
it "should build an array of all data sources for array searches" do
|
56
56
|
Hiera::Backend.stubs(:empty_answer).returns([])
|
57
|
-
Backend.stubs(:parse_answer).with('answer', {}).returns("answer")
|
57
|
+
Backend.stubs(:parse_answer).with('answer', {}, {}, anything).returns("answer")
|
58
58
|
Backend.expects(:datafile).with(:json, {}, "one", "json").returns("/nonexisting/one.json")
|
59
59
|
Backend.expects(:datafile).with(:json, {}, "two", "json").returns("/nonexisting/two.json")
|
60
60
|
|
@@ -66,18 +66,18 @@ class Hiera
|
|
66
66
|
@cache.expects(:read_file).with("/nonexisting/one.json", Hash).returns({"key" => "answer"})
|
67
67
|
@cache.expects(:read_file).with("/nonexisting/two.json", Hash).returns({"key" => "answer"})
|
68
68
|
|
69
|
-
@backend.lookup("key", {}, nil, :array).should == ["answer", "answer"]
|
69
|
+
@backend.lookup("key", {}, nil, :array, nil).should == ["answer", "answer"]
|
70
70
|
end
|
71
71
|
|
72
72
|
it "should parse the answer for scope variables" do
|
73
|
-
Backend.stubs(:parse_answer).with('test_%{rspec}', {'rspec' => 'test'}).returns("test_test")
|
73
|
+
Backend.stubs(:parse_answer).with('test_%{rspec}', {'rspec' => 'test'}, {}, anything).returns("test_test")
|
74
74
|
Backend.expects(:datasources).yields("one")
|
75
75
|
Backend.expects(:datafile).with(:json, {"rspec" => "test"}, "one", "json").returns("/nonexisting/one.json")
|
76
76
|
|
77
77
|
File.expects(:exist?).with("/nonexisting/one.json").returns(true)
|
78
78
|
@cache.expects(:read_file).with("/nonexisting/one.json", Hash).returns({"key" => "test_%{rspec}"})
|
79
79
|
|
80
|
-
@backend.lookup("key", {"rspec" => "test"}, nil, :priority).should == "test_test"
|
80
|
+
@backend.lookup("key", {"rspec" => "test"}, nil, :priority, nil).should == "test_test"
|
81
81
|
end
|
82
82
|
end
|
83
83
|
end
|
@@ -41,7 +41,7 @@ class Hiera
|
|
41
41
|
Backend.expects(:datasourcefiles).with(:yaml, {}, "yaml", nil).yields(["one", "/nonexisting/one.yaml"])
|
42
42
|
@cache.value = "---\nkey: answer"
|
43
43
|
|
44
|
-
@backend.lookup("key", {}, nil, :priority).should == "answer"
|
44
|
+
@backend.lookup("key", {}, nil, :priority, nil).should == "answer"
|
45
45
|
end
|
46
46
|
|
47
47
|
describe "handling unexpected YAML values" do
|
@@ -49,19 +49,24 @@ class Hiera
|
|
49
49
|
Backend.expects(:datasourcefiles).with(:yaml, {}, "yaml", nil).yields(["one", "/nonexisting/one.yaml"])
|
50
50
|
end
|
51
51
|
|
52
|
-
it "
|
52
|
+
it "throws :no_such_key when key is missing in YAML" do
|
53
53
|
@cache.value = "---\n"
|
54
|
-
@backend.lookup("key", {}, nil, :priority).
|
54
|
+
expect { @backend.lookup("key", {}, nil, :priority, nil) }.to throw_symbol(:no_such_key)
|
55
|
+
end
|
56
|
+
|
57
|
+
it "returns nil when the YAML value is nil" do
|
58
|
+
@cache.value = "key: ~\n"
|
59
|
+
@backend.lookup("key", {}, nil, :priority, nil).should be_nil
|
55
60
|
end
|
56
61
|
|
57
|
-
it "
|
62
|
+
it "throws :no_such_key when the YAML file is false" do
|
58
63
|
@cache.value = ""
|
59
|
-
@backend.lookup("key", {}, nil, :priority).
|
64
|
+
expect { @backend.lookup("key", {}, nil, :priority, nil) }.to throw_symbol(:no_such_key)
|
60
65
|
end
|
61
66
|
|
62
67
|
it "raises a TypeError when the YAML value is not a hash" do
|
63
68
|
@cache.value = "---\n[one, two, three]"
|
64
|
-
expect { @backend.lookup("key", {}, nil, :priority) }.to raise_error(TypeError)
|
69
|
+
expect { @backend.lookup("key", {}, nil, :priority, nil) }.to raise_error(TypeError)
|
65
70
|
end
|
66
71
|
end
|
67
72
|
|
@@ -70,7 +75,7 @@ class Hiera
|
|
70
75
|
@cache.expects(:read_file).with("/nonexisting/one.yaml", Hash).returns({"key"=>"answer"})
|
71
76
|
@cache.expects(:read_file).with("/nonexisting/two.yaml", Hash).returns({"key"=>"answer"})
|
72
77
|
|
73
|
-
@backend.lookup("key", {}, nil, :array).should == ["answer", "answer"]
|
78
|
+
@backend.lookup("key", {}, nil, :array, nil).should == ["answer", "answer"]
|
74
79
|
end
|
75
80
|
|
76
81
|
it "should ignore empty hash of data sources for hash searches" do
|
@@ -79,7 +84,7 @@ class Hiera
|
|
79
84
|
@cache.expects(:read_file).with("/nonexisting/one.yaml", Hash).returns({})
|
80
85
|
@cache.expects(:read_file).with("/nonexisting/two.yaml", Hash).returns({"key"=>{"a"=>"answer"}})
|
81
86
|
|
82
|
-
@backend.lookup("key", {}, nil, :hash).should == {"a" => "answer"}
|
87
|
+
@backend.lookup("key", {}, nil, :hash, nil).should == {"a" => "answer"}
|
83
88
|
end
|
84
89
|
|
85
90
|
it "should build a merged hash of data sources for hash searches" do
|
@@ -88,7 +93,7 @@ class Hiera
|
|
88
93
|
@cache.expects(:read_file).with("/nonexisting/one.yaml", Hash).returns({"key"=>{"a"=>"answer"}})
|
89
94
|
@cache.expects(:read_file).with("/nonexisting/two.yaml", Hash).returns({"key"=>{"b"=>"answer", "a"=>"wrong"}})
|
90
95
|
|
91
|
-
@backend.lookup("key", {}, nil, :hash).should == {"a" => "answer", "b" => "answer"}
|
96
|
+
@backend.lookup("key", {}, nil, :hash, nil).should == {"a" => "answer", "b" => "answer"}
|
92
97
|
end
|
93
98
|
|
94
99
|
it "should fail when trying to << a Hash" do
|
@@ -97,7 +102,7 @@ class Hiera
|
|
97
102
|
@cache.expects(:read_file).with("/nonexisting/one.yaml", Hash).returns({"key"=>["a", "answer"]})
|
98
103
|
@cache.expects(:read_file).with("/nonexisting/two.yaml", Hash).returns({"key"=>{"a"=>"answer"}})
|
99
104
|
|
100
|
-
expect {@backend.lookup("key", {}, nil, :array)}.to raise_error(Exception, "Hiera type mismatch: expected Array and got Hash")
|
105
|
+
expect {@backend.lookup("key", {}, nil, :array, nil)}.to raise_error(Exception, "Hiera type mismatch for key 'key': expected Array and got Hash")
|
101
106
|
end
|
102
107
|
|
103
108
|
it "should fail when trying to merge an Array" do
|
@@ -106,7 +111,7 @@ class Hiera
|
|
106
111
|
@cache.expects(:read_file).with("/nonexisting/one.yaml", Hash).returns({"key"=>{"a"=>"answer"}})
|
107
112
|
@cache.expects(:read_file).with("/nonexisting/two.yaml", Hash).returns({"key"=>["a", "wrong"]})
|
108
113
|
|
109
|
-
expect { @backend.lookup("key", {}, nil, :hash) }.to raise_error(Exception, "Hiera type mismatch: expected Hash and got Array")
|
114
|
+
expect { @backend.lookup("key", {}, nil, :hash, nil) }.to raise_error(Exception, "Hiera type mismatch for key 'key': expected Hash and got Array")
|
110
115
|
end
|
111
116
|
|
112
117
|
it "should parse the answer for scope variables" do
|
@@ -114,7 +119,7 @@ class Hiera
|
|
114
119
|
|
115
120
|
@cache.expects(:read_file).with("/nonexisting/one.yaml", Hash).returns({"key"=>"test_%{rspec}"})
|
116
121
|
|
117
|
-
@backend.lookup("key", {"rspec" => "test"}, nil, :priority).should == "test_test"
|
122
|
+
@backend.lookup("key", {"rspec" => "test"}, nil, :priority, nil).should == "test_test"
|
118
123
|
end
|
119
124
|
|
120
125
|
it "should retain datatypes found in yaml files" do
|
@@ -123,9 +128,9 @@ class Hiera
|
|
123
128
|
|
124
129
|
@cache.value = "---\nstringval: 'string'\nboolval: true\nnumericval: 1"
|
125
130
|
|
126
|
-
@backend.lookup("stringval", {}, nil, :priority).should == "string"
|
127
|
-
@backend.lookup("boolval", {}, nil, :priority).should == true
|
128
|
-
@backend.lookup("numericval", {}, nil, :priority).should == 1
|
131
|
+
@backend.lookup("stringval", {}, nil, :priority, nil).should == "string"
|
132
|
+
@backend.lookup("boolval", {}, nil, :priority, nil).should == true
|
133
|
+
@backend.lookup("numericval", {}, nil, :priority, nil).should == 1
|
129
134
|
end
|
130
135
|
end
|
131
136
|
end
|
data/spec/unit/backend_spec.rb
CHANGED
@@ -2,6 +2,14 @@ require 'spec_helper'
|
|
2
2
|
require 'hiera/util'
|
3
3
|
|
4
4
|
class Hiera
|
5
|
+
module Backend
|
6
|
+
class Backend1x_backend
|
7
|
+
def lookup(key, scope, order_override, resolution_type)
|
8
|
+
["a", "b"]
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
5
13
|
describe Backend do
|
6
14
|
describe "#datadir" do
|
7
15
|
it "interpolates any values in the configured value" do
|
@@ -84,7 +92,7 @@ class Hiera
|
|
84
92
|
end
|
85
93
|
|
86
94
|
it "parses the names of the hierarchy levels using the given scope" do
|
87
|
-
Backend.expects(:parse_string).with("common", {:rspec => :tests})
|
95
|
+
Backend.expects(:parse_string).with("common", {:rspec => :tests}, {}, {:order_override => nil})
|
88
96
|
Backend.datasources({:rspec => :tests}) { }
|
89
97
|
end
|
90
98
|
|
@@ -181,17 +189,6 @@ class Hiera
|
|
181
189
|
"test_%{scope('rspec')}_test" => "test__test"
|
182
190
|
}
|
183
191
|
|
184
|
-
@interprets_undefined_in_scope_tests.each do |input, expected|
|
185
|
-
it "interprets :undefined in scope as a non-value" do
|
186
|
-
Backend.parse_string(input, {"rspec" => :undefined}).should == expected
|
187
|
-
end
|
188
|
-
end
|
189
|
-
|
190
|
-
it "uses the value from extra_data when scope is :undefined" do
|
191
|
-
input = "test_%{rspec}_test"
|
192
|
-
Backend.parse_string(input, {"rspec" => :undefined}, { "rspec" => "extra" }).should == "test_extra_test"
|
193
|
-
end
|
194
|
-
|
195
192
|
@exact_lookup_tests = {
|
196
193
|
"test_%{::rspec::data}_test" => "test_value_test",
|
197
194
|
"test_%{scope('::rspec::data')}_test" => "test_value_test"
|
@@ -264,10 +261,21 @@ class Hiera
|
|
264
261
|
scope = {}
|
265
262
|
Config.load({:yaml => {:datadir => "/tmp"}})
|
266
263
|
Config.load_backends
|
267
|
-
Backend::Yaml_backend.any_instance.stubs(:lookup).with("key1", scope, nil, :priority).returns("answer")
|
264
|
+
Backend::Yaml_backend.any_instance.stubs(:lookup).with("key1", scope, nil, :priority, instance_of(Hash)).returns("answer")
|
268
265
|
|
269
266
|
Backend.parse_string(input, scope).should == "answer"
|
270
267
|
end
|
268
|
+
|
269
|
+
it "interpolation passes the order_override back into the backend" do
|
270
|
+
Backend.expects(:lookup).with("lookup::key", nil, {}, "order_override_datasource", :priority, instance_of(Hash))
|
271
|
+
Backend.parse_string("%{hiera('lookup::key')}", {}, {}, {:order_override => "order_override_datasource"})
|
272
|
+
end
|
273
|
+
|
274
|
+
it "replaces literal interpolations with their argument" do
|
275
|
+
scope = {}
|
276
|
+
input = "%{literal('%')}{rspec::data}"
|
277
|
+
Backend.parse_string(input, scope).should == "%{rspec::data}"
|
278
|
+
end
|
271
279
|
end
|
272
280
|
|
273
281
|
describe "#parse_answer" do
|
@@ -306,16 +314,47 @@ class Hiera
|
|
306
314
|
scope = {}
|
307
315
|
Config.load({:yaml => {:datadir => "/tmp"}})
|
308
316
|
Config.load_backends
|
309
|
-
Backend::Yaml_backend.any_instance.stubs(:lookup).with("rspec", scope, nil, :priority).returns("test")
|
317
|
+
Backend::Yaml_backend.any_instance.stubs(:lookup).with("rspec", scope, nil, :priority, instance_of(Hash)).returns("test")
|
310
318
|
Backend.parse_answer(input, scope).should == "test_test_test"
|
311
319
|
end
|
312
320
|
|
321
|
+
it "interpolates alias lookups with non-string types" do
|
322
|
+
input = "%{alias('rspec')}"
|
323
|
+
scope = {}
|
324
|
+
Config.load({:yaml => {:datadir => "/tmp"}})
|
325
|
+
Config.load_backends
|
326
|
+
Backend::Yaml_backend.any_instance.stubs(:lookup).with("rspec", scope, nil, :priority, instance_of(Hash)).returns(['test', 'test'])
|
327
|
+
Backend.parse_answer(input, scope).should == ['test', 'test']
|
328
|
+
end
|
329
|
+
|
330
|
+
it 'fails if alias interpolation is attempted in a string context with a prefix' do
|
331
|
+
input = "stuff_before%{alias('rspec')}"
|
332
|
+
scope = {}
|
333
|
+
Config.load({:yaml => {:datadir => "/tmp"}})
|
334
|
+
Config.load_backends
|
335
|
+
Backend::Yaml_backend.any_instance.stubs(:lookup).with("rspec", scope, nil, :priority, instance_of(Hash)).returns(['test', 'test'])
|
336
|
+
expect do
|
337
|
+
Backend.parse_answer(input, scope).should == ['test', 'test']
|
338
|
+
end.to raise_error(Hiera::InterpolationInvalidValue, 'Cannot call alias in the string context')
|
339
|
+
end
|
340
|
+
|
341
|
+
it 'fails if alias interpolation is attempted in a string context with a postfix' do
|
342
|
+
input = "%{alias('rspec')}_stiff after"
|
343
|
+
scope = {}
|
344
|
+
Config.load({:yaml => {:datadir => "/tmp"}})
|
345
|
+
Config.load_backends
|
346
|
+
Backend::Yaml_backend.any_instance.stubs(:lookup).with("rspec", scope, nil, :priority, instance_of(Hash)).returns(['test', 'test'])
|
347
|
+
expect do
|
348
|
+
Backend.parse_answer(input, scope).should == ['test', 'test']
|
349
|
+
end.to raise_error(Hiera::InterpolationInvalidValue, 'Cannot call alias in the string context')
|
350
|
+
end
|
351
|
+
|
313
352
|
it "interpolates hiera lookups in each string in an array" do
|
314
353
|
input = ["test_%{hiera('rspec')}_test", "test_%{hiera('rspec')}_test", ["test_%{hiera('rspec')}_test"]]
|
315
354
|
scope = {}
|
316
355
|
Config.load({:yaml => {:datadir => "/tmp"}})
|
317
356
|
Config.load_backends
|
318
|
-
Backend::Yaml_backend.any_instance.stubs(:lookup).with("rspec", scope, nil, :priority).returns("test")
|
357
|
+
Backend::Yaml_backend.any_instance.stubs(:lookup).with("rspec", scope, nil, :priority, instance_of(Hash)).returns("test")
|
319
358
|
Backend.parse_answer(input, scope).should == ["test_test_test", "test_test_test", ["test_test_test"]]
|
320
359
|
end
|
321
360
|
|
@@ -324,7 +363,7 @@ class Hiera
|
|
324
363
|
scope = {}
|
325
364
|
Config.load({:yaml => {:datadir => "/tmp"}})
|
326
365
|
Config.load_backends
|
327
|
-
Backend::Yaml_backend.any_instance.stubs(:lookup).with("rspec", scope, nil, :priority).returns("test")
|
366
|
+
Backend::Yaml_backend.any_instance.stubs(:lookup).with("rspec", scope, nil, :priority, instance_of(Hash)).returns("test")
|
328
367
|
Backend.parse_answer(input, scope).should == {"foo"=>"test_test_test", "bar"=>"test_test_test"}
|
329
368
|
end
|
330
369
|
|
@@ -333,7 +372,7 @@ class Hiera
|
|
333
372
|
scope = {}
|
334
373
|
Config.load({:yaml => {:datadir => "/tmp"}})
|
335
374
|
Config.load_backends
|
336
|
-
Backend::Yaml_backend.any_instance.stubs(:lookup).with("rspec", scope, nil, :priority).returns("foo")
|
375
|
+
Backend::Yaml_backend.any_instance.stubs(:lookup).with("rspec", scope, nil, :priority, instance_of(Hash)).returns("foo")
|
337
376
|
Backend.parse_answer(input, scope).should == {"foo"=>"test"}
|
338
377
|
end
|
339
378
|
|
@@ -342,7 +381,7 @@ class Hiera
|
|
342
381
|
scope = {}
|
343
382
|
Config.load({:yaml => {:datadir => "/tmp"}})
|
344
383
|
Config.load_backends
|
345
|
-
Backend::Yaml_backend.any_instance.stubs(:lookup).with("rspec", scope, nil, :priority).returns("foo")
|
384
|
+
Backend::Yaml_backend.any_instance.stubs(:lookup).with("rspec", scope, nil, :priority, instance_of(Hash)).returns("foo")
|
346
385
|
Backend.parse_answer(input, scope).should == {"topkey"=>{"foo" => "test"}}
|
347
386
|
end
|
348
387
|
|
@@ -351,7 +390,7 @@ class Hiera
|
|
351
390
|
scope = {}
|
352
391
|
Config.load({:yaml => {:datadir => "/tmp"}})
|
353
392
|
Config.load_backends
|
354
|
-
Backend::Yaml_backend.any_instance.stubs(:lookup).with("rspec", scope, nil, :priority).returns("test")
|
393
|
+
Backend::Yaml_backend.any_instance.stubs(:lookup).with("rspec", scope, nil, :priority, instance_of(Hash)).returns("test")
|
355
394
|
Backend.parse_answer(input, scope).should == {"foo"=>"test_test_test", "bar"=>["test_test_test", "test_test_test"]}
|
356
395
|
end
|
357
396
|
|
@@ -360,7 +399,7 @@ class Hiera
|
|
360
399
|
scope = {"rspec2" => "scope_rspec"}
|
361
400
|
Config.load({:yaml => {:datadir => "/tmp"}})
|
362
401
|
Config.load_backends
|
363
|
-
Backend::Yaml_backend.any_instance.stubs(:lookup).with("rspec", scope, nil, :priority).returns("hiera_rspec")
|
402
|
+
Backend::Yaml_backend.any_instance.stubs(:lookup).with("rspec", scope, nil, :priority, instance_of(Hash)).returns("hiera_rspec")
|
364
403
|
Backend.parse_answer(input, scope).should == {"foo"=>"test_hiera_rspec_test", "bar"=>"test_scope_rspec_test"}
|
365
404
|
end
|
366
405
|
|
@@ -369,7 +408,7 @@ class Hiera
|
|
369
408
|
scope = {"rspec" => "scope_rspec"}
|
370
409
|
Config.load({:yaml => {:datadir => "/tmp"}})
|
371
410
|
Config.load_backends
|
372
|
-
Backend::Yaml_backend.any_instance.stubs(:lookup).with("rspec", scope, nil, :priority).returns("hiera_rspec")
|
411
|
+
Backend::Yaml_backend.any_instance.stubs(:lookup).with("rspec", scope, nil, :priority, instance_of(Hash)).returns("hiera_rspec")
|
373
412
|
Backend.parse_answer(input, scope).should == "test_hiera_rspec_test_scope_rspec"
|
374
413
|
end
|
375
414
|
|
@@ -431,7 +470,7 @@ class Hiera
|
|
431
470
|
Config.load({:yaml => {:datadir => "/tmp"}})
|
432
471
|
Config.load_backends
|
433
472
|
|
434
|
-
Backend::Yaml_backend.any_instance.expects(:lookup).with("key", {}, nil, nil).returns("answer")
|
473
|
+
Backend::Yaml_backend.any_instance.expects(:lookup).with("key", {}, nil, nil, instance_of(Hash)).returns("answer")
|
435
474
|
|
436
475
|
Backend.lookup("key", "default", {}, nil, nil).should == "answer"
|
437
476
|
end
|
@@ -440,9 +479,9 @@ class Hiera
|
|
440
479
|
Config.load({:yaml => {:datadir => "/tmp"}})
|
441
480
|
Config.load_backends
|
442
481
|
|
443
|
-
Backend::Yaml_backend.any_instance.expects(:lookup).with("stringval", {}, nil, nil).returns("string")
|
444
|
-
Backend::Yaml_backend.any_instance.expects(:lookup).with("boolval", {}, nil, nil).returns(false)
|
445
|
-
Backend::Yaml_backend.any_instance.expects(:lookup).with("numericval", {}, nil, nil).returns(1)
|
482
|
+
Backend::Yaml_backend.any_instance.expects(:lookup).with("stringval", {}, nil, nil, instance_of(Hash)).returns("string")
|
483
|
+
Backend::Yaml_backend.any_instance.expects(:lookup).with("boolval", {}, nil, nil, instance_of(Hash)).returns(false)
|
484
|
+
Backend::Yaml_backend.any_instance.expects(:lookup).with("numericval", {}, nil, nil, instance_of(Hash)).returns(1)
|
446
485
|
|
447
486
|
Backend.lookup("stringval", "default", {}, nil, nil).should == "string"
|
448
487
|
Backend.lookup("boolval", "default", {}, nil, nil).should == false
|
@@ -524,7 +563,7 @@ class Hiera
|
|
524
563
|
Config.load_backends
|
525
564
|
|
526
565
|
Backend.expects(:resolve_answer).with("test_test", :priority).returns("parsed")
|
527
|
-
Backend::Yaml_backend.any_instance.expects(:lookup).with("key", {"rspec" => "test"}, nil, :priority).returns("test_test")
|
566
|
+
Backend::Yaml_backend.any_instance.expects(:lookup).with("key", {"rspec" => "test"}, nil, :priority, instance_of(Hash)).returns("test_test")
|
528
567
|
|
529
568
|
Backend.lookup("key", "test_%{rspec}", {"rspec" => "test"}, nil, :priority).should == "parsed"
|
530
569
|
end
|
@@ -533,31 +572,129 @@ class Hiera
|
|
533
572
|
Config.load({:yaml => {:datadir => "/tmp"}})
|
534
573
|
Config.load_backends
|
535
574
|
|
536
|
-
Backend::Yaml_backend.any_instance.expects(:lookup).with("key", {"rspec" => "test"}, nil, nil)
|
575
|
+
Backend::Yaml_backend.any_instance.expects(:lookup).with("key", {"rspec" => "test"}, nil, nil, instance_of(Hash)).throws(:no_such_key)
|
537
576
|
|
538
577
|
Backend.lookup("key", "test_%{rspec}", {"rspec" => "test"}, nil, nil).should == "test_test"
|
539
578
|
end
|
540
579
|
|
580
|
+
it "returns nil instead of the default when key is found with a nil value" do
|
581
|
+
Config.load({:yaml => {:datadir => "/tmp"}})
|
582
|
+
Config.load_backends
|
583
|
+
|
584
|
+
Backend::Yaml_backend.any_instance.expects(:lookup).with("key", {"rspec" => "test"}, nil, nil, instance_of(Hash)).returns(nil)
|
585
|
+
|
586
|
+
Backend.lookup("key", "test_%{rspec}", {"rspec" => "test"}, nil, nil).should == nil
|
587
|
+
end
|
588
|
+
|
541
589
|
it "keeps string default data as a string" do
|
542
590
|
Config.load({:yaml => {:datadir => "/tmp"}})
|
543
591
|
Config.load_backends
|
544
|
-
Backend::Yaml_backend.any_instance.expects(:lookup).with("key", {}, nil, nil)
|
592
|
+
Backend::Yaml_backend.any_instance.expects(:lookup).with("key", {}, nil, nil, instance_of(Hash)).throws(:no_such_key)
|
545
593
|
Backend.lookup("key", "test", {}, nil, nil).should == "test"
|
546
594
|
end
|
547
595
|
|
548
596
|
it "keeps array default data as an array" do
|
549
597
|
Config.load({:yaml => {:datadir => "/tmp"}})
|
550
598
|
Config.load_backends
|
551
|
-
Backend::Yaml_backend.any_instance.expects(:lookup).with("key", {}, nil, :array)
|
599
|
+
Backend::Yaml_backend.any_instance.expects(:lookup).with("key", {}, nil, :array, instance_of(Hash)).throws(:no_such_key)
|
552
600
|
Backend.lookup("key", ["test"], {}, nil, :array).should == ["test"]
|
553
601
|
end
|
554
602
|
|
555
603
|
it "keeps hash default data as a hash" do
|
556
604
|
Config.load({:yaml => {:datadir => "/tmp"}})
|
557
605
|
Config.load_backends
|
558
|
-
Backend::Yaml_backend.any_instance.expects(:lookup).with("key", {}, nil, :hash)
|
606
|
+
Backend::Yaml_backend.any_instance.expects(:lookup).with("key", {}, nil, :hash, instance_of(Hash)).throws(:no_such_key)
|
559
607
|
Backend.lookup("key", {"test" => "value"}, {}, nil, :hash).should == {"test" => "value"}
|
560
608
|
end
|
609
|
+
|
610
|
+
it 'can use qualified key to lookup value in hash' do
|
611
|
+
Config.load({:yaml => {:datadir => '/tmp'}})
|
612
|
+
Config.load_backends
|
613
|
+
Backend::Yaml_backend.any_instance.expects(:lookup).with('key', {}, nil, nil, instance_of(Hash)).returns({ 'test' => 'value'})
|
614
|
+
Backend.lookup('key.test', 'dflt', {}, nil, nil).should == 'value'
|
615
|
+
end
|
616
|
+
|
617
|
+
it 'can use qualified key to lookup value in array' do
|
618
|
+
Config.load({:yaml => {:datadir => '/tmp'}})
|
619
|
+
Config.load_backends
|
620
|
+
Backend::Yaml_backend.any_instance.expects(:lookup).with('key', {}, nil, nil, instance_of(Hash)).returns([ 'first', 'second'])
|
621
|
+
Backend.lookup('key.1', 'dflt', {}, nil, nil).should == 'second'
|
622
|
+
end
|
623
|
+
|
624
|
+
it 'will fail when qualified key is partially found but not expected hash' do
|
625
|
+
Config.load({:yaml => {:datadir => '/tmp'}})
|
626
|
+
Config.load_backends
|
627
|
+
Backend::Yaml_backend.any_instance.expects(:lookup).with('key', {}, nil, nil, instance_of(Hash)).returns(['value 1', 'value 2'])
|
628
|
+
expect do
|
629
|
+
Backend.lookup('key.test', 'dflt', {}, nil, nil)
|
630
|
+
end.to raise_error(Exception, /^Hiera type mismatch:/)
|
631
|
+
end
|
632
|
+
|
633
|
+
it 'will fail when qualified key used with resolution_type :hash' do
|
634
|
+
expect do
|
635
|
+
Backend.lookup('key.test', 'dflt', {}, nil, :hash)
|
636
|
+
end.to raise_error(ArgumentError, /^Resolution type :hash is illegal/)
|
637
|
+
end
|
638
|
+
|
639
|
+
it 'will fail when qualified key used with resolution_type :array' do
|
640
|
+
expect do
|
641
|
+
Backend.lookup('key.test', 'dflt', {}, nil, :array)
|
642
|
+
end.to raise_error(ArgumentError, /^Resolution type :array is illegal/)
|
643
|
+
end
|
644
|
+
|
645
|
+
it 'will succeed when qualified key used with resolution_type :priority' do
|
646
|
+
Config.load({:yaml => {:datadir => '/tmp'}})
|
647
|
+
Config.load_backends
|
648
|
+
Backend::Yaml_backend.any_instance.expects(:lookup).with('key', {}, nil, :priority, instance_of(Hash)).returns({ 'test' => 'value'})
|
649
|
+
Backend.lookup('key.test', 'dflt', {}, nil, :priority).should == 'value'
|
650
|
+
end
|
651
|
+
|
652
|
+
it 'will fail when qualified key is partially found but not expected array' do
|
653
|
+
Config.load({:yaml => {:datadir => '/tmp'}})
|
654
|
+
Config.load_backends
|
655
|
+
Backend::Yaml_backend.any_instance.expects(:lookup).with('key', {}, nil, nil, instance_of(Hash)).returns({ 'test' => 'value'})
|
656
|
+
expect do
|
657
|
+
Backend.lookup('key.2', 'dflt', {}, nil, nil)
|
658
|
+
end.to raise_error(Exception, /^Hiera type mismatch:/)
|
659
|
+
end
|
660
|
+
|
661
|
+
it 'will not fail when qualified key is partially not found' do
|
662
|
+
Config.load({:yaml => {:datadir => '/tmp'}})
|
663
|
+
Config.load_backends
|
664
|
+
Backend::Yaml_backend.any_instance.expects(:lookup).with('key', {}, nil, nil, instance_of(Hash)).returns(nil)
|
665
|
+
Backend.lookup('key.test', 'dflt', {}, nil, nil).should == 'dflt'
|
666
|
+
end
|
667
|
+
|
668
|
+
it 'will not fail when qualified key is array index out of bounds' do
|
669
|
+
Config.load({:yaml => {:datadir => '/tmp'}})
|
670
|
+
Config.load_backends
|
671
|
+
Backend::Yaml_backend.any_instance.expects(:lookup).with('key', {}, nil, nil, instance_of(Hash)).returns(['value 1', 'value 2'])
|
672
|
+
Backend.lookup('key.33', 'dflt', {}, nil, nil).should == 'dflt'
|
673
|
+
end
|
674
|
+
|
675
|
+
it 'can use qualified key in interpolation to lookup value in hash' do
|
676
|
+
Config.load({:yaml => {:datadir => '/tmp'}})
|
677
|
+
Config.load_backends
|
678
|
+
Hiera::Backend.stubs(:datasourcefiles).yields('foo', 'bar')
|
679
|
+
Hiera::Filecache.any_instance.expects(:read_file).at_most(2).returns({'key' => '%{hiera(\'some.subkey\')}', 'some' => { 'subkey' => 'value' }})
|
680
|
+
Backend.lookup('key', 'dflt', {}, nil, nil).should == 'value'
|
681
|
+
end
|
682
|
+
|
683
|
+
it 'can use qualified key in interpolated default and scope' do
|
684
|
+
Config.load({:yaml => {:datadir => '/tmp'}})
|
685
|
+
Config.load_backends
|
686
|
+
scope = { 'some' => { 'test' => 'value'}}
|
687
|
+
Backend::Yaml_backend.any_instance.expects(:lookup).with('key', scope, nil, nil, instance_of(Hash))
|
688
|
+
Backend.lookup('key.notfound', '%{some.test}', scope, nil, nil).should == 'value'
|
689
|
+
end
|
690
|
+
|
691
|
+
it "handles older backend with 4 argument lookup" do
|
692
|
+
Config.load({})
|
693
|
+
Config.instance_variable_set("@config", {:backends => ["Backend1x"]})
|
694
|
+
|
695
|
+
Hiera.expects(:debug).at_least_once.with(regexp_matches /Using Hiera 1.x backend/)
|
696
|
+
Backend.lookup("key", {}, {"rspec" => "test"}, nil, :priority).should == ["a", "b"]
|
697
|
+
end
|
561
698
|
end
|
562
699
|
|
563
700
|
describe '#merge_answer' do
|
@@ -575,13 +712,30 @@ class Hiera
|
|
575
712
|
|
576
713
|
it "uses deep_merge! when configured with :merge_behavior => :deeper" do
|
577
714
|
Config.load({:merge_behavior => :deeper})
|
578
|
-
Hash.any_instance.expects('deep_merge!').with({"b" => "bnswer"}).returns({"a" => "answer", "b" => "bnswer"})
|
715
|
+
Hash.any_instance.expects('deep_merge!').with({"b" => "bnswer"}, {}).returns({"a" => "answer", "b" => "bnswer"})
|
579
716
|
Backend.merge_answer({"a" => "answer"},{"b" => "bnswer"}).should == {"a" => "answer", "b" => "bnswer"}
|
580
717
|
end
|
581
718
|
|
582
719
|
it "uses deep_merge when configured with :merge_behavior => :deep" do
|
583
720
|
Config.load({:merge_behavior => :deep})
|
584
|
-
Hash.any_instance.expects('deep_merge').with({"b" => "bnswer"}).returns({"a" => "answer", "b" => "bnswer"})
|
721
|
+
Hash.any_instance.expects('deep_merge').with({"b" => "bnswer"}, {}).returns({"a" => "answer", "b" => "bnswer"})
|
722
|
+
Backend.merge_answer({"a" => "answer"},{"b" => "bnswer"}).should == {"a" => "answer", "b" => "bnswer"}
|
723
|
+
end
|
724
|
+
|
725
|
+
it "disregards configuration when 'merge' parameter is given as a Hash" do
|
726
|
+
Config.load({:merge_behavior => :deep})
|
727
|
+
Hash.any_instance.expects('deep_merge!').with({"b" => "bnswer"}, {}).returns({"a" => "answer", "b" => "bnswer"})
|
728
|
+
Backend.merge_answer({"a" => "answer"},{"b" => "bnswer"}, {:behavior => 'deeper' }).should == {"a" => "answer", "b" => "bnswer"}
|
729
|
+
end
|
730
|
+
|
731
|
+
it "propagates deep merge options when given Hash 'merge' parameter" do
|
732
|
+
Hash.any_instance.expects('deep_merge!').with({"b" => "bnswer"}, { :knockout_prefix => '-' }).returns({"a" => "answer", "b" => "bnswer"})
|
733
|
+
Backend.merge_answer({"a" => "answer"},{"b" => "bnswer"}, {:behavior => 'deeper', :knockout_prefix => '-'}).should == {"a" => "answer", "b" => "bnswer"}
|
734
|
+
end
|
735
|
+
|
736
|
+
it "passes Config[:deep_merge_options] into calls to deep_merge" do
|
737
|
+
Config.load({:merge_behavior => :deep, :deep_merge_options => { :knockout_prefix => '-' } })
|
738
|
+
Hash.any_instance.expects('deep_merge').with({"b" => "bnswer"}, {:knockout_prefix => '-'}).returns({"a" => "answer", "b" => "bnswer"})
|
585
739
|
Backend.merge_answer({"a" => "answer"},{"b" => "bnswer"}).should == {"a" => "answer", "b" => "bnswer"}
|
586
740
|
end
|
587
741
|
end
|