Make it possible to retrigger a regression

This commit is contained in:
Hannes Verschore 2015-11-12 02:08:27 -08:00
Родитель 777df85d62
Коммит 5ed59a936d
14 изменённых файлов: 580 добавлений и 323 удалений

Просмотреть файл

@ -29,7 +29,7 @@ if (GET_string("run") == 'yes') {
// Start an out of order run. Retriggering a particular mode.
if (GET_string("run") == 'ooo') {
$machine_id = GET_int('MACHINE');
$mode = Mode::FromMode(GET_string('name'));
$mode = Mode::FromMode(GET_string('mode'));
$revision = GET_string('revision');
$run_before_id = GET_int('run_before_id');
$run_after_id = GET_int('run_after_id');
@ -63,7 +63,7 @@ if (GET_string("run") == 'addEngine') {
$mode = Mode::FromMode(GET_string('name'));
if ($run->isFinished() || $run->hasError())
throw new Error("Run was already finished or error'ed");
throw new Exception("Run was already finished or error'ed");
if ($run->isOutOfOrder()) {
// out of order builds cannot add extra modes. The available

Просмотреть файл

@ -3,7 +3,7 @@
class BashInterpreter {
public static function matchCommand($text, $command) {
$command = str_replace("/", "\/", $command);
preg_match_all("/(".$command." .*)[;$\r\n#]/", $text, $matches);
preg_match_all("/(".$command." [^;$\n\r\r\n#]*)/", $text, $matches);
return $matches[1];
}

Просмотреть файл

@ -0,0 +1,77 @@
<?php
require_once("DB.php");
require_once("Build.php");
class Breakdown extends DB {
public static $db = "awfy_breakdown";
public function __construct($id) {
$this->id = $id;
}
public function suite_test_id() {
return $this->select("suite_test_id");
}
public function score_id() {
return $this->select("score_id");
}
public function score() {
return Score::FromId($this->score_id());
}
public function points() {
return $this->select("score");
}
public function prev() {
$score = $this->score();
$build = $score->build();
$run = $build->run();
$qPrev = mysql_query("SELECT awfy_breakdown.id
FROM awfy_breakdown
INNER JOIN awfy_score ON awfy_score.id = awfy_breakdown.score_id
INNER JOIN awfy_build ON awfy_build.id = awfy_score.build_id
INNER JOIN awfy_run ON awfy_run.id = awfy_build.run_id
WHERE awfy_run.sort_order < ".$run->sort_order()." AND
awfy_run.machine = ".$run->machine_id()." AND
awfy_run.status = 1 AND
awfy_build.mode_id = ".$build->mode_id()." AND
awfy_score.suite_version_id = ".$score->suite_version_id()." AND
awfy_breakdown.suite_test_id = ".$this->suite_test_id()."
ORDER BY sort_order DESC
LIMIT 1") or throw_exception(mysql_error());
if (mysql_num_rows($qPrev) == 0)
return null;
$prev = mysql_fetch_object($qPrev);
return new Breakdown($prev->id);
}
public function next() {
$score = $this->score();
$build = $score->build();
$run = $build->run();
$qNext = mysql_query("SELECT awfy_breakdown.id
FROM awfy_breakdown
INNER JOIN awfy_score ON awfy_score.id = awfy_breakdown.score_id
INNER JOIN awfy_build ON awfy_build.id = awfy_score.build_id
INNER JOIN awfy_run ON awfy_run.id = awfy_build.run_id
WHERE awfy_run.sort_order > ".$run->sort_order()." AND
awfy_run.machine = ".$run->machine_id()." AND
awfy_run.status = 1 AND
awfy_build.mode_id = ".$build->mode_id()." AND
awfy_score.suite_version_id = ".$score->suite_version_id()." AND
awfy_breakdown.suite_test_id = ".$this->suite_test_id()."
ORDER BY sort_order ASC
LIMIT 1") or throw_exception(mysql_error());
if (mysql_num_rows($qNext) == 0)
return null;
$next = mysql_fetch_object($qNext);
return new Breakdown($next->id);
}
}

Просмотреть файл

@ -1,6 +1,7 @@
<?php
require_once("DB.php");
require_once("Run.php");
class Build extends DB {
@ -15,6 +16,8 @@ class Build extends DB {
WHERE run_id = $run_id AND
mode_id = $mode_id
LIMIT 1") or die(mysql_error());
if (mysql_num_rows($qBuild) == 0)
return null;
$build = mysql_fetch_object($qBuild);
return new Build($build->id);
}
@ -32,13 +35,17 @@ class Build extends DB {
}
public function revision() {
return $this->select("revision");
return $this->select("cset");
}
public function run_id() {
return $this->select("run_id");
}
public function run() {
return new Run($this->run_id());
}
public function mode_id() {
return $this->select("mode_id");
}

Просмотреть файл

@ -2,10 +2,23 @@
class DB {
public static function FromId($id) {
$id = (int) $id;
$qField = mysql_query("SELECT id from ".static::$db."
WHERE id = {$id}") or die(mysql_error());
if (mysql_num_rows($qField) == 0)
return null;
$field = mysql_fetch_object($qField);
$class = get_called_class();
return new $class($field->id);
}
public function select($field) {
$qField = mysql_query("SELECT $field as field from {$this::$db}
WHERE id = {$this->id}") or die(mysql_error());
$field = mysql_fetch_object($qField);
if (!isset($field->field))
throw new Exception("Unknown field or non existed id.");
return $field->field;
}

Просмотреть файл

@ -10,6 +10,17 @@ class Run extends DB {
$this->id = $id;
}
public static function withMachineAndSortOrder($machine_id, $sort_order) {
$qRun = mysql_query("SELECT id FROM awfy_run
WHERE machine = $machine_id AND
sort_order = $sort_order
LIMIT 1") or die(mysql_error());
if (mysql_num_rows($qRun) == 0)
return null;
$run = mysql_fetch_object($qRun);
return new Run($run->id);
}
public static function insert($machine_id, $sort_order, $approx_stamp = 0) {
$approx_stamp = intval($approx_stamp);
if ($approx_stamp == 0)
@ -53,6 +64,10 @@ class Run extends DB {
return $this->select("sort_order");
}
public function machine_id() {
return $this->select("machine");
}
public function approx_stamp() {
return $this->select("approx_stamp");
}
@ -70,4 +85,28 @@ class Run extends DB {
// add their build info.
return $this->isFinished() || $this->isOutOfOrder() || $this->hasError();
}
public function next() {
$sort_order = $this->sort_order();
$machine = $this->machine_id();
$qRun = mysql_query("SELECT id from awfy_run
WHERE sort_order > {$sort_order} AND
machine = {$machine}
ORDER BY sort_order ASC
LIMIT 1") or throw_exception(mysql_error());
$run = mysql_fetch_object($qRun);
return new Run($run->id);
}
public function prev() {
$sort_order = $this->sort_order();
$machine = $this->machine_id();
$qRun = mysql_query("SELECT id from awfy_run
WHERE sort_order < {$sort_order} AND
machine = {$machine}
ORDER BY sort_order DESC
LIMIT 1") or throw_exception(mysql_error());
$run = mysql_fetch_object($qRun);
return new Run($run->id);
}
}

83
website/lib/DB/Score.php Normal file
Просмотреть файл

@ -0,0 +1,83 @@
<?php
require_once("DB.php");
require_once("Build.php");
class Score extends DB {
public static $db = "awfy_score";
public function __construct($id) {
$this->id = $id;
}
public static function withBuildAndSuiteVersion($build_id, $suite_version_id) {
$qScore = mysql_query("SELECT id FROM awfy_score
WHERE build_id = $build_id AND
suite_version_id = $suite_version_id
LIMIT 1") or die(mysql_error());
if (mysql_num_rows($qScore) == 0)
return null;
$score = mysql_fetch_object($qScore);
return new Score($score->id);
}
public function build_id() {
return $this->select("build_id");
}
public function build() {
return new Build($this->build_id());
}
public function suite_version_id() {
return $this->select("suite_version_id");
}
public function points() {
return $this->select("score");
}
public function prev() {
$build = $this->build();
$run = $build->run();
$qPrev = mysql_query("SELECT awfy_score.id
FROM awfy_score
INNER JOIN awfy_build ON awfy_build.id = awfy_score.build_id
INNER JOIN awfy_run ON awfy_run.id = awfy_build.run_id
WHERE awfy_run.sort_order < ".$run->sort_order()." AND
awfy_run.machine = ".$run->machine_id()." AND
awfy_run.status = 1 AND
awfy_build.mode_id = ".$build->mode_id()." AND
awfy_score.suite_version_id = ".$this->suite_version_id()."
ORDER BY sort_order DESC
LIMIT 1") or throw_exception(mysql_error());
if (mysql_num_rows($qPrev) == 0)
return null;
$prev = mysql_fetch_object($qPrev);
return new Score($prev->id);
}
public function next() {
$build = $this->build();
$run = $build->run();
$qNext = mysql_query("SELECT awfy_score.id
FROM awfy_score
INNER JOIN awfy_build ON awfy_build.id = awfy_score.build_id
INNER JOIN awfy_run ON awfy_run.id = awfy_build.run_id
WHERE awfy_run.sort_order > ".$run->sort_order()." AND
awfy_run.machine = ".$run->machine_id()." AND
awfy_run.status = 1 AND
awfy_build.mode_id = ".$build->mode_id()." AND
awfy_score.suite_version_id = ".$this->suite_version_id()."
ORDER BY sort_order ASC
LIMIT 1") or throw_exception(mysql_error());
if (mysql_num_rows($qNext) == 0)
return null;
$next = mysql_fetch_object($qNext);
return new Score($next->id);
}
}

Просмотреть файл

@ -1,18 +1,16 @@
<?php
class Vendor {
require_once("DB.php");
// db: awfy_mode
function __construct($id) {
class Vendor extends DB {
public static $db = "awfy_vendor";
public function __construct($id) {
$this->id = $id;
}
function csetURL() {
$qVendor = mysql_query("SELECT csetURL
FROM awfy_vendor
WHERE id = {$this->id}");
$vendor = mysql_fetch_object($qVendor);
return $vendor->csetURL;
return $this->select("csetURL");
}
}

Просмотреть файл

@ -77,7 +77,6 @@ class RetriggerController {
$benchmark = str_replace("-", "", $benchmark);
$benchmark = str_replace("misc", "assorted", $benchmark);
$benchmark = str_replace("asmjsubench", "asmjsmicro", $benchmark);
echo $benchmark;
return $benchmark;
}

Просмотреть файл

@ -3,6 +3,7 @@
require_once("DB/Run.php");
require_once("DB/Mode.php");
require_once("DB/Build.php");
require_once("VersionControl.php");
class RunReporter {
@ -24,28 +25,50 @@ class RunReporter {
// Find the sorting order where we could add this revision;
$sort_order = RunReporter::findSortOrder($run_before, $mode_id, $revision);
// Get the approx stamp of the run with the sort_order before the one we are replacing.
$old_run = Run::withMachineAndSortOrder($machine_id, $sort_order - 1);
$approx_stamp = $old_run->approx_stamp();
// sanity check.
if ($sort_order >= $run_after->sort_order())
throw new Exception("Given run bounds were incorrect.");
RunReporter::assertInBound($run_before, $run_after, $mode_id, $sort_order);
// Create a space at the given sort_order, by shifting all sort_order,
// equal or higher than the given sort_order.
RunReporter::increaseNextSortOrder($machine_id, $sort_order);
$run = Run::insert($machine_id, $sort_order, $run_before->approx_stamp());
$run = Run::insert($machine_id, $sort_order, $approx_stamp);
$run->updateInt("out_of_order", 1);
$build = Build::insert($run, $mode_id, $revision);
return $run;
}
private static function assertInBound($run_before, $run_after, $mode_id, $sort_order) {
if ($sort_order <= $run_before->sort_order())
throw new Exception("bound is lower.");
if ($sort_order > $run_after->sort_order()) {
// It is allowed to have a not in bound $sort_order,
// when the revision stays the same between $run_after and the $sort_order.
$current_run = Run::withMachineAndSortOrder($run_after->machine_id(), $sort_order)->prev();
$current_build = Build::withRunAndMode($current_run->id, $mode_id);
$after_build = Build::withRunAndMode($run_after->id, $mode_id);
if ($current_build->revision() != $after_build->revision())
throw new Exception("bound is higher.");
}
}
private static function findSortOrder($run, $mode_id, $revision)
{
$version_control = VersionControl::forMode($mode_id);
$j = 0;
while (True) {
if ($j++ > 30)
throw new Exception("There shouldn't be too many runs in between");
if (!$run->isBuildInfoComplete())
throw new Exception("Encountered an incomplete run.");
$build = Build::withRunAndMode($run_before->id, $mode_id);
$build = Build::withRunAndMode($run->id, $mode_id);
// We can safely ignore runs that have no results with the requested mode_id
if (!$build) {
@ -62,8 +85,9 @@ class RunReporter {
// Using version control take a peek if the revision
// is later/earlier than this one.
if ($version_control->isAfter($build->revision(), $revision))
if ($version_control->isAfter($build->revision(), $revision)) {
return $run->sort_order();
}
$run = $run->next();
}

Просмотреть файл

@ -0,0 +1,42 @@
<?php
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
require_once("../lib/DB/Score.php");
class ScoreTools {
// Accepts Score and Breakdown
static function build($score) {
if ($score instanceof Score)
return $score->build();
else
return $score->score()->build();
}
// Accepts Score and Breakdown
static function prevList($score, $amount = 1) {
$list = Array();
for ($i = 0; $i < $amount; $i++) {
$score = $score->prev();
if (!$score)
return $list;
$list[] = $score;
}
return $list;
}
// Accepts Score and Breakdown
static function nextList($score, $amount = 1) {
$list = Array();
for ($i = 0; $i < $amount; $i++) {
$score = $score->next();
if (!$score)
return $list;
$list[] = $score;
}
return $list;
}
}

Просмотреть файл

@ -36,7 +36,7 @@ class HGWeb {
if (strpos($html, "pushlogentry") !== false)
return true;
throw new Exception("Could find relationship between $revision1 and $revision2.");
throw new Exception("Couldn't find relationship between $revision1 and $revision2.");
}
}

Просмотреть файл

@ -4,49 +4,24 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
require_once("../internals.php");
require_once("data-func.php");
init_database();
require_once("../lib/ScoreTools.php");
require_once("../lib/DB/Score.php");
require_once("../lib/DB/Breakdown.php");
$postdata = file_get_contents("php://input");
$request = json_decode($postdata);
if (!empty($request->score_id)) {
$suite_version_id = get("score", (int)$request->score_id, "suite_version_id");
$build_id = get("score", (int)$request->score_id, "build_id");
$run_id = get("build", $build_id, "run_id");
$sort_order_id = get("run", $run_id, "sort_order");
$machine = get("run", $run_id, "machine");
$mode_id = get("build", $build_id, "mode_id");
$score = isset($request->score_id) ? Score::FromId($request->score_id) :
Breakdown::FromId($request->breakdown_id);
if (!$score)
die();
if ($request->type == "prev") {
$prev = prev_($sort_order_id, $machine, $mode_id, $suite_version_id, (int)$request->amount);
$last = array_pop($prev);
} else {
$next = next_($sort_order_id, $machine, $mode_id, $suite_version_id, (int)$request->amount);
$last = array_pop($next);
}
$build_id = get("score", $last["id"], "build_id");
} else {
$suite_test_id = get("breakdown", (int)$request->breakdown_id, "suite_test_id");
$score_id = get("breakdown", (int)$request->breakdown_id, "score_id");
$build_id = get("score", (int)$score_id, "build_id");
$run_id = get("build", $build_id, "run_id");
$sort_order_id = get("run", $run_id, "sort_order");
$machine = get("run", $run_id, "machine");
$mode_id = get("build", $build_id, "mode_id");
if ($request->type == "prev")
$list = ScoreTools::prevList($score, (int)$request->amount);
else
$list = ScoreTools::nextList($score, (int)$request->amount);
if ($request->type == "prev") {
$prev = prev_suite_test($sort_order_id, $machine, $mode_id, $suite_test_id, (int)$request->amount);
$last = array_pop($prev);
} else {
$next = next_suite_test($sort_order_id, $machine, $mode_id, $suite_test_id, (int)$request->amount);
$last = array_pop($next);
}
$score_id = get("breakdown", $last["id"], "score_id");
$build_id = get("score", $score_id, "build_id");
}
$run_id = get("build", $build_id, "run_id");
$stamp = get("run", $run_id, "finish_stamp");
echo $stamp;
$last = array_pop($list);
echo ScoreTools::build($last)->run()->approx_stamp();

Просмотреть файл

@ -163,8 +163,8 @@ awfyCtrl.controller('regressionCtrl', ['$scope', '$http', '$routeParams', '$q',
"view=single&"+
"suite="+score.suite+"&"+
(score.suitetest ? "subtest="+score.suitetest+"&" : "") +
"start="+data[0].data+"&"+
"end="+data[1].data,
"start="+(data[0].data*1-1)+"&"+
"end="+(data[1].data*1+1),
"score": score,
"regression": regression,
"showRegression": $scope.showRegression