mirror of
https://github.com/silverstripe/silverstripe-testsession
synced 2024-10-22 14:06:00 +02:00
Merge pull request #58 from open-sausages/pulls/2.2/pending-requests-awaited
ADD / TestSessionState initial implementation
This commit is contained in:
commit
fc0f7baa11
@ -20,6 +20,11 @@ is a random token stored in the browser session, in order to make the
|
||||
test session specific to the executing browser, and allow multiple
|
||||
people using their own test session in the same webroot.
|
||||
|
||||
The module also keeps some metadata about the session state in the database,
|
||||
so that it may be available for the clients as well.
|
||||
E.g. the silverstripe-behat-extension may use it through this module APIs,
|
||||
allowing us to introduce some grey-box testing techniques.
|
||||
|
||||
The module also serves as an initializer for the
|
||||
[SilverStripe Behat Extension](https://github.com/silverstripe-labs/silverstripe-behat-extension/).
|
||||
It is required for Behat because the Behat CLI test runner needs to persist
|
||||
|
@ -335,6 +335,8 @@ class TestSessionEnvironment
|
||||
// Connect to the new database, overwriting the old DB connection (if any)
|
||||
DB::connect($databaseConfig);
|
||||
}
|
||||
|
||||
TestSessionState::create()->write(); // initialize the session state
|
||||
}
|
||||
|
||||
// Mailer
|
||||
@ -363,6 +365,7 @@ class TestSessionEnvironment
|
||||
}
|
||||
|
||||
$this->saveState($state);
|
||||
|
||||
$this->extend('onAfterApplyState');
|
||||
}
|
||||
|
||||
@ -558,4 +561,38 @@ class TestSessionEnvironment
|
||||
{
|
||||
return PUBLIC_PATH . DIRECTORY_SEPARATOR . 'assets_backup';
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Wait for pending requests
|
||||
*
|
||||
* @param int $await Time to wait (in ms) after the last response (to allow the browser react)
|
||||
* @param int $timeout For how long (in ms) do we wait before giving up
|
||||
*
|
||||
* @return bool Whether there are no more pending requests
|
||||
*/
|
||||
public function waitForPendingRequests($await = 700, $timeout = 10000)
|
||||
{
|
||||
$now = static function () {
|
||||
return microtime(true) * 10000;
|
||||
};
|
||||
|
||||
$timeout = $now() + $timeout;
|
||||
$interval = max(300, $await);
|
||||
do {
|
||||
$model = TestSessionState::get()->byID(1);
|
||||
|
||||
$pendingRequests = $model->PendingRequests > 0;
|
||||
$lastRequestAwait = ($model->LastResponseTimestamp + $await) > $now();
|
||||
|
||||
$pending = $pendingRequests || $lastRequestAwait;
|
||||
|
||||
if ($timeout < $now()) {
|
||||
// timed out
|
||||
return false;
|
||||
}
|
||||
} while ($pending && (usleep($interval * 1000) || true));
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -39,12 +39,14 @@ class TestSessionHTTPMiddleware implements HTTPMiddleware
|
||||
|
||||
// Load test state
|
||||
$this->loadTestState($request);
|
||||
TestSessionState::incrementState();
|
||||
|
||||
// Call with safe teardown
|
||||
try {
|
||||
return $delegate($request);
|
||||
} finally {
|
||||
$this->restoreTestState($request);
|
||||
TestSessionState::decrementState();
|
||||
}
|
||||
}
|
||||
|
||||
|
60
src/TestSessionState.php
Normal file
60
src/TestSessionState.php
Normal file
@ -0,0 +1,60 @@
|
||||
<?php
|
||||
|
||||
namespace SilverStripe\TestSession;
|
||||
|
||||
use SilverStripe\ORM\DataObject;
|
||||
use SilverStripe\ORM\Queries\SQLUpdate;
|
||||
|
||||
/**
|
||||
* The session state keeps some metadata about the current test session.
|
||||
* This may allow the client (Behat) to get some insight into the
|
||||
* server side affairs (e.g. if the server is handling some number requests at the moment).
|
||||
*
|
||||
* The client side (Behat) must not use this class straightforwardly, but rather
|
||||
* rely on the API of {@see TestSessionEnvironment} or {@see TestSessionController}.
|
||||
*
|
||||
* @property int PendingRequests keeps information about how many requests are in progress
|
||||
* @property float LastResponseTimestamp microtime of the last response made by the server
|
||||
*/
|
||||
class TestSessionState extends DataObject
|
||||
{
|
||||
private static $table_name = 'TestSessionState';
|
||||
|
||||
private static $db = [
|
||||
'PendingRequests' => 'Int',
|
||||
'LastResponseTimestamp' => 'Decimal(14, 0)'
|
||||
];
|
||||
|
||||
/**
|
||||
* Increments TestSessionState.PendingRequests number by 1
|
||||
* to indicate we have one more request in progress
|
||||
*/
|
||||
public static function incrementState()
|
||||
{
|
||||
$schema = DataObject::getSchema();
|
||||
|
||||
$update = SQLUpdate::create(sprintf('"%s"', $schema->tableName(self::class)))
|
||||
->addWhere(['ID' => 1])
|
||||
->assignSQL('"PendingRequests"', '"PendingRequests" + 1');
|
||||
|
||||
$update->execute();
|
||||
}
|
||||
|
||||
/**
|
||||
* Decrements TestSessionState.PendingRequests number by 1
|
||||
* to indicate we have one more request in progress.
|
||||
* Also updates TestSessionState.LastResponseTimestamp
|
||||
* to the current timestamp.
|
||||
*/
|
||||
public static function decrementState()
|
||||
{
|
||||
$schema = DataObject::getSchema();
|
||||
|
||||
$update = SQLUpdate::create(sprintf('"%s"', $schema->tableName(self::class)))
|
||||
->addWhere(['ID' => 1])
|
||||
->assignSQL('"PendingRequests"', '"PendingRequests" - 1')
|
||||
->assign('"LastResponseTimestamp"', microtime(true) * 10000);
|
||||
|
||||
$update->execute();
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user