<?php
/**
* Tests for the client pool.
*
* @copyright 2013 Perforce Software. All rights reserved.
* @license Please see LICENSE.txt in top-level folder of this distribution.
* @version <release>/<patch>
*/
namespace P4Test\ClientPool;
use P4\Spec\Depot;
use P4Test\TestCase;
use P4\Spec\Client;
use P4\ClientPool\ClientPool;
class ClientPoolTest extends TestCase
{
public function testBasicFunction()
{
new ClientPool;
}
public function testBasicGet()
{
$clients = new ClientPool($this->p4);
$clients->setMax(3)->setRoot(DATA_PATH . '/clients');
// get a client and verify re-requesting gives the same one
$id1 = $clients->grab();
$this->assertSame(
$id1,
$clients->grab(),
'expected to get the same client on two requests'
);
}
public function testViewCreation()
{
$clients = new ClientPool($this->p4);
$clients->setMax(3)->setRoot(DATA_PATH . '/clients');
// get a client and verify re-requesting gives the same one
$id1 = $clients->grab();
$this->assertSame(
array(
array(
'depot' => '//depot/...',
'client' => '//' . $id1 . '/depot/...'
)
),
Client::fetch($id1, $this->p4)->get('View'),
'expected matching view'
);
}
/**
* @expectedException \P4\ClientPool\Exception
*/
public function testNoFolderPermissions()
{
// ensure the clients folder exists and we lack write access to it
$path = DATA_PATH . '/clients';
mkdir($path);
chmod($path, 0100);
$this->assertSame(array(), glob($path . '/*'));
$clients = new ClientPool($this->p4);
$clients->setMax(3)->setRoot(DATA_PATH . '/clients');
// expect the blocking grab to toss our expected exception
$clients->grab();
}
/**
* @expectedException \P4\ClientPool\Exception
*/
public function testNoFilePermissions()
{
// ensure the clients folder exists and we lack write access to the lock files
$path = DATA_PATH . '/clients';
mkdir($path);
touch($path . '/00000000-0000-0000-0000-000000000001' . ClientPool::LOCK_EXTENSION);
chmod($path . '/00000000-0000-0000-0000-000000000001' . ClientPool::LOCK_EXTENSION, 0100);
touch($path . '/00000000-0000-0000-0000-000000000002' . ClientPool::LOCK_EXTENSION);
chmod($path . '/00000000-0000-0000-0000-000000000002' . ClientPool::LOCK_EXTENSION, 0100);
touch($path . '/00000000-0000-0000-0000-000000000003' . ClientPool::LOCK_EXTENSION);
chmod($path . '/00000000-0000-0000-0000-000000000003' . ClientPool::LOCK_EXTENSION, 0100);
// test a single file to verify we indeed cannot open it
$this->assertTrue(
@fopen($path . '/00000000-0000-0000-0000-000000000001' . ClientPool::LOCK_EXTENSION, 'c') === false
);
// setup the client pool to test blocking and non-blocking grab
$clients = new ClientPool($this->p4);
$clients->setMax(3)->setRoot(DATA_PATH . '/clients');
// expect the blocking grab to toss our expected exception
$clients->grab();
}
public function testGettingMax()
{
$clients = new ClientPool($this->p4);
$clients->setMax(3)->setRoot(DATA_PATH . '/clients');
// get a client and verify re-requesting gives the same one
$id1 = $clients->grab();
$this->assertSame(
$id1,
$clients->grab(),
'expected to get the same client on two requests'
);
// get another client by passing reuse=false
$id2 = $clients->grab(false);
$this->assertFalse(
$id1 == $id2,
'expected different id for client 2! ' . $id2
);
$id3 = $clients->grab(false);
$this->assertFalse(
$id1 == $id3 || $id2 == $id3,
'expected different id for client 3! ' . $id3
);
$this->assertSame(
false,
$clients->grab(false, false),
'Expected false on non blocking request for client 4'
);
$this->assertSame(
$id1,
$clients->grab(),
'Expected first client to be returned when several available and re-using'
);
}
public function testTwoCopies()
{
$clients1 = new ClientPool($this->p4);
$clients1->setMax(3)->setPrefix('test-')->setRoot(DATA_PATH . '/clients');
$clients2 = new ClientPool($this->p4);
$clients2->setMax(3)->setPrefix('test-')->setRoot(DATA_PATH . '/clients');
$id1 = $clients1->grab();
$id2 = $clients2->grab();
$this->assertTrue(
strpos($id1, $clients1->getPrefix()) === 0,
'expected valid looking id1'
);
$this->assertTrue(
strpos($id2, $clients2->getPrefix()) === 0,
'expected valid looking id2'
);
$this->assertTrue(
$id1 != $id2,
'expected two different ids'
);
}
public function testRelease()
{
$clients1 = new ClientPool($this->p4);
$clients1->setMax(3)->setPrefix('test-')->setRoot(DATA_PATH . '/clients');
$clients2 = new ClientPool($this->p4);
$clients2->setMax(3)->setPrefix('test-')->setRoot(DATA_PATH . '/clients');
$id1 = $clients1->grab();
$id2 = $clients2->grab();
$this->assertTrue(
strpos($id1, $clients1->getPrefix()) === 0,
'expected valid looking id1'
);
$this->assertTrue(
strpos($id2, $clients2->getPrefix()) === 0,
'expected valid looking id2'
);
$this->assertTrue(
$id1 != $id2,
'expected two different ids'
);
$clients2->release();
$this->assertSame(
$id2,
$clients1->grab(false),
'expected id2 to be freed up for ClientPool1 to get'
);
}
public function testSimpleHistory()
{
$clients = new ClientPool($this->p4);
$clients->setMax(3)->setPrefix('test-')->setRoot(DATA_PATH . '/clients');
$starting = $this->p4->getClient($this->p4);
$clients->grab();
$this->assertFalse($starting == $this->p4->getClient(), 'expected client to change');
$this->assertTrue(strpos($this->p4->getClient(), 'test-') == 0, 'expected test prefix');
$clients->release();
$this->assertSame($starting, $this->p4->getClient(), 'expected original client to be restored');
}
public function testDeeperHistory()
{
$clients = new ClientPool($this->p4);
$clients->setMax(3)->setPrefix('test-')->setRoot(DATA_PATH . '/clients');
$starting = $this->p4->getClient($this->p4);
$clients->grab();
$this->assertFalse($starting == $this->p4->getClient($this->p4), 'expected client to change');
$this->assertTrue(strpos($this->p4->getClient(), 'test-') == 0, 'expected test prefix');
$grab1 = $this->p4->getClient();
$clients->grab(false);
$this->assertFalse($grab1 == $this->p4->getClient(), 'expected client to change2');
$this->assertTrue(strpos($this->p4->getClient(), 'test-') == 0, 'expected test prefix2');
$grab2 = $this->p4->getClient();
$clients->grab(false);
$this->assertFalse($grab2 == $this->p4->getClient(), 'expected client to change3');
$this->assertTrue(strpos($this->p4->getClient(), 'test-') == 0, 'expected test prefix3');
$clients->release();
$this->assertSame($grab2, $this->p4->getClient(), 'expected original grab2 to be restored');
$clients->release();
$this->assertSame($grab1, $this->p4->getClient(), 'expected original grab1 to be restored');
$clients->release();
$this->assertSame($starting, $this->p4->getClient(), 'expected original to be restored');
}
public function testStreamReset()
{
// create a stream depot and stream //stream/main
$depot = $this->p4->run('depot', array('-o', 'stream'))->getData(-1);
$this->p4->run('depot', '-i', array('Type' => 'stream') + $depot);
$stream = array('Type' => 'mainline') + $this->p4->run('stream', array('-o', '//stream/main'))->getData(-1);
$this->p4->run('stream', '-i', $stream)->getData(-1);
$this->p4->disconnect(); // required for 2010.2 p4d to pick up the new depot
$clients = new ClientPool($this->p4);
$clients->setMax(3)->setPrefix('test-')->setRoot(DATA_PATH . '/clients');
$id = $clients->grab();
$clients->reset(true, '//stream/main');
$this->assertSame(
'//stream/main',
Client::fetch($id, $this->p4)->get('Stream')
);
}
/**
* @expectedException \P4\Connection\Exception\CommandException
*/
public function testBadDepotStreamReset()
{
$clients = new ClientPool($this->p4);
$clients->setMax(3)->setPrefix('test-')->setRoot(DATA_PATH . '/clients');
$clients->grab();
$clients->reset(true, '//madeup/madeup');
}
/**
* @expectedException \P4\Connection\Exception\CommandException
*/
public function testBadStreamReset()
{
$depot = $this->p4->run('depot', array('-o', 'stream'))->getData(-1);
$this->p4->run('depot', '-i', array('Type' => 'stream') + $depot);
$clients = new ClientPool($this->p4);
$clients->setMax(3)->setPrefix('test-')->setRoot(DATA_PATH . '/clients');
$clients->grab();
$clients->reset(true, '//stream/madeup');
}
}