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 удалений

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

@ -4,7 +4,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
if (strpos($_SERVER['SCRIPT_FILENAME'], "UPDATE.php") !== false)
die("Please rename this file to something more unknown.");
die("Please rename this file to something more unknown.");
require_once("internals.php");
@ -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,27 +2,40 @@
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;
}
public function updateInt($field, $value) {
$value = (int)$value;
$this->updateRaw($field, $value);
}
public function updateInt($field, $value) {
$value = (int)$value;
$this->updateRaw($field, $value);
}
public function updateString($field, $value) {
$value = "'".mysql_real_escape_string($value)."'";
$this->updateRaw($field, $value);
}
public function updateString($field, $value) {
$value = "'".mysql_real_escape_string($value)."'";
$this->updateRaw($field, $value);
}
public function updateRaw($field, $value) {
public function updateRaw($field, $value) {
mysql_query("UPDATE {$this::$db}
SET $field = $value
SET $field = $value
WHERE id = {$this->id}") or throw_exception(mysql_error());
}
}
}

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

@ -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");
class Vendor extends DB {
// db: awfy_mode
function __construct($id) {
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");
}
}

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

@ -15,7 +15,7 @@ class RetriggerController {
$retrigger = new RetriggerController();
$retrigger->unit_id = $unit_id;
$qTask = mysql_query("SELECT * FROM control_tasks WHERE control_unit_id = $unit_id");
$qTask = mysql_query("SELECT * FROM control_tasks WHERE control_unit_id = $unit_id");
while ($task = mysql_fetch_object($qTask)) {
$task = new ManipulateTask($task->task);
$retrigger->tasks[] = $task;
@ -27,7 +27,7 @@ class RetriggerController {
$retrigger = new RetriggerController();
$mode = new Mode($mode_id);
$qTask = mysql_query("SELECT * FROM control_tasks WHERE machine_id = $machine_id") or die(mysql_error());
$qTask = mysql_query("SELECT * FROM control_tasks WHERE machine_id = $machine_id") or die(mysql_error());
while ($task = mysql_fetch_object($qTask)) {
if (!($mode_id == 0 || $task->mode_id == 0 || $task->mode_id == $mode_id))
continue;
@ -47,18 +47,18 @@ class RetriggerController {
}
public static function retriggerable($machine_id, $mode_id) {
$retrigger = RetriggerController::fromMachine($machine_id, $mode_id);
if (count($retrigger->tasks) == 0)
return false;
$retrigger = RetriggerController::fromMachine($machine_id, $mode_id);
if (count($retrigger->tasks) == 0)
return false;
try {
VersionControl::forMode($mode_id);
} catch(Exception $e) {
return false;
}
try {
VersionControl::forMode($mode_id);
} catch(Exception $e) {
return false;
}
return true;
}
return true;
}
public function convertToRevision($mode_id, $revision, $run_before_id, $run_after_id) {
$mode = new Mode($mode_id);
@ -70,40 +70,39 @@ class RetriggerController {
}
}
private function normalizeBenchmark($benchmark) {
$benchmark = str_replace("local.", "", $benchmark);
$benchmark = str_replace("remote.", "", $benchmark);
$benchmark = str_replace("shell.", "", $benchmark);
$benchmark = str_replace("-", "", $benchmark);
$benchmark = str_replace("misc", "assorted", $benchmark);
$benchmark = str_replace("asmjsubench", "asmjsmicro", $benchmark);
echo $benchmark;
return $benchmark;
}
private function normalizeBenchmark($benchmark) {
$benchmark = str_replace("local.", "", $benchmark);
$benchmark = str_replace("remote.", "", $benchmark);
$benchmark = str_replace("shell.", "", $benchmark);
$benchmark = str_replace("-", "", $benchmark);
$benchmark = str_replace("misc", "assorted", $benchmark);
$benchmark = str_replace("asmjsubench", "asmjsmicro", $benchmark);
return $benchmark;
}
private function benchmarksEqual($benchmark1, $benchmark2) {
return $this->normalizeBenchmark($benchmark1) == $this->normalizeBenchmark($benchmark2);
}
return $this->normalizeBenchmark($benchmark1) == $this->normalizeBenchmark($benchmark2);
}
public function selectBenchmarks($benchmarks) {
foreach ($this->tasks as $task) {
$new_benchmarks = Array();
foreach ($task->benchmarks() as $task_benchmark) {
foreach ($benchmarks as $benchmark) {
if ($this->benchmarksEqual($benchmark, $task_benchmark))
$new_benchmarks[] = $task_benchmark;
}
}
$task->update_benchmarks($new_benchmarks);
}
}
public function selectBenchmarks($benchmarks) {
foreach ($this->tasks as $task) {
$new_benchmarks = Array();
foreach ($task->benchmarks() as $task_benchmark) {
foreach ($benchmarks as $benchmark) {
if ($this->benchmarksEqual($benchmark, $task_benchmark))
$new_benchmarks[] = $task_benchmark;
}
}
$task->update_benchmarks($new_benchmarks);
}
}
public function enqueue() {
if ($this->unit_id == 0)
throw new Exception("No control_unit specified.");
foreach ($this->tasks as $task) {
mysql_query("INSERT INTO control_task_queue
mysql_query("INSERT INTO control_task_queue
(control_unit_id, task)
VALUES ({$this->unit_id}, '".mysql_escape_string($task->task())."')") or throw_exception(mysql_error());
}

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

@ -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();

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

@ -22,20 +22,20 @@ awfyCtrl.filter('linkify', function($sce, $parse) {
awfyCtrl.controller('addCtrl', ['$scope', '$http', '$routeParams', 'RegressionService', '$location',
function ($scope, $http, $routeParams, regression, $location) {
var data = {};
data["id"] = $routeParams.id * 1;
if ($routeParams.subtest)
data["subtest"] = 1;
var data = {};
data["id"] = $routeParams.id * 1;
if ($routeParams.subtest)
data["subtest"] = 1;
$http.post('data-score.php', data).then(function(data) {
$scope.regression = regression.normalize_score(data.data);
});
$scope.regression = regression.normalize_score(data.data);
});
$scope.submit = function() {
$http.post('data-submit.php', data).then(function(data) {
$location.path("/regression/"+(data.data*1));
});
};
$scope.submit = function() {
$http.post('data-submit.php', data).then(function(data) {
$location.path("/regression/"+(data.data*1));
});
};
}
]);
@ -52,14 +52,14 @@ awfyCtrl.controller('regressionCtrl', ['$scope', '$http', '$routeParams', '$q',
$scope.regression = regression.normalize(data[0].data);
$scope.states = regression.normalize_states(data[1].data);
var noise = {"score": {}, "breakdown":{}}
for (var i=0; i<$scope.regression["scores"].length; i++) {
if (data[0].data["scores"][i]["breakdown_id"]) {
var id = data[0].data["scores"][i]["breakdown_id"]
noise["breakdown"][id] = data[0].data["scores"][i]["noise"];
} else{
var id = data[0].data["scores"][i]["score_id"]
noise["score"][id] = data[0].data["scores"][i]["noise"];
}
for (var i=0; i<$scope.regression["scores"].length; i++) {
if (data[0].data["scores"][i]["breakdown_id"]) {
var id = data[0].data["scores"][i]["breakdown_id"]
noise["breakdown"][id] = data[0].data["scores"][i]["noise"];
} else{
var id = data[0].data["scores"][i]["score_id"]
noise["score"][id] = data[0].data["scores"][i]["noise"];
}
}
$scope.noise = noise
updateNoiseCount();
@ -96,45 +96,45 @@ awfyCtrl.controller('regressionCtrl', ['$scope', '$http', '$routeParams', '$q',
}
$scope.showRetriggerPopup = function(regression) {
var retrigger = {
"machine": regression.machine,
"mode": regression.mode,
"cset": regression.cset,
"suites": [],
"submit": function() {
var benchmarks = [];
for (var i=0; i<retrigger.suites.length; i++) {
if (retrigger.suites[i].selected)
benchmarks.push(retrigger.suites[i].name);
}
$http.post('retrigger.php', {
machine_id: regression.machine_id,
mode_id: regression.mode_id,
revision: retrigger.cset,
run_before_id: regression.prev_run_id,
run_after_id: regression.run_id,
benchmarks: benchmarks
}).then(function(data) {
});
modalDialog.close()
}
}
var suites = {};
var retrigger = {
"machine": regression.machine,
"mode": regression.mode,
"cset": regression.cset,
"suites": [],
"submit": function() {
var benchmarks = [];
for (var i=0; i<retrigger.suites.length; i++) {
if (retrigger.suites[i].selected)
benchmarks.push(retrigger.suites[i].name);
}
$http.post('retrigger.php', {
machine_id: regression.machine_id,
mode_id: regression.mode_id,
revision: retrigger.cset,
run_before_id: regression.prev_run_id,
run_after_id: regression.run_id,
benchmarks: benchmarks
}).then(function(data) {
});
modalDialog.close()
}
}
var suites = {};
for (var i=0; i<regression.scores.length; i++) {
var name = regression.scores[i]["suite"];
var selected = !regression.scores[i]["noise"];
if (suites[name]) {
if (selected && !suites[name]["selected"])
suites[name]["selected"] = true;
} else {
suites[name] = {
"name": name,
"selected": selected
};
retrigger.suites.push(suites[name]);
}
}
var name = regression.scores[i]["suite"];
var selected = !regression.scores[i]["noise"];
if (suites[name]) {
if (selected && !suites[name]["selected"])
suites[name]["selected"] = true;
} else {
suites[name] = {
"name": name,
"selected": selected
};
retrigger.suites.push(suites[name]);
}
}
modalDialog.open("partials/retrigger.html", retrigger);
}
@ -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
@ -219,32 +219,32 @@ awfyCtrl.controller('regressionCtrl', ['$scope', '$http', '$routeParams', '$q',
"regression_id": regression_id,
"extra": status
}).success(function() {
$scope.addComment = false;
$scope.addComment = false;
updateLogs();
}).error(function() {
alert("failed");
});
}
$scope.editNoiseFn = function() {
$scope.editNoise = true;
}
$scope.editNoise = true;
}
$scope.saveNoiseFn = function() {
$http.post('change-noise.php', {
"regression_id": $scope.regression["id"],
"noise": $scope.noise
}).success(function() {
$scope.editNoise = false;
updateNoiseCount();
$scope.editNoise = false;
updateNoiseCount();
}).error(function() {
alert("failed");
});
}
}
$scope.showNoiseFn = function() {
$scope.showNoise = true;
}
$scope.showNoise = true;
}
$scope.hideNoiseFn = function() {
$scope.showNoise = false;
}
$scope.showNoise = false;
}
function updateLogs() {
$http.post('data-regression-status.php', {id:regression_id}).then(function(data) {
@ -257,18 +257,18 @@ awfyCtrl.controller('regressionCtrl', ['$scope', '$http', '$routeParams', '$q',
for (var j = 0; j < $scope.regression["scores"].length; j++) {
if ($scope.regression["scores"][j]["suitetest"]) {
var id = $scope.regression["scores"][j]["breakdown_id"];
$scope.regression["scores"][j]["noise"] = $scope.noise.breakdown[id]
$scope.regression["scores"][j]["noise"] = $scope.noise.breakdown[id]
if ($scope.noise.breakdown[id])
count++;
} else {
} else {
var id = $scope.regression["scores"][j]["score_id"];
$scope.regression["scores"][j]["noise"] = $scope.noise.score[id]
$scope.regression["scores"][j]["noise"] = $scope.noise.score[id]
if ($scope.noise.score[id])
count++;
}
}
}
$scope.noiseCount = count;
}
}
}
]);
@ -277,67 +277,67 @@ awfyCtrl.controller('compareCtrl', ['$scope', '$http', '$routeParams', '$q', 'mo
function ($scope, $http, $routeParams, $q, modalDialog, regression, $location) {
var regression_id = $routeParams.id * 1;
$http.post('data-regression.php', {
$http.post('data-regression.php', {
id:regression_id
}).then(function(data) {
$scope.regression = regression.normalize(data.data);
}).then(function(data) {
$scope.regression = regression.normalize(data.data);
$http.post('data-revision.php', {
machine: $scope.regression["machine_id"],
mode: $scope.regression["mode_id"],
}).then(function(data) {
$http.post('data-revision.php', {
machine: $scope.regression["machine_id"],
mode: $scope.regression["mode_id"],
}).then(function(data) {
for (var i=0; i<$scope.regression.scores.length; i++) {
for (var j=0; j<data.data.length; j++) {
if ($scope.regression.scores[i]["suite_version"] == data.data[j]["suite_version"] &&
$scope.regression.scores[i]["suite_test"] == data.data[j]["suite_test"])
{
var now = data.data[j]["score"];
var prev = $scope.regression.scores[i]["prev_score"];
var score = $scope.regression.scores[i]["score"];
{
var now = data.data[j]["score"];
var prev = $scope.regression.scores[i]["prev_score"];
var score = $scope.regression.scores[i]["score"];
$scope.regression.scores[i]["now"] = now;
if (Math.abs(prev - now) < Math.abs(score - now)) {
if (score > prev) {
if (now < prev + 0.2 * (score - prev))
$scope.regression.scores[i]["good"] = 1;
} else {
if (now > prev + 0.2 * (score - prev))
$scope.regression.scores[i]["good"] = 1;
}
} else {
if (score > prev) {
if (now > score - 0.8 * (score - prev))
$scope.regression.scores[i]["bad"] = 1;
} else {
if (now < score - 0.8 * (score - prev))
$scope.regression.scores[i]["bad"] = 1;
}
}
if (Math.abs(prev - now) < Math.abs(score - now)) {
if (score > prev) {
if (now < prev + 0.2 * (score - prev))
$scope.regression.scores[i]["good"] = 1;
} else {
if (now > prev + 0.2 * (score - prev))
$scope.regression.scores[i]["good"] = 1;
}
} else {
if (score > prev) {
if (now > score - 0.8 * (score - prev))
$scope.regression.scores[i]["bad"] = 1;
} else {
if (now < score - 0.8 * (score - prev))
$scope.regression.scores[i]["bad"] = 1;
}
}
}
}
}
});
}
}
});
});
$scope.showRegression = function(regression, score) {
var start = regression.stamp/1000;
var end = new Date()/1000;
var start = regression.stamp/1000;
var end = new Date()/1000;
// Increase start so it is visible.
var duration = end - start;
start -= duration * 0.1;
// Increase start so it is visible.
var duration = end - start;
start -= duration * 0.1;
modalDialog.open("partials/graph-popup.html", {
"url": "//arewefastyet.com/#"+
"machine="+regression.machine_id+"&"+
"view=single&"+
"suite="+score.suite+"&"+
(score.suitetest ? "subtest="+score.suitetest+"&" : "") +
"start="+start+"&"+
"end="+end,
"score": score,
"regression": regression,
"showRegression": $scope.showRegression
});
modalDialog.open("partials/graph-popup.html", {
"url": "//arewefastyet.com/#"+
"machine="+regression.machine_id+"&"+
"view=single&"+
"suite="+score.suite+"&"+
(score.suitetest ? "subtest="+score.suitetest+"&" : "") +
"start="+start+"&"+
"end="+end,
"score": score,
"regression": regression,
"showRegression": $scope.showRegression
});
}
}
@ -351,7 +351,7 @@ awfyCtrl.controller('searchCtrl', ['$scope', '$http', '$routeParams', '$q', 'mod
function setDefaultModeAndMachine() {
var machines = ["11","12","14","17","26","27","28","29","30"];
var modes = ["14","16","20","21","22","23","25","26","27","28","29","31","32","33","35"];
setMachines(machines);
setMachines(machines);
setModes(modes);
setBug(undefined);
}
@ -364,16 +364,16 @@ awfyCtrl.controller('searchCtrl', ['$scope', '$http', '$routeParams', '$q', 'mod
var modes = []
for (var mode in $scope.master.modes) {
if ($scope.master.modes[mode].selected)
modes.push(mode);
modes.push(mode);
}
return modes;
return modes;
}
function setBug(bug) {
$scope.bug = bug
}
function getBug() {
return $scope.bug;
}
$scope.bug = bug
}
function getBug() {
return $scope.bug;
}
function setMachines(machines) {
for (var id in machines) {
$scope.master.machines[machines[id]].selected = true;
@ -383,9 +383,9 @@ awfyCtrl.controller('searchCtrl', ['$scope', '$http', '$routeParams', '$q', 'mod
var machines = []
for (var machine in $scope.master.machines) {
if ($scope.master.machines[machine].selected)
machines.push(machine);
machines.push(machine);
}
return machines;
return machines;
}
function setStates(states) {
for (var id in $scope.availablestates) {
@ -397,22 +397,22 @@ awfyCtrl.controller('searchCtrl', ['$scope', '$http', '$routeParams', '$q', 'mod
var states = []
for (var id in $scope.availablestates) {
if ($scope.availablestates[id].selected)
states.push($scope.availablestates[id].name);
states.push($scope.availablestates[id].name);
}
return states;
return states;
}
function setTitle(title) {
$scope.title = title
}
function setTitle(title) {
$scope.title = title
}
function initAdvanced() {
var search = $location.search();
var search = $location.search();
setMachines(search.machines || []);
setStates(search.states || []);
setModes(search.modes || []);
setBug(search.bug);
fetch()
}
function fetch() {
}
function fetch() {
var selected_machines = []
for (var id in $scope.master.machines) {
if ($scope.master.machines[id].selected)
@ -433,119 +433,119 @@ awfyCtrl.controller('searchCtrl', ['$scope', '$http', '$routeParams', '$q', 'mod
machines:selected_machines,
modes:selected_modes,
states:selected_states,
bug:$scope.bug
bug:$scope.bug
}).then(function(data) {
if ($routeParams.search == "notTriaged")
$scope.$parent.triaged_no = data.data.length;
if ($routeParams.search == "notTriaged")
$scope.$parent.triaged_no = data.data.length;
$scope.ids = data.data
$scope.currentPage = 1;
$scope.items = $scope.ids.length;
$scope.advanced = ($routeParams.search == "advanced");
$scope.ids = data.data
$scope.currentPage = 1;
$scope.items = $scope.ids.length;
$scope.advanced = ($routeParams.search == "advanced");
$scope.fetchPage();
$scope.fetchPage();
});
}
$scope.fetchPage = function() {
$scope.regressions = [];
$scope.fetchPage = function() {
$scope.regressions = [];
var ids = $scope.ids.slice(($scope.currentPage - 1) * 10, $scope.currentPage * 10);
var minimal = false;
if ($location.path().indexOf("open") == 1 && !$routeParams.bug) {
ids = $scope.ids;
minimal = true;
}
var minimal = false;
if ($location.path().indexOf("open") == 1 && !$routeParams.bug) {
ids = $scope.ids;
minimal = true;
}
$http.post('data-regression.php', {
ids: ids,
minimal: minimal
}).then(function(data) {
$http.post('data-regression.php', {
ids: ids,
minimal: minimal
}).then(function(data) {
var regressions = data.data;
for (var i = 0; i < regressions.length; i++) {
regressions[i] = regression.normalize(regressions[i])
}
var regressions = data.data;
for (var i = 0; i < regressions.length; i++) {
regressions[i] = regression.normalize(regressions[i])
}
$scope.regressions = regressions;
$scope.regressions = regressions;
if ($location.path().indexOf("open") == 1 && !$routeParams.bug) {
var bugs = [];
for (var j = 0; j < regressions.length; j++) {
var bug = regressions[j].bug;
if (!bugs[bug])
bugs[bug] = {"items":[], "bug":bug};
bugs[bug].items[bugs[bug].items.length] = regressions[j];
}
var retBugs = [];
bugs.forEach(function(el) {
retBugs[retBugs.length] = el;
$http.get(
'https://bugzilla.mozilla.org/rest/bug/'+el.bug+'?include_fields=summary'
).then(function(data) {
for (var j=0; j<$scope.bugs.length; j++) {
if ($scope.bugs[j]["bug"] == el.bug) {
$scope.bugs[j]["title"] = data.data["bugs"][0]["summary"];
}
}
},function(data) {
for (var j=0; j<$scope.bugs.length; j++) {
if ($scope.bugs[j]["bug"] == el.bug) {
if (data.data["code"] && data.data["code"] == 102)
$scope.bugs[j]["title"] = "Security bug";
}
}
});
});
$scope.bugs = retBugs;
}
});
if ($location.path().indexOf("open") == 1 && !$routeParams.bug) {
var bugs = [];
for (var j = 0; j < regressions.length; j++) {
var bug = regressions[j].bug;
if (!bugs[bug])
bugs[bug] = {"items":[], "bug":bug};
bugs[bug].items[bugs[bug].items.length] = regressions[j];
}
var retBugs = [];
bugs.forEach(function(el) {
retBugs[retBugs.length] = el;
$http.get(
'https://bugzilla.mozilla.org/rest/bug/'+el.bug+'?include_fields=summary'
).then(function(data) {
for (var j=0; j<$scope.bugs.length; j++) {
if ($scope.bugs[j]["bug"] == el.bug) {
$scope.bugs[j]["title"] = data.data["bugs"][0]["summary"];
}
}
},function(data) {
for (var j=0; j<$scope.bugs.length; j++) {
if ($scope.bugs[j]["bug"] == el.bug) {
if (data.data["code"] && data.data["code"] == 102)
$scope.bugs[j]["title"] = "Security bug";
}
}
});
});
$scope.bugs = retBugs;
}
});
}
}
$scope.setNonTriaged = function() {
setTitle("Untriaged regressions");
setTitle("Untriaged regressions");
setDefaultModeAndMachine();
setStates(["unconfirmed"]);
fetch()
}
$scope.setNotFixedRegressions = function(bug) {
if (bug === undefined)
setTitle("Confirmed regressions");
else if (bug == 0)
setTitle("Confirmed regressions without bug number");
else
setTitle("Confirmed regressions for #"+bug);
if (bug === undefined)
setTitle("Confirmed regressions");
else if (bug == 0)
setTitle("Confirmed regressions without bug number");
else
setTitle("Confirmed regressions for #"+bug);
setDefaultModeAndMachine();
setStates(["confirmed"]);
setBug(bug);
setBug(bug);
fetch()
}
$scope.setRegressions = function(bug) {
setTitle("Regressions for #"+bug);
setTitle("Regressions for #"+bug);
setDefaultModeAndMachine();
setStates(["confirmed", "fixed", "improvement", "wontfix"]);
setBug(bug);
setBug(bug);
fetch()
}
$scope.setImprovements = function() {
setTitle("Improvements");
setTitle("Improvements");
setDefaultModeAndMachine();
setStates(["improvement"]);
fetch()
}
$scope.advancedSearch = function() {
setTitle("Search");
setTitle("Search");
$scope.advanced = true;
}
$scope.open = function(id) {
$location.path("/regression/"+id);
}
$scope.search = function() {
$location.path("advanced");
$location.path("advanced");
$location.search({machines: getMachines(), states: getStates(), modes: getModes(),
bug: getBug()});
}
bug: getBug()});
}
$scope.advanced = ($routeParams.search == "advanced");
$scope.regressions = [];
@ -557,7 +557,7 @@ awfyCtrl.controller('searchCtrl', ['$scope', '$http', '$routeParams', '$q', 'mod
else if ($routeParams.search == "improvements")
$scope.setImprovements();
else if ($routeParams.search == "advanced")
initAdvanced();
initAdvanced();
else
$scope.setNonTriaged();
}
@ -591,8 +591,8 @@ awfyCtrl.controller('graphCtrl', ['$scope', '$http',
"data": {
"cols": [
{ type: 'date', id: 'Date' },
{ type: 'number', id: 'Won/Loss' }
],
{ type: 'number', id: 'Won/Loss' }
],
"rows": data.data
},
"options": {
@ -602,6 +602,6 @@ awfyCtrl.controller('graphCtrl', ['$scope', '$http',
}
});
});
}
]);