hiera 2.0.0-x86-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.rb +115 -0
  7. data/lib/hiera/backend.rb +325 -0
  8. data/lib/hiera/backend/json_backend.rb +58 -0
  9. data/lib/hiera/backend/yaml_backend.rb +63 -0
  10. data/lib/hiera/config.rb +90 -0
  11. data/lib/hiera/console_logger.rb +13 -0
  12. data/lib/hiera/error.rb +4 -0
  13. data/lib/hiera/fallback_logger.rb +41 -0
  14. data/lib/hiera/filecache.rb +86 -0
  15. data/lib/hiera/interpolate.rb +98 -0
  16. data/lib/hiera/noop_logger.rb +8 -0
  17. data/lib/hiera/puppet_logger.rb +17 -0
  18. data/lib/hiera/recursive_guard.rb +20 -0
  19. data/lib/hiera/util.rb +47 -0
  20. data/lib/hiera/version.rb +89 -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 +142 -0
@@ -0,0 +1,118 @@
1
+ require 'spec_helper'
2
+
3
+ class Hiera
4
+ describe Config do
5
+ describe "#load" do
6
+ let(:default_config) do
7
+ {
8
+ :backends => ["yaml"],
9
+ :hierarchy => "common",
10
+ :logger => "console",
11
+ :merge_behavior=>:native
12
+ }
13
+ end
14
+
15
+ it "should treat string sources as a filename" do
16
+ expect { Config.load("/nonexisting") }.to raise_error
17
+ end
18
+
19
+ it "should raise an error for missing config files" do
20
+ File.expects(:exist?).with("/nonexisting").returns(false)
21
+ YAML.expects(:load_file).with("/nonexisting").never
22
+
23
+ expect { Config.load("/nonexisting") }.to raise_error "Config file /nonexisting not found"
24
+ end
25
+
26
+ it "should attempt to YAML load config files" do
27
+ File.expects(:exist?).with("/nonexisting").returns(true)
28
+ YAML.expects(:load_file).with("/nonexisting").returns(YAML.load("---\n"))
29
+
30
+ Config.load("/nonexisting")
31
+ end
32
+
33
+ it "should use defaults on empty YAML config file" do
34
+ File.expects(:exist?).with("/nonexisting").returns(true)
35
+ YAML.expects(:load_file).with("/nonexisting").returns(YAML.load(""))
36
+
37
+ Config.load("/nonexisting").should == default_config
38
+ end
39
+
40
+ it "should use hash data as source if supplied" do
41
+ config = Config.load({"rspec" => "test"})
42
+ config["rspec"].should == "test"
43
+ end
44
+
45
+ it "should merge defaults with the loaded or supplied config" do
46
+ config = Config.load({})
47
+ config.should == {:backends => ["yaml"], :hierarchy => "common", :logger => "console", :merge_behavior=>:native}
48
+ end
49
+
50
+ it "should force :backends to be a flattened array" do
51
+ Config.load({:backends => [["foo", ["bar"]]]}).should == {:backends => ["foo", "bar"], :hierarchy => "common", :logger => "console", :merge_behavior=>:native}
52
+ end
53
+
54
+ it "should load the supplied logger" do
55
+ Hiera.expects(:logger=).with("foo")
56
+ Config.load({:logger => "foo"})
57
+ end
58
+
59
+ it "should default to the console logger" do
60
+ Hiera.expects(:logger=).with("console")
61
+ Config.load({})
62
+ end
63
+
64
+ context "loading '/dev/null' as spec tests do", :unless => Hiera::Util.microsoft_windows? do
65
+ before :each do
66
+ # Simulate the behavior of YAML.load_file('/dev/null') in MRI 1.9.3p194
67
+ Config.stubs(:yaml_load_file).
68
+ raises(TypeError, "no implicit conversion from nil to integer")
69
+ end
70
+
71
+ it "is not exceptional behavior" do
72
+ Config.load('/dev/null')
73
+ end
74
+ end
75
+
76
+ describe "if deep_merge can't be loaded" do
77
+ let(:error_message) { "Must have 'deep_merge' gem installed for the configured merge_behavior." }
78
+ before(:each) do
79
+ Config.expects(:require).with("deep_merge").raises(LoadError, "unable to load")
80
+ end
81
+
82
+ it "should error if merge_behavior is 'deep'" do
83
+ expect { Config.load(:merge_behavior => :deep) }.to raise_error(Hiera::Error, error_message)
84
+ end
85
+
86
+ it "should error if merge_behavior is 'deeper'" do
87
+ expect { Config.load(:merge_behavior => :deeper) }.to raise_error(Hiera::Error, error_message)
88
+ end
89
+ end
90
+ end
91
+
92
+ describe "#load_backends" do
93
+ it "should load each backend" do
94
+ Config.load(:backends => ["One", "Two"])
95
+ Config.expects(:require).with("hiera/backend/one_backend")
96
+ Config.expects(:require).with("hiera/backend/two_backend")
97
+ Config.load_backends
98
+ end
99
+
100
+ it "should warn if it cant load a backend" do
101
+ Config.load(:backends => ["one"])
102
+ Config.expects(:require).with("hiera/backend/one_backend").raises("fail")
103
+
104
+ expect {
105
+ Config.load_backends
106
+ }.to raise_error("fail")
107
+ end
108
+ end
109
+
110
+ describe "#include?" do
111
+ it "should correctly report inclusion" do
112
+ Config.load({})
113
+ Config.include?(:foo).should == false
114
+ Config.include?(:logger).should == true
115
+ end
116
+ end
117
+ end
118
+ end
@@ -0,0 +1,19 @@
1
+ require 'spec_helper'
2
+
3
+ class Hiera
4
+ describe Console_logger do
5
+ describe "#warn" do
6
+ it "should warn to STDERR" do
7
+ STDERR.expects(:puts).with("WARN: 0: foo")
8
+ Time.expects(:now).returns(0)
9
+ Console_logger.warn("foo")
10
+ end
11
+
12
+ it "should debug to STDERR" do
13
+ STDERR.expects(:puts).with("DEBUG: 0: foo")
14
+ Time.expects(:now).returns(0)
15
+ Console_logger.debug("foo")
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,80 @@
1
+ require 'hiera/fallback_logger'
2
+
3
+ describe Hiera::FallbackLogger do
4
+ before :each do
5
+ InMemoryLogger.reset
6
+ SuitableLogger.reset
7
+ end
8
+
9
+ it "delegates #warn to the logger implemenation" do
10
+ logger = Hiera::FallbackLogger.new(InMemoryLogger)
11
+
12
+ logger.warn("the message")
13
+
14
+ InMemoryLogger.warnings.should == ["the message"]
15
+ end
16
+
17
+ it "delegates #debug to the logger implemenation" do
18
+ logger = Hiera::FallbackLogger.new(InMemoryLogger)
19
+
20
+ logger.debug("the message")
21
+
22
+ InMemoryLogger.debugs.should == ["the message"]
23
+ end
24
+
25
+ it "chooses the first logger that is suitable" do
26
+ logger = Hiera::FallbackLogger.new(UnsuitableLogger, SuitableLogger)
27
+
28
+ logger.warn("for the suitable logger")
29
+
30
+ SuitableLogger.warnings.should include("for the suitable logger")
31
+ end
32
+
33
+ it "raises an error if no implementation is suitable" do
34
+ expect do
35
+ Hiera::FallbackLogger.new(UnsuitableLogger)
36
+ end.to raise_error "No suitable logging implementation found."
37
+ end
38
+
39
+ it "issues a warning for each implementation that is not suitable" do
40
+ Hiera::FallbackLogger.new(UnsuitableLogger, UnsuitableLogger, SuitableLogger)
41
+
42
+ SuitableLogger.warnings.should == [
43
+ "Not using UnsuitableLogger. It does not report itself to be suitable.",
44
+ "Not using UnsuitableLogger. It does not report itself to be suitable."]
45
+ end
46
+
47
+ # Preserves log messages in memory
48
+ # and also serves as a "legacy" logger that has no
49
+ # suitable? method
50
+ class InMemoryLogger
51
+ class << self
52
+ attr_accessor :warnings, :debugs
53
+ end
54
+
55
+ def self.reset
56
+ self.warnings = []
57
+ self.debugs = []
58
+ end
59
+
60
+ def self.warn(message)
61
+ self.warnings << message
62
+ end
63
+
64
+ def self.debug(message)
65
+ self.debugs << message
66
+ end
67
+ end
68
+
69
+ class UnsuitableLogger
70
+ def self.suitable?
71
+ false
72
+ end
73
+ end
74
+
75
+ class SuitableLogger < InMemoryLogger
76
+ def self.suitable?
77
+ true
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,142 @@
1
+ require 'spec_helper'
2
+ require 'tmpdir'
3
+
4
+ class Hiera
5
+ describe Filecache do
6
+ before do
7
+ @cache = Filecache.new
8
+ end
9
+
10
+ def write_file(file, contents)
11
+ File.open(file, 'w') do |f|
12
+ f.write(contents)
13
+ end
14
+ end
15
+
16
+ describe "#read" do
17
+ it "reads data from a file" do
18
+ Dir.mktmpdir do |dir|
19
+ file = File.join(dir, "testing")
20
+ write_file(file, "my data")
21
+
22
+ @cache.read(file).should == "my data"
23
+ end
24
+ end
25
+
26
+ it "rereads data when the file changes" do
27
+ Dir.mktmpdir do |dir|
28
+ file = File.join(dir, "testing")
29
+ write_file(file, "my data")
30
+ @cache.read(file).should == "my data"
31
+
32
+ write_file(file, "changed data")
33
+ @cache.read(file).should == "changed data"
34
+ end
35
+ end
36
+
37
+ it "uses the provided default when the type does not match the expected type" do
38
+ Hiera.expects(:debug).with(regexp_matches(/String.*not.*Hash, setting defaults/))
39
+ Dir.mktmpdir do |dir|
40
+ file = File.join(dir, "testing")
41
+ write_file(file, "my data")
42
+ data = @cache.read(file, Hash, { :testing => "hash" }) do |data|
43
+ "a string"
44
+ end
45
+
46
+ data.should == { :testing => "hash" }
47
+ end
48
+ end
49
+
50
+ it "traps any errors from the block and uses the default value" do
51
+ Hiera.expects(:debug).with(regexp_matches(/Reading data.*failed:.*testing error/))
52
+ Dir.mktmpdir do |dir|
53
+ file = File.join(dir, "testing")
54
+ write_file(file, "my data")
55
+ data = @cache.read(file, Hash, { :testing => "hash" }) do |data|
56
+ raise ArgumentError, "testing error"
57
+ end
58
+
59
+ data.should == { :testing => "hash" }
60
+ end
61
+ end
62
+
63
+ it "raises an error when there is no default given and there is a problem" do
64
+ Dir.mktmpdir do |dir|
65
+ file = File.join(dir, "testing")
66
+ write_file(file, "my data")
67
+
68
+ expect do
69
+ @cache.read(file, Hash) do |data|
70
+ raise ArgumentError, "testing error"
71
+ end
72
+ end.to raise_error(ArgumentError, "testing error")
73
+ end
74
+ end
75
+ end
76
+
77
+ describe "#read_file" do
78
+ it "reads data from a file" do
79
+ Dir.mktmpdir do |dir|
80
+ file = File.join(dir, "testing")
81
+ write_file(file, "my data")
82
+
83
+ @cache.read_file(file).should == "my data"
84
+ end
85
+ end
86
+
87
+ it "rereads data when the file changes" do
88
+ Dir.mktmpdir do |dir|
89
+ file = File.join(dir, "testing")
90
+ write_file(file, "my data")
91
+ @cache.read_file(file).should == "my data"
92
+
93
+ write_file(file, "changed data")
94
+ @cache.read_file(file).should == "changed data"
95
+ end
96
+ end
97
+
98
+ it "errors when the type does not match the expected type" do
99
+ Dir.mktmpdir do |dir|
100
+ file = File.join(dir, "testing")
101
+ write_file(file, "my data")
102
+
103
+ expect do
104
+ @cache.read_file(file, Hash) do |data|
105
+ "a string"
106
+ end
107
+ end.to raise_error(TypeError)
108
+ end
109
+ end
110
+
111
+ it "converts the read data using the block" do
112
+ Dir.mktmpdir do |dir|
113
+ file = File.join(dir, "testing")
114
+ write_file(file, "my data")
115
+
116
+ @cache.read_file(file, Hash) do |data|
117
+ { :data => data }
118
+ end.should == { :data => "my data" }
119
+ end
120
+ end
121
+
122
+ it "errors when the file does not exist" do
123
+ expect do
124
+ @cache.read_file("/notexist")
125
+ end.to raise_error(Errno::ENOENT)
126
+ end
127
+
128
+ it "propogates any errors from the block" do
129
+ Dir.mktmpdir do |dir|
130
+ file = File.join(dir, "testing")
131
+ write_file(file, "my data")
132
+
133
+ expect do
134
+ @cache.read_file(file) do |data|
135
+ raise ArgumentError, "testing error"
136
+ end
137
+ end.to raise_error(ArgumentError, "testing error")
138
+ end
139
+ end
140
+ end
141
+ end
142
+ end
@@ -0,0 +1,6 @@
1
+ :backends:
2
+ - yaml
3
+
4
+ :hierarchy:
5
+ - recursive
6
+ - niltest
@@ -0,0 +1,2 @@
1
+ niltest: 'Missing key #%{hiera("knotfound")}#. Key with nil #%{hiera("knil")}#'
2
+ knil: null
@@ -0,0 +1,3 @@
1
+ foo: '%{hiera("bar")}'
2
+
3
+ bar: '%{hiera("foo")}'
@@ -0,0 +1,5 @@
1
+ :backends:
2
+ - yaml
3
+
4
+ :hierarchy:
5
+ - common
@@ -0,0 +1 @@
1
+ bar: 'alternate'
@@ -0,0 +1,2 @@
1
+ foo: '%{hiera("bar")}'
2
+ bar: 'common'
@@ -0,0 +1,81 @@
1
+ require 'spec_helper'
2
+ require 'hiera/util'
3
+
4
+ # This is only around for the logger setup tests
5
+ module Hiera::Foo_logger
6
+ end
7
+
8
+ describe "Hiera" do
9
+ describe "#logger=" do
10
+ it "loads the given logger" do
11
+ Hiera.expects(:require).with("hiera/foo_logger")
12
+
13
+ Hiera.logger = "foo"
14
+ end
15
+
16
+ it "falls back to the Console logger when the logger could not be loaded" do
17
+ Hiera.expects(:warn)
18
+
19
+ Hiera.logger = "no_such_logger"
20
+
21
+ Hiera.logger.should be Hiera::Console_logger
22
+ end
23
+
24
+ it "falls back to the Console logger when the logger class could not be found" do
25
+ Hiera.expects(:warn)
26
+ Hiera.expects(:require).with("hiera/no_constant_logger")
27
+
28
+ Hiera.logger = "no_constant"
29
+
30
+ Hiera.logger.should be Hiera::Console_logger
31
+ end
32
+ end
33
+
34
+ describe "#warn" do
35
+ it "delegates to the configured logger" do
36
+ Hiera.logger = 'console'
37
+ Hiera::Console_logger.expects(:warn).with("rspec")
38
+
39
+ Hiera.warn("rspec")
40
+ end
41
+ end
42
+
43
+ describe "#debug" do
44
+ it "delegates to the configured logger" do
45
+ Hiera.logger = 'console'
46
+ Hiera::Console_logger.expects(:debug).with("rspec")
47
+
48
+ Hiera.debug("rspec")
49
+ end
50
+ end
51
+
52
+ describe "#initialize" do
53
+ it "uses a default config file when none is provided" do
54
+ config_file = File.join(Hiera::Util.config_dir, 'hiera.yaml')
55
+ Hiera::Config.expects(:load).with(config_file)
56
+ Hiera::Config.stubs(:load_backends)
57
+ Hiera.new
58
+ end
59
+
60
+ it "passes the supplied config to the config class" do
61
+ Hiera::Config.expects(:load).with({"test" => "rspec"})
62
+ Hiera::Config.stubs(:load_backends)
63
+ Hiera.new(:config => {"test" => "rspec"})
64
+ end
65
+
66
+ it "loads all backends on start" do
67
+ Hiera::Config.stubs(:load)
68
+ Hiera::Config.expects(:load_backends)
69
+ Hiera.new
70
+ end
71
+ end
72
+
73
+ describe "#lookup" do
74
+ it "delegates to the Backend#lookup method" do
75
+ Hiera::Config.stubs(:load)
76
+ Hiera::Config.stubs(:load_backends)
77
+ Hiera::Backend.expects(:lookup).with(:key, :default, :scope, :order_override, :resolution_type)
78
+ Hiera.new.lookup(:key, :default, :scope, :order_override, :resolution_type)
79
+ end
80
+ end
81
+ end