<?php
/**
 * ezcCacheStorageApcPlainTest 
 * 
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 *
 * @package Cache
 * @subpackage Tests
 * @version //autogen//
 * @copyright Copyright (C) 2005-2010 eZ Systems AS. All rights reserved.
 * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0
 */

/**
 * Require parent test class. 
 */
require_once 'storage_test.php';
require_once 'wrappers/apc_wrapper.php';

/**
 * Test suite for ezcCacheStorageApc class. 
 * 
 * @package Cache
 * @subpackage Tests
 */
class ezcCacheStorageApcPlainTest extends ezcCacheStorageTest
{
    /**
     * Test data.
     *
     * @var array(string)
     */
    protected $testData = array(
        1 => "Test 1 2 3 4 5 6 7 8\\\\",
        2 => 'La la la 02064 lololo',
        3 => 12345,
        4 => 12.3746,
    );

    protected function setUp()
    {
        if ( !ezcBaseFeatures::hasExtensionSupport( 'apc' ) )
        {
            $this->markTestSkipped( "PHP must have APC support." );
        }

        // Class name == <inheriting class> - "Test"
        $storageClass = ( $this->storageClass = substr( get_class( $this ), 0, strlen( get_class(  $this ) ) - 4 ) );
        $this->storage = new $storageClass( $this->createTempDir( 'ezcCacheTest' ), array( 'ttl' => 10 ) );
    }

    // Override test from parent class
    public function testConstructorErrorLocationNotWriteable()
    {
        return true;
    }

    // Override test from parent class
    public function testStoreRestoreOutdatedWithoutAttributes()
    {
        $options = array( 'ttl' => 10 );
        $storage = new ezcCacheStorageApcWrapper( $this->getTempDir(), $options );
        $storage->reset();

        foreach ( $this->testData as $id => $dataArr ) 
        {
            $storage->store( $id, $dataArr );
            
            // Hack the cache to be outdated by 100 seconds
            $data = $storage->restore( $id );
            $registry = $storage->getRegistry();

            $location = $this->getTempDir() . DIRECTORY_SEPARATOR;
            list( $identifier, $dataObj ) = each( $registry[$location][$id] );
            $registry[$location][$id][$identifier]->time = time() - 100;
            $storage->setRegistry( $registry );

            $data = $storage->restore( $id );
            $this->assertTrue( $data === false, "Restore data broken for ID <{$id}>." );
        }

    }

    // Override test from parent class
    public function testStoreRestoreOutdatedWithAttributes()
    {
        $options = array( 'ttl' => 10 );
        $storage = new ezcCacheStorageApcWrapper( $this->getTempDir(), $options );
        $storage->reset();

        foreach ( $this->testData as $id => $dataArr ) 
        {
            $attributes = array(
                'name'      => 'test',
                'title'     => 'Test item',
                'date'      => time() . $id,
            );

            $storage->store( $id, $dataArr, $attributes );

            // Hack the cache to be outdated by 100 seconds
            $data = $storage->restore( $id, $attributes );
            $registry = $storage->getRegistry();

            $location = $this->getTempDir() . DIRECTORY_SEPARATOR;
            list( $identifier, $dataObj ) = each( $registry[$location][$id] );
            $registry[$location][$id][$identifier]->time = time() - 100;
            $storage->setRegistry( $registry );

            // Wait for cache to be outdated.
            $data = $storage->restore( $id, $attributes );
            $this->assertTrue( $data === false, "Restore data broken for ID <{$id}>." );
        }
    }

    public function testMockApcBackend()
    {
        $apcBackend = $this->getMock( 'ezcCacheApcBackend', array( 'store' ), array() );
        $apcBackend->expects( $this->any() )
                   ->method( 'store' )
                   ->will( $this->returnValue( false ) );

        $options = array( 'ttl' => 10 );
        $storage = new ezcCacheStorageApcWrapper( '.', $options );
        $storage->reset();
        $storage->setBackend( $apcBackend );

        $id = 'id';
        try
        {
            $storage->store( $id, 'data' );
            $this->fail( "Expected exception was not thrown." );
        }
        catch ( ezcCacheApcException $e )
        {
            $this->assertEquals( "Apc store failed.", $e->getMessage() );
        }
    }

    public function testStoreResource()
    {
        $resource = fopen( dirname( __FILE__ ) . DIRECTORY_SEPARATOR . 'wrappers' . DIRECTORY_SEPARATOR . 'apc_wrapper.php', 'r' );
        try
        {
            $this->storage->store( "key", $resource );
            $this->storage->reset();
            fclose( $resource );
            $this->fail( "Expected exception was not thrown." );
        }
        catch ( ezcCacheInvalidDataException $e )
        {
            fclose( $resource );
            $this->assertEquals( "The given data was of type 'resource', which can not be stored. Expecting: 'simple, array, object'.", $e->getMessage() );
        }
    }

    public function testGetRemainingLifetimeId()
    {
        $this->storage->setOptions( array( 'ttl' => 10 ) );

        $this->storage->store( '1', 'data1' );

        // "8 <= " - for those cases where the current second changes after the storage
        $this->assertEquals( true, 8 <= $this->storage->getRemainingLifetime( '1' ) );

    }

    public function testGetRemainingLifetimeAttributes()
    {
        $this->storage->reset();
        $this->storage->setOptions( array( 'ttl' => 10 ) );

        $this->storage->store( '1', 'data1', array( 'type' => 'simple' ) );
        $this->storage->store( '2', 'data2', array( 'type' => 'simple' ) );

        // "8 <= " - for those cases where the current second changes after the storage
        $this->assertGreaterThan(
            8,
            $this->storage->getRemainingLifetime( null, array( 'type' => 'simple' ) )
        );

    }

    public function testGetRemainingLifetimeNoMatch()
    {
        $this->storage->setOptions( array( 'ttl' => 10 ) );

        $this->assertEquals( 0, $this->storage->getRemainingLifetime( 'no_such_id' ) );

    }

    public function testCacheManagerLocationEmpty()
    {
        $options = array( 'ttl' => 10 );
        ezcCacheManager::createCache( 'cache', null, 'ezcCacheStorageApcPlain', $options );
        $storage = ezcCacheManager::getCache( 'cache' );
        $storage->reset();
        $storage->store( 'key', 'data' );
        $this->assertEquals( 'data', $storage->restore( 'key' ) );
    }

    public function testStorageApcOptions()
    {
        $options = new ezcCacheStorageApcOptions();

        $this->assertTrue( isset( $options->ttl ) );
        $this->assertTrue( isset( $options->lockWaitTime ) );
        $this->assertTrue( isset( $options->maxLockTime ) );
        $this->assertTrue( isset( $options->lockKey ) );
        $this->assertTrue( isset( $options->metaDataKey ) );

        $this->assertEquals( $options->ttl, 86400 );
        
        $this->assertFalse( isset( $options->foo ), 'Exception not thrown on invalid property.' );

        $this->assertSetPropertyFails(
            $options,
            'ttl',
            array( true, 42.23, array(), new stdClass(), '', 'foo' )
        );
        $this->assertSetPropertyFails(
            $options,
            'lockWaitTime',
            array( true, false, -23, 42.23, array(), new stdClass(), '', 'foo' )
        );
        $this->assertSetPropertyFails(
            $options,
            'maxLockTime',
            array( true, false, -23, 42.23, array(), new stdClass(), '', 'foo' )
        );
        $this->assertSetPropertyFails(
            $options,
            'lockKey',
            array( true, false, 42, -23, 42.23, array(), new stdClass(), '' )
        );
        $this->assertSetPropertyFails(
            $options,
            'metaDataKey',
            array( true, false, 42, -23, 42.23, array(), new stdClass(), '' )
        );

        $this->assertSetProperty( $options, 'ttl', array( 1, 1000 ) );
        $this->assertSetProperty( $options, 'lockWaitTime', array( 1, 10 ) );
        $this->assertSetProperty( $options, 'maxLockTime', array( 1, 10 ) );
        $this->assertSetProperty( $options, 'lockKey', array( 'foo' ) );
        $this->assertSetProperty( $options, 'metaDataKey', array( 'foo' ) );

        try
        {
            $options->foo = 23;
            $this->fail( 'Exception not thrown on set for unknown property.' );
        }
        catch ( ezcBasePropertyNotFoundException $e ) {}
        try
        {
            echo $options->foo;
            $this->fail( 'Exception not thrown on get for unknown property.' );
        }
        catch ( ezcBasePropertyNotFoundException $e ) {}
    }
    
    public function testStorageOptions()
    {
        $storageOptions = new ezcCacheStorageOptions();
        $storageApcOptions = new ezcCacheStorageApcOptions();
        $arrayOptions = array();

        $storage = new ezcCacheStorageApcPlain(
            '.',
            array()
        );
        $storage->reset();

        $storage->setOptions( $storageApcOptions );
        $this->assertEquals( $storageApcOptions, $storage->getOptions() );

        $storage->options = $storageApcOptions;
        $this->assertEquals( $storageApcOptions, $storage->getOptions() );
        
        $storage->setOptions( $storageOptions );
        $this->assertEquals( $storageApcOptions, $storage->getOptions() );

        $storage->options = $storageOptions;
        $this->assertEquals( $storageApcOptions, $storage->getOptions() );
        
        $storage->setOptions( $arrayOptions );
        $this->assertEquals( $storageApcOptions, $storage->getOptions() );

        $storage->options = $arrayOptions;
        $this->assertEquals( $storageApcOptions, $storage->getOptions() );

        $options = new stdClass();
        try
        {
            $storage->setOptions( $options );
            $this->fail( "Expected exception was not thrown." );
        }
        catch ( ezcBaseValueException $e )
        {
            $this->assertEquals(
                "The value 'O:8:\"stdClass\":0:{}' that you were trying to "
                    . "assign to setting 'options' is invalid. Allowed values "
                    . "are: instance of ezcCacheStorageApcOptions.",
                $e->getMessage()
            );
        }
    }
    
    public function testResetSuccess()
    {
        $options = array( 'ttl' => 10 );
        $storage = new ezcCacheStorageApcWrapper( '.', $options );
        $storage->reset();

        $data = array( 
            'ID',
            'Some/Dir/ID',
            'Some/other/Dir/ID/1',
            'Some/other/Dir/ID/2',
            'Some/other/Dir/ID/3',
        );
        foreach ( $data as $id ) 
        {
            $storage->store( $id, $id );
        }

        $this->assertEquals(
            5,
            $storage->countDataItems()
        );

        $storage->reset();

        $this->assertEquals(
            0,
            $storage->countDataItems()
        );
    }

    public function testDeleteReturnIds()
    {
        $storage = new ezcCacheStorageApcWrapper(
            '.',
            array( 'ttl' => 100 )
        );
        $storage->reset();

        $data = array( 
            'ID',
            'Some/Dir/ID',
            'Some/other/Dir/ID/1',
            'Some/other/Dir/ID/2',
            'Some/other/Dir/ID/3',
        );

        $attributes = array(
            'lang' => 'en',
        );

        foreach ( $data as $id ) 
        {
            $storage->store( $id, $id, $attributes );
        }

        $deleted = $storage->delete( 'Some/other/Dir/ID/3', $attributes, true );
        
        $this->assertEquals(
            array( 'Some/other/Dir/ID/3' ),
            $deleted,
            'Deleted IDs not returned correctly.'
        );

        $deleted = $storage->delete( null, $attributes, true );

        $this->assertEquals(
            array( 
                'ID',
                'Some/Dir/ID',
                'Some/other/Dir/ID/1',
                'Some/other/Dir/ID/2',
            ),
            $deleted,
            'Deleted IDs not returned correctly.'
        );
    }

    public function testPurgeNoLimit()
    {
        $storage = new ezcCacheStorageApcWrapper(
            '.',
            array( 'ttl' => 1 )
        );
        $storage->reset();

        $data = array( 
            'ID',
            'Some/Dir/ID',
            'Some/other/Dir/ID/1',
            'Some/other/Dir/ID/2',
            'Some/other/Dir/ID/3',
        );

        foreach ( $data as $id ) 
        {
            $storage->store( $id, $id );
        }

        // Outdate
        usleep( 1000002 );

        $purgedIds = $storage->purge();

        $this->assertEquals(
            $data,
            $purgedIds,
            'Purged IDs not returned correctly.'
        );
    }

    public function testPurgeLimit()
    {
        $storage = new ezcCacheStorageApcWrapper(
            '.',
            array( 'ttl' => 1 )
        );
        $storage->reset();

        $data = array( 
            'ID',
            'Some/Dir/ID',
            'Some/other/Dir/ID/1',
            'Some/other/Dir/ID/2',
            'Some/other/Dir/ID/3',
        );

        foreach ( $data as $id ) 
        {
            $storage->store( $id, $id );
        }

        // Outdate
        usleep( 1000002 );

        $purgedIds = $storage->purge( 3 );

        $this->assertEquals(
            array( 
                'ID',
                'Some/Dir/ID',
                'Some/other/Dir/ID/1',
            ),
            $purgedIds,
            'Purged IDs not returned correctly.'
        );
    }

    public function testLockSimple()
    {
        $storage = new ezcCacheStorageApcWrapper(
            '.',
            array( 'ttl' => 1 )
        );
        $storage->reset();

        $lockKey = urlencode( $storage->getLocation() ) . '_'
            . $storage->options->lockKey;

        $this->assertFalse(
            apc_fetch( $lockKey ),
            'Lock key exists.'
        );

        $this->assertFalse(
            $this->readAttribute( $storage, 'lock' ),
            'Lock stat not correctly initialized'
        );

        $storage->lock();

        $this->assertNotEquals(
            false,
            apc_fetch( $lockKey ),
            'Lock key not created correctly.'
        );

        $this->assertTrue(
            $this->readAttribute( $storage, 'lock' ),
            'Lock stat not correctly switched.'
        );

        $storage->unlock();

        $this->assertFalse(
            apc_fetch( $lockKey ),
            'Lock key exists.'
        );

        $this->assertFalse(
            $this->readAttribute( $storage, 'lock' ),
            'Lock stat not correctly initialized'
        );
    }

    public function testLockTimeout()
    {
        // Init 2 storages on same Memcache
        $opts = array(
            'ttl'         => 1,
            'maxLockTime' => 1
        );
        $storage = new ezcCacheStorageApcWrapper(
            '.',
            $opts
        );
        $storage->reset();
        $secondStorage = new ezcCacheStorageApcWrapper(
            '.',
            $opts
        );
        $secondStorage->reset();
        
        $lockKey = urlencode( $storage->getLocation() ) . '_'
            . $storage->options->lockKey;

        // Assert initial state
        $this->assertFalse(
            apc_fetch( $lockKey ),
            'Lock key exists.'
        );
        $this->assertFalse(
            $this->readAttribute( $storage, 'lock' ),
            'Lock state not correctly initialized'
        );
        $this->assertFalse(
            $this->readAttribute( $secondStorage, 'lock' ),
            'Lock state not correctly initialized in second storage'
        );

        $lockTime = time();
        // Perform lock
        $storage->lock();

        // Assert locked state
        $this->assertNotEquals(
            false,
            ( $oldLock = apc_fetch( $lockKey ) ),
            'Lock key not created correctly.'
        );
        $this->assertTrue(
            $this->readAttribute( $storage, 'lock' ),
            'Lock stat not correctly switched.'
        );
        $this->assertFalse(
            $this->readAttribute( $secondStorage, 'lock' ),
            'Lock state not correctly initialized in second storage'
        );

        // Should kill lock file after 1 sec
        $secondStorage->lock();

        // Assert that kill did not occur earlier
        $this->assertGreaterThanOrEqual(
            1,
            ( time() - $lockTime ),
            'Lock did not last for 1 sec.'
        );

        // Assert that lock key exists again
        $this->assertNotEquals(
            false,
            apc_fetch( $lockKey ),
            'Lock key not created correctly.'
        );
        // Assert that the new lock is not the same as the old one
        $this->assertGreaterThan(
            $oldLock,
            apc_fetch( $lockKey ),
            'Lock key not created correctly.'
        );
        // First storage does not note that its lock disappeared
        $this->assertTrue(
            $this->readAttribute( $storage, 'lock' ),
            'Lock state switched unexpectedly.'
        );
        // Second storage now has the lock
        $this->assertTrue(
            $this->readAttribute( $secondStorage, 'lock' ),
            'Lock state not correctly initialized in second storage'
        );

        $secondStorage->unlock();

        $this->assertFalse(
            apc_fetch( $lockKey ),
            'Lock key not created correctly.'
        );
        // First storage does not note that its lock disappeared and was not unlocked
        $this->assertTrue(
            $this->readAttribute( $storage, 'lock' ),
            'Lock state switched unexpectedly.'
        );
        // Second storage released the lock
        $this->assertFalse(
            $this->readAttribute( $secondStorage, 'lock' ),
            'Lock state not correctly initialized in second storage'
        );
    }

    public function testMetaDataSuccess()
    {
        $opts = array(
            'ttl'         => 1,
        );
        $storage = new ezcCacheStorageApcWrapper(
            '.',
            $opts
        );
        $storage->reset();
        
        $metaDataKey = urlencode( $storage->getLocation() ) . '_'
            . $storage->options->metaDataKey;

        $meta = new ezcCacheStackLruMetaData();
        $meta->setState(
            array(
                'replacementData' => array(
                    'id_1' => 23,
                    'id_2' => 42,
                ),
                'storageData' => array(
                    'storage_id_1' => array(
                        'id_1' => true,
                        'id_2' => true,
                    ),
                    'storage_id_2' => array(
                        'id_2' => true,
                    ),
                ),
            )
        );

        $this->assertFalse(
            apc_fetch( $metaDataKey ),
            'Meta data key existed before the storage was created.'
        );

        $storage->storeMetaData( $meta );

        $this->assertEquals(
            $meta,
            apc_fetch( $metaDataKey )->var,
            'Meta data file existed before the storage was created.'
        );

        $restoredMeta = $storage->restoreMetaData();

        $this->assertEquals(
            $meta,
            $restoredMeta,
            'Meta data not restored correctly.'
        );

        $this->assertEquals(
            $meta,
            apc_fetch( $metaDataKey )->var,
            'Meta data file existed before the storage was created.'
        );
    }

    public function testMetaDataFailure()
    {
        $opts = array(
            'ttl'         => 1,
        );
        $storage = new ezcCacheStorageApcWrapper(
            '.',
            $opts
        );
        $storage->reset();

        $metaDataKey = urlencode( $storage->getLocation() ) . '_'
            . $storage->options->metaDataKey;

        $this->assertFalse(
            apc_fetch( $metaDataKey ),
            'Meta data file existed before the storage was created.'
        );

        $restoredMeta = $storage->restoreMetaData();

        $this->assertNull(
            $restoredMeta,
            'Meta data not restored correctly.'
        );

        $this->assertFalse(
            apc_fetch( $metaDataKey ),
            'Meta data file existed before the storage was created.'
        );
    }

    public static function suite()
	{
		return new PHPUnit_Framework_TestSuite( __CLASS__ );
	}
}
?>
