Location: PHPKode > scripts > PHP DataCache > php-datacachea1/tests/TestDataCacheDaoPgDb.php
<?php
/**
 * test harness for DataCacheDaoPgDb class tests
 *
 * Modification History: <pre>
 *	$Log: TestDataCacheDaoPgDb.php,v $
 *	Revision 1.1.1.1  2003/12/11 05:22:12  jsweat
 *	Initial check-in of PHP DataCache library.
 *	
 * </pre>
 * @author		Jason E. Sweat
 * @since		2003-11-21
 * @package		DataCache
 * @subpackage	tests
 * @version		$Id: TestDataCacheDaoPgDb.php,v 1.1.1.1 2003/12/11 05:22:12 jsweat Exp $
 */
error_reporting(E_ALL);

/**
 *	relative path to SimpleTest
 *	@ignore
 */
@define('SIMPLE_TEST', '../.lib/simpletest/');
/**
 *	SimpleTest base class
 */
require_once SIMPLE_TEST.'unit_tester.php';
/**
 *	SimpleTest reporter class
 */
require_once SIMPLE_TEST.'reporter.php';
/**
 *	SimpleTest mock objects support
 */
require_once SIMPLE_TEST.'mock_objects.php';
/**
 * modify the php include path to include parent directory
 *
 * This is done becuase the tests are run from the tests sub-directory
 * and the application is run (and coded for) from the parent directory
 * @ignore
 */
if (!defined('TEST_PATH_MODIFIED')) {
	ini_set('include_path', '..:'.ini_get('include_path'));
	define('TEST_PATH_MODIFIED', true);
}
/**
 *	DataCache config
 */
require_once 'DataCacheConfig.php';
/**
 *	DataCache class to be tested
 */
require_once 'DataCacheDaoPgDb.php';
/**
 *	Application Identifier to use for the tests
 *	@ignore
 */
@define('TEST_APPLICATION', 'SimpleTests');
/**
 *	simulated application id
 */
define('TEST_DAOPGDB_APPL_ID', 1);
/**
 *	empty cache data identifier
 */
define('TEST_DAOPGDB_BLANK', 'empty');
/**
 * still not working
 * with funky chars ~!@#$%^&*()_+`-={}|\][:"<>?';/.,
 *
 */
define('TEST_DAOPGDB_STRING', <<<EOS
has both ' 
and " in it
on multiple lines
EOS
);

/**
 *
 * @package		DataCache
 * @subpackage	tests
 */
class TestDataCacheDaoPgDb extends UnitTestCase 
{
	/**
	 * @var	object	$_moCache	the data cache object
	 */
	var $_moCache;

	/**
	 * constructor
	 *
	 * @return	void
	 */
	function TestDataCacheDaoPgDb($psName='') {
		$this->UnitTestCase($psName);
	}
	
	/**
	 * initialization of test function
	 *
	 * @return	void
	 */
	function SetUp() {
		/**
		 *	ADOdb library
		 *	{@link http://php.weblogs.com/ADOdb php.weblogs.com/ADOdb}
		 */
		require_once DATACACHE_ADODB_LIB_PATH.'adodb.inc.php';
		
		Mock::Generate('ADOConnection');
		Mock::Generate('ADORecordSet');
		$this->_moConn =& new MockADOConnection($this);
		$o_rs_appl =& new MockADORecordSet($this);
		$o_rs_appl->SetReturnValueAt(0, 'FetchRow'
									, array(DATACACHE_DAOPGDB_SEL_APPL_ID => TEST_DAOPGDB_APPL_ID));
		$this->_moConn->SetReturnReferenceAt(0, 'Execute', $o_rs_appl);
		$this->_moConn->ExpectArgumentsAt(0
							,'Execute'
							,array('select '.DATACACHE_DAOPGDB_SEL_APPL_ID.'(?)'
									, array(TEST_APPLICATION)));
		$this->_moCache =& new DataCacheDaoPgDb(TEST_APPLICATION, $this->_moConn);
	}
	
	/**
	 * test php environment is setup correctly
	 *
	 * @return	void
	 */
	function TestInstanciate() {
		$this->AssertNoErrors();
		$this->_moConn->Tally();
	}
	
	/**
	 * test when data not already cached
	 *
	 * @return	void
	 */
	function TestEmptyCache() {
		$o_conn =& $this->_moConn;
		$o_test =& $this->_moCache;
		$id = TEST_DAOPGDB_BLANK;
		
		$o_rs =& new MockADORecordSet($this);
		$o_rs->SetReturnValueAt(0, 'FetchRow'
								, array(DATACACHE_DAOPGDB_CHK_DATA => '0'));

		$o_conn->SetReturnReferenceAt(1, 'Execute', $o_rs); //starts at 1
		$o_conn->ExpectCallCount('Execute', 2);
		$o_conn->ExpectArgumentsAt(1, 'Execute'
							,array('select '.DATACACHE_DAOPGDB_CHK_DATA.'(?, ?)'
									,array(TEST_DAOPGDB_APPL_ID, $id)));
		$this->AssertFalse($o_test->IsCached($id));
		$o_conn->Tally();
	}
	
	/**
	 * simulate the compression used by the DAO
	 *
	 * @param	mixed	$pmData	the data to zip
	 * @return	string			the ziped date
	 */
	function Zip($pmData)
	{
		return base64_encode(gzcompress(serialize($pmData)));
	}
	
	/**
	 * simulate the serialization used by the DAO
	 *
	 * @param	mixed	$pmData	the data to zip
	 * @return	string			the ziped date
	 */
	function Ser($pmData)
	{
		return addslashes(serialize($pmData));
	}

	/**
	 * test caching different types
	 *
	 * @return	void
	 */
	function TestCache() {
		$data_id = 'data';
		$data = array(
			 'str1'		=> 'a simple string'
			,'str2'		=> "a multi-\nline string"
			,'str3'		=> 'a "double quote" string'
			,'str4' 	=> "a 'single quote' string"
			,'str5' 	=> TEST_DAOPGDB_STRING
			,'int'		=> mktime()
			,'array'	=> array('one', 'two', 'three')
			,'object'	=> new ObjectTest
			);
		$s_serial_compress_data = $this->Zip($data);
		$s_slashed_serial_data = $this->Ser($data);

		$o_test =& $this->_moCache;
		$o_conn =& $this->_moConn;
		
		$o_rs =& new MockADORecordSet($this);
		$o_rs->SetReturnValueAt(0, 'FetchRow', array(DATACACHE_DAOPGDB_SET_DATA => '1'));
		$o_rs->SetReturnValueAt(1, 'FetchRow', array(DATACACHE_DAOPGDB_CHK_DATA => '1'));
		$o_rs->SetReturnValueAt(2, 'FetchRow', array(DATACACHE_DAOPGDB_GET_DATA => 'Y'.$s_serial_compress_data));
		$o_conn->SetReturnReference('Execute', $o_rs);
		$o_conn->ExpectArgumentsAt(1 , 'Execute', array(
									'select '.DATACACHE_DAOPGDB_SET_DATA.'(?, ?, ?, ?)'
									,array(TEST_DAOPGDB_APPL_ID, $data_id, 'Y', $s_serial_compress_data)
									));
		$o_conn->ExpectArgumentsAt(2, 'Execute'
							,array('select '.DATACACHE_DAOPGDB_CHK_DATA.'(?, ?)'
									,array(TEST_DAOPGDB_APPL_ID, $data_id)));
		$o_conn->ExpectArgumentsAt(3, 'Execute'
							,array('select '.DATACACHE_DAOPGDB_GET_DATA.'(?, ?)'
									,array(TEST_DAOPGDB_APPL_ID, $data_id)));
		$this->AssertTrue($o_test->SetCache($data_id, $data));
		$this->AssertIdentical($o_test->GetCache($data_id), $data);
		
		$o_rs->SetReturnValueAt(3, 'FetchRow', array(DATACACHE_DAOPGDB_SET_DATA => '1'));
		$o_rs->SetReturnValueAt(4, 'FetchRow', array(DATACACHE_DAOPGDB_CHK_DATA => '1'));
		$o_rs->SetReturnValueAt(5, 'FetchRow', array(DATACACHE_DAOPGDB_GET_DATA => 'N'.$s_slashed_serial_data));
		$o_conn->ExpectArgumentsAt(4 , 'Execute', array(
									'select '.DATACACHE_DAOPGDB_SET_DATA.'(?, ?, ?, ?)'
									,array(TEST_DAOPGDB_APPL_ID, $data_id, 'N', $s_slashed_serial_data)
									));
		$o_conn->ExpectArgumentsAt(5, 'Execute'
							,array('select '.DATACACHE_DAOPGDB_CHK_DATA.'(?, ?)'
									,array(TEST_DAOPGDB_APPL_ID, $data_id)));
		$o_conn->ExpectArgumentsAt(6, 'Execute'
							,array('select '.DATACACHE_DAOPGDB_GET_DATA.'(?, ?)'
									,array(TEST_DAOPGDB_APPL_ID, $data_id)));
		
		$this->AssertTrue($o_test->SetCache($data_id, $data, false));
		$this->AssertIdentical($o_test->GetCache($data_id), $data);
		$o_conn->Tally();
	}

	/**
	 * test timestamp
	 *
	 * @return	void
	 */
	function TestTimeStamp() {
		$o_test =& $this->_moCache;
		$o_conn =& $this->_moConn;
		$id = 'time';
		$ts = mktime();
		
		$o_rs =& new MockADORecordSet($this);
		$o_conn->SetReturnReference('Execute', $o_rs);

		$o_rs->SetReturnValueAt(0, 'FetchRow', array(DATACACHE_DAOPGDB_SET_DATA => '1'));
		$this->AssertTrue($b_ret = $o_test->SetCache($id, $ts.$ts));

		$o_rs->SetReturnValueAt(1, 'FetchRow', array(DATACACHE_DAOPGDB_CHK_DATA => '1'));
		$o_rs->SetReturnValueAt(2, 'FetchRow', array(DATACACHE_DAOPGDB_GET_DATA_DATE => date('Y-m-d H:i:s', $ts)));
		$this->AssertNow($o_test->GetCacheTime($id));

		$o_rs->SetReturnValueAt(3, 'FetchRow', array(DATACACHE_DAOPGDB_CHK_DATA => '1'));
		$o_rs->SetReturnValueAt(4, 'FetchRow', array(DATACACHE_DAOPGDB_GET_DATA => 'Y'.$this->Zip($ts.$ts)));
		$this->AssertEqual($o_test->GetCache($id), $ts.$ts);
	}

	/**
	 * test removing cached data works
	 *
	 * @return	void
	 */
	function TestRemove()
	{
		$o_test =& $this->_moCache;
		$o_conn =& $this->_moConn;
		$data = TEST_APPLICATION.mktime();
		$id = 'to_be_removed';
		$o_rs =& new MockADORecordSet($this);
		$o_conn->SetReturnReference('Execute', $o_rs);
		
		$o_rs->SetReturnValueAt(0, 'FetchRow', array(DATACACHE_DAOPGDB_SET_DATA => '1'));
		$this->AssertTrue($o_test->SetCache($id, $data));
		
		$o_rs->SetReturnValueAt(1, 'FetchRow', array(DATACACHE_DAOPGDB_CHK_DATA => '1'));
		$o_rs->SetReturnValueAt(2, 'FetchRow', array(DATACACHE_DAOPGDB_GET_DATA => 'Y'.$this->Zip($data)));
		$this->AssertIdentical($data, $o_test->GetCache($id));

		$o_rs->SetReturnValueAt(3, 'FetchRow', array(DATACACHE_DAOPGDB_CHK_DATA => '1'));
		$o_rs->SetReturnValueAt(4, 'FetchRow', array(DATACACHE_DAOPGDB_DEL_DATA => '1'));
		$this->AssertTrue($o_test->RemoveCache($id));
		$r = $o_test->GetCache($id);
		$this->AssertError("Data Identified '$id' is not cached");
	}

	/**
	 * test removing cached data works
	 *
	 * @return	void
	 */
	function xTestRemovePattern()
	{
		$data = TEST_APPLICATION.mktime();
		$id1 = 'ato_be_removed';
		$id2 = 'bto_be_removed';
		$id3 = 'foobar';
		$this->AssertTrue($this->c->SetCache($id1.'1', $data.'1'));
		$this->AssertTrue($this->c->SetCache($id1.'2', $data.'2'));
		$this->AssertTrue($this->c->SetCache($id2.'1', $data.'1'));
		$this->AssertTrue($this->c->SetCache($id2.'2', $data.'2'));
		$this->AssertIdentical($data.'1', $this->c->GetCache($id1.'1'));
		$this->AssertIdentical($data.'2', $this->c->GetCache($id1.'2'));
		$this->AssertIdentical($data.'1', $this->c->GetCache($id2.'1'));
		$this->AssertIdentical($data.'2', $this->c->GetCache($id2.'2'));
		$this->AssertTrue($this->c->RemovePatternCache(substr($id1,0,3)));
		$r = $this->c->GetCache($id1.'1');
		$this->AssertError("identifier '{$id1}1' does not have a valid cache");
		$r = $this->c->GetCache($id1.'2');
		$this->AssertError("identifier '{$id1}2' does not have a valid cache");
		$this->AssertIdentical($data.'1', $this->c->GetCache($id2.'1'));
		$this->AssertIdentical($data.'2', $this->c->GetCache($id2.'2'));
		$this->AssertTrue($this->c->RemovePatternCache(substr($id2,0,5)));
		$r = $this->c->GetCache($id2.'1');
		$this->AssertError("identifier '{$id2}1' does not have a valid cache");
		$r = $this->c->GetCache($id2.'2');
		$this->AssertError("identifier '{$id2}2' does not have a valid cache");
		$this->AssertFalse($this->c->RemovePatternCache($id3));
		$this->AssertError("identifier pattern '$id3' does not have any valid cached data");
	}

	/**
	 * Check that a timestamp is within a small difference from now
	 *
	 * @param	timestamp	$ptsTest		the timestamp to test
	 * @param	integer		$piMaxSecDiff	optional, the number of seconds difference to allow
	 * @param	string		$psMsg			optional, message to use in failure condition
	 * @return	void
	 */
	function AssertNow($ptsTest, $piMaxSecDiff=1, $psMsg='%s')
	{
		$s_msg = sprintf($psMsg, "Within $piMaxSecDiff of now");
		$this->AssertTrue($piMaxSecDiff >= abs($ptsTest - mktime()), $s_msg);
	}
	
}


/**
 *
 * @package		DataCache
 * @subpackage	tests
 */
class TestDataCacheDaoPgDbIntegration extends UnitTestCase 
{
	/**
	 * @var	object	$_moCache	the data cache object
	 */
	var $_moCache;

	/**
	 * constructor
	 *
	 * @return	void
	 */
	function TestDataCacheDaoPgDbIntegration($psName='') {
		$this->UnitTestCase($psName);
	}
	
	/**
	 * initialization of test function
	 *
	 * @return	void
	 */
	function SetUp() {
		/**
		 *	ADOdb library
		 *	{@link http://php.weblogs.com/ADOdb php.weblogs.com/ADOdb}
		 */
		require_once DATACACHE_ADODB_LIB_PATH.'adodb.inc.php';
		
		$GLOBALS['ADODB_FETCH_MODE'] = ADODB_FETCH_ASSOC;
		
		$s_conn_funct = (DATACACHE_USE_PCONNECT) ? 'PConnect' : 'Connect';
		
		$this->_moConn =& NewADOConnection('postgres7');
		//$this->_moConn->debug = true;
		$this->_moConn->$s_conn_funct(	 DATACACHE_DB_HOST
										,DATACACHE_DB_USER
										,DATACACHE_DB_PASSWD
										,DATACACHE_DB_NAME
										);
		$this->_moCache =& new DataCacheDaoPgDb(TEST_APPLICATION, $this->_moConn);
	}
	
	/**
	 * test php environment is setup correctly
	 *
	 * @return	void
	 */
	function TestInstanciate() {
		$this->AssertNoErrors();
	}
	
	/**
	 * test when data not already cached
	 *
	 * @return	void
	 */
	function TestEmptyCache() {
		$this->AssertFalse($this->_moCache->IsCached(TEST_DAOPGDB_BLANK));
	}
	
	/**
	 * test caching different types
	 *
	 * @return	void
	 */
	function TestCache() {
		$data_id = 'data';
		$data = array(
			 'str1'		=> 'a simple string'
			,'str2'		=> "a multi-\nline string"
			,'str3'		=> 'a "double quote" string'
			,'str4' 	=> "a 'single quote' string"
			,'str5' 	=> TEST_DAOPGDB_STRING
			,'int'		=> mktime()
			,'array'	=> array('one', 'two', 'three')
			,'object'	=> new ObjectTest
			);
		$o_test =& $this->_moCache;
		$this->AssertTrue($o_test->SetCache($data_id, $data));
		$this->AssertIdentical($o_test->GetCache($data_id), $data);
		
		$this->AssertTrue($o_test->SetCache($data_id, $data, false));
		$this->AssertIdentical($o_test->GetCache($data_id), $data);
	}

	/**
	 * test timestamp
	 *
	 * @return	void
	 */
	function TestTimeStamp() {
		$o_test =& $this->_moCache;
		$id = 'time';
		$ts = mktime();
		
		$this->AssertTrue($b_ret = $o_test->SetCache($id, $ts.$ts), 'Sucessfully Cached Data');
		$this->AssertNow($o_test->GetCacheTime($id));
		$this->AssertEqual($o_test->GetCache($id), $ts.$ts);
	}

	/**
	 * test removing cached data works
	 *
	 * @return	void
	 */
	function TestRemove()
	{
		$o_test =& $this->_moCache;
		$data = TEST_APPLICATION.mktime();
		$id = 'to_be_removed';

		$this->AssertTrue($o_test->SetCache($id, $data));
		$this->AssertIdentical($data, $o_test->GetCache($id));
		$this->AssertTrue($o_test->RemoveCache($id));
		$r = $o_test->GetCache($id);
		$this->AssertError("Data Identified '$id' is not cached");
	}

	/**
	 * test a large chunk of data being cached
	 * @return	void
	 */
	function TestBigData()
	{
		ob_start();
		phpinfo();
		$s = addslashes(htmlspecialchars(ob_get_contents()));
		ob_end_clean();
		
		$o_test =& $this->_moCache;
		$s_big = $s.$s.$s.$s.$s.$s.$s.$s.$s.$s.$s;
		$a_data = array('value' => $s_big, 'len' => strlen($s_big));
		$id = 'bigdata';
		
		$this->AssertTrue(500000 < strlen($s_big));
		$this->AssertTrue($o_test->SetCache($id, $a_data));
		$this->AssertEqual($a_data, $o_test->GetCache($id));
		$this->AssertTrue($o_test->RemoveCache($id));
	}
	

	/**
	 * test removing cached data works
	 *
	 * @return	void
	 */
	function xTestRemovePattern()
	{
		$data = TEST_APPLICATION.mktime();
		$id1 = 'ato_be_removed';
		$id2 = 'bto_be_removed';
		$id3 = 'foobar';
		$this->AssertTrue($this->c->SetCache($id1.'1', $data.'1'));
		$this->AssertTrue($this->c->SetCache($id1.'2', $data.'2'));
		$this->AssertTrue($this->c->SetCache($id2.'1', $data.'1'));
		$this->AssertTrue($this->c->SetCache($id2.'2', $data.'2'));
		$this->AssertIdentical($data.'1', $this->c->GetCache($id1.'1'));
		$this->AssertIdentical($data.'2', $this->c->GetCache($id1.'2'));
		$this->AssertIdentical($data.'1', $this->c->GetCache($id2.'1'));
		$this->AssertIdentical($data.'2', $this->c->GetCache($id2.'2'));
		$this->AssertTrue($this->c->RemovePatternCache(substr($id1,0,3)));
		$r = $this->c->GetCache($id1.'1');
		$this->AssertError("identifier '{$id1}1' does not have a valid cache");
		$r = $this->c->GetCache($id1.'2');
		$this->AssertError("identifier '{$id1}2' does not have a valid cache");
		$this->AssertIdentical($data.'1', $this->c->GetCache($id2.'1'));
		$this->AssertIdentical($data.'2', $this->c->GetCache($id2.'2'));
		$this->AssertTrue($this->c->RemovePatternCache(substr($id2,0,5)));
		$r = $this->c->GetCache($id2.'1');
		$this->AssertError("identifier '{$id2}1' does not have a valid cache");
		$r = $this->c->GetCache($id2.'2');
		$this->AssertError("identifier '{$id2}2' does not have a valid cache");
		$this->AssertFalse($this->c->RemovePatternCache($id3));
		$this->AssertError("identifier pattern '$id3' does not have any valid cached data");
	}

	
	/**
	 * Check that a timestamp is within a small difference from now
	 *
	 * @param	timestamp	$ptsTest		the timestamp to test
	 * @param	integer		$piMaxSecDiff	optional, the number of seconds difference to allow
	 * @param	string		$psMsg			optional, message to use in failure condition
	 * @return	void
	 */
	function AssertNow($ptsTest, $piMaxSecDiff=1, $psMsg='%s')
	{
		$s_msg = sprintf($psMsg, "Within $piMaxSecDiff of now");
		$this->AssertTrue($piMaxSecDiff >= abs($ptsTest - mktime()), $s_msg);
	}
}


/**
 * A test object for caching
 * @package		DataCache
 * @subpackage	tests
 */ 
class ObjectTest
{
	function ObjectTest() {
		$this->val=mktime();
	}
}



//run if stand alone
if (!isset($this)) {
	$test =& new GroupTest('DataCache Postgres DAO Tests');
	$test->AddTestCase(new TestDataCacheDaoPgDb);
	$test->AddTestCase(new TestDataCacheDaoPgDbIntegration);
	$test->Run(new HtmlReporter());
}

/* vim: set tabstop=4: */
#?>
Return current item: PHP DataCache