/** * Restore the database from a local file. * * @SideEffects: * Restores dump file to local database * * @return bool true on success, false on fail * @throws PermissionFailureException * @throws Exception */ public function execute() { $this->checkPerm(); $fullPath = FileSystemTools::build_path($this->Path, $this->FileName); if (!file_exists($fullPath)) { $this->failed("No such file '{$fullPath}'"); throw new Exception("No such file {$fullPath}"); } // detect if we should use GZIP from the file name terminal extension being '.gz' if (substr($this->FileName, -3) == '.gz') { $this->UseGZIP = true; $command = sprintf("gunzip < %s | %s --host=%s --user=%s --password=%s %s ", $fullPath, Replicant::config()->get('path_to_mysql'), DatabaseTools::getDBCredential('Server'), DatabaseTools::getDBCredential('UserName'), DatabaseTools::getDBCredential('Password'), $this->Database); } else { $command = sprintf("%s --host=%s --user=%s --password=%s %s < %s", Replicant::config()->get('path_to_mysql'), DatabaseTools::getDBCredential('Server'), DatabaseTools::getDBCredential('UserName'), DatabaseTools::getDBCredential('Password'), $this->Database, $fullPath); } $this->step("Restoring database '{$this->UserName}@{$this->RemoteHost}:{$this->Database}' from '{$fullPath}'"); if ($this->system($command, $retval)) { // we need a new one here as existing one will be gone when database // ReplicantActionRestore::create(static::ActionRestore, "", static::ResultMessageSuccess, "Restoring database '$this->UserName@$this->RemoteHost:$this->Database' from '$fullPath'"); $this->success("Restored database '{$this->Database}' from '{$fullPath}'"); return true; } else { $this->failed("Failed, command returned #{$retval}"); return false; } }
/** * Return a list of files from the provided as the requested mimeType (default text/html unordered list, otherwise application/json structure). * * @SideEffects: * Writes content to output buffer. * * @param $path * @param array $mimeTypes * @return number of files listed */ public function execute($mimeTypes = array('text/html')) { $this->checkPerm(); $files = FileSystemTools::nodot_files($this->Path); if (in_array('application/json', $mimeTypes)) { $this->step("Sending results as json"); $body = ''; foreach ($files as $fullPath => $fileName) { $fileInfo = new ReplicantFileInfo($fullPath); $body .= "," . $fileInfo->to_json(); } $body = "[" . substr($body, 1) . "]"; } else { $this->step("Sending results as html"); $body = "<ul>"; foreach ($files as $this->Path => $fileName) { // strip extension, not needed $body .= '<li>' . $fileName . ' <a href="/replicant/files/' . $fileName . '">download</a> <a onclick="javascript: return confirm("Are you sure you want to restore ' . $fileName . ' to this server?);" href="/dev/tasks/ReplicantTask?action=restore&filename=' . $fileName . '">restore to this server</a> </li>'; } $body .= "</ul>"; } echo $body; $this->success("Output " . count($files) . " files"); return count($files); }
/** * Dump database to the local filesystem via mysqldump command and optionally gzipping output. * * @SideEffects: * Dumps database to local filesystem. * * @return bool true on success, false on fail * @throws PermissionFailureException */ public function execute() { $fullPath = FileSystemTools::build_path($this->Path, $this->FileName) . ($this->UseGZIP ? ".gz" : ''); $this->step("Dumping database '{$this->Database}' to '{$fullPath}'"); // local server dump requested, create paths and dump the file. if (!is_dir($this->Path)) { // path doesn't exist, create it recursively $this->step("Creating folder '{$this->Path}'"); if (!FileSystemTools::make_path($this->Path)) { $this->failed("Failed to create path '{$this->Path}'"); return false; } } $excludeTables = ''; if (count(Replicant::config()->get('exclude_tables'))) { $excludeTables = " --ignore-table={$this->Database}." . implode(" --ignore-table={$this->Database}.", Replicant::config()->get('exclude_tables')) . " "; } $command = sprintf("%s --host=%s --user=%s --password=%s %s %s %s %s", Replicant::config()->get('path_to_mysqldump'), DatabaseTools::getDBCredential('Server'), DatabaseTools::getDBCredential('UserName'), DatabaseTools::getDBCredential('Password'), $excludeTables, $this->Database, $this->UseGZIP ? " | gzip > " : " > ", $fullPath); $ok = $this->system($command, $retval); if ($ok) { $this->success("Dumped Database to {$fullPath}"); } else { $this->failed("Execute returned #{$retval}"); } return $ok; }
/** * Dump the current SilverStripe database to the local filesystem. * * Returns true on successful execution of mysqldump command, false otherwise. * * @param SS_HTTPRequest $request * @return bool * @throws PermissionFailureException */ public function dump(SS_HTTPRequest $request) { $options = CollectionTools::options_from_array($request->getVars(), array('RemoteHost' => $request->getIP(), 'Path' => Replicant::asset_path(), 'FileName' => FileSystemTools::filename_from_timestamp('.sql'), 'UseGZIP' => false)); $action = ReplicantActionDump::create(); $action->checkPerm()->update($options)->execute(); return $action->format(); }
private function tryToTest(AcceptanceGuy $I) { // need a copy of test folder FileSystemTools::copyRecursive(TestConfig::getConfig('testPath'), $this->tmpStaging); $I->runShellCommand(TestConfig::getConfig('testRunnerPath') . DS . 'runtests.bat testStagingPath:' . $this->tmpStaging); $I->seeInShellOutput('Codeception PHP Testing Framework'); //$I->seeInShellOutput('PhantomJS server stopped'); }
public function testPrune() { $this->guy->createTestFolderTree($this->tmpPath1); $this->assertTrue($this->guy->isTestFolderTree($this->tmpPath1)); FileSystemTools::prune($this->tmpPath1); $this->assertTrue(is_dir($this->tmpPath1)); $this->assertFalse($this->guy->isTestFolderTree($this->tmpPath1)); }
function removeTestTemplateFiles() { FileSystemTools::rmdirRecursive($this->ROOT_PATH . "/system/modules/systestmodule"); FileSystemTools::rmdirRecursive($this->ROOT_PATH . "/modules/testmodule"); foreach (['templates/testmodule/testtemplate', 'templates/testmodule/get', 'templates/testmodule/edit', 'templates/testmodule/submodule', 'templates/testmodule/testmodule', 'templates/testtemplate', 'templates/get', 'templates/edit', 'templates/submodule', 'templates/testmodule', 'system/templates/testtemplate', 'system/templates/get', 'system/templates/edit', 'system/templates/submodule', 'system/templates/testmodule'] as $toRemove) { if (file_exists($this->ROOT_PATH . DIRECTORY_SEPARATOR . $toRemove . '.tpl.php')) { unlink($this->ROOT_PATH . DIRECTORY_SEPARATOR . $toRemove . '.tpl.php'); } } if (file_exists($this->ROOT_PATH . "/templates/minilayout.tpl.php")) { unlink($this->ROOT_PATH . "/templates/minilayout.tpl.php"); } }
/** * Read the file to the output buffer. * * SideEffects: * Writes file contents to output buffer if found * * Path to file is hard-coded as Replicant::asset_path() setting. * * Content-Type returned is text/plain. * * @return bool|int result from readfile (bytes output to buffer or false if failed) */ public function execute() { $this->checkPerm(); $fullPath = FileSystemTools::build_path($this->Path, "{$this->FileName}"); if (!file_exists($fullPath)) { $this->failed("File '{$fullPath}' doesn't exist"); return false; } $this->step("Reading file '{$fullPath}'"); ob_clean(); Header('Content-Type: text/plain'); $res = readfile($fullPath); if ($res === false) { $this->failed("Failed to read file '{$fullPath}'"); } else { $this->success("Read #{$res} bytes"); } return $res; }
/** * Fetch a file or if no FileName set all files found at remote location. * * @SideEffects: * Writes files to local filesystem * * If all files then don't overwrite existing files, otherwise if a single file then overwrite it every time. * * @return int number of files fetched */ public function execute() { $this->checkPerm(); $transport = Replicant::transportFactory($this->Protocol, $this->RemoteHost, $this->Proxy, $this->UserName, $this->Password); // if we have a FileName then only enqueue that file, otherwise get a list of files from remote host and enqueue all for fetching (existing files won't be refetched in this case). if (!$this->FileName) { $this->step("Fetching file list from '{$this->Protocol}://{$this->UserName}@{$this->RemoteHost}/{$this->Path}'"); try { $files = $transport->fetchFileList($this->Path); } catch (Exception $e) { $this->failed("Failed to get file list: " . $e->getMessage()); return 0; } } else { $fullPath = FileSystemTools::build_path($this->Path, $this->FileName); $this->step("Enqueuing file '{$fullPath}'"); // create the files array as a single entry with path and name $files = array(array('Path' => $this->Path, 'FileName' => $this->FileName)); } $numFiles = count($files); $numFetched = 0; $this->step("Fetching #{$numFiles} files"); foreach ($files as $fileInfo) { // strip off extension here or alpha will reject request $fileName = $fileInfo['FileName']; $remotePathName = FileSystemTools::build_path(Replicant::config()->get('remote_path'), basename($fileName)); $localPathName = FileSystemTools::build_path(Replicant::asset_path(), $fileName); $overwrite = $this->FileName != ''; $this->step("Fetching file '{$remotePathName}' with overwrite (" . ($overwrite ? "set" : "not set") . ")"); try { if (false !== $transport->fetchFile($remotePathName, $localPathName, $overwrite)) { $numFetched++; } } catch (Exception $e) { $this->failed("Failed to fetch file '{$remotePathName}': " . $e->getMessage()); // EARLY EXIT! return false; } } $this->success("Fetched #{$numFetched} files of #{$numFiles}"); return $numFetched; }
ob_start(); $testResult = TestRunner::runTests($folder); $testOutput = ob_get_contents(); ob_end_clean(); if (!$testResult['result']) { $passedAllTests = false; $output[] = "TEST FAILED"; } else { $output[] = "TEST PASSED"; } $output[] = $testOutput; //$output=array_merge($output,$testResult['output']); // CHECK PHP LOG FILE if (!empty(TestConfig::getConfig('testLogFiles'))) { foreach (explode(",", TestConfig::getConfig('testLogFiles')) as $k => $logFile) { $lines = FileSystemTools::checkChangesToFile($snapshots[$logFile], $logFile); if (count($lines) > 0) { $output[] = "-------------------------------------------------"; $output[] = 'LOG FILE ' . $logFile; $output[] = "-------------------------------------------------"; $output = array_merge($output, $lines); $output[] = "-------------------------------------------------"; } } } if (php_sapi_name() == 'cli') { echo "\n" . implode("\n", $output) . "\n"; $output = array(); } // $output=array_merge($output, }
static function runTests($testFolder) { $output = []; // clean staging $cmds = array(); $staging = TestConfig::getConfig('testStagingPath'); //FileSystemTools::setPermissionsAllowEveryone($staging); //FileSystemTools::setPermissionsAllowEveryone(TestConfig::getConfig('testOutputPath')); $passedAllTests = true; // some sanity checking before pruning if (strlen(trim($staging)) > 0) { // clean up staging FileSystemTools::prune($staging); //return array(); // create staging location @mkdir($staging . DS . 'tests', 0777, true); @mkdir($staging . DS . 'tests' . DS . '_support', 0777, true); // copy shared test support files FileSystemTools::copyRecursive(TestConfig::getConfig('testSharedSupportPath'), $staging . DS . 'tests' . DS . '_support'); //return array(); // then copy over the top, test suites etc to staging FileSystemTools::copyRecursive($testFolder, $staging . DS . 'tests'); // ensure required test directories @mkdir($staging . DS . 'tests' . DS . '_support', 0777, true); @mkdir($staging . DS . 'tests' . DS . '_output', 0777, true); @mkdir($staging . DS . 'tests' . DS . '_data', 0777, true); @mkdir($staging . DS . 'tests' . DS . '_support' . DS . 'Helper', 0777, true); TestConfig::writeCodeceptionConfig(); $objects = glob($staging . DS . 'tests' . DS . '*.suite.yml'); if (sizeof($objects) > 0) { foreach ($objects as $file) { if ($file == "." || $file == "..") { continue; } TestConfig::writeWebDriverConfig($file); } } // cm5? if (strlen(trim(TestConfig::getConfig('cmFivePath'))) > 0) { // copy installer sql to test data directory copy(TestConfig::getConfig('cmFivePath') . DS . 'cache' . DS . 'install.sql', $staging . DS . 'tests' . DS . '_data' . DS . 'dump.sql'); // copy c3.php for accptance test coverage if (TestConfig::getConfig('coverage')) { copy(TestConfig::getConfig('testRunnerPath') . DS . 'src' . DS . 'lib' . DS . 'c3.php', TestConfig::getConfig('testRunnerPath') . DS . 'staging' . DS . 'c3.php'); } } // build and run array_push($cmds, array('CODECEPTION BUILD', TestConfig::getConfig('codeception') . ' build ' . ' -c ' . $staging)); $testParam = TestConfig::getConfig('testSuite'); $testParam .= strlen(trim(TestConfig::getConfig('testSuite'))) > 0 ? ' ' . TestConfig::getConfig('test') : ''; // these options conflict with coverage options below so only one set $coverage = ' -d --no-colors --steps '; if (TestConfig::getConfig('coverage')) { //--coverage-xml $coverage = ' --coverage --xml --html --coverage-html --report '; } array_push($cmds, array('CODECEPTION RUN', TestConfig::getConfig('codeception') . ' run ' . $coverage . ' -c ' . $staging . ' ' . $testParam)); foreach ($cmds as $cmd) { if (php_sapi_name() == 'cli') { echo "-------------------------------------------------\n"; echo $cmd[0] . "\n"; echo $cmd[1] . "\n"; echo "-------------------------------------------------\n"; } else { $output[] = "-------------------------------------------------"; $output[] = $cmd[0]; $output[] = $cmd[1]; $output[] = "-------------------------------------------------"; } $handle = popen($cmd[1], "r"); $detailsTest = ''; $errorActive = false; $testType = ''; while (!feof($handle)) { $buffer = fgets($handle); //$buffer = trim(htmlspecialchars($buffer)); if (php_sapi_name() == 'cli') { echo $buffer; } else { $output[] = trim($buffer); } } $exitCode = pclose($handle); if ($exitCode > 0) { $passedAllTests = false; } } // save output files $testSuiteName = str_replace(':', '_', str_replace(DS, '_', $testFolder)); @mkdir(TestConfig::getConfig('testOutputPath') . DS . $testSuiteName); $output[] = "COPY test results from " . $staging . DS . 'tests' . DS . '_output' . " to " . TestConfig::getConfig('testOutputPath') . DS . $testSuiteName; FileSystemTools::copyRecursive($staging . DS . 'tests' . DS . '_output', TestConfig::getConfig('testOutputPath') . DS . $testSuiteName); } // clean up if (strlen(trim(TestConfig::getConfig('testRunnerPath'))) > 0 && file_exists(TestConfig::getConfig("testRunnerPath") . "/staging/c3.php")) { //unlink(TestConfig::getConfig("testRunnerPath")."/staging/c3.php"); } //FileSystemTools::setPermissionsAllowEveryone($staging); //FileSystemTools::setPermissionsAllowEveryone(TestConfig::getConfig('testOutputPath')); return array('output' => $output, 'result' => $passedAllTests); }
static function writeCodeceptionConfig() { // codeception.yml write db parameters $baseFolder = TestConfig::getConfig('testRunnerPath'); // load template $yaml = file_get_contents($baseFolder . DS . 'codeception.template.yml'); $data = Yaml::parse($yaml); // ensure structure in template array if (is_array($data)) { //if (!array_key_exists('modules',$data)) $data['modules']=array(); //if (!array_key_exists('enabled',$data['modules'])) $data['modules']['enabled']=array(); //if (!array_key_exists('Db',$data['modules']['enabled'])) $data['modules']['enabled']['Db']=array(); // set db connection details $portNumber = TestConfig::getConfig('port'); $port = isset($portNumber) && !empty($portNumber) ? ";port=" . $portNumber : ""; $url = TestConfig::getConfig('driver') . ":host=" . TestConfig::getConfig('confighostname') . ";dbname=" . TestConfig::getConfig('database') . $port; //$data['coverage']['include']=[$url]; //$data['coverage']['exclude']=[$url]; $data['modules']['config']['Db']['dsn'] = $url; $data['modules']['config']['Db']['user'] = strlen(trim(TestConfig::getConfig('username'))) > 0 ? TestConfig::getConfig('username') : ''; $data['modules']['config']['Db']['password'] = strlen(trim(TestConfig::getConfig('password'))) > 0 ? TestConfig::getConfig('password') : ''; // disable phantom for unit tests if (TestConfig::getConfig('testSuite') === 'unit') { unset($data['extensions']['enabled'][array_search('Codeception\\Extension\\Phantoman', $data['extensions']['enabled'])]); } else { $data['extensions']['config']['Codeception\\Extension\\Phantoman']['path'] = TestConfig::getConfig('phantomjs'); } // enable coverage if (TestConfig::getConfig('coverage') && TestConfig::getConfig('cmFivePath') && is_dir(TestConfig::getConfig('cmFivePath'))) { $relativePath = FileSystemTools::findRelativePath(realpath(TestConfig::getConfig('testStagingPath')), realpath(TestConfig::getConfig('cmFivePath'))); $data['coverage'] = ['enabled' => 'true', 'remote' => 'false', 'include' => [$relativePath . '\\system\\web*.php', $relativePath . '\\system\\functions*.php', $relativePath . '\\system\\html*.php', $relativePath . '\\system\\classes\\*', $relativePath . '\\system\\modules\\*', $relativePath . '\\modules\\*'], 'exclude' => ['\\*']]; } $yaml = Yaml::dump($data); } $codeceptionFile = TestConfig::getConfig('testStagingPath') . DS . 'codeception.yml'; file_put_contents($codeceptionFile, $yaml); }
protected function _after() { FileSystemTools::rmdirRecursive($this->tmpPath1); FileSystemTools::rmdirRecursive($this->tmpPath2); }
static function prune($dir) { // echo "PRUNE ".$dir."\n"; if (is_dir($dir)) { // echo "PRUNE IS DIR ".$dir."\n"; foreach (glob($dir . '/*') as $file) { // echo "PRUNE INNER ".$file."\n"; if (is_dir($dir . DS . basename($file))) { // echo "PRUNE ISDIR ".$dir.DS.basename($file)."\n"; FileSystemTools::rmdirRecursive($dir . DS . basename($file)); } else { //echo "PRUNE IS FILE".$dir.DS.basename($file)."\n"; unlink($dir . DS . basename($file)); } } } }