4dcff11cb99530e9b0d799bf8a7450c2747b5ec0
[packages/precise/mcollective.git] / spec / unit / cache_spec.rb
1 #!/usr/bin/env rspec
2
3 require 'spec_helper'
4
5 module MCollective
6   describe Cache do
7     before do
8       @locks_mutex = Cache.instance_variable_set("@locks_mutex", Mutex.new)
9       @cache_locks = Cache.instance_variable_set("@cache_locks", {})
10       @cache = Cache.instance_variable_set("@cache", {})
11     end
12
13     describe "#check_cache!" do
14       it "should correctly check for valid caches" do
15         Cache.expects(:has_cache?).with("rspec").returns(true)
16         Cache.expects(:has_cache?).with("fail").returns(false)
17
18         Cache.check_cache!("rspec")
19         expect { Cache.check_cache!("fail") }.to raise_code("Could not find a cache called '%{cache_name}'", :cache_name => "fail")
20       end
21     end
22
23     describe "#setup" do
24       it "should use a mutex to manage access to the cache" do
25         @locks_mutex.expects(:synchronize).yields
26         Cache.setup("x").should == true
27         @cache.should == {"x" => {:max_age => 300.0}}
28       end
29
30       it "should correctly setup a new cache" do
31         @locks_mutex.expects(:synchronize).twice.yields
32         Cache.setup("rspec1", 300)
33         @cache["rspec1"].should == {:max_age => 300.0}
34
35         Cache.setup("rspec2")
36         @cache["rspec2"].should == {:max_age => 300.0}
37       end
38     end
39
40     describe "#has_cache?" do
41       it "should correctly report presense of a cache" do
42         Cache.setup("rspec")
43         Cache.has_cache?("rspec").should == true
44         Cache.has_cache?("fail").should == false
45       end
46     end
47
48     describe "#delete!" do
49       it "should delete the cache and return true" do
50         Cache.expects(:check_cache!).with("rspec")
51
52         Cache.setup("rspec")
53         Cache.delete!("rspec").should == true
54       end
55     end
56
57     describe "#write" do
58       it "should write to the cache" do
59         time = Time.now
60         Time.expects(:now).returns(time)
61         Cache.expects(:check_cache!).with("rspec")
62
63         Cache.setup("rspec")
64         Cache.write("rspec", :key, :val).should == :val
65
66         @cache["rspec"][:key][:value].should == :val
67         @cache["rspec"][:key][:cache_create_time].should == time
68       end
69     end
70
71     describe "#read" do
72       it "should read a written entry correctly" do
73         Cache.setup("rspec")
74         Cache.write("rspec", :key, :val)
75
76         Cache.expects(:check_cache!).with("rspec")
77         Cache.expects(:ttl).with("rspec", :key).returns(1)
78
79         Cache.read("rspec", :key).should == :val
80       end
81
82       it "should raise on expired reads" do
83         Cache.setup("rspec")
84         Cache.write("rspec", :key, :val)
85
86         Cache.expects(:ttl).returns(0)
87
88         Cache.expects(:check_cache!).with("rspec")
89
90         expect { Cache.read("rspec", :key) }.to raise_code("Cache expired on '%{cache_name}' key '%{item}'", :cache_name => "rspec", :item => :key)
91       end
92     end
93
94     describe "#invalidate!" do
95       it "should return false for unknown keys" do
96         Cache.expects(:check_cache!).with("rspec")
97
98         @locks_mutex.expects(:synchronize).yields
99
100         Cache.setup("rspec")
101         Cache.invalidate!("rspec", "no_such_key").should == false
102       end
103
104       it "should delete the key" do
105         Cache.setup("rspec")
106         Cache.write("rspec", "valid_key", "rspec")
107
108         Cache.expects(:check_cache!).with("rspec")
109         @cache["rspec"].expects(:delete).with("valid_key")
110
111         Cache.invalidate!("rspec", "valid_key")
112       end
113     end
114
115     describe "#ttl" do
116       it "should detect invalid key names" do
117         Cache.expects(:check_cache!).with("rspec")
118         Cache.setup("rspec", 300)
119         expect { Cache.ttl("rspec", :key) }.to raise_code("No item called '%{item}' for cache '%{cache_name}'", :cache_name => "rspec", :item => :key)
120       end
121
122       it "should return >0 for valid" do
123         Cache.setup("rspec", 300)
124         Cache.write("rspec", :key, :val)
125
126         Cache.expects(:check_cache!).with("rspec")
127         Cache.ttl("rspec", :key).should >= 0
128       end
129
130       it "should return <0 for expired messages" do
131         Cache.setup("rspec", 300)
132         Cache.write("rspec", :key, :val)
133
134         time = Time.now + 600
135         Time.expects(:now).returns(time)
136
137         Cache.expects(:check_cache!).with("rspec")
138         Cache.ttl("rspec", :key).should <= 0
139       end
140     end
141
142     describe "#synchronize" do
143       it "should use the correct mutex" do
144         Cache.expects(:check_cache!).with("rspec")
145         Cache.setup("rspec")
146
147         rspec_lock = @cache_locks["rspec"]
148         rspec_lock.expects(:synchronize).yields
149
150         @cache_locks.expects("[]").with("rspec").returns(rspec_lock)
151
152         ran = 0
153         Cache.synchronize("rspec") do
154           ran = 1
155         end
156
157         ran.should == 1
158       end
159     end
160   end
161 end