Skip to content
This repository has been archived by the owner on Apr 5, 2020. It is now read-only.

Commit

Permalink
- Create reusable unittest action "StartServer" for FTP and remote in…
Browse files Browse the repository at this point in the history
…tegration tests

# See  xp-framework/rfc#272
  • Loading branch information
thekid committed Oct 19, 2013
1 parent 54faece commit 7736288
Show file tree
Hide file tree
Showing 4 changed files with 130 additions and 161 deletions.
85 changes: 85 additions & 0 deletions core/src/test/php/net/xp_framework/unittest/StartServer.class.php
@@ -0,0 +1,85 @@
<?php namespace net\xp_framework\unittest;

use lang\Runtime;
use lang\IllegalStateException;

/**
* Starts a server for integration tests
*/
class StartServer extends \lang\Object implements \unittest\TestClassAction {
protected $serverProcess;
protected $mainClass;
protected $connected;
protected $shutdown;

/**
* Constructor
*
* @param string $mainClass Server process main class
* @param string $connected Name of method to invoke once connected
* @param string $shutdown Name of method to invoke to shut down
* @param string[] $arguments Arguments to server process
*/
public function __construct($mainClass, $connected, $shutdown, $arguments= array()) {
$this->mainClass= $mainClass;
$this->connected= $connected;
$this->shutdown= $shutdown;
$this->arguments= $arguments;
}

/**
* Starts server
*
* @param lang.XPClass $c
* @return void
* @throws unittest.PrerequisitesNotMetError
*/
public function beforeTestClass(\lang\XPClass $c) {

// Start server process
$this->serverProcess= Runtime::getInstance()->newInstance(null, 'class', $this->mainClass, $this->arguments);
$this->serverProcess->in->close();

// Check if startup succeeded
$status= $this->serverProcess->out->readLine();
if (1 != sscanf($status, '+ Service %[0-9.:]', $bindAddress)) {
try {
$this->afterTestClass($c);
} catch (IllegalStateException $e) {
$status.= $e->getMessage();
}
throw new \unittest\PrerequisitesNotMetError('Cannot start server: '.$status, null);
}

$c->getMethod($this->connected)->invoke(null, array($bindAddress));
}

/**
* Shuts down server
*
* @param lang.XPClass $c
* @return void
*/
public function afterTestClass(\lang\XPClass $c) {

// Tell the server to shut down
try {
$c->getMethod($this->shutdown)->invoke(null, array());
} catch (\lang\Throwable $ignored) {
// Fall through, below should terminate the process anyway
}

$status= $this->serverProcess->out->readLine();
if (!strlen($status) || '+' != $status{0}) {
while ($l= $this->serverProcess->out->readLine()) {
$status.= $l;
}
while ($l= $this->serverProcess->err->readLine()) {
$status.= $l;
}
$this->serverProcess->close();
throw new IllegalStateException($status);
}
$this->serverProcess->close();
}
}
@@ -1,5 +1,6 @@
<?php namespace net\xp_framework\unittest\peer\ftp;

use net\xp_framework\unittest\StartServer;
use unittest\TestCase;
use io\streams\MemoryInputStream;
use io\streams\MemoryOutputStream;
Expand All @@ -13,131 +14,65 @@
*
* @see xp://peer.ftp.FtpConnection
*/
#[@action(new StartServer('net.xp_framework.unittest.peer.ftp.TestingServer', 'connected', 'shutdown'))]
class IntegrationTest extends TestCase {
protected static
$serverProcess = null,
$bindAddress = null;

protected
$conn = null;
public static $bindAddress= null;
protected $conn= null;

/**
* Sets up test case
* Callback for when server is connected
*
* @param string $bindAddress
*/
#[@beforeClass]
public static function startFtpServer() {

// Arguments to server process
$args= array(
'debugServerProtocolToFile' => null,
);

// Start server process
self::$serverProcess= Runtime::getInstance()->newInstance(
null,
'class',
'net.xp_framework.unittest.peer.ftp.TestingServer',
array_values($args)
);
self::$serverProcess->in->close();

// Check if startup succeeded
$status= self::$serverProcess->out->readLine();
if (1 != sscanf($status, '+ Service %[0-9.:]', self::$bindAddress)) {
try {
self::shutdownFtpServer();
} catch (\lang\IllegalStateException $e) {
$status.= $e->getMessage();
}
throw new \unittest\PrerequisitesNotMetError('Cannot start FTP server: '.$status, null);
}
public static function connected($bindAddress) {
self::$bindAddress= $bindAddress;
}

/**
* Shut down FTP server
*
* Callback for when server should be shut down
*/
#[@afterClass]
public static function shutdownFtpServer() {

// Tell the FTP server to shut down
try {
$c= new FtpConnection('ftp://test:test@'.self::$bindAddress);
$c->connect();
$c->sendCommand('SHUTDOWN');
$c->close();
} catch (\lang\Throwable $ignored) {
// Fall through, below should terminate the process anyway
}

$status= self::$serverProcess->out->readLine();
if (!strlen($status) || '+' != $status{0}) {
while ($l= self::$serverProcess->out->readLine()) {
$status.= $l;
}
while ($l= self::$serverProcess->err->readLine()) {
$status.= $l;
}
self::$serverProcess->close();
throw new \lang\IllegalStateException($status);
}
self::$serverProcess->close();
public static function shutdown() {
$c= new FtpConnection('ftp://test:test@'.self::$bindAddress);
$c->connect();
$c->sendCommand('SHUTDOWN');
$c->close();
}

/**
* Sets up test case
*
*/
public function setUp() {
$this->conn= new FtpConnection('ftp://test:test@'.self::$bindAddress.'?passive=1&timeout=1');
}

/**
* Sets up test case
*
* Tears down test case
*/
public function tearDown() {
$this->conn->close();
}

/**
* Test connecting and logging in
*
*/
#[@test]
public function connect() {
$this->conn->connect();
}

/**
* Test connecting and logging in with incorrect credentials
*
*/
#[@test, @expect('peer.AuthenticationException')]
public function incorrectCredentials() {
public function incorrect_credentials() {
create(new FtpConnection('ftp://test:INCORRECT@'.self::$bindAddress.'?timeout=1'))->connect();
}

/**
* Test retrieving root directory
*
*/
#[@test]
public function rootDir() {
public function retrieve_root_dir() {
$this->conn->connect();
with ($root= $this->conn->rootDir()); {
$this->assertClass($root, 'peer.ftp.FtpDir');
$this->assertEquals('/', $root->getName());
}
}

/**
* Test retrieving root directory's contents
*
*/
#[@test]
public function entries() {
public function retrieve_root_dir_entries() {
$this->conn->connect();
$entries= $this->conn->rootDir()->entries();
$this->assertClass($entries, 'peer.ftp.FtpEntryList');
Expand Down

0 comments on commit 7736288

Please sign in to comment.