/** endElement function */ public function endElement($parser, $name) { parent::endElement($parser, $name); if ($name == 'NOTE') { $this->Build->ProjectId = $this->projectid; $this->Build->GetIdFromName($this->SubProjectName); $this->Build->RemoveIfDone(); // If the build doesn't exist we add it. if ($this->Build->Id == 0) { $this->Build->SetSubProject($this->SubProjectName); // Since we only have precision in minutes (not seconds) here, // set the start time at the end of the minute so it can be overridden // by any more precise XML file received later. $start_time = gmdate(FMT_DATETIME, strtotime($this->Note->Time) + 59); $this->Build->StartTime = $start_time; $this->Build->EndTime = $this->Note->Time; $this->Build->SubmitTime = gmdate(FMT_DATETIME); $this->Build->InsertErrors = false; add_build($this->Build, $this->scheduleid); } if ($this->Build->Id > 0) { // Insert the note $this->Note->BuildId = $this->Build->Id; $this->Note->Insert(); } else { add_log('Trying to add a note to a nonexistent build', 'note_handler.php', LOG_ERR); } } }
function store_results($db, $master, $builder_name, $build_number, $start_time, $end_time, $revisions, $json_path) { $test_results = fetch_and_parse_test_results_json($json_path); if (!$test_results) { exit_with_error('InvalidResultsJSON'); } $builder_id = add_builder($db, $master, $builder_name); if (!$builder_id) { exit_with_error('FailedToInsertBuilder', array('master' => $master, 'builderName' => $builder_name)); } $slave_id = add_slave($db, $_POST['build_slave']); $build_id = add_build($db, $builder_id, $build_number, $slave_id); if (!$build_id) { exit_with_error('FailedToInsertBuild', array('builderId' => $builder_id, 'buildNumber' => $build_number)); } foreach ($revisions as $repository_name => $revision_data) { $repository_id = $db->select_or_insert_row('repositories', NULL, array('name' => $repository_name)); if (!$repository_id) { exit_with_error('FailedToInsertRepository', array('name' => $repository_name)); } $revision_data = array('repository' => $repository_id, 'build' => $build_id, 'value' => $revision_data['revision'], 'time' => array_get($revision_data, 'timestamp')); $db->select_or_insert_row('build_revisions', NULL, array('repository' => $repository_id, 'build' => $build_id), $revision_data, 'value') or exit_with_error('FailedToInsertRevision', array('name' => $repository_name, 'data' => $revision_data)); } if (!store_test_results($db, $test_results, $build_id, $start_time, $end_time)) { exit_with_error('FailedToStoreResults', array('buildId' => $build_id)); } }
/** End element */ public function endElement($parser, $name) { parent::endElement($parser, $name); if ($name == 'SITE') { $this->Site->Insert(); } else { if ($name == 'UPDATE') { $this->Build->SiteId = $this->Site->Id; $start_time = gmdate(FMT_DATETIME, $this->StartTimeStamp); $end_time = gmdate(FMT_DATETIME, $this->EndTimeStamp); $submit_time = gmdate(FMT_DATETIME); $this->Build->ProjectId = $this->projectid; $buildid = $this->Build->GetIdFromName($this->SubProjectName); // If the build doesn't exist we add it if ($buildid == 0) { $this->Build->ProjectId = $this->projectid; $this->Build->StartTime = $start_time; $this->Build->EndTime = $end_time; $this->Build->SubmitTime = $submit_time; $this->Build->InsertErrors = false; add_build($this->Build, $this->scheduleid); $buildid = $this->Build->Id; } else { $this->Build->Id = $buildid; $this->Build->ProjectId = $this->projectid; $this->Build->StartTime = $start_time; $this->Build->EndTime = $end_time; $this->Build->SubmitTime = $submit_time; } $GLOBALS['PHP_ERROR_BUILD_ID'] = $buildid; $this->Update->BuildId = $buildid; $this->Update->StartTime = $start_time; $this->Update->EndTime = $end_time; // Insert the update $this->Update->Insert(); global $CDASH_ENABLE_FEED; if ($CDASH_ENABLE_FEED) { // We need to work the magic here to have a good description $this->Feed->InsertUpdate($this->projectid, $buildid); } // Compute the update statistics $this->Build->ComputeUpdateStatistics(); } else { if ($name == 'UPDATED' || $name == 'CONFLICTING' || $name == 'MODIFIED') { $this->Update->AddFile($this->UpdateFile); unset($this->UpdateFile); } } } }
public function endElement($parser, $name) { parent::endElement($parser, $name); if ($name == 'CONFIGURE') { $start_time = gmdate(FMT_DATETIME, $this->StartTimeStamp); $end_time = gmdate(FMT_DATETIME, $this->EndTimeStamp); $this->Build->ProjectId = $this->projectid; $buildid = $this->Build->GetIdFromName($this->SubProjectName); // If the build doesn't exist we add it if ($buildid == 0) { $this->Build->ProjectId = $this->projectid; $this->Build->StartTime = $start_time; $this->Build->EndTime = $end_time; $this->Build->SubmitTime = gmdate(FMT_DATETIME); $this->Build->SetSubProject($this->SubProjectName); $this->Build->InsertErrors = false; add_build($this->Build, $this->scheduleid); $buildid = $this->Build->Id; } $GLOBALS['PHP_ERROR_BUILD_ID'] = $buildid; $this->Configure->BuildId = $buildid; $this->Configure->StartTime = $start_time; $this->Configure->EndTime = $end_time; // Insert the configure if ($this->Configure->Exists()) { $this->Configure->Delete(); } $this->Configure->Insert(); // Insert errors from the log file $this->Configure->ComputeWarnings(); $this->Configure->ComputeErrors(); $this->Build->Id = $buildid; $this->Build->ComputeConfigureDifferences(); // Record the number of warnings & errors with the build. $this->Build->SetNumberOfConfigureWarnings($this->Configure->NumberOfWarnings); $this->Build->SetNumberOfConfigureErrors($this->Configure->NumberOfErrors); // Update the tally of warnings & errors in the parent build, // if applicable. $this->Build->UpdateParentConfigureNumbers($this->Configure->NumberOfWarnings, $this->Configure->NumberOfErrors); } else { if ($name == 'LABEL') { if (isset($this->Configure)) { $this->Configure->AddLabel($this->Label); } } } }
/** End Element */ public function endElement($parser, $name) { parent::endElement($parser, $name); if ($name === 'SITE') { $start_time = gmdate(FMT_DATETIME, $this->StartTimeStamp); $end_time = gmdate(FMT_DATETIME, $this->EndTimeStamp); $this->Build->ProjectId = $this->projectid; $this->Build->StartTime = $start_time; $this->Build->EndTime = $end_time; $this->Build->SubmitTime = gmdate(FMT_DATETIME); $this->Build->SetSubProject($this->SubProjectName); $this->Build->GetIdFromName($this->SubProjectName); $this->Build->RemoveIfDone(); if ($this->Build->Id == 0) { // If the build doesn't exist we add it. $this->Build->InsertErrors = false; add_build($this->Build, $this->scheduleid); } else { // Otherwise make sure that it's up-to-date. $this->Build->UpdateBuild($this->Build->Id, -1, -1); } // Record the coverage data that we parsed from this file. foreach ($this->CoverageFiles as $coverageInfo) { $coverageFile = $coverageInfo[0]; $coverageFileLog = $coverageInfo[1]; $coverageFile->TrimLastNewline(); $coverageFile->Update($this->Build->Id); $coverageFileLog->BuildId = $this->Build->Id; $coverageFileLog->FileId = $coverageFile->Id; $coverageFileLog->Insert(true); } } elseif ($name == 'LINE') { $this->CurrentCoverageFile->File .= rtrim($this->CurrentLine); // Cannot be <br/> for backward compatibility. $this->CurrentCoverageFile->File .= '<br>'; } elseif ($name == 'FILE') { // Store these objects to be inserted after we're guaranteed // to have a valid buildid. $this->CoverageFiles[] = array($this->CurrentCoverageFile, $this->CurrentCoverageFileLog); } elseif ($name == 'COVERAGELOG') { if (empty($this->CoverageFiles)) { // Store these objects to be inserted after we're guaranteed // to have a valid buildid. $this->CoverageFiles[] = array(new CoverageFile(), new CoverageFileLog()); } } }
/** End element */ public function endElement($parser, $name) { parent::endElement($parser, $name); if ($name == 'SITE') { $start_time = gmdate(FMT_DATETIME, $this->StartTimeStamp); $end_time = gmdate(FMT_DATETIME, $this->EndTimeStamp); $this->Build->ProjectId = $this->projectid; $buildid = $this->Build->GetIdFromName($this->SubProjectName); // If the build doesn't exist we add it if ($buildid == 0) { $this->Build->ProjectId = $this->projectid; $this->Build->StartTime = $start_time; $this->Build->EndTime = $end_time; $this->Build->SubmitTime = gmdate(FMT_DATETIME); $this->Build->InsertErrors = false; add_build($this->Build, $this->scheduleid); $buildid = $this->Build->Id; } // Remove any previous coverage information $GLOBALS['PHP_ERROR_BUILD_ID'] = $buildid; $this->CoverageSummary->BuildId = $buildid; $this->CoverageSummary->RemoveAll(); // Insert coverage summary $this->CoverageSummary->Insert(); $this->CoverageSummary->ComputeDifference(); } else { if ($name == 'SOURCEFILE') { $this->CoverageSummary->AddCoverage($this->Coverage); } else { if ($name == 'LABEL') { if (isset($this->Coverage)) { $this->Coverage->AddLabel($this->Label); } } } } }
/** Function to deal with the external tool mechanism */ function post_submit() { include "models/buildfile.php"; // We expect POST to contain the following values. $vars = array('project', 'build', 'stamp', 'site', 'track', 'type', 'starttime', 'endtime', 'datafilesmd5'); foreach ($vars as $var) { if (!isset($_POST[$var]) || empty($_POST[$var])) { $response_array['status'] = 1; $response_array['description'] = 'Variable \'' . $var . '\' not set but required.'; echo json_encode($response_array); return; } } $projectname = htmlspecialchars(pdo_real_escape_string($_POST['project'])); $buildname = htmlspecialchars(pdo_real_escape_string($_POST['build'])); $buildstamp = htmlspecialchars(pdo_real_escape_string($_POST['stamp'])); $sitename = htmlspecialchars(pdo_real_escape_string($_POST['site'])); $track = htmlspecialchars(pdo_real_escape_string($_POST['track'])); $type = htmlspecialchars(pdo_real_escape_string($_POST['type'])); $starttime = htmlspecialchars(pdo_real_escape_string($_POST['starttime'])); $endtime = htmlspecialchars(pdo_real_escape_string($_POST['endtime'])); // Check if we have the CDash@Home scheduleid $scheduleid = 0; if (isset($_POST["clientscheduleid"])) { $scheduleid = pdo_real_escape_numeric($_POST["clientscheduleid"]); } // Add the build $build = new Build(); $build->ProjectId = get_project_id($projectname); $build->StartTime = gmdate(FMT_DATETIME, $starttime); $build->EndTime = gmdate(FMT_DATETIME, $endtime); $build->SubmitTime = gmdate(FMT_DATETIME); $build->Name = $buildname; $build->InsertErrors = false; // we have no idea if we have errors at this point $build->SetStamp($buildstamp); // Get the site id $site = new Site(); $site->Name = $sitename; $site->Insert(); $build->SiteId = $site->Id; // Make this an "append" build, so that it doesn't result in a separate row // from the rest of the "normal" submission. $build->Append = true; // TODO: Check the labels and generator and other optional if (isset($_POST["generator"])) { $build->Generator = htmlspecialchars(pdo_real_escape_string($_POST['generator'])); } $subprojectname = ""; if (isset($_POST["subproject"])) { $subprojectname = htmlspecialchars(pdo_real_escape_string($_POST['subproject'])); $build->SetSubProject($subprojectname); } // Check if this build already exists. $buildid = $build->GetIdFromName($subprojectname); // If not, add a new one. if ($buildid === 0) { $buildid = add_build($build, $scheduleid); } // Returns the OK submission $response_array['status'] = 0; $response_array['buildid'] = $buildid; $buildfile = new BuildFile(); // Check if the files exists foreach ($_POST['datafilesmd5'] as $md5) { $buildfile->md5 = $md5; $old_buildid = $buildfile->MD5Exists(); if (!$old_buildid) { $response_array['datafilesmd5'][] = 0; } else { $response_array['datafilesmd5'][] = 1; // Associate this build file with the new build if it has been previously // uploaded. require_once "copy_build_data.php"; copy_build_data($old_buildid, $buildid, $type); } } echo json_encode($response_array); }
/** Start Element */ public function startElement($parser, $name, $attributes) { parent::startElement($parser, $name, $attributes); $parent = $this->getParent(); // should be before endElement if ($name == 'SITE') { $this->HasSiteTag = true; $this->Site->Name = $attributes['NAME']; if (empty($this->Site->Name)) { $this->Site->Name = "(empty)"; } $this->Site->Insert(); $siteInformation = new SiteInformation(); $buildInformation = new BuildInformation(); // Fill in the attribute foreach ($attributes as $key => $value) { $siteInformation->SetValue($key, $value); $buildInformation->SetValue($key, $value); } $this->Site->SetInformation($siteInformation); $this->Build->SiteId = $this->Site->Id; $this->Build->Name = $attributes['BUILDNAME']; if (empty($this->Build->Name)) { $this->Build->Name = "(empty)"; } $this->Build->SetStamp($attributes['BUILDSTAMP']); $this->Build->Generator = $attributes['GENERATOR']; $this->Build->Information = $buildInformation; if (array_key_exists('APPEND', $attributes)) { $this->Append = $attributes['APPEND']; } else { $this->Append = false; } } else { if ($name == "FAILURE") { $this->Test->Details = $attributes['TYPE']; } else { if ($name == "PROPERTY" && $parent == "PROPERTIES") { $this->TestProperties .= $attributes['NAME'] . '=' . $attributes['VALUE'] . "\n"; if ($this->HasSiteTag == false) { switch ($attributes['NAME']) { case 'os.name': $this->Build->Information->OSName = $attributes['VALUE']; break; case 'os.version': $this->Build->Information->OSVersion = $attributes['VALUE']; break; case 'java.vm.name': $this->Build->Information->CompilerName = $attributes['VALUE']; break; case 'java.vm.version': $this->Build->Information->CompilerVersion = $attributes['VALUE']; break; case 'hostname': if (empty($this->Site->Name)) { $this->Site->Name = $attributes['VALUE']; $this->Site->Insert(); $this->Build->SiteId = $this->Site->Id; } break; } } } else { if ($name == "TESTCASE" && count($attributes) > 0) { if ($this->BuildAdded == false) { $this->Build->SaveTotalTestsTime(0); $start_time = gmdate(FMT_DATETIME, $this->StartTimeStamp); $this->Build->ProjectId = $this->projectid; $buildid = $this->Build->GetIdFromName($this->SubProjectName); // If the build doesn't exist we add it if ($buildid == 0) { $this->Build->ProjectId = $this->projectid; $this->Build->StartTime = $start_time; $this->Build->EndTime = $start_time; $this->Build->SubmitTime = gmdate(FMT_DATETIME); $this->Build->SetSubProject($this->SubProjectName); $this->Build->Append = $this->Append; $this->Build->InsertErrors = false; add_build($this->Build, $this->scheduleid); $this->UpdateEndTime = true; $buildid = $this->Build->Id; } else { $this->Build->Id = $buildid; //if the build already exists factor the number of tests that have //already been run into our running total $this->NumberTestsFailed += $this->Build->GetNumberOfFailedTests(); $this->NumberTestsNotRun += $this->Build->GetNumberOfNotRunTests(); $this->NumberTestsPassed += $this->Build->GetNumberOfPassedTests(); } $GLOBALS['PHP_ERROR_BUILD_ID'] = $buildid; $this->BuildId = $buildid; $this->BuildAdded = true; } $this->Test = new Test(); $this->Test->Command = $this->TestProperties; $this->Test->ProjectId = $this->projectid; $this->BuildTest = new BuildTest(); if (isset($attributes['TIME'])) { $this->BuildTest->Time = $attributes['TIME']; } // Default is that the test passes unless there is a <failure> tag $this->BuildTest->Status = "passed"; $this->Test->Name = $attributes['NAME']; $this->Test->Path = $attributes['CLASSNAME']; } else { if ($name == "TESTSUITE") { // If the XML file doesn't have a <Site> tag then we use the information // provided by the testsuite. // buildname is 'name' // sitename is 'hostname' // timestamp is 'timestamp' if ($this->HasSiteTag == false) { // Hostname is not necessarily defined if (!empty($attributes['HOSTNAME'])) { $this->Site->Name = $attributes['HOSTNAME']; $this->Site->Insert(); $this->Build->SiteId = $this->Site->Id; } $this->Build->Information = new BuildInformation(); $this->Build->Name = $attributes['NAME']; // Construct a CMake-Like build stamp // We assume Nightly // If the TIMESTAMP attribute is not defined we take the current timestamp if (!isset($attributes['TIMESTAMP'])) { $timestamp = time(); } else { $timestamp = strtotime($attributes['TIMESTAMP']); } $stamp = date("Ymd-Hi", $timestamp) . '-Nightly'; $this->Build->SetStamp($stamp); $this->Append = false; } else { if (!isset($attributes['TIMESTAMP'])) { $stamp = $this->Build->GetStamp(); $timestamp = mktime(substr($stamp, 9, 2), substr($stamp, 11, 2), 0, substr($stamp, 6, 2), substr($stamp, 4, 2), substr($stamp, 0, 4)); } } $this->StartTimeStamp = $timestamp; $this->EndTimeStamp = $this->StartTimeStamp + $attributes['TIME']; $this->Build->SaveTotalTestsTime($attributes['TIME']); } } } } } }
public function endElement($parser, $name) { parent::endElement($parser, $name); if ($name == 'BUILD') { $start_time = gmdate(FMT_DATETIME, $this->StartTimeStamp); $end_time = gmdate(FMT_DATETIME, $this->EndTimeStamp); $submit_time = gmdate(FMT_DATETIME); $this->Build->ProjectId = $this->projectid; $this->Build->StartTime = $start_time; $this->Build->EndTime = $end_time; $this->Build->SubmitTime = $submit_time; $this->Build->SetSubProject($this->SubProjectName); $this->Build->Append = $this->Append; add_build($this->Build, $this->scheduleid); $this->Build->ComputeDifferences(); global $CDASH_ENABLE_FEED; if ($CDASH_ENABLE_FEED) { // Insert the build into the feed $this->Feed->InsertBuild($this->projectid, $this->Build->Id); } } else { if ($name == 'WARNING' || $name == 'ERROR' || $name == 'FAILURE') { global $CDASH_LARGE_TEXT_LIMIT; $threshold = $CDASH_LARGE_TEXT_LIMIT; if ($threshold > 0 && isset($this->Error->StdOutput)) { $outlen = strlen($this->Error->StdOutput); if ($outlen > $threshold) { $tmp = substr($this->Error->StdOutput, 0, $threshold); unset($this->Error->StdOutput); $this->Error->StdOutput = $tmp . "\n...\nCDash truncated output because it exceeded {$threshold} characters.\n"; $outlen = strlen($this->Error->StdOutput); //add_log("truncated long out text", "build_handler", LOG_INFO); } $errlen = strlen($this->Error->StdError); if ($errlen > $threshold) { $tmp = substr($this->Error->StdError, 0, $threshold); unset($this->Error->StdError); $this->Error->StdError = $tmp . "\n...\nCDash truncated output because it exceeded {$threshold} characters.\n"; $errlen = strlen($this->Error->StdError); //add_log("truncated long err text", "build_handler", LOG_INFO); } } $this->Build->AddError($this->Error); unset($this->Error); } else { if ($name == 'LABEL') { if (isset($this->Error)) { $this->Error->AddLabel($this->Label); } else { if (isset($this->Build)) { $this->Build->AddLabel($this->Label); } } } } } }
/** Start element */ public function startElement($parser, $name, $attributes) { parent::startElement($parser, $name, $attributes); if ($this->UploadError) { return; } if ($name == 'SITE') { $this->Site->Name = $attributes['NAME']; if (empty($this->Site->Name)) { $this->Site->Name = "(empty)"; } $this->Site->Insert(); $siteInformation = new SiteInformation(); $buildInformation = new BuildInformation(); // Fill in the attribute foreach ($attributes as $key => $value) { $siteInformation->SetValue($key, $value); $buildInformation->SetValue($key, $value); } $this->Site->SetInformation($siteInformation); $this->Build->SiteId = $this->Site->Id; $this->Build->Name = $attributes['BUILDNAME']; if (empty($this->Build->Name)) { $this->Build->Name = "(empty)"; } $this->Build->SetStamp($attributes['BUILDSTAMP']); $this->Build->Generator = $attributes['GENERATOR']; $this->Build->Information = $buildInformation; } else { if ($name == 'UPLOAD') { $this->Build->ProjectId = $this->projectid; $buildid = $this->Build->GetIdFromName($this->SubProjectName); // If the build doesn't exist we add it if ($buildid == 0) { $this->Build->ProjectId = $this->projectid; $this->Build->StartTime = gmdate(FMT_DATETIME); $this->Build->EndTime = gmdate(FMT_DATETIME); $this->Build->SubmitTime = gmdate(FMT_DATETIME); $this->Build->SetSubProject($this->SubProjectName); $this->Build->Append = false; $this->Build->InsertErrors = false; add_build($this->Build, $this->scheduleid); $this->UpdateEndTime = true; $buildid = $this->Build->Id; } else { $this->Build->Id = $buildid; } $GLOBALS['PHP_ERROR_BUILD_ID'] = $buildid; $this->BuildId = $buildid; } else { if ($name == 'FILE') { $this->UploadFile = new UploadFile(); $this->UploadFile->Filename = $attributes['FILENAME']; } else { if ($name == 'CONTENT') { $fileEncoding = isset($attributes['ENCODING']) ? $attributes['ENCODING'] : 'base64'; if (strcmp($fileEncoding, 'base64') != 0) { // Only base64 encoding is supported for file upload add_log("upload_handler: Only 'base64' encoding is supported", __FILE__ . ':' . __LINE__ . ' - ' . __FUNCTION__, LOG_ERR); $this->UploadError = true; return; } // Create tmp file $this->TmpFilename = tempnam($GLOBALS['CDASH_UPLOAD_DIRECTORY'], 'tmp'); // TODO Handle error if (empty($this->TmpFilename)) { add_log("Failed to create temporary filename", __FILE__ . ':' . __LINE__ . ' - ' . __FUNCTION__, LOG_ERR); $this->UploadError = true; return; } $this->Base64TmpFilename = $this->TmpFilename . '-base64'; // Open base64 temporary file for writting $this->Base64TmpFileWriteHandle = fopen($this->Base64TmpFilename, 'w'); if (!$this->Base64TmpFileWriteHandle) { add_log("Failed to open file '" . $this->Base64TmpFilename . "' for writting", __FILE__ . ':' . __LINE__ . ' - ' . __FUNCTION__, LOG_ERR); $this->UploadError = true; return; } } } } } }
/** End element */ public function endElement($parser, $name) { parent::endElement($parser, $name); if ($name == 'SITE') { $start_time = gmdate(FMT_DATETIME, $this->StartTimeStamp); $end_time = gmdate(FMT_DATETIME, $this->EndTimeStamp); $this->Build->ProjectId = $this->projectid; $this->Build->StartTime = $start_time; $this->Build->EndTime = $end_time; $this->Build->SubmitTime = gmdate(FMT_DATETIME); $this->Build->SetSubProject($this->SubProjectName); $this->Build->GetIdFromName($this->SubProjectName); $this->Build->RemoveIfDone(); // If the build doesn't exist we add it if ($this->Build->Id == 0) { $this->Build->InsertErrors = false; add_build($this->Build, $this->scheduleid); } else { // Otherwise make sure that it's up-to-date. $this->Build->UpdateBuild($this->Build->Id, -1, -1); } $GLOBALS['PHP_ERROR_BUILD_ID'] = $this->Build->Id; $this->CoverageSummary->BuildId = $this->Build->Id; // Insert coverage summary $this->CoverageSummary->Insert(true); $this->CoverageSummary->ComputeDifference(); } elseif ($name == 'FILE') { $this->CoverageSummary->AddCoverage($this->Coverage); } elseif ($name == 'LABEL') { if (isset($this->Coverage)) { $this->Coverage->AddLabel($this->Label); } } }
function create_aggregate_build($build, $siteid = null) { require_once 'include/ctestparserutils.php'; if (is_null($siteid)) { $siteid = get_server_siteid(); } $aggregate_build = new Build(); $aggregate_build->Name = 'Aggregate Coverage'; $aggregate_build->SiteId = $siteid; $date = substr($build->GetStamp(), 0, strpos($build->GetStamp(), '-')); $aggregate_build->SetStamp($date . "-0000-Nightly"); $aggregate_build->ProjectId = $build->ProjectId; $aggregate_build->StartTime = $build->StartTime; $aggregate_build->EndTime = $build->EndTime; $aggregate_build->SubmitTime = gmdate(FMT_DATETIME); $aggregate_build->SetSubProject($build->GetSubProjectName()); $aggregate_build->InsertErrors = false; add_build($aggregate_build); return $aggregate_build; }
$revisions = json_decode(str_replace('\\', '', $_POST['revisions']), TRUE); foreach ($revisions as $repository_name => $revision_data) { require_format('repository_name', $repository_name, '/^\\w+$/'); require_existence_of($revision_data, array('revision' => '/^[a-z0-9]+$/', 'timestamp' => '/^[a-z0-9\\-\\.:TZ]+$/'), 'revision'); } $test_results = fetch_and_parse_test_results_json($_FILES['file']['tmp_name']); if (!$test_results) { exit_with_error('InvalidResultsJSON'); } $start_time = float_to_time($_POST['start_time']); $end_time = float_to_time($_POST['end_time']); $builder_id = add_builder($db, $master, $builder_name); if (!$builder_id) { exit_with_error('FailedToInsertBuilder', array('master' => $master, 'builderName' => $builder_name)); } $build_id = add_build($db, $builder_id, $build_number); if (!$build_id) { exit_with_error('FailedToInsertBuild', array('builderId' => $builder_id, 'buildNumber' => $build_number)); } foreach ($revisions as $repository_name => $revision_data) { $repository_id = $db->select_or_insert_row('repositories', NULL, array('name' => $repository_name)); if (!$repository_id) { exit_with_error('FailedToInsertRepository', array('name' => $repository_name)); } $revision_data = array('repository' => $repository_id, 'build' => $build_id, 'value' => $revision_data['revision'], 'time' => array_get($revision_data, 'timestamp')); $db->select_or_insert_row('build_revisions', NULL, array('repository' => $repository_id, 'build' => $build_id), $revision_data, 'value') or exit_with_error('FailedToInsertRevision', array('name' => $repository_name, 'data' => $revision_data)); } $slave_id = add_slave($db, $_POST['build_slave']); if (!store_test_results($db, $test_results, $build_id, $start_time, $end_time, $slave_id)) { exit_with_error('FailedToStoreResults', array('buildId' => $build_id)); }
/** Start element */ public function startElement($parser, $name, $attributes) { parent::startElement($parser, $name, $attributes); if ($this->UploadError) { return; } if ($name == 'SITE') { $this->Site->Name = $attributes['NAME']; if (empty($this->Site->Name)) { $this->Site->Name = '(empty)'; } $this->Site->Insert(); $siteInformation = new SiteInformation(); $buildInformation = new BuildInformation(); // Fill in the attribute foreach ($attributes as $key => $value) { $siteInformation->SetValue($key, $value); $buildInformation->SetValue($key, $value); } $this->Site->SetInformation($siteInformation); $this->Build->SiteId = $this->Site->Id; $this->Build->Name = $attributes['BUILDNAME']; if (empty($this->Build->Name)) { $this->Build->Name = '(empty)'; } $this->Build->SetStamp($attributes['BUILDSTAMP']); $this->Build->Generator = $attributes['GENERATOR']; $this->Build->Information = $buildInformation; } elseif ($name == 'UPLOAD') { // Setting start time and end time is tricky here, since all // we have is the build stamp. The strategy we take here is: // Set the start time as late as possible, and set the end time // as early as possible. // This way we don't override any existing values for these fields // when we call UpdateBuild() below. // // For end time, we use the start of the testing day. // For start time, we use either the submit time (now) or // one second before the start time of the *next* testing day // (whichever is earlier). // Yes, this means the build finished before it began. // // This associates the build with the correct day if it is only // an upload. Otherwise we defer to the values set by the // other handlers. $row = pdo_single_row_query("SELECT nightlytime FROM project where id='{$this->projectid}'"); $nightly_time = $row['nightlytime']; $build_date = extract_date_from_buildstamp($this->Build->GetStamp()); list($prev, $nightly_start_time, $next) = get_dates($build_date, $nightly_time); // If the nightly start time is after noon (server time) // and this buildstamp is on or after the nightly start time // then this build belongs to the next testing day. if (date(FMT_TIME, $nightly_start_time) > '12:00:00') { $build_timestamp = strtotime($build_date); $next_timestamp = strtotime($next); if (strtotime(date(FMT_TIME, $build_timestamp), $next_timestamp) >= strtotime(date(FMT_TIME, $nightly_start_time), $next_timestamp)) { $nightly_start_time += 3600 * 24; } } $this->Build->EndTime = gmdate(FMT_DATETIME, $nightly_start_time); $now = time(); $one_second_before_tomorrow = strtotime('+1 day -1 second', $nightly_start_time); if ($one_second_before_tomorrow < time()) { $this->Build->StartTime = gmdate(FMT_DATETIME, $one_second_before_tomorrow); } else { $this->Build->StartTime = gmdate(FMT_DATETIME, $now); } $this->Build->SubmitTime = gmdate(FMT_DATETIME, $now); $this->Build->ProjectId = $this->projectid; $this->Build->SetSubProject($this->SubProjectName); $this->Build->GetIdFromName($this->SubProjectName); $this->Build->RemoveIfDone(); // If the build doesn't exist we add it if ($this->Build->Id == 0) { $this->Build->Append = false; $this->Build->InsertErrors = false; add_build($this->Build, $this->scheduleid); $this->UpdateEndTime = true; } else { // Otherwise make sure that the build is up-to-date. $this->Build->UpdateBuild($this->Build->Id, -1, -1); } $GLOBALS['PHP_ERROR_BUILD_ID'] = $this->Build->Id; } elseif ($name == 'FILE') { $this->UploadFile = new UploadFile(); $this->UploadFile->Filename = $attributes['FILENAME']; } elseif ($name == 'CONTENT') { $fileEncoding = isset($attributes['ENCODING']) ? $attributes['ENCODING'] : 'base64'; if (strcmp($fileEncoding, 'base64') != 0) { // Only base64 encoding is supported for file upload add_log("upload_handler: Only 'base64' encoding is supported", __FILE__ . ':' . __LINE__ . ' - ' . __FUNCTION__, LOG_ERR); $this->UploadError = true; return; } // Create tmp file $this->TmpFilename = tempnam($GLOBALS['CDASH_UPLOAD_DIRECTORY'], 'tmp'); // TODO Handle error if (empty($this->TmpFilename)) { add_log('Failed to create temporary filename', __FILE__ . ':' . __LINE__ . ' - ' . __FUNCTION__, LOG_ERR); $this->UploadError = true; return; } $this->Base64TmpFilename = $this->TmpFilename . '-base64'; // Open base64 temporary file for writting $this->Base64TmpFileWriteHandle = fopen($this->Base64TmpFilename, 'w'); if (!$this->Base64TmpFileWriteHandle) { add_log("Failed to open file '" . $this->Base64TmpFilename . "' for writting", __FILE__ . ':' . __LINE__ . ' - ' . __FUNCTION__, LOG_ERR); $this->UploadError = true; return; } } }
/** Function endElement */ public function endElement($parser, $name) { $parent = $this->getParent(); // should be before endElement parent::endElement($parser, $name); if ($name == 'STARTTESTTIME' && $parent == 'DYNAMICANALYSIS') { $this->Build->ProjectId = $this->projectid; $start_time = gmdate(FMT_DATETIME, $this->StartTimeStamp); $this->Build->StartTime = $start_time; // EndTimeStamp hasn't been parsed yet. We update this value later. $this->Build->EndTime = $start_time; $this->Build->SubmitTime = gmdate(FMT_DATETIME); $this->Build->SetSubProject($this->SubProjectName); $this->Build->GetIdFromName($this->SubProjectName); $this->Build->RemoveIfDone(); // If the build doesn't exist we add it if ($this->Build->Id == 0) { $this->Build->InsertErrors = false; add_build($this->Build, $this->scheduleid); } else { // Otherwise make sure that the build is up-to-date. $this->Build->UpdateBuild($this->Build->Id, -1, -1); // Remove all the previous analysis $this->DynamicAnalysis = new DynamicAnalysis(); $this->DynamicAnalysis->BuildId = $this->Build->Id; $this->DynamicAnalysis->RemoveAll(); unset($this->DynamicAnalysis); } $GLOBALS['PHP_ERROR_BUILD_ID'] = $this->Build->Id; $this->DynamicAnalysisSummary->BuildId = $this->Build->Id; } elseif ($name == 'TEST' && $parent == 'DYNAMICANALYSIS') { $this->DynamicAnalysis->BuildId = $this->Build->Id; $this->DynamicAnalysis->Insert(); } elseif ($name == 'DEFECT') { $this->DynamicAnalysis->AddDefect($this->DynamicAnalysisDefect); $this->DynamicAnalysisSummary->AddDefects($this->DynamicAnalysisDefect->Value); unset($this->DynamicAnalysisDefect); } elseif ($name == 'LABEL') { if (isset($this->DynamicAnalysis)) { $this->DynamicAnalysis->AddLabel($this->Label); } } elseif ($name == 'DYNAMICANALYSIS') { // Update this build's end time if necessary. $this->Build->EndTime = gmdate(FMT_DATETIME, $this->EndTimeStamp); $this->Build->UpdateBuild($this->Build->Id, -1, -1); // If everything is perfect CTest doesn't send any <test> // But we still want a line showing the current dynamic analysis if (!isset($this->DynamicAnalysis)) { $this->DynamicAnalysis = new DynamicAnalysis(); $this->DynamicAnalysis->BuildId = $this->Build->Id; $this->DynamicAnalysis->Status = 'passed'; $this->DynamicAnalysis->Checker = $this->Checker; $this->DynamicAnalysis->Insert(); } $this->DynamicAnalysisSummary->Insert(); // If this is a child build append these defects to the parent's // summary. $parentid = $this->Build->LookupParentBuildId(); if ($parentid > 0) { $this->DynamicAnalysisSummary->BuildId = $parentid; $this->DynamicAnalysisSummary->Insert(true); } } }
/** Start Element */ public function startElement($parser, $name, $attributes) { parent::startElement($parser, $name, $attributes); $parent = $this->getParent(); // should be before endElement if ($name == 'SITE') { $this->HasSiteTag = true; $this->Site->Name = $attributes['NAME']; if (empty($this->Site->Name)) { $this->Site->Name = "(empty)"; } $this->Site->Insert(); $siteInformation = new SiteInformation(); $buildInformation = new BuildInformation(); // Fill in the attribute foreach ($attributes as $key => $value) { $siteInformation->SetValue($key, $value); $buildInformation->SetValue($key, $value); } $this->Site->SetInformation($siteInformation); $this->Build->SiteId = $this->Site->Id; $this->Build->Name = $attributes['BUILDNAME']; if (empty($this->Build->Name)) { $this->Build->Name = "(empty)"; } $this->Build->SetStamp($attributes['BUILDSTAMP']); $this->Build->Generator = $attributes['GENERATOR']; $this->Build->Information = $buildInformation; if (array_key_exists('APPEND', $attributes)) { $this->Append = $attributes['APPEND']; } else { $this->Append = false; } } else { if ($name == "TEST-CASE" && count($attributes) > 0) { $this->Test = new Test(); $this->Test->ProjectId = $this->projectid; $this->BuildTest = new BuildTest(); $teststatus = "notrun"; if ($attributes['RESULT'] == "Success") { $teststatus = "passed"; } else { if ($attributes['RESULT'] == "Failure") { $teststatus = "failed"; } } $this->BuildTest->Status = $teststatus; if ($teststatus == "passed") { $this->NumberTestsPassed++; } else { if ($teststatus == "failed") { $this->NumberTestsFailed++; } else { if ($teststatus == "notrun") { $this->NumberTestsNotRun++; } } } if (isset($attributes['TIME'])) { $this->BuildTest->Time = $attributes['TIME']; } if (isset($attributes['ASSERTS'])) { $this->Test->Details = $attributes['ASSERTS']; } $this->Test->Name = $attributes['NAME']; $this->Test->Path = $attributes['NAME']; $this->Test->Command = $attributes['NAME']; } else { if ($name == "TEST-RESULTS") { $this->StartTimeStamp = strtotime($attributes['DATE'] . ' ' . $attributes['TIME']); $this->EndTimeStamp = $this->StartTimeStamp; } else { if ($this->HasSiteTag == false && $name == "ENVIRONMENT") { // If the XML file doesn't have a <Site> tag then we use the information // provided by the testsuite. // buildname is 'name' // sitename is 'hostname' // timestamp is 'timestamp' $this->Site->Name = $attributes['MACHINE-NAME']; $this->Site->Insert(); $buildInformation = new BuildInformation(); $buildInformation->OSName = $attributes['PLATFORM']; $buildInformation->OSVersion = $attributes['OS-VERSION']; $buildInformation->CompilerName = 'CLR'; $buildInformation->CompilerVersion = $attributes['CLR-VERSION']; $this->Build->SiteId = $this->Site->Id; $this->Build->Name = $attributes['PLATFORM']; // Construct a CMake-Like build stamp // We assume Nightly $stamp = date("Ymd-Hi", $this->StartTimeStamp) . '-Nightly'; $this->Build->SetStamp($stamp); $this->Build->Information = $buildInformation; $this->Append = false; } else { if ($this->BuildAdded == false && $name == "TEST-SUITE") { $this->Build->SaveTotalTestsTime(0); $start_time = gmdate(FMT_DATETIME, $this->StartTimeStamp); $this->Build->ProjectId = $this->projectid; $buildid = $this->Build->GetIdFromName($this->SubProjectName); // If the build doesn't exist we add it if ($buildid == 0) { $this->Build->ProjectId = $this->projectid; $this->Build->StartTime = $start_time; $this->Build->EndTime = $start_time; $this->Build->SubmitTime = gmdate(FMT_DATETIME); $this->Build->SetSubProject($this->SubProjectName); $this->Build->Append = $this->Append; $this->Build->InsertErrors = false; add_build($this->Build, $this->scheduleid); $this->UpdateEndTime = true; $buildid = $this->Build->Id; } else { $this->Build->Id = $buildid; //if the build already exists factor the number of tests that have //already been run into our running total $this->NumberTestsFailed += $this->Build->GetNumberOfFailedTests(); $this->NumberTestsNotRun += $this->Build->GetNumberOfNotRunTests(); $this->NumberTestsPassed += $this->Build->GetNumberOfPassedTests(); } $GLOBALS['PHP_ERROR_BUILD_ID'] = $buildid; $this->BuildId = $buildid; $this->BuildAdded = true; } } } } } }
/** Start Element */ public function startElement($parser, $name, $attributes) { parent::startElement($parser, $name, $attributes); $parent = $this->getParent(); // should be before endElement if ($name == 'SITE') { $this->Site->Name = $attributes['NAME']; if (empty($this->Site->Name)) { $this->Site->Name = '(empty)'; } $this->Site->Insert(); $siteInformation = new SiteInformation(); $buildInformation = new BuildInformation(); // Fill in the attribute foreach ($attributes as $key => $value) { if ($key === 'CHANGEID') { $this->Build->SetPullRequest($value); continue; } $siteInformation->SetValue($key, $value); $buildInformation->SetValue($key, $value); } $this->Site->SetInformation($siteInformation); $this->Build->SiteId = $this->Site->Id; $this->Build->Name = $attributes['BUILDNAME']; if (empty($this->Build->Name)) { $this->Build->Name = '(empty)'; } $this->Build->SetStamp($attributes['BUILDSTAMP']); $this->Build->Generator = $attributes['GENERATOR']; $this->Build->Information = $buildInformation; if (array_key_exists('APPEND', $attributes)) { $this->Append = $attributes['APPEND']; } else { $this->Append = false; } } elseif ($name == 'TEST' && count($attributes) > 0) { $this->Test = new Test(); $this->Test->ProjectId = $this->projectid; $this->BuildTest = new BuildTest(); $this->BuildTest->Status = $attributes['STATUS']; if ($attributes['STATUS'] == 'passed') { $this->NumberTestsPassed++; } elseif ($attributes['STATUS'] == 'failed') { $this->NumberTestsFailed++; } elseif ($attributes['STATUS'] == 'notrun') { $this->NumberTestsNotRun++; } } elseif ($name == 'NAMEDMEASUREMENT') { $this->TestMeasurement = new TestMeasurement(); if ($attributes['TYPE'] == 'file') { $this->TestMeasurement->Name = $attributes['FILENAME']; } else { $this->TestMeasurement->Name = $attributes['NAME']; } $this->TestMeasurement->Type = $attributes['TYPE']; } elseif ($name == 'VALUE' && $parent == 'MEASUREMENT') { if (isset($attributes['COMPRESSION']) && $attributes['COMPRESSION'] == 'gzip') { $this->Test->CompressedOutput = true; } } elseif ($name == 'LABEL' && $parent == 'LABELS') { $this->Label = new Label(); } elseif ($name == 'TESTLIST' && $parent == 'TESTING') { $start_time = gmdate(FMT_DATETIME, $this->StartTimeStamp); $this->Build->ProjectId = $this->projectid; $this->Build->StartTime = $start_time; // EndTimeStamp hasn't been parsed yet. $this->Build->EndTime = $start_time; $this->Build->SubmitTime = gmdate(FMT_DATETIME); $this->Build->SetSubProject($this->SubProjectName); $this->Build->GetIdFromName($this->SubProjectName); $this->Build->RemoveIfDone(); // If the build doesn't exist we add it if ($this->Build->Id == 0) { $this->Build->Append = $this->Append; $this->Build->InsertErrors = false; add_build($this->Build, $this->scheduleid); } else { // Otherwise make sure that the build is up-to-date. $this->Build->UpdateBuild($this->Build->Id, -1, -1); // If the build already exists factor the number of tests // that have already been run into our running total. $this->NumberTestsFailed += $this->Build->GetNumberOfFailedTests(); $this->NumberTestsNotRun += $this->Build->GetNumberOfNotRunTests(); $this->NumberTestsPassed += $this->Build->GetNumberOfPassedTests(); } $GLOBALS['PHP_ERROR_BUILD_ID'] = $this->Build->Id; } }
/** Function endElement */ public function endElement($parser, $name) { $parent = $this->getParent(); // should be before endElement parent::endElement($parser, $name); if ($name == "STARTTESTTIME" && $parent == 'DYNAMICANALYSIS') { $start_time = gmdate(FMT_DATETIME, $this->StartTimeStamp); $this->Build->ProjectId = $this->projectid; $buildid = $this->Build->GetIdFromName($this->SubProjectName); // If the build doesn't exist we add it if ($buildid == 0) { $this->Build->ProjectId = $this->projectid; $this->Build->StartTime = $start_time; $this->Build->EndTime = $start_time; $this->Build->SubmitTime = gmdate(FMT_DATETIME); $this->Build->InsertErrors = false; add_build($this->Build, $this->scheduleid); $this->UpdateEndTime = true; $buildid = $this->Build->Id; } else { // Remove all the previous analysis $this->DynamicAnalysis = new DynamicAnalysis(); $this->DynamicAnalysis->BuildId = $buildid; $this->DynamicAnalysis->RemoveAll(); unset($this->DynamicAnalysis); } $GLOBALS['PHP_ERROR_BUILD_ID'] = $buildid; $this->BuildId = $buildid; } else { if ($name == "TEST" && $parent == 'DYNAMICANALYSIS') { $this->DynamicAnalysis->BuildId = $this->BuildId; $this->DynamicAnalysis->Insert(); } else { if ($name == 'DEFECT') { $this->DynamicAnalysis->AddDefect($this->DynamicAnalysisDefect); unset($this->DynamicAnalysisDefect); } else { if ($name == "SITE") { if ($this->UpdateEndTime) { $end_time = gmdate(FMT_DATETIME, $this->EndTimeStamp); // The EndTimeStamp $this->Build->UpdateEndTime($end_time); } } else { if ($name == 'LABEL') { if (isset($this->DynamicAnalysis)) { $this->DynamicAnalysis->AddLabel($this->Label); } } else { if ($name == 'DYNAMICANALYSIS') { // If everything is perfect CTest doesn't send any <test> // But we still want a line showing the current dynamic analysis if (!isset($this->DynamicAnalysis)) { $this->DynamicAnalysis = new DynamicAnalysis(); $this->DynamicAnalysis->BuildId = $this->BuildId; $this->DynamicAnalysis->Status = 'passed'; $this->DynamicAnalysis->Checker = $this->Checker; $this->DynamicAnalysis->Insert(); } } } } } } } }
/** * Parse an individual .gcov file. **/ public function ParseGcovFile($fileinfo) { $coverageFileLog = new CoverageFileLog(); $coverageFileLog->AggregateBuildId = $this->AggregateBuildId; $coverageFileLog->PreviousAggregateParentId = $this->PreviousAggregateParentId; $coverageFile = new CoverageFile(); $coverage = new Coverage(); $coverage->CoverageFile = $coverageFile; // Begin parsing this file. // The first thing we look for is the full path to this source file. $file = new SplFileObject($fileinfo); $path = ''; while (!$file->eof()) { $gcovLine = $file->current(); $term = ':Source:'; $pos = strpos($gcovLine, $term); if ($pos !== false) { $path = substr($gcovLine, $pos + strlen($term)); break; } $file->next(); } if (empty($path)) { return; } // Check if this file belongs to a different SubProject. $buildid = $this->Build->Id; if (!empty($this->SubProjectPath) && strpos($path, $this->SubProjectPath) === false) { // Find the SubProject that corresponds to this path. $query = "SELECT id, name, path FROM subproject\n WHERE projectid = {$this->ProjectId} AND\n endtime = '1980-01-01 00:00:00' AND\n path != '' AND\n '{$path}' LIKE CONCAT('%',path,'%')"; $result = pdo_query($query); if (!$result || pdo_num_rows($result) == 0) { add_log("No SubProject found for '{$path}'", 'ParseGcovFile', LOG_INFO, $this->ProjectId, $this->Build->Id); return; } $row = pdo_fetch_array($result); $subprojectid = $row['id']; $subprojectname = $row['name']; $subprojectpath = $row['path']; // Find the sibling build that performed this SubProject. $siblingBuild = new Build(); $query = 'SELECT b.id FROM build AS b INNER JOIN subproject2build AS sp2b ON (sp2b.buildid=b.id) WHERE b.parentid= (SELECT parentid FROM build WHERE id=' . $this->Build->Id . ")\n AND sp2b.subprojectid={$subprojectid}"; $row = pdo_single_row_query($query); if ($row && array_key_exists('id', $row)) { $buildid = $row['id']; $siblingBuild->Id = $buildid; $siblingBuild->FillFromId($buildid); } else { // Build doesn't exist yet, add it here. $siblingBuild->Name = $this->Build->Name; $siblingBuild->ProjectId = $this->ProjectId; $siblingBuild->SiteId = $this->Build->SiteId; $siblingBuild->SetParentId($this->Build->GetParentId()); $siblingBuild->SetStamp($this->Build->GetStamp()); $siblingBuild->SetSubProject($subprojectname); $siblingBuild->StartTime = $this->Build->StartTime; $siblingBuild->EndTime = $this->Build->EndTime; $siblingBuild->SubmitTime = gmdate(FMT_DATETIME); add_build($siblingBuild, 0); $buildid = $siblingBuild->Id; } $coverageFileLog->Build = $siblingBuild; // Remove any part of the file path that comes before // the subproject path. $path = substr($path, strpos($path, $subprojectpath)); // Replace the subproject path with '.' $path = substr_replace($path, '.', 0, strlen($subprojectpath)); } else { // If this source file isn't from the source or binary directory // we shouldn't include it in our coverage report. if (!empty($this->SubProjectPath) && strpos($path, $this->SubProjectPath) !== false) { $path = substr($path, strpos($path, $this->SubProjectPath)); $path = substr_replace($path, '.', 0, strlen($this->SubProjectPath)); } elseif (strpos($path, $this->SourceDirectory) !== false) { $path = str_replace($this->SourceDirectory, '.', trim($path)); } elseif (strpos($path, $this->BinaryDirectory) !== false) { $path = str_replace($this->BinaryDirectory, '.', trim($path)); } else { return; } $coverageFileLog->Build = $this->Build; } // Get a reference to the coverage summary for this build. if ($buildid === $this->Build->Id) { $coverageSummary = $this->CoverageSummary; } else { if (!array_key_exists($buildid, $this->SubProjectSummaries)) { $coverageSummary = new CoverageSummary(); $coverageSummary->BuildId = $buildid; $this->SubProjectSummaries[$buildid] = $coverageSummary; } else { $coverageSummary = $this->SubProjectSummaries[$buildid]; } } // Use a regexp to resolve any /../ in this path. // We can't use realpath() because we're referencing a path that // doesn't exist on the server. // For a source file that contains: // #include "src/../include/foo.h" // CDash will report the covered file as include/foo.h $pattern = "#/[^/]*?/\\.\\./#"; while (strpos($path, "/../") !== false) { $path = preg_replace($pattern, "/", $path, 1); } $coverageFile->FullPath = trim($path); $lineNumber = 0; // The lack of rewind is intentional. while (!$file->eof()) { $gcovLine = $file->current(); // "Ordinary" entries in a .gcov file take the following format: // <lineNumber>: <timesHit>: <source code at that line> // So we check if this line matches the format & parse the // data out of it if so. $fields = explode(':', $gcovLine, 3); if (count($fields) > 2) { // Separate out delimited values from this line. $timesHit = trim($fields[0]); $lineNumber = trim($fields[1]); $sourceLine = rtrim($fields[2]); if ($lineNumber > 0) { $coverageFile->File .= $sourceLine; // cannot be <br/> for backward compatibility. $coverageFile->File .= '<br>'; } // This is how gcov indicates a line of unexecutable code. if ($timesHit === '-') { $file->next(); continue; } // This is how gcov indicates an uncovered line. if ($timesHit === '#####') { $timesHit = 0; } $coverageFileLog->AddLine($lineNumber - 1, $timesHit); $file->next(); } else { $coveredBranches = 0; $uncoveredBranches = 0; $throwBranches = 0; $fallthroughBranches = 0; while (count($fields) < 3 && !$file->eof()) { // Parse branch coverage here. if (substr($gcovLine, 0, 6) === 'branch') { // Figure out whether this branch was covered or not. if (strpos($gcovLine, 'taken 0%') !== false) { $uncoveredBranches += 1; } else { $coveredBranches += 1; } // Also keep track of the different types of branches encountered. if (strpos($gcovLine, '(throw)') !== false) { $throwBranches += 1; } elseif (strpos($gcovLine, '(fallthrough)') !== false) { $fallthroughBranches += 1; } } $file->next(); $gcovLine = $file->current(); $fields = explode(':', $gcovLine); } // Don't report branch coverage for this line if we only // encountered (throw) and (fallthrough) branches here. $totalBranches = $coveredBranches + $uncoveredBranches; if ($totalBranches > 0 && $totalBranches > $throwBranches + $fallthroughBranches) { $coverageFileLog->AddBranch($lineNumber - 1, $coveredBranches, $totalBranches); } } } // Save these models to the database. $coverageFile->TrimLastNewline(); $coverageFile->Update($buildid); $coverageFileLog->BuildId = $buildid; $coverageFileLog->FileId = $coverageFile->Id; $coverageFileLog->Insert(true); // Query the filelog to get how many lines & branches were covered. // We do this after inserting the filelog because we want to accurately // reflect the union of the current and previously existing results // (if any). $stats = $coverageFileLog->GetStats(); $coverage->LocUntested = $stats['locuntested']; $coverage->LocTested = $stats['loctested']; $coverage->Covered = 1; $coverage->BranchesUntested = $stats['branchesuntested']; $coverage->BranchesTested = $stats['branchestested']; // Add any labels. if (array_key_exists($path, $this->Labels)) { foreach ($this->Labels[$path] as $labelText) { $label = new Label(); $label->SetText($labelText); $coverage->AddLabel($label); } } // Add this Coverage to our summary. $coverageSummary->AddCoverage($coverage); }
/** End element */ public function endElement($parser, $name) { parent::endElement($parser, $name); if ($name == 'SITE') { $this->Site->Insert(); } elseif ($name == 'UPDATE') { $this->Build->SiteId = $this->Site->Id; $start_time = gmdate(FMT_DATETIME, $this->StartTimeStamp); $end_time = gmdate(FMT_DATETIME, $this->EndTimeStamp); $submit_time = gmdate(FMT_DATETIME); $this->Build->StartTime = $start_time; $this->Build->EndTime = $end_time; $this->Build->SubmitTime = $submit_time; $this->Build->ProjectId = $this->projectid; $this->Build->GetIdFromName($this->SubProjectName); // Update.xml doesn't include SubProject information. // Check if GetIdFromName returned a child build, and // if so, change our buildid to point at the parent instead. $parentid = $this->Build->LookupParentBuildId(); if ($parentid > 0) { $this->Build->Id = $parentid; } $this->Build->RemoveIfDone(); // If the build doesn't exist we add it if ($this->Build->Id == 0) { $this->Build->SetSubProject($this->SubProjectName); $this->Build->Append = $this->Append; $this->Build->InsertErrors = false; add_build($this->Build, $this->scheduleid); } else { // Otherwise make sure that it's up-to-date. $this->Build->UpdateBuild($this->Build->Id, -1, -1); } $GLOBALS['PHP_ERROR_BUILD_ID'] = $this->Build->Id; $this->Update->BuildId = $this->Build->Id; $this->Update->StartTime = $start_time; $this->Update->EndTime = $end_time; // Insert the update $this->Update->Insert(); global $CDASH_ENABLE_FEED; if ($CDASH_ENABLE_FEED) { // We need to work the magic here to have a good description $this->Feed->InsertUpdate($this->projectid, $this->Build->Id); } if ($this->Update->Command === '') { // If the UpdateCommand was not set, then this was a // "version only" update. This means that CTest only told us // what version of the code is being built, not what changed // since last time. In this case we need to query the remote // repository to figure out what changed. perform_version_only_diff($this->Update, $this->projectid); } // Compute the update statistics $this->Build->ComputeUpdateStatistics(); } elseif ($name == 'UPDATED' || $name == 'CONFLICTING' || $name == 'MODIFIED') { $this->Update->AddFile($this->UpdateFile); unset($this->UpdateFile); } }