hiera 2.0.0-x64-mingw32

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. checksums.yaml +7 -0
  2. data/COPYING +202 -0
  3. data/LICENSE +18 -0
  4. data/README.md +276 -0
  5. data/bin/hiera +248 -0
  6. data/lib/hiera/backend/json_backend.rb +58 -0
  7. data/lib/hiera/backend/yaml_backend.rb +63 -0
  8. data/lib/hiera/backend.rb +325 -0
  9. data/lib/hiera/config.rb +90 -0
  10. data/lib/hiera/console_logger.rb +13 -0
  11. data/lib/hiera/error.rb +4 -0
  12. data/lib/hiera/fallback_logger.rb +41 -0
  13. data/lib/hiera/filecache.rb +86 -0
  14. data/lib/hiera/interpolate.rb +98 -0
  15. data/lib/hiera/noop_logger.rb +8 -0
  16. data/lib/hiera/puppet_logger.rb +17 -0
  17. data/lib/hiera/recursive_guard.rb +20 -0
  18. data/lib/hiera/util.rb +47 -0
  19. data/lib/hiera/version.rb +89 -0
  20. data/lib/hiera.rb +115 -0
  21. data/spec/spec_helper.rb +78 -0
  22. data/spec/unit/backend/json_backend_spec.rb +85 -0
  23. data/spec/unit/backend/yaml_backend_spec.rb +138 -0
  24. data/spec/unit/backend_spec.rb +743 -0
  25. data/spec/unit/config_spec.rb +118 -0
  26. data/spec/unit/console_logger_spec.rb +19 -0
  27. data/spec/unit/fallback_logger_spec.rb +80 -0
  28. data/spec/unit/filecache_spec.rb +142 -0
  29. data/spec/unit/fixtures/interpolate/config/hiera.yaml +6 -0
  30. data/spec/unit/fixtures/interpolate/data/niltest.yaml +2 -0
  31. data/spec/unit/fixtures/interpolate/data/recursive.yaml +3 -0
  32. data/spec/unit/fixtures/override/config/hiera.yaml +5 -0
  33. data/spec/unit/fixtures/override/data/alternate.yaml +1 -0
  34. data/spec/unit/fixtures/override/data/common.yaml +2 -0
  35. data/spec/unit/hiera_spec.rb +81 -0
  36. data/spec/unit/interpolate_spec.rb +36 -0
  37. data/spec/unit/puppet_logger_spec.rb +31 -0
  38. data/spec/unit/util_spec.rb +49 -0
  39. data/spec/unit/version_spec.rb +44 -0
  40. metadata +128 -0
@@ -0,0 +1,78 @@
1
+ $:.insert(0, File.join([File.dirname(__FILE__), "..", "lib"]))
2
+
3
+ require 'rubygems'
4
+ require 'rspec'
5
+ require 'mocha'
6
+ require 'hiera'
7
+ require 'tmpdir'
8
+
9
+ RSpec.configure do |config|
10
+ config.mock_with :mocha
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
+
19
+ config.after :suite do
20
+ # Log the spec order to a file, but only if the LOG_SPEC_ORDER environment variable is
21
+ # set. This should be enabled on Jenkins runs, as it can be used with Nick L.'s bisect
22
+ # script to help identify and debug order-dependent spec failures.
23
+ if ENV['LOG_SPEC_ORDER']
24
+ File.open("./spec_order.txt", "w") do |logfile|
25
+ config.instance_variable_get(:@files_to_run).each { |f| logfile.puts f }
26
+ end
27
+ end
28
+ end
29
+ end
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
+
36
+ # In ruby 1.8.5 Dir does not have mktmpdir defined, so this monkey patches
37
+ # Dir to include the 1.8.7 definition of that method if it isn't already defined.
38
+ # Method definition borrowed from ruby-1.8.7-p357/lib/ruby/1.8/tmpdir.rb
39
+ unless Dir.respond_to?(:mktmpdir)
40
+ def Dir.mktmpdir(prefix_suffix=nil, tmpdir=nil)
41
+ case prefix_suffix
42
+ when nil
43
+ prefix = "d"
44
+ suffix = ""
45
+ when String
46
+ prefix = prefix_suffix
47
+ suffix = ""
48
+ when Array
49
+ prefix = prefix_suffix[0]
50
+ suffix = prefix_suffix[1]
51
+ else
52
+ raise ArgumentError, "unexpected prefix_suffix: #{prefix_suffix.inspect}"
53
+ end
54
+ tmpdir ||= Dir.tmpdir
55
+ t = Time.now.strftime("%Y%m%d")
56
+ n = nil
57
+ begin
58
+ path = "#{tmpdir}/#{prefix}#{t}-#{$$}-#{rand(0x100000000).to_s(36)}"
59
+ path << "-#{n}" if n
60
+ path << suffix
61
+ Dir.mkdir(path, 0700)
62
+ rescue Errno::EEXIST
63
+ n ||= 0
64
+ n += 1
65
+ retry
66
+ end
67
+
68
+ if block_given?
69
+ begin
70
+ yield path
71
+ ensure
72
+ FileUtils.remove_entry_secure path
73
+ end
74
+ else
75
+ path
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,85 @@
1
+ require 'spec_helper'
2
+ require 'hiera/backend/json_backend'
3
+
4
+ class Hiera
5
+ module Backend
6
+ describe Json_backend do
7
+ before do
8
+ Hiera.stubs(:debug)
9
+ Hiera.stubs(:warn)
10
+ Hiera::Backend.stubs(:empty_answer).returns(nil)
11
+ @cache = mock
12
+ @backend = Json_backend.new(@cache)
13
+ end
14
+
15
+ describe "#initialize" do
16
+ it "should announce its creation" do # because other specs checks this
17
+ Hiera.expects(:debug).with("Hiera JSON backend starting")
18
+ Json_backend.new
19
+ end
20
+ end
21
+
22
+ describe "#lookup" do
23
+ it "should look for data in all sources" do
24
+ Backend.expects(:datasources).multiple_yields(["one"], ["two"])
25
+ Backend.expects(:datafile).with(:json, {}, "one", "json").returns(nil)
26
+ Backend.expects(:datafile).with(:json, {}, "two", "json").returns(nil)
27
+
28
+ expect { @backend.lookup("key", {}, nil, :priority, nil) }.to throw_symbol(:no_such_key)
29
+ end
30
+
31
+ it "should retain the data types found in data files" do
32
+ Backend.expects(:datasources).yields("one").times(3)
33
+ Backend.expects(:datafile).with(:json, {}, "one", "json").returns("/nonexisting/one.json").times(3)
34
+ File.stubs(:exist?).with("/nonexisting/one.json").returns(true)
35
+
36
+ @cache.expects(:read_file).with("/nonexisting/one.json", Hash).returns({"stringval" => "string", "boolval" => true, "numericval" => 1}).times(3)
37
+
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
+ end
42
+
43
+ it "should pick data earliest source that has it for priority searches" do
44
+ scope = {"rspec" => "test"}
45
+ Backend.expects(:datasources).multiple_yields(["one"], ["two"])
46
+ Backend.expects(:datafile).with(:json, scope, "one", "json").returns("/nonexisting/one.json")
47
+ Backend.expects(:datafile).with(:json, scope, "two", "json").never
48
+
49
+ File.stubs(:exist?).with("/nonexisting/one.json").returns(true)
50
+ @cache.expects(:read_file).with("/nonexisting/one.json", Hash).returns({"key" => "test_%{rspec}"})
51
+
52
+ @backend.lookup("key", scope, nil, :priority, nil).should == "test_test"
53
+ end
54
+
55
+ it "should build an array of all data sources for array searches" do
56
+ Hiera::Backend.stubs(:empty_answer).returns([])
57
+ Backend.stubs(:parse_answer).with('answer', {}, {}, anything).returns("answer")
58
+ Backend.expects(:datafile).with(:json, {}, "one", "json").returns("/nonexisting/one.json")
59
+ Backend.expects(:datafile).with(:json, {}, "two", "json").returns("/nonexisting/two.json")
60
+
61
+ Backend.expects(:datasources).multiple_yields(["one"], ["two"])
62
+
63
+ File.expects(:exist?).with("/nonexisting/one.json").returns(true)
64
+ File.expects(:exist?).with("/nonexisting/two.json").returns(true)
65
+
66
+ @cache.expects(:read_file).with("/nonexisting/one.json", Hash).returns({"key" => "answer"})
67
+ @cache.expects(:read_file).with("/nonexisting/two.json", Hash).returns({"key" => "answer"})
68
+
69
+ @backend.lookup("key", {}, nil, :array, nil).should == ["answer", "answer"]
70
+ end
71
+
72
+ it "should parse the answer for scope variables" do
73
+ Backend.stubs(:parse_answer).with('test_%{rspec}', {'rspec' => 'test'}, {}, anything).returns("test_test")
74
+ Backend.expects(:datasources).yields("one")
75
+ Backend.expects(:datafile).with(:json, {"rspec" => "test"}, "one", "json").returns("/nonexisting/one.json")
76
+
77
+ File.expects(:exist?).with("/nonexisting/one.json").returns(true)
78
+ @cache.expects(:read_file).with("/nonexisting/one.json", Hash).returns({"key" => "test_%{rspec}"})
79
+
80
+ @backend.lookup("key", {"rspec" => "test"}, nil, :priority, nil).should == "test_test"
81
+ end
82
+ end
83
+ end
84
+ end
85
+ end
@@ -0,0 +1,138 @@
1
+ require 'spec_helper'
2
+ require 'hiera/backend/yaml_backend'
3
+
4
+ class Hiera
5
+ module Backend
6
+ class FakeCache
7
+ attr_accessor :value
8
+ def read(path, expected_type, default, &block)
9
+ read_file(path, expected_type, &block)
10
+ rescue => e
11
+ default
12
+ end
13
+
14
+ def read_file(path, expected_type, &block)
15
+ output = block.call(@value)
16
+ if !output.is_a? expected_type
17
+ raise TypeError
18
+ end
19
+ output
20
+ end
21
+ end
22
+
23
+ describe Yaml_backend do
24
+ before do
25
+ Config.load({})
26
+ Hiera.stubs(:debug)
27
+ Hiera.stubs(:warn)
28
+ @cache = FakeCache.new
29
+ @backend = Yaml_backend.new(@cache)
30
+ end
31
+
32
+ describe "#initialize" do
33
+ it "should announce its creation" do # because other specs checks this
34
+ Hiera.expects(:debug).with("Hiera YAML backend starting")
35
+ Yaml_backend.new
36
+ end
37
+ end
38
+
39
+ describe "#lookup" do
40
+ it "should pick data earliest source that has it for priority searches" do
41
+ Backend.expects(:datasourcefiles).with(:yaml, {}, "yaml", nil).yields(["one", "/nonexisting/one.yaml"])
42
+ @cache.value = "---\nkey: answer"
43
+
44
+ @backend.lookup("key", {}, nil, :priority, nil).should == "answer"
45
+ end
46
+
47
+ describe "handling unexpected YAML values" do
48
+ before do
49
+ Backend.expects(:datasourcefiles).with(:yaml, {}, "yaml", nil).yields(["one", "/nonexisting/one.yaml"])
50
+ end
51
+
52
+ it "throws :no_such_key when key is missing in YAML" do
53
+ @cache.value = "---\n"
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
60
+ end
61
+
62
+ it "throws :no_such_key when the YAML file is false" do
63
+ @cache.value = ""
64
+ expect { @backend.lookup("key", {}, nil, :priority, nil) }.to throw_symbol(:no_such_key)
65
+ end
66
+
67
+ it "raises a TypeError when the YAML value is not a hash" do
68
+ @cache.value = "---\n[one, two, three]"
69
+ expect { @backend.lookup("key", {}, nil, :priority, nil) }.to raise_error(TypeError)
70
+ end
71
+ end
72
+
73
+ it "should build an array of all data sources for array searches" do
74
+ Backend.expects(:datasourcefiles).with(:yaml, {}, "yaml", nil).multiple_yields(["one", "/nonexisting/one.yaml"], ["two", "/nonexisting/two.yaml"])
75
+ @cache.expects(:read_file).with("/nonexisting/one.yaml", Hash).returns({"key"=>"answer"})
76
+ @cache.expects(:read_file).with("/nonexisting/two.yaml", Hash).returns({"key"=>"answer"})
77
+
78
+ @backend.lookup("key", {}, nil, :array, nil).should == ["answer", "answer"]
79
+ end
80
+
81
+ it "should ignore empty hash of data sources for hash searches" do
82
+ Backend.expects(:datasourcefiles).with(:yaml, {}, "yaml", nil).multiple_yields(["one", "/nonexisting/one.yaml"], ["two", "/nonexisting/two.yaml"])
83
+
84
+ @cache.expects(:read_file).with("/nonexisting/one.yaml", Hash).returns({})
85
+ @cache.expects(:read_file).with("/nonexisting/two.yaml", Hash).returns({"key"=>{"a"=>"answer"}})
86
+
87
+ @backend.lookup("key", {}, nil, :hash, nil).should == {"a" => "answer"}
88
+ end
89
+
90
+ it "should build a merged hash of data sources for hash searches" do
91
+ Backend.expects(:datasourcefiles).with(:yaml, {}, "yaml", nil).multiple_yields(["one", "/nonexisting/one.yaml"], ["two", "/nonexisting/two.yaml"])
92
+
93
+ @cache.expects(:read_file).with("/nonexisting/one.yaml", Hash).returns({"key"=>{"a"=>"answer"}})
94
+ @cache.expects(:read_file).with("/nonexisting/two.yaml", Hash).returns({"key"=>{"b"=>"answer", "a"=>"wrong"}})
95
+
96
+ @backend.lookup("key", {}, nil, :hash, nil).should == {"a" => "answer", "b" => "answer"}
97
+ end
98
+
99
+ it "should fail when trying to << a Hash" do
100
+ Backend.expects(:datasourcefiles).with(:yaml, {}, "yaml", nil).multiple_yields(["one", "/nonexisting/one.yaml"], ["two", "/nonexisting/two.yaml"])
101
+
102
+ @cache.expects(:read_file).with("/nonexisting/one.yaml", Hash).returns({"key"=>["a", "answer"]})
103
+ @cache.expects(:read_file).with("/nonexisting/two.yaml", Hash).returns({"key"=>{"a"=>"answer"}})
104
+
105
+ expect {@backend.lookup("key", {}, nil, :array, nil)}.to raise_error(Exception, "Hiera type mismatch for key 'key': expected Array and got Hash")
106
+ end
107
+
108
+ it "should fail when trying to merge an Array" do
109
+ Backend.expects(:datasourcefiles).with(:yaml, {}, "yaml", nil).multiple_yields(["one", "/nonexisting/one.yaml"], ["two", "/nonexisting/two.yaml"])
110
+
111
+ @cache.expects(:read_file).with("/nonexisting/one.yaml", Hash).returns({"key"=>{"a"=>"answer"}})
112
+ @cache.expects(:read_file).with("/nonexisting/two.yaml", Hash).returns({"key"=>["a", "wrong"]})
113
+
114
+ expect { @backend.lookup("key", {}, nil, :hash, nil) }.to raise_error(Exception, "Hiera type mismatch for key 'key': expected Hash and got Array")
115
+ end
116
+
117
+ it "should parse the answer for scope variables" do
118
+ Backend.expects(:datasourcefiles).with(:yaml, {"rspec" => "test"}, "yaml", nil).multiple_yields(["one", "/nonexisting/one.yaml"])
119
+
120
+ @cache.expects(:read_file).with("/nonexisting/one.yaml", Hash).returns({"key"=>"test_%{rspec}"})
121
+
122
+ @backend.lookup("key", {"rspec" => "test"}, nil, :priority, nil).should == "test_test"
123
+ end
124
+
125
+ it "should retain datatypes found in yaml files" do
126
+ Backend.expects(:datasourcefiles).with(:yaml, {}, "yaml", nil).multiple_yields(["one", "/nonexisting/one.yaml"]).times(3)
127
+
128
+
129
+ @cache.value = "---\nstringval: 'string'\nboolval: true\nnumericval: 1"
130
+
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
134
+ end
135
+ end
136
+ end
137
+ end
138
+ end