public function AddMeasurement($measurement) { $measurement->TestId = $this->Id; $this->Measurements[] = $measurement; if ($measurement->Name == 'Label') { $label = new Label(); $label->SetText($measurement->Value); $this->AddLabel($label); } }
/** * Parse an individual uncovered source file. **/ public function ParseUncoveredSourceFile($fileinfo, $path) { $coverageFileLog = new CoverageFileLog(); $coverageFileLog->AggregateBuildId = $this->AggregateBuildId; $coverageFileLog->PreviousAggregateParentId = $this->PreviousAggregateParentId; $coverageFile = new CoverageFile(); $coverageFile->FullPath = trim($path); $coverage = new Coverage(); $coverage->CoverageFile = $coverageFile; // SplFileObject was giving me an erroneous extra line at the // end of the file, so instead we use good old file(). $lines = file($fileinfo); $lineNumber = 0; foreach ($lines as $line) { $sourceLine = rtrim($line); $coverageFile->File .= $sourceLine; $coverageFile->File .= '<br>'; $coverageFileLog->AddLine($lineNumber, 0); $lineNumber++; } // Save this source file to the database. $coverageFile->TrimLastNewline(); $coverageFile->Update($this->Build->Id); // Check if this build already has coverage for this file. // If so, return early so we don't overwrite it with a blank entry. $coverage->BuildId = $this->Build->Id; if ($coverage->Exists()) { return false; } // Otherwise save the line-by-line coverage to the database. $coverageFileLog->BuildId = $this->Build->Id; $coverageFileLog->FileId = $coverageFile->Id; $coverageFileLog->Insert(true); $coverage->LocUntested = $lineNumber; $coverage->LocTested = 0; $coverage->Covered = 1; // 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. $this->CoverageSummary->AddCoverage($coverage); }
public function testBuildRemovalWorksAsExpected() { require_once 'include/common.php'; require_once 'include/pdo.php'; require_once 'models/build.php'; require_once 'models/buildconfigure.php'; require_once 'models/builderror.php'; require_once 'models/buildfailure.php'; require_once 'models/buildgroup.php'; require_once 'models/buildnote.php'; require_once 'models/buildupdate.php'; require_once 'models/coverage.php'; require_once 'models/dynamicanalysis.php'; require_once 'models/dynamicanalysissummary.php'; require_once 'models/image.php'; require_once 'models/label.php'; require_once 'models/test.php'; require_once 'models/uploadfile.php'; $time = gmdate(FMT_DATETIME); // Find an existing site. $row = pdo_single_row_query('SELECT id FROM site LIMIT 1'); $siteid = $row['id']; // Label $label = new Label(); $label->SetText('remove me'); // Build $build = new Build(); $build->Name = 'RemovalWorksAsExpected'; $build->SetStamp('20160822-1810-Experimental'); $build->ProjectId = 1; $build->InsertErrors = true; $build->SiteId = $siteid; $build->StartTime = $time; $build->EndTime = $time; $build->SubmitTime = $time; $build->AddLabel($label); $buildgroup = new BuildGroup(); $build->GroupId = $buildgroup->GetGroupIdFromRule($build); $info = new BuildInformation(); $info->SetValue('OSNAME', 'Windows'); $build->Information = $info; // BuildError $error = new BuildError(); $error->Text = 'error: asdf'; $build->AddError($error); // BuildFailure $failure = new BuildFailure(); $failure->StdError = 'failure: asdf'; $failure->AddArgument('arg1'); $failure->AddLabel($label); $build->AddError($failure); $build->Save(); // Create another build to test shared resources. $existing_build = new Build(); $existing_build->Id = $build->Id; $existing_build->FillFromId($build->Id); $existing_build->SetStamp('20160822-1811-Experimental'); $existing_build->SubmitTime = $time; $existing_build->InsertErrors = true; $existing_build->AddError($failure); $existing_build->Id = null; $existing_build->Save(); // BuildConfigure $configure = new BuildConfigure(); $configure->BuildId = $build->Id; $configure->StartTime = $time; $configure->EndTime = $time; $configure->Command = 'cmake'; $configure->Log = "precontext\nWARNING: bar\npostcontext"; $configure->Status = 5; $configure->AddLabel($label); $configure->Insert(); $configure->ComputeWarnings(); $configure->ComputeErrors(); // BuildNote $note = new BuildNote(); $note->Name = 'my note'; $note->Text = 'note text'; $note->Time = $time; $note->BuildId = $build->Id; $note->Insert(); $shared_note = new BuildNote(); $shared_note->Name = 'my shared note'; $shared_note->Text = 'shared note text'; $shared_note->Time = $time; $shared_note->BuildId = $build->Id; $shared_note->Insert(); $shared_note->BuildId = $existing_build->Id; $shared_note->Insert(); // buildtesttime $build->SaveTotalTestsTime(8); // BuildUpdate $updatefile = new BuildUpdateFile(); $updatefile->Author = 'My Self'; $updatefile->Committer = 'My Self'; $updatefile->Email = '*****@*****.**'; $updatefile->CommitterEmail = '*****@*****.**'; $updatefile->Revision = 2; $updatefile->PriorRevision = 1; $updatefile->Filename = 'foo.cpp'; $updatefile->Status = 'MODIFIED'; $update = new BuildUpdate(); $update->AddFile($updatefile); $update->BuildId = $build->Id; $update->StartTime = $time; $update->EndTime = $time; $update->Command = 'git fetch'; $update->Insert(); pdo_query("INSERT INTO build2update (buildid, updateid)\n VALUES ({$existing_build->Id}, {$update->UpdateId})"); // Coverage $file1 = new CoverageFile(); $file1->FullPath = '/path/to/unshared.php'; $file1->File .= "this unshared line gets covered<br>"; $file1->File .= "this unshared line does not<br>"; $coverage1 = new Coverage(); $coverage1->Covered = 1; $coverage1->CoverageFile = $file1; $coverage1->LocTested = 1; $coverage1->LocUntested = 1; $coverage1->AddLabel($label); $file2 = new CoverageFile(); $file2->FullPath = '/path/to/shared.php'; $file2->File .= "this shared line gets covered<br>"; $file2->File .= "this shared line does not<br>"; $coverage2 = new Coverage(); $coverage2->Covered = 1; $coverage2->CoverageFile = $file2; $coverage2->LocTested = 1; $coverage2->LocUntested = 1; $coverage2->AddLabel($label); $summary = new CoverageSummary(); $summary->BuildId = $build->Id; $summary->AddCoverage($coverage1); $summary->AddCoverage($coverage2); $summary->Insert(true); $file1->TrimLastNewline(); $file1->Update($build->Id); $log1 = new CoverageFileLog(); $log1->AddLine(1, 1); $log1->BuildId = $build->Id; $log1->FileId = $file1->Id; $log1->Insert(true); $file2->TrimLastNewline(); $file2->Update($build->Id); $log2 = new CoverageFileLog(); $log2->AddLine(1, 1); $log2->BuildId = $build->Id; $log2->FileId = $file2->Id; $log2->Insert(true); // Also add coverage to existing build to test that shared files // do not get deleted. $existing_cov = new Coverage(); $existing_cov->Covered = 1; $existing_cov->CoverageFile = $file2; $existing_cov->LocTested = 1; $existing_cov->LocUntested = 1; $existing_cov->AddLabel($label); $existing_summary = new CoverageSummary(); $existing_summary->BuildId = $existing_build->Id; $existing_summary->AddCoverage($existing_cov); $existing_summary->Insert(true); $file2->Update($existing_build->Id); $existing_log = new CoverageFileLog(); $existing_log->AddLine(1, 1); $existing_log->BuildId = $existing_build->Id; $existing_log->FileId = $file2->Id; $existing_log->Insert(true); // DynamicAnalysis $DA_defect = new DynamicAnalysisDefect(); $DA_defect->Type = 'Potential Memory Leak'; $DA_defect->Value = 5; $DA = new DynamicAnalysis(); $DA->BuildId = $build->Id; $DA->Checker = 'Valgrind'; $DA->FullCommandLine = 'php DA_removebuilds.php'; $DA->Log = 'build removed successfully'; $DA->Name = 'removal test'; $DA->Path = '/path/to/removal/DA'; $DA->Status = 'failed'; $DA->AddDefect($DA_defect); $DA->AddLabel($label); $DA->Insert(); $DA_summary = new DynamicAnalysisSummary(); $DA_summary->BuildId = $build->Id; $DA_summary->Checker = 'Valgrind'; $DA_summary->AddDefects($DA_defect->Value); $DA_summary->Insert(); // Test $test = new Test(); $test->ProjectId = 1; $test->CompressedOutput = false; $test->Details = 'Completed'; $test->Name = 'removal test'; $test->Path = '/path/to/removal/test'; $test->Command = 'php test_removebuilds.php'; $test->Output = 'build removed successfully'; $measurement = new TestMeasurement(); $measurement->Name = 'Exit Value'; $measurement->Type = 'text/string'; $measurement->Value = 5; $test->AddMeasurement($measurement); $image = new Image(); $image->Extension = 'image/png'; $image->Data = 'iVBORw0KGgoAAAANSUhEUgAAABwAAAASCAMAAAB/2U7WAAAABl' . 'BMVEUAAAD///+l2Z/dAAAASUlEQVR4XqWQUQoAIAxC2/0vXZDr' . 'EX4IJTRkb7lobNUStXsB0jIXIAMSsQnWlsV+wULF4Avk9fLq2r' . '8a5HSE35Q3eO2XP1A1wQkZSgETvDtKdQAAAABJRU5ErkJggg=='; $image->Name = 'remove_me.png'; $test->AddImage($image); $test->Insert(); $buildtest = new BuildTest(); $buildtest->BuildId = $build->Id; $buildtest->TestId = $test->Id; $buildtest->Status = 'passed'; $buildtest->Insert(); $test->AddLabel($label); $test->InsertLabelAssociations($build->Id); $test2 = new Test(); $test2->ProjectId = 1; $test2->CompressedOutput = false; $test2->Details = 'Completed'; $test2->Name = 'shared test'; $test2->Path = '/path/to/shared/test'; $test2->Command = 'php test_sharedtest.php'; $test2->Output = 'test shared successfully'; $measurement2 = new TestMeasurement(); $measurement2->Name = 'Exit Value'; $measurement2->Type = 'text/string'; $measurement2->Value = 0; $test2->AddMeasurement($measurement2); $image2 = new Image(); $image2->Extension = 'image/gif'; $image2->Name = 'smile.gif'; $image2->Data = base64_encode(file_get_contents(dirname(__FILE__) . '/data/smile.gif')); $test2->AddImage($image2); $test2->Insert(); $buildtest2 = new BuildTest(); $buildtest2->BuildId = $build->Id; $buildtest2->TestId = $test2->Id; $buildtest2->Status = 'passed'; $buildtest2->Insert(); $buildtest2->BuildId = $existing_build->Id; $buildtest2->Insert(); $test2->AddLabel($label); $test2->InsertLabelAssociations($build->Id); // UploadFile $filename = dirname(__FILE__) . '/data/smile.gif'; $upload1 = new UploadFile(); $upload1->Filename = $filename; $upload1->IsUrl = false; $upload1->BuildId = $build->Id; $upload1->Sha1Sum = sha1_file($filename); $upload1->Filesize = filesize($filename); $upload1->Insert(); $filename = dirname(__FILE__) . '/data/smile2.gif'; $upload2 = new UploadFile(); $upload2->Filename = $filename; $upload2->IsUrl = false; $upload2->BuildId = $build->Id; $upload2->Sha1Sum = sha1_file($filename); $upload2->Filesize = filesize($filename); $upload2->Insert(); $upload2->BuildId = $existing_build->Id; $upload2->Insert(); // Various tables that are too hard to spoof with models so we resort // to direct insertion. pdo_query("INSERT INTO buildemail (userid, buildid, category)\n VALUES (1, {$build->Id}, 0)"); pdo_query("INSERT INTO builderrordiff\n (buildid, type, difference_positive, difference_negative)\n VALUES ({$build->Id}, 0, 1, 1)"); pdo_query("INSERT INTO configureerrordiff (buildid, type, difference)\n VALUES ({$build->Id}, 0, 1)"); pdo_query("INSERT INTO coveragesummarydiff (buildid, loctested, locuntested)\n VALUES ({$build->Id}, 1, 1)"); pdo_query("INSERT INTO summaryemail (buildid, date, groupid)\n VALUES ({$build->Id}, '{$time}', 1)"); pdo_query("INSERT INTO subproject2build (subprojectid, buildid)\n VALUES (1, {$build->Id})"); pdo_query("INSERT INTO testdiff\n (buildid, type, difference_positive, difference_negative)\n VALUES ({$build->Id}, 0, 1, 1)"); // Check that everything was created successfully. $this->verify('build', 'id', '=', $build->Id, 1); $this->verify('build2group', 'buildid', '=', $build->Id, 1); $this->verify('buildemail', 'buildid', '=', $build->Id, 1); $this->verify('builderror', 'buildid', '=', $build->Id, 1); $this->verify('builderrordiff', 'buildid', '=', $build->Id, 1); $this->verify('buildinformation', 'buildid', '=', $build->Id, 1); $this->verify('buildtesttime', 'buildid', '=', $build->Id, 1); $this->verify('configure', 'buildid', '=', $build->Id, 1); $this->verify('configureerror', 'buildid', '=', $build->Id, 1); $this->verify('configureerrordiff', 'buildid', '=', $build->Id, 1); $this->verify('coveragesummary', 'buildid', '=', $build->Id, 1); $this->verify('coveragesummarydiff', 'buildid', '=', $build->Id, 1); $this->verify('coveragefilelog', 'buildid', '=', $build->Id, 2); $this->verify('dynamicanalysissummary', 'buildid', '=', $build->Id, 1); $this->verify('summaryemail', 'buildid', '=', $build->Id, 1); $this->verify('subproject2build', 'buildid', '=', $build->Id, 1); $this->verify('testdiff', 'buildid', '=', $build->Id, 1); list($buildfailureid, $detailsid) = $this->verify_get_columns('buildfailure', ['id', 'detailsid'], 'buildid', '=', $build->Id, 1); $this->verify('buildfailure2argument', 'buildfailureid', '=', $buildfailureid, 1); $this->verify('buildfailuredetails', 'id', '=', $detailsid, 1); $noteids = $this->verify_get_rows('build2note', 'noteid', 'buildid', '=', $build->Id, 2); $this->verify('note', 'id', 'IN', $noteids, 2); $coveragefileids = $this->verify_get_rows('coverage', 'fileid', 'buildid', '=', $build->Id, 2); $this->verify('coveragefile', 'id', 'IN', $coveragefileids, 2); $dynamicanalysisid = $this->verify_get_rows('dynamicanalysis', 'id', 'buildid', '=', $build->Id, 1); $this->verify('dynamicanalysisdefect', 'dynamicanalysisid', '=', $dynamicanalysisid, 1); $testids = $this->verify_get_rows('build2test', 'testid', 'buildid', '=', $build->Id, 2); $this->verify('test', 'id', 'IN', $testids, 2); $this->verify('testmeasurement', 'testid', 'IN', $testids, 2); $imgids = $this->verify_get_rows('test2image', 'imgid', 'testid', 'IN', $testids, 2); $this->verify('image', 'id', 'IN', $imgids, 2); $updateid = $this->verify_get_rows('build2update', 'updateid', 'buildid', '=', $build->Id, 1); $this->verify('buildupdate', 'id', '=', $updateid, 1); $this->verify('updatefile', 'updateid', '=', $updateid, 1); $uploadfileids = $this->verify_get_rows('build2uploadfile', 'fileid', 'buildid', '=', $build->Id, 2); $this->verify('uploadfile', 'id', 'IN', $uploadfileids, 2); $labelid = $this->verify_get_rows('label2build', 'labelid', 'buildid', '=', $build->Id, 1); $this->verify('label', 'id', '=', $labelid, 1); $this->verify('label2buildfailure', 'labelid', '=', $labelid, 2); $this->verify('label2coveragefile', 'labelid', '=', $labelid, 3); $this->verify('label2dynamicanalysis', 'labelid', '=', $labelid, 1); $this->verify('label2test', 'labelid', '=', $labelid, 2); // Remove the build. remove_build($build->Id); // Check that everything was deleted properly. $this->verify('build', 'id', '=', $build->Id, 0, true); $this->verify('build2group', 'buildid', '=', $build->Id, 0, true); $this->verify('build2note', 'buildid', '=', $build->Id, 0, true); $this->verify('build2test', 'buildid', '=', $build->Id, 0, true); $this->verify('build2update', 'buildid', '=', $build->Id, 0, true); $this->verify('build2uploadfile', 'buildid', '=', $build->Id, 0, true); $this->verify('buildemail', 'buildid', '=', $build->Id, 0, true); $this->verify('builderror', 'buildid', '=', $build->Id, 0, true); $this->verify('builderrordiff', 'buildid', '=', $build->Id, 0, true); $this->verify('buildfailure', 'buildid', '=', $build->Id, 0, true); $this->verify('buildfailure2argument', 'buildfailureid', '=', $buildfailureid, 0, true); $this->verify('buildfailuredetails', 'id', '=', $detailsid, 1, true); $this->verify('buildinformation', 'buildid', '=', $build->Id, 0, true); $this->verify('buildtesttime', 'buildid', '=', $build->Id, 0, true); $this->verify('buildupdate', 'id', '=', $updateid, 1, true); $this->verify('configure', 'buildid', '=', $build->Id, 0, true); $this->verify('configureerror', 'buildid', '=', $build->Id, 0, true); $this->verify('configureerrordiff', 'buildid', '=', $build->Id, 0, true); $this->verify('coverage', 'buildid', '=', $build->Id, 0, true); $this->verify('coveragefile', 'id', 'IN', $coveragefileids, 1, true); $this->verify('coveragefilelog', 'buildid', '=', $build->Id, 0, true); $this->verify('coveragesummary', 'buildid', '=', $build->Id, 0, true); $this->verify('coveragesummarydiff', 'buildid', '=', $build->Id, 0, true); $this->verify('dynamicanalysis', 'buildid', '=', $build->Id, 0, true); $this->verify('dynamicanalysissummary', 'buildid', '=', $build->Id, 0, true); $this->verify('dynamicanalysisdefect', 'dynamicanalysisid', '=', $dynamicanalysisid, 0, true); $this->verify('image', 'id', 'IN', $imgids, 1, true); $this->verify('label2build', 'buildid', '=', $build->Id, 0, true); $this->verify('label2buildfailure', 'labelid', '=', $labelid, 1, true); $this->verify('label2coveragefile', 'labelid', '=', $labelid, 1, true); $this->verify('label2dynamicanalysis', 'labelid', '=', $labelid, 0, true); $this->verify('label2test', 'labelid', '=', $labelid, 0, true); $this->verify('note', 'id', 'IN', $noteids, 1, true); $this->verify('summaryemail', 'buildid', '=', $build->Id, 0, true); $this->verify('subproject2build', 'buildid', '=', $build->Id, 0, true); $this->verify('test', 'id', 'IN', $testids, 1, true); $this->verify('test2image', 'testid', 'IN', $testids, 1, true); $this->verify('testdiff', 'buildid', '=', $build->Id, 0, true); $this->verify('testmeasurement', 'testid', 'IN', $testids, 1, true); $this->verify('updatefile', 'updateid', '=', $updateid, 1, true); $this->verify('uploadfile', 'id', 'IN', $uploadfileids, 1, true); }
/** endElement function */ public function endElement($parser, $name) { parent::endElement($parser, $name); global $CDASH_DELETE_OLD_SUBPROJECTS; if (!$this->ProjectNameMatches) { return; } if ($name == 'PROJECT') { foreach ($this->SubProjects as $subproject) { if ($CDASH_DELETE_OLD_SUBPROJECTS) { // Remove dependencies that do not exist anymore, // but only for those relationships where both sides // are present in $this->SubProjects. // $dependencyids = $subproject->GetDependencies(); $removeids = array_diff($dependencyids, $this->Dependencies[$subproject->GetId()]); foreach ($removeids as $removeid) { if (array_key_exists($removeid, $this->SubProjects)) { $subproject->RemoveDependency($removeid); } else { $dep = pdo_get_field_value("SELECT name FROM subproject WHERE id='{$removeid}'", 'name', "{$removeid}"); add_log("Not removing dependency {$dep}({$removeid}) from " . $subproject->GetName() . 'because it is not a SubProject element in this Project.xml file', 'ProjectHandler:endElement', LOG_WARNING, $this->projectid); } } } // Add dependencies that were queued up as we processed the DEPENDENCY // elements: // foreach ($this->Dependencies[$subproject->GetId()] as $addid) { if (array_key_exists($addid, $this->SubProjects)) { $subproject->AddDependency($addid); } else { add_log('impossible condition: should NEVER see this: unknown DEPENDENCY clause should prevent this case', 'ProjectHandler:endElement', LOG_WARNING, $this->projectid); } } } if ($CDASH_DELETE_OLD_SUBPROJECTS) { // Delete old subprojects that weren't included in this file. $previousSubProjectIds = $this->Project->GetSubProjects(); foreach ($previousSubProjectIds as $previousId) { $found = false; foreach ($this->SubProjects as $subproject) { if ($subproject->GetId() == $previousId) { $found = true; break; } } if (!$found) { $subProjectToRemove = new SubProject(); $subProjectToRemove->SetId($previousId); $subProjectToRemove->Delete(); add_log("Deleted " . $subProjectToRemove->GetName() . " because it was not mentioned in Project.xml", 'ProjectHandler:endElement', LOG_WARNING, $this->projectid); } } } } elseif ($name == 'SUBPROJECT') { // Insert the SubProject. $this->SubProject->Save(); // Insert the label. $Label = new Label(); $Label->Text = $this->SubProject->GetName(); $Label->Insert(); $this->SubProjects[$this->SubProject->GetId()] = $this->SubProject; // Handle dependencies here too. $this->Dependencies[$this->SubProject->GetId()] = array(); foreach ($this->CurrentDependencies as $dependencyid) { $added = false; if ($dependencyid !== false && is_numeric($dependencyid)) { if (array_key_exists($dependencyid, $this->SubProjects)) { $this->Dependencies[$this->SubProject->GetId()][] = $dependencyid; $added = true; } } if (!$added) { add_log('Project.xml DEPENDENCY of ' . $this->SubProject->GetName() . ' not mentioned earlier in file.', 'ProjectHandler:endElement', LOG_WARNING, $this->projectid); } } // Check if the user is in the database. $User = new User(); $posat = strpos($this->Email, '@'); if ($posat !== false) { $User->FirstName = substr($this->Email, 0, $posat); $User->LastName = substr($this->Email, $posat + 1); } else { $User->FirstName = $this->Email; $User->LastName = $this->Email; } $User->Email = $this->Email; $User->Password = md5($this->Email); $User->Admin = 0; $userid = $User->GetIdFromEmail($this->Email); if (!$userid) { $User->Save(); $userid = $User->Id; } // Insert into the UserProject $UserProject = new UserProject(); $UserProject->EmailType = 3; // any build $UserProject->EmailCategory = 54; // everything except warnings $UserProject->UserId = $userid; $UserProject->ProjectId = $this->projectid; $UserProject->Save(); // Insert the labels for this user $LabelEmail = new LabelEmail(); $LabelEmail->UserId = $userid; $LabelEmail->ProjectId = $this->projectid; $Label = new Label(); $Label->SetText($this->SubProject->GetName()); $labelid = $Label->GetIdFromText(); if (!empty($labelid)) { $LabelEmail->LabelId = $labelid; $LabelEmail->Insert(); } } }
/** * Parse an individual .gcov file. **/ function ParseGcovFile($fileinfo) { $coverageFileLog = new CoverageFileLog(); $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; } // If this source file isn't from the source or binary directory // we shouldn't include it in our coverage report. if (strpos($path, $this->SourceDirectory) !== false) { $path = str_replace($this->SourceDirectory, ".", trim($path)); } else { if (strpos($path, $this->BinaryDirectory) !== false) { $path = str_replace($this->BinaryDirectory, ".", trim($path)); } else { return; } } $coverageFile->FullPath = $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 = trim($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; $coverage->LocUntested += 1; $this->CoverageSummary->LocUntested += 1; } else { $coverage->Covered = 1; $coverage->LocTested += 1; $this->CoverageSummary->LocTested += 1; } $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; } else { if (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); } } } // Get the ID for this coverage file, or create a new empty one //if it doesn't already exist. $sql = pdo_query("SELECT id FROM coveragefile WHERE fullpath='{$path}' AND file IS NULL"); if (pdo_num_rows($sql) == 0) { pdo_query("INSERT INTO coveragefile (fullpath) VALUES ('{$path}')"); $fileid = pdo_insert_id("coveragefile"); } else { $coveragefile_array = pdo_fetch_array($sql); $fileid = $coveragefile_array["id"]; } $coverageFile->Id = $fileid; // Save these models to the database. $coverageFile->Update($this->BuildId); $coverageFileLog->BuildId = $this->BuildId; $coverageFileLog->FileId = $coverageFile->Id; $coverageFileLog->Insert(); // 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. $this->CoverageSummary->AddCoverage($coverage); }
/** startElement function */ public function startElement($parser, $name, $attributes) { parent::startElement($parser, $name, $attributes); // Check that the project name matches if ($name == 'PROJECT') { if (get_project_id($attributes['NAME']) != $this->projectid) { add_log("Wrong project name: " . $attributes['NAME'], "ProjectHandler::startElement", LOG_ERR, $this->projectid); $this->ProjectNameMatches = false; } } if (!$this->ProjectNameMatches) { return; } if ($name == 'PROJECT') { $this->SubProjects = array(); $this->Dependencies = array(); } else { if ($name == 'SUBPROJECT') { $this->SubProject = new SubProject(); $this->SubProject->SetProjectId($this->projectid); $this->SubProject->SetName($attributes['NAME']); if (array_key_exists("GROUP", $attributes)) { $this->SubProject->SetGroup($attributes['GROUP']); } $this->SubProject->Save(); // Insert the label $Label = new Label(); $Label->Text = $this->SubProject->GetName(); $Label->Insert(); $this->SubProjects[$this->SubProject->GetId()] = $this->SubProject; $this->Dependencies[$this->SubProject->GetId()] = array(); } else { if ($name == 'DEPENDENCY') { // A DEPENDENCY is expected to be: // // - another subproject that already exists (from a previous element in // this submission) // $dependentProject = new SubProject(); $dependentProject->SetName($attributes['NAME']); $dependentProject->SetProjectId($this->projectid); // The subproject's Id is automatically loaded once its name & projectid // are set. $dependencyid = $dependentProject->GetId(); $added = false; if ($dependencyid !== false && is_numeric($dependencyid)) { if (array_key_exists($dependencyid, $this->SubProjects)) { $this->Dependencies[$this->SubProject->GetId()][] = $dependencyid; $added = true; } } if (!$added) { add_log("Project.xml DEPENDENCY of " . $this->SubProject->GetName() . " not mentioned earlier in file: " . $attributes['NAME'], "ProjectHandler:startElement", LOG_WARNING, $this->projectid); } } else { if ($name == 'EMAIL') { $email = $attributes['ADDRESS']; // Check if the user is in the database $User = new User(); $posat = strpos($email, '@'); if ($posat !== false) { $User->FirstName = substr($email, 0, $posat); $User->LastName = substr($email, $posat + 1); } else { $User->FirstName = $email; $User->LastName = $email; } $User->Email = $email; $User->Password = md5($email); $User->Admin = 0; $userid = $User->GetIdFromEmail($email); if (!$userid) { $User->Save(); $userid = $User->Id; } // Insert into the UserProject $UserProject = new UserProject(); $UserProject->EmailType = 3; // any build $UserProject->EmailCategory = 54; // everything except warnings $UserProject->UserId = $userid; $UserProject->ProjectId = $this->projectid; $UserProject->Save(); // Insert the labels for this user $LabelEmail = new LabelEmail(); $LabelEmail->UserId = $userid; $LabelEmail->ProjectId = $this->projectid; $Label = new Label(); $Label->SetText($this->SubProject->GetName()); $labelid = $Label->GetIdFromText(); if (!empty($labelid)) { $LabelEmail->LabelId = $labelid; $LabelEmail->Insert(); } } } } } }