/* ====================================================================
 * The Apache Software License, Version 1.1
 *
 * Copyright (c) 2000-2001 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Apache" and "Apache Software Foundation" and
 *     "Apache Jetspeed" must not be used to endorse or promote products
 *    derived from this software without prior written permission. For
 *    written permission, please contact apache@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache" or
 *    "Apache Jetspeed", nor may "Apache" appear in their name, without
 *    prior written permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */


package org.apache.turbine.services.cache;

// Cactus and Junit imports
import junit.awtui.TestRunner;
import junit.framework.Test;
import junit.framework.TestSuite;
import org.apache.cactus.ServletTestCase;

// Turbine imports
import org.apache.turbine.services.TurbineServices;
import org.apache.turbine.services.cache.GlobalCacheService;
import org.apache.turbine.services.cache.CachedObject;
import org.apache.turbine.services.cache.ObjectExpiredException;
import org.apache.turbine.services.cache.Refreshable;
import org.apache.turbine.services.cache.RefreshableCachedObject;
import org.apache.turbine.Turbine;

/**
 * TurbineCacheTest
 *
 * @author <a href="paulsp@apache.org">Paul Spencer</a>
 * @version $Id$
 */
public class TurbineCacheTest extends ServletTestCase {
    
    private Turbine turbine = null;
    private static final String cacheKey = new String("CacheKey");
    private static final String cacheKey_2 = new String("CacheKey_2");
    private static final long TURBINE_CACHE_REFRESH = 5000; // in millis
    private static final long TEST_EXPIRETIME = TURBINE_CACHE_REFRESH + 1000;
    private static final long TEST_TIMETOLIVE = TEST_EXPIRETIME * 5;
    /**
     * Defines the testcase name for JUnit.
     *
     * @param name the testcase's name.
     */
    public TurbineCacheTest( String name )
    {
        super( name );
    }
    
    /**
     * Start the tests.
     *
     * @param args the arguments. Not used
     */
    public static void main(String args[])
    {
        TestRunner.main(new String[] { TurbineCacheTest.class.getName() });
    }

    /**
     * Creates the test suite.
     *
     * @return a test suite (<code>TestSuite</code>) that includes all methods
     *         starting with "test"
     */
    public static Test suite()
    {
        // All methods starting with "test" will be executed in the test suite.
        return new TestSuite( TurbineCacheTest.class );
    }

    /**
     * This setup will be running server side.  We startup Turbine and
     * get our test port from the properties.  This gets run before
     * each testXXX test.
     */
    protected void setUp()
        throws Exception
    {
        super.setUp();
        config.setInitParameter("properties",
                "/WEB-INF/conf/TurbineCacheTest.properties");
        turbine = new Turbine();
        turbine.init(config);
    }

    /**
     * After each testXXX test runs, shut down the Turbine servlet.
     */
    protected void tearDown()
        throws Exception
    {
        turbine.destroy();
        super.tearDown();
    }
    
    /**
     * Simple test that verify an object can be created and deleted.
     * @throws Exception
     */
    public void testSimpleAddGetCacheObject() throws Exception
    {
        String testString = new String( "This is a test");
        Object retrievedObject = null;
        CachedObject cacheObject1 = null;
        
        GlobalCacheService globalCache = (GlobalCacheService)TurbineServices
        .getInstance()
        .getService( GlobalCacheService.SERVICE_NAME );
        
        // Create object
        cacheObject1 = new CachedObject(testString);
        assertNotNull( "Failed to create a cachable object 1", cacheObject1);
        
        // Add object to cache
        globalCache.addObject(cacheKey, cacheObject1);
        
        // Get object from cache
        retrievedObject = globalCache.getObject(cacheKey);
        assertNotNull( "Did not retrieved a cached object 1", retrievedObject);
        assertTrue( "Did not retrieved a correct, expected cached object 1", retrievedObject == cacheObject1);
        
        // Remove object from cache
        globalCache.removeObject(cacheKey);
        
        // Verify object removed from cache
        retrievedObject = null;
        cacheObject1 = null;
        try
        {
            retrievedObject = globalCache.getObject(cacheKey);
            assertNull( "Retrieved the deleted cached object 1 and did not get expected ObjectExpiredException", retrievedObject);
            assertNotNull( "Did not get expected ObjectExpiredException retrieving a deleted object", retrievedObject);
        }
        catch (ObjectExpiredException e)
        {
            assertNull( "Retrieved the deleted cached object 1, but caught expected ObjectExpiredException exception", retrievedObject);
        }
        catch (Exception e)
        {
            throw e;
        }
        
        // Remove object from cache that does NOT exist in the cache
        globalCache.removeObject(cacheKey);
    }
    
    /**
     * Simple test that adds, retrieves, and deletes 2 object.
     *
     * @throws Exception
     */
    public void test2ObjectAddGetCachedObject() throws Exception
    {
        String testString = new String( "This is a test");
        Object retrievedObject = null;
        CachedObject cacheObject1 = null;
        CachedObject cacheObject2 = null;
        
        GlobalCacheService globalCache = (GlobalCacheService)TurbineServices
        .getInstance()
        .getService( GlobalCacheService.SERVICE_NAME );
        
        // Create and add Object #1
        cacheObject1 = new CachedObject(testString);
        assertNotNull( "Failed to create a cachable object 1", cacheObject1);
        globalCache.addObject(cacheKey, cacheObject1);
        retrievedObject = globalCache.getObject(cacheKey);
        assertNotNull( "Did not retrieved a cached object 1", retrievedObject);
        assertEquals( "Did not retrieved correct cached object", cacheObject1, retrievedObject);
        
        // Create and add Object #2
        cacheObject2 = new CachedObject(testString);
        assertNotNull( "Failed to create a cachable object 2", cacheObject2);
        globalCache.addObject(cacheKey_2, cacheObject2);
        retrievedObject = globalCache.getObject(cacheKey_2);
        assertNotNull( "Did not retrieved a cached object 2", retrievedObject);
        assertEquals( "Did not retrieved correct cached object 2", cacheObject2, retrievedObject);
        
        // Get object #1
        retrievedObject = globalCache.getObject(cacheKey);
        assertNotNull( "Did not retrieved a cached object 1. Attempt #2", retrievedObject);
        assertEquals( "Did not retrieved correct cached object 1. Attempt #2", cacheObject1, retrievedObject);
        
        // Get object #1
        retrievedObject = globalCache.getObject(cacheKey);
        assertNotNull( "Did not retrieved a cached object 1. Attempt #3", retrievedObject);
        assertEquals( "Did not retrieved correct cached object 1. Attempt #3", cacheObject1, retrievedObject);
        
        // Get object #2
        retrievedObject = globalCache.getObject(cacheKey_2);
        assertNotNull( "Did not retrieved a cached object 2. Attempt #2", retrievedObject);
        assertEquals( "Did not retrieved correct cached object 2 Attempt #2", cacheObject2, retrievedObject);
        
        // Remove objects
        globalCache.removeObject(cacheKey);
        globalCache.removeObject(cacheKey_2);
    }
    
    /**
     * Verify that an object will throw the ObjectExpiredException
     * when it now longer exists in cache.
     *
     * @throws Exception
     */    
    public void testObjectExpiration() throws Exception
    {
        String testString = new String( "This is a test");
        Object retrievedObject = null;
        CachedObject cacheObject = null;
        
        GlobalCacheService globalCache = (GlobalCacheService)TurbineServices
        .getInstance()
        .getService( GlobalCacheService.SERVICE_NAME );
        
        // Create and add Object that expires in 1000 millis (1 second)
        cacheObject = new CachedObject(testString, 1000);
        assertNotNull( "Failed to create a cachable object", cacheObject);
        long addTime = System.currentTimeMillis();
        globalCache.addObject(cacheKey, cacheObject);
        
        // Try to get un-expired object
        try
        {
            retrievedObject = null;
            retrievedObject = globalCache.getObject(cacheKey);
            assertNotNull( "Did not retrieved a cached object", retrievedObject);
            assertEquals( "Did not retrieved correct cached object", cacheObject, retrievedObject);
        }
        catch (ObjectExpiredException e)
        {
            assertTrue( "Object expired early ( " + (System.currentTimeMillis() - addTime) + " millis)", false);
        }
        catch (Exception e)
        {
            throw e;
        }
        
        // Sleep 1500 Millis (1.5 seconds)
        Thread.sleep(1500);
        
        // Try to get expired object
        try
        {
            retrievedObject = null;
            retrievedObject = globalCache.getObject(cacheKey);
            assertNull( "Retrieved the expired cached object  and did not get expected ObjectExpiredException", retrievedObject);
            assertNotNull( "Did not get expected ObjectExpiredException retrieving an expired object", retrievedObject);
        }
        catch (ObjectExpiredException e)
        {
            assertNull( "Retrieved the expired cached object, but caught expected ObjectExpiredException exception", retrievedObject);
        }
        catch (Exception e)
        {
            throw e;
        }
        
        // Remove objects
        globalCache.removeObject(cacheKey);
    }

    /**
     * Verify the all object will be flushed from the cache.
     *
     * This test can take server minutes.
     *
     * @throws Exception
     */    
    public void testCacheFlush() throws Exception
    {
        String testString = new String( "This is a test");
        Object retrievedObject = null;
        CachedObject cacheObject = null;
        
        GlobalCacheService globalCache = (GlobalCacheService)TurbineServices
        .getInstance()
        .getService( GlobalCacheService.SERVICE_NAME );
        
        // Create and add Object that expires in 1 turbine Refresh + 1 millis 
        cacheObject = new CachedObject(testString, (TURBINE_CACHE_REFRESH*5) + 1);
        assertNotNull( "Failed to create a cachable object", cacheObject);
        long addTime = System.currentTimeMillis();
        globalCache.addObject(cacheKey, cacheObject);
                
        // 1 Refresh
        Thread.sleep(TURBINE_CACHE_REFRESH + 1);
        assertTrue("No object in cache before flush", (0 < globalCache.getNumberOfObjects()));
        
        // Flush Cache
        globalCache.flushCache();

        // Wait 15 seconds, 3 Refresh
        Thread.sleep((TURBINE_CACHE_REFRESH * 2) + 1);
        assertEquals("After refresh", 0, globalCache.getNumberOfObjects());
        
        // Remove objects
        globalCache.removeObject(cacheKey);
    }

    /**
     * Verify the Cache count is correct.
     * @throws Exception
     */    
    public void testObjectCount() throws Exception
    {
        GlobalCacheService globalCache = (GlobalCacheService)TurbineServices
        .getInstance()
        .getService( GlobalCacheService.SERVICE_NAME );
        assertNotNull("Could not retrive cache service.", globalCache);

        // Create and add Object that expires in 1.5 turbine Refresh
        long expireTime = TURBINE_CACHE_REFRESH + TURBINE_CACHE_REFRESH/2;
        CachedObject cacheObject = new CachedObject("This is a test", expireTime);
        assertNotNull( "Failed to create a cachable object", cacheObject);

        globalCache.addObject(cacheKey, cacheObject);
        assertEquals("After adding 1 Object", 1, globalCache.getNumberOfObjects());
        
        // Wait until we're passed 1 refresh, but not half way.
        Thread.sleep(TURBINE_CACHE_REFRESH + TURBINE_CACHE_REFRESH/3);
        assertEquals("After one refresh", 1, globalCache.getNumberOfObjects());

        // Wait until we're passed 2 more refreshes
        Thread.sleep((TURBINE_CACHE_REFRESH * 2) + TURBINE_CACHE_REFRESH/3);
        assertEquals("After three refreshes", 0, globalCache.getNumberOfObjects());
    }

    /**
     * Verfy a refreshable object will refreshed in the following cases:
     * o The object is retrieved via getObject an it is stale.
     * o The object is determied to be stale during a cache
     *   refresh
     *
     * This test can take serveral minutes.
     *
     * @throws Exception
     */    
    public void testRefreshableObject() throws Exception
    {
        String testString = new String( "This is a test");
        Object retrievedObject = null;
        RefreshableCachedObject cacheObject = null;
        
        GlobalCacheService globalCache = (GlobalCacheService)TurbineServices
        .getInstance()
        .getService( GlobalCacheService.SERVICE_NAME );
        
        // Create and add Object that expires in TEST_EXPIRETIME millis.
        cacheObject = new RefreshableCachedObject(new RefreshableObject(), TEST_EXPIRETIME);
        assertNotNull( "Failed to create a cachable object", cacheObject);
        long addTime = System.currentTimeMillis();
        globalCache.addObject(cacheKey, cacheObject);
        
        // Try to get un-expired object
        try
        {
            retrievedObject = null;
            retrievedObject = globalCache.getObject(cacheKey);
            assertNotNull( "Did not retrieved a cached object", retrievedObject);
            assertEquals( "Did not retrieved correct cached object", cacheObject, retrievedObject);
        }
        catch (ObjectExpiredException e)
        {
            assertTrue( "Object expired early ( " + (System.currentTimeMillis() - addTime) + " millis)", false);
        }
        catch (Exception e)
        {
            throw e;
        }
        
        // Wait 1 Turbine cache refresh + 1 second.
        Thread.sleep(TEST_EXPIRETIME + 1000);
        
        // Try to get expired object
        try
        {
            retrievedObject = null;
            retrievedObject = globalCache.getObject(cacheKey);
            assertNotNull( "Did not retrieved a cached object, after sleep", retrievedObject);
            assertNotNull( "Cached object has no contents, after sleep.", ((RefreshableCachedObject)retrievedObject).getContents());
            assertTrue( "Object did not refresh.", ( ((RefreshableObject)((RefreshableCachedObject)retrievedObject).getContents()).getRefreshCount() > 0));
        }
        catch (ObjectExpiredException e)
        {
            assertTrue( "Received unexpected ObjectExpiredException exception "
            + "when retrieving refreshable object after ( "
            + (System.currentTimeMillis() - addTime) + " millis)", false);
        }
        catch (Exception e)
        {
            throw e;
        }
        
        // See if object will expires (testing every second for 100 seconds.  It sould not!
        for (int i=0; i<100; i++)
        {
            Thread.sleep(1000); // Sleep 0.5 seconds
            
            // Try to get expired object
            try
            {
                retrievedObject = null;
                retrievedObject = globalCache.getObject(cacheKey);
                assertNotNull( "Did not retrieved a cached object, after sleep", retrievedObject);
                assertNotNull( "Cached object has no contents, after sleep.", ((RefreshableCachedObject)retrievedObject).getContents());
                assertTrue( "Object did not refresh.", ( ((RefreshableObject)((RefreshableCachedObject)retrievedObject).getContents()).getRefreshCount() > 0));
            }
            catch (ObjectExpiredException e)
            {
                assertTrue( "Received unexpected ObjectExpiredException exception "
                + "when retrieving refreshable object after ( "
                + (System.currentTimeMillis() - addTime) + " millis)", false);
            }
            catch (Exception e)
            {
                throw e;
            }
        }
        // Remove objects
        globalCache.removeObject(cacheKey);
    }
    
    /**
     * Verify a cached object will be delete after it has been
     * untouched beyond it's TimeToLive.
     *
     * This test can take serveral minutes.
     *
     * @throws Exception
     */    
    public void testRefreshableTimeToLive() throws Exception
    {
        String testString = new String( "This is a test");
        Object retrievedObject = null;
        RefreshableCachedObject cacheObject = null;
        
        GlobalCacheService globalCache = (GlobalCacheService)TurbineServices
        .getInstance()
        .getService( GlobalCacheService.SERVICE_NAME );
        
        // Create and add Object that expires in TEST_EXPIRETIME millis.
        cacheObject = new RefreshableCachedObject(new RefreshableObject(), TEST_EXPIRETIME);
        assertNotNull( "Failed to create a cachable object", cacheObject);
        cacheObject.setTTL(TEST_TIMETOLIVE);

        // Verify TimeToLive was set
        assertEquals( "Returned TimeToLive", TEST_TIMETOLIVE, cacheObject.getTTL());

        // Add object to Cache
        long addTime = System.currentTimeMillis();
        globalCache.addObject(cacheKey, cacheObject);
        
        // Try to get un-expired object
        try
        {
            retrievedObject = null;
            retrievedObject = globalCache.getObject(cacheKey);
            assertNotNull( "Did not retrieved a cached object", retrievedObject);
            assertEquals( "Did not retrieved correct cached object", cacheObject, retrievedObject);
        }
        catch (ObjectExpiredException e)
        {
            assertTrue( "Object expired early ( " + (System.currentTimeMillis() - addTime) + " millis)", false);
        }
        catch (Exception e)
        {
            throw e;
        }
        
        // Wait long enough to allow object to expire, but do not exceed TTL
        Thread.sleep(TEST_TIMETOLIVE - 2000);
        
        // Try to get expired object
        try
        {
            retrievedObject = null;
            retrievedObject = globalCache.getObject(cacheKey);
            assertNotNull( "Did not retrieved a cached object, after sleep", retrievedObject);
            assertNotNull( "Cached object has no contents, after sleep.", ((RefreshableCachedObject)retrievedObject).getContents());
            assertTrue( "Object did not refresh.", ( ((RefreshableObject)((RefreshableCachedObject)retrievedObject).getContents()).getRefreshCount() > 0));
        }
        catch (ObjectExpiredException e)
        {
            assertTrue( "Received unexpected ObjectExpiredException exception "
            + "when retrieving refreshable object after ( "
            + (System.currentTimeMillis() - addTime) + " millis)", false);
        }
        catch (Exception e)
        {
            throw e;
        }
        
        // Wait long enough to allow object to expire and exceed TTL
        Thread.sleep(TEST_TIMETOLIVE +5000);
        
        // Try to get expired object
        try
        {
            retrievedObject = null;
            retrievedObject = globalCache.getObject(cacheKey);
            assertNull( "Retrieved a cached object, after exceeding TimeToLive", retrievedObject);
        }
        catch (ObjectExpiredException e)
        {
            assertNull( "Retrieved the expired cached object, but caught expected ObjectExpiredException exception", retrievedObject);
        }
        catch (Exception e)
        {
            throw e;
        }
    }

    /**
     * Simple object that can be refreshed
     */
    class RefreshableObject implements Refreshable
    {
        
        private int refreshCount = 0;
        
        /**
         * Increment the refresh counter
         */
        public void refresh()
        {
            this.refreshCount++;
        }
        
        /**
         * Reutrn the number of time this object has been refreshed
         *
         * @return Number of times refresh() has been called
         */
        public int getRefreshCount()
        {
            return this.refreshCount;
        }
    }
}
