function souk($app, $user_id = NULL) { static $log; if (!isset($log)) { $log = function ($action, Gaia\Souk\Listing $listing) { Tap::debug('LOG: ' . $listing->id . ': ' . $action); }; } return new Gaia\Souk\Logger(new Gaia\Souk($app, $user_id), $log); }
$user_id2 = uniqueUserID(); $item_id = uniqueNumber(1, 10000000); Transaction::claimStart(); $stockpile1 = stockpile($app, $user_id1); $stockpile2 = stockpile($app, $user_id2); $start = microtime(TRUE); $total1 = $stockpile1->add($item_id); $total2 = $stockpile2->add($item_id); $elapsed = microtime(TRUE) - $start; Transaction::commit(); Tap::cmp_ok($elapsed, '<', 1, 'two users adding the same item doesnt create deadlock. took ' . number_format($elapsed, 2) . ' seconds'); $user_id = uniqueUserID(); $item_id = uniqueNumber(1, 10000000); $stockpile = stockpile($app, $user_id); $q = $stockpile->quantity(2); $q->set($stockpile->newId(), array('event' => 'summer2010')); $q->set($stockpile->newId(), array('event' => 'fall2010')); $total = $stockpile->add($item_id, $q); $total = $stockpile->subtract($item_id, 3); Tap::is(quantify($total), 1, 'after adding a tally of 2 and 2 serials for a total of 4, then subtracting 3, my total is now 1'); $user_id = uniqueUserID(); $item_id = uniqueNumber(1, 10000000); $stockpile = stockpile($app, $user_id); $stockpile->add($item_id, 3); $total = $stockpile->convert($item_id, 2); Tap::is($total->tally(), 1, 'After adding 3 quantity items and then converting 2 into serials, the tally is 1'); Tap::is(count($total->serials()), 2, 'The serial count is 2'); $total = $stockpile->convert($item_id, $total->grab(2)); Tap::is($total->tally(), 2, 'after grabbing 2 and converting them into tally, tally is now at 2'); Tap::is(count($total->serials()), 1, 'serial count is now 1'); //print "\n";
$res = $stratum->store($key, $value); } $res = $stratum->query(); asort($pairs, TRUE); Tap::is($res, $pairs, 'stored a bunch of pairs ... query matches what I stored'); //Tap::debug( $pairs ); //Tap::debug( $res ); Tap::is($stratum->query(array('limit' => '0,1')), array_slice($pairs, 0, 1, TRUE), 'queried the first in the list'); Tap::is($stratum->query(array('limit' => 2, 'sort' => 'desc')), array_slice($pairs, -2, NULL, TRUE), 'queried the last two in the list'); $middle = array_slice($pairs, 5, 1, TRUE); list($key, $value) = each($middle); Tap::is($stratum->query(array('min' => $value, 'limit' => 2)), array_slice($pairs, 5, 2, TRUE), 'queried from the middle of the list'); Tap::is($stratum->query(array('max' => $value, 'limit' => 2, 'sort' => 'DESC')), array_reverse(array_slice($pairs, 4, 2, TRUE), TRUE), 'queried from the middle of the list in reverse'); Tap::is($stratum->query(array('search' => array_values(array_slice($pairs, 2, 3, TRUE)))), array_slice($pairs, 2, 3, TRUE), 'search by value matches correct result set'); $expected = $pairs; ksort($expected); $res = $stratum->batch(); Tap::is(count($res), count($pairs), 'batch call returns correct result count'); if ($use_bin_constraint) { $expected = $res; Tap::ok(TRUE, 'skipping first sort order because we cant do exact match of mysql binary ordering'); } else { Tap::is($res, $expected, 'batch call returns result set sorted by key'); } Tap::is($stratum->batch(array('limit' => '0,1')), array_slice($expected, 0, 1, TRUE), 'batch the first in the list'); Tap::is($stratum->batch(array('limit' => 2, 'sort' => 'desc')), array_slice(array_reverse($expected, TRUE), 0, 2, TRUE), 'batch the last two in the list'); Tap::is($stratum->batch(array('start_after' => min(array_keys($expected)))), array_slice($expected, 1, count($expected), TRUE), 'batch starting after the first one'); $expected = array_reverse($expected, TRUE); Tap::is($stratum->batch(array('sort' => 'DESC')), $expected, 'batch call returns result set sorted by key and sort desc works'); Tap::ok($stratum->delete($key), 'successfully deleted a constraint'); //Tap::debug($pairs);
Tap::is(convertResultToScalar($stockpile->all()), array(13 => 2, 15 => 1, 14 => 1), 'when adding to an existing item that one pops to the top'); $stockpile->sort(array(14, 15)); Tap::is(convertResultToScalar($stockpile->all()), array(14 => 1, 15 => 1, 13 => 2), 'custom sorting layers over the top'); $user_id = uniqueUserId(); $stockpile = new FirstAddedSorter(stockpile($app, $user_id)); foreach (range(13, 15) as $item_id) { $stockpile->add($item_id); advanceCurrentTime(1); } Tap::is(convertResultToScalar($stockpile->all()), array_fill_keys(range(15, 13), 1), 'firstaddedsorter sorts keys by time in reverse order when first adding'); $stockpile->add(13); Tap::is(convertResultToScalar($stockpile->all()), array(15 => 1, 14 => 1, 13 => 2), 'when adding to an existing item that one stays where it is'); $stockpile->sort(array(14, 15)); Tap::is(convertResultToScalar($stockpile->all()), array(14 => 1, 15 => 1, 13 => 2), 'custom sorting layers over the top'); $user_id = uniqueUserId(); $stockpile = new OldestSorter(stockpile($app, $user_id)); foreach (range(15, 13) as $item_id) { $stockpile->add($item_id); advanceCurrentTime(1); } Tap::is(convertResultToScalar($stockpile->all()), array(15 => 1, 14 => 1, 13 => 1), 'oldestsorter sorts keys by time in order of add'); $stockpile->add(13); Tap::is(convertResultToScalar($stockpile->all()), array(15 => 1, 14 => 1, 13 => 2), 'when adding to an existing item that one stays where it is'); $stockpile->sort(array(14, 15)); Tap::is(convertResultToScalar($stockpile->all()), array(14 => 1, 15 => 1, 13 => 2), 'custom sorting layers over the top'); $stockpile->sort(array(13, 15)); Tap::is(convertResultToScalar($stockpile->all()), array(13 => 2, 15 => 1, 14 => 1), 'adding a different layering of custom filtering over the top'); $stockpile->subtract(15); $stockpile->add(15); Tap::is(convertResultToScalar($stockpile->all()), array(13 => 2, 14 => 1, 15 => 1), 'after deleting an item and adding it again, it shows up at the end of the list');
<?php namespace Gaia\Stockpile; use Gaia\DB\Transaction; use Gaia\Test\Tap; $user_id = uniqueUserID(); $item_id = uniqueNumber(1, 1000000); // test transaction support. Transaction::claimStart(); $total = stockpile($app, $user_id)->add($item_id); Tap::is(quantify($total), 4, 'add inside a transaction'); // revert the transaction Transaction::rollback(); $total = stockpile($app, $user_id)->get($item_id); Tap::is(quantify($total), 3, 'after txn rollback, the value we added isnt there'); // add inside a transaction and commit it. Transaction::claimStart(); $total = stockpile($app, $user_id)->add($item_id); Tranaction::commit(); $total = stockpile($app, $user_id)->get($item_id); Tap::is(quantify($total), 4, 'add inside of a transaction and commit it. now we can see it!');
<?php use Gaia\Test\Tap; if (!function_exists('mcrypt_encrypt')) { Tap::plan('skip_all', 'php5-mcrypt extension not installed'); }
} function binder() { return new Souk_StockpileHybridBinderTest1(); } $binder = binder(); // wrap in try/catch so we can fail and print out debug. try { //* $seller_id = uniqueUserId(); $buyer_id = uniqueUserId(); $item_id = uniqueNumber(1, 1000000); $binder->itemAccount($seller_id)->add($item_id, 100); $binder->currencyAccount($buyer_id)->add($binder->currencyId(), 100000000); include __DIR__ . '/auction.test.php'; $seller_id = uniqueUserId(); $buyer_id = uniqueUserId(); $item_id = uniqueNumber(1, 1000000); $binder->itemAccount($seller_id)->add($item_id, 100); $binder->currencyAccount($buyer_id)->add($binder->currencyId(), 100000000); include __DIR__ . '/transaction.test.php'; $seller_id = uniqueUserId(); $buyer_id = uniqueUserId(); $item_id = uniqueNumber(1, 1000000); $binder->itemAccount($seller_id)->add($item_id, 100); $binder->currencyAccount($buyer_id)->add($binder->currencyId(), 100000000); include __DIR__ . '/search.test.php'; } catch (Exception $e) { Tap::fail('unexpected exception thrown'); print $e; }
<?php use Gaia\Test\Tap; if (!class_exists('domdocument')) { Tap::plan('skip_all', 'php dom classes missing. install php5-xml.'); }
<?php use Gaia\Test\Tap; if (!function_exists('mb_check_encoding')) { Tap::plan('skip_all', 'php5-mbstring not installed. compile php with --enable-mbstring'); }
<?php use Gaia\Test\Tap; if (!function_exists('pg_connect')) { Tap::plan('skip_all', 'php-postgres not installed'); }
<?php use Gaia\Test\Tap; if (!@fsockopen('127.0.0.1', '11211')) { Tap::plan('skip_all', 'couchbase not running on 127.0.0.1:11211'); } if (!@fsockopen('127.0.0.1', '8092')) { Tap::plan('skip_all', 'couchbase REST API not running on 127.0.0.1:8092'); }
<?php use Gaia\Test\Tap; if (!@fsockopen('127.0.0.1', '3306')) { Tap::plan('skip_all', 'mysql-server not running on localhost'); }
<?php namespace Gaia\Stockpile; use Gaia\DB\Transaction; use Gaia\Test\Tap; $user_id = uniqueUserID(); // test transaction in/out of txn reads. $item_id = uniqueNumber(1, 1000000); Transaction::reset(); Transaction::claimStart(); stockpile($app, $user_id)->add($item_id, 10); // now we should see it. Transaction::commit(); $total = stockpile($app, $user_id)->get($item_id); Tap::is(quantify($total), 10, 'after it is committed we can still see the value we added');
$each = array(); while (list($k, $v) = $c->each()) { $each[$k] = $v; } Tap::is($c->all(), $each, 'each loop returns all the data in the container'); Tap::is(array_keys($input), $c->keys(), 'keys returns all the keys passed to input'); Tap::is(array_keys($input, 'a'), $c->keys('a'), 'search for a key'); Tap::is($c->pop(), $v = array_pop($input), 'popped off an element, same as input'); Tap::is($c->push($v), array_push($input, $v), 'pushed an element back onto the container'); Tap::is($c->all(), $input, 'after pop and push, input matches container'); Tap::is($c->shift(), $v = array_shift($input), 'shifted off an element, same as input'); Tap::is($c->unshift($v), array_unshift($input, $v), 'unshift an element back onto the container'); Tap::is($c->all(), $input, 'after shift and unshift, input matches container'); @asort($input); @$c->sort(); Tap::is($c->all(), $input, 'after sorting, matches sorted input'); ksort($input); $c->ksort(); Tap::is($c->all(), $input, 'after key sorting, matches sorted input'); krsort($input); Tap::is($c->all(), $input, 'after reverse key sorting, matches sorted input'); $c->flush(); Tap::is($c->all(), array(), 'flush removes everything from the container'); $c->load($input); Tap::is($c->all(), $input, 'load puts it all back in again'); $c->push(0); $c->push(NULL); array_push($input, 0); array_push($input, NULL); Tap::is($c->keys(NULL, TRUE), array_keys($input, NULL, TRUE), 'strict match works');
<?php use Gaia\Test\Tap; if (!class_exists('BaseFacebook')) { Tap::plan('skip_all', 'basefacebook class not loaded.'); }
<?php use Gaia\Test\Tap; if (!function_exists('apc_fetch') || !ini_get('apc.enable_cli')) { Tap::plan('skip_all', 'php5-apc extension not installed or enabled (check apc.enable_cli=1)'); }
<?php use Gaia\DB; use Gaia\Test\Tap; include __DIR__ . '/../lib/setup.php'; include __DIR__ . '/../../assert/pdo_installed.php'; include __DIR__ . '/../../assert/pdo_sqlite_installed.php'; DB\Connection::load(array('test' => function () { $db = new DB\Driver\PDO('sqlite:/tmp/souk.db'); $cb = array('start' => function () { $i = \Gaia\DB\Transaction::internals(); Tap::debug('TXN: start ' . $i['depth']); }, 'commit' => function () { $i = \Gaia\DB\Transaction::internals(); Tap::debug('TXN: commit ' . $i['depth']); }, 'rollback' => function () { $i = \Gaia\DB\Transaction::internals(); Tap::debug('TXN: rollback ' . $i['depth']); }, 'query' => function ($args) { $query = array_shift($args); $query = \Gaia\DB\Query::format($query, $args); Tap::debug('QUERY: ' . $query); }); //$db = new DB\Observe( $db, $cb); return $db; }));
<?php // test transaction in/out of txn reads. namespace Gaia\Stockpile; use Gaia\DB\Transaction; use Gaia\Test\Tap; $user_id = uniqueUserID(); $item_id = uniqueNumber(1, 1000000); Transaction::reset(); Transaction::claimStart(); stockpile($app, $user_id)->add($item_id, 10); // read the value outside of the transaction ... shouldn't be able to see it yet. $total = stockpile($app, $user_id)->get($item_id); Tap::is(quantify($total), 10, 'get outside of txn sees the value we added - it is in the cache optimistically'); // now it should go away Transaction::rollback(); $total = stockpile($app, $user_id)->get($item_id); Tap::is(quantify($total), 0, 'after it is rolled back the value disappears from the cache'); Transaction::claimStart(); stockpile($app, $user_id)->add($item_id, 10); $stockpike = stockpile($app, $user_id); $stockpile->forceRefresh(TRUE); $total = $stockpile->get($item_id); Tap::is(quantify($total), 0, 'when force-refreshing the cache, item disappears that we added but didnt commit'); Transaction::rollback();
$e = NULL; try { $listing = $souk->buy($listing->id); } catch (Exception $e) { $e = $e->getMessage(); } Tap::is($e, 'bid only', 'when buying bid-only, fails'); DB\Transaction::reset(); DB\Connection::reset(); $listing = $souk->bid($listing->id, 1); Tap::is($listing->bid, 1, 'bid works fine, tho'); $listing = Souk($app, $seller_id)->auction(array('bid' => 0, 'reserve' => 5, 'item_id' => $item_id)); $listing = Souk($app, $buyer_id)->bid($listing->id, 5); Tap::is($listing->bid, 5, 'without enable_proxy, bid is set, not stepped'); $listing = Souk($app)->close($listing->id); Tap::is($listing->buyer, 0, 'when reserve isnt met, bidder doesnt win listing'); Tap::is($listing->closed, 1, 'even tho reserve wasnt met, closing still ends the bidding.'); unset($seller_id); unset($buyer_id); unset($item_id); Time::offset(86400 * 30); $id = 0; $ct = 0; while ($listings = Souk($app)->pending(0, 5, $id)) { foreach ($listings as $id) { $ct++; //Tap::debug('pending: ' . $id ); } } Tap::cmp_ok($ct, '>=', 1, "found at least 1 item in pending: {$ct} found"); //print "\n\n";
$res = array(); foreach (souk($app)->fetch(souk($app)->search(array('item_id' => $item_id, 'seller' => $seller_id, 'floor' => 4, 'ceiling' => 6))) as $id => $listing) { $res[$listing->price] = TRUE; } $res = array_keys($res); sort($res); Tap::is($res, array(4, 5, 6), 'setting floor and ceiling limits the result set to prices in the correct range'); $search = souk($app)->search(array('item_id' => $item_id, 'seller' => $seller_id, 'closed' => 0)); $id = array_shift($search); souk($app)->close($id); $ids = souk($app)->search(array('item_id' => $item_id, 'seller' => $seller_id, 'closed' => 0)); Tap::ok(!in_array($id, $ids, TRUE), 'after closing an item, it no longer appears in the list of unclosed items'); $res = souk($app)->fetch(souk($app)->search(array('item_id' => $item_id, 'seller' => $seller_id, 'closed' => 0, 'only' => 'bid'))); $bidonly = TRUE; foreach ($res as $listing) { if (!$listing->step || $listing->price) { $bidonly = FALSE; } } Tap::ok($bidonly, 'searching with only=>bid param returns results that are all bid only items, no prices'); $res = souk($app)->fetch(souk($app)->search(array('item_id' => $item_id, 'seller' => $seller_id, 'closed' => 0, 'only' => 'buy'))); $buynow = TRUE; foreach ($res as $listing) { if ($listing->step || !$listing->price) { $buynow = FALSE; } } Tap::ok($buynow, 'searching with only=>buy param returns results that are all buy now only items, no bids'); unset($seller_id); unset($buyer_id); unset($item_id);
<?php use Gaia\Test\Tap; if (!function_exists('dba_open')) { Tap::plan('skip_all', 'dba not enabled'); }
<?php use Gaia\Test\Tap; if (!@fsockopen('127.0.0.1', 5432)) { Tap::plan('skip_all', 'postgres not running on 127.0.0.1:5432'); }
<?php use Gaia\Test\Tap; if (!@fsockopen('127.0.0.1', '8098')) { Tap::plan('skip_all', 'Riak not running on localhost'); }
<?php use Gaia\Test\Tap; if (!@fsockopen('api.facebook.com', '443')) { Tap::plan('skip_all', 'unable to connect to facebook api'); }
<?php use Gaia\Test\Tap; if (!class_exists('\\MySQLi')) { Tap::plan('skip_all', 'php-mysqli not installed'); }
<?php namespace Gaia\Stockpile; use Gaia\DB\Transaction; use Gaia\Test\Tap; $user_id = uniqueUserID(); $item_id = uniqueNumber(1, 1000000); stockpile($app, $user_id)->add($item_id, 5); // cant subtract zero $e = NULL; try { stockpile($app, $user_id)->subtract($item_id, 0); } catch (\Exception $e) { } Tap::ok($e instanceof \Exception && preg_match('/cannot subtract/', $e->getMessage()), 'cant subtract zero'); // subtract more than we have. $starting_total = stockpile($app, $user_id)->get($item_id); $e = NULL; try { $stockpile = stockpile($app, $user_id); $stockpile->subtract($item_id, quantify($stockpile->get($item_id)) + 1); } catch (\Exception $e) { } Tap::ok($e instanceof \Exception && preg_match('/not enough/', $e->getMessage()), 'wont allow to subtract more than you have'); // after failed subtraction, amount is still correct. $total = stockpile($app, $user_id)->get($item_id); Tap::is($total, $starting_total, 'after failed subtract, amount is still the same');
Tap::ok(Transaction::rollback(), 'rolled back the transaction at the global level'); Tap::ok($rs = $dbmain->execute("select id from {$table}"), 'selected all rows from the table'); $ct = $rs->affected(); Tap::is($ct, 2, '2 rows in the table, new rows rolled back'); $rs = $conn1->execute("select id from {$table}"); Tap::is($rs, FALSE, 'after rolling back, new queries fail on rolled back db object'); $dbmain->execute("drop table {$table}"); $db = $newconn(); $raw = file_get_contents(__DIR__ . '/../sample/i_can_eat_glass.txt'); $lines = explode("\n", $raw); $lines = array_slice($lines, 0, 10) + array_slice($lines, 100, 10) + array_slice($lines, 200, 10) + array_slice($lines, 200, 10); $raw = implode("\n", $lines); $sql = "CREATE TEMPORARY TABLE t1utf8 (`i` INT UNSIGNED NOT NULL PRIMARY KEY, `line` VARCHAR(5000) ) ENGINE=InnoDB DEFAULT CHARACTER SET utf8"; $db->execute($sql); foreach ($lines as $i => $line) { //$lines[ $i ] = $line = mb_convert_encoding($line, 'UTF-8', 'auto'); $db->execute('INSERT INTO t1utf8 (`i`, `line`) VALUES (%i, %s)', $i, $line); } $rs = $db->execute('SELECT * FROM t1utf8'); $readlines = array(); while ($row = $rs->fetch()) { $readlines[$row['i']] = $row['line']; } $rs->free(); Tap::cmp_ok($readlines, '===', $lines, 'inserted all the rows and read them back, worked as expected'); //Tap::debug( $readlines ); $rs = $db->execute('SELECT %s AS `d`', $raw); $row = $rs->fetch(); $rs->free(); Tap::cmp_ok($row['d'], '===', $raw, 'passed a huge chunk of utf-8 data to db and asked for it back. got what I sent.'); //Tap::debug( $row['d'] );
<?php use Gaia\Test\Tap; if (!in_array('mysql', PDO::getAvailableDrivers())) { Tap::plan('skip_all', 'this version of PDO does not support mysql'); }
<?php use Gaia\Test\Tap; if (!@fsockopen('127.0.0.1', '11300')) { Tap::plan('skip_all', 'Beanstalkd not running on localhost'); }
$expected_sum = 0; foreach (array_slice(array_reverse($batch, TRUE), 5) as $data) { $expected_sum = bcadd($expected_sum, $data['foo']); } Tap::is($ct, 6, 'filter descending with start_after iterated the correct number of rows'); Tap::is($sum, $expected_sum, 'sum from filter with start_after arrived at the correct amount'); $generated_ids = $post_processed_ids = array(); $generate = function (array $params) use($skein, &$generated_ids, &$post_processed_ids) { $return = array(); $ids = $skein->ids($params); foreach ($ids as $id) { $generated_ids[] = $id; if ($id % 2 == 0) { $post_processed_ids[] = $return[] = $id; } } return $return; }; $processed_ids = array(); $process = function ($id, $data) use(&$processed_ids) { $processed_ids[] = $id; }; $skein->filter(array('process' => $process, 'generate' => $generate)); Tap::is($generated_ids, $ids, 'generate filter gets all the ids'); Tap::is($processed_ids, $post_processed_ids, 'process filter gets only the ids returned by generate'); $shard = mt_rand(1, 100); $id = $skein->add($data = array('foo' => mt_rand(1, 1000000000)), $shard); $parts = Skein\Util::parseId($id); Tap::is($parts[0], $shard, 'created a new entry, using a custom shard'); Tap::is($skein->get($id), $data, 'read back the entry with custom shard');