hiera 0.3.0 → 1.0.0rc4
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of hiera might be problematic. Click here for more details.
- data/CHANGELOG +112 -0
- data/COPYING +202 -0
- data/README.md +237 -0
- data/bin/hiera +160 -156
- data/lib/hiera.rb +58 -50
- data/lib/hiera/backend.rb +174 -161
- data/lib/hiera/backend/yaml_backend.rb +67 -45
- data/lib/hiera/config.rb +43 -41
- data/lib/hiera/console_logger.rb +9 -9
- data/lib/hiera/noop_logger.rb +8 -0
- data/lib/hiera/puppet_logger.rb +10 -5
- data/lib/hiera/util.rb +47 -0
- data/spec/spec_helper.rb +42 -6
- data/spec/unit/backend/yaml_backend_spec.rb +153 -104
- data/spec/unit/backend_spec.rb +309 -255
- data/spec/unit/config_spec.rb +85 -79
- data/spec/unit/console_logger_spec.rb +13 -13
- data/spec/unit/hiera_spec.rb +57 -54
- data/spec/unit/util_spec.rb +49 -0
- metadata +21 -10
data/lib/hiera/config.rb
CHANGED
@@ -1,51 +1,53 @@
|
|
1
1
|
class Hiera::Config
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
2
|
+
class << self
|
3
|
+
# Takes a string or hash as input, strings are treated as filenames
|
4
|
+
# hashes are stored as data that would have been in the config file
|
5
|
+
#
|
6
|
+
# Unless specified it will only use YAML as backend with a single
|
7
|
+
# 'common' hierarchy and console logger
|
8
|
+
def load(source)
|
9
|
+
@config = {:backends => "yaml",
|
10
|
+
:hierarchy => "common"}
|
11
|
+
|
12
|
+
if source.is_a?(String)
|
13
|
+
if File.exist?(source)
|
14
|
+
config = YAML.load_file(source)
|
15
|
+
@config.merge! config if config
|
16
|
+
else
|
17
|
+
raise "Config file #{source} not found"
|
18
|
+
end
|
19
|
+
elsif source.is_a?(Hash)
|
20
|
+
@config.merge! source
|
21
|
+
end
|
20
22
|
|
21
|
-
|
23
|
+
@config[:backends] = [ @config[:backends] ].flatten
|
22
24
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
25
|
+
if @config.include?(:logger)
|
26
|
+
Hiera.logger = @config[:logger].to_s
|
27
|
+
else
|
28
|
+
@config[:logger] = "console"
|
29
|
+
Hiera.logger = "console"
|
30
|
+
end
|
29
31
|
|
30
|
-
|
31
|
-
|
32
|
+
@config
|
33
|
+
end
|
32
34
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
end
|
40
|
-
end
|
35
|
+
def load_backends
|
36
|
+
@config[:backends].each do |backend|
|
37
|
+
begin
|
38
|
+
require "hiera/backend/#{backend.downcase}_backend"
|
39
|
+
rescue LoadError => e
|
40
|
+
Hiera.warn "Cannot load backend #{backend}: #{e}"
|
41
41
|
end
|
42
|
+
end
|
43
|
+
end
|
42
44
|
|
43
|
-
|
44
|
-
|
45
|
-
|
45
|
+
def include?(key)
|
46
|
+
@config.include?(key)
|
47
|
+
end
|
46
48
|
|
47
|
-
|
48
|
-
|
49
|
-
end
|
49
|
+
def [](key)
|
50
|
+
@config[key]
|
50
51
|
end
|
52
|
+
end
|
51
53
|
end
|
data/lib/hiera/console_logger.rb
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
class Hiera
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
2
|
+
module Console_logger
|
3
|
+
class << self
|
4
|
+
def warn(msg)
|
5
|
+
STDERR.puts("WARN: %s: %s" % [Time.now.to_s, msg])
|
6
|
+
end
|
7
7
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
end
|
8
|
+
def debug(msg)
|
9
|
+
STDERR.puts("DEBUG: %s: %s" % [Time.now.to_s, msg])
|
10
|
+
end
|
12
11
|
end
|
12
|
+
end
|
13
13
|
end
|
data/lib/hiera/puppet_logger.rb
CHANGED
@@ -1,8 +1,13 @@
|
|
1
1
|
class Hiera
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
2
|
+
module Puppet_logger
|
3
|
+
class << self
|
4
|
+
def warn(msg)
|
5
|
+
Puppet.notice("hiera(): #{msg}")
|
6
|
+
end
|
7
|
+
|
8
|
+
def debug(msg)
|
9
|
+
Puppet.debug("hiera(): #{msg}")
|
10
|
+
end
|
7
11
|
end
|
12
|
+
end
|
8
13
|
end
|
data/lib/hiera/util.rb
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
class Hiera
|
2
|
+
module Util
|
3
|
+
module_function
|
4
|
+
|
5
|
+
def posix?
|
6
|
+
require 'etc'
|
7
|
+
Etc.getpwuid(0) != nil
|
8
|
+
end
|
9
|
+
|
10
|
+
def microsoft_windows?
|
11
|
+
return false unless file_alt_separator
|
12
|
+
|
13
|
+
begin
|
14
|
+
require 'win32/dir'
|
15
|
+
true
|
16
|
+
rescue LoadError => err
|
17
|
+
warn "Cannot run on Microsoft Windows without the win32-dir gem: #{err}"
|
18
|
+
false
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def config_dir
|
23
|
+
if microsoft_windows?
|
24
|
+
File.join(common_appdata, 'PuppetLabs', 'hiera', 'etc')
|
25
|
+
else
|
26
|
+
'/etc'
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def var_dir
|
31
|
+
if microsoft_windows?
|
32
|
+
File.join(common_appdata, 'PuppetLabs', 'hiera', 'var')
|
33
|
+
else
|
34
|
+
'/var/lib/hiera'
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def file_alt_separator
|
39
|
+
File::ALT_SEPARATOR
|
40
|
+
end
|
41
|
+
|
42
|
+
def common_appdata
|
43
|
+
Dir::COMMON_APPDATA
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
data/spec/spec_helper.rb
CHANGED
@@ -7,13 +7,49 @@ require 'rspec/mocks'
|
|
7
7
|
require 'mocha'
|
8
8
|
|
9
9
|
RSpec.configure do |config|
|
10
|
-
|
10
|
+
config.mock_with :mocha
|
11
11
|
end
|
12
12
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
13
|
+
# In ruby 1.8.5 Dir does not have mktmpdir defined, so this monkey patches
|
14
|
+
# Dir to include the 1.8.7 definition of that method if it isn't already defined.
|
15
|
+
# Method definition borrowed from ruby-1.8.7-p357/lib/ruby/1.8/tmpdir.rb
|
16
|
+
unless Dir.respond_to?(:mktmpdir)
|
17
|
+
def Dir.mktmpdir(prefix_suffix=nil, tmpdir=nil)
|
18
|
+
case prefix_suffix
|
19
|
+
when nil
|
20
|
+
prefix = "d"
|
21
|
+
suffix = ""
|
22
|
+
when String
|
23
|
+
prefix = prefix_suffix
|
24
|
+
suffix = ""
|
25
|
+
when Array
|
26
|
+
prefix = prefix_suffix[0]
|
27
|
+
suffix = prefix_suffix[1]
|
28
|
+
else
|
29
|
+
raise ArgumentError, "unexpected prefix_suffix: #{prefix_suffix.inspect}"
|
30
|
+
end
|
31
|
+
tmpdir ||= Dir.tmpdir
|
32
|
+
t = Time.now.strftime("%Y%m%d")
|
33
|
+
n = nil
|
34
|
+
begin
|
35
|
+
path = "#{tmpdir}/#{prefix}#{t}-#{$$}-#{rand(0x100000000).to_s(36)}"
|
36
|
+
path << "-#{n}" if n
|
37
|
+
path << suffix
|
38
|
+
Dir.mkdir(path, 0700)
|
39
|
+
rescue Errno::EEXIST
|
40
|
+
n ||= 0
|
41
|
+
n += 1
|
42
|
+
retry
|
17
43
|
end
|
18
|
-
end
|
19
44
|
|
45
|
+
if block_given?
|
46
|
+
begin
|
47
|
+
yield path
|
48
|
+
ensure
|
49
|
+
FileUtils.remove_entry_secure path
|
50
|
+
end
|
51
|
+
else
|
52
|
+
path
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -1,140 +1,189 @@
|
|
1
|
-
require '
|
2
|
-
|
1
|
+
require 'tmpdir'
|
3
2
|
require 'hiera/backend/yaml_backend'
|
3
|
+
require 'hiera/backend'
|
4
|
+
require 'fileutils'
|
5
|
+
require 'spec_helper'
|
4
6
|
|
5
7
|
class Hiera
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
8
|
+
module Backend
|
9
|
+
describe Yaml_backend do
|
10
|
+
before do
|
11
|
+
Hiera.stubs(:debug)
|
12
|
+
Hiera.stubs(:warn)
|
13
|
+
@backend = Yaml_backend.new
|
14
|
+
@backend.stubs(:stale?).returns(true)
|
15
|
+
end
|
16
|
+
|
17
|
+
describe "#initialize" do
|
18
|
+
it "should announce its creation" do # because other specs checks this
|
19
|
+
Hiera.expects(:debug).with("Hiera YAML backend starting")
|
20
|
+
Yaml_backend.new
|
21
|
+
end
|
22
|
+
end
|
20
23
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
24
|
+
describe "#lookup" do
|
25
|
+
it "should look for data in all sources" do
|
26
|
+
Backend.expects(:datasources).multiple_yields(["one"], ["two"])
|
27
|
+
Backend.expects(:datafile).with(:yaml, {}, "one", "yaml").returns(nil)
|
28
|
+
Backend.expects(:datafile).with(:yaml, {}, "two", "yaml").returns(nil)
|
26
29
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
it "should pick data earliest source that has it for priority searches" do
|
31
|
-
Backend.expects(:datasources).multiple_yields(["one"], ["two"])
|
32
|
-
Backend.expects(:datafile).with(:yaml, {}, "one", "yaml").returns("/nonexisting/one.yaml")
|
33
|
-
Backend.expects(:datafile).with(:yaml, {}, "two", "yaml").returns(nil).never
|
34
|
-
YAML.expects(:load_file).with("/nonexisting/one.yaml").returns(YAML.load("---\nkey: answer"))
|
30
|
+
@backend.lookup("key", {}, nil, :priority)
|
31
|
+
end
|
35
32
|
|
36
|
-
|
37
|
-
|
33
|
+
it "should pick data earliest source that has it for priority searches" do
|
34
|
+
Backend.expects(:datasources).multiple_yields(["one"], ["two"])
|
35
|
+
Backend.expects(:datafile).with(:yaml, {}, "one", "yaml").returns("/nonexisting/one.yaml")
|
36
|
+
Backend.expects(:datafile).with(:yaml, {}, "two", "yaml").returns(nil).never
|
37
|
+
YAML.expects(:load_file).with("/nonexisting/one.yaml").returns(YAML.load("---\nkey: answer"))
|
38
38
|
|
39
|
-
|
40
|
-
|
41
|
-
Backend.expects(:datafile).with(:yaml, {}, "one", "yaml").returns(nil)
|
42
|
-
YAML.expects(:load_file).never
|
39
|
+
@backend.lookup("key", {}, nil, :priority).should == "answer"
|
40
|
+
end
|
43
41
|
|
44
|
-
|
45
|
-
|
42
|
+
it "should not look up missing data files" do
|
43
|
+
Backend.expects(:datasources).multiple_yields(["one"])
|
44
|
+
Backend.expects(:datafile).with(:yaml, {}, "one", "yaml").returns(nil)
|
45
|
+
YAML.expects(:load_file).never
|
46
46
|
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
47
|
+
@backend.lookup("key", {}, nil, :priority)
|
48
|
+
end
|
49
|
+
|
50
|
+
it "should return nil for empty data files" do
|
51
|
+
Backend.expects(:datasources).multiple_yields(["one"])
|
52
|
+
Backend.expects(:datafile).with(:yaml, {}, "one", "yaml").returns("/nonexisting/one.yaml")
|
53
|
+
YAML.expects(:load_file).with("/nonexisting/one.yaml").returns(YAML.load(""))
|
51
54
|
|
52
|
-
|
53
|
-
|
55
|
+
@backend.lookup("key", {}, nil, :priority).should be_nil
|
56
|
+
end
|
54
57
|
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
58
|
+
it "should build an array of all data sources for array searches" do
|
59
|
+
Backend.expects(:datasources).multiple_yields(["one"], ["two"])
|
60
|
+
Backend.expects(:datafile).with(:yaml, {}, "one", "yaml").returns("/nonexisting/one.yaml")
|
61
|
+
Backend.expects(:datafile).with(:yaml, {}, "two", "yaml").returns("/nonexisting/two.yaml")
|
59
62
|
|
60
|
-
|
61
|
-
|
63
|
+
YAML.expects(:load_file).with("/nonexisting/one.yaml").returns(YAML.load("---\nkey: answer"))
|
64
|
+
YAML.expects(:load_file).with("/nonexisting/two.yaml").returns(YAML.load("---\nkey: answer"))
|
65
|
+
|
66
|
+
@backend.lookup("key", {}, nil, :array).should == ["answer", "answer"]
|
67
|
+
end
|
62
68
|
|
63
|
-
|
64
|
-
|
69
|
+
it "should ignore empty hash of data sources for hash searches" do
|
70
|
+
Backend.expects(:datasources).multiple_yields(["one"], ["two"])
|
71
|
+
Backend.expects(:datafile).with(:yaml, {}, "one", "yaml").returns("/nonexisting/one.yaml")
|
72
|
+
Backend.expects(:datafile).with(:yaml, {}, "two", "yaml").returns("/nonexisting/two.yaml")
|
65
73
|
|
66
|
-
|
67
|
-
|
68
|
-
Backend.expects(:datafile).with(:yaml, {}, "one", "yaml").returns("/nonexisting/one.yaml")
|
74
|
+
YAML.expects(:load_file).with("/nonexisting/one.yaml").returns(YAML.load(""))
|
75
|
+
YAML.expects(:load_file).with("/nonexisting/two.yaml").returns(YAML.load("---\nkey:\n a: answer"))
|
69
76
|
|
70
|
-
|
77
|
+
@backend.lookup("key", {}, nil, :hash).should == {"a" => "answer"}
|
78
|
+
end
|
71
79
|
|
72
|
-
|
73
|
-
|
80
|
+
it "should build a merged hash of data sources for hash searches" do
|
81
|
+
Backend.expects(:datasources).multiple_yields(["one"], ["two"])
|
82
|
+
Backend.expects(:datafile).with(:yaml, {}, "one", "yaml").returns("/nonexisting/one.yaml")
|
83
|
+
Backend.expects(:datafile).with(:yaml, {}, "two", "yaml").returns("/nonexisting/two.yaml")
|
74
84
|
|
75
|
-
|
76
|
-
|
77
|
-
Backend.expects(:datafile).with(:yaml, {}, "one", "yaml").returns("/nonexisting/one.yaml")
|
78
|
-
Backend.expects(:datafile).with(:yaml, {}, "two", "yaml").returns("/nonexisting/two.yaml")
|
85
|
+
YAML.expects(:load_file).with("/nonexisting/one.yaml").returns(YAML.load("---\nkey:\n a: answer"))
|
86
|
+
YAML.expects(:load_file).with("/nonexisting/two.yaml").returns(YAML.load("---\nkey:\n a: wrong\n b: answer"))
|
79
87
|
|
80
|
-
|
81
|
-
|
88
|
+
@backend.lookup("key", {}, nil, :hash).should == {"a" => "answer", "b" => "answer"}
|
89
|
+
end
|
82
90
|
|
83
|
-
|
84
|
-
|
91
|
+
it "should fail when trying to << a Hash" do
|
92
|
+
Backend.expects(:datasources).multiple_yields(["one"], ["two"])
|
93
|
+
Backend.expects(:datafile).with(:yaml, {}, "one", "yaml").returns("/nonexisting/one.yaml")
|
94
|
+
Backend.expects(:datafile).with(:yaml, {}, "two", "yaml").returns("/nonexisting/two.yaml")
|
85
95
|
|
86
|
-
|
87
|
-
|
88
|
-
Backend.expects(:datafile).with(:yaml, {}, "one", "yaml").returns("/nonexisting/one.yaml")
|
89
|
-
Backend.expects(:datafile).with(:yaml, {}, "two", "yaml").returns("/nonexisting/two.yaml")
|
96
|
+
YAML.expects(:load_file).with("/nonexisting/one.yaml").returns(YAML.load("---\nkey:\n- a\n- answer"))
|
97
|
+
YAML.expects(:load_file).with("/nonexisting/two.yaml").returns(YAML.load("---\nkey:\n a: answer"))
|
90
98
|
|
91
|
-
|
92
|
-
|
99
|
+
lambda {@backend.lookup("key", {}, nil, :array)}.should raise_error(Exception, "Hiera type mismatch: expected Array and got Hash")
|
100
|
+
end
|
93
101
|
|
94
|
-
|
95
|
-
|
102
|
+
it "should fail when trying to merge an Array" do
|
103
|
+
Backend.expects(:datasources).multiple_yields(["one"], ["two"])
|
104
|
+
Backend.expects(:datafile).with(:yaml, {}, "one", "yaml").returns("/nonexisting/one.yaml")
|
105
|
+
Backend.expects(:datafile).with(:yaml, {}, "two", "yaml").returns("/nonexisting/two.yaml")
|
96
106
|
|
97
|
-
|
98
|
-
|
99
|
-
Backend.expects(:datafile).with(:yaml, {}, "one", "yaml").returns("/nonexisting/one.yaml")
|
100
|
-
Backend.expects(:datafile).with(:yaml, {}, "two", "yaml").returns("/nonexisting/two.yaml")
|
107
|
+
YAML.expects(:load_file).with("/nonexisting/one.yaml").returns(YAML.load("---\nkey:\n a: answer"))
|
108
|
+
YAML.expects(:load_file).with("/nonexisting/two.yaml").returns(YAML.load("---\nkey:\n- a\n- wrong"))
|
101
109
|
|
102
|
-
|
103
|
-
|
110
|
+
lambda {@backend.lookup("key", {}, nil, :hash)}.should raise_error(Exception, "Hiera type mismatch: expected Hash and got Array")
|
111
|
+
end
|
104
112
|
|
105
|
-
|
106
|
-
|
113
|
+
it "should parse the answer for scope variables" do
|
114
|
+
Backend.expects(:datasources).yields("one")
|
115
|
+
Backend.expects(:datafile).with(:yaml, {"rspec" => "test"}, "one", "yaml").returns("/nonexisting/one.yaml")
|
116
|
+
YAML.expects(:load_file).with("/nonexisting/one.yaml").returns(YAML.load("---\nkey: 'test_%{rspec}'"))
|
107
117
|
|
108
|
-
|
109
|
-
|
110
|
-
Backend.expects(:datafile).with(:yaml, {}, "one", "yaml").returns("/nonexisting/one.yaml")
|
111
|
-
Backend.expects(:datafile).with(:yaml, {}, "two", "yaml").returns("/nonexisting/two.yaml")
|
118
|
+
@backend.lookup("key", {"rspec" => "test"}, nil, :priority).should == "test_test"
|
119
|
+
end
|
112
120
|
|
113
|
-
|
114
|
-
|
121
|
+
it "should retain datatypes found in yaml files" do
|
122
|
+
Backend.expects(:datasources).yields("one").times(3)
|
123
|
+
Backend.expects(:datafile).with(:yaml, {}, "one", "yaml").returns("/nonexisting/one.yaml").times(3)
|
115
124
|
|
116
|
-
|
117
|
-
end
|
125
|
+
YAML.expects(:load_file).with("/nonexisting/one.yaml").returns(YAML.load("---\nstringval: 'string'\nboolval: true\nnumericval: 1")).times(3)
|
118
126
|
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
127
|
+
@backend.lookup("stringval", {}, nil, :priority).should == "string"
|
128
|
+
@backend.lookup("boolval", {}, nil, :priority).should == true
|
129
|
+
@backend.lookup("numericval", {}, nil, :priority).should == 1
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
123
133
|
|
124
|
-
|
125
|
-
|
134
|
+
describe '#stale?' do
|
135
|
+
before do
|
136
|
+
Hiera.stubs(:debug)
|
137
|
+
Hiera.stubs(:warn)
|
138
|
+
@backend = Yaml_backend.new
|
139
|
+
@fakestat = Struct.new(:ino, :mtime, :size)
|
140
|
+
end
|
141
|
+
|
142
|
+
def create_yaml_file(data, path)
|
143
|
+
File.open(path, 'w') do |f|
|
144
|
+
f.write(data)
|
145
|
+
end
|
146
|
+
end
|
126
147
|
|
127
|
-
|
128
|
-
|
129
|
-
|
148
|
+
def update_file(data, path)
|
149
|
+
File.open(path, 'a') do |f|
|
150
|
+
f.write(data)
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
it 'should report a stale cache if a data lookup has not been performed' do
|
155
|
+
tmp_yamlfile = Pathname(Dir.mktmpdir('yaml')) + 'yamlfile'
|
156
|
+
create_yaml_file({'foo' => 'bar'}.to_yaml, tmp_yamlfile)
|
157
|
+
@backend.stale?(tmp_yamlfile).should == true
|
158
|
+
end
|
159
|
+
|
160
|
+
describe 'lookup tests' do
|
161
|
+
before(:each) do
|
162
|
+
@tmp_yamlfile = Pathname(Dir.mktmpdir('yaml')) + 'yamlfile'
|
163
|
+
create_yaml_file({'foo' => 'bar'}.to_yaml, @tmp_yamlfile)
|
164
|
+
Backend.expects(:datasources).yields("one")
|
165
|
+
Backend.expects(:datafile).with(:yaml, {}, "one", "yaml").returns(@tmp_yamlfile)
|
166
|
+
end
|
130
167
|
|
131
|
-
|
168
|
+
it 'should not report a stale cache after a data lookup' do
|
169
|
+
@backend.stale?(@tmp_yamlfile).should == true
|
170
|
+
@backend.lookup('foo', {}, nil, :priority).should == 'bar'
|
171
|
+
@backend.stale?(@tmp_yamlfile).should == false
|
172
|
+
end
|
132
173
|
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
174
|
+
[:ino, :mtime, :size].each do |attribute|
|
175
|
+
it "should report a stale cache if a backend file's #{attribute} has changed" do
|
176
|
+
@stat_instance = @fakestat.new(1234, 1234, 1234)
|
177
|
+
File.expects(:stat).with(@tmp_yamlfile).returns(@stat_instance).twice
|
178
|
+
@backend.stale?(@tmp_yamlfile).should == true
|
179
|
+
@backend.lookup('foo', {}, nil, :priority).should == 'bar'
|
180
|
+
@backend.stale?(@tmp_yamlfile).should == false
|
181
|
+
@stat_instance[attribute] += 1
|
182
|
+
File.unstub && File.expects(:stat).with(@tmp_yamlfile).returns(@stat_instance)
|
183
|
+
@backend.stale?(@tmp_yamlfile).should == true
|
184
|
+
end
|
138
185
|
end
|
186
|
+
end
|
139
187
|
end
|
188
|
+
end
|
140
189
|
end
|