Froze rails gems
[depot.git] / vendor / rails / actionpack / test / controller / session / mem_cache_store_test.rb
diff --git a/vendor/rails/actionpack/test/controller/session/mem_cache_store_test.rb b/vendor/rails/actionpack/test/controller/session/mem_cache_store_test.rb
new file mode 100644 (file)
index 0000000..a7d4843
--- /dev/null
@@ -0,0 +1,181 @@
+require 'abstract_unit'
+require 'action_controller/cgi_process'
+require 'action_controller/cgi_ext'
+
+
+class CGI::Session
+  def cache
+    dbman.instance_variable_get(:@cache)
+  end
+end
+
+
+uses_mocha 'MemCacheStore tests' do
+if defined? MemCache::MemCacheError
+
+class MemCacheStoreTest < Test::Unit::TestCase
+  SESSION_KEY_RE = /^session:[0-9a-z]+/
+  CONN_TEST_KEY = 'connection_test'
+  MULTI_TEST_KEY = '0123456789'
+  TEST_DATA = 'Hello test'
+
+  def self.get_mem_cache_if_available
+    begin
+      require 'memcache'
+      cache = MemCache.new('127.0.0.1')
+      # Test availability of the connection
+      cache.set(CONN_TEST_KEY, 1)
+      unless cache.get(CONN_TEST_KEY) == 1
+        puts 'Warning: memcache server available but corrupted.'
+        return nil
+      end
+    rescue LoadError, MemCache::MemCacheError
+      return nil
+    end
+    return cache
+  end
+
+  CACHE = get_mem_cache_if_available
+
+
+  def test_initialization
+    assert_raise(ArgumentError) { new_session('session_id' => '!invalid_id') }
+    new_session do |s|
+      assert_equal Hash.new, s.cache.get('session:' + s.session_id)
+    end
+  end
+
+
+  def test_storage
+    d = rand(0xffff)
+    new_session do |s|
+      session_key = 'session:' + s.session_id
+      unless CACHE
+        s.cache.expects(:get).with(session_key) \
+                             .returns(:test => d)
+        s.cache.expects(:set).with(session_key,
+                                   has_entry(:test, d),
+                                   0)
+      end
+      s[:test] = d
+      s.close
+      assert_equal d, s.cache.get(session_key)[:test]
+      assert_equal d, s[:test]
+    end
+  end         
+  
+  def test_deletion
+    new_session do |s|
+      session_key = 'session:' + s.session_id
+      unless CACHE
+        s.cache.expects(:delete)
+        s.cache.expects(:get).with(session_key) \
+                             .returns(nil)
+      end
+      s[:test] = rand(0xffff)
+      s.delete
+      assert_nil s.cache.get(session_key)
+    end
+  end
+
+
+  def test_other_session_retrieval
+    new_session do |sa|
+      unless CACHE
+        sa.cache.expects(:set).with('session:' + sa.session_id,
+                                    has_entry(:test, TEST_DATA),
+                                    0)
+      end
+      sa[:test] = TEST_DATA
+      sa.close
+      new_session('session_id' => sa.session_id) do |sb|
+        unless CACHE
+          sb.cache.expects(:[]).with('session:' + sb.session_id) \
+                               .returns(:test => TEST_DATA)
+        end
+        assert_equal(TEST_DATA, sb[:test])
+      end
+    end
+  end
+
+
+  def test_multiple_sessions
+    s_slots = Array.new(10)
+    operation = :write
+    last_data = nil
+    reads = writes = 0
+    50.times do
+      current = rand(10)
+      s_slots[current] ||= new_session('session_id' => MULTI_TEST_KEY,
+                                       'new_session' => true)
+      s = s_slots[current]
+      case operation
+      when :write
+        last_data = rand(0xffff)
+        unless CACHE
+          s.cache.expects(:set).with('session:' + MULTI_TEST_KEY,
+                                     { :test => last_data },
+                                     0)
+        end
+        s[:test] = last_data
+        s.close
+        writes += 1
+      when :read
+        # Make CGI::Session#[] think there was no data retrieval yet.
+        # Normally, the session caches the data during its lifetime.
+        s.instance_variable_set(:@data, nil)
+        unless CACHE
+          s.cache.expects(:[]).with('session:' + MULTI_TEST_KEY) \
+                              .returns(:test => last_data)
+        end
+        d = s[:test]
+        assert_equal(last_data, d, "OK reads: #{reads}, OK writes: #{writes}")
+        reads += 1
+      end
+      operation = rand(5) == 0 ? :write : :read
+    end
+  end
+
+
+
+  private
+  def obtain_session_options
+    options = { 'database_manager' => CGI::Session::MemCacheStore,
+                'session_key' => '_test_app_session'
+              }
+    # if don't have running memcache server we use mock instead
+    unless CACHE
+      options['cache'] = c = mock
+      c.stubs(:[]).with(regexp_matches(SESSION_KEY_RE))
+      c.stubs(:get).with(regexp_matches(SESSION_KEY_RE)) \
+                   .returns(Hash.new)
+      c.stubs(:add).with(regexp_matches(SESSION_KEY_RE),
+                         instance_of(Hash),
+                         0)
+    end
+    options
+  end
+
+
+  def new_session(options = {})
+    with_cgi do |cgi|
+      @options = obtain_session_options.merge(options)
+      session = CGI::Session.new(cgi, @options)
+      yield session if block_given?
+      return session
+    end
+  end
+
+  def with_cgi
+    ENV['REQUEST_METHOD'] = 'GET'
+    ENV['HTTP_HOST'] = 'example.com'
+    ENV['QUERY_STRING'] = ''
+
+    cgi = CGI.new('query', StringIO.new(''))
+    yield cgi if block_given?
+    cgi
+  end
+end
+
+end # defined? MemCache
+end # uses_mocha