/** * Builds a system db for the test environment * * @todo This replicates some code in Command/System/Build - needs to be much more DRY */ protected function buildTestSystemDatabase() { // Load the Meshing_Test_Paths class $projectRoot = Meshing_Utils::getProjectRoot(); require_once $projectRoot . '/tests/unit/Meshing_Test_Paths.php'; Meshing_Utils::reinitialise(new Meshing_Test_Paths()); $paths = Meshing_Utils::getPaths(); // Build a system connection file $task = new Meshing_Propel_ConfBuilder(); $task->addSchemas($projectRoot . $paths->getPathDbConfig(), $paths->getLeafStandardSchema()); $task->setXmlFile($projectRoot . $paths->getFileRuntimeXml()); $task->setPropelConnection(Meshing_Utils::CONN_SYSTEM_TEST); $task->setOutputDir($projectRoot . $paths->getPathConnsSystem()); $task->setOutputFile($paths->getLeafRuntimePhp()); $task->run(); // Build the SQL for a test system database $task = new Meshing_Propel_SqlBuilder(); $task->addSchemas($projectRoot . $paths->getPathDbConfig(), $paths->getLeafStandardSchema()); $task->setOutputDir($projectRoot . $paths->getPathSqlSystem()); $task->setPropelConnection(Meshing_Utils::CONN_SYSTEM_TEST); $task->run(); // Run the sql $task = new Meshing_Propel_SqlRunner(); $task->setSqlDir($projectRoot . $paths->getPathSqlSystem()); $task->setMapFile($projectRoot . $paths->getFileDbMap()); $task->setPropelConnection(Meshing_Utils::CONN_SYSTEM_TEST); $task->run(); }
protected function runCommand($command) { $projectRoot = Meshing_Utils::getProjectRoot(); $command = $projectRoot . '/meshing ' . $command; $output = array(); exec($command, $output); return implode("\n", $output); }
protected function useVersionStrategy() { $paths = Meshing_Utils::getPaths(); $strategy = new Meshing_Hash_Strategy_Version($this->conNode); $paths->setHashProvider($strategy); $this->clearProviderCache(); return $strategy; }
public function __construct() { parent::__construct(); // Sets up default Propel build properties $projectPath = Meshing_Utils::getProjectRoot(); $propertiesFile = $projectPath . '/vendor/propel-1.6/generator/default.properties'; $this->addPropertiesFile($propertiesFile); }
/** * Testing syncing node 1 containing a few rows with node 2, which is empty */ public function testSimpleSync1() { // Set up data in node 1 $fixtures = $this->projectRoot . Meshing_Utils::getPaths()->getFixturesPath(); $data = (require_once $fixtures . '/simpleSync1.php'); $dbUtils = new Meshing_Database_Utils(); $dbUtils->writeVersionableData($data, $this->node1, $this->conNode); // @todo Sync data into node 2 here :) }
public function preRunCheck() { if (!$this->opts->name) { throw new Zend_Console_Getopt_Exception('Which node would you like have send updates? (use --name)'); } Meshing_Utils::initialiseDb(); $this->node = P2POwnNodeQuery::create()->findOneByName($this->opts->name); if (!$this->node) { throw new Zend_Console_Getopt_Exception('A node of that name is not registered'); } }
public function run() { Meshing_Utils::initialiseDb(); $outFormat = '%-15s%-15s%-15s'; $this->ruleOff($lineLength = 15 + 15 + 15); echo sprintf($outFormat, 'Name', 'Schema', 'Connection') . "\n"; $this->ruleOff($lineLength); /* @var $ownNode P2POwnNode */ foreach (P2POwnNodePeer::doSelect(new Criteria()) as $ownNode) { echo sprintf($outFormat, $ownNode->getName(), $ownNode->getMeshingSchema()->getName(), $ownNode->getP2PConnection()->getName()) . "\n"; } }
public function run() { Meshing_Utils::initialiseDb(); $outFormat = '%-15s'; $this->ruleOff($lineLength = 15); echo sprintf($outFormat, 'Name', 'Schema', 'Connection') . "\n"; $this->ruleOff($lineLength); /* @var $schema MeshingSchema */ foreach (MeshingSchemaPeer::doSelect(new Criteria()) as $schema) { echo sprintf($outFormat, $schema->getName()) . "\n"; } }
public function preRunCheck() { $name = $this->opts->name; if (!$name) { throw new Zend_Console_Getopt_Exception('The connection name must be specified.'); } // @todo Check that this connection isn't in use Meshing_Utils::initialiseDb(); $this->connection = P2PConnectionQuery::create()->findOneByName($name); if (!$this->connection) { throw new Zend_Console_Getopt_Exception('No such connection.'); } }
protected function deleteDirectories() { $projectRoot = Meshing_Utils::getProjectRoot(); $schemaDir = $projectRoot . Meshing_Utils::getPaths()->getPathSchemasNodes() . '/' . $this->opts->name; $modelDir = $projectRoot . Meshing_Utils::getPaths()->getPathModelsNodes() . '/' . $this->opts->name; echo "Done.\n"; $ok = @rmdir($schemaDir); $ok = $ok && @rmdir($modelDir); if (!$ok) { echo "Not (yet) deleting empty dirs. Please run these, if safe:\n"; echo "rm -rf " . $schemaDir . "\n"; echo "rm -rf " . $modelDir . "\n"; } }
public function run() { Meshing_Utils::initialiseDb(); $outFormat = '%-15s%-12s%-15s%-40s'; $this->ruleOff($lineLength = 15 + 12 + 15 + 40); echo sprintf($outFormat, 'Name', 'Adaptor', 'User', 'Host') . "\n"; $this->ruleOff($lineLength); $connections = P2PConnectionPeer::doSelect(new Criteria()); /* @var $connection P2PConnection */ foreach ($connections as $connection) { echo sprintf($outFormat, $connection->getName(), $connection->getAdaptor(), $connection->getUsername() ? $connection->getUsername() : 'n/a', $connection->getHost()); echo "\n"; } }
/** * Specify which connection on which to carry out the schema task * * @param strings $connName Optional connection name (defaults to system connection) */ public function setPropelConnection($connName = Meshing_Utils::SYSTEM_CONNECTION) { // Grab the db details directly out of the Propel config file $xmlPath = Meshing_Utils::getProjectRoot() . Meshing_Utils::getPaths()->getFileRuntimeXml(); $conf = simplexml_load_file($xmlPath); /* @var $conf SimpleXMLElement */ $entry = $conf->xpath('/config/propel/datasources/datasource[@id="' . $connName . '"]'); // If an element doesn't exist here, we've probably got the connection name wrong if (!array_key_exists(0, $entry)) { throw new Exception("Connection name '{$connName}' not found"); } $entry = $entry[0]; $this->setDatabaseCredentials((string) $entry->adapter, (string) $entry->connection->dsn, (string) $entry->connection->user, (string) $entry->connection->password); }
protected static function readCommands($incHidden = false) { static $commands = array(); static $hidden = array(); if (!$commands) { $projectRoot = Meshing_Utils::getProjectRoot(); $consoleRoot = $projectRoot . Meshing_Utils::getPaths()->getPathMeshingCommands(); $directory = new RecursiveDirectoryIterator($consoleRoot); $iterator = new RecursiveIteratorIterator($directory); $regex = new RegexIterator($iterator, '/^.+\\.php$/i', RecursiveRegexIterator::GET_MATCH); $regex->next(); $i++; while ($regex->valid()) { // For safety! if ($i > 50) { break; } // Get the full pathname of the class $item = $regex->current(); $item = $item[0]; // Strip out the full path bit, and generally tidy $item = str_replace($consoleRoot . DIRECTORY_SEPARATOR, '', $item); $item = str_replace('.php', '', $item); $className = 'Meshing_Console_Command_' . str_replace(DIRECTORY_SEPARATOR, '_', $item); $item = strtolower(str_replace(DIRECTORY_SEPARATOR, ':', $item)); // Classes without this method are not commands at all $realCommand = method_exists($className, 'getDescription'); // We consult a special method to determine whether to show the command if ($realCommand) { $cmdClass = new $className(); $commands[$className] = $item; if ($cmdClass->isHiddenCommand()) { $hidden[] = $className; } } $regex->next(); } // Preserve the keys when sorting asort($commands); } // Strip out hidden commands if (!$incHidden) { foreach ($hidden as $removeClass) { unset($commands[$removeClass]); } } return $commands; }
/** * Gets mixed array of MeshingOwnNode and *KnownNode objects to send to */ protected function getLocalAndRemoteReceiverNodes(P2POwnNode $node) { // Rewrite the above from the perspective of the local 'to' node $localNodes = P2POwnNodeQuery::create()->joinMeshingTrustLocalRelatedByToOwnNodeId('TrustLocal')->useQuery('TrustLocal')->joinMeshingTrustType()->endUse()->where('TrustLocal.FromOwnNodeId = ?', $node->getId())->where('MeshingTrustType.Name LIKE ?', 'write%')->find(); // Get array of node ids in remote database (we can't join between system and node dbs) $remoteNodeIds = MeshingTrustRemoteQuery::create()->joinMeshingTrustType()->where('MeshingTrustRemote.FromOwnNodeId = ?', $node->getId())->where('MeshingTrustType.Name LIKE ?', 'write%')->select('MeshingTrustRemote.KnownNodeId')->find()->getArrayCopy(); // Initialise remote node models $schemaName = $node->getMeshingSchema()->getName(); Meshing_Utils::initialiseNodeDbs($schemaName); $con = Meshing_Node_Utils::getConnectionForNode($node); // Do select in node database for remote node ids $className = Meshing_Node_Utils::getNodeClassName($schemaName, 'KnownNodeQuery'); /* @var $query JobsKnownNodeQuery */ // (This is just an example - can be of any *KnownNodeQuery class) $query = call_user_func(array($className, 'create'), 'KnownNode'); $remoteNodes = $query->where('KnownNode.Id IN ?', $remoteNodeIds)->find($con); /* @var $localNodes PropelObjectCollection */ /* @var $remoteNodes PropelObjectCollection */ return array_merge($localNodes->getArrayCopy(), $remoteNodes->getArrayCopy()); }
public function preRunCheck() { // Used to track bad combos e.g. local-to AND remote-to $hasToLocal = $hasToRemote = false; $localFromName = $this->opts->{'local-from'}; if (!$localFromName) { throw new Zend_Console_Getopt_Exception('A local node must be specified (use --local-from)'); } if ($localToName = $this->opts->{'local-to'}) { $hasToLocal = true; } // @todo Not implemented yet if ($remoteToName = $this->opts->{'remote-to'}) { throw new Zend_Console_Getopt_Exception('Remote nodes are not currently supported'); //$hasToRemote = true; } // Check for bad combinations if ($localToName && $remoteToName) { throw new Zend_Console_Getopt_Exception('You cannot have a local-to AND a remote-to node'); } if (!$localToName && !$remoteToName) { throw new Zend_Console_Getopt_Exception('You must have one \'to\' node (use --local-to or --remote-to)'); } // Check that the local from actually exists Meshing_Utils::initialiseDb(); $this->localFromNode = P2POwnNodeQuery::create()->findOneByName($localFromName); if (!$this->localFromNode) { throw new Zend_Console_Getopt_Exception('A local node of that (from) name is not registered'); } if ($localToName) { $this->localToNode = P2POwnNodeQuery::create()->findOneByName($localToName); if (!$this->localToNode) { throw new Zend_Console_Getopt_Exception('A local node of that (to) name is not registered'); } } // We cannot trust ourselves, so to speak ;-) if ($localFromName == $localToName) { throw new Zend_Console_Getopt_Exception('There is no point in setting a node to trust itself'); } }
public function preRunCheck() { if (!$this->opts->name) { throw new Zend_Console_Getopt_Exception('Which node would you like to start? (use --name)'); } Meshing_Utils::initialiseDb(); $node = P2POwnNodeQuery::create()->findOneByName($this->opts->name); if (!$node) { throw new Zend_Console_Getopt_Exception('A node of that name is not registered'); } // Connect with this node's connection, and ensure there are rows in known_nodes $conn = Propel::getConnection($node->getP2PConnection()->getName()); $schemaName = $node->getMeshingSchema()->getName(); Meshing_Utils::initialiseNodeDbs($schemaName); // Obtain the number of trusted nodes $class = Meshing_Node_Utils::getNodeClassName($schemaName, 'KnownNodePeer'); $knownNodeCount = call_user_func(array($class, 'doCount'), new Criteria(), $distinct = false, $conn); // If there are no trust rows, we cannot start if (!$knownNodeCount) { throw new Zend_Console_Getopt_Exception('A node needs to trust other nodes before it can be started'); } }
public function testMaxContention() { // If Windows, we can't test if (substr(PHP_OS, 0, 3) == 'WIN') { user_error("Can't currently test locking on the Windows platform", E_USER_WARNING); return; } // Append errors to this log file $logDir = Meshing_Utils::getProjectRoot() . Meshing_Utils::getPaths()->getTestLogPath(); $childCount = 10; for ($id = 0; $id < $childCount; $id++) { $command = 'php "' . __FILE__ . '" ' . CHILD_TOKEN . ' ' . $id; $background = '>> ' . $logDir . '/' . LOCKING_TEST_LOG . ' 2>&1 &'; $return = null; $output = system($command . ' ' . $background, $return); // @todo Need to find a way to detect if the process launch failed // (no $output is returned even if errors are output to stdout) if ($output === false) { user_error('There was a problem executing a background task', E_USER_WARNING); break; } } // Wait for all children to finish $iter = 0; $okCount = null; do { sleep(1); $iter++; $completed = $this->allChildrenFinished($childCount, $okCount); // Time limit if ($iter > 20 && !$completed) { user_error("Time limit expired, but only {$okCount} of {$childCount} children finished", E_USER_WARNING); break; } } while (!$completed); $this->assertEqual($okCount, $childCount, 'Check that all inserts have completed without race condition problems'); }
protected function runFixtures($verbose) { $fixturesFile = $this->projectRoot . Meshing_Utils::getPaths()->getPathSystemFixtures() . '/fixtures.php'; if (file_exists($fixturesFile)) { $runner = new Meshing_Propel_FixturesRunner($fixturesFile); $runner->run(); } }
/** * Useful when testing and wishing to reset the paths class * * @param Meshing_Paths $paths */ public static function reinitialise(Meshing_Paths $paths) { if (self::$isMeshingInitialised) { self::$isMeshingInitialised = false; set_include_path(self::$oldIncludes); self::$oldIncludes = null; } self::initialise($paths); }
public function testCreateChangeTables() { $paths = Meshing_Utils::getPaths(); $snippetsPath = Meshing_Utils::getProjectRoot() . $paths->getPathSystemSnippets(); $tables = $this->xml->getTables(); $changeTables = $this->xml->createChangeTables($snippetsPath . '/change_table.xml', $tables); $this->assertEqual(count($tables), count($changeTables), 'Ensure there is a change table for each real table'); // @todo Check that the prefix is the same for each change table // @todo Check that the FKs in each change table are mapped to current table PK equivs }
/** * Get XML version of default runtime file, returns temp version to convert to PHP */ protected function createRuntimeXml($runTime, $newRunTime) { // Ensure the file exists if (!is_readable($runTime)) { throw new Exception("Can't load runtime configuration"); } // Ensure the new file won't overwrite the old one! if ($runTime == $newRunTime) { throw new Exception('The new XML location must be different to the existing one'); } // Load up the XML doc $xml = simplexml_load_file($runTime); // @todo Validate XML file // Grab the connections known to the system (@todo would we want more than 50!?) Meshing_Utils::initialiseDb(); $c = new Criteria(); $c->setLimit(50); $connections = P2PConnectionPeer::doSelect($c); // Add each connection in as a datasource /* @var $connection P2PConnection */ foreach ($connections as $connection) { // Modify XML document $element = $xml->propel->datasources->addChild('datasource'); $element['id'] = $connection->getName(); $inner1 = $element->addChild('adapter', $connection->getAdaptor()); $inner2 = $element->addChild('connection'); $inner2->addChild('dsn', $connection->getCalculatedDsn()); $inner2->addChild('user', $connection->getUsername()); $inner2->addChild('password', $connection->getPassword()); } // Write out modified XML doc to new file $xml->asXml($newRunTime); }
public function __construct($inFilename, $outFilename) { $this->xml = simplexml_load_file($inFilename, 'Meshing_Schema_Element'); $this->filename = $outFilename; $this->snippetDir = Meshing_Utils::getProjectRoot() . Meshing_Utils::getPaths()->getPathSystemSnippets(); }
<?php // Set up project $projectRoot = realpath(dirname(__FILE__) . '/../../..'); require_once $projectRoot . '/lib/Meshing/Paths.php'; require_once $projectRoot . '/tests/unit/Meshing_Test_Paths.php'; require_once $projectRoot . '/lib/Meshing/Utils.php'; Meshing_Utils::reinitialise(new Meshing_Test_Paths()); // Init simpletest require_once 'simpletest/autorun.php'; class PropelModelTestCase extends Meshing_Test_DatabaseTestCase { public function __construct($label = false) { parent::__construct('test_model', $label); } /** * Tests the building of node model class files */ public function testClassBuilder() { $this->doFixup(); // Do generation of classes and all checking $this->_testClassBuilder('TestModel'); } /** * This is an extended list of expected classes * * @return array */ protected function expectedClasses()
<?php // System initialisation (some hardwiring required before autoloader kicks in) $projectRoot = realpath(dirname(__FILE__) . DIRECTORY_SEPARATOR . '..'); require_once $projectRoot . '/lib/Meshing/Paths.php'; require_once $projectRoot . '/lib/Meshing/Utils.php'; Meshing_Utils::initialise(new Meshing_Paths()); // Pop off the script name, grab the command, pop again array_shift($argv); $command = array_key_exists(0, $argv) ? $argv[0] : null; array_shift($argv); if ($command) { $className = Meshing_Console_Utils::getCommandClass($command); if ($className === false) { echo "Unrecognised command.\n"; exit(1); } } else { $className = 'Meshing_Console_Command_Help'; } // Run the implementation try { $ok = Meshing_Console_Utils::runCommand($className, $argv); } catch (Zend_Console_Getopt_Exception $e) { echo $e->getMessage() . "\n"; exit(1); } catch (Meshing_Console_RunException $e) { echo $e->getMessage() . "\n"; exit(2); }
/** * Runs the already-built SQL for the system db (deletes the existing system tables) * * @todo This is similar to system:build, fix this? * * @param string $projectRoot */ protected function runSql($projectRoot) { $sqlDir = $projectRoot . Meshing_Utils::getPaths()->getPathSqlNodes() . '/' . $this->opts->name; $mapFile = $projectRoot . Meshing_Utils::getPaths()->getFileDbMap(); $task = new Meshing_Propel_SqlRunner(); $task->setSqlDir($sqlDir); $task->setMapFile($mapFile); // Set build properties (@todo switch this to use setPropelConnection) $task->addProperty('propel.database', $this->connection->getAdaptor()); $task->addProperty('propel.database.url', $this->connection->getCalculatedDsn()); $task->addProperty('propel.database.user', $this->connection->getUsername()); $task->addProperty('propel.database.password', $this->connection->getPassword()); $task->run(); }
protected function createConf() { $paths = Meshing_Utils::getPaths(); $configName = $paths->getLeafRuntimePhp(); $this->convertConf($this->projectRoot . $paths->getFileRuntimeXml(), $this->projectRoot . $paths->getPathConnsNodes($this->opts->name), $configName); // We only want the autoloading file, not the connections file... deleting to be tidy! $configPath = $this->projectRoot . Meshing_Utils::getPaths()->getPathConnsNodes($this->opts->name) . '/' . $configName; @unlink($configPath); }
/** * Connect to the new connection, and throw exception if it fails * * @return boolean */ protected function testNewConnection() { if ($this->opts->test) { Meshing_Utils::initialiseDb(); try { $conn = Propel::getConnection($this->opts->name); } catch (PropelException $e) { throw new Meshing_Console_RunException($e->getMessage()); } } return true; }
/** * Initialise the test system and test node databases * * Can't init the test node db in the constructor, since the conf file may not be created */ protected function initConnections() { Meshing_Utils::initialiseDb($testMode = true); Meshing_Utils::initialiseNodeDbs($this->package, $testMode); $this->conSystem = Propel::getConnection(Meshing_Utils::CONN_SYSTEM_TEST); $this->conNode = Propel::getConnection(Meshing_Utils::CONN_NODE_TEST_1); }
/** * Gets an instance of the hashing object * * It is possible that Meshing will connect to several connections, either in a production * nodeset where several databases are in use, or in testing. To ensure our provider uses * the right connection, we cache hash providers per connection. * * @staticvar Meshing_Hash_Base $hashProvider * @param PropelPDO $con * @return Meshing_Hash_Base */ protected function getHashProvider(Meshing_Database_Connection $con) { $key = (string) $con; if (!array_key_exists($key, self::$hashProviders)) { self::$hashProviders[$key] = Meshing_Utils::getPaths()->getHashProvider($con); } return self::$hashProviders[$key]; }
public function __construct($fixturesFile) { $this->fixturesFile = $fixturesFile; Meshing_Utils::initialiseDb(); }