public function __construct() { $this->BuildId = 0; $this->Checker = ''; $this->NumDefects = 0; $this->PDO = get_link_identifier()->getPdo(); }
public function testImageComparison() { // Submit test data. if (!$this->submission('InsightExample', dirname(__FILE__) . '/data/ImageComparisonTest.xml')) { $this->fail('Failed to submit test data'); return 1; } // Get the images created by this test. $pdo = get_link_identifier()->getPdo(); $stmt = $pdo->query("SELECT b.id AS buildid, i.id AS imgid FROM build b\n JOIN build2test b2t ON (b2t.buildid=b.id)\n JOIN test2image t2i ON (b2t.testid=t2i.testid)\n JOIN image i ON (i.id=t2i.imgid)\n WHERE b.name='image_comparison'"); $imgids = array(); $buildid = 0; while ($row = $stmt->fetch()) { $buildid = $row['buildid']; $imgids[] = $row['imgid']; } $num_imgs = count($imgids); if ($num_imgs !== 3) { $this->fail("Expected 3 images, found {$num_imgs}"); } foreach ($imgids as $imgid) { $image = new Image(); $image->Id = $imgid; $image->Load(); if (imagecreatefromstring($image->Data) === false) { $this->fail("Image {$imgid} is corrupted"); } } remove_build($buildid); }
public function testNoBackup() { // Enable config setting. $this->addLineToConfig($this->ConfigLine); // Submit XML file. $xml = dirname(__FILE__) . '/data/nobackup/Build.xml'; if (!$this->submission('InsightExample', $xml)) { $this->fail('failed to submit Build.xml'); return 1; } // Submit gcov.tar to test the 'PUT' submission path. $post_result = $this->post($this->url . '/submit.php', array('project' => 'InsightExample', 'build' => 'nobackup', 'site' => 'localhost', 'stamp' => '20161004-0500-Nightly', 'starttime' => '1475599870', 'endtime' => '1475599870', 'track' => 'Nightly', 'type' => 'GcovTar', 'datafilesmd5[0]=' => '5454e16948a1d58d897e174b75cc5633')); $post_json = json_decode($post_result, true); if ($post_json['status'] != 0) { $this->fail('POST returned ' . $post_json['status'] . ":\n" . $post_json['description'] . "\n"); return 1; } $buildid = $post_json['buildid']; if (!is_numeric($buildid) || $buildid < 1) { $this->fail("Expected positive integer for buildid, instead got {$buildid}"); return 1; } $puturl = $this->url . "/submit.php?type=GcovTar&md5=5454e16948a1d58d897e174b75cc5633&filename=gcov.tar&buildid={$buildid}"; $filename = dirname(__FILE__) . '/data/gcov.tar'; $put_result = $this->uploadfile($puturl, $filename); $put_json = json_decode($put_result, true); if ($put_json['status'] != 0) { $this->fail('PUT returned ' . $put_json['status'] . ":\n" . $put_json['description'] . "\n"); return 1; } // Make sure they were both parsed correctly. echo "Waiting for async processing (2 seconds)\n"; sleep(2); $pdo = get_link_identifier()->getPdo(); $stmt = $pdo->prepare('SELECT b.builderrors, cs.loctested FROM build b JOIN coveragesummary cs ON (cs.buildid=b.id) WHERE b.id=?'); $stmt->execute(array($buildid)); $row = $stmt->fetch(); if ($row['builderrors'] != 0) { $this->fail("Unexpected number of build errors found"); } if ($row['loctested'] < 1) { $this->fail("Unexpected number of loctested found"); } $this->checkLog($this->logfilename); // Cleanup $this->removeLineFromConfig($this->ConfigLine); remove_build($buildid); }
public function testExportToCSV() { // Get the ID of a build that has tests. $pdo = get_link_identifier()->getPdo(); $stmt = $pdo->prepare("\n SELECT b.id FROM build b\n JOIN build2test b2t ON b2t.buildid=b.id\n JOIN test t ON t.id=b2t.testid\n WHERE b.name='Win32-MSVC2009' AND t.name='curl'"); $stmt->execute(); $row = $stmt->fetch(); $buildid = $row['id']; // Export this build's tests to CSV. $content = $this->connect($this->url . "/api/v1/viewTest.php?buildid={$buildid}&export=csv"); // Verify expected contents. $expected = 'DashboardSendTest,0.05,"Completed (OTHER_FAULT)",Failed'; if (strpos($content, $expected) === false) { $this->fail("Expected content not found in CSV output"); } }
public function testUniqueDiffsUpgrade() { require_once 'include/upgrade_functions.php'; global $CDASH_DB_TYPE; $pdo = get_link_identifier()->getPdo(); $tables = ['test_builderrordiff', 'test_configureerrordiff', 'test_testdiff']; foreach ($tables as $table) { // Create testing tables. if ($CDASH_DB_TYPE == 'pgsql') { $create_query = ' CREATE TABLE "' . $table . '" ( "buildid" integer NOT NULL, "type" smallint NOT NULL, "difference" integer NOT NULL )'; } else { // MySQL $create_query = "\n CREATE TABLE `{$table}` (\n `buildid` int(11) NOT NULL,\n `type` tinyint(4) NOT NULL,\n `difference` int(11) NOT NULL,\n KEY `buildid` (`buildid`),\n KEY `type` (`type`)\n )"; } if (!$pdo->query($create_query)) { $this->fail("Error creating {$table}"); } // Insert duplicate data into each. $stmt = $pdo->prepare("INSERT INTO {$table} (buildid, type, difference)\n VALUES (?, 0, 1)"); $stmt->execute([$this->BuildId]); $stmt = $pdo->prepare("INSERT INTO {$table} (buildid, type, difference)\n VALUES (?, 0, 2)"); $stmt->execute([$this->BuildId]); // Verify duplicate was inserted successfully. $this->checkRowCount($pdo, $table, 2); } // Run the upgrade function. AddUniqueConstraintToDiffTables(true); foreach ($tables as $table) { // Verify that each table only has one row. $this->checkRowCount($pdo, $table, 1); // Drop the testing tables. $pdo->query("DROP TABLE {$table}"); } }
public static function getNotesForBuild($buildid) { if (!$buildid) { return; } $pdo = get_link_identifier()->getPdo(); $stmt = $pdo->prepare('SELECT * FROM buildnote WHERE buildid=? ORDER BY timestamp ASC'); $stmt->execute(array($buildid)); $notes = array(); while ($row = $stmt->fetch()) { $note = new BuildUserNote(); $note->BuildId = $buildid; $note->UserId = $row['userid']; $note->Note = $row['note']; $note->TimeStamp = $row['timestamp']; $note->Status = $row['status']; $notes[] = $note; } return $notes; }
/** Returns true and sets loginerror if the user's account is locked out. * Unlocks the account if the expiration time has already passed. */ function accountIsLocked($userid) { global $CDASH_LOCKOUT_ATTEMPTS; if ($CDASH_LOCKOUT_ATTEMPTS == 0) { return false; } global $loginerror; $loginerror = ''; $pdo = get_link_identifier()->getPdo(); $pdo->beginTransaction(); $stmt = $pdo->prepare('SELECT islocked, unlocktime FROM lockout WHERE userid=?'); if (!$stmt->execute(array($userid))) { $pdo->rollBack(); return false; } $row = $stmt->fetch(); if ($row['islocked'] == 1) { $now = strtotime(gmdate(FMT_DATETIME)); $unlocktime = strtotime($row['unlocktime']); if ($now > $unlocktime) { // Lockout period has expired. $stmt = $pdo->prepare("UPDATE lockout SET failedattempts = 0,\n islocked = 0, unlocktime = '1980-01-01 00:00:00'\n WHERE userid=?"); if (!$stmt->execute(array($userid))) { $pdo->rollBack(); return false; } } else { // Account still locked. $num_minutes = round(($unlocktime - $now) / 60, 0) + 1; $loginerror = "Your account is locked due to failed login attempts. Please try again in {$num_minutes} minutes."; $pdo->commit(); return true; } } $pdo->commit(); return false; }
/** Load the image from the database. */ public function Load() { if (!$this->Exists()) { return false; } $pdo = get_link_identifier()->getPdo(); $stmt = $pdo->prepare('SELECT * FROM image WHERE id=?'); $stmt->execute([$this->Id]); $row = $stmt->fetch(); $this->Extension = $row['extension']; $this->Checksum = $row['checksum']; global $CDASH_DB_TYPE; if ($CDASH_DB_TYPE == 'pgsql') { $this->Data = stream_get_contents($row['img']); } else { $this->Data = $row['img']; } }
if ($build->ProjectId < 1) { return; } // Take subproject into account, such that if there is one, then the // previous builds must be associated with the same subproject. // $subproj_table = ''; $subproj_criteria = ''; if ($build->SubProjectId > 0) { $subproj_table = 'INNER JOIN subproject2build AS sp2b ON (b.id=sp2b.buildid)'; $subproj_criteria = 'AND sp2b.subprojectid=:subprojectid'; } // Get details about previous builds. // Currently just grabbing the info used for the graphs and charts // on buildSummary.php. $pdo = get_link_identifier()->getPdo(); $stmt = $pdo->prepare("SELECT b.id, nfiles, configureerrors, configurewarnings,\n buildwarnings, builderrors, testfailed, b.starttime, b.endtime\n FROM build AS b\n LEFT JOIN build2update AS b2u ON (b2u.buildid=b.id)\n LEFT JOIN buildupdate AS bu ON (b2u.updateid=bu.id)\n {$subproj_table}\n WHERE siteid=:siteid AND b.type=:type AND name=:name AND\n projectid=:projectid AND b.starttime<=:starttime\n {$subproj_criteria}\n ORDER BY starttime ASC LIMIT 50"); $stmt->bindParam(':siteid', $build->SiteId); $stmt->bindParam(':type', $build->Type); $stmt->bindParam(':name', $build->Name); $stmt->bindParam(':projectid', $build->ProjectId); $stmt->bindParam(':starttime', $build->StartTime); if ($build->SubProjectId > 0) { $stmt->bindParam(':subprojectid', $build->SubProjectId); } $stmt->execute(); $builds_response = array(); while ($previous_build_row = $stmt->fetch()) { $build_response = array(); $build_response['id'] = $previous_build_row['id']; $build_response['nfiles'] = $previous_build_row['nfiles'];
public function Load() { global $CDASH_USE_COMPRESSION; if (!$this->Id) { return false; } $pdo = get_link_identifier()->getPdo(); $stmt = $pdo->prepare('SELECT * FROM coveragefile WHERE id=:id'); $stmt->bindParam(':id', $this->Id); $stmt->execute(); $row = $stmt->fetch(); if (!array_key_exists('id', $row)) { return false; } $this->FullPath = $row['fullpath']; $this->Crc32 = $row['crc32']; if ($CDASH_USE_COMPRESSION) { if (is_resource($row['file'])) { $this->File = base64_decode(stream_get_contents($row['file'])); } else { $this->File = base64_decode($row['file']); } @($uncompressedrow = gzuncompress($this->File)); if ($uncompressedrow !== false) { $this->File = $uncompressedrow; } } else { $this->File = $row['file']; } return true; }
public function RemoveBlockedBuild($id) { $pdo = get_link_identifier()->getPdo(); $stmt = $pdo->prepare('DELETE FROM blockbuild WHERE id=?'); $stmt->execute(array($id)); }
/** Add the difference between the numbers of tests * for the previous and current build */ function compute_test_difference($buildid, $previousbuildid, $testtype, $projecttestmaxstatus) { $pdo = get_link_identifier()->getPdo(); $extra_sql = ''; if ($testtype == 0) { $status = 'notrun'; } elseif ($testtype == 1) { $status = 'failed'; } elseif ($testtype == 2) { $status = 'passed'; } elseif ($testtype == 3) { $status = 'passed'; $extra_sql = " AND timestatus > {$projecttestmaxstatus}"; } // Look at the difference positive and negative test errors $stmt = $pdo->prepare("UPDATE build2test SET newstatus=1 WHERE buildid=:buildid AND testid IN\n (SELECT testid FROM (SELECT test.id AS testid,name FROM build2test,test WHERE build2test.buildid=:buildid\n AND build2test.testid=test.id AND build2test.status=:status {$extra_sql}) AS testa\n LEFT JOIN (SELECT name as name2 FROM build2test,test WHERE build2test.buildid=:previousbuildid\n AND build2test.testid=test.id AND build2test.status=:status {$extra_sql})\n AS testb ON testa.name=testb.name2 WHERE testb.name2 IS NULL)"); $stmt->bindParam(':buildid', $buildid); $stmt->bindParam(':previousbuildid', $previousbuildid); $stmt->bindParam(':status', $status); if (!$stmt->execute()) { add_last_sql_error('compute_test_difference', 0, $buildid); } // Maybe we can get that from the query (don't know). $stmt = $pdo->prepare("SELECT COUNT(*) FROM build2test WHERE buildid=:buildid AND newstatus=1 AND status=:status {$extra_sql}"); $stmt->bindParam(':buildid', $buildid); $stmt->bindParam(':status', $status); $stmt->execute(); $row = $stmt->fetch(); $npositives = $row[0]; // Count the difference between the number of tests that were passing (or failing) // and now that have a different one $stmt = $pdo->prepare("SELECT COUNT(*) FROM\n (SELECT name FROM build2test,test WHERE build2test.buildid=:previousbuildid AND\n build2test.testid=test.id AND build2test.status=:status {$extra_sql}) AS testa\n LEFT JOIN (SELECT name as name2 FROM build2test,test WHERE build2test.buildid=:buildid\n AND build2test.testid=test.id AND build2test.status=:status {$extra_sql})\n AS testb ON testa.name=testb.name2 WHERE testb.name2 IS NULL"); $stmt->bindParam(':buildid', $buildid); $stmt->bindParam(':previousbuildid', $previousbuildid); $stmt->bindParam(':status', $status); $stmt->execute(); $row = $stmt->fetch(); $nnegatives = $row[0]; // Check that we don't have any duplicates (this messes up index.php). $pdo->beginTransaction(); $stmt = $pdo->prepare('SELECT * FROM testdiff WHERE buildid=:buildid AND type=:type FOR UPDATE'); $stmt->bindParam(':buildid', $buildid); $stmt->bindParam(':type', $testtype); $stmt->execute(); $row = $stmt->fetch(); $existing_npositives = 0; $existing_nnegatives = 0; if ($row) { $existing_npositives = $row['difference_positive']; $existing_nnegatives = $row['difference_negative']; } // Don't log if no diff. if ($npositives == 0 && $nnegatives == 0 && $existing_npositives == 0 && $existing_nnegatives == 0) { $pdo->commit(); return; } if ($row) { // Update existing record. $stmt = $pdo->prepare('UPDATE testdiff SET difference_positive=:npositives, difference_negative=:nnegatives WHERE buildid=:buildid AND type=:type'); } else { // Insert new record. $duplicate_sql = ''; global $CDASH_DB_TYPE; if ($CDASH_DB_TYPE !== 'pgsql') { $duplicate_sql = 'ON DUPLICATE KEY UPDATE difference_positive=:npositives, difference_negative=:nnegatives'; } $stmt = $pdo->prepare("INSERT INTO testdiff\n (buildid, type, difference_positive, difference_negative)\n VALUES (:buildid, :type, :npositives, :nnegatives)\n {$duplicate_sql}"); } $stmt->bindParam(':buildid', $buildid); $stmt->bindParam(':type', $testtype); $stmt->bindParam(':npositives', $npositives); $stmt->bindParam(':nnegatives', $nnegatives); if (!$stmt->execute()) { add_last_sql_error('compute_test_difference', 0, $buildid); $pdo->rollBack(); return; } $pdo->commit(); }
function perform_github_version_only_diff($project, $update, $previous_revision) { require_once 'include/memcache_functions.php'; global $CDASH_MEMCACHE_ENABLED, $CDASH_MEMCACHE_PREFIX, $CDASH_MEMCACHE_SERVER; $current_revision = $update->Revision; // Check if we have a Github account associated with this project. // If so, we are much less likely to get rate-limited by the API. $auth = array(); $repositories = $project->GetRepositories(); foreach ($repositories as $repo) { if (strlen($repo['username']) > 0 && strlen($repo['password']) > 0) { $auth = ['auth' => [$repo['username'], $repo['password']]]; break; } } // Connect to memcache. if ($CDASH_MEMCACHE_ENABLED) { list($server, $port) = $CDASH_MEMCACHE_SERVER; $memcache = cdash_memcache_connect($server, $port); // Disable memcache for this request if it fails to connect. if ($memcache === false) { $CDASH_MEMCACHE_ENABLED = false; } } // Check if we've memcached the difference between these two revisions. $diff_response = null; $diff_key = "{$CDASH_MEMCACHE_PREFIX}:{$project->Name}:{$current_revision}:{$previous_revision}"; if ($CDASH_MEMCACHE_ENABLED) { $cached_response = cdash_memcache_get($memcache, $diff_key); if ($cached_response !== false) { $diff_response = $cached_response; } } if (is_null($diff_response)) { // Use the GitHub API to find what changed between these two revisions. // This API endpoint takes the following form: // GET /repos/:owner/:repo/compare/:base...:head $base_api_url = get_github_api_url($project->CvsUrl); $client = new GuzzleHttp\Client(); $api_url = "{$base_api_url}/compare/{$previous_revision}...{$current_revision}"; try { $response = $client->request('GET', $api_url, $auth); } catch (GuzzleHttp\Exception\ClientException $e) { // Typically this occurs due to a local commit that GitHub does not // know about. add_log($e->getMessage(), "perform_github_version_only_diff", LOG_WARNING, $project->Id); return; } $diff_response = strval($response->getBody()); // Cache the response from the GitHub API for 24 hours. if ($CDASH_MEMCACHE_ENABLED) { cdash_memcache_set($memcache, $diff_key, $diff_response, 60 * 60 * 24); } } $response_array = json_decode($diff_response, true); // To do anything meaningful here our response needs to tell us about commits // and the files that changed. Abort early if either of these pieces of // information are missing. if (!is_array($response_array) || !array_key_exists('commits', $response_array) || !array_key_exists('files', $response_array)) { return; } // Discard merge commits. We want to assign credit to the author who did // the actual work, not the approver who clicked the merge button. foreach ($response_array['commits'] as $idx => $commit) { if (strpos($commit['commit']['message'], 'Merge pull request') !== false) { unset($response_array['commits'][$idx]); } } // If we still have more than one commit, we'll need to perform follow-up // API calls to figure out which commit was likely responsible for each // changed file. $multiple_commits = false; if (count($response_array['commits']) > 1) { $multiple_commits = true; // Generate list of commits contained by this changeset in reverse order // (most recent first). $list_of_commits = array_reverse($response_array['commits']); // Also maintain a local cache of what files were changed by each commit. // This prevents us from hitting the GitHub API more than necessary. $cached_commits = array(); } $pdo = get_link_identifier()->getPdo(); // Find the commit that changed each file. foreach ($response_array['files'] as $modified_file) { if ($multiple_commits) { // Find the most recent commit that changed this file. $commit = null; // First check our local cache. foreach ($cached_commits as $sha => $files) { if (in_array($modified_file['filename'], $files)) { $idx = array_search($sha, array_column($list_of_commits, 'sha')); $commit = $list_of_commits[$idx]; break; } } if (is_null($commit)) { // Next, check the database. $stmt = $pdo->prepare('SELECT DISTINCT revision FROM updatefile WHERE filename=?'); $stmt->execute(array($modified_file['filename'])); while ($row = $stmt->fetch()) { foreach ($list_of_commits as $c) { if ($row['revision'] == $c['sha']) { $commit = $c; break; } } if (!is_null($commit)) { break; } } } if (is_null($commit)) { // Lastly, use the Github API to find what files this commit changed. // To avoid being rate-limited, we only perform this lookup once // per commit, caching the results as we go. foreach ($list_of_commits as $c) { $sha = $c['sha']; if (array_key_exists($sha, $cached_commits)) { // We already looked up this commit. // Apparently it didn't modify the file we're looking for. continue; } $commit_response = null; $commit_key = "{$CDASH_MEMCACHE_PREFIX}:{$project->Name}:{$sha}"; if ($CDASH_MEMCACHE_ENABLED) { // Check memcache if it is enabled before hitting // the GitHub API. $cached_response = cdash_memcache_get($memcache, $commit_key); if ($cached_response !== false) { $commit_response = $cached_response; } } if (is_null($commit_response)) { $api_url = "{$base_api_url}/commits/{$sha}"; try { $r = $client->request('GET', $api_url, $auth); } catch (GuzzleHttp\Exception\ClientException $e) { add_log($e->getMessage(), "perform_github_version_only_diff", LOG_ERROR, $project->Id); break; } $commit_response = strval($r->getBody()); if ($CDASH_MEMCACHE_ENABLED) { // Cache this response for 24 hours. cdash_memcache_set($memcache, $commit_key, $commit_response, 60 * 60 * 24); } } $commit_array = json_decode($commit_response, true); if (!is_array($commit_array) || !array_key_exists('files', $commit_array)) { // Skip to the next commit if no list of files was returned. $cached_commits[$sha] = array(); continue; } // Locally cache what files this commit changed. $cached_commits[$sha] = array_column($commit_array['files'], 'filename'); // Check if this commit modified the file in question. foreach ($commit_array['files'] as $file) { if ($file['filename'] === $modified_file['filename']) { $commit = $c; break; } } if (!is_null($commit)) { // Stop examining commits once we find one that matches. break; } } } if (is_null($commit)) { // Skip this file if we couldn't find a commit that modified it. continue; } } else { $commit = $response_array['commits'][0]; } // Record this modified file as part of the changeset. $updateFile = new BuildUpdateFile(); $updateFile->Filename = $modified_file['filename']; $updateFile->CheckinDate = $commit['commit']['author']['date']; $updateFile->Author = $commit['commit']['author']['name']; $updateFile->Email = $commit['commit']['author']['email']; $updateFile->Committer = $commit['commit']['committer']['name']; $updateFile->CommitterEmail = $commit['commit']['committer']['email']; $updateFile->Log = $commit['commit']['message']; $updateFile->Revision = $commit['sha']; $updateFile->PriorRevision = $previous_revision; $updateFile->Status = 'MODIFIED'; $update->AddFile($updateFile); } $update->Insert(); return true; }
public function Insert() { if ($this->Exists()) { return true; } include 'config/config.php'; $command = pdo_real_escape_string($this->Command); $name = pdo_real_escape_string($this->Name); $path = pdo_real_escape_string($this->Path); $details = pdo_real_escape_string($this->Details); $id = ''; $idvalue = ''; if ($this->Id) { $id = 'id,'; $idvalue = "'" . $this->Id . "',"; } if ($this->CompressedOutput) { if ($CDASH_DB_TYPE == 'pgsql') { $output = $this->Output; } else { $output = base64_decode($this->Output); } } elseif ($CDASH_USE_COMPRESSION) { $output = gzcompress($this->Output); if ($output === false) { $output = $this->Output; } else { if ($CDASH_DB_TYPE == 'pgsql') { if (strlen($this->Output) < 2000) { // compression doesn't help for small chunk $output = $this->Output; } $output = base64_encode($output); } } } else { $output = $this->Output; } // We check for mysql that the if ($CDASH_DB_TYPE == '' || $CDASH_DB_TYPE == 'mysql') { $query = pdo_query("SHOW VARIABLES LIKE 'max_allowed_packet'"); $query_array = pdo_fetch_array($query); $max = $query_array[1]; if (strlen($this->Output) > $max) { add_log('Output is bigger than max_allowed_packet', 'Test::Insert', LOG_ERR, $this->ProjectId); // We cannot truncate the output because it is compressed (too complicated) } } $pdo = get_link_identifier()->getPdo(); if ($this->Id) { $stmt = $pdo->prepare(' INSERT INTO test (id, projectid, crc32, name, path, command, details, output) VALUES (:id, :projectid, :crc32, :name, :path, :command, :details, :output)'); $stmt->bindParam(':id', $this->Id); $stmt->bindParam(':projectid', $this->ProjectId); $stmt->bindParam(':crc32', $this->Crc32); $stmt->bindParam(':name', $name); $stmt->bindParam(':path', $path); $stmt->bindParam(':command', $command); $stmt->bindParam(':details', $details); $stmt->bindParam(':output', $output, PDO::PARAM_LOB); $success = $stmt->execute(); } else { $stmt = $pdo->prepare(' INSERT INTO test (projectid, crc32, name, path, command, details, output) VALUES (:projectid, :crc32, :name, :path, :command, :details, :output)'); $stmt->bindParam(':projectid', $this->ProjectId); $stmt->bindParam(':crc32', $this->Crc32); $stmt->bindParam(':name', $name); $stmt->bindParam(':path', $path); $stmt->bindParam(':command', $command); $stmt->bindParam(':details', $details); $stmt->bindParam(':output', $output, PDO::PARAM_LOB); $success = $stmt->execute(); $this->Id = pdo_insert_id('test'); } if (!$success) { add_last_sql_error("Cannot insert test: {$name} into the database", $this->ProjectId); return false; } // Add the measurements foreach ($this->Measurements as $measurement) { $measurement->TestId = $this->Id; $measurement->Insert(); } // Add the images foreach ($this->Images as $image) { // Decode the data $imgStr = base64_decode($image->Data); $img = imagecreatefromstring($imgStr); ob_start(); switch ($image->Extension) { case 'image/jpg': imagejpeg($img); break; case 'image/jpeg': imagejpeg($img); break; case 'image/gif': imagegif($img); break; case 'image/png': imagepng($img); break; default: echo "Unknown image type: {$type}"; return; } $imageVariable = ob_get_contents(); ob_end_clean(); $image->Data = $imageVariable; $image->Checksum = crc32($imageVariable); $image->Save(); $testImage = new TestImage(); $testImage->Id = $image->Id; $testImage->TestId = $this->Id; $testImage->Role = $image->Name; $testImage->Insert(); } return true; }
public function testCleanup() { // Delete users created by this test. foreach ($this->Users as $user) { $user->Delete(); } // Delete builds. $pdo = get_link_identifier()->getPdo(); $stmt = $pdo->prepare("SELECT id FROM build WHERE name='GithubUserStats'"); $stmt->execute(); while ($row = $stmt->fetch()) { remove_build($row['id']); } // Delete project. $this->deleteProject($this->ProjectId); }
/** Helper function for AddUpdateStatistics */ private function AddUpdateStatistics($author, $email, $checkindate, $firstbuild, $warningdiff, $errordiff, $testdiff) { $pdo = get_link_identifier()->getPdo(); // Find user by email address. $user_table = qid('user'); $stmt = $pdo->prepare("SELECT id FROM {$user_table} WHERE email=?"); $stmt->execute(array($email)); $row = $stmt->fetch(); if ($row) { $userid = $row['id']; } else { // Find user by author name. $stmt = $pdo->prepare('SELECT up.userid FROM user2project AS up JOIN user2repository AS ur ON (ur.userid=up.userid) WHERE up.projectid=:projectid AND (ur.credential=:author OR ur.credential=:email) AND (ur.projectid=0 OR ur.projectid=:projectid)'); $stmt->bindParam(':projectid', $this->ProjectId); $stmt->bindParam(':author', $author); $stmt->bindParam(':email', $email); $stmt->execute(); $row = $stmt->fetch(); if (!$row) { // Unable to find user, return early. return; } $userid = $row['userid']; } $totalbuilds = 0; if ($firstbuild == 1) { $totalbuilds = 1; } // Convert errordiff to nfailederrors & nfixederrors (etc). $nfailedwarnings = 0; $nfixedwarnings = 0; $nfailederrors = 0; $nfixederrors = 0; $nfailedtests = 0; $nfixedtests = 0; if ($warningdiff > 0) { $nfailedwarnings = $warningdiff; } else { $nfixedwarnings = abs($warningdiff); } if ($errordiff > 0) { $nfailederrors = $errordiff; } else { $nfixederrors = abs($errordiff); } if ($testdiff > 0) { $nfailedtests = $testdiff; } else { $nfixedtests = abs($testdiff); } // Insert or update appropriately. $pdo->beginTransaction(); $stmt = $pdo->prepare('SELECT totalupdatedfiles FROM userstatistics WHERE userid=:userid AND projectid=:projectid AND checkindate=:checkindate FOR UPDATE'); $stmt->bindParam(':userid', $userid); $stmt->bindParam(':projectid', $this->ProjectId); $stmt->bindParam(':checkindate', $checkindate); $stmt->execute(); $row = $stmt->fetch(); if ($row) { // Update existing entry. $stmt = $pdo->prepare('UPDATE userstatistics SET totalupdatedfiles=totalupdatedfiles+1, totalbuilds=totalbuilds+:totalbuilds, nfixedwarnings=nfixedwarnings+:nfixedwarnings, nfailedwarnings=nfailedwarnings+:nfailedwarnings, nfixederrors=nfixederrors+:nfixederrors, nfailederrors=nfailederrors+:nfailederrors, nfixedtests=nfixedtests+:nfixedtests, nfailedtests=nfailedtests+:nfailedtests WHERE userid=:userid AND projectid=:projectid AND checkindate>=:checkindate'); $stmt->bindParam(':totalbuilds', $totalbuilds); $stmt->bindParam(':nfixedwarnings', $nfixedwarnings); $stmt->bindParam(':nfailedwarnings', $nfailedwarnings); $stmt->bindParam(':nfixederrors', $nfixederrors); $stmt->bindParam(':nfailederrors', $nfailederrors); $stmt->bindParam(':nfixedtests', $nfixedtests); $stmt->bindParam(':nfailedtests', $nfailedtests); $stmt->bindParam(':userid', $userid); $stmt->bindParam(':projectid', $this->ProjectId); $stmt->bindParam(':checkindate', $checkindate); $stmt->execute(); add_last_sql_error('Build:AddUpdateStatistics', $this->ProjectId, $this->Id); } else { // Insert a new row into the database. $stmt = $pdo->prepare('INSERT INTO userstatistics (userid,projectid,checkindate,totalupdatedfiles,totalbuilds, nfixedwarnings,nfailedwarnings,nfixederrors,nfailederrors, nfixedtests,nfailedtests) VALUES (:userid,:projectid,:checkindate,1,:totalbuilds, :nfixedwarnings,:nfailedwarnings,:nfixederrors, :nfailederrors,:nfixedtests,:nfailedtests)'); $stmt->bindParam(':userid', $userid); $stmt->bindParam(':projectid', $this->ProjectId); $stmt->bindParam(':checkindate', $checkindate); $stmt->bindParam(':totalbuilds', $totalbuilds); $stmt->bindParam(':nfixedwarnings', $nfixedwarnings); $stmt->bindParam(':nfailedwarnings', $nfailedwarnings); $stmt->bindParam(':nfixederrors', $nfixederrors); $stmt->bindParam(':nfailederrors', $nfailederrors); $stmt->bindParam(':nfixedtests', $nfixedtests); $stmt->bindParam(':nfailedtests', $nfailedtests); $stmt->execute(); add_last_sql_error('Build:AddUpdateStatistics', $this->ProjectId, $this->Id); } $pdo->commit(); }
/** * Roll back a transaction with PDO. * @param PDO|null $link_identifier */ function pdo_rollback($link_identifier = null) { get_link_identifier($link_identifier)->getPdo()->rollBack(); }
function AddUniqueConstraintToDiffTables($testing = false) { global $CDASH_DB_TYPE; $prefix = ''; if ($testing) { $prefix = 'test_'; } $tables = [$prefix . 'builderrordiff', $prefix . 'configureerrordiff', $prefix . 'testdiff']; $pdo = get_link_identifier()->getPdo(); foreach ($tables as $table) { // Find all the rows that will violate this new unique constraint. $rows = $pdo->query("SELECT buildid, type, COUNT(*) AS c FROM {$table}\n GROUP BY buildid, type HAVING COUNT(*) > 1"); foreach ($rows as $row) { // Remove duplicates by deleting all but one row. $buildid = $row['buildid']; $type = $row['type']; $limit = $row['c'] - 1; if ($CDASH_DB_TYPE == 'pgsql') { // Postgres doesn't allow DELETE with LIMIT, so we use // ctid to get around this limitation. $delete_stmt = $pdo->prepare("DELETE FROM {$table} WHERE ctid IN\n (SELECT ctid FROM {$table}\n WHERE buildid=:buildid AND type=:type\n LIMIT {$limit})"); } else { $delete_stmt = $pdo->prepare("DELETE FROM {$table} WHERE buildid=:buildid AND type=:type\n LIMIT {$limit}"); } $delete_stmt->bindParam(':buildid', $buildid); $delete_stmt->bindParam(':type', $type); $delete_stmt->execute(); } // It should be safe to add the constraints now. if ($CDASH_DB_TYPE == 'pgsql') { $pdo->query("ALTER TABLE {$table} ADD UNIQUE (buildid,type)"); $index_name = $table . '_buildid_type'; $pdo->query("CREATE INDEX \"{$index_name}\" ON \"{$table}\" (\"buildid\",\"type\")"); } else { $pdo->query("ALTER TABLE {$table} ADD UNIQUE KEY (buildid,type)"); } } }
/** */ function pdo_select_db($database_name, &$link_identifier) { global $CDASH_DB_TYPE; if (isset($CDASH_DB_TYPE) && $CDASH_DB_TYPE != "mysql") { global $db_server, $db_username, $db_password, $last_link, $db_port; $dsn = "{$CDASH_DB_TYPE}:host={$db_server};dbname={$database_name}"; if (!empty($db_port)) { $dsn .= ';port=' . $db_port; } try { $last_link = $link_identifier = new PDO($dsn, $db_username, $db_password); /*if($CDASH_DB_TYPE == "mysql") // necessary for looping through rows { $link_identifier->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, true); }*/ pdo_query("SET client_encoding to 'UTF8'"); return true; } catch (PDOException $e) { //print_r($e); // Add debug information return false; } } else { $ln = get_link_identifier($link_identifier); $db = mysql_select_db($database_name, $ln); if (PHP_VERSION >= 5.3) { mysql_set_charset('utf8', $ln); } else { mysql_query("SET NAMES 'utf8'"); } return $db; } }
public function Delete() { if (!$this->Id) { return false; } $pdo = get_link_identifier()->getPdo(); $user_table = qid('user'); $stmt = $pdo->prepare("DELETE FROM {$user_table} WHERE id=?"); $stmt->execute(array($this->Id)); }