Skip to content

Commit

Permalink
protocol version, VALUE status, _value suffix, tests for set-meta, li…
Browse files Browse the repository at this point in the history
…st-meta

git-svn-id: https://svn.toolserver.org/svnroot/daniel/duesenstuff/trunk/gpClient@566 9f2c43bc-b3c0-43f4-b155-41619b16f219
  • Loading branch information
Daniel Kinzler committed Jan 3, 2012
1 parent 0920fe3 commit 1232411
Show file tree
Hide file tree
Showing 2 changed files with 134 additions and 19 deletions.
86 changes: 68 additions & 18 deletions php/gpClient.php
Original file line number Diff line number Diff line change
Expand Up @@ -57,10 +57,23 @@
define( 'GP_PORT', 6666 );

/**
* Expected GraphServ protocol version. If GraphServ (resp GraphCore)
* reports a different protocol version, the conenction is aborted.
* Implemented GraphServ protocol version. This indicates what features the
* client library supports. It is not validated against the peer's protocol version,
* see GP_MIN_PROTOCOL_VERSION and GP_MAX_PROTOCOL_VERSION for that.
*/
define( 'GP_CLIENT_PROTOCOL_VERSION', 3 );
define( 'GP_CLIENT_PROTOCOL_VERSION', 4 ); #TODO: port min/max logic to python

/**
* Lowest acceptable GraphServ protocol version. If GraphServ (resp GraphCore)
* reports a lower protocol version, the conenction is aborted.
*/
define( 'GP_MIN_PROTOCOL_VERSION', 2.0 ); #TODO: port min/max logic to python

/**
* Highest acceptable GraphServ protocol version. If GraphServ (resp GraphCore)
* reports a higher protocol version, the conenction is aborted.
*/
define( 'GP_MAX_PROTOCOL_VERSION', 4.99 ); #TODO: port min/max logic to python

/**
* Base class for gpClient exceptions.
Expand Down Expand Up @@ -981,6 +994,11 @@ public function checkPeer() {
* a key-value pairs. If the _map suffix is used without the capture_ prefix,
* a gpUsageException is raised.
*
* * if the method name is suffixed with _value, the command is expected
* to return a value in the status line, prefixed by either "OK." or "VALUE:".
* The value is returned. If the command does not provide a VALUE or OK status,
* an exception is raised.
*
* Modifiers can also be combined. For instance, try_capture_stats_map would
* return GraphCore stats as an associative array, or null of the call failed.
*
Expand Down Expand Up @@ -1095,7 +1113,7 @@ public function connect() {
*
* * $connection this gpConnection instance
* * &$cmd a reference to the command name, as a string, with the try_,
* capture_ and _map modifiers removed.
* capture_, _map or _value modifiers removed.
* * &$args a reference to the argument array, unprocessed, as passed to
* the method.
* * &$source a reference to a gpDatSource (or null), may be altered to
Expand Down Expand Up @@ -1211,18 +1229,28 @@ public function setDebug($debug) {
* Returns the protocol version reported by the peer.
*/
public function getProtocolVersion() {
$this->protocol_version();
$version = trim($this->statusMessage);
return $version;
if ( empty($this->protocol_version) ) { #TODO: port lazy init to python!
$this->protocol_version();
$this->protocol_version = trim($this->statusMessage);
}

return $this->protocol_version;
}

/**
* Raises a gpProtocolException if the protocol version reported by the peer is
* not compatible with GP_CLIENT_PROTOCOL_VERSION.
*/
public function checkProtocolVersion() {
$version = $this->getProtocolVersion();
if ( $version != GP_CLIENT_PROTOCOL_VERSION ) throw new gpProtocolException( "Bad protocol version: expected " . GP_CLIENT_PROTOCOL_VERSION . ", but peer uses " . $version );
$version = (float)$this->getProtocolVersion();

if ( $version < GP_MIN_PROTOCOL_VERSION ) { #TODO: port min/max to python
throw new gpProtocolException( "Bad protocol version: expected at least " . GP_MIN_PROTOCOL_VERSION . ", but peer uses " . $version );
}

if ( $version > GP_MAX_PROTOCOL_VERSION ) { #TODO: port min/max to python
throw new gpProtocolException( "Bad protocol version: expected at most " . GP_MAX_PROTOCOL_VERSION . ", but peer uses " . $version );
}
}

/**
Expand Down Expand Up @@ -1273,6 +1301,15 @@ public function __call($name, $arguments) {
$map = false;
}

if ( preg_match( '/-value$/', $cmd ) ) { #TODO: port to python
if ($capture) throw new gpUsageException( "using the _value suffix together with the capture_ prefix is meaningless" );

$cmd = substr( $cmd, 0, strlen($cmd) -6 );
$val = true;
} else {
$val = false;
}

$result = null;
foreach ( $this->call_handlers as $handler ) {
$continue = call_user_func_array( $handler, array( $this, &$cmd, &$arguments, &$source, &$sink, &$capture, &$result ) );
Expand Down Expand Up @@ -1328,9 +1365,9 @@ public function __call($name, $arguments) {
else return false;
}

//note: call modifiers like capture change the return type!
//note: call modifiers like "_capture" change the return type!
if ( $capture ) {
if ( $status == 'OK' ) {
if ( $status == 'OK' || $status == 'VALUE' ) { #TODO: port VALUE to python
if ( $has_output ) {
if ($map) return $sink->getMap();
else return $sink->getData();
Expand All @@ -1341,8 +1378,17 @@ public function __call($name, $arguments) {
else if ( $status == 'NONE' ) return null;
else return false;
} else {
if ( $result ) return $result; // from handler
else return $status;
if ( $result ) $status = $result; // from handler

if ( $val ) { #TODO: port to python!
if ( $status == "VALUE" || $status == "OK" ) {
return $this->statusMessage; #XXX: not so pretty
} else {
throw new gpUsageException( "Can't apply _value modifier: command " . $command . " did not return a VALUE or OK status, but this: " . $status );
}
}

return $status;
}
}

Expand All @@ -1366,7 +1412,7 @@ public function __call($name, $arguments) {
* @throws gpProtocolException if a communication error ocurred while talking to the peer
* @throws gpProcessorException if the peer reported an error
* @throws gpUsageException if $command does not conform to the rules for commands. Note that
* $this->strictArguments and $this->alloPipes influence which commands are allowed.
* $this->strictArguments and $this->allowPipes influence which commands are allowed.
*/
public function exec( $command, gpDataSource $source = null, gpDataSink $sink = null, &$has_output = null ) {
$this->trace(__METHOD__, "BEGIN");
Expand Down Expand Up @@ -1400,6 +1446,11 @@ public function exec( $command, gpDataSource $source = null, gpDataSink $sink =
}

$strictArgs = $this->strictArguments;

if ( $c == "set-meta" || $c == "authorize" ) { #XXX: ugly hack for wellknown commands #TODO: port to python
$strictArgs = false;
}

foreach ( $command as $c ) {
if ( is_array( $c ) || is_object( $c ) ) throw new gpUsageException("invalid argument type: " . gettype($c));

Expand Down Expand Up @@ -1475,7 +1526,7 @@ public function exec( $command, gpDataSource $source = null, gpDataSink $sink =
$this->status = $m[1];
$this->statusMessage = trim($m[2]);

if ( $this->status != 'OK' && $this->status != 'NONE' ) {
if ( $this->status != 'OK' && $this->status != 'NONE' && $this->status != 'VALUE' ) { #TODO: port VALUE to python
throw new gpProcessorException( $this->status, $m[2], $command );
}

Expand Down Expand Up @@ -1544,9 +1595,8 @@ public static function isValidCommandString( $command ) {
public static function isValidCommandArgument( $arg, $strict = true ) {
if ( $arg === '' || $arg === false || $arg === null ) return false;

if ( $strict ) return preg_match('/^\w[-\w]*(:\w[-\w]*)?$/', $arg); //XXX: the ":" is needed for user:passwd auth. not pretty.

return !preg_match('/[\0-\x1F\x80-\xFF:|<>!&#]/', $arg); //low chars, high chars, and operators.
if ( $strict ) return preg_match('/^\w[-\w]*$/', $arg); #TODO: port stricter pattern to python
else return !preg_match('/[\s\0-\x1F\x80-\xFF:|<>!&#]/', $arg); //space, low chars, high chars, and operators. #TODO: port exclusion of spaces to python
}

/**
Expand Down
67 changes: 66 additions & 1 deletion php/test/gpCore.test.php
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,72 @@ public function testTraverseSuccessorsWithout() {

$this->assertEquals( array( array(11), array(112), array(1121), ), $succ );
}


public function testSetMeta() { #TODO: port to python
$this->gp->set_meta("foo", 1234);
$val = $this->gp->get_meta_value("foo");
$this->assertEquals( "1234", $val );

$this->gp->set_meta("foo", "bla/bla");
$val = $this->gp->get_meta_value("foo");
$this->assertEquals( "bla/bla", $val );

# test bad -----------------------------------------
try {
$this->gp->set_meta("...", 1234);
$this->fail( "exception expected" );
} catch ( gpException $ex ) {
// ok
}

try {
$ok = $this->gp->try_set_meta("x y", 1234);
$this->fail( "exception expected" );
} catch ( gpException $ex ) {
// ok
}

try {
$this->gp->_set_meta(" ", 1234);
$this->fail( "exception expected" );
} catch ( gpException $ex ) {
// ok
}

try {
$this->gp->set_meta("foo", "bla bla");
$this->fail( "exception expected" );
} catch ( gpException $ex ) {
// ok
}

try {
$this->gp->set_meta("foo", "2<3");
$this->fail( "exception expected" );
} catch ( gpException $ex ) {
// ok
}
}

public function testGetMeta() { #TODO: port to python
}

public function testRemoveMeta() { #TODO: port to python
}

public function testListMeta() { #TODO: port to python
$meta = $this->gp->capture_list_meta();
$this->assertEmpty( $meta );

$this->gp->set_meta("foo", 1234);
$meta = $this->gp->capture_list_meta_map();
$this->assertEquals( array("foo" => "1234"), $meta );

$this->gp->remove_meta("foo");
$meta = $this->gp->capture_list_meta();
$this->assertEmpty( $meta );
}

//TODO: add all the tests we have in the talkback test suit

}
Expand Down

0 comments on commit 1232411

Please sign in to comment.