public function testSetupRepositories()
 {
     $insight = new Project();
     $row = pdo_single_row_query("SELECT id FROM project where name='InsightExample'");
     $insight->Id = $row['id'];
     $insight->Fill();
     $insight->AddRepositories(array(':pserver:anoncvs@itk.org:/cvsroot/Insight'), array('anoncvs'), array(''), array(''));
     $insight->CTestTemplateScript = 'client testing works';
     $insight->Save();
     $pub = new Project();
     $row = pdo_single_row_query("SELECT id FROM project where name='PublicDashboard'");
     $pub->Id = $row['id'];
     $pub->Fill();
     $pub->AddRepositories(array('git://cmake.org/cmake.git'), array(''), array(''), array(''));
     $pub->CvsViewerType = 'gitweb';
     $pub->CvsUrl = 'cmake.org/gitweb?p=cmake.git';
     $pub->Save();
     $email = new Project();
     $row = pdo_single_row_query("SELECT id FROM project where name='EmailProjectExample'");
     $email->Id = $row['id'];
     $email->Fill();
     $email->AddRepositories(array('https://www.kitware.com/svn/CDash/trunk'), array(''), array(''), array(''));
     $pub->CvsViewerType = 'websvn';
     $email->CvsUrl = 'https://www.kitware.com/svn/CDash/trunk';
     $email->Save();
 }
 private function expectedTest($buildname, $projectname)
 {
     // Mark an old build as expected.
     $query = "\n            SELECT b.siteid, b.type, g.id AS groupid FROM build AS b\n            INNER JOIN build2group AS b2g ON (b.id=b2g.buildid)\n            INNER JOIN buildgroup AS g ON (b2g.groupid=g.id)\n            WHERE b.name='{$buildname}'";
     if ($projectname === 'Trilinos') {
         $query .= ' AND b.parentid=-1';
     }
     $build_row = pdo_single_row_query($query);
     $groupid = $build_row['groupid'];
     $buildtype = $build_row['type'];
     $siteid = $build_row['siteid'];
     if (!pdo_query("\n                    INSERT INTO build2grouprule(groupid,buildtype,buildname,siteid,expected,starttime,endtime)\n                    VALUES ('{$groupid}','{$buildtype}','{$buildname}','{$siteid}','1','2013-01-01 00:00:00','1980-01-01 00:00:00')")) {
         $this->fail("Error marking {$buildname} as expected");
         return 1;
     }
     // Verify that our API lists this build even though it hasn't submitted today.
     $this->get($this->url . "/api/v1/index.php?project={$projectname}");
     $content = $this->getBrowser()->getContent();
     $jsonobj = json_decode($content, true);
     $buildgroup = array_pop($jsonobj['buildgroups']);
     $found = false;
     foreach ($buildgroup['builds'] as $build) {
         if ($build['buildname'] == $buildname && $build['expectedandmissing'] == 1) {
             $found = true;
         }
     }
     // Make it unexpected again.
     pdo_query("DELETE FROM build2grouprule WHERE buildname='{$buildname}'");
     if (!$found) {
         $this->fail("Expected missing build '{$buildname}' not included");
         return 1;
     }
     $this->pass('Passed');
     return 0;
 }
Example #3
0
 public function testTruncateOutput()
 {
     // Set a limit so long output will be truncated.
     $this->addLineToConfig($this->ConfigLine);
     // Submit our testing data.
     $rep = dirname(__FILE__) . "/data/TruncateOutput";
     if (!$this->submission('InsightExample', "{$rep}/Build.xml")) {
         $this->fail("failed to submit Build.xml");
         $this->cleanup();
         return 1;
     }
     // Query for the ID of the build that we just created.
     $buildid_results = pdo_single_row_query("SELECT id FROM build WHERE name='TruncateOutput'");
     $this->BuildId = $buildid_results['id'];
     // Verify that the output was properly truncated.
     $this->get($this->url . "/api/v1/viewBuildError.php?buildid=" . $this->BuildId);
     $content = $this->getBrowser()->getContent();
     $jsonobj = json_decode($content, true);
     foreach ($jsonobj['errors'] as $error) {
         if ($error['stdoutput'] != $this->Expected) {
             $this->fail("Expected {$this->Expected}, found " . $error['stdoutput']);
             $this->cleanup();
             return 1;
         }
         if ($error['stderror'] != $this->Expected) {
             $this->fail("Expected {$this->Expected}, found " . $error['stderror']);
             $this->cleanup();
             return 1;
         }
     }
     $this->cleanup();
     $this->pass("Passed");
     return 0;
 }
Example #4
0
function echo_currently_processing_submissions()
{
    include "cdash/config.php";
    if ($CDASH_DB_TYPE == "pgsql") {
        $sql_query = "SELECT now() AT TIME ZONE 'UTC'";
    } else {
        $sql_query = "SELECT UTC_TIMESTAMP()";
    }
    $current_time = pdo_single_row_query($sql_query);
    $sql_query = "SELECT project.name, submission.*, ";
    if ($CDASH_DB_TYPE == "pgsql") {
        $sql_query .= "round((extract(EPOCH FROM now() - created)/3600)::numeric, 2) AS hours_ago ";
    } else {
        $sql_query .= "ROUND(TIMESTAMPDIFF(SECOND, created, UTC_TIMESTAMP)/3600, 2) AS hours_ago ";
    }
    $sql_query .= "FROM " . qid("project") . ", " . qid("submission") . " " . "WHERE project.id = submission.projectid AND status = 1";
    $rows = pdo_all_rows_query($sql_query);
    $sep = ', ';
    echo "<h3>Currently Processing Submissions as of " . $current_time[0] . " UTC</h3>";
    echo '<pre>';
    if (count($rows) > 0) {
        echo 'project name, backlog in hours' . "\n";
        echo '    submission.id, filename, projectid, status, attempts, filesize, filemd5sum, lastupdated, created, started, finished' . "\n";
        echo "\n";
        foreach ($rows as $row) {
            echo $row['name'] . $sep . $row['hours_ago'] . ' hours behind' . "\n";
            echo "    " . $row['id'] . $sep . $row['filename'] . $sep . $row['projectid'] . $sep . $row['status'] . $sep . $row['attempts'] . $sep . $row['filesize'] . $sep . $row['filemd5sum'] . $sep . $row['lastupdated'] . $sep . $row['created'] . $sep . $row['started'] . $sep . $row['finished'] . "\n";
            echo "\n";
        }
    } else {
        echo 'Nothing is currently processing...' . "\n";
    }
    echo '</pre>';
    echo '<br/>';
}
Example #5
0
 function MD5Exists()
 {
     $md5 = pdo_real_escape_string($this->md5);
     $row = pdo_single_row_query("SELECT buildid FROM buildfile WHERE md5='" . $md5 . "'");
     if (empty($row)) {
         return false;
     }
     return $row[0];
 }
Example #6
0
File: pdo.php Project: rpshaw/CDash
function pdo_get_field_value($qry, $fieldname, $default)
{
    $row = pdo_single_row_query($qry);
    if (!empty($row)) {
        $f = $row["{$fieldname}"];
    } else {
        $f = $default;
    }
    return $f;
}
Example #7
0
 public function testBuildGetDate()
 {
     $retval = 0;
     $build = new Build();
     $build->Id = 1;
     $build->ProjectId = 1;
     $build->Filled = true;
     $row = pdo_single_row_query('SELECT nightlytime FROM project WHERE id=1');
     $original_nightlytime = $row['nightlytime'];
     // Test the case where the project's start time is in the evening.
     pdo_query("UPDATE project SET nightlytime = '20:00:00' WHERE id=1");
     $build->StartTime = date('Y-m-d H:i:s', strtotime('2009-02-23 19:59:59'));
     $expected_date = '2009-02-23';
     $date = $build->GetDate();
     if ($date !== $expected_date) {
         $this->fail("Evening case: expected {$expected_date}, found {$date}");
         $retval = 1;
     }
     $build->StartTime = date('Y-m-d H:i:s', strtotime('2009-02-23 20:00:00'));
     $expected_date = '2009-02-24';
     $build->NightlyStartTime = false;
     $date = $build->GetDate();
     if ($date !== $expected_date) {
         $this->fail("Evening case: expected {$expected_date}, found {$date}");
         $retval = 1;
     }
     // Test the case where the project's start time is in the morning.
     pdo_query("UPDATE project SET nightlytime = '09:00:00' WHERE id=1");
     $build->StartTime = date('Y-m-d H:i:s', strtotime('2009-02-23 08:59:59'));
     $expected_date = '2009-02-22';
     $build->NightlyStartTime = false;
     $date = $build->GetDate();
     if ($date !== $expected_date) {
         $this->fail("Morning case: expected {$expected_date}, found {$date}");
         $retval = 1;
     }
     $build->StartTime = date('Y-m-d H:i:s', strtotime('2009-02-23 09:00:00'));
     $expected_date = '2009-02-23';
     $build->NightlyStartTime = false;
     $date = $build->GetDate();
     if ($date !== $expected_date) {
         $this->fail("Morning case: expected {$expected_date}, found {$date}");
         $retval = 1;
     }
     pdo_query("UPDATE project SET nightlytime = '{$original_nightlytime}' WHERE id=1");
     if ($retval === 0) {
         $this->pass('Tests passed');
     }
     return $retval;
 }
Example #8
0
 /** Return whether or not a CoverageSummaryDiff exists for this build. */
 public function Exists()
 {
     if (!$this->BuildId) {
         return false;
     }
     $exists_result = pdo_single_row_query('SELECT COUNT(1) AS numrows FROM coveragesummarydiff
             WHERE buildid=' . qnum($this->BuildId));
     if ($exists_result && array_key_exists('numrows', $exists_result)) {
         $numrows = $exists_result['numrows'];
         if ($numrows > 0) {
             return true;
         }
     }
     return false;
 }
Example #9
0
function get_dynamic_builds($projectid, $end_UTCDate)
{
    $builds = array();
    // Get the build rules for each dynamic group belonging to this project.
    $rules = pdo_query("\n    SELECT b2gr.buildname, b2gr.siteid, b2gr.parentgroupid, bg.id, bg.name,\n           bg.type, gp.position\n    FROM build2grouprule AS b2gr\n    LEFT JOIN buildgroup AS bg ON (bg.id = b2gr.groupid)\n    LEFT JOIN buildgroupposition AS gp ON (gp.buildgroupid=bg.id)\n    WHERE bg.projectid='{$projectid}' AND bg.endtime='1980-01-01 00:00:00' AND\n          bg.type != 'Daily'");
    if (!$rules) {
        echo pdo_error();
        return;
    }
    while ($rule = pdo_fetch_array($rules)) {
        $buildgroup_name = $rule['name'];
        $buildgroup_id = $rule['id'];
        $buildgroup_position = $rule['position'];
        if ($rule['type'] == 'Latest') {
            // optional fields: parentgroupid, site, and build name match.
            // Use these to construct a WHERE clause for our query.
            $where = '';
            $whereClauses = array();
            if (!empty($rule['parentgroupid'])) {
                $whereClauses[] = "b2g.groupid='" . $rule['parentgroupid'] . "'";
            }
            if (!empty($rule['siteid'])) {
                $whereClauses[] = "s.id='" . $rule['siteid'] . "'";
            }
            if (!empty($rule['buildname'])) {
                $whereClauses[] = "b.name LIKE '" . $rule['buildname'] . "'";
            }
            if (!empty($whereClauses)) {
                $where = 'WHERE ' . implode($whereClauses, ' AND ');
                $where .= " AND b.starttime<'{$end_UTCDate}'";
            }
            // We only want the most recent build.
            $order = 'ORDER BY b.submittime DESC LIMIT 1';
            $sql = get_index_query();
            $sql .= "{$where} {$order}";
            $build = pdo_single_row_query($sql);
            if (empty($build)) {
                continue;
            }
            $build['groupname'] = $buildgroup_name;
            $build['groupid'] = $buildgroup_id;
            $build['position'] = $buildgroup_position;
            $builds[] = $build;
        }
    }
    return $builds;
}
Example #10
0
function get_dynamic_builds($projectid)
{
    $builds = array();
    // Get the build rules for each dynamic group belonging to this project.
    $rules = pdo_query("\n    SELECT b2gr.buildname, b2gr.siteid, b2gr.parentgroupid, bg.id, bg.name,\n           bg.type, gp.position\n    FROM build2grouprule AS b2gr\n    LEFT JOIN buildgroup AS bg ON (bg.id = b2gr.groupid)\n    LEFT JOIN buildgroupposition AS gp ON (gp.buildgroupid=bg.id)\n    WHERE bg.projectid='{$projectid}' AND bg.endtime='1980-01-01 00:00:00' AND\n          bg.type != 'Daily'");
    if (!$rules) {
        echo pdo_error();
        return;
    }
    while ($rule = pdo_fetch_array($rules)) {
        $buildgroup_name = $rule['name'];
        $buildgroup_id = $rule['id'];
        $buildgroup_position = $rule['position'];
        if ($rule['type'] == 'Latest') {
            // optional fields: parentgroupid, site, and build name match.
            // Use these to construct a WHERE clause for our query.
            $where = "";
            $whereClauses = array();
            if (!empty($rule['parentgroupid'])) {
                $whereClauses[] = "b2g.groupid='" . $rule['parentgroupid'] . "'";
            }
            if (!empty($rule['siteid'])) {
                $whereClauses[] = "s.id='" . $rule['siteid'] . "'";
            }
            if (!empty($rule['buildname'])) {
                $whereClauses[] = "b.name LIKE '" . $rule['buildname'] . "'";
            }
            if (!empty($whereClauses)) {
                $where = "WHERE " . implode($whereClauses, " AND ");
            }
            // We only want the most recent build.
            $order = "ORDER BY b.submittime DESC LIMIT 1";
            // Copied from index.php.
            $sql = "SELECT b.id,b.siteid,b.parentid,\n              bu.status AS updatestatus,\n              i.osname AS osname,\n              bu.starttime AS updatestarttime,\n              bu.endtime AS updateendtime,\n              bu.nfiles AS countupdatefiles,\n              bu.warnings AS countupdatewarnings,\n              c.status AS configurestatus,\n              c.starttime AS configurestarttime,\n              c.endtime AS configureendtime,\n              be_diff.difference_positive AS countbuilderrordiffp,\n              be_diff.difference_negative AS countbuilderrordiffn,\n              bw_diff.difference_positive AS countbuildwarningdiffp,\n              bw_diff.difference_negative AS countbuildwarningdiffn,\n              ce_diff.difference AS countconfigurewarningdiff,\n              btt.time AS testsduration,\n              tnotrun_diff.difference_positive AS counttestsnotrundiffp,\n              tnotrun_diff.difference_negative AS counttestsnotrundiffn,\n              tfailed_diff.difference_positive AS counttestsfaileddiffp,\n              tfailed_diff.difference_negative AS counttestsfaileddiffn,\n              tpassed_diff.difference_positive AS counttestspasseddiffp,\n              tpassed_diff.difference_negative AS counttestspasseddiffn,\n              tstatusfailed_diff.difference_positive AS countteststimestatusfaileddiffp,\n              tstatusfailed_diff.difference_negative AS countteststimestatusfaileddiffn,\n              (SELECT count(buildid) FROM build2note WHERE buildid=b.id)  AS countnotes,\n              (SELECT count(buildid) FROM buildnote WHERE buildid=b.id) AS countbuildnotes,\n              s.name AS sitename,\n              s.outoforder AS siteoutoforder,\n              b.stamp,b.name,b.type,b.generator,b.starttime,b.endtime,b.submittime,\n              b.configureerrors AS countconfigureerrors,\n              b.configurewarnings AS countconfigurewarnings,\n              b.builderrors AS countbuilderrors,\n              b.buildwarnings AS countbuildwarnings,\n              b.testnotrun AS counttestsnotrun,\n              b.testfailed AS counttestsfailed,\n              b.testpassed AS counttestspassed,\n              b.testtimestatusfailed AS countteststimestatusfailed,\n              sp.id AS subprojectid,\n              sp.groupid AS subprojectgroup,\n              (SELECT count(buildid) FROM errorlog WHERE buildid=b.id) AS nerrorlog,\n              (SELECT count(buildid) FROM build2uploadfile WHERE buildid=b.id) AS builduploadfiles\n              FROM build AS b\n              LEFT JOIN build2group AS b2g ON (b2g.buildid=b.id)\n              LEFT JOIN buildgroup AS g ON (g.id=b2g.groupid)\n              LEFT JOIN site AS s ON (s.id=b.siteid)\n              LEFT JOIN build2update AS b2u ON (b2u.buildid=b.id)\n              LEFT JOIN buildupdate AS bu ON (b2u.updateid=bu.id)\n              LEFT JOIN configure AS c ON (c.buildid=b.id)\n              LEFT JOIN buildinformation AS i ON (i.buildid=b.id)\n              LEFT JOIN builderrordiff AS be_diff ON (be_diff.buildid=b.id AND be_diff.type=0)\n              LEFT JOIN builderrordiff AS bw_diff ON (bw_diff.buildid=b.id AND bw_diff.type=1)\n              LEFT JOIN configureerrordiff AS ce_diff ON (ce_diff.buildid=b.id AND ce_diff.type=1)\n              LEFT JOIN buildtesttime AS btt ON (btt.buildid=b.id)\n              LEFT JOIN testdiff AS tnotrun_diff ON (tnotrun_diff.buildid=b.id AND tnotrun_diff.type=0)\n              LEFT JOIN testdiff AS tfailed_diff ON (tfailed_diff.buildid=b.id AND tfailed_diff.type=1)\n              LEFT JOIN testdiff AS tpassed_diff ON (tpassed_diff.buildid=b.id AND tpassed_diff.type=2)\n              LEFT JOIN testdiff AS tstatusfailed_diff ON (tstatusfailed_diff.buildid=b.id AND tstatusfailed_diff.type=3)\n              LEFT JOIN subproject2build AS sp2b ON (sp2b.buildid = b.id)\n              LEFT JOIN subproject as sp ON (sp2b.subprojectid = sp.id)\n              LEFT JOIN label2build AS l2b ON (l2b.buildid = b.id)\n              LEFT JOIN label AS l ON (l.id = l2b.labelid) {$where} {$order}";
            $build = pdo_single_row_query($sql);
            if (empty($build)) {
                continue;
            }
            $build['groupname'] = $buildgroup_name;
            $build['groupid'] = $buildgroup_id;
            $build['position'] = $buildgroup_position;
            $builds[] = $build;
        }
    }
    return $builds;
}
Example #11
0
 public function testNotesAPI()
 {
     echo "1. testNotesAPI\n";
     // Find the smallest buildid that has more than one note.
     // This was 13 at the time this test was written, but things
     // like this have a habit of changing.
     $buildid_result = pdo_single_row_query('SELECT buildid, COUNT(1) FROM build2note
    GROUP BY buildid HAVING COUNT(1) > 1 ORDER BY buildid LIMIT 1');
     if (empty($buildid_result)) {
         $this->fail('No build found with multiple notes');
         return 1;
     }
     $buildid = $buildid_result['buildid'];
     // Use the API to get the notes for this build.
     $this->get($this->url . "/api/v1/viewNotes.php?buildid={$buildid}");
     $response = json_decode($this->getBrowser()->getContentAsText(), true);
     // Verify some details about this builds notes.
     $numNotes = count($response['notes']);
     if ($numNotes != 2) {
         $this->fail("Expected two notes, found {$numNotes}");
         return 1;
     }
     $driverFound = false;
     $cronFound = false;
     foreach ($response['notes'] as $note) {
         if (strpos($note['name'], 'TrilinosDriverDashboard.cmake') !== false) {
             $driverFound = true;
         }
         if (strpos($note['name'], 'cron_driver.bat') !== false) {
             $cronFound = true;
         }
     }
     if ($driverFound === false) {
         $this->fail('Expected to find a note named TrilinosDriverDashboard.cmake');
         return 1;
     }
     if ($cronFound === false) {
         $this->fail('Expected to find a note named cron_driver.bat');
         return 1;
     }
     $this->pass('Passed');
     return 0;
 }
 public function testExternalLinksFromTests()
 {
     // Submit our testing data.
     $file_to_submit = dirname(__FILE__) . '/data/ExternalLinksFromTests/Test.xml';
     if (!$this->submission('InsightExample', $file_to_submit)) {
         $this->fail("Failed to submit {$file_to_submit}");
         return 1;
     }
     // Get the IDs for the build and test that we just created.
     $result = pdo_single_row_query("SELECT id FROM build WHERE name = 'test_output_link'");
     $buildid = $result['id'];
     $result = pdo_single_row_query("SELECT testid FROM build2test WHERE buildid={$buildid}");
     $testid = $result['testid'];
     // Use the API to verify that our external link was parsed properly.
     $this->get($this->url . "/api/v1/testDetails.php?test={$testid}&build={$buildid}");
     $content = $this->getBrowser()->getContent();
     $jsonobj = json_decode($content, true);
     $measurement = array_pop($jsonobj['test']['measurements']);
     $success = true;
     $error_msg = '';
     if ($measurement['name'] !== 'Interesting website') {
         $error_msg = "Expected name to be 'Interesting website', instead found " . $measurement['name'];
         $success = false;
     }
     if ($measurement['type'] !== 'text/link') {
         $error_msg = "Expected type to be 'text/link', instead found " . $measurement['type'];
         $success = false;
     }
     if ($measurement['value'] !== 'http://www.google.com') {
         $error_msg = "Expected value to be 'http://www.google.com', instead found " . $measurement['value'];
         $success = false;
     }
     // Delete the build that we created during this test.
     remove_build($buildid);
     if (!$success) {
         $this->fail($error_msg);
         return 1;
     }
     $this->pass('Tests passed');
     return 0;
 }
Example #13
0
 public function onlyColumn($method)
 {
     // Submit our testing file.
     $rep = dirname(__FILE__) . '/data/HideColumns';
     if (!$this->submission('InsightExample', "{$rep}/{$method}.xml")) {
         return false;
     }
     // Use our API to verify which columns will be displayed.
     $content = $this->connect($this->url . '/api/v1/index.php?project=InsightExample&date=2015-10-06');
     $jsonobj = json_decode($content, true);
     $buildgroup = array_pop($jsonobj['buildgroups']);
     $retval = false;
     switch ($method) {
         case 'Update':
             if ($buildgroup['hasupdatedata'] == true && $buildgroup['hasconfiguredata'] == false && $buildgroup['hascompilationdata'] == false && $buildgroup['hastestdata'] == false) {
                 $retval = true;
             }
             break;
         case 'Configure':
             if ($buildgroup['hasupdatedata'] == false && $buildgroup['hasconfiguredata'] == true && $buildgroup['hascompilationdata'] == false && $buildgroup['hastestdata'] == false) {
                 $retval = true;
             }
             break;
         case 'Build':
             if ($buildgroup['hasupdatedata'] == false && $buildgroup['hasconfiguredata'] == false && $buildgroup['hascompilationdata'] == true && $buildgroup['hastestdata'] == false) {
                 $retval = true;
             }
             break;
         case 'Test':
             if ($buildgroup['hasupdatedata'] == false && $buildgroup['hasconfiguredata'] == false && $buildgroup['hascompilationdata'] == false && $buildgroup['hastestdata'] == true) {
                 $retval = true;
             }
             break;
     }
     // Remove the build that we just created.
     $buildid_results = pdo_single_row_query("SELECT id FROM build WHERE name='HideColumns'");
     $buildid = $buildid_results['id'];
     remove_build($buildid);
     return $retval;
 }
 public function testParallelSubmissions()
 {
     // Delete the existing Trilinos build.
     $row = pdo_single_row_query("SELECT id FROM build\n                WHERE parentid=-1 AND\n                projectid=(SELECT id FROM project WHERE name='Trilinos') AND\n                name='Windows_NT-MSVC10-SERIAL_DEBUG_DEV' AND\n                starttime BETWEEN '2011-07-22 00:00:00' AND '2011-07-22 23:59:59'");
     remove_build($row['id']);
     // Disable submission processing so that the queue will accumulate.
     $this->addLineToConfig($this->DisableProcessingConfig);
     // Re-submit the Trilinos build.
     $begin = time();
     $this->submitFiles('ActualTrilinosSubmission', true);
     echo 'Submission took ' . (time() - $begin) . " seconds.\n";
     // Re-enable submission processing and enable parallel processing
     $this->removeLineFromConfig($this->DisableProcessingConfig);
     $this->addLineToConfig($this->ParallelProcessingConfig);
     // Submit another file to Trilinos to start the processing loop.
     $file = dirname(__FILE__) . '/data/SubProjectNextPrevious/Build_1.xml';
     $this->submission('Trilinos', $file);
     // Wait for processing to complete.
     $todo = 999;
     $begin = time();
     while ($todo > 0) {
         $row = pdo_single_row_query('SELECT count(1) AS todo
                 FROM submission WHERE status=0 OR status=1');
         $todo = $row['todo'];
         sleep(1);
         if (time() - $begin > 120) {
             $this->fail("Processing took longer than 120 seconds.\n");
             break;
         }
     }
     echo 'Processing took ' . (time() - $begin) . " seconds.\n";
     // Verify the results.
     $this->verifyResults();
     // Clean up by reverting our config settings and deleting the
     // extra build that we created to trigger the processing.
     $this->removeLineFromConfig($this->ParallelProcessingConfig);
     $row = pdo_single_row_query("SELECT build.id FROM build\n                WHERE build.parentid=-1 AND\n                projectid=(SELECT id FROM project WHERE name='Trilinos') AND\n                stamp='20110723-1515-Experimental'");
     remove_build($row['id']);
 }
Example #15
0
require_once "filterdataFunctions.php";
@($date = $_GET["date"]);
if ($date != NULL) {
    $date = htmlspecialchars(pdo_real_escape_string($date));
}
@($projectname = $_GET["project"]);
if ($projectname != NULL) {
    $projectname = htmlspecialchars(pdo_real_escape_string($projectname));
}
$start = microtime_float();
$db = pdo_connect("{$CDASH_DB_HOST}", "{$CDASH_DB_LOGIN}", "{$CDASH_DB_PASS}");
pdo_select_db("{$CDASH_DB_NAME}", $db);
if ($projectname == '') {
    $project = pdo_single_row_query("SELECT * FROM project LIMIT 1");
} else {
    $project = pdo_single_row_query("SELECT * FROM project WHERE name='{$projectname}'");
}
checkUserPolicy(@$_SESSION['cdash']['loginid'], $project['id']);
list($previousdate, $currentstarttime, $nextdate) = get_dates($date, $project['nightlytime']);
$xml = begin_XML_for_XSLT();
$xml .= "<title>CDash : " . $project['name'] . "</title>";
$xml .= get_cdash_dashboard_xml_by_name($project['name'], $date);
// Filters:
//
$filterdata = get_filterdata_from_request();
$filter_sql = $filterdata['sql'];
$limit_sql = '';
if ($filterdata['limit'] > 0) {
    $limit_sql = ' LIMIT ' . $filterdata['limit'];
}
$xml .= $filterdata['xml'];
Example #16
0
 /**
  * Update the tally of configure errors & warnings for this build's
  * parent.
  **/
 function UpdateParentConfigureNumbers($newWarnings, $newErrors)
 {
     $this->ParentId = $this->GetParentBuildId();
     if ($this->ParentId < 1) {
         return;
     }
     $numErrors = 0;
     $numWarnings = 0;
     $parent = pdo_single_row_query("SELECT configureerrors, configurewarnings\n       FROM build WHERE id=" . qnum($this->ParentId));
     // Don't let the -1 default value screw up our math.
     if ($parent['configureerrors'] == -1) {
         $parent['configureerrors'] = 0;
     }
     if ($parent['configurewarnings'] == -1) {
         $parent['configurewarnings'] = 0;
     }
     $numErrors = $newErrors + $parent['configureerrors'];
     $numWarnings = $newWarnings + $parent['configurewarnings'];
     pdo_query("UPDATE build SET configureerrors='{$numErrors}',\n                        configurewarnings='{$numWarnings}'\n                    WHERE id=" . qnum($this->ParentId));
     add_last_sql_error("Build:UpdateParentConfigureNumbers", $this->ProjectId, $this->Id);
 }
Example #17
0
/** Function to deal with the external tool mechanism */
function put_submit_file()
{
    include "models/buildfile.php";
    // We expect GET to contain the following values:
    $vars = array('buildid', 'type');
    foreach ($vars as $var) {
        if (!isset($_GET[$var]) || empty($_GET[$var])) {
            $response_array['status'] = 1;
            $response_array['description'] = 'Variable \'' . $var . '\' not set but required.';
            echo json_encode($response_array);
            return;
        }
    }
    // Verify buildid.
    if (!is_numeric($_GET['buildid'])) {
        $response_array['status'] = 1;
        $response_array['description'] = 'Variable \'buildid\' is not numeric.';
        echo json_encode($response_array);
        return;
    }
    // Abort early if we already have this file.
    $buildfile = new BuildFile();
    $buildfile->BuildId = $_GET['buildid'];
    $buildfile->Type = htmlspecialchars(pdo_real_escape_string($_GET['type']));
    $buildfile->md5 = htmlspecialchars(pdo_real_escape_string($_GET['md5']));
    $buildfile->Filename = htmlspecialchars(pdo_real_escape_string($_GET['filename']));
    if (!$buildfile->Insert()) {
        $response_array['status'] = 1;
        $response_array['description'] = 'Cannot insert buildfile into database. The file might already exist.';
        echo json_encode($response_array);
        return;
    }
    // Get the ID of the project associated with this build.
    $row = pdo_single_row_query("SELECT projectid FROM build WHERE id = {$buildfile->BuildId}");
    if (empty($row)) {
        $response_array['status'] = 1;
        $response_array['description'] = "Cannot find projectid for build #{$buildfile->BuildId}";
        echo json_encode($response_array);
        return;
    }
    $projectid = $row[0];
    // Begin writing this file to the backup directory.
    global $CDASH_BACKUP_DIRECTORY;
    $uploadDir = $CDASH_BACKUP_DIRECTORY;
    $ext = pathinfo($buildfile->Filename, PATHINFO_EXTENSION);
    $filename = $uploadDir . "/" . $buildfile->BuildId . "_" . $buildfile->md5 . ".{$ext}";
    if (!($handle = fopen($filename, 'w'))) {
        $response_array['status'] = 1;
        $response_array['description'] = "Cannot open file ({$filename})";
        echo json_encode($response_array);
        return;
    }
    // Read the data 1 KB at a time and write to the file.
    $putdata = fopen("php://input", "r");
    while ($data = fread($putdata, 1024)) {
        fwrite($handle, $data);
    }
    // Close the streams.
    fclose($handle);
    fclose($putdata);
    // Check that the md5sum of the file matches what we were expecting.
    $md5sum = md5_file($filename);
    if ($md5sum != $buildfile->md5) {
        $response_array['status'] = 1;
        $response_array['description'] = "md5 mismatch. expected: {$buildfile->md5}, received: {$md5sum}";
        unlink($filename);
        $buildfile->Delete();
        echo json_encode($response_array);
        return;
    }
    global $CDASH_ASYNCHRONOUS_SUBMISSION;
    if ($CDASH_ASYNCHRONOUS_SUBMISSION) {
        // Create a new entry in the submission table for this file.
        $bytes = filesize($filename);
        $now_utc = gmdate(FMT_DATETIMESTD);
        pdo_query("INSERT INTO submission (filename,projectid,status,attempts,filesize,filemd5sum,created) " . "VALUES ('{$filename}','{$projectid}','0','0','{$bytes}','{$buildfile->md5}','{$now_utc}')");
        // Trigger the processing loop in case it's not already running.
        trigger_process_submissions($projectid);
    } else {
        // synchronous processing.
        $handle = fopen($filename, 'r');
        do_submit($handle, $projectid, $buildfile->md5, false);
        // The file is given a more appropriate name during do_submit, so we can
        // delete the old file now.
        unlink($filename);
    }
    // Returns the OK submission
    $response_array['status'] = 0;
    echo json_encode($response_array);
}
Example #18
0
//
if ($projectdisplaylabels) {
    // Get the set of labels involved:
    //
    $labels = array();
    $covlabels = pdo_all_rows_query('SELECT DISTINCT id, text FROM label, label2coveragefile WHERE ' . 'label.id=label2coveragefile.labelid AND ' . 'label2coveragefile.buildid=' . qnum($buildid));
    foreach ($covlabels as $row) {
        $labels[$row['id']] = $row['text'];
    }
    // For each label, compute the percentcoverage for files with
    // that label:
    //
    if (count($labels) > 0) {
        $xml .= '<labels>';
        foreach ($labels as $id => $label) {
            $row = pdo_single_row_query('SELECT COUNT(*) AS c, SUM(loctested) AS loctested, SUM(locuntested) AS locuntested ' . 'FROM label2coveragefile, coverage WHERE ' . 'label2coveragefile.labelid=' . qnum($id) . ' AND ' . 'label2coveragefile.buildid=' . qnum($buildid) . ' AND ' . 'coverage.buildid=label2coveragefile.buildid AND ' . 'coverage.fileid=label2coveragefile.coveragefileid');
            $loctested = $row['loctested'];
            $locuntested = $row['locuntested'];
            $percentcoverage = compute_percentcoverage($loctested, $locuntested);
            $xml .= '<label>';
            $xml .= add_XML_value('name', $label);
            $xml .= add_XML_value('percentcoverage', $percentcoverage);
            $xml .= '</label>';
        }
        $xml .= '</labels>';
    }
}
$coveredfiles = pdo_query("SELECT count(covered) FROM coverage WHERE buildid='{$buildid}' AND covered='1'");
$coveredfiles_array = pdo_fetch_array($coveredfiles);
$ncoveredfiles = $coveredfiles_array[0];
$files = pdo_query("SELECT count(covered) FROM coverage WHERE buildid='{$buildid}'");
Example #19
0
 /** Update the content of the file */
 function Update($buildid)
 {
     if (!is_numeric($buildid) || $buildid == 0) {
         return;
     }
     include "cdash/config.php";
     // Compute the crc32 of the file (before compression for backward compatibility)
     $this->Crc32 = crc32($this->FullPath . $this->File);
     $this->FullPath = pdo_real_escape_string($this->FullPath);
     if ($CDASH_USE_COMPRESSION) {
         $file = gzcompress($this->File);
         if ($file === false) {
             $file = $this->File;
         } else {
             if ($CDASH_DB_TYPE == "pgsql") {
                 if (strlen($this->File) < 2000) {
                     $file = $this->File;
                 }
                 $file = pg_escape_bytea(base64_encode($file));
                 // hopefully does the escaping correctly
             }
         }
     } else {
         $file = $this->File;
         if ($CDASH_DB_TYPE == "pgsql") {
             $file = pg_escape_bytea($file);
         }
     }
     $file = pdo_real_escape_string($file);
     $coveragefile = pdo_query("SELECT id FROM coveragefile WHERE crc32=" . qnum($this->Crc32));
     add_last_sql_error("CoverageFile:Update");
     if (pdo_num_rows($coveragefile) > 0) {
         $coveragefile_array = pdo_fetch_array($coveragefile);
         $this->Id = $coveragefile_array["id"];
         // Update the current coverage.fileid
         $coverage = pdo_query("SELECT c.fileid FROM coverage AS c,coveragefile AS cf \n                            WHERE c.fileid=cf.id AND c.buildid=" . qnum($buildid) . "\n                              AND cf.fullpath='{$this->FullPath}'");
         $coverage_array = pdo_fetch_array($coverage);
         $prevfileid = $coverage_array["fileid"];
         pdo_query("UPDATE coverage SET fileid=" . qnum($this->Id) . " WHERE buildid=" . qnum($buildid) . " AND fileid=" . qnum($prevfileid));
         add_last_sql_error("CoverageFile:Update");
         $row = pdo_single_row_query("SELECT COUNT(*) AS c FROM label2coveragefile WHERE buildid=" . qnum($buildid) . " AND coveragefileid=" . qnum($prevfileid));
         if (isset($row['c']) && $row['c'] > 0) {
             pdo_query("UPDATE label2coveragefile SET coveragefileid=" . qnum($this->Id) . " WHERE buildid=" . qnum($buildid) . " AND coveragefileid=" . qnum($prevfileid));
             add_last_sql_error("CoverageFile:Update");
         }
         // Remove the file if the crc32 is NULL
         pdo_query("DELETE FROM coveragefile WHERE id=" . qnum($prevfileid) . " AND file IS NULL and crc32 IS NULL");
         add_last_sql_error("CoverageFile:Update");
     } else {
         // We find the current fileid based on the name and the file should be null
         $coveragefile = pdo_query("SELECT cf.id,cf.file FROM coverage AS c,coveragefile AS cf \n                                   WHERE c.fileid=cf.id AND c.buildid=" . qnum($buildid) . "\n                                   AND cf.fullpath='{$this->FullPath}' ORDER BY cf.id ASC");
         $coveragefile_array = pdo_fetch_array($coveragefile);
         // The GcovTarHandler creates coveragefiles before coverages
         // so we need a simpler query in this case.
         if (empty($coveragefile_array)) {
             $coveragefile = pdo_query("SELECT id, file FROM coveragefile\n           WHERE fullpath='{$this->FullPath}' AND file IS NULL\n           ORDER BY id ASC");
             $coveragefile_array = pdo_fetch_array($coveragefile);
         }
         $this->Id = $coveragefile_array["id"];
         pdo_query("UPDATE coveragefile SET file='{$file}',crc32='{$this->Crc32}' WHERE id=" . qnum($this->Id));
         add_last_sql_error("CoverageFile:Update");
     }
     return true;
 }
Example #20
0
/** Generate the main dashboard XML */
function generate_main_dashboard_XML($project_instance, $date)
{
    $start = microtime_float();
    $noforcelogin = 1;
    include_once "cdash/config.php";
    require_once "cdash/pdo.php";
    include 'login.php';
    include_once "models/banner.php";
    include_once "models/subproject.php";
    $db = pdo_connect("{$CDASH_DB_HOST}", "{$CDASH_DB_LOGIN}", "{$CDASH_DB_PASS}");
    if (!$db) {
        echo "Error connecting to CDash database server<br>\n";
        return;
    }
    if (!pdo_select_db("{$CDASH_DB_NAME}", $db)) {
        echo "Error selecting CDash database<br>\n";
        return;
    }
    $projectid = $project_instance->Id;
    $project = pdo_query("SELECT * FROM project WHERE id='{$projectid}'");
    if (pdo_num_rows($project) > 0) {
        $project_array = pdo_fetch_array($project);
        $svnurl = make_cdash_url(htmlentities($project_array["cvsurl"]));
        $homeurl = make_cdash_url(htmlentities($project_array["homeurl"]));
        $bugurl = make_cdash_url(htmlentities($project_array["bugtrackerurl"]));
        $googletracker = htmlentities($project_array["googletracker"]);
        $docurl = make_cdash_url(htmlentities($project_array["documentationurl"]));
        $projectpublic = $project_array["public"];
        $projectname = $project_array["name"];
        if (isset($project_array['testingdataurl']) && $project_array['testingdataurl'] != '') {
            $testingdataurl = make_cdash_url(htmlentities($project_array['testingdataurl']));
        }
    } else {
        redirect_error('This project doesn\'t exist. Maybe the URL you are trying to access is wrong.');
        return false;
    }
    checkUserPolicy(@$_SESSION['cdash']['loginid'], $project_array["id"]);
    $xml = begin_XML_for_XSLT();
    $xml .= "<title>CDash - " . $projectname . "</title>";
    $Banner = new Banner();
    $Banner->SetProjectId(0);
    $text = $Banner->GetText();
    if ($text !== false) {
        $xml .= "<banner>";
        $xml .= add_XML_value("text", $text);
        $xml .= "</banner>";
    }
    $Banner->SetProjectId($projectid);
    $text = $Banner->GetText();
    if ($text !== false) {
        $xml .= "<banner>";
        $xml .= add_XML_value("text", $text);
        $xml .= "</banner>";
    }
    $sitexml = "";
    list($previousdate, $currentstarttime, $nextdate) = get_dates($date, $project_array["nightlytime"]);
    $logoid = getLogoID($projectid);
    // Main dashboard section
    $xml .= "<dashboard>\n  <datetime>" . date("l, F d Y H:i:s T", time()) . "</datetime>\n  <date>" . $date . "</date>\n  <unixtimestamp>" . $currentstarttime . "</unixtimestamp>\n  <svn>" . $svnurl . "</svn>\n  <bugtracker>" . $bugurl . "</bugtracker>\n  <googletracker>" . $googletracker . "</googletracker>\n  <documentation>" . $docurl . "</documentation>\n  <logoid>" . $logoid . "</logoid>\n  <projectid>" . $projectid . "</projectid>\n  <projectname>" . $projectname . "</projectname>\n  <projectname_encoded>" . urlencode($projectname) . "</projectname_encoded>\n  <previousdate>" . $previousdate . "</previousdate>\n  <projectpublic>" . $projectpublic . "</projectpublic>\n  <displaylabels>" . $project_array["displaylabels"] . "</displaylabels>\n  <nextdate>" . $nextdate . "</nextdate>";
    if (empty($project_array["homeurl"])) {
        $xml .= "<home>index.php?project=" . urlencode($projectname) . "</home>";
    } else {
        $xml .= "<home>" . $homeurl . "</home>";
    }
    if (isset($_GET["parentid"])) {
        $xml .= "<childview>1</childview>";
    } else {
        $xml .= "<childview>0</childview>";
    }
    if ($CDASH_USE_LOCAL_DIRECTORY && file_exists("local/models/proProject.php")) {
        include_once "local/models/proProject.php";
        $pro = new proProject();
        $pro->ProjectId = $projectid;
        $xml .= "<proedition>" . $pro->GetEdition(1) . "</proedition>";
    }
    if ($currentstarttime > time()) {
        $xml .= "<future>1</future>";
    } else {
        $xml .= "<future>0</future>";
    }
    $xml .= "</dashboard>";
    // Menu definition
    $xml .= "<menu>";
    if (!has_next_date($date, $currentstarttime)) {
        $xml .= add_XML_value("nonext", "1");
    }
    $xml .= "</menu>";
    // Check the builds
    $beginning_timestamp = $currentstarttime;
    $end_timestamp = $currentstarttime + 3600 * 24;
    $beginning_UTCDate = gmdate(FMT_DATETIME, $beginning_timestamp);
    $end_UTCDate = gmdate(FMT_DATETIME, $end_timestamp);
    // Add the extra url if necessary
    if (isset($_GET["display"]) && $_GET["display"] == "project") {
        $xml .= add_XML_value("extraurl", "&display=project");
    }
    // If we have a subproject
    $subproject_name = @$_GET["subproject"];
    $subprojectid = false;
    if ($subproject_name) {
        $SubProject = new SubProject();
        $subproject_name = htmlspecialchars(pdo_real_escape_string($subproject_name));
        $SubProject->SetName($subproject_name);
        $SubProject->SetProjectId($projectid);
        $subprojectid = $SubProject->GetId();
        if ($subprojectid) {
            // Add an extra URL argument for the menu
            $xml .= add_XML_value("extraurl", "&subproject=" . urlencode($subproject_name));
            $xml .= add_XML_value("subprojectname", $subproject_name);
            $xml .= "<subproject>";
            $xml .= add_XML_value("name", $SubProject->GetName());
            $rowparity = 0;
            $dependencies = $SubProject->GetDependencies();
            if ($dependencies) {
                foreach ($dependencies as $dependency) {
                    $xml .= "<dependency>";
                    $DependProject = new SubProject();
                    $DependProject->SetId($dependency);
                    $xml .= add_XML_value("rowparity", $rowparity);
                    $xml .= add_XML_value("name", $DependProject->GetName());
                    $xml .= add_XML_value("name_encoded", urlencode($DependProject->GetName()));
                    $xml .= add_XML_value("nbuilderror", $DependProject->GetNumberOfErrorBuilds($beginning_UTCDate, $end_UTCDate));
                    $xml .= add_XML_value("nbuildwarning", $DependProject->GetNumberOfWarningBuilds($beginning_UTCDate, $end_UTCDate));
                    $xml .= add_XML_value("nbuildpass", $DependProject->GetNumberOfPassingBuilds($beginning_UTCDate, $end_UTCDate));
                    $xml .= add_XML_value("nconfigureerror", $DependProject->GetNumberOfErrorConfigures($beginning_UTCDate, $end_UTCDate));
                    $xml .= add_XML_value("nconfigurewarning", $DependProject->GetNumberOfWarningConfigures($beginning_UTCDate, $end_UTCDate));
                    $xml .= add_XML_value("nconfigurepass", $DependProject->GetNumberOfPassingConfigures($beginning_UTCDate, $end_UTCDate));
                    $xml .= add_XML_value("ntestpass", $DependProject->GetNumberOfPassingTests($beginning_UTCDate, $end_UTCDate));
                    $xml .= add_XML_value("ntestfail", $DependProject->GetNumberOfFailingTests($beginning_UTCDate, $end_UTCDate));
                    $xml .= add_XML_value("ntestnotrun", $DependProject->GetNumberOfNotRunTests($beginning_UTCDate, $end_UTCDate));
                    if (strlen($DependProject->GetLastSubmission()) == 0) {
                        $xml .= add_XML_value("lastsubmission", "NA");
                    } else {
                        $xml .= add_XML_value("lastsubmission", $DependProject->GetLastSubmission());
                    }
                    $rowparity = $rowparity == 1 ? 0 : 1;
                    $xml .= "</dependency>";
                }
            }
            $xml .= "</subproject>";
        } else {
            add_log("SubProject '{$subproject_name}' does not exist", __FILE__ . ':' . __LINE__ . ' - ' . __FUNCTION__, LOG_WARNING);
        }
    }
    if (isset($testingdataurl)) {
        $xml .= add_XML_value("testingdataurl", $testingdataurl);
    }
    // updates
    $xml .= "<updates>";
    $gmdate = gmdate(FMT_DATE, $currentstarttime);
    $xml .= "<url>viewChanges.php?project=" . urlencode($projectname) . "&amp;date=" . $gmdate . "</url>";
    $dailyupdate = pdo_query("SELECT count(ds.dailyupdateid),count(distinct ds.author)\n                            FROM dailyupdate AS d LEFT JOIN dailyupdatefile AS ds ON (ds.dailyupdateid = d.id)\n                            WHERE d.date='{$gmdate}' and d.projectid='{$projectid}' GROUP BY ds.dailyupdateid");
    if (pdo_num_rows($dailyupdate) > 0) {
        $dailupdate_array = pdo_fetch_array($dailyupdate);
        $xml .= "<nchanges>" . $dailupdate_array[0] . "</nchanges>";
        $xml .= "<nauthors>" . $dailupdate_array[1] . "</nauthors>";
    } else {
        $xml .= "<nchanges>-1</nchanges>";
    }
    $xml .= add_XML_value("timestamp", date("l, F d Y - H:i T", $currentstarttime));
    $xml .= "</updates>";
    // User
    if (isset($_SESSION['cdash'])) {
        $xml .= "<user>";
        $userid = $_SESSION['cdash']['loginid'];
        $user2project = pdo_query("SELECT role FROM user2project WHERE userid='{$userid}' and projectid='{$projectid}'");
        $user2project_array = pdo_fetch_array($user2project);
        $user = pdo_query("SELECT admin FROM " . qid("user") . "  WHERE id='{$userid}'");
        $user_array = pdo_fetch_array($user);
        $xml .= add_XML_value("id", $userid);
        $isadmin = 0;
        if ($user2project_array["role"] > 1 || $user_array["admin"]) {
            $isadmin = 1;
        }
        $xml .= add_XML_value("admin", $isadmin);
        $xml .= add_XML_value("projectrole", $user2project_array['role']);
        $xml .= "</user>";
    }
    // Filters:
    //
    $filterdata = get_filterdata_from_request();
    $filter_sql = $filterdata['sql'];
    $limit_sql = '';
    if ($filterdata['limit'] > 0) {
        $limit_sql = ' LIMIT ' . $filterdata['limit'];
    }
    $xml .= $filterdata['xml'];
    // Local function to add expected builds
    function add_expected_builds($groupid, $currentstarttime, $received_builds)
    {
        include 'cdash/config.php';
        $currentUTCTime = gmdate(FMT_DATETIME, $currentstarttime + 3600 * 24);
        $xml = "";
        $build2grouprule = pdo_query("SELECT g.siteid,g.buildname,g.buildtype,s.name,s.outoforder FROM build2grouprule AS g,site as s\n                                  WHERE g.expected='1' AND g.groupid='{$groupid}' AND s.id=g.siteid\n                                  AND g.starttime<'{$currentUTCTime}' AND (g.endtime>'{$currentUTCTime}' OR g.endtime='1980-01-01 00:00:00')\n                                  ");
        while ($build2grouprule_array = pdo_fetch_array($build2grouprule)) {
            $key = $build2grouprule_array["name"] . "_" . $build2grouprule_array["buildname"];
            if (array_search($key, $received_builds) === FALSE) {
                $site = $build2grouprule_array["name"];
                $siteid = $build2grouprule_array["siteid"];
                $siteoutoforder = $build2grouprule_array["outoforder"];
                $buildtype = $build2grouprule_array["buildtype"];
                $buildname = $build2grouprule_array["buildname"];
                $xml .= "<build>";
                $xml .= add_XML_value("site", $site);
                $xml .= add_XML_value("siteoutoforder", $siteoutoforder);
                $xml .= add_XML_value("siteid", $siteid);
                $xml .= add_XML_value("buildname", $buildname);
                $xml .= add_XML_value("buildtype", $buildtype);
                $xml .= add_XML_value("buildgroupid", $groupid);
                $xml .= add_XML_value("expected", "1");
                // compute historical average to get approximate expected time
                // PostgreSQL doesn't have the necessary functions for this
                if ($CDASH_DB_TYPE == 'pgsql') {
                    $query = pdo_query("SELECT submittime FROM build,build2group\n                              WHERE build2group.buildid=build.id AND siteid='{$siteid}' AND name='{$buildname}'\n                              AND type='{$buildtype}' AND build2group.groupid='{$groupid}'\n                              ORDER BY id DESC LIMIT 5");
                    $time = 0;
                    while ($query_array = pdo_fetch_array($query)) {
                        $time += strtotime(date("H:i:s", strtotime($query_array['submittime'])));
                    }
                    if (pdo_num_rows($query) > 0) {
                        $time /= pdo_num_rows($query);
                    }
                    $nextExpected = strtotime(date("H:i:s", $time) . " UTC");
                } else {
                    $query = pdo_query("SELECT AVG(TIME_TO_SEC(TIME(submittime))) FROM (SELECT submittime FROM build,build2group\n                                WHERE build2group.buildid=build.id AND siteid='{$siteid}' AND name='{$buildname}'\n                                AND type='{$buildtype}' AND build2group.groupid='{$groupid}'\n                                ORDER BY id DESC LIMIT 5) as t");
                    $query_array = pdo_fetch_array($query);
                    $time = $query_array[0];
                    $hours = floor($time / 3600);
                    $time = $time % 3600;
                    $minutes = floor($time / 60);
                    $seconds = $time % 60;
                    $nextExpected = strtotime($hours . ":" . $minutes . ":" . $seconds . " UTC");
                }
                $divname = $build2grouprule_array["siteid"] . "_" . $build2grouprule_array["buildname"];
                $divname = str_replace("+", "_", $divname);
                $divname = str_replace(".", "_", $divname);
                $divname = str_replace(':', "_", $divname);
                $divname = str_replace(' ', "_", $divname);
                $xml .= add_XML_value("expecteddivname", $divname);
                $xml .= add_XML_value("submitdate", "No Submission");
                $xml .= add_XML_value("expectedstarttime", date(FMT_TIME, $nextExpected));
                $xml .= "</build>";
            }
        }
        return $xml;
    }
    // add a request for the subproject
    $subprojectsql = "";
    $subprojecttablesql = "";
    if ($subproject_name && is_numeric($subprojectid)) {
        $subprojectsql = " AND sp2b.subprojectid=" . $subprojectid;
    }
    // Use this as the default date clause, but if $filterdata has a date clause,
    // then cancel this one out:
    //
    $date_clause = "AND b.starttime<'{$end_UTCDate}' AND b.starttime>='{$beginning_UTCDate}' ";
    if ($filterdata['hasdateclause']) {
        $date_clause = '';
    }
    $parent_clause = "";
    if (isset($_GET["parentid"])) {
        // If we have a parentid, then we should only show children of that build.
        // Date becomes irrelevant in this case.
        $parent_clause = "AND (b.parentid = " . qnum($_GET["parentid"]) . ") ";
        $date_clause = "";
    } else {
        if (empty($subprojectsql)) {
            // Only show builds that are not children.
            $parent_clause = "AND (b.parentid = -1 OR b.parentid = 0) ";
        }
    }
    $build_rows = array();
    // If the user is logged in we display if the build has some changes for him
    $userupdatesql = "";
    if (isset($_SESSION['cdash'])) {
        $userupdatesql = "(SELECT count(updatefile.updateid) FROM updatefile,build2update,user2project,\n                      user2repository\n                      WHERE build2update.buildid=b.id\n                      AND build2update.updateid=updatefile.updateid\n                      AND user2project.projectid=b.projectid\n                      AND user2project.userid='" . $_SESSION['cdash']['loginid'] . "'\n                      AND user2repository.userid=user2project.userid\n                      AND (user2repository.projectid=0 OR user2repository.projectid=b.projectid)\n                      AND user2repository.credential=updatefile.author) AS userupdates,";
    }
    // Postgres differs from MySQL on how to aggregate results
    // into a single column.
    $label_sql = "";
    $groupby_sql = "";
    if ($CDASH_DB_TYPE != 'pgsql') {
        $label_sql = "GROUP_CONCAT(l.text SEPARATOR ', ') AS labels,";
        $groupby_sql = " GROUP BY b.id";
    }
    $sql = "SELECT b.id,b.siteid,b.parentid,\n                  bu.status AS updatestatus,\n                  i.osname AS osname,\n                  bu.starttime AS updatestarttime,\n                  bu.endtime AS updateendtime,\n                  bu.nfiles AS countupdatefiles,\n                  bu.warnings AS countupdatewarnings,\n                  c.status AS configurestatus,\n                  c.starttime AS configurestarttime,\n                  c.endtime AS configureendtime,\n                  be_diff.difference_positive AS countbuilderrordiffp,\n                  be_diff.difference_negative AS countbuilderrordiffn,\n                  bw_diff.difference_positive AS countbuildwarningdiffp,\n                  bw_diff.difference_negative AS countbuildwarningdiffn,\n                  ce_diff.difference AS countconfigurewarningdiff,\n                  btt.time AS testsduration,\n                  tnotrun_diff.difference_positive AS counttestsnotrundiffp,\n                  tnotrun_diff.difference_negative AS counttestsnotrundiffn,\n                  tfailed_diff.difference_positive AS counttestsfaileddiffp,\n                  tfailed_diff.difference_negative AS counttestsfaileddiffn,\n                  tpassed_diff.difference_positive AS counttestspasseddiffp,\n                  tpassed_diff.difference_negative AS counttestspasseddiffn,\n                  tstatusfailed_diff.difference_positive AS countteststimestatusfaileddiffp,\n                  tstatusfailed_diff.difference_negative AS countteststimestatusfaileddiffn,\n                  (SELECT count(buildid) FROM build2note WHERE buildid=b.id)  AS countnotes,\n                  (SELECT count(buildid) FROM buildnote WHERE buildid=b.id) AS countbuildnotes," . $userupdatesql . "\n                  s.name AS sitename,\n                  s.outoforder AS siteoutoforder,\n                  b.stamp,b.name,b.type,b.generator,b.starttime,b.endtime,b.submittime,\n                  b.configureerrors AS countconfigureerrors,\n                  b.configurewarnings AS countconfigurewarnings,\n                  b.builderrors AS countbuilderrors,\n                  b.buildwarnings AS countbuildwarnings,\n                  b.testnotrun AS counttestsnotrun,\n                  b.testfailed AS counttestsfailed,\n                  b.testpassed AS counttestspassed,\n                  b.testtimestatusfailed AS countteststimestatusfailed,\n                  sp.id AS subprojectid,\n                  sp.groupid AS subprojectgroup,\n                  g.name as groupname,gp.position,g.id as groupid,\n                  {$label_sql}\n                  (SELECT count(buildid) FROM errorlog WHERE buildid=b.id) AS nerrorlog,\n                  (SELECT count(buildid) FROM build2uploadfile WHERE buildid=b.id) AS builduploadfiles\n                  FROM build AS b\n                  LEFT JOIN build2group AS b2g ON (b2g.buildid=b.id)\n                  LEFT JOIN buildgroup AS g ON (g.id=b2g.groupid)\n                  LEFT JOIN buildgroupposition AS gp ON (gp.buildgroupid=g.id)\n                  LEFT JOIN site AS s ON (s.id=b.siteid)\n                  LEFT JOIN build2update AS b2u ON (b2u.buildid=b.id)\n                  LEFT JOIN buildupdate AS bu ON (b2u.updateid=bu.id)\n                  LEFT JOIN configure AS c ON (c.buildid=b.id)\n                  LEFT JOIN buildinformation AS i ON (i.buildid=b.id)\n                  LEFT JOIN builderrordiff AS be_diff ON (be_diff.buildid=b.id AND be_diff.type=0)\n                  LEFT JOIN builderrordiff AS bw_diff ON (bw_diff.buildid=b.id AND bw_diff.type=1)\n                  LEFT JOIN configureerrordiff AS ce_diff ON (ce_diff.buildid=b.id AND ce_diff.type=1)\n                  LEFT JOIN buildtesttime AS btt ON (btt.buildid=b.id)\n                  LEFT JOIN testdiff AS tnotrun_diff ON (tnotrun_diff.buildid=b.id AND tnotrun_diff.type=0)\n                  LEFT JOIN testdiff AS tfailed_diff ON (tfailed_diff.buildid=b.id AND tfailed_diff.type=1)\n                  LEFT JOIN testdiff AS tpassed_diff ON (tpassed_diff.buildid=b.id AND tpassed_diff.type=2)\n                  LEFT JOIN testdiff AS tstatusfailed_diff ON (tstatusfailed_diff.buildid=b.id AND tstatusfailed_diff.type=3)\n                  LEFT JOIN subproject2build AS sp2b ON (sp2b.buildid = b.id)\n                  LEFT JOIN subproject as sp ON (sp2b.subprojectid = sp.id)\n                  LEFT JOIN label2build AS l2b ON (l2b.buildid = b.id)\n                  LEFT JOIN label AS l ON (l.id = l2b.labelid)\n                  WHERE b.projectid='{$projectid}' AND g.type='Daily'\n                  {$parent_clause} {$date_clause}\n                  " . $subprojectsql . " " . $filter_sql . " " . $groupby_sql . $limit_sql;
    // We shouldn't get any builds for group that have been deleted (otherwise something is wrong)
    $builds = pdo_query($sql);
    echo pdo_error();
    // Sort results from this query.
    // We used to do this in MySQL with the following directive:
    // ORDER BY gp.position ASC,b.name ASC,b.siteid ASC,b.stamp DESC
    // But this dramatically impacted performance when the number of rows was
    // relatively large (in the thousands).  So now we accomplish the same
    // sorting within PHP instead.
    $build_data = array();
    while ($build_row = pdo_fetch_array($builds)) {
        $build_data[] = $build_row;
    }
    $dynamic_builds = array();
    if (empty($filter_sql)) {
        $dynamic_builds = get_dynamic_builds($projectid);
        $build_data = array_merge($build_data, $dynamic_builds);
    }
    $positions = array();
    $names = array();
    $siteids = array();
    $stamps = array();
    foreach ($build_data as $key => $row) {
        $positions[$key] = $row['position'];
        $names[$key] = $row['name'];
        $siteids[$key] = $row['siteid'];
        $stamps[$key] = $row['stamp'];
    }
    array_multisort($positions, SORT_ASC, $names, SORT_ASC, $siteids, SORT_ASC, $stamps, SORT_DESC, $build_data);
    // The SQL results are ordered by group so this should work
    // Group position have to be continuous
    $previousgroupposition = -1;
    $received_builds = array();
    // Find the last position of the group
    $groupposition_array = pdo_fetch_array(pdo_query("SELECT gp.position FROM buildgroupposition AS gp,buildgroup AS g\n                                                        WHERE g.projectid='{$projectid}' AND g.id=gp.buildgroupid\n                                                        AND gp.starttime<'{$end_UTCDate}' AND (gp.endtime>'{$end_UTCDate}' OR gp.endtime='1980-01-01 00:00:00')\n                                                        ORDER BY gp.position DESC LIMIT 1"));
    $lastGroupPosition = $groupposition_array["position"];
    // Check if we need to summarize coverage by subproject groups.
    // This happens when we have subprojects and we're looking at the children
    // of a specific build.
    $subproject_groups = array();
    $subproject_group_coverage = array();
    if (isset($_GET["parentid"]) && $_GET["parentid"] > 0 && $project_instance->GetNumberOfSubProjects($end_UTCDate) > 0) {
        $groups = $project_instance->GetSubProjectGroups();
        foreach ($groups as $group) {
            // Create an Id -> Object mapping for our subproject groups.
            $subproject_groups[$group->GetId()] = $group;
            // Also keep track of coverage info on a per-group basis.
            $subproject_group_coverage[$group->GetId()] = array();
            $subproject_group_coverage[$group->GetId()]["tested"] = 0;
            $subproject_group_coverage[$group->GetId()]["untested"] = 0;
        }
    }
    // Fetch all the rows of builds into a php array.
    // Compute additional fields for each row that we'll need to generate the xml.
    //
    $build_rows = array();
    foreach ($build_data as $build_row) {
        // Fields that come from the initial query:
        //  id
        //  sitename
        //  stamp
        //  name
        //  siteid
        //  type
        //  generator
        //  starttime
        //  endtime
        //  submittime
        //  groupname
        //  position
        //  groupid
        //  countupdatefiles
        //  updatestatus
        //  countupdatewarnings
        //  countbuildwarnings
        //  countbuilderrors
        //  countbuilderrordiff
        //  countbuildwarningdiff
        //  configurestatus
        //  countconfigureerrors
        //  countconfigurewarnings
        //  countconfigurewarningdiff
        //  counttestsnotrun
        //  counttestsnotrundiff
        //  counttestsfailed
        //  counttestsfaileddiff
        //  counttestspassed
        //  counttestspasseddiff
        //  countteststimestatusfailed
        //  countteststimestatusfaileddiff
        //  testsduration
        //
        // Fields that we add within this loop:
        //  maxstarttime
        //  buildids (array of buildids for summary rows)
        //  countbuildnotes (added by users)
        //  labels
        //  updateduration
        //  countupdateerrors
        //  buildduration
        //  hasconfigurestatus
        //  configureduration
        //  test
        //
        $buildid = $build_row['id'];
        $groupid = $build_row['groupid'];
        $siteid = $build_row['siteid'];
        $parentid = $build_row['parentid'];
        $build_row['buildids'][] = $buildid;
        $build_row['maxstarttime'] = $build_row['starttime'];
        // Split out labels
        if (empty($build_row['labels'])) {
            $build_row['labels'] = array();
        } else {
            $build_row['labels'] = explode(",", $build_row['labels']);
        }
        // If this is a parent build get the labels from all the children too.
        if ($parentid == -1) {
            $query = "SELECT l.text FROM build AS b\n        INNER JOIN label2build AS l2b ON l2b.buildid = b.id\n        INNER JOIN label AS l ON l.id = l2b.labelid\n        WHERE b.parentid='{$buildid}'";
            $childLabelsResult = pdo_query($query);
            while ($childLabelsArray = pdo_fetch_array($childLabelsResult)) {
                $build_row['labels'][] = $childLabelsArray['text'];
            }
        }
        // Updates
        if (!empty($build_row['updatestarttime'])) {
            $build_row['updateduration'] = round((strtotime($build_row['updateendtime']) - strtotime($build_row['updatestarttime'])) / 60, 1);
        } else {
            $build_row['updateduration'] = 0;
        }
        if (strlen($build_row["updatestatus"]) > 0 && $build_row["updatestatus"] != "0") {
            $build_row['countupdateerrors'] = 1;
        } else {
            $build_row['countupdateerrors'] = 0;
        }
        $build_row['buildduration'] = round((strtotime($build_row['endtime']) - strtotime($build_row['starttime'])) / 60, 1);
        // Error/Warnings differences
        if (empty($build_row['countbuilderrordiffp'])) {
            $build_row['countbuilderrordiffp'] = 0;
        }
        if (empty($build_row['countbuilderrordiffn'])) {
            $build_row['countbuilderrordiffn'] = 0;
        }
        if (empty($build_row['countbuildwarningdiffp'])) {
            $build_row['countbuildwarningdiffp'] = 0;
        }
        if (empty($build_row['countbuildwarningdiffn'])) {
            $build_row['countbuildwarningdiffn'] = 0;
        }
        if ($build_row['countconfigureerrors'] < 0) {
            $build_row['countconfigureerrors'] = 0;
        }
        if ($build_row['countconfigurewarnings'] < 0) {
            $build_row['countconfigurewarnings'] = 0;
        }
        $build_row['hasconfigurestatus'] = 0;
        $build_row['configureduration'] = 0;
        if (strlen($build_row['configurestatus']) > 0) {
            $build_row['hasconfigurestatus'] = 1;
            $build_row['configureduration'] = round((strtotime($build_row["configureendtime"]) - strtotime($build_row["configurestarttime"])) / 60, 1);
        }
        if (empty($build_row['countconfigurewarningdiff'])) {
            $build_row['countconfigurewarningdiff'] = 0;
        }
        $build_row['hastest'] = 0;
        if ($build_row['counttestsfailed'] != -1) {
            $build_row['hastest'] = 1;
        }
        if (empty($build_row['testsduration'])) {
            $time_array = pdo_fetch_array(pdo_query("SELECT SUM(time) FROM build2test WHERE buildid='{$buildid}'"));
            $build_row['testsduration'] = round($time_array[0] / 60, 1);
        } else {
            $build_row['testsduration'] = round($build_row['testsduration'], 1);
            //already in minutes
        }
        $build_rows[] = $build_row;
    }
    // Generate the xml from the rows of builds:
    //
    $totalUpdatedFiles = 0;
    $totalUpdateError = 0;
    $totalUpdateWarning = 0;
    $totalUpdateDuration = 0;
    $totalConfigureError = 0;
    $totalConfigureWarning = 0;
    $totalConfigureDuration = 0;
    $totalerrors = 0;
    $totalwarnings = 0;
    $totalBuildDuration = 0;
    $totalnotrun = 0;
    $totalfail = 0;
    $totalpass = 0;
    $totalTestsDuration = 0;
    foreach ($build_rows as $build_array) {
        $groupposition = $build_array["position"];
        if ($previousgroupposition != $groupposition) {
            $groupname = $build_array["groupname"];
            if ($previousgroupposition != -1) {
                if (!$filter_sql) {
                    $xml .= add_expected_builds($groupid, $currentstarttime, $received_builds);
                }
                $xml .= add_XML_value("totalUpdatedFiles", $totalUpdatedFiles);
                $xml .= add_XML_value("totalUpdateError", $totalUpdateError);
                $xml .= add_XML_value("totalUpdateWarning", $totalUpdateWarning);
                $xml .= add_XML_value("totalUpdateDuration", $totalUpdateDuration);
                $xml .= add_XML_value("totalConfigureDuration", $totalConfigureDuration);
                $xml .= add_XML_value("totalConfigureError", $totalConfigureError);
                $xml .= add_XML_value("totalConfigureWarning", $totalConfigureWarning);
                $xml .= add_XML_value("totalError", $totalerrors);
                $xml .= add_XML_value("totalWarning", $totalwarnings);
                $xml .= add_XML_value("totalBuildDuration", $totalBuildDuration);
                $xml .= add_XML_value("totalNotRun", $totalnotrun);
                $xml .= add_XML_value("totalFail", $totalfail);
                $xml .= add_XML_value("totalPass", $totalpass);
                $xml .= add_XML_value("totalTestsDuration", time_difference($totalTestsDuration * 60.0, true));
                $xml .= "</buildgroup>";
            }
            // We assume that the group position are continuous in N
            // So we fill in the gap if we are jumping
            $prevpos = $previousgroupposition + 1;
            if ($prevpos == 0) {
                $prevpos = 1;
            }
            for ($i = $prevpos; $i < $groupposition; $i++) {
                $group = pdo_fetch_array(pdo_query("SELECT g.name,g.id FROM buildgroup AS g,buildgroupposition AS gp WHERE g.id=gp.buildgroupid\n                                                AND gp.position='{$i}' AND g.projectid='{$projectid}'\n                                                AND gp.starttime<'{$end_UTCDate}' AND (gp.endtime>'{$end_UTCDate}'  OR gp.endtime='1980-01-01 00:00:00')\n                                                "));
                $xml .= "<buildgroup>";
                $xml .= add_buildgroup_sortlist($group['name']);
                $xml .= add_XML_value("name", $group["name"]);
                $xml .= add_XML_value("linkname", str_replace(" ", "_", $group["name"]));
                $xml .= add_XML_value("id", $group["id"]);
                if (!$filter_sql) {
                    $xml .= add_expected_builds($group["id"], $currentstarttime, $received_builds);
                }
                $xml .= "</buildgroup>";
            }
            $xml .= "<buildgroup>";
            $totalUpdatedFiles = 0;
            $totalUpdateError = 0;
            $totalUpdateWarning = 0;
            $totalUpdateDuration = 0;
            $totalConfigureError = 0;
            $totalConfigureWarning = 0;
            $totalConfigureDuration = 0;
            $totalerrors = 0;
            $totalwarnings = 0;
            $totalBuildDuration = 0;
            $totalnotrun = 0;
            $totalfail = 0;
            $totalpass = 0;
            $totalTestsDuration = 0;
            $xml .= add_buildgroup_sortlist($groupname);
            $xml .= add_XML_value("name", $groupname);
            $xml .= add_XML_value("linkname", str_replace(" ", "_", $groupname));
            $xml .= add_XML_value("id", $build_array["groupid"]);
            $received_builds = array();
            $previousgroupposition = $groupposition;
        }
        $xml .= "<build>";
        $received_builds[] = $build_array["sitename"] . "_" . $build_array["name"];
        $buildid = $build_array["id"];
        $groupid = $build_array["groupid"];
        $siteid = $build_array["siteid"];
        $countChildrenResult = pdo_single_row_query("SELECT count(id) AS nchildren FROM build WHERE parentid=" . qnum($buildid));
        $countchildren = $countChildrenResult['nchildren'];
        $xml .= add_XML_value("countchildren", $countchildren);
        $child_builds_hyperlink = "";
        if ($countchildren > 0) {
            $child_builds_hyperlink = get_child_builds_hyperlink($build_array["id"], $filterdata);
            $xml .= add_XML_value("multiplebuildshyperlink", $child_builds_hyperlink);
        }
        $xml .= add_XML_value("type", strtolower($build_array["type"]));
        // Attempt to determine the platform based on the OSName and the buildname
        $buildplatform = '';
        if (strtolower(substr($build_array["osname"], 0, 7)) == 'windows') {
            $buildplatform = 'windows';
        } else {
            if (strtolower(substr($build_array["osname"], 0, 8)) == 'mac os x') {
                $buildplatform = 'mac';
            } else {
                if (strtolower(substr($build_array["osname"], 0, 5)) == 'linux' || strtolower(substr($build_array["osname"], 0, 3)) == 'aix') {
                    $buildplatform = 'linux';
                } else {
                    if (strtolower(substr($build_array["osname"], 0, 7)) == 'freebsd') {
                        $buildplatform = 'freebsd';
                    } else {
                        if (strtolower(substr($build_array["osname"], 0, 3)) == 'gnu') {
                            $buildplatform = 'gnu';
                        }
                    }
                }
            }
        }
        if (isset($_GET["parentid"]) && empty($sitexml)) {
            $sitexml .= add_XML_value("site", $build_array["sitename"]);
            $sitexml .= add_XML_value("siteoutoforder", $build_array["siteoutoforder"]);
            $sitexml .= add_XML_value("siteid", $siteid);
            $sitexml .= add_XML_value("buildname", $build_array["name"]);
            $sitexml .= add_XML_value("buildplatform", $buildplatform);
        } else {
            $xml .= add_XML_value("site", $build_array["sitename"]);
            $xml .= add_XML_value("siteoutoforder", $build_array["siteoutoforder"]);
            $xml .= add_XML_value("siteid", $siteid);
            $xml .= add_XML_value("buildname", $build_array["name"]);
            $xml .= add_XML_value("buildplatform", $buildplatform);
        }
        if (isset($build_array["userupdates"])) {
            $xml .= add_XML_value("userupdates", $build_array["userupdates"]);
        }
        $xml .= add_XML_value("buildid", $build_array["id"]);
        $xml .= add_XML_value("generator", $build_array["generator"]);
        $xml .= add_XML_value("upload-file-count", $build_array["builduploadfiles"]);
        if ($build_array['countbuildnotes'] > 0) {
            $xml .= add_XML_value("buildnote", "1");
        }
        if ($build_array['countnotes'] > 0) {
            $xml .= add_XML_value("note", "1");
        }
        // Are there labels for this build?
        //
        $labels_array = $build_array['labels'];
        if (!empty($labels_array)) {
            $xml .= '<labels>';
            foreach ($labels_array as $label) {
                $xml .= add_XML_value("label", $label);
            }
            $xml .= '</labels>';
        }
        $xml .= "<update>";
        $countupdatefiles = $build_array['countupdatefiles'];
        $totalUpdatedFiles += $countupdatefiles;
        $xml .= add_XML_value("files", $countupdatefiles);
        if (!empty($build_array['updatestarttime'])) {
            $xml .= add_XML_value("defined", 1);
            if ($build_array['countupdateerrors'] > 0) {
                $xml .= add_XML_value("errors", 1);
                $totalUpdateError += 1;
            } else {
                $xml .= add_XML_value("errors", 0);
                if ($build_array['countupdatewarnings'] > 0) {
                    $xml .= add_XML_value("warning", 1);
                    $totalUpdateWarning += 1;
                }
            }
            $duration = $build_array['updateduration'];
            $totalUpdateDuration += $duration;
            $xml .= add_XML_value("time", time_difference($duration * 60.0, true));
            $xml .= add_XML_value("timefull", $duration);
        }
        // end if we have an update
        $xml .= "</update>";
        $xml .= "<compilation>";
        if ($build_array['countbuilderrors'] >= 0) {
            $nerrors = $build_array['countbuilderrors'];
            $totalerrors += $nerrors;
            $xml .= add_XML_value("error", $nerrors);
            $nwarnings = $build_array['countbuildwarnings'];
            $totalwarnings += $nwarnings;
            $xml .= add_XML_value("warning", $nwarnings);
            $duration = $build_array['buildduration'];
            $totalBuildDuration += $duration;
            $xml .= add_XML_value("time", time_difference($duration * 60.0, true));
            $xml .= add_XML_value("timefull", $duration);
            $diff = $build_array['countbuilderrordiffp'];
            if ($diff != 0) {
                $xml .= add_XML_value("nerrordiffp", $diff);
            }
            $diff = $build_array['countbuilderrordiffn'];
            if ($diff != 0) {
                $xml .= add_XML_value("nerrordiffn", $diff);
            }
            $diff = $build_array['countbuildwarningdiffp'];
            if ($diff != 0) {
                $xml .= add_XML_value("nwarningdiffp", $diff);
            }
            $diff = $build_array['countbuildwarningdiffn'];
            if ($diff != 0) {
                $xml .= add_XML_value("nwarningdiffn", $diff);
            }
        }
        $xml .= "</compilation>";
        $xml .= "<configure>";
        $xml .= add_XML_value("error", $build_array['countconfigureerrors']);
        $totalConfigureError += $build_array['countconfigureerrors'];
        $nconfigurewarnings = $build_array['countconfigurewarnings'];
        $xml .= add_XML_value("warning", $nconfigurewarnings);
        $totalConfigureWarning += $nconfigurewarnings;
        $diff = $build_array['countconfigurewarningdiff'];
        if ($diff != 0) {
            $xml .= add_XML_value("warningdiff", $diff);
        }
        if ($build_array['hasconfigurestatus'] != 0) {
            $duration = $build_array['configureduration'];
            $totalConfigureDuration += $duration;
            $xml .= add_XML_value("time", time_difference($duration * 60.0, true));
            $xml .= add_XML_value("timefull", $duration);
        }
        $xml .= "</configure>";
        if ($build_array['hastest'] != 0) {
            $xml .= "<test>";
            $nnotrun = $build_array['counttestsnotrun'];
            if ($build_array['counttestsnotrundiffp'] != 0) {
                $xml .= add_XML_value("nnotrundiffp", $build_array['counttestsnotrundiffp']);
            }
            if ($build_array['counttestsnotrundiffn'] != 0) {
                $xml .= add_XML_value("nnotrundiffn", $build_array['counttestsnotrundiffn']);
            }
            $nfail = $build_array['counttestsfailed'];
            if ($build_array['counttestsfaileddiffp'] != 0) {
                $xml .= add_XML_value("nfaildiffp", $build_array['counttestsfaileddiffp']);
            }
            if ($build_array['counttestsfaileddiffn'] != 0) {
                $xml .= add_XML_value("nfaildiffn", $build_array['counttestsfaileddiffn']);
            }
            $npass = $build_array['counttestspassed'];
            if ($build_array['counttestspasseddiffp'] != 0) {
                $xml .= add_XML_value("npassdiffp", $build_array['counttestspasseddiffp']);
            }
            if ($build_array['counttestspasseddiffn'] != 0) {
                $xml .= add_XML_value("npassdiffn", $build_array['counttestspasseddiffn']);
            }
            if ($project_array["showtesttime"] == 1) {
                $xml .= add_XML_value("timestatus", $build_array['countteststimestatusfailed']);
                if ($build_array['countteststimestatusfaileddiffp'] != 0) {
                    $xml .= add_XML_value("ntimediffp", $build_array['countteststimestatusfaileddiffp']);
                }
                if ($build_array['countteststimestatusfaileddiffn'] != 0) {
                    $xml .= add_XML_value("ntimediffn", $build_array['countteststimestatusfaileddiffn']);
                }
            }
            $totalnotrun += $nnotrun;
            $totalfail += $nfail;
            $totalpass += $npass;
            $xml .= add_XML_value("notrun", $nnotrun);
            $xml .= add_XML_value("fail", $nfail);
            $xml .= add_XML_value("pass", $npass);
            $duration = $build_array['testsduration'];
            $totalTestsDuration += $duration;
            $xml .= add_XML_value("time", time_difference($duration * 60.0, true));
            $xml .= add_XML_value("timefull", $duration);
            $xml .= "</test>";
        }
        $starttimestamp = strtotime($build_array["starttime"] . " UTC");
        $submittimestamp = strtotime($build_array["submittime"] . " UTC");
        $xml .= add_XML_value("builddatefull", $starttimestamp);
        // use the default timezone
        // If the data is more than 24h old then we switch from an elapsed to a normal representation
        if (time() - $starttimestamp < 86400) {
            $xml .= add_XML_value("builddate", date(FMT_DATETIMEDISPLAY, $starttimestamp));
            // use the default timezone
            $xml .= add_XML_value("builddateelapsed", time_difference(time() - $starttimestamp, false, 'ago'));
            // use the default timezone
        } else {
            $xml .= add_XML_value("builddateelapsed", date(FMT_DATETIMEDISPLAY, $starttimestamp));
            // use the default timezone
            $xml .= add_XML_value("builddate", time_difference(time() - $starttimestamp, false, 'ago'));
            // use the default timezone
        }
        $xml .= add_XML_value("submitdate", date(FMT_DATETIMEDISPLAY, $submittimestamp));
        // use the default timezone
        $xml .= add_XML_value("nerrorlog", $build_array["nerrorlog"]);
        // use the default timezone
        $xml .= "</build>";
        // Coverage
        //
        // Determine if this is a parent build with no actual coverage of its own.
        $linkToChildCoverage = false;
        if ($countchildren > 0) {
            $countChildrenResult = pdo_single_row_query("SELECT count(fileid) AS nfiles FROM coverage\n         WHERE buildid=" . qnum($buildid));
            if ($countChildrenResult['nfiles'] == 0) {
                $linkToChildCoverage = true;
            }
        }
        $coverages = pdo_query("SELECT * FROM coveragesummary WHERE buildid='{$buildid}'");
        while ($coverage_array = pdo_fetch_array($coverages)) {
            $xml .= "<coverage>";
            $xml .= "  <site>" . $build_array["sitename"] . "</site>";
            $xml .= "  <buildname>" . $build_array["name"] . "</buildname>";
            $xml .= "  <buildid>" . $build_array["id"] . "</buildid>";
            if ($linkToChildCoverage) {
                $xml .= add_XML_value("childlink", "{$child_builds_hyperlink}#Coverage");
            }
            @($percent = round($coverage_array["loctested"] / ($coverage_array["loctested"] + $coverage_array["locuntested"]) * 100, 2));
            $coverageThreshold = $project_array["coveragethreshold"];
            if ($build_array["subprojectgroup"]) {
                $groupId = $build_array["subprojectgroup"];
                $coverageThreshold = $subproject_groups[$groupId]->GetCoverageThreshold();
                $subproject_group_coverage[$groupId]["tested"] += $coverage_array["loctested"];
                $subproject_group_coverage[$groupId]["untested"] += $coverage_array["locuntested"];
                $xml .= "  <group>{$groupId}</group>";
            }
            $xml .= "  <percentage>" . $percent . "</percentage>";
            $xml .= "  <percentagegreen>" . $coverageThreshold . "</percentagegreen>";
            $xml .= "  <fail>" . $coverage_array["locuntested"] . "</fail>";
            $xml .= "  <pass>" . $coverage_array["loctested"] . "</pass>";
            // Compute the diff
            $coveragediff = pdo_query("SELECT * FROM coveragesummarydiff WHERE buildid='{$buildid}'");
            if (pdo_num_rows($coveragediff) > 0) {
                $coveragediff_array = pdo_fetch_array($coveragediff);
                $loctesteddiff = $coveragediff_array['loctested'];
                $locuntesteddiff = $coveragediff_array['locuntested'];
                @($previouspercent = round(($coverage_array["loctested"] - $loctesteddiff) / ($coverage_array["loctested"] - $loctesteddiff + $coverage_array["locuntested"] - $locuntesteddiff) * 100, 2));
                $percentdiff = round($percent - $previouspercent, 2);
                $xml .= "<percentagediff>" . $percentdiff . "</percentagediff>";
                $xml .= "<faildiff>" . $locuntesteddiff . "</faildiff>";
                $xml .= "<passdiff>" . $loctesteddiff . "</passdiff>";
            }
            $starttimestamp = strtotime($build_array["starttime"] . " UTC");
            $xml .= add_XML_value("datefull", $starttimestamp);
            // use the default timezone
            // If the data is more than 24h old then we switch from an elapsed to a normal representation
            if (time() - $starttimestamp < 86400) {
                $xml .= add_XML_value("date", date(FMT_DATETIMEDISPLAY, $starttimestamp));
                // use the default timezone
                $xml .= add_XML_value("dateelapsed", time_difference(time() - $starttimestamp, false, 'ago'));
                // use the default timezone
            } else {
                $xml .= add_XML_value("dateelapsed", date(FMT_DATETIMEDISPLAY, $starttimestamp));
                // use the default timezone
                $xml .= add_XML_value("date", time_difference(time() - $starttimestamp, false, 'ago'));
                // use the default timezone
            }
            // Are there labels for this build?
            //
            if (!empty($labels_array)) {
                $xml .= '<labels>';
                foreach ($labels_array as $label) {
                    $xml .= add_XML_value("label", $label);
                }
                $xml .= '</labels>';
            }
            $xml .= "</coverage>";
        }
        // end coverage
        // Dynamic Analysis
        //
        $dynanalysis = pdo_query("SELECT checker,status FROM dynamicanalysis WHERE buildid='{$buildid}' LIMIT 1");
        while ($dynanalysis_array = pdo_fetch_array($dynanalysis)) {
            $xml .= "<dynamicanalysis>";
            $xml .= "  <site>" . $build_array["sitename"] . "</site>";
            $xml .= "  <buildname>" . $build_array["name"] . "</buildname>";
            $xml .= "  <buildid>" . $build_array["id"] . "</buildid>";
            $xml .= "  <checker>" . $dynanalysis_array["checker"] . "</checker>";
            $xml .= "  <status>" . $dynanalysis_array["status"] . "</status>";
            $defect = pdo_query("SELECT sum(dd.value) FROM dynamicanalysisdefect AS dd,dynamicanalysis as d\n                                              WHERE d.buildid='{$buildid}' AND dd.dynamicanalysisid=d.id");
            $defectcount = pdo_fetch_array($defect);
            if (!isset($defectcount[0])) {
                $defectcounts = 0;
            } else {
                $defectcounts = $defectcount[0];
            }
            $xml .= "  <defectcount>" . $defectcounts . "</defectcount>";
            $starttimestamp = strtotime($build_array["starttime"] . " UTC");
            $xml .= add_XML_value("datefull", $starttimestamp);
            // use the default timezone
            // If the data is more than 24h old then we switch from an elapsed to a normal representation
            if (time() - $starttimestamp < 86400) {
                $xml .= add_XML_value("date", date(FMT_DATETIMEDISPLAY, $starttimestamp));
                // use the default timezone
                $xml .= add_XML_value("dateelapsed", time_difference(time() - $starttimestamp, false, 'ago'));
                // use the default timezone
            } else {
                $xml .= add_XML_value("dateelapsed", date(FMT_DATETIMEDISPLAY, $starttimestamp));
                // use the default timezone
                $xml .= add_XML_value("date", time_difference(time() - $starttimestamp, false, 'ago'));
                // use the default timezone
            }
            // Are there labels for this build?
            //
            if (!empty($labels_array)) {
                $xml .= '<labels>';
                foreach ($labels_array as $label) {
                    $xml .= add_XML_value("label", $label);
                }
                $xml .= '</labels>';
            }
            $xml .= "</dynamicanalysis>";
        }
        // end dynamicanalysis
    }
    // end looping through builds
    if (pdo_num_rows($builds) + count($dynamic_builds) > 0) {
        if (!$filter_sql) {
            $xml .= add_expected_builds($groupid, $currentstarttime, $received_builds);
        }
        $xml .= add_XML_value("totalUpdatedFiles", $totalUpdatedFiles);
        $xml .= add_XML_value("totalUpdateError", $totalUpdateError);
        $xml .= add_XML_value("totalUpdateWarning", $totalUpdateWarning);
        $xml .= add_XML_value("totalUpdateDuration", $totalUpdateDuration);
        $xml .= add_XML_value("totalConfigureDuration", $totalConfigureDuration);
        $xml .= add_XML_value("totalConfigureError", $totalConfigureError);
        $xml .= add_XML_value("totalConfigureWarning", $totalConfigureWarning);
        $xml .= add_XML_value("totalError", $totalerrors);
        $xml .= add_XML_value("totalWarning", $totalwarnings);
        $xml .= add_XML_value("totalBuildDuration", $totalBuildDuration);
        $xml .= add_XML_value("totalNotRun", $totalnotrun);
        $xml .= add_XML_value("totalFail", $totalfail);
        $xml .= add_XML_value("totalPass", $totalpass);
        $xml .= add_XML_value("totalTestsDuration", time_difference($totalTestsDuration * 60.0, true));
        $xml .= "</buildgroup>";
    }
    // generate subproject coverage by group here.
    if (!empty($subproject_groups)) {
        foreach ($subproject_groups as $groupid => $group) {
            $group_cov = $subproject_group_coverage[$groupid];
            $tested = $group_cov['tested'];
            $untested = $group_cov['untested'];
            if ($tested == 0 && $untested == 0) {
                continue;
            }
            $coverage = round($tested / ($tested + $untested) * 100, 2);
            $xml .= "<subprojectgroup>";
            $xml .= add_XML_value("name", $group->GetName());
            $xml .= add_XML_value("id", $group->GetId());
            $xml .= add_XML_value("threshold", $group->GetCoverageThreshold());
            $xml .= add_XML_value("coverage", $coverage);
            $xml .= add_XML_value("tested", $tested);
            $xml .= add_XML_value("untested", $untested);
            $xml .= "</subprojectgroup>";
        }
    }
    // Fill in the rest of the info
    $prevpos = $previousgroupposition + 1;
    if ($prevpos == 0) {
        $prevpos = 1;
    }
    for ($i = $prevpos; $i <= $lastGroupPosition; $i++) {
        $group = pdo_fetch_array(pdo_query("SELECT g.name,g.id FROM buildgroup AS g,buildgroupposition AS gp WHERE g.id=gp.buildgroupid\n                                                                                     AND gp.position='{$i}' AND g.projectid='{$projectid}'\n                                                                                     AND gp.starttime<'{$end_UTCDate}' AND (gp.endtime>'{$end_UTCDate}'  OR gp.endtime='1980-01-01 00:00:00')"));
        $xml .= "<buildgroup>";
        $xml .= add_buildgroup_sortlist($group['name']);
        $xml .= add_XML_value("id", $group["id"]);
        $xml .= add_XML_value("name", $group["name"]);
        $xml .= add_XML_value("linkname", str_replace(" ", "_", $group["name"]));
        if (!$filter_sql) {
            $xml .= add_expected_builds($group["id"], $currentstarttime, $received_builds);
        }
        $xml .= "</buildgroup>";
    }
    $xml .= add_XML_value("enableTestTiming", $project_array["showtesttime"]);
    $end = microtime_float();
    $xml .= "<generationtime>" . round($end - $start, 3) . "</generationtime>";
    if (!empty($sitexml)) {
        $xml .= $sitexml;
    }
    $xml .= "</cdash>";
    return $xml;
}
Example #21
0
 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);
 }
Example #22
0
 function testBuildFailureDetailsUpgrade()
 {
     require_once dirname(__FILE__) . '/cdash_test_case.php';
     require_once 'cdash/common.php';
     require_once 'cdash/pdo.php';
     $retval = 0;
     $old_table = "testbuildfailure";
     $new_table = "testdetails";
     global $CDASH_DB_TYPE;
     if ($CDASH_DB_TYPE == 'pgsql') {
         $create_old_query = '
     CREATE TABLE "' . $old_table . '" (
       "id" bigserial NOT NULL,
       "buildid" bigint NOT NULL,
       "type" smallint NOT NULL,
       "workingdirectory" character varying(512) NOT NULL,
       "stdoutput" text NOT NULL,
       "stderror" text NOT NULL,
       "exitcondition" character varying(255) NOT NULL,
       "language" character varying(64) NOT NULL,
       "targetname" character varying(255) NOT NULL,
       "outputfile" character varying(512) NOT NULL,
       "outputtype" character varying(255) NOT NULL,
       "sourcefile" character varying(512) NOT NULL,
       "crc32" bigint DEFAULT \'0\' NOT NULL,
       "newstatus" smallint DEFAULT \'0\' NOT NULL,
       PRIMARY KEY ("id")
     )';
         $create_new_query = '
     CREATE TABLE "' . $new_table . '" (
       "id" bigserial NOT NULL,
       "type" smallint NOT NULL,
       "stdoutput" text NOT NULL,
       "stderror" text NOT NULL,
       "exitcondition" character varying(255) NOT NULL,
       "language" character varying(64) NOT NULL,
       "targetname" character varying(255) NOT NULL,
       "outputfile" character varying(512) NOT NULL,
       "outputtype" character varying(255) NOT NULL,
       "crc32" bigint DEFAULT \'0\' NOT NULL,
       PRIMARY KEY ("id")
     )';
     } else {
         // MySQL
         $create_old_query = "\n        CREATE TABLE `{$old_table}` (\n          `id` bigint(20) NOT NULL auto_increment,\n          `buildid` bigint(20) NOT NULL,\n          `type` tinyint(4) NOT NULL,\n          `workingdirectory` varchar(512) NOT NULL,\n          `stdoutput` mediumtext NOT NULL,\n          `stderror` mediumtext NOT NULL,\n          `exitcondition` varchar(255) NOT NULL,\n          `language` varchar(64) NOT NULL,\n          `targetname` varchar(255) NOT NULL,\n          `outputfile` varchar(512) NOT NULL,\n          `outputtype` varchar(255) NOT NULL,\n          `sourcefile` varchar(512) NOT NULL,\n          `crc32` bigint(20) NOT NULL default '0',\n          `newstatus` tinyint(4) NOT NULL default '0',\n          PRIMARY KEY  (`id`)\n        )";
         $create_new_query = "\n        CREATE TABLE `{$new_table}` (\n          `id` bigint(20) NOT NULL auto_increment,\n          `type` tinyint(4) NOT NULL,\n          `stdoutput` mediumtext NOT NULL,\n          `stderror` mediumtext NOT NULL,\n          `exitcondition` varchar(255) NOT NULL,\n          `language` varchar(64) NOT NULL,\n          `targetname` varchar(255) NOT NULL,\n          `outputfile` varchar(512) NOT NULL,\n          `outputtype` varchar(255) NOT NULL,\n          `crc32` bigint(20) NOT NULL default '0',\n          PRIMARY KEY  (`id`)\n        )";
     }
     // Create testing tables.
     if (!pdo_query($create_old_query)) {
         $this->fail("pdo_query returned false");
         $retval = 1;
     }
     if (!pdo_query($create_new_query)) {
         $this->fail("pdo_query returned false");
         $retval = 1;
     }
     // Insert two identical buildfailures into the old table.
     $insert_query = "\n      INSERT INTO {$old_table}\n        (buildid, type, workingdirectory, stdoutput, stderror, exitcondition,\n         language, targetname, outputfile, outputtype, sourcefile, crc32,\n         newstatus)\n      VALUES\n        (1, 1, '/tmp/', 'this is stdout', 'this is stderror', '0',\n         'C', 'foo', 'foo.o', 'object file', 'foo.c', '1234',\n         '0')";
     if (!pdo_query($insert_query)) {
         $this->fail("pdo_query returned false");
         $retval = 1;
     }
     if (!pdo_query($insert_query)) {
         $this->fail("pdo_query returned false");
         $retval = 1;
     }
     // Run the upgrade function.
     UpgradeBuildFailureTable($old_table, $new_table);
     // Verify that we now have two buildfailures and one buildfailuredetails.
     $count_query = "\n      SELECT COUNT(DISTINCT id) AS numfails,\n             COUNT(DISTINCT detailsid) AS numdetails\n      FROM {$old_table}";
     $count_results = pdo_single_row_query($count_query);
     if ($count_results['numfails'] != 2) {
         $this->fail("Expected 2 buildfailures, found " . $count_results['numfails']);
         $retval = 1;
     }
     if ($count_results['numdetails'] != 1) {
         $this->fail("Expected 1 buildfailuredetails, found " . $count_results['numdetails']);
         $retval = 1;
     }
     // Drop the testing tables.
     pdo_query("DROP TABLE {$old_table}");
     pdo_query("DROP TABLE {$new_table}");
     if ($retval == 0) {
         $this->pass("Passed");
     }
     return $retval;
 }
Example #23
0
 /** Function to set this subproject's group. */
 public function SetGroup($groupName)
 {
     $groupName = pdo_real_escape_string($groupName);
     $row = pdo_single_row_query("SELECT id from subprojectgroup\n            WHERE name = '{$groupName}' AND endtime='1980-01-01 00:00:00'");
     if (empty($row)) {
         // Create the group if it doesn't exist yet.
         $subprojectGroup = new SubProjectGroup();
         $subprojectGroup->SetName($groupName);
         $subprojectGroup->SetProjectId($this->ProjectId);
         if ($subprojectGroup->Save() === false) {
             return false;
         }
         $this->GroupId = $subprojectGroup->GetId();
         return true;
     }
     $this->GroupId = $row['id'];
     return true;
 }
Example #24
0
function ReleaseProcessingLock($projectid)
{
    $unlocked = false;
    $tables = array();
    $tables[] = 'submissionprocessor';
    $table_locked = pdo_lock_tables($tables);
    if (!$table_locked) {
        add_log("could not lock database tables", "ReleaseProcessingLock", LOG_ERR, $projectid);
    }
    if ($table_locked) {
        $now_utc = gmdate(FMT_DATETIMESTD);
        $mypid = getmypid();
        $row = pdo_single_row_query("SELECT * FROM submissionprocessor WHERE projectid='" . $projectid . "'");
        $pid = $row['pid'];
        if ($pid == $mypid) {
            pdo_query("UPDATE submissionprocessor " . "SET pid='0', lastupdated='{$now_utc}', locked='1980-01-01 00:00:00' " . "WHERE projectid='" . $projectid . "'");
            add_last_sql_error("ReleaseProcessingLock-1");
            $unlocked = true;
        } else {
            add_log("lock not released, unexpected pid mismatch: pid='{$pid}' mypid='{$mypid}' - attempt to unlock a lock we don't own...", "ReleaseProcessingLock", LOG_ERR, $projectid);
        }
        $table_unlocked = pdo_unlock_tables($tables);
        if (!$table_unlocked) {
            add_log("could not unlock database tables", "ReleaseProcessingLock", LOG_ERR, $projectid);
        }
    }
    return $unlocked;
}
Example #25
0
 public function testGithubPRComment()
 {
     echo "1. testGithubPRComment\n";
     global $configure;
     $this->login();
     // Create a project named CDash and set its repository information.
     $settings = ['Name' => 'CDash', 'Description' => 'CDash', 'CvsUrl' => 'github.com/Kitware/CDash', 'CvsViewerType' => 'github', 'BugTrackerFileUrl' => 'http://public.kitware.com/Bug/view.php?id=', 'repositories' => [['url' => 'https://github.com/Kitware/CDash', 'branch' => 'master', 'username' => $configure['github_username'], 'password' => $configure['github_password']]]];
     $this->ProjectId = $this->createProject($settings);
     if ($this->ProjectId < 1) {
         return 1;
     }
     // Setup subprojects by submitting the Project.xml file.
     global $configure;
     // Submit the file.
     $url = $this->url . '/submit.php?project=CDash';
     $result = $this->uploadfile($url, dirname(__FILE__) . '/data/GithubPR/Project.xml');
     $this->deleteLog($this->logfilename);
     // Submit a failing test.
     echo "Submitting Test.xml\n";
     if (!$this->submitPullRequestFile(dirname(__FILE__) . '/data/GithubPR/Test.xml')) {
         return 1;
     }
     // Submit a broken build.
     echo "Submitting Build.xml\n";
     if (!$this->submitPullRequestFile(dirname(__FILE__) . '/data/GithubPR/Build.xml')) {
         return 1;
     }
     // Submit a failed configure.
     echo "Submitting Configure.xml\n";
     if (!$this->submitPullRequestFile(dirname(__FILE__) . '/data/GithubPR/Configure.xml')) {
         return 1;
     }
     // Make sure these builds link back to the GitHub PR.
     $row = pdo_single_row_query("SELECT id, parentid FROM build\n                WHERE name = 'test_PR_comment' AND parentid>0 LIMIT 1");
     $build = new Build();
     $build->Id = $row['id'];
     $build->FillFromId($build->Id);
     $date = $build->GetDate();
     // Parent view
     $content = $this->connect($this->url . "/api/v1/index.php?project=CDash&date={$date}");
     $jsonobj = json_decode($content, true);
     $buildgroup = array_pop($jsonobj['buildgroups']);
     $build_response = $buildgroup['builds'][0];
     if ($build_response['changelink'] !== 'github.com/Kitware/CDash/pull/80') {
         $this->fail("Expected changelink not found for parent build.  Found: " . $build_response['changelink']);
     }
     if ($build_response['changeicon'] !== 'img/Octocat.png') {
         $this->fail("Expected changeicon not found for parent build.  Found: " . $build_response['changeicon']);
     }
     // Child view
     $parentid = $row['parentid'];
     $content = $this->connect($this->url . "/api/v1/index.php?project=CDash&parentid={$parentid}");
     $jsonobj = json_decode($content, true);
     if ($jsonobj['changelink'] !== 'github.com/Kitware/CDash/pull/80') {
         $this->fail("Expected changelink not found for parent build");
     }
     if ($jsonobj['changeicon'] !== 'img/Octocat.png') {
         $this->fail("Expected changeicon not found for parent build");
     }
     // Delete the project now that we're done with it.
     $this->deleteProject($this->ProjectId);
 }
 public function testSubProjectNextPrevious()
 {
     // Submit our testing data.  This sets up three days of data for the
     // Didasko subproject.
     //
     // Build_3.xml creates a build of Mesquite.  The purpose of this is
     // to keep the 'Current' link honest.  This test will fail if the
     // underlying functionality ignores the subproject & finds the
     // most recently submitted build instead.
     $filesToSubmit = array('Build_1.xml', 'Configure_1.xml', 'Notes_1.xml', 'Test_1.xml', 'Build_2.xml', 'Configure_2.xml', 'Notes_2.xml', 'Test_2.xml', 'Build_3.xml');
     $dir = dirname(__FILE__) . '/data/SubProjectNextPrevious';
     foreach ($filesToSubmit as $file) {
         if (!$this->submission('Trilinos', "{$dir}/{$file}")) {
             $this->fail("Failed to submit {$file}");
             return 1;
         }
     }
     // Get the ids for the three subsequent builds of Didasko.
     $result = pdo_query("\n                SELECT b.id FROM build AS b\n                LEFT JOIN subproject2build AS sp2b ON sp2b.buildid=b.id\n                LEFT JOIN subproject AS sp ON sp.id = sp2b.subprojectid\n                WHERE sp.name = 'Didasko'\n                ORDER BY b.starttime");
     $num_rows = pdo_num_rows($result);
     if ($num_rows != 3) {
         $this->fail("Expected 3 rows, found {$num_rows}");
         return 1;
     }
     $buildids = array();
     while ($row = pdo_fetch_array($result)) {
         $buildids[] = $row['id'];
     }
     $first_buildid = $buildids[0];
     $second_buildid = $buildids[1];
     $third_buildid = $buildids[2];
     // Verify the relevant pages have the correct links for
     // Previous, Next, and Current.
     $success = true;
     $error_msg = '';
     $old_style_pages = array('viewConfigure', 'viewUpdate');
     $new_style_pages = array('buildSummary', 'viewBuildError', 'viewNotes');
     foreach ($old_style_pages as $page) {
         $this->get($this->url . "/{$page}.php?buildid=" . $first_buildid);
         $content = $this->getBrowser()->getContent();
         if ($content == false) {
             $error_msg = "Error retrieving content from {$page}.php";
             $success = false;
             break;
         }
         // Verify 'Next' from build #1 points to build #2
         $pattern = "#<a href=\"[a-zA-Z.]+\\?buildid={$second_buildid}\">\\s*Next\\s*</a>#";
         if (preg_match($pattern, $content) !== 1) {
             $error_msg = "Expected 'Next' link not found on {$page} for {$first_buildid}";
             $success = false;
             break;
         }
         // Verify 'Current' from build #1 points to build #3
         $pattern = "#<a href=\"[a-zA-Z.]+\\?buildid={$third_buildid}\">\\s*Current\\s*</a>#";
         if (preg_match($pattern, $content) !== 1) {
             $error_msg = "Expected 'Current' link not found on {$page} for {$first_buildid}";
             $success = false;
             break;
         }
         $this->get($this->url . "/{$page}.php?buildid=" . $second_buildid);
         $content = $this->getBrowser()->getContent();
         if ($content == false) {
             $error_msg = "Error retrieving content from {$page}.php";
             $success = false;
             break;
         }
         // Verify 'Previous' from build #2 points to build #1
         $pattern = "#<a href=\"[a-zA-Z.]+\\?buildid={$first_buildid}\">\\s*Previous\\s*</a>#";
         if (preg_match($pattern, $content) !== 1) {
             $error_msg = "Expected 'Previous' link not found on {$page} for {$second_buildid}";
             $success = false;
             break;
         }
         // Verify 'Next' from build #2 points to build #3
         $pattern = "#<a href=\"[a-zA-Z.]+\\?buildid={$third_buildid}\">\\s*Next\\s*</a>#";
         if (preg_match($pattern, $content) !== 1) {
             $error_msg = "Expected 'Next' link not found on {$page} for {$second_buildid}";
             $success = false;
             break;
         }
         // Verify 'Current' from build #2 points to build #3
         $pattern = "#<a href=\"[a-zA-Z.]+\\?buildid={$third_buildid}\">\\s*Current\\s*</a>#";
         if (preg_match($pattern, $content) !== 1) {
             $error_msg = "Expected 'Current' link not found on {$page} for {$second_buildid}";
             $success = false;
             break;
         }
         $this->get($this->url . "/{$page}.php?buildid=" . $third_buildid);
         $content = $this->getBrowser()->getContent();
         if ($content == false) {
             $error_msg = "Error retrieving content from {$page}.php";
             $success = false;
             break;
         }
         // Verify 'Previous' from build #3 points to build #2
         $pattern = "#<a href=\"[a-zA-Z.]+\\?buildid={$second_buildid}\">\\s*Previous\\s*</a>#";
         if (preg_match($pattern, $content) !== 1) {
             $error_msg = "Expected 'Previous' link not found on {$page} for {$third_buildid}";
             $success = false;
             break;
         }
     }
     foreach ($new_style_pages as $page) {
         $this->get($this->url . "/api/v1/{$page}.php?buildid=" . $first_buildid);
         $content = $this->getBrowser()->getContent();
         $jsonobj = json_decode($content, true);
         // Verify 'Next' from build #1 points to build #2
         if (strpos($jsonobj['menu']['next'], "buildid={$second_buildid}") === false) {
             $error_msg = "Expected 'Next' link not found on {$page} for {$first_buildid}";
             $success = false;
             break;
         }
         // Verify 'Current' from build #1 points to build #3
         if (strpos($jsonobj['menu']['current'], "buildid={$third_buildid}") === false) {
             $error_msg = "Expected 'Current' link not found on {$page} for {$first_buildid}";
             $success = false;
             break;
         }
         $this->get($this->url . "/api/v1/{$page}.php?buildid=" . $second_buildid);
         $content = $this->getBrowser()->getContent();
         $jsonobj = json_decode($content, true);
         // Verify 'Previous' from build #2 points to build #1
         if (strpos($jsonobj['menu']['previous'], "buildid={$first_buildid}") === false) {
             $error_msg = "Expected 'Previous' link not found on {$page} for {$second_buildid}";
             $success = false;
             break;
         }
         // Verify 'Next' from build #2 points to build #3
         if (strpos($jsonobj['menu']['next'], "buildid={$third_buildid}") === false) {
             $error_msg = "Expected 'Next' link not found on {$page} for {$second_buildid}";
             $success = false;
             break;
         }
         // Verify 'Current' from build #2 points to build #3
         if (strpos($jsonobj['menu']['current'], "buildid={$third_buildid}") === false) {
             $error_msg = "Expected 'Current' link not found on {$page} for {$second_buildid}";
             $success = false;
             break;
         }
         $this->get($this->url . "/api/v1/{$page}.php?buildid=" . $third_buildid);
         $content = $this->getBrowser()->getContent();
         $jsonobj = json_decode($content, true);
         // Verify 'Previous' from build #3 points to build #2
         if (strpos($jsonobj['menu']['previous'], "buildid={$second_buildid}") === false) {
             $error_msg = "Expected 'Previous' link not found on {$page} for {$third_buildid}";
             $success = false;
             break;
         }
     }
     // Make sure that the parent builds link to each other correctly.
     $result = pdo_single_row_query("SELECT parentid FROM build WHERE id={$first_buildid}");
     $first_parentid = $result['parentid'];
     $result = pdo_single_row_query("SELECT parentid FROM build WHERE id={$second_buildid}");
     $second_parentid = $result['parentid'];
     $result = pdo_single_row_query("SELECT parentid FROM build WHERE id={$third_buildid}");
     $third_parentid = $result['parentid'];
     $this->get($this->url . "/api/v1/index.php?project=Trilinos&parentid={$first_parentid}");
     $content = $this->getBrowser()->getContent();
     $jsonobj = json_decode($content, true);
     // Verify 'Next' from parent #1 points to parent #2
     if (strpos($jsonobj['menu']['next'], "parentid={$second_parentid}") === false) {
         $error_msg = "Expected 'Next' link not found for first parent build";
         $success = false;
     }
     // Verify 'Current' from parent #1 points to parent #3
     if (strpos($jsonobj['menu']['current'], "parentid={$third_parentid}") === false) {
         $error_msg = "Expected 'Current' link not found for first parent build";
         $success = false;
     }
     $this->get($this->url . "/api/v1/index.php?project=Trilinos&parentid={$second_parentid}");
     $content = $this->getBrowser()->getContent();
     $jsonobj = json_decode($content, true);
     // Verify 'Previous' from parent #2 points to parent #1
     if (strpos($jsonobj['menu']['previous'], "parentid={$first_parentid}") === false) {
         $error_msg = "Expected 'Previous' link not found for second parent build";
         $success = false;
     }
     // Verify 'Next' from parent #2 points to parent #3
     if (strpos($jsonobj['menu']['next'], "parentid={$third_parentid}") === false) {
         $error_msg = "Expected 'Next' link not found for second parent build";
         $success = false;
     }
     // Verify 'Current' from parent #2 points to parent #3
     if (strpos($jsonobj['menu']['current'], "parentid={$third_parentid}") === false) {
         $error_msg = "Expected 'Current' link not found for second parent build";
         $success = false;
     }
     $this->get($this->url . "/api/v1/index.php?project=Trilinos&parentid={$third_parentid}");
     $content = $this->getBrowser()->getContent();
     $jsonobj = json_decode($content, true);
     // Verify 'Previous' from parent #3 points to parent #2
     if (strpos($jsonobj['menu']['previous'], "parentid={$second_parentid}") === false) {
         $error_msg = "Expected 'Previous' link not found for third parent build";
         $success = false;
     }
     // Make sure that a build is not displayed when it does not
     // contain any of the whitelisted SubProjects.
     $this->get($this->url . '/api/v1/index.php?project=Trilinos&date=2011-07-23&filtercount=1&showfilters=1&field1=subprojects&compare1=93&value1=Teuchos');
     $content = $this->getBrowser()->getContent();
     $jsonobj = json_decode($content, true);
     $num_buildgroups = count($jsonobj['buildgroups']);
     if ($num_buildgroups !== 0) {
         $error_msg = "Expected 0 BuildGroups while whitelisting, found {$num_buildgroups}";
         $success = false;
     }
     // Make sure that a build is not displayed when all of its
     // SubProjects have been blacklisted away.
     $this->get($this->url . '/api/v1/index.php?project=Trilinos&date=2011-07-23&filtercount=1&showfilters=1&field1=subprojects&compare1=92&value1=Didasko');
     $content = $this->getBrowser()->getContent();
     $jsonobj = json_decode($content, true);
     $num_buildgroups = count($jsonobj['buildgroups']);
     if ($num_buildgroups !== 0) {
         $error_msg = "Expected 0 BuildGroups while blacklisting, found {$num_buildgroups}";
         $success = false;
     }
     // Make sure that the reported number of labels does not
     // change when an irrelevant blacklist criterion is added.
     $this->get($this->url . '/api/v1/index.php?project=Trilinos&date=2011-07-23&filtercount=1&showfilters=1&field1=subprojects&compare1=92&value1=Teuchos');
     $content = $this->getBrowser()->getContent();
     $jsonobj = json_decode($content, true);
     $buildgroup = array_pop($jsonobj['buildgroups']);
     $label = $buildgroup['builds'][0]['label'];
     if ($label !== 'Didasko') {
         $error_msg = "Expected label 'Didasko', found {$label}";
         $success = false;
     }
     // Test the 'last clean build' feature.
     $this->get("{$this->url}/api/v1/build.php?buildid={$third_parentid}&getproblems=1");
     $content = $this->getBrowser()->getContent();
     $jsonobj = json_decode($content, true);
     if ($jsonobj['hasErrors'] !== true) {
         $error_msg = "Expected 'hasErrors' to be true";
         $success = false;
     }
     if ($jsonobj['hasFailingTests'] !== false) {
         $error_msg = "Expected 'hasFailingTests' to be false";
         $success = false;
     }
     if ($jsonobj['daysWithErrors'] !== 1) {
         $error_msg = "Expected 'daysWithErrors' to be 1, found " . $jsonobj['daysWithErrors'];
         $success = false;
     }
     if ($jsonobj['failingDate'] !== '2011-07-23') {
         $error_msg = "Expected 'failingDate' to be '2011-07-23', found " . $jsonobj['failingDate'];
         $success = false;
     }
     // Make sure the 'type' parameter is preserved across Previous/Next/Current
     // on viewBuildError.php.
     $this->get($this->url . "/api/v1/viewBuildError.php?type=1&buildid={$second_buildid}");
     $content = $this->getBrowser()->getContent();
     $jsonobj = json_decode($content, true);
     if (strpos($jsonobj['menu']['next'], "type=1") === false) {
         $error_msg = "type=1 not found in Next link of viewBuildError.php";
         $success = false;
     }
     if (strpos($jsonobj['menu']['previous'], "type=1") === false) {
         $error_msg = "type=1 not found in Previous link of viewBuildError.php";
         $success = false;
     }
     if (strpos($jsonobj['menu']['current'], "type=1") === false) {
         $error_msg = "type=1 not found in Current link of viewBuildError.php";
         $success = false;
     }
     // Delete the builds that we created during this test.
     remove_build($second_parentid);
     remove_build($third_parentid);
     if (!$success) {
         $this->fail($error_msg);
         return 1;
     }
     $this->pass('Tests passed');
     return 0;
 }
Example #27
0
 /**
  * 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);
 }
Example #28
0
function echo_main_dashboard_JSON($project_instance, $date)
{
    $start = microtime_float();
    $noforcelogin = 1;
    include_once dirname(dirname(dirname(__DIR__))) . '/config/config.php';
    require_once 'include/pdo.php';
    include 'public/login.php';
    include_once 'models/banner.php';
    include_once 'models/build.php';
    include_once 'models/subproject.php';
    $response = array();
    $db = pdo_connect("{$CDASH_DB_HOST}", "{$CDASH_DB_LOGIN}", "{$CDASH_DB_PASS}");
    if (!$db) {
        $response['error'] = 'Error connecting to CDash database server';
        echo json_encode($response);
        return;
    }
    if (!pdo_select_db("{$CDASH_DB_NAME}", $db)) {
        $response['error'] = 'Error selecting CDash database';
        echo json_encode($response);
        return;
    }
    $projectid = $project_instance->Id;
    $project = pdo_query("SELECT * FROM project WHERE id='{$projectid}'");
    if (pdo_num_rows($project) > 0) {
        $project_array = pdo_fetch_array($project);
        $projectname = $project_array['name'];
        if (isset($project_array['testingdataurl']) && $project_array['testingdataurl'] != '') {
            $testingdataurl = make_cdash_url(htmlentities($project_array['testingdataurl']));
        }
    } else {
        $response['error'] = "This project doesn't exist. Maybe the URL you are trying to access is wrong.";
        echo json_encode($response);
        return;
    }
    if (!checkUserPolicy(@$_SESSION['cdash']['loginid'], $project_array['id'], 1)) {
        $response['requirelogin'] = 1;
        echo json_encode($response);
        return;
    }
    $response = begin_JSON_response();
    $response['title'] = "CDash - {$projectname}";
    $response['feed'] = $CDASH_ENABLE_FEED;
    $response['showcalendar'] = 1;
    $Banner = new Banner();
    $Banner->SetProjectId(0);
    $text = $Banner->GetText();
    $banners = array();
    if ($text !== false) {
        $banners[] = $text;
    }
    $Banner->SetProjectId($projectid);
    $text = $Banner->GetText();
    if ($text !== false) {
        $banners[] = $text;
    }
    $response['banners'] = $banners;
    $site_response = array();
    // If parentid is set we need to lookup the date for this build
    // because it is not specified as a query string parameter.
    if (isset($_GET['parentid'])) {
        $parentid = pdo_real_escape_numeric($_GET['parentid']);
        $parent_build = new Build();
        $parent_build->Id = $parentid;
        $date = $parent_build->GetDate();
        $response['parentid'] = $parentid;
    } else {
        $response['parentid'] = -1;
    }
    list($previousdate, $currentstarttime, $nextdate) = get_dates($date, $project_array['nightlytime']);
    // Main dashboard section
    get_dashboard_JSON($projectname, $date, $response);
    $response['displaylabels'] = $project_array['displaylabels'];
    $page_id = 'index.php';
    $response['childview'] = 0;
    if ($CDASH_USE_LOCAL_DIRECTORY && file_exists('local/models/proProject.php')) {
        include_once 'local/models/proProject.php';
        $pro = new proProject();
        $pro->ProjectId = $projectid;
        $response['proedition'] = $pro->GetEdition(1);
    }
    if ($currentstarttime > time() && !isset($_GET['parentid'])) {
        $response['error'] = 'CDash cannot predict the future (yet)';
        echo json_encode($response);
        return;
    }
    // Menu definition
    $response['menu'] = array();
    $beginning_timestamp = $currentstarttime;
    $end_timestamp = $currentstarttime + 3600 * 24;
    $beginning_UTCDate = gmdate(FMT_DATETIME, $beginning_timestamp);
    $end_UTCDate = gmdate(FMT_DATETIME, $end_timestamp);
    if ($project_instance->GetNumberOfSubProjects($end_UTCDate) > 0) {
        $response['menu']['subprojects'] = 1;
    }
    if (isset($_GET['parentid'])) {
        $page_id = 'indexchildren.php';
        $response['childview'] = 1;
        // When a parentid is specified, we should link to the next build,
        // not the next day.
        $previous_buildid = $parent_build->GetPreviousBuildId();
        $current_buildid = $parent_build->GetCurrentBuildId();
        $next_buildid = $parent_build->GetNextBuildId();
        $base_url = 'index.php?project=' . urlencode($projectname);
        if ($previous_buildid > 0) {
            $response['menu']['previous'] = "{$base_url}&parentid={$previous_buildid}";
        } else {
            $response['menu']['noprevious'] = '1';
        }
        $response['menu']['current'] = "{$base_url}&parentid={$current_buildid}";
        if ($next_buildid > 0) {
            $response['menu']['next'] = "{$base_url}&parentid={$next_buildid}";
        } else {
            $response['menu']['nonext'] = '1';
        }
    } elseif (!has_next_date($date, $currentstarttime)) {
        $response['menu']['nonext'] = 1;
    }
    // Check if a SubProject parameter was specified.
    $subproject_name = @$_GET['subproject'];
    $subprojectid = false;
    if ($subproject_name) {
        $SubProject = new SubProject();
        $subproject_name = htmlspecialchars(pdo_real_escape_string($subproject_name));
        $SubProject->SetName($subproject_name);
        $SubProject->SetProjectId($projectid);
        $subprojectid = $SubProject->GetId();
        if ($subprojectid) {
            // Add an extra URL argument for the menu
            $response['extraurl'] = '&subproject=' . urlencode($subproject_name);
            $response['subprojectname'] = $subproject_name;
            $subproject_response = array();
            $subproject_response['name'] = $SubProject->GetName();
            $dependencies = $SubProject->GetDependencies();
            if ($dependencies) {
                $dependencies_response = array();
                foreach ($dependencies as $dependency) {
                    $dependency_response = array();
                    $DependProject = new SubProject();
                    $DependProject->SetId($dependency);
                    $dependency_response['name'] = $DependProject->GetName();
                    $dependency_response['name_encoded'] = urlencode($DependProject->GetName());
                    $dependency_response['nbuilderror'] = $DependProject->GetNumberOfErrorBuilds($beginning_UTCDate, $end_UTCDate);
                    $dependency_response['nbuildwarning'] = $DependProject->GetNumberOfWarningBuilds($beginning_UTCDate, $end_UTCDate);
                    $dependency_response['nbuildpass'] = $DependProject->GetNumberOfPassingBuilds($beginning_UTCDate, $end_UTCDate);
                    $dependency_response['nconfigureerror'] = $DependProject->GetNumberOfErrorConfigures($beginning_UTCDate, $end_UTCDate);
                    $dependency_response['nconfigurewarning'] = $DependProject->GetNumberOfWarningConfigures($beginning_UTCDate, $end_UTCDate);
                    $dependency_response['nconfigurepass'] = $DependProject->GetNumberOfPassingConfigures($beginning_UTCDate, $end_UTCDate);
                    $dependency_response['ntestpass'] = $DependProject->GetNumberOfPassingTests($beginning_UTCDate, $end_UTCDate);
                    $dependency_response['ntestfail'] = $DependProject->GetNumberOfFailingTests($beginning_UTCDate, $end_UTCDate);
                    $dependency_response['ntestnotrun'] = $DependProject->GetNumberOfNotRunTests($beginning_UTCDate, $end_UTCDate);
                    if (strlen($DependProject->GetLastSubmission()) == 0) {
                        $dependency_response['lastsubmission'] = 'NA';
                    } else {
                        $dependency_response['lastsubmission'] = $DependProject->GetLastSubmission();
                    }
                    $dependencies_response[] = $dependency_response;
                }
                $subproject_response['dependencies'] = $dependencies_response;
            }
            $response['subproject'] = $subproject_response;
        } else {
            add_log("SubProject '{$subproject_name}' does not exist", __FILE__ . ':' . __LINE__ . ' - ' . __FUNCTION__, LOG_WARNING);
        }
    }
    if (isset($testingdataurl)) {
        $response['testingdataurl'] = $testingdataurl;
    }
    // updates
    $updates_response = array();
    $gmdate = gmdate(FMT_DATE, $currentstarttime);
    $updates_response['url'] = 'viewChanges.php?project=' . urlencode($projectname) . '&amp;date=' . $gmdate;
    $dailyupdate = pdo_query("SELECT count(ds.dailyupdateid),count(distinct ds.author)\n            FROM dailyupdate AS d LEFT JOIN dailyupdatefile AS ds ON (ds.dailyupdateid = d.id)\n            WHERE d.date='{$gmdate}' and d.projectid='{$projectid}' GROUP BY ds.dailyupdateid");
    if (pdo_num_rows($dailyupdate) > 0) {
        $dailupdate_array = pdo_fetch_array($dailyupdate);
        $updates_response['nchanges'] = $dailupdate_array[0];
        $updates_response['nauthors'] = $dailupdate_array[1];
    } else {
        $updates_response['nchanges'] = -1;
    }
    $updates_response['timestamp'] = date('l, F d Y - H:i T', $currentstarttime);
    $response['updates'] = $updates_response;
    // This array is used to track if expected builds are found or not.
    $received_builds = array();
    // Get info about our buildgroups.
    $buildgroups_response = array();
    $buildgroup_result = pdo_query("SELECT bg.id, bg.name, bgp.position FROM buildgroup AS bg\n            LEFT JOIN buildgroupposition AS bgp ON (bgp.buildgroupid=bg.id)\n            WHERE bg.projectid={$projectid} AND bg.starttime < '{$beginning_UTCDate}' AND\n            (bg.endtime > '{$beginning_UTCDate}' OR\n             bg.endtime='1980-01-01 00:00:00')");
    while ($buildgroup_array = pdo_fetch_array($buildgroup_result)) {
        $buildgroup_response = array();
        $groupname = $buildgroup_array['name'];
        $buildgroup_response['id'] = $buildgroup_array['id'];
        $buildgroup_response['name'] = $groupname;
        $buildgroup_response['linkname'] = str_replace(' ', '_', $groupname);
        $buildgroup_response['position'] = $buildgroup_array['position'];
        $buildgroup_response['numupdatedfiles'] = 0;
        $buildgroup_response['numupdateerror'] = 0;
        $buildgroup_response['numupdatewarning'] = 0;
        $buildgroup_response['updateduration'] = 0;
        $buildgroup_response['configureduration'] = 0;
        $buildgroup_response['numconfigureerror'] = 0;
        $buildgroup_response['numconfigurewarning'] = 0;
        $buildgroup_response['numbuilderror'] = 0;
        $buildgroup_response['numbuildwarning'] = 0;
        $buildgroup_response['numtestnotrun'] = 0;
        $buildgroup_response['numtestfail'] = 0;
        $buildgroup_response['numtestpass'] = 0;
        $buildgroup_response['testduration'] = 0;
        $buildgroup_response['hasupdatedata'] = false;
        $buildgroup_response['hasconfiguredata'] = false;
        $buildgroup_response['hascompilationdata'] = false;
        $buildgroup_response['hastestdata'] = false;
        $buildgroup_response['hasnormalbuilds'] = false;
        $buildgroup_response['hasparentbuilds'] = false;
        $buildgroup_response['builds'] = array();
        $received_builds[$groupname] = array();
        $buildgroups_response[] = $buildgroup_response;
    }
    // Filters:
    //
    $filterdata = get_filterdata_from_request($page_id);
    $filter_sql = $filterdata['sql'];
    $limit_sql = '';
    if ($filterdata['limit'] > 0) {
        $limit_sql = ' LIMIT ' . $filterdata['limit'];
    }
    unset($filterdata['xml']);
    $response['filterdata'] = $filterdata;
    $response['filterurl'] = get_filterurl();
    // Check if we should be excluding some SubProjects from our
    // build results.
    $include_subprojects = false;
    $exclude_subprojects = false;
    $included_subprojects = array();
    $excluded_subprojects = array();
    $selected_subprojects = '';
    $num_selected_subprojects = 0;
    $filter_on_labels = false;
    $share_label_filters = false;
    foreach ($filterdata['filters'] as $filter) {
        if ($filter['field'] == 'subprojects') {
            if ($filter['compare'] == 92) {
                $excluded_subprojects[] = $filter['value'];
            } elseif ($filter['compare'] == 93) {
                $included_subprojects[] = $filter['value'];
            }
        } elseif ($filter['field'] == 'label') {
            $filter_on_labels = true;
        }
    }
    if ($filter_on_labels && $project_instance->ShareLabelFilters) {
        $share_label_filters = true;
        $response['sharelabelfilters'] = true;
        $label_ids_array = get_label_ids_from_filterdata($filterdata);
        $label_ids = '(' . implode(', ', $label_ids_array) . ')';
    }
    // Include takes precedence over exclude.
    if (!empty($included_subprojects)) {
        $num_selected_subprojects = count($included_subprojects);
        $selected_subprojects = implode("','", $included_subprojects);
        $selected_subprojects = "('" . $selected_subprojects . "')";
        $include_subprojects = true;
    } elseif (!empty($excluded_subprojects)) {
        $num_selected_subprojects = count($excluded_subprojects);
        $selected_subprojects = implode("','", $excluded_subprojects);
        $selected_subprojects = "('" . $selected_subprojects . "')";
        $exclude_subprojects = true;
    }
    // add a request for the subproject
    $subprojectsql = '';
    if ($subproject_name && is_numeric($subprojectid)) {
        $subprojectsql = ' AND sp2b.subprojectid=' . $subprojectid;
    }
    // Use this as the default date clause, but if $filterdata has a date clause,
    // then cancel this one out:
    //
    $date_clause = "AND b.starttime<'{$end_UTCDate}' AND b.starttime>='{$beginning_UTCDate}' ";
    if ($filterdata['hasdateclause']) {
        $date_clause = '';
    }
    $parent_clause = '';
    if (isset($_GET['parentid'])) {
        // If we have a parentid, then we should only show children of that build.
        // Date becomes irrelevant in this case.
        $parent_clause = 'AND (b.parentid = ' . qnum($_GET['parentid']) . ') ';
        $date_clause = '';
    } elseif (empty($subprojectsql)) {
        // Only show builds that are not children.
        $parent_clause = 'AND (b.parentid = -1 OR b.parentid = 0) ';
    }
    $build_rows = array();
    // If the user is logged in we display if the build has some changes for him
    $userupdatesql = '';
    if (isset($_SESSION['cdash']) && array_key_exists('loginid', $_SESSION['cdash'])) {
        $userupdatesql = "(SELECT count(updatefile.updateid) FROM updatefile,build2update,user2project,\n            user2repository\n                WHERE build2update.buildid=b.id\n                AND build2update.updateid=updatefile.updateid\n                AND user2project.projectid=b.projectid\n                AND user2project.userid='" . $_SESSION['cdash']['loginid'] . "'\n                AND user2repository.userid=user2project.userid\n                AND (user2repository.projectid=0 OR user2repository.projectid=b.projectid)\n                AND user2repository.credential=updatefile.author) AS userupdates,";
    }
    $sql = get_index_query();
    $sql .= "WHERE b.projectid='{$projectid}' AND g.type='Daily'\n        {$parent_clause} {$date_clause} {$subprojectsql} {$filter_sql} {$limit_sql}";
    // We shouldn't get any builds for group that have been deleted (otherwise something is wrong)
    $builds = pdo_query($sql);
    // Log any errors
    $pdo_error = pdo_error();
    if (strlen($pdo_error) > 0) {
        add_log('SQL error: ' . $pdo_error, 'Index.php', LOG_ERR);
    }
    // Gather up results from this query.
    $build_data = array();
    while ($build_row = pdo_fetch_array($builds)) {
        $build_data[] = $build_row;
    }
    $dynamic_builds = array();
    if (empty($filter_sql)) {
        $dynamic_builds = get_dynamic_builds($projectid, $end_UTCDate);
        $build_data = array_merge($build_data, $dynamic_builds);
    }
    // Check if we need to summarize coverage by subproject groups.
    // This happens when we have subprojects and we're looking at the children
    // of a specific build.
    $coverage_groups = array();
    if (isset($_GET['parentid']) && $_GET['parentid'] > 0 && $project_instance->GetNumberOfSubProjects($end_UTCDate) > 0) {
        $groups = $project_instance->GetSubProjectGroups();
        foreach ($groups as $group) {
            // Keep track of coverage info on a per-group basis.
            $groupId = $group->GetId();
            $coverage_groups[$groupId] = array();
            $coverageThreshold = $group->GetCoverageThreshold();
            $coverage_groups[$groupId]['thresholdgreen'] = $coverageThreshold;
            $coverage_groups[$groupId]['thresholdyellow'] = $coverageThreshold * 0.7;
            $coverage_groups[$groupId]['label'] = $group->GetName();
            $coverage_groups[$groupId]['loctested'] = 0;
            $coverage_groups[$groupId]['locuntested'] = 0;
            $coverage_groups[$groupId]['position'] = $group->GetPosition();
            $coverage_groups[$groupId]['coverages'] = array();
        }
        if (count($groups) > 1) {
            // Add a Total group too.
            $coverage_groups[0] = array();
            $coverageThreshold = $project_array['coveragethreshold'];
            $coverage_groups[0]['thresholdgreen'] = $coverageThreshold;
            $coverage_groups[0]['thresholdyellow'] = $coverageThreshold * 0.7;
            $coverage_groups[0]['label'] = 'Total';
            $coverage_groups[0]['loctested'] = 0;
            $coverage_groups[0]['locuntested'] = 0;
            $coverage_groups[0]['position'] = 0;
        }
    }
    // Fetch all the rows of builds into a php array.
    // Compute additional fields for each row that we'll need to generate the xml.
    //
    $build_rows = array();
    foreach ($build_data as $build_row) {
        // Fields that come from the initial query:
        //  id
        //  sitename
        //  stamp
        //  name
        //  siteid
        //  type
        //  generator
        //  starttime
        //  endtime
        //  submittime
        //  groupname
        //  position
        //  groupid
        //  countupdatefiles
        //  updatestatus
        //  countupdatewarnings
        //  countbuildwarnings
        //  countbuilderrors
        //  countbuilderrordiff
        //  countbuildwarningdiff
        //  configureduration
        //  countconfigureerrors
        //  countconfigurewarnings
        //  countconfigurewarningdiff
        //  counttestsnotrun
        //  counttestsnotrundiff
        //  counttestsfailed
        //  counttestsfaileddiff
        //  counttestspassed
        //  counttestspasseddiff
        //  countteststimestatusfailed
        //  countteststimestatusfaileddiff
        //  testduration
        //
        // Fields that we add within this loop:
        //  maxstarttime
        //  buildids (array of buildids for summary rows)
        //  countbuildnotes (added by users)
        //  labels
        //  updateduration
        //  countupdateerrors
        //  test
        //
        $buildid = $build_row['id'];
        $groupid = $build_row['groupid'];
        $siteid = $build_row['siteid'];
        $parentid = $build_row['parentid'];
        $build_row['buildids'][] = $buildid;
        $build_row['maxstarttime'] = $build_row['starttime'];
        // Updates
        if (!empty($build_row['updatestarttime'])) {
            $build_row['updateduration'] = round((strtotime($build_row['updateendtime']) - strtotime($build_row['updatestarttime'])) / 60, 1);
        } else {
            $build_row['updateduration'] = 0;
        }
        if (strlen($build_row['updatestatus']) > 0 && $build_row['updatestatus'] != '0') {
            $build_row['countupdateerrors'] = 1;
        } else {
            $build_row['countupdateerrors'] = 0;
        }
        // Error/Warnings differences
        if (empty($build_row['countbuilderrordiffp'])) {
            $build_row['countbuilderrordiffp'] = 0;
        }
        if (empty($build_row['countbuilderrordiffn'])) {
            $build_row['countbuilderrordiffn'] = 0;
        }
        if (empty($build_row['countbuildwarningdiffp'])) {
            $build_row['countbuildwarningdiffp'] = 0;
        }
        if (empty($build_row['countbuildwarningdiffn'])) {
            $build_row['countbuildwarningdiffn'] = 0;
        }
        $build_row['hasconfigure'] = 0;
        if ($build_row['countconfigureerrors'] != -1 || $build_row['countconfigurewarnings'] != -1) {
            $build_row['hasconfigure'] = 1;
        }
        if ($build_row['countconfigureerrors'] < 0) {
            $build_row['countconfigureerrors'] = 0;
        }
        if ($build_row['countconfigurewarnings'] < 0) {
            $build_row['countconfigurewarnings'] = 0;
        }
        if (empty($build_row['countconfigurewarningdiff'])) {
            $build_row['countconfigurewarningdiff'] = 0;
        }
        $build_row['hastest'] = 0;
        if ($build_row['counttestsfailed'] != -1) {
            $build_row['hastest'] = 1;
        }
        if (empty($build_row['testduration'])) {
            $time_array = pdo_fetch_array(pdo_query("SELECT SUM(time) FROM build2test WHERE buildid='{$buildid}'"));
            $build_row['testduration'] = round($time_array[0], 1);
        } else {
            $build_row['testduration'] = round($build_row['testduration'], 1);
        }
        $build_rows[] = $build_row;
    }
    // Generate the JSON response from the rows of builds.
    $response['coverages'] = array();
    $response['dynamicanalyses'] = array();
    $num_nightly_coverages_builds = 0;
    $show_aggregate = false;
    $response['comparecoverage'] = 0;
    foreach ($build_rows as $build_array) {
        $groupid = $build_array['groupid'];
        // Find the buildgroup array for this build.
        $i = -1;
        for ($j = 0; $j < count($buildgroups_response); $j++) {
            if ($buildgroups_response[$j]['id'] == $groupid) {
                $i = $j;
                break;
            }
        }
        if ($i == -1) {
            add_log("BuildGroup '{$groupid}' not found for build #" . $build_array['id'], __FILE__ . ':' . __LINE__ . ' - ' . __FUNCTION__, LOG_WARNING);
            continue;
        }
        $groupname = $buildgroups_response[$i]['name'];
        $build_response = array();
        $received_builds[$groupname][] = $build_array['sitename'] . '_' . $build_array['name'];
        $buildid = $build_array['id'];
        $siteid = $build_array['siteid'];
        $countChildrenResult = pdo_single_row_query('SELECT count(id) AS numchildren
                FROM build WHERE parentid=' . qnum($buildid));
        $numchildren = $countChildrenResult['numchildren'];
        $build_response['numchildren'] = $numchildren;
        $child_builds_hyperlink = '';
        $selected_configure_errors = 0;
        $selected_configure_warnings = 0;
        $selected_configure_duration = 0;
        $selected_build_errors = 0;
        $selected_build_warnings = 0;
        $selected_build_duration = 0;
        $selected_tests_not_run = 0;
        $selected_tests_failed = 0;
        $selected_tests_passed = 0;
        $selected_test_duration = 0;
        if ($numchildren > 0) {
            $child_builds_hyperlink = get_child_builds_hyperlink($build_array['id'], $filterdata);
            $build_response['multiplebuildshyperlink'] = $child_builds_hyperlink;
            $buildgroups_response[$i]['hasparentbuilds'] = true;
            // Compute selected (excluded or included) SubProject results.
            if ($selected_subprojects) {
                $select_query = "\n                    SELECT configureerrors, configurewarnings, configureduration,\n                           builderrors, buildwarnings, buildduration,\n                           b.starttime, b.endtime, testnotrun, testfailed, testpassed,\n                           btt.time AS testduration, sb.name\n                    FROM build AS b\n                    INNER JOIN subproject2build AS sb2b ON (b.id = sb2b.buildid)\n                    INNER JOIN subproject AS sb ON (sb2b.subprojectid = sb.id)\n                    LEFT JOIN buildtesttime AS btt ON (b.id=btt.buildid)\n                    WHERE b.parentid={$buildid}\n                    AND sb.name IN {$selected_subprojects}";
                $select_results = pdo_query($select_query);
                while ($select_array = pdo_fetch_array($select_results)) {
                    $selected_configure_errors += max(0, $select_array['configureerrors']);
                    $selected_configure_warnings += max(0, $select_array['configurewarnings']);
                    $selected_configure_duration += max(0, $select_array['configureduration']);
                    $selected_build_errors += max(0, $select_array['builderrors']);
                    $selected_build_warnings += max(0, $select_array['buildwarnings']);
                    $selected_build_duration += max(0, $select_array['buildduration']);
                    $selected_tests_not_run += max(0, $select_array['testnotrun']);
                    $selected_tests_failed += max(0, $select_array['testfailed']);
                    $selected_tests_passed += max(0, $select_array['testpassed']);
                    $selected_test_duration += max(0, $select_array['testduration']);
                }
            }
        } else {
            $buildgroups_response[$i]['hasnormalbuilds'] = true;
        }
        if (strtolower($build_array['type']) == 'continuous') {
            $buildgroups_response[$i]['sorttype'] = 'time';
        }
        // Attempt to determine the platform based on the OSName and the buildname
        $buildplatform = '';
        if (strtolower(substr($build_array['osname'], 0, 7)) == 'windows') {
            $buildplatform = 'windows';
        } elseif (strtolower(substr($build_array['osname'], 0, 8)) == 'mac os x') {
            $buildplatform = 'mac';
        } elseif (strtolower(substr($build_array['osname'], 0, 5)) == 'linux' || strtolower(substr($build_array['osname'], 0, 3)) == 'aix') {
            $buildplatform = 'linux';
        } elseif (strtolower(substr($build_array['osname'], 0, 7)) == 'freebsd') {
            $buildplatform = 'freebsd';
        } elseif (strtolower(substr($build_array['osname'], 0, 3)) == 'gnu') {
            $buildplatform = 'gnu';
        }
        // Add link based on changeid if appropriate.
        $changelink = null;
        $changeicon = null;
        if ($build_array['changeid'] && $project_instance->CvsViewerType === 'github') {
            $changelink = $project_instance->CvsUrl . '/pull/' . $build_array['changeid'];
            $changeicon = 'img/Octocat.png';
        }
        if (isset($_GET['parentid'])) {
            if (empty($site_response)) {
                $site_response['site'] = $build_array['sitename'];
                $site_response['siteoutoforder'] = $build_array['siteoutoforder'];
                $site_response['siteid'] = $siteid;
                $site_response['buildname'] = $build_array['name'];
                $site_response['buildplatform'] = $buildplatform;
                $site_response['generator'] = $build_array['generator'];
                if (!is_null($changelink)) {
                    $site_response['changelink'] = $changelink;
                    $site_response['changeicon'] = $changeicon;
                }
            }
        } else {
            $build_response['site'] = $build_array['sitename'];
            $build_response['siteoutoforder'] = $build_array['siteoutoforder'];
            $build_response['siteid'] = $siteid;
            $build_response['buildname'] = $build_array['name'];
            $build_response['buildplatform'] = $buildplatform;
            if (!is_null($changelink)) {
                $build_response['changelink'] = $changelink;
                $build_response['changeicon'] = $changeicon;
            }
        }
        if (isset($build_array['userupdates'])) {
            $build_response['userupdates'] = $build_array['userupdates'];
        }
        $build_response['id'] = $build_array['id'];
        $build_response['done'] = $build_array['done'];
        $build_response['uploadfilecount'] = $build_array['builduploadfiles'];
        $build_response['buildnotes'] = $build_array['countbuildnotes'];
        $build_response['notes'] = $build_array['countnotes'];
        // Figure out how many labels to report for this build.
        if (!array_key_exists('numlabels', $build_array) || $build_array['numlabels'] == 0) {
            $num_labels = 0;
        } else {
            $num_labels = $build_array['numlabels'];
        }
        $label_query = 'SELECT l.text FROM label AS l
            INNER JOIN label2build AS l2b ON (l.id=l2b.labelid)
            INNER JOIN build AS b ON (l2b.buildid=b.id)
            WHERE b.id=' . qnum($buildid);
        $build_labels = array();
        if ($num_selected_subprojects > 0) {
            // Special handling for whitelisting/blacklisting SubProjects.
            if ($include_subprojects) {
                $num_labels = 0;
            }
            $labels_result = pdo_query($label_query);
            while ($label_row = pdo_fetch_array($labels_result)) {
                // Whitelist case
                if ($include_subprojects && in_array($label_row['text'], $included_subprojects)) {
                    $num_labels++;
                    $build_labels[] = $label_row['text'];
                }
                // Blacklist case
                if ($exclude_subprojects) {
                    if (in_array($label_row['text'], $excluded_subprojects)) {
                        $num_labels--;
                    } else {
                        $build_labels[] = $label_row['text'];
                    }
                }
            }
            if ($num_labels === 0) {
                // Skip this build entirely if none of its SubProjects
                // survived filtering.
                continue;
            }
        }
        // Assign a label to this build based on how many labels it has.
        if ($num_labels == 0) {
            $build_label = '(none)';
        } elseif ($num_labels == 1) {
            // Exactly one label for this build
            if (!empty($build_labels)) {
                // If we're whitelisting or blacklisting we've already figured
                // out what this label is.
                $build_label = $build_labels[0];
            } else {
                // Otherwise we look it up here.
                $label_result = pdo_single_row_query($label_query);
                $build_label = $label_result['text'];
            }
        } else {
            // More than one label, just report the number.
            $build_label = "({$num_labels} labels)";
        }
        $build_response['label'] = $build_label;
        // Calculate this build's total duration.
        $duration = strtotime($build_array['endtime']) - strtotime($build_array['starttime']);
        $build_response['time'] = time_difference($duration, true);
        $build_response['timefull'] = $duration;
        $update_response = array();
        $countupdatefiles = $build_array['countupdatefiles'];
        $update_response['files'] = $countupdatefiles;
        $buildgroups_response[$i]['numupdatedfiles'] += $countupdatefiles;
        $build_response['hasupdate'] = false;
        if (!empty($build_array['updatestarttime'])) {
            $build_response['hasupdate'] = true;
            if ($build_array['countupdateerrors'] > 0) {
                $update_response['errors'] = 1;
                $buildgroups_response[$i]['numupdateerror'] += 1;
            } else {
                $update_response['errors'] = 0;
                if ($build_array['countupdatewarnings'] > 0) {
                    $update_response['warning'] = 1;
                    $buildgroups_response[$i]['numupdatewarning'] += 1;
                }
            }
            $duration = $build_array['updateduration'];
            $update_response['time'] = time_difference($duration * 60.0, true);
            $update_response['timefull'] = $duration;
            $buildgroups_response[$i]['updateduration'] += $duration;
            $buildgroups_response[$i]['hasupdatedata'] = true;
            $build_response['update'] = $update_response;
        }
        $compilation_response = array();
        if ($build_array['countbuilderrors'] >= 0) {
            if ($include_subprojects) {
                $nerrors = $selected_build_errors;
                $nwarnings = $selected_build_warnings;
                $buildduration = $selected_build_duration;
            } else {
                $nerrors = $build_array['countbuilderrors'] - $selected_build_errors;
                $nwarnings = $build_array['countbuildwarnings'] - $selected_build_warnings;
                $buildduration = $build_array['buildduration'] - $selected_build_duration;
            }
            $compilation_response['error'] = $nerrors;
            $buildgroups_response[$i]['numbuilderror'] += $nerrors;
            $compilation_response['warning'] = $nwarnings;
            $buildgroups_response[$i]['numbuildwarning'] += $nwarnings;
            $compilation_response['time'] = time_difference($buildduration, true);
            $compilation_response['timefull'] = $buildduration;
            if (!$include_subprojects && !$exclude_subprojects) {
                // Don't show diff when filtering by SubProject.
                $compilation_response['nerrordiffp'] = $build_array['countbuilderrordiffp'];
                $compilation_response['nerrordiffn'] = $build_array['countbuilderrordiffn'];
                $compilation_response['nwarningdiffp'] = $build_array['countbuildwarningdiffp'];
                $compilation_response['nwarningdiffn'] = $build_array['countbuildwarningdiffn'];
            }
        }
        $build_response['hascompilation'] = false;
        if (!empty($compilation_response)) {
            $build_response['hascompilation'] = true;
            $build_response['compilation'] = $compilation_response;
            $buildgroups_response[$i]['hascompilationdata'] = true;
        }
        $build_response['hasconfigure'] = false;
        if ($build_array['hasconfigure'] != 0) {
            $build_response['hasconfigure'] = true;
            $configure_response = array();
            if ($include_subprojects) {
                $nconfigureerrors = $selected_configure_errors;
                $nconfigurewarnings = $selected_configure_warnings;
                $configureduration = $selected_configure_duration;
            } else {
                $nconfigureerrors = $build_array['countconfigureerrors'] - $selected_configure_errors;
                $nconfigurewarnings = $build_array['countconfigurewarnings'] - $selected_configure_warnings;
                $configureduration = $build_array['configureduration'] - $selected_configure_duration;
            }
            $configure_response['error'] = $nconfigureerrors;
            $buildgroups_response[$i]['numconfigureerror'] += $nconfigureerrors;
            $configure_response['warning'] = $nconfigurewarnings;
            $buildgroups_response[$i]['numconfigurewarning'] += $nconfigurewarnings;
            if (!$include_subprojects && !$exclude_subprojects) {
                $configure_response['warningdiff'] = $build_array['countconfigurewarningdiff'];
            }
            $configure_response['time'] = time_difference($configureduration, true);
            $configure_response['timefull'] = $configureduration;
            $build_response['configure'] = $configure_response;
            $buildgroups_response[$i]['hasconfiguredata'] = true;
            $buildgroups_response[$i]['configureduration'] += $configureduration;
        }
        $build_response['hastest'] = false;
        if ($build_array['hastest'] != 0) {
            $build_response['hastest'] = true;
            $buildgroups_response[$i]['hastestdata'] = true;
            $test_response = array();
            if ($include_subprojects) {
                $nnotrun = $selected_tests_not_run;
                $nfail = $selected_tests_failed;
                $npass = $selected_tests_passed;
                $testduration = $selected_test_duration;
            } else {
                $nnotrun = $build_array['counttestsnotrun'] - $selected_tests_not_run;
                $nfail = $build_array['counttestsfailed'] - $selected_tests_failed;
                $npass = $build_array['counttestspassed'] - $selected_tests_passed;
                $testduration = $build_array['testduration'] - $selected_test_duration;
            }
            if (!$include_subprojects && !$exclude_subprojects) {
                $test_response['nnotrundiffp'] = $build_array['counttestsnotrundiffp'];
                $test_response['nnotrundiffn'] = $build_array['counttestsnotrundiffn'];
                $test_response['nfaildiffp'] = $build_array['counttestsfaileddiffp'];
                $test_response['nfaildiffn'] = $build_array['counttestsfaileddiffn'];
                $test_response['npassdiffp'] = $build_array['counttestspasseddiffp'];
                $test_response['npassdiffn'] = $build_array['counttestspasseddiffn'];
            }
            if ($project_array['showtesttime'] == 1) {
                $test_response['timestatus'] = $build_array['countteststimestatusfailed'];
                $test_response['ntimediffp'] = $build_array['countteststimestatusfaileddiffp'];
                $test_response['ntimediffn'] = $build_array['countteststimestatusfaileddiffn'];
            }
            if ($share_label_filters) {
                $label_query_base = "SELECT b2t.status, b2t.newstatus\n                    FROM build2test AS b2t\n                    INNER JOIN label2test AS l2t ON\n                    (l2t.testid=b2t.testid AND l2t.buildid=b2t.buildid)\n                    WHERE b2t.buildid = '{$buildid}' AND\n                    l2t.labelid IN {$label_ids}";
                $label_filter_query = $label_query_base . $limit_sql;
                $labels_result = pdo_query($label_filter_query);
                $nnotrun = 0;
                $nfail = 0;
                $npass = 0;
                $test_response['nfaildiffp'] = 0;
                $test_response['nfaildiffn'] = 0;
                $test_response['npassdiffp'] = 0;
                $test_response['npassdiffn'] = 0;
                $test_response['nnotrundiffp'] = 0;
                $test_response['nnotrundiffn'] = 0;
                while ($label_row = pdo_fetch_array($labels_result)) {
                    switch ($label_row['status']) {
                        case 'passed':
                            $npass++;
                            if ($label_row['newstatus'] == 1) {
                                $test_response['npassdiffp']++;
                            }
                            break;
                        case 'failed':
                            $nfail++;
                            if ($label_row['newstatus'] == 1) {
                                $test_response['nfaildiffp']++;
                            }
                            break;
                        case 'notrun':
                            $nnotrun++;
                            if ($label_row['newstatus'] == 1) {
                                $test_response['nnotrundiffp']++;
                            }
                            break;
                    }
                }
            }
            $test_response['notrun'] = $nnotrun;
            $test_response['fail'] = $nfail;
            $test_response['pass'] = $npass;
            $buildgroups_response[$i]['numtestnotrun'] += $nnotrun;
            $buildgroups_response[$i]['numtestfail'] += $nfail;
            $buildgroups_response[$i]['numtestpass'] += $npass;
            $test_response['time'] = time_difference($testduration, true);
            $test_response['timefull'] = $testduration;
            $buildgroups_response[$i]['testduration'] += $testduration;
            $build_response['test'] = $test_response;
        }
        $starttimestamp = strtotime($build_array['starttime'] . ' UTC');
        $submittimestamp = strtotime($build_array['submittime'] . ' UTC');
        // Use the default timezone.
        $build_response['builddatefull'] = $starttimestamp;
        // If the data is more than 24h old then we switch from an elapsed to a normal representation
        if (time() - $starttimestamp < 86400) {
            $build_response['builddate'] = date(FMT_DATETIMEDISPLAY, $starttimestamp);
            $build_response['builddateelapsed'] = time_difference(time() - $starttimestamp, false, 'ago');
        } else {
            $build_response['builddateelapsed'] = date(FMT_DATETIMEDISPLAY, $starttimestamp);
            $build_response['builddate'] = time_difference(time() - $starttimestamp, false, 'ago');
        }
        $build_response['submitdate'] = date(FMT_DATETIMEDISPLAY, $submittimestamp);
        // Generate a string summarizing this build's timing.
        $timesummary = $build_response['builddate'];
        if ($build_response['hasupdate'] && array_key_exists('time', $build_response['update'])) {
            $timesummary .= ', Update time: ' . $build_response['update']['time'];
        }
        if ($build_response['hasconfigure'] && array_key_exists('time', $build_response['configure'])) {
            $timesummary .= ', Configure time: ' . $build_response['configure']['time'];
        }
        if ($build_response['hascompilation'] && array_key_exists('time', $build_response['compilation'])) {
            $timesummary .= ', Build time: ' . $build_response['compilation']['time'];
        }
        if ($build_response['hastest'] && array_key_exists('time', $build_response['test'])) {
            $timesummary .= ', Test time: ' . $build_response['test']['time'];
        }
        $timesummary .= ', Total time: ' . $build_response['time'];
        $build_response['timesummary'] = $timesummary;
        if ($include_subprojects || $exclude_subprojects) {
            // Check if this build should be filtered out now that its
            // numbers have been updated by the SubProject include/exclude
            // filter.
            if (!build_survives_filter($build_response, $filterdata)) {
                continue;
            }
        }
        if ($build_array['name'] != 'Aggregate Coverage') {
            $buildgroups_response[$i]['builds'][] = $build_response;
        }
        // Coverage
        //
        // Determine if this is a parent build with no actual coverage of its own.
        $linkToChildCoverage = false;
        if ($numchildren > 0) {
            $countChildrenResult = pdo_single_row_query('SELECT count(fileid) AS nfiles FROM coverage
                    WHERE buildid=' . qnum($buildid));
            if ($countChildrenResult['nfiles'] == 0) {
                $linkToChildCoverage = true;
            }
        }
        $coverageIsGrouped = false;
        $loctested = $build_array['loctested'];
        $locuntested = $build_array['locuntested'];
        if ($loctested + $locuntested > 0) {
            $coverage_response = array();
            $coverage_response['buildid'] = $build_array['id'];
            if ($linkToChildCoverage) {
                $coverage_response['childlink'] = "{$child_builds_hyperlink}##Coverage";
            }
            if ($build_array['type'] === 'Nightly' && $build_array['name'] !== 'Aggregate Coverage') {
                $num_nightly_coverages_builds++;
                if ($num_nightly_coverages_builds > 1) {
                    $show_aggregate = true;
                    if ($linkToChildCoverage) {
                        $response['comparecoverage'] = 1;
                    }
                }
            }
            $percent = round(compute_percentcoverage($loctested, $locuntested), 2);
            if ($build_array['subprojectgroup']) {
                $groupId = $build_array['subprojectgroup'];
                if (array_key_exists($groupId, $coverage_groups)) {
                    $coverageIsGrouped = true;
                    $coverageThreshold = $coverage_groups[$groupId]['thresholdgreen'];
                    $coverage_groups[$groupId]['loctested'] += $loctested;
                    $coverage_groups[$groupId]['locuntested'] += $locuntested;
                    if (count($coverage_groups) > 1) {
                        // Add to Total.
                        $coverage_groups[0]['loctested'] += $loctested;
                        $coverage_groups[0]['locuntested'] += $locuntested;
                    }
                }
            }
            $coverage_response['percentage'] = $percent;
            $coverage_response['locuntested'] = intval($locuntested);
            $coverage_response['loctested'] = intval($loctested);
            // Compute the diff
            if (!empty($build_array['loctesteddiff'])) {
                $loctesteddiff = $build_array['loctesteddiff'];
                $locuntesteddiff = $build_array['locuntesteddiff'];
                @($previouspercent = round(($loctested - $loctesteddiff) / ($loctested - $loctesteddiff + $locuntested - $locuntesteddiff) * 100, 2));
                $percentdiff = round($percent - $previouspercent, 2);
                $coverage_response['percentagediff'] = $percentdiff;
                $coverage_response['locuntesteddiff'] = $locuntesteddiff;
                $coverage_response['loctesteddiff'] = $loctesteddiff;
            }
            $starttimestamp = strtotime($build_array['starttime'] . ' UTC');
            $coverage_response['datefull'] = $starttimestamp;
            // If the data is more than 24h old then we switch from an elapsed to a normal representation
            if (time() - $starttimestamp < 86400) {
                $coverage_response['date'] = date(FMT_DATETIMEDISPLAY, $starttimestamp);
                $coverage_response['dateelapsed'] = time_difference(time() - $starttimestamp, false, 'ago');
            } else {
                $coverage_response['dateelapsed'] = date(FMT_DATETIMEDISPLAY, $starttimestamp);
                $coverage_response['date'] = time_difference(time() - $starttimestamp, false, 'ago');
            }
            // Are there labels for this build?
            //
            $coverage_response['label'] = $build_label;
            if ($coverageIsGrouped) {
                $coverage_groups[$groupId]['coverages'][] = $coverage_response;
            } else {
                $coverage_response['site'] = $build_array['sitename'];
                $coverage_response['buildname'] = $build_array['name'];
                $response['coverages'][] = $coverage_response;
            }
        }
        if (!$coverageIsGrouped) {
            $coverageThreshold = $project_array['coveragethreshold'];
            $response['thresholdgreen'] = $coverageThreshold;
            $response['thresholdyellow'] = $coverageThreshold * 0.7;
        }
        // Dynamic Analysis
        //
        if (!empty($build_array['checker'])) {
            // Determine if this is a parent build with no dynamic analysis
            // of its own.
            $linkToChildren = false;
            if ($numchildren > 0) {
                $countChildrenResult = pdo_single_row_query('SELECT count(id) AS num FROM dynamicanalysis
                        WHERE buildid=' . qnum($build_array['id']));
                if ($countChildrenResult['num'] == 0) {
                    $linkToChildren = true;
                }
            }
            $DA_response = array();
            $DA_response['site'] = $build_array['sitename'];
            $DA_response['buildname'] = $build_array['name'];
            $DA_response['buildid'] = $build_array['id'];
            $DA_response['checker'] = $build_array['checker'];
            $DA_response['defectcount'] = $build_array['numdefects'];
            $starttimestamp = strtotime($build_array['starttime'] . ' UTC');
            $DA_response['datefull'] = $starttimestamp;
            if ($linkToChildren) {
                $DA_response['childlink'] = "{$child_builds_hyperlink}##DynamicAnalysis";
            }
            // If the data is more than 24h old then we switch from an elapsed to a normal representation
            if (time() - $starttimestamp < 86400) {
                $DA_response['date'] = date(FMT_DATETIMEDISPLAY, $starttimestamp);
                $DA_response['dateelapsed'] = time_difference(time() - $starttimestamp, false, 'ago');
            } else {
                $DA_response['dateelapsed'] = date(FMT_DATETIMEDISPLAY, $starttimestamp);
                $DA_response['date'] = time_difference(time() - $starttimestamp, false, 'ago');
            }
            // Are there labels for this build?
            //
            $DA_response['label'] = $build_label;
            $response['dynamicanalyses'][] = $DA_response;
        }
    }
    // Put some finishing touches on our buildgroups now that we're done
    // iterating over all the builds.
    $addExpected = empty($filter_sql) && pdo_num_rows($builds) + count($dynamic_builds) > 0;
    for ($i = 0; $i < count($buildgroups_response); $i++) {
        $buildgroups_response[$i]['testduration'] = time_difference($buildgroups_response[$i]['testduration'], true);
        $num_expected_builds = 0;
        if (!$filter_sql) {
            $groupname = $buildgroups_response[$i]['name'];
            $expected_builds = add_expected_builds($buildgroups_response[$i]['id'], $currentstarttime, $received_builds[$groupname]);
            if (is_array($expected_builds)) {
                $num_expected_builds = count($expected_builds);
                $buildgroups_response[$i]['builds'] = array_merge($buildgroups_response[$i]['builds'], $expected_builds);
            }
        }
        // Show how many builds this group has.
        $num_builds = count($buildgroups_response[$i]['builds']);
        $num_builds_label = '';
        if ($num_expected_builds > 0) {
            $num_actual_builds = $num_builds - $num_expected_builds;
            $num_builds_label = "{$num_actual_builds} of {$num_builds} builds";
        } else {
            if ($num_builds === 1) {
                $num_builds_label = '1 build';
            } else {
                $num_builds_label = "{$num_builds} builds";
            }
        }
        $buildgroups_response[$i]['numbuildslabel'] = $num_builds_label;
    }
    // Create a separate "all buildgroups" section of our response.
    // This is used to allow project admins to move builds between groups.
    $response['all_buildgroups'] = array();
    foreach ($buildgroups_response as $group) {
        $response['all_buildgroups'][] = array('id' => $group['id'], 'name' => $group['name']);
    }
    // At this point it is safe to remove any empty buildgroups from our response.
    function is_buildgroup_nonempty($group)
    {
        return !empty($group['builds']);
    }
    $buildgroups_response = array_filter($buildgroups_response, 'is_buildgroup_nonempty');
    // Report buildgroups as a list, not an associative array.
    // Otherwise any missing buildgroups will cause our view to
    // not honor the order specified by the project admins.
    $buildgroups_response = array_values($buildgroups_response);
    // Remove Aggregate Coverage if it should not be displayed.
    if (!$show_aggregate) {
        for ($i = 0; $i < count($response['coverages']); $i++) {
            if ($response['coverages'][$i]['buildname'] === 'Aggregate Coverage') {
                unset($response['coverages'][$i]);
            }
        }
        $response['coverages'] = array_values($response['coverages']);
    }
    if ($response['childview'] == 1) {
        // Report number of children.
        if (!empty($buildgroups_response)) {
            $numchildren = count($buildgroups_response[0]['builds']);
        } else {
            $row = pdo_single_row_query('SELECT count(id) AS numchildren
                    FROM build WHERE parentid=' . qnum($parentid));
            $numchildren = $row['numchildren'];
        }
        $response['numchildren'] = $numchildren;
    }
    // Generate coverage by group here.
    if (!empty($coverage_groups)) {
        $response['coveragegroups'] = array();
        foreach ($coverage_groups as $groupid => $group) {
            $loctested = $group['loctested'];
            $locuntested = $group['locuntested'];
            if ($loctested == 0 && $locuntested == 0) {
                continue;
            }
            $percentage = round($loctested / ($loctested + $locuntested) * 100, 2);
            $group['percentage'] = $percentage;
            $group['id'] = $groupid;
            $response['coveragegroups'][] = $group;
        }
    }
    $response['buildgroups'] = $buildgroups_response;
    $response['enableTestTiming'] = $project_array['showtesttime'];
    $end = microtime_float();
    $response['generationtime'] = round($end - $start, 3);
    if (!empty($site_response)) {
        $response = array_merge($response, $site_response);
    }
    echo json_encode(cast_data_for_JSON($response));
}
Example #29
0
/** Function to handle new style submissions via HTTP PUT */
function parse_put_submission($filehandler, $projectid, $expected_md5)
{
    if (!$expected_md5) {
        return false;
    }
    $buildfile_row = pdo_single_row_query("SELECT * FROM buildfile WHERE md5='{$expected_md5}'");
    if (empty($buildfile_row)) {
        return false;
    }
    // Save a backup file for this submission.
    $row = pdo_single_row_query("SELECT name FROM project WHERE id={$projectid}");
    $projectname = $row["name"];
    $buildid = $buildfile_row['buildid'];
    $row = pdo_single_row_query("SELECT name, stamp FROM build WHERE id={$buildid}");
    $buildname = $row["name"];
    $stamp = $row["stamp"];
    $row = pdo_single_row_query("SELECT name FROM site WHERE id=\n     (SELECT siteid FROM build WHERE id={$buildid})");
    $sitename = $row["name"];
    writeBackupFile($filehandler, "", $projectname, $buildname, $sitename, $stamp, $buildfile_row["filename"]);
    // Include the handler file for this type of submission.
    $type = $buildfile_row['type'];
    $include_file = "xml_handlers/" . $type . "_handler.php";
    if (stream_resolve_include_path($include_file) === false) {
        add_log("No handler include file for {$type} (tried {$include_file})", "parse_put_submission", LOG_ERR, $projectid);
        return true;
    }
    require_once $include_file;
    // Instantiate the handler.
    $className = $type . "Handler";
    if (!class_exists($className)) {
        add_log("No handler class for {$type}", "parse_put_submission", LOG_ERR, $projectid);
        return true;
    }
    $handler = new $className($buildid);
    // Parse the file.
    $handler->Parse($filehandler);
    return true;
}
Example #30
0
/** Function to handle new style submissions via HTTP PUT */
function parse_put_submission($filehandler, $projectid, $expected_md5)
{
    if (!$expected_md5) {
        return false;
    }
    $buildfile_row = pdo_single_row_query("SELECT * FROM buildfile WHERE md5='{$expected_md5}' LIMIT 1");
    if (empty($buildfile_row)) {
        return false;
    }
    // Save a backup file for this submission.
    $row = pdo_single_row_query("SELECT name FROM project WHERE id={$projectid}");
    $projectname = $row['name'];
    $buildid = $buildfile_row['buildid'];
    $row = pdo_single_row_query("SELECT name, stamp FROM build WHERE id={$buildid}");
    $buildname = $row['name'];
    $stamp = $row['stamp'];
    $row = pdo_single_row_query("SELECT name FROM site WHERE id=\n            (SELECT siteid FROM build WHERE id={$buildid})");
    $sitename = $row['name'];
    global $CDASH_BACKUP_TIMEFRAME;
    if ($CDASH_BACKUP_TIMEFRAME == '0') {
        $meta_data = stream_get_meta_data($filehandler);
        $filename = $meta_data['uri'];
    } else {
        $filename = writeBackupFile($filehandler, '', $projectname, $buildname, $sitename, $stamp, $buildfile_row['filename']);
    }
    // Instantiate a buildfile object so we can delete it from the database
    // once we're done parsing it.
    require_once 'models/buildfile.php';
    $buildfile = new BuildFile();
    $buildfile->BuildId = $buildid;
    $buildfile->md5 = $expected_md5;
    // Include the handler file for this type of submission.
    $type = $buildfile_row['type'];
    $include_file = 'xml_handlers/' . $type . '_handler.php';
    if (stream_resolve_include_path($include_file) === false) {
        add_log("No handler include file for {$type} (tried {$include_file})", 'parse_put_submission', LOG_ERR, $projectid);
        check_for_immediate_deletion($filename);
        $buildfile->Delete();
        return true;
    }
    require_once $include_file;
    // Instantiate the handler.
    $className = $type . 'Handler';
    if (!class_exists($className)) {
        add_log("No handler class for {$type}", 'parse_put_submission', LOG_ERR, $projectid);
        check_for_immediate_deletion($filename);
        $buildfile->Delete();
        return true;
    }
    $handler = new $className($buildid);
    // Parse the file.
    $handler->Parse($filename);
    check_for_immediate_deletion($filename);
    $buildfile->Delete();
    return true;
}