hiera 2.0.0-x64-mingw32

Sign up to get free protection for your applications and to get access to all the features.
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