Updated mcollective.init according to OSCI-658
[packages/precise/mcollective.git] / spec / unit / cache_spec.rb
diff --git a/spec/unit/cache_spec.rb b/spec/unit/cache_spec.rb
new file mode 100644 (file)
index 0000000..4dcff11
--- /dev/null
@@ -0,0 +1,161 @@
+#!/usr/bin/env rspec
+
+require 'spec_helper'
+
+module MCollective
+  describe Cache do
+    before do
+      @locks_mutex = Cache.instance_variable_set("@locks_mutex", Mutex.new)
+      @cache_locks = Cache.instance_variable_set("@cache_locks", {})
+      @cache = Cache.instance_variable_set("@cache", {})
+    end
+
+    describe "#check_cache!" do
+      it "should correctly check for valid caches" do
+        Cache.expects(:has_cache?).with("rspec").returns(true)
+        Cache.expects(:has_cache?).with("fail").returns(false)
+
+        Cache.check_cache!("rspec")
+        expect { Cache.check_cache!("fail") }.to raise_code("Could not find a cache called '%{cache_name}'", :cache_name => "fail")
+      end
+    end
+
+    describe "#setup" do
+      it "should use a mutex to manage access to the cache" do
+        @locks_mutex.expects(:synchronize).yields
+        Cache.setup("x").should == true
+        @cache.should == {"x" => {:max_age => 300.0}}
+      end
+
+      it "should correctly setup a new cache" do
+        @locks_mutex.expects(:synchronize).twice.yields
+        Cache.setup("rspec1", 300)
+        @cache["rspec1"].should == {:max_age => 300.0}
+
+        Cache.setup("rspec2")
+        @cache["rspec2"].should == {:max_age => 300.0}
+      end
+    end
+
+    describe "#has_cache?" do
+      it "should correctly report presense of a cache" do
+        Cache.setup("rspec")
+        Cache.has_cache?("rspec").should == true
+        Cache.has_cache?("fail").should == false
+      end
+    end
+
+    describe "#delete!" do
+      it "should delete the cache and return true" do
+        Cache.expects(:check_cache!).with("rspec")
+
+        Cache.setup("rspec")
+        Cache.delete!("rspec").should == true
+      end
+    end
+
+    describe "#write" do
+      it "should write to the cache" do
+        time = Time.now
+        Time.expects(:now).returns(time)
+        Cache.expects(:check_cache!).with("rspec")
+
+        Cache.setup("rspec")
+        Cache.write("rspec", :key, :val).should == :val
+
+        @cache["rspec"][:key][:value].should == :val
+        @cache["rspec"][:key][:cache_create_time].should == time
+      end
+    end
+
+    describe "#read" do
+      it "should read a written entry correctly" do
+        Cache.setup("rspec")
+        Cache.write("rspec", :key, :val)
+
+        Cache.expects(:check_cache!).with("rspec")
+        Cache.expects(:ttl).with("rspec", :key).returns(1)
+
+        Cache.read("rspec", :key).should == :val
+      end
+
+      it "should raise on expired reads" do
+        Cache.setup("rspec")
+        Cache.write("rspec", :key, :val)
+
+        Cache.expects(:ttl).returns(0)
+
+        Cache.expects(:check_cache!).with("rspec")
+
+        expect { Cache.read("rspec", :key) }.to raise_code("Cache expired on '%{cache_name}' key '%{item}'", :cache_name => "rspec", :item => :key)
+      end
+    end
+
+    describe "#invalidate!" do
+      it "should return false for unknown keys" do
+        Cache.expects(:check_cache!).with("rspec")
+
+        @locks_mutex.expects(:synchronize).yields
+
+        Cache.setup("rspec")
+        Cache.invalidate!("rspec", "no_such_key").should == false
+      end
+
+      it "should delete the key" do
+        Cache.setup("rspec")
+        Cache.write("rspec", "valid_key", "rspec")
+
+        Cache.expects(:check_cache!).with("rspec")
+        @cache["rspec"].expects(:delete).with("valid_key")
+
+        Cache.invalidate!("rspec", "valid_key")
+      end
+    end
+
+    describe "#ttl" do
+      it "should detect invalid key names" do
+        Cache.expects(:check_cache!).with("rspec")
+        Cache.setup("rspec", 300)
+        expect { Cache.ttl("rspec", :key) }.to raise_code("No item called '%{item}' for cache '%{cache_name}'", :cache_name => "rspec", :item => :key)
+      end
+
+      it "should return >0 for valid" do
+        Cache.setup("rspec", 300)
+        Cache.write("rspec", :key, :val)
+
+        Cache.expects(:check_cache!).with("rspec")
+        Cache.ttl("rspec", :key).should >= 0
+      end
+
+      it "should return <0 for expired messages" do
+        Cache.setup("rspec", 300)
+        Cache.write("rspec", :key, :val)
+
+        time = Time.now + 600
+        Time.expects(:now).returns(time)
+
+        Cache.expects(:check_cache!).with("rspec")
+        Cache.ttl("rspec", :key).should <= 0
+      end
+    end
+
+    describe "#synchronize" do
+      it "should use the correct mutex" do
+        Cache.expects(:check_cache!).with("rspec")
+        Cache.setup("rspec")
+
+        rspec_lock = @cache_locks["rspec"]
+        rspec_lock.expects(:synchronize).yields
+
+        @cache_locks.expects("[]").with("rspec").returns(rspec_lock)
+
+        ran = 0
+        Cache.synchronize("rspec") do
+          ran = 1
+        end
+
+        ran.should == 1
+      end
+    end
+  end
+end