| 
<?php
 /**
 * this is a synchronized incrementation test,
 * you can launch           ==>    N NUMBER_OF_THREAD
 * each thread will iterate ==>    M TOTAL_ITERATION
 * also, for each launched THREAD, you can configure the    ==> MAX_ATTEMPT
 *                                                          ==> DELAY_ATTEMPT (µs)
 * you can also configure the TOLERANCE_TO_LOSS
 * 2 clients trying to increment 1000 times a shared synchronized resource,
 * a client can consume all his attempts without getting a lock for this resource
 * so, this resouce will not be incremented.
 * TOLERANCE_TO_LOSS represents this incrementation loss
 */
 
 set_time_limit  (0) ;
 ini_set         ('memory_limit', '256M');
 
 require_once (__DIR__ . '/../../ANYEM_SHARED/' . 'anyem.resource.impl/ResourceIdentifierImpl.php')  ;
 require_once (__DIR__ . '/../../ANYEM_SHARED/' . 'anyem.resource.impl/ResponseWrapperImpl.php')     ;
 
 require_once (__DIR__ . '/../anyem.client.impl/ClientConnectionImpl.php');
 
 define ("TOTAL_ITERATION",      100);
 define ("NUMBER_OF_THREAD",     20);
 define ("MAX_ATTEMPT",          35);
 define ("DELAY_ATTEMPT",        100000); # == (1/10) s
 define ("TOLERANCE_TO_LOSS",    15);
 
 /**
 *
 * @author Anis.Halayem
 */
 class AnyemClientMultiThreadTest extends PHPUnit_Framework_TestCase {
 
 public function setUp() {}
 
 public function testGetPutMultiThread() {
 $startAnyemTest = new AnyemMTForPHPUnit();
 $startAnyemTest->start();
 $startAnyemTest->join();
 
 $var_pattern_s = 'anyemMultiThreading_';
 for ($i=0 ; $i<NUMBER_OF_THREAD ; $i++) {
 $newVar     = $var_pattern_s + $i;
 ${$newVar}  = new AnyemMT();
 ${$newVar}->start();
 
 }
 for ($i=0 ; $i<NUMBER_OF_THREAD ; $i++) {
 $newVar     = $var_pattern_s + $i;
 ${$newVar}->join();
 }
 
 $endAnyemTest = new AnyemMTForPHPUnit();
 $endAnyemTest->start();
 $endAnyemTest->join();
 
 $expectedValue  = (TOTAL_ITERATION * NUMBER_OF_THREAD) + $startAnyemTest->value;
 $actualValue    = $endAnyemTest->value;
 $this->assertLessThanOrEqual(
 TOLERANCE_TO_LOSS,
 $expectedValue - $actualValue
 );
 }
 }
 
 class AnyemMTForPHPUnit extends Thread {
 private static $_clientConnection   = NULL;
 private static $_identifier         = NULL;
 private static $_initialized        = FALSE;
 
 public $value                       = NULL;
 
 private static function init() {
 if (self::$_initialized === TRUE) {
 return;
 }
 self::$_clientConnection    = ClientConnectionImpl::newClient();
 self::$_identifier          = new ResourceIdentifierImpl("anyem.com", "anyemNameSpace", "a");
 self::$_initialized         = TRUE;
 }
 
 
 public function run() {
 self::init();
 require_once (__DIR__ . '/../anyem.client.impl/AnyemClientImpl.php');
 $anyemClient        = new AnyemClientImpl(self::$_clientConnection, self::$_identifier);
 $responseWrapper    = $anyemClient->read();
 $resourceImpl       = $responseWrapper->getResource();
 if (!is_null($resourceImpl)) {
 $value          = $responseWrapper->getResource()->getData();
 }
 else {
 $value          = 0;
 }
 $this->value        = $value;
 }
 }
 
 class AnyemMT extends Thread {
 private static $_clientConnection   = NULL;
 private static $_identifier         = NULL;
 private static $_initialized        = FALSE;
 
 private static function init() {
 if (self::$_initialized === TRUE) {
 return;
 }
 self::$_clientConnection    = ClientConnectionImpl::newClient();
 self::$_identifier          = new ResourceIdentifierImpl("anyem.com", "anyemNameSpace", "a");
 self::$_initialized         = TRUE;
 }
 
 
 public function run() {
 self::init();
 require_once (__DIR__ . '/../anyem.client.impl/AnyemClientImpl.php');
 $anyemClient = new AnyemClientImpl(self::$_clientConnection, self::$_identifier);
 
 $a = 0;
 for ($i=0 ; $i<TOTAL_ITERATION ; $i++) {
 try {
 $responseWrapper = $anyemClient->get($a, MAX_ATTEMPT, DELAY_ATTEMPT);
 }
 catch (Exception $e) {
 print $e->getMessage() . "\n";
 continue;
 }
 
 $a = $responseWrapper->getResource()->getData();
 $anyemClient->put(++$a);
 }
 }
 }
 |