From 1172ab108fac78285634f3468fa2540e80ccf5bb Mon Sep 17 00:00:00 2001 From: Patrick Reynolds Date: Sun, 6 Mar 2016 02:03:52 -0500 Subject: [PATCH 01/40] WIP: Migrate data from scalar to submission in tracker. --- modules/tracker/database/mysql/2.0.0.sql | 118 ++++++++++++++++++ .../database/mysql/create_submissions.sql | 23 ++++ .../mysql/migrate_items_to_submissions.sql | 29 +++++ .../tracker/database/mysql/migrate_params.sql | 28 +++++ .../database/mysql/scalar_to_submission.sql | 38 ++++++ modules/tracker/database/upgrade/2.0.0.php | 106 ++++++++++++++++ .../tracker/models/base/ScalarModelBase.php | 17 --- .../models/base/SubmissionModelBase.php | 17 +++ modules/tracker/models/pdo/ScalarModel.php | 45 ------- .../tracker/models/pdo/SubmissionModel.php | 46 +++++++ 10 files changed, 405 insertions(+), 62 deletions(-) create mode 100644 modules/tracker/database/mysql/2.0.0.sql create mode 100644 modules/tracker/database/mysql/create_submissions.sql create mode 100644 modules/tracker/database/mysql/migrate_items_to_submissions.sql create mode 100644 modules/tracker/database/mysql/migrate_params.sql create mode 100644 modules/tracker/database/mysql/scalar_to_submission.sql create mode 100644 modules/tracker/database/upgrade/2.0.0.php diff --git a/modules/tracker/database/mysql/2.0.0.sql b/modules/tracker/database/mysql/2.0.0.sql new file mode 100644 index 000000000..82d91556d --- /dev/null +++ b/modules/tracker/database/mysql/2.0.0.sql @@ -0,0 +1,118 @@ +-- Midas Server. Copyright Kitware SAS. Licensed under the Apache License 2.0. + +-- MySQL database for the tracker module, version 1.2.4 + +CREATE TABLE IF NOT EXISTS `tracker_producer` ( + `producer_id` bigint(20) NOT NULL AUTO_INCREMENT, + `community_id` bigint(20) NOT NULL, + `repository` varchar(255) NOT NULL, + `executable_name` varchar(255) NOT NULL, + `display_name` varchar(255) NOT NULL, + `description` text NOT NULL, + `revision_url` text NOT NULL, + PRIMARY KEY (`producer_id`), + KEY (`community_id`) +) DEFAULT CHARSET=utf8; + +CREATE TABLE IF NOT EXISTS `tracker_scalar` ( + `scalar_id` bigint(20) NOT NULL AUTO_INCREMENT, + `trend_id` bigint(20) NOT NULL, + `value` double, + `submission_id` bigint(20) NOT NULL DEFAULT '-1', + PRIMARY KEY (`scalar_id`), + KEY (`trend_id`), + KEY (`submission_id`) +) DEFAULT CHARSET=utf8; + +CREATE TABLE IF NOT EXISTS `tracker_submission` ( + `submission_id` bigint(20) NOT NULL AUTO_INCREMENT, + `producer_id` bigint(20) NOT NULL, + `name` varchar(255) NOT NULL DEFAULT '', + `uuid` varchar(255) NOT NULL DEFAULT '', + `submit_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + `producer_revision` varchar(255), + `user_id` bigint(20) NOT NULL DEFAULT '-1', + `official` tinyint(4) NOT NULL DEFAULT '1', + `build_results_url` text NOT NULL, + `branch` varchar(255) NOT NULL DEFAULT '', + `extra_urls` text, + `reproduction_command` text, + PRIMARY KEY (`submission_id`), + UNIQUE KEY (`uuid`), + KEY (`user_id`), + KEY (`submit_time`), + KEY (`branch`) +) DEFAULT CHARSET=utf8; + +CREATE TABLE IF NOT EXISTS `tracker_submission2item` ( + `submission_id` bigint(20) NOT NULL, + `item_id` bigint(20) NOT NULL, + `label` varchar(255) NOT NULL, + KEY (`submission_id`) +) DEFAULT CHARSET=utf8; + +CREATE TABLE IF NOT EXISTS `tracker_threshold_notification` ( + `threshold_id` bigint(20) NOT NULL AUTO_INCREMENT, + `trend_id` bigint(20) NOT NULL, + `value` double, + `comparison` varchar(2), + `action` varchar(80) NOT NULL, + `recipient_id` bigint(20) NOT NULL, + PRIMARY KEY (`threshold_id`), + KEY (`trend_id`) +) DEFAULT CHARSET=utf8; + +CREATE TABLE IF NOT EXISTS `tracker_trend` ( + `trend_id` bigint(20) NOT NULL AUTO_INCREMENT, + `producer_id` bigint(20) NOT NULL, + `metric_name` varchar(255) NOT NULL, + `display_name` varchar(255) NOT NULL, + `unit` varchar(255) NOT NULL, + `config_item_id` bigint(20), + `test_dataset_id` bigint(20), + `truth_dataset_id` bigint(20), + `key_metric` tinyint(4) NOT NULL DEFAULT '0', + PRIMARY KEY (`trend_id`), + KEY (`producer_id`) +) DEFAULT CHARSET=utf8; + +CREATE TABLE IF NOT EXISTS `tracker_param` ( + `param_id` bigint(20) NOT NULL AUTO_INCREMENT, + `submission_id` bigint(20) NOT NULL, + `param_name` varchar(255) NOT NULL, + `param_type` enum('text', 'numeric') NOT NULL, + `text_value` text, + `numeric_value` double, + PRIMARY KEY (`param_id`), + KEY (`param_name`) +) DEFAULT CHARSET=utf8; + +CREATE TABLE IF NOT EXISTS `tracker_aggregate_metric` ( + `aggregate_metric_id` bigint(20) NOT NULL AUTO_INCREMENT, + `aggregate_metric_spec_id` bigint(20) NOT NULL, + `submission_id` bigint(20) NOT NULL, + `value` double, + PRIMARY KEY (`aggregate_metric_id`), + KEY (`aggregate_metric_spec_id`), + KEY (`submission_id`) +) DEFAULT CHARSET=utf8; + +CREATE TABLE IF NOT EXISTS `tracker_aggregate_metric_spec` ( + `aggregate_metric_spec_id` bigint(20) NOT NULL AUTO_INCREMENT, + `producer_id` bigint(20) NOT NULL, + `branch` varchar(255) NOT NULL DEFAULT '', + `name` varchar(255) NOT NULL DEFAULT '', + `description` varchar(255) NOT NULL DEFAULT '', + `spec` text NOT NULL DEFAULT '', + `value` double, + `comparison` varchar(2) NOT NULL DEFAULT '', + PRIMARY KEY (`aggregate_metric_spec_id`), + KEY (`producer_id`), + KEY (`branch`) +) DEFAULT CHARSET=utf8; + +CREATE TABLE IF NOT EXISTS `tracker_user2aggregate_metric_spec` ( + `user_id` bigint(20) NOT NULL, + `aggregate_metric_spec_id` bigint(20) NOT NULL, + PRIMARY KEY (`user_id`, `aggregate_metric_spec_id`) +) DEFAULT CHARSET=utf8; diff --git a/modules/tracker/database/mysql/create_submissions.sql b/modules/tracker/database/mysql/create_submissions.sql new file mode 100644 index 000000000..d5091a3a4 --- /dev/null +++ b/modules/tracker/database/mysql/create_submissions.sql @@ -0,0 +1,23 @@ +CREATE DEFINER=`root`@`%` PROCEDURE `create_submissions`() +BEGIN + DECLARE finished INTEGER DEFAULT 0; + DECLARE cur_id bigint(20) default -1; + DECLARE cur_time timestamp default NOW(); + + DECLARE curs CURSOR FOR SELECT scalar_id, submit_time FROM tracker_scalar WHERE submission_id=-1 group by submit_time; + + DECLARE CONTINUE HANDLER FOR NOT FOUND SET finished = 1; + + OPEN curs; + + get_scalars: LOOP + FETCH curs INTO cur_id, cur_time; + IF finished = 1 THEN + LEAVE get_scalars; + END IF; + + INSERT INTO tracker_submission (uuid, submit_time) VALUES (UUID(), cur_time); + UPDATE tracker_scalar set submission_id=LAST_INSERT_ID() where submit_time=cur_time; + END LOOP get_scalars; + CLOSE curs; +END diff --git a/modules/tracker/database/mysql/migrate_items_to_submissions.sql b/modules/tracker/database/mysql/migrate_items_to_submissions.sql new file mode 100644 index 000000000..925a0dec0 --- /dev/null +++ b/modules/tracker/database/mysql/migrate_items_to_submissions.sql @@ -0,0 +1,29 @@ +CREATE DEFINER=`root`@`%` PROCEDURE `migrate_items_to_submissions`() +BEGIN + + DECLARE finished INTEGER DEFAULT 0; + DECLARE cur_item_id bigint(20) default -1; + DECLARE cur_submission_id bigint(20) default -1; + DECLARE cur_label varchar(255) default ''; + + DECLARE curs CURSOR FOR + SELECT distinct ti.item_id, ti.label, tu.submission_id FROM + tracker_scalar AS ts, tracker_submission AS tu, tracker_scalar2item AS ti WHERE + ts.submission_id=tu.submission_id AND ts.scalar_id=ti.scalar_id; + + DECLARE CONTINUE HANDLER FOR NOT FOUND SET finished = 1; + + OPEN curs; + + get_items: LOOP + FETCH curs INTO cur_item_id, cur_label, cur_submission_id; + IF finished = 1 THEN + LEAVE get_items; + END IF; + + INSERT INTO tracker_submission2item (submission_id, item_id, label) VALUES (cur_submission_id, cur_item_id, cur_label); + + END LOOP get_items; + + CLOSE curs; +END \ No newline at end of file diff --git a/modules/tracker/database/mysql/migrate_params.sql b/modules/tracker/database/mysql/migrate_params.sql new file mode 100644 index 000000000..461ee59c5 --- /dev/null +++ b/modules/tracker/database/mysql/migrate_params.sql @@ -0,0 +1,28 @@ +CREATE DEFINER=`root`@`%` PROCEDURE `migrate_params`() +BEGIN + + DECLARE finished INTEGER DEFAULT 0; + DECLARE cur_id bigint(20) default -1; + DECLARE cur_name varchar(255) default ''; + DECLARE cur_type enum('text', 'numeric') default 'text'; + DECLARE cur_text_value text default ''; + DECLARE cur_numeric_value double default 0; + + DECLARE outer_curs CURSOR FOR SELECT submission_id FROM tracker_submission; + DECLARE curs CURSOR FOR SELECT submission_id, param_name, param_type, text_value, numeric_value FROM tracker_param, tracker_scalar WHERE tracker_param.scalar_id=tracker_scalar.scalar_id GROUP BY submission_id, param_name; + + DECLARE CONTINUE HANDLER FOR NOT FOUND SET finished = 1; + + OPEN curs; + + get_params: LOOP + FETCH curs INTO cur_id, cur_name, cur_type, cur_text_value, cur_numeric_value; + IF finished = 1 THEN + LEAVE get_params; + END IF; + INSERT INTO tracker_submissionparam (submission_id, param_name, param_type, text_value, numeric_value) + VALUES (cur_id, cur_name, cur_type, cur_text_value, cur_numeric_value); + END LOOP get_params; + + CLOSE curs; +END \ No newline at end of file diff --git a/modules/tracker/database/mysql/scalar_to_submission.sql b/modules/tracker/database/mysql/scalar_to_submission.sql new file mode 100644 index 000000000..376b3df6d --- /dev/null +++ b/modules/tracker/database/mysql/scalar_to_submission.sql @@ -0,0 +1,38 @@ +CREATE DEFINER=`root`@`%` PROCEDURE `scalar_to_submission`() +BEGIN + + DECLARE finished INTEGER DEFAULT 0; + DECLARE cur_id bigint(20) default -1; + DECLARE cur_producer_revision varchar(255) default ''; + DECLARE cur_user_id bigint(20) default -1; + DECLARE cur_official tinyint(4) default 1; + DECLARE cur_build_results_url text default ''; + DECLARE cur_branch varchar(255) default ''; + DECLARE cur_extra_urls text default ''; + DECLARE cur_reproduction_command text default ''; + + DECLARE curs CURSOR FOR SELECT ts.submission_id, ts.producer_revision, ts.user_id, ts.official, ts.build_results_url, ts.branch, ts.extra_urls, ts.reproduction_command + FROM tracker_scalar AS ts, tracker_submission AS tu WHERE ts.submission_id = tu.submission_id + GROUP BY tu.submission_id; + + DECLARE CONTINUE HANDLER FOR NOT FOUND SET finished = 1; + + OPEN curs; + + get_scalars: LOOP + FETCH curs INTO cur_id, cur_producer_revision, cur_user_id, cur_official, + cur_build_results_url, cur_branch, cur_extra_urls, cur_reproduction_command; + IF finished = 1 THEN + LEAVE get_scalars; + END IF; + + UPDATE tracker_submission SET + producer_revision=cur_producer_revision, user_id=cur_user_id, official=cur_official, + build_results_url=cur_build_results_url, branch=cur_branch, extra_urls=cur_extra_urls, + reproduction_command=cur_reproduction_command WHERE submission_id=cur_id; + + END LOOP get_scalars; + + CLOSE curs; +END + diff --git a/modules/tracker/database/upgrade/2.0.0.php b/modules/tracker/database/upgrade/2.0.0.php new file mode 100644 index 000000000..6f63a0a09 --- /dev/null +++ b/modules/tracker/database/upgrade/2.0.0.php @@ -0,0 +1,106 @@ +db->query( + 'CREATE TABLE IF NOT EXISTS `tracker_submission2item` ('. + '`submission_id` bigint(20) NOT NULL,'. + '`item_id` bigint(20) NOT NULL,'. + '`label` varchar(255) NOT NULL,'. + 'KEY (`submission_id`)'. + ') DEFAULT CHARSET=utf8;' + ); + + // Create new table to relate params to submissions. We will rename this later + // TODO(cpatrick): rename members in model classes + $this->db->query( + "CREATE TABLE IF NOT EXISTS `tracker_submissionparam` ( + `param_id` bigint(20) NOT NULL AUTO_INCREMENT, + `submission_id` bigint(20) NOT NULL, + `param_name` varchar(255) NOT NULL, + `param_type` enum('text', 'numeric') NOT NULL, + `text_value` text, + `numeric_value` double, + PRIMARY KEY (`param_id`), + KEY (`submission_id`), + KEY (`param_name`) + ) DEFAULT CHARSET=utf8;"); + + // Add columns to submission (that were formerly on scalar) + $this->db->query('ALTER TABLE tracker_submission ADD COLUMN `producer_revision` VARCHAR(255);'); + $this->db->query('ALTER TABLE tracker_submission ADD COLUMN `user_id` bigint(20) NOT NULL DEFAULT \'-1\';'); + $this->db->query('ALTER TABLE tracker_submission ADD COLUMN `official` tinyint(4) NOT NULL DEFAULT \'1\';'); + $this->db->query('ALTER TABLE tracker_submission ADD COLUMN `build_results_url` text NOT NULL;'); + $this->db->query('ALTER TABLE tracker_submission ADD COLUMN `branch` varchar(255) NOT NULL DEFAULT \'\';'); + $this->db->query('ALTER TABLE tracker_submission ADD COLUMN `extra_urls` text;'); + $this->db->query('ALTER TABLE tracker_submission ADD COLUMN `reproduction_command` text;'); + + // Create indices on submission + $this->db->query('ALTER TABLE tracker_submission ADD KEY (`user_id`);'); + $this->db->query('ALTER TABLE tracker_submission ADD KEY(`submit_time`);'); + $this->db->query('ALTER TABLE tracker_submission ADD KEY (`branch`);'); + + + // TODO(cpatrick): Do grouping of scalars to create submissions. + // This is done by running the stored procedure in ../mysql/create_submissions.sql + + // TODO(cpatrick): Move params to submission. + // This is done by running the stored procedure in ../mysql/migrate_params.sql. This assumes create_submissions + // has been run. + + // Drop old param table + $this->db->query('DROP TABLE IF EXISTS tracker_param;'); + + // Rename new param table. + $this->db->query('RENAME TABLE tracker_submissionparam TO tracker_param;'); + + // TODO(cpatrick): Move values from scalar2item to submission2item + // This is done by running the stored procedure in ../mysql/migrate_items_to_submissions.sql + + // TODO(cpatrick): Move values from scalars to submissions. + // This is done by running the stored procedure in ../mysql/scalar_to_submission.sql + + // Delete old values from scalars + $this->db->query('ALTER TABLE tracker_scalar DROP COLUMN `producer_revision`;'); + $this->db->query('ALTER TABLE tracker_scalar DROP COLUMN `user_id`;'); + $this->db->query('ALTER TABLE tracker_scalar DROP COLUMN `official`;'); + $this->db->query('ALTER TABLE tracker_scalar DROP COLUMN `build_results_url`;'); + $this->db->query('ALTER TABLE tracker_scalar DROP COLUMN `branch`;'); + $this->db->query('ALTER TABLE tracker_scalar DROP COLUMN `extra_urls`;'); + $this->db->query('ALTER TABLE tracker_scalar DROP COLUMN `reproduction_command`;'); + $this->db->query('ALTER TABLE tracker_scalar DROP COLUMN `submit_time`;'); + $this->db->query('DROP TABLE IF EXISTS `tracker_scalar2item`;'); + + } + + /** Upgrade a PostgreSQL database. */ + public function pgsql() + { + $this->db->query(''); + } +} diff --git a/modules/tracker/models/base/ScalarModelBase.php b/modules/tracker/models/base/ScalarModelBase.php index 9be7c0210..a42f5f5b8 100644 --- a/modules/tracker/models/base/ScalarModelBase.php +++ b/modules/tracker/models/base/ScalarModelBase.php @@ -73,23 +73,6 @@ public function __construct() $this->initialize(); } - /** - * Associate the given scalar and item. - * - * @param Tracker_ScalarDao $scalarDao scalar DAO - * @param ItemDao $itemDao item DAO - * @param string $label label - */ - abstract public function associateItem($scalarDao, $itemDao, $label); - - /** - * Return the items associated with the given scalar. - * - * @param Tracker_ScalarDao $scalarDao scalar DAO - * @return array array of associative arrays with keys "item" and "label" - */ - abstract public function getAssociatedItems($scalarDao); - /** * Return any other scalars from the same submission as the given scalar. * diff --git a/modules/tracker/models/base/SubmissionModelBase.php b/modules/tracker/models/base/SubmissionModelBase.php index 586e040cd..6c20d6890 100644 --- a/modules/tracker/models/base/SubmissionModelBase.php +++ b/modules/tracker/models/base/SubmissionModelBase.php @@ -48,6 +48,23 @@ public function __construct() $this->initialize(); } + /** + * Associate the given submission and item. + * + * @param Tracker_SubmissionDao $submissionDao submission DAO + * @param ItemDao $itemDao item DAO + * @param string $label label + */ + abstract public function associateItem($submissionDao, $itemDao, $label); + + /** + * Return the items associated with the given submission. + * + * @param Tracker_SubmissionDao $submissionDao submission DAO + * @return array array of associative arrays with keys "item" and "label" + */ + abstract public function getAssociatedItems($scalarDao); + /** * Create a submission. * diff --git a/modules/tracker/models/pdo/ScalarModel.php b/modules/tracker/models/pdo/ScalarModel.php index 85b9e2653..02f6e781f 100644 --- a/modules/tracker/models/pdo/ScalarModel.php +++ b/modules/tracker/models/pdo/ScalarModel.php @@ -23,51 +23,6 @@ /** Scalar model for the tracker module. */ class Tracker_ScalarModel extends Tracker_ScalarModelBase { - /** - * Associate the given scalar and item. - * - * @param Tracker_ScalarDao $scalarDao scalar DAO - * @param ItemDao $itemDao item DAO - * @param string $label label - */ - public function associateItem($scalarDao, $itemDao, $label) - { - $data = array('scalar_id' => $scalarDao->getKey(), 'item_id' => $itemDao->getKey(), 'label' => $label); - $this->database->getDB()->insert('tracker_scalar2item', $data); - } - - /** - * Return the items associated with the given scalar. - * - * @param Tracker_ScalarDao $scalarDao scalar DAO - * @return array array of associative arrays with keys "item" and "label" - */ - public function getAssociatedItems($scalarDao) - { - $sql = $this->database->select()->setIntegrityCheck(false)->from('tracker_scalar2item')->where( - 'scalar_id = ?', - $scalarDao->getKey() - ); - $rows = $this->database->fetchAll($sql); - $results = array(); - - /** @var ItemModel $itemModel */ - $itemModel = MidasLoader::loadModel('Item'); - - /** @var Zend_Db_Table_Row_Abstract $row */ - foreach ($rows as $row) { - $itemDao = $itemModel->load($row['item_id']); - $results[] = array('label' => $row['label'], 'item' => $itemDao); - } - usort( - $results, - function ($a, $b) { - return strcmp($a['label'], $b['label']); - } - ); - - return $results; - } /** * Return any other scalars from the same submission as the given scalar. diff --git a/modules/tracker/models/pdo/SubmissionModel.php b/modules/tracker/models/pdo/SubmissionModel.php index 75258471d..6143625e7 100644 --- a/modules/tracker/models/pdo/SubmissionModel.php +++ b/modules/tracker/models/pdo/SubmissionModel.php @@ -27,6 +27,52 @@ class Tracker_SubmissionModel extends Tracker_SubmissionModelBase { const SEC_IN_DAY = 86400; + /** + * Associate the given submission and item. + * + * @param Tracker_SubmissionDao $submissionDao submission DAO + * @param ItemDao $itemDao item DAO + * @param string $label label + */ + public function associateItem($submissionDao, $itemDao, $label) + { + $data = array('submission_id' => $submissionDao->getKey(), 'item_id' => $itemDao->getKey(), 'label' => $label); + $this->database->getDB()->insert('tracker_submission2item', $data); + } + + /** + * Return the items associated with the given submission. + * + * @param Tracker_SubmissionDao $submissionDao submission DAO + * @return array array of associative arrays with keys "item" and "label" + */ + public function getAssociatedItems($submissionDao) + { + $sql = $this->database->select()->setIntegrityCheck(false)->from('tracker_submission2item')->where( + 'submission_id = ?', + $submissionDao->getKey() + ); + $rows = $this->database->fetchAll($sql); + $results = array(); + + /** @var ItemModel $itemModel */ + $itemModel = MidasLoader::loadModel('Item'); + + /** @var Zend_Db_Table_Row_Abstract $row */ + foreach ($rows as $row) { + $itemDao = $itemModel->load($row['item_id']); + $results[] = array('label' => $row['label'], 'item' => $itemDao); + } + usort( + $results, + function ($a, $b) { + return strcmp($a['label'], $b['label']); + } + ); + + return $results; + } + /** * Create a submission. * From 32fe86a49428d8ac5547c251f2999cd0e5cb316f Mon Sep 17 00:00:00 2001 From: Patrick Reynolds Date: Tue, 8 Mar 2016 21:49:02 -0500 Subject: [PATCH 02/40] Clean up SQL files. --- .../database/mysql/create_submissions.sql | 4 +- .../mysql/migrate_items_to_submissions.sql | 44 +++++----- .../tracker/database/mysql/migrate_params.sql | 44 +++++----- .../database/mysql/scalar_to_submission.sql | 71 ++++++++-------- .../database/mysql/upgrade_to_2.0.0.sql | 55 ++++++++++++ modules/tracker/database/upgrade/2.0.0.php | 83 ++----------------- 6 files changed, 144 insertions(+), 157 deletions(-) create mode 100644 modules/tracker/database/mysql/upgrade_to_2.0.0.sql diff --git a/modules/tracker/database/mysql/create_submissions.sql b/modules/tracker/database/mysql/create_submissions.sql index d5091a3a4..a390d5d20 100644 --- a/modules/tracker/database/mysql/create_submissions.sql +++ b/modules/tracker/database/mysql/create_submissions.sql @@ -4,8 +4,8 @@ BEGIN DECLARE cur_id bigint(20) default -1; DECLARE cur_time timestamp default NOW(); - DECLARE curs CURSOR FOR SELECT scalar_id, submit_time FROM tracker_scalar WHERE submission_id=-1 group by submit_time; - + DECLARE curs CURSOR FOR SELECT scalar_id, submit_time FROM tracker_scalar + WHERE submission_id=-1 group by submit_time; DECLARE CONTINUE HANDLER FOR NOT FOUND SET finished = 1; OPEN curs; diff --git a/modules/tracker/database/mysql/migrate_items_to_submissions.sql b/modules/tracker/database/mysql/migrate_items_to_submissions.sql index 925a0dec0..0ff3b34e2 100644 --- a/modules/tracker/database/mysql/migrate_items_to_submissions.sql +++ b/modules/tracker/database/mysql/migrate_items_to_submissions.sql @@ -1,29 +1,29 @@ CREATE DEFINER=`root`@`%` PROCEDURE `migrate_items_to_submissions`() BEGIN - - DECLARE finished INTEGER DEFAULT 0; - DECLARE cur_item_id bigint(20) default -1; - DECLARE cur_submission_id bigint(20) default -1; - DECLARE cur_label varchar(255) default ''; - DECLARE curs CURSOR FOR - SELECT distinct ti.item_id, ti.label, tu.submission_id FROM - tracker_scalar AS ts, tracker_submission AS tu, tracker_scalar2item AS ti WHERE - ts.submission_id=tu.submission_id AND ts.scalar_id=ti.scalar_id; - - DECLARE CONTINUE HANDLER FOR NOT FOUND SET finished = 1; + DECLARE finished INTEGER DEFAULT 0; + DECLARE cur_item_id bigint(20) default -1; + DECLARE cur_submission_id bigint(20) default -1; + DECLARE cur_label varchar(255) default ''; + + DECLARE curs CURSOR FOR + SELECT DISTINCT ti.item_id, ti.label, tu.submission_id FROM + tracker_scalar AS ts, tracker_submission AS tu, tracker_scalar2item AS ti WHERE + ts.submission_id=tu.submission_id AND ts.scalar_id=ti.scalar_id; + DECLARE CONTINUE HANDLER FOR NOT FOUND SET finished = 1; - OPEN curs; + OPEN curs; - get_items: LOOP - FETCH curs INTO cur_item_id, cur_label, cur_submission_id; - IF finished = 1 THEN - LEAVE get_items; - END IF; + get_items: LOOP + FETCH curs INTO cur_item_id, cur_label, cur_submission_id; + IF finished = 1 THEN + LEAVE get_items; + END IF; - INSERT INTO tracker_submission2item (submission_id, item_id, label) VALUES (cur_submission_id, cur_item_id, cur_label); + INSERT INTO tracker_submission2item (submission_id, item_id, label) VALUES (cur_submission_id, cur_item_id, cur_label); - END LOOP get_items; - - CLOSE curs; -END \ No newline at end of file + END LOOP get_items; + + CLOSE curs; + +END diff --git a/modules/tracker/database/mysql/migrate_params.sql b/modules/tracker/database/mysql/migrate_params.sql index 461ee59c5..a10f84d5c 100644 --- a/modules/tracker/database/mysql/migrate_params.sql +++ b/modules/tracker/database/mysql/migrate_params.sql @@ -1,28 +1,28 @@ CREATE DEFINER=`root`@`%` PROCEDURE `migrate_params`() BEGIN - - DECLARE finished INTEGER DEFAULT 0; - DECLARE cur_id bigint(20) default -1; - DECLARE cur_name varchar(255) default ''; - DECLARE cur_type enum('text', 'numeric') default 'text'; - DECLARE cur_text_value text default ''; - DECLARE cur_numeric_value double default 0; - DECLARE outer_curs CURSOR FOR SELECT submission_id FROM tracker_submission; - DECLARE curs CURSOR FOR SELECT submission_id, param_name, param_type, text_value, numeric_value FROM tracker_param, tracker_scalar WHERE tracker_param.scalar_id=tracker_scalar.scalar_id GROUP BY submission_id, param_name; - - DECLARE CONTINUE HANDLER FOR NOT FOUND SET finished = 1; + DECLARE finished INTEGER DEFAULT 0; + DECLARE cur_id bigint(20) default -1; + DECLARE cur_name varchar(255) default ''; + DECLARE cur_type enum('text', 'numeric') default 'text'; + DECLARE cur_text_value text default ''; + DECLARE cur_numeric_value double default 0; + + DECLARE curs CURSOR FOR SELECT submission_id, param_name, param_type, text_value, numeric_value + FROM tracker_param, tracker_scalar WHERE tracker_param.scalar_id=tracker_scalar.scalar_id + GROUP BY submission_id, param_name; + DECLARE CONTINUE HANDLER FOR NOT FOUND SET finished = 1; - OPEN curs; + OPEN curs; - get_params: LOOP - FETCH curs INTO cur_id, cur_name, cur_type, cur_text_value, cur_numeric_value; - IF finished = 1 THEN - LEAVE get_params; - END IF; - INSERT INTO tracker_submissionparam (submission_id, param_name, param_type, text_value, numeric_value) - VALUES (cur_id, cur_name, cur_type, cur_text_value, cur_numeric_value); - END LOOP get_params; + get_params: LOOP + FETCH curs INTO cur_id, cur_name, cur_type, cur_text_value, cur_numeric_value; + IF finished = 1 THEN + LEAVE get_params; + END IF; + INSERT INTO tracker_submissionparam (submission_id, param_name, param_type, text_value, numeric_value) + VALUES (cur_id, cur_name, cur_type, cur_text_value, cur_numeric_value); + END LOOP get_params; - CLOSE curs; -END \ No newline at end of file + CLOSE curs; +END diff --git a/modules/tracker/database/mysql/scalar_to_submission.sql b/modules/tracker/database/mysql/scalar_to_submission.sql index 376b3df6d..032ac28e5 100644 --- a/modules/tracker/database/mysql/scalar_to_submission.sql +++ b/modules/tracker/database/mysql/scalar_to_submission.sql @@ -1,38 +1,39 @@ CREATE DEFINER=`root`@`%` PROCEDURE `scalar_to_submission`() BEGIN - - DECLARE finished INTEGER DEFAULT 0; - DECLARE cur_id bigint(20) default -1; - DECLARE cur_producer_revision varchar(255) default ''; - DECLARE cur_user_id bigint(20) default -1; - DECLARE cur_official tinyint(4) default 1; - DECLARE cur_build_results_url text default ''; - DECLARE cur_branch varchar(255) default ''; - DECLARE cur_extra_urls text default ''; - DECLARE cur_reproduction_command text default ''; - - DECLARE curs CURSOR FOR SELECT ts.submission_id, ts.producer_revision, ts.user_id, ts.official, ts.build_results_url, ts.branch, ts.extra_urls, ts.reproduction_command - FROM tracker_scalar AS ts, tracker_submission AS tu WHERE ts.submission_id = tu.submission_id - GROUP BY tu.submission_id; - - DECLARE CONTINUE HANDLER FOR NOT FOUND SET finished = 1; - - OPEN curs; - - get_scalars: LOOP - FETCH curs INTO cur_id, cur_producer_revision, cur_user_id, cur_official, - cur_build_results_url, cur_branch, cur_extra_urls, cur_reproduction_command; - IF finished = 1 THEN - LEAVE get_scalars; - END IF; - - UPDATE tracker_submission SET - producer_revision=cur_producer_revision, user_id=cur_user_id, official=cur_official, - build_results_url=cur_build_results_url, branch=cur_branch, extra_urls=cur_extra_urls, - reproduction_command=cur_reproduction_command WHERE submission_id=cur_id; - - END LOOP get_scalars; - - CLOSE curs; -END + DECLARE finished INTEGER DEFAULT 0; + DECLARE cur_id bigint(20) default -1; + DECLARE cur_producer_revision varchar(255) default ''; + DECLARE cur_user_id bigint(20) default -1; + DECLARE cur_official tinyint(4) default 1; + DECLARE cur_build_results_url text default ''; + DECLARE cur_branch varchar(255) default ''; + DECLARE cur_extra_urls text default ''; + DECLARE cur_reproduction_command text default ''; + + DECLARE curs CURSOR FOR + SELECT ts.submission_id, ts.producer_revision, ts.user_id, ts.official, + ts.build_results_url, ts.branch, ts.extra_urls, ts.reproduction_command + FROM tracker_scalar AS ts, tracker_submission AS tu WHERE ts.submission_id = tu.submission_id + GROUP BY tu.submission_id; + DECLARE CONTINUE HANDLER FOR NOT FOUND SET finished = 1; + + OPEN curs; + + get_scalars: LOOP + FETCH curs INTO cur_id, cur_producer_revision, cur_user_id, cur_official, + cur_build_results_url, cur_branch, cur_extra_urls, cur_reproduction_command; + IF finished = 1 THEN + LEAVE get_scalars; + END IF; + + UPDATE tracker_submission SET + producer_revision=cur_producer_revision, user_id=cur_user_id, official=cur_official, + build_results_url=cur_build_results_url, branch=cur_branch, extra_urls=cur_extra_urls, + reproduction_command=cur_reproduction_command WHERE submission_id=cur_id; + + END LOOP get_scalars; + + CLOSE curs; + +END diff --git a/modules/tracker/database/mysql/upgrade_to_2.0.0.sql b/modules/tracker/database/mysql/upgrade_to_2.0.0.sql new file mode 100644 index 000000000..13f91387f --- /dev/null +++ b/modules/tracker/database/mysql/upgrade_to_2.0.0.sql @@ -0,0 +1,55 @@ +-- Midas Server. Copyright Kitware SAS. Licensed under the Apache License 2.0. + +CREATE TABLE IF NOT EXISTS `tracker_submission2item` ( + `submission_id` bigint(20) NOT NULL, + `item_id` bigint(20) NOT NULL, + `label` varchar(255) NOT NULL, + KEY (`submission_id`) +) DEFAULT CHARSET=utf8; + +CREATE TABLE IF NOT EXISTS `tracker_submissionparam` ( + `param_id` bigint(20) NOT NULL AUTO_INCREMENT, + `submission_id` bigint(20) NOT NULL, + `param_name` varchar(255) NOT NULL, + `param_type` enum('text', 'numeric') NOT NULL, + `text_value` text, + `numeric_value` double, + PRIMARY KEY (`param_id`), + KEY (`submission_id`), + KEY (`param_name`) +) DEFAULT CHARSET=utf8; + +ALTER TABLE tracker_submission ADD COLUMN `producer_revision` VARCHAR(255); +ALTER TABLE tracker_submission ADD COLUMN `user_id` bigint(20) NOT NULL DEFAULT '-1'; +ALTER TABLE tracker_submission ADD COLUMN `official` tinyint(4) NOT NULL DEFAULT '1'; +ALTER TABLE tracker_submission ADD COLUMN `build_results_url` text NOT NULL; +ALTER TABLE tracker_submission ADD COLUMN `branch` varchar(255) NOT NULL DEFAULT ''; +ALTER TABLE tracker_submission ADD COLUMN `extra_urls` text; +ALTER TABLE tracker_submission ADD COLUMN `reproduction_command` text; + +ALTER TABLE tracker_submission ADD KEY (`user_id`); +ALTER TABLE tracker_submission ADD KEY(`submit_time`); +ALTER TABLE tracker_submission ADD KEY (`branch`); + +CALL create_submissions(); + +CALL migrate_params(); + +CALL migrate_items_to_submissions(); + +CALL scalar_to_submissions(); + +DROP TABLE IF EXISTS tracker_param; + +RENAME TABLE tracker_submissionparam TO tracker_param; + +ALTER TABLE tracker_scalar DROP COLUMN `producer_revision`; +ALTER TABLE tracker_scalar DROP COLUMN `user_id`; +ALTER TABLE tracker_scalar DROP COLUMN `official`; +ALTER TABLE tracker_scalar DROP COLUMN `build_results_url`; +ALTER TABLE tracker_scalar DROP COLUMN `branch`; +ALTER TABLE tracker_scalar DROP COLUMN `extra_urls`; +ALTER TABLE tracker_scalar DROP COLUMN `reproduction_command`; +ALTER TABLE tracker_scalar DROP COLUMN `submit_time`; + +DROP TABLE IF EXISTS `tracker_scalar2item`; diff --git a/modules/tracker/database/upgrade/2.0.0.php b/modules/tracker/database/upgrade/2.0.0.php index 6f63a0a09..2bdc3f5d5 100644 --- a/modules/tracker/database/upgrade/2.0.0.php +++ b/modules/tracker/database/upgrade/2.0.0.php @@ -26,81 +26,12 @@ class Tracker_Upgrade_2_0_0 extends MIDASUpgrade /** Upgrade a MySQL database. */ public function mysql() { - // Create new table to relate items to submissions - $this->db->query( - 'CREATE TABLE IF NOT EXISTS `tracker_submission2item` ('. - '`submission_id` bigint(20) NOT NULL,'. - '`item_id` bigint(20) NOT NULL,'. - '`label` varchar(255) NOT NULL,'. - 'KEY (`submission_id`)'. - ') DEFAULT CHARSET=utf8;' - ); - - // Create new table to relate params to submissions. We will rename this later - // TODO(cpatrick): rename members in model classes - $this->db->query( - "CREATE TABLE IF NOT EXISTS `tracker_submissionparam` ( - `param_id` bigint(20) NOT NULL AUTO_INCREMENT, - `submission_id` bigint(20) NOT NULL, - `param_name` varchar(255) NOT NULL, - `param_type` enum('text', 'numeric') NOT NULL, - `text_value` text, - `numeric_value` double, - PRIMARY KEY (`param_id`), - KEY (`submission_id`), - KEY (`param_name`) - ) DEFAULT CHARSET=utf8;"); - - // Add columns to submission (that were formerly on scalar) - $this->db->query('ALTER TABLE tracker_submission ADD COLUMN `producer_revision` VARCHAR(255);'); - $this->db->query('ALTER TABLE tracker_submission ADD COLUMN `user_id` bigint(20) NOT NULL DEFAULT \'-1\';'); - $this->db->query('ALTER TABLE tracker_submission ADD COLUMN `official` tinyint(4) NOT NULL DEFAULT \'1\';'); - $this->db->query('ALTER TABLE tracker_submission ADD COLUMN `build_results_url` text NOT NULL;'); - $this->db->query('ALTER TABLE tracker_submission ADD COLUMN `branch` varchar(255) NOT NULL DEFAULT \'\';'); - $this->db->query('ALTER TABLE tracker_submission ADD COLUMN `extra_urls` text;'); - $this->db->query('ALTER TABLE tracker_submission ADD COLUMN `reproduction_command` text;'); - - // Create indices on submission - $this->db->query('ALTER TABLE tracker_submission ADD KEY (`user_id`);'); - $this->db->query('ALTER TABLE tracker_submission ADD KEY(`submit_time`);'); - $this->db->query('ALTER TABLE tracker_submission ADD KEY (`branch`);'); - - - // TODO(cpatrick): Do grouping of scalars to create submissions. - // This is done by running the stored procedure in ../mysql/create_submissions.sql - - // TODO(cpatrick): Move params to submission. - // This is done by running the stored procedure in ../mysql/migrate_params.sql. This assumes create_submissions - // has been run. - - // Drop old param table - $this->db->query('DROP TABLE IF EXISTS tracker_param;'); - - // Rename new param table. - $this->db->query('RENAME TABLE tracker_submissionparam TO tracker_param;'); - - // TODO(cpatrick): Move values from scalar2item to submission2item - // This is done by running the stored procedure in ../mysql/migrate_items_to_submissions.sql - - // TODO(cpatrick): Move values from scalars to submissions. - // This is done by running the stored procedure in ../mysql/scalar_to_submission.sql - - // Delete old values from scalars - $this->db->query('ALTER TABLE tracker_scalar DROP COLUMN `producer_revision`;'); - $this->db->query('ALTER TABLE tracker_scalar DROP COLUMN `user_id`;'); - $this->db->query('ALTER TABLE tracker_scalar DROP COLUMN `official`;'); - $this->db->query('ALTER TABLE tracker_scalar DROP COLUMN `build_results_url`;'); - $this->db->query('ALTER TABLE tracker_scalar DROP COLUMN `branch`;'); - $this->db->query('ALTER TABLE tracker_scalar DROP COLUMN `extra_urls`;'); - $this->db->query('ALTER TABLE tracker_scalar DROP COLUMN `reproduction_command`;'); - $this->db->query('ALTER TABLE tracker_scalar DROP COLUMN `submit_time`;'); - $this->db->query('DROP TABLE IF EXISTS `tracker_scalar2item`;'); - - } - - /** Upgrade a PostgreSQL database. */ - public function pgsql() - { - $this->db->query(''); + // THIS UPGRADE DOES NOTHING. TODO(cpatrick). + // ../mysql/upgrade_to_2.0.0.sql should be run after installing the + // four stored procedures (all in ../mysql/ and named the same): + // create_submissions + // migrate_params + // migrate_items_to_submissions + // scalar_to_submission } } From 791b62bd6bbee51e55509b7c8e8277b88a47623b Mon Sep 17 00:00:00 2001 From: Patrick Reynolds Date: Sat, 12 Mar 2016 08:58:40 -0500 Subject: [PATCH 03/40] Move more data up from scalar to submission. --- modules/tracker/Notification.php | 5 +- .../tracker/controllers/ScalarController.php | 25 +- .../tracker/controllers/TrendController.php | 5 +- .../controllers/components/ApiComponent.php | 439 ++---------------- .../components/ApiscalarComponent.php | 50 +- .../components/ApisubmissionComponent.php | 68 ++- .../database/mysql/create_submissions.sql | 2 +- .../mysql/migrate_items_to_submissions.sql | 2 +- .../tracker/database/mysql/migrate_params.sql | 2 +- .../database/mysql/scalar_to_submission.sql | 2 +- .../database/mysql/upgrade_to_2.0.0.sql | 13 +- .../tracker/models/base/ParamModelBase.php | 10 +- .../tracker/models/base/ScalarModelBase.php | 118 +---- .../models/base/SubmissionModelBase.php | 37 +- modules/tracker/models/dao/ScalarDao.php | 20 - modules/tracker/models/dao/SubmissionDao.php | 16 + modules/tracker/models/pdo/ScalarModel.php | 52 +-- .../tracker/models/pdo/SubmissionModel.php | 45 ++ modules/tracker/models/pdo/TrendModel.php | 32 +- modules/tracker/views/scalar/details.phtml | 15 +- 20 files changed, 287 insertions(+), 671 deletions(-) diff --git a/modules/tracker/Notification.php b/modules/tracker/Notification.php index a9286eb92..1c1e378ee 100644 --- a/modules/tracker/Notification.php +++ b/modules/tracker/Notification.php @@ -25,6 +25,7 @@ * * @property Tracker_ScalarModel $Tracker_Scalar * @property Tracker_TrendModel $Tracker_Trend + * @property Tracker_SubmissionModel $Tracker_Submission */ class Tracker_Notification extends ApiEnabled_Notification { @@ -35,7 +36,7 @@ class Tracker_Notification extends ApiEnabled_Notification public $_models = array('User'); /** @var array */ - public $_moduleModels = array('Scalar', 'Trend', 'AggregateMetricSpec', 'AggregateMetric'); + public $_moduleModels = array('Scalar', 'Trend', 'AggregateMetricSpec', 'AggregateMetric', 'Submission'); /** @var array */ public $_moduleComponents = array('Api'); @@ -94,7 +95,7 @@ public function communityDeleted($args) } /** - * When an item is deleted, we must delete associated item2scalar records. + * When an item is deleted, we must delete associated item2submission records. * * @todo * @param array $args associative array of parameters including the key "item" diff --git a/modules/tracker/controllers/ScalarController.php b/modules/tracker/controllers/ScalarController.php index d5400f14a..c5218324a 100644 --- a/modules/tracker/controllers/ScalarController.php +++ b/modules/tracker/controllers/ScalarController.php @@ -22,11 +22,12 @@ * Scalar controller for the tracker module. * * @property Tracker_ScalarModel $Tracker_Scalar + * @property Tracker_SubmissionModelModel $Tracker_Submission */ class Tracker_ScalarController extends Tracker_AppController { /** @var array */ - public $_moduleModels = array('Scalar'); + public $_moduleModels = array('Scalar', 'Submission'); /** * Display the dialog of scalar details, including associated result items with thumbnails. @@ -50,18 +51,24 @@ public function detailsAction() /** @var Tracker_ScalarDao $scalarDao */ $scalarDao = $this->Tracker_Scalar->load($scalarId); + /** @var Tracker_SubmissionDao $submissionDao */ + $submissionDao = $this->Tracker_Submission->load($scalarDao->getSubmissionId()); + if ($this->Tracker_Scalar->policyCheck($scalarDao, $this->userSession->Dao, MIDAS_POLICY_READ) === false ) { throw new Zend_Exception('The scalar does not exist or you do not have the necessary permission', 403); } + // TODO(cpatrick): This may be a performance issue. $this->view->isAdmin = $this->Tracker_Scalar->policyCheck($scalarDao, $this->userSession->Dao, MIDAS_POLICY_ADMIN); + $this->view->scalar = $scalarDao; - $this->view->extraParams = $scalarDao->getParams(); - $this->view->extraUrls = json_decode($scalarDao->getExtraUrls(), true); + $this->view->submission = $submissionDao; + $this->view->extraParams = $submissionDao->getParams(); + $this->view->extraUrls = json_decode($submissionDao->getExtraUrls(), true); - $revisionUrl = $scalarDao->getTrend()->getProducer()->getRevisionUrl(); - $producerRevision = $scalarDao->getProducerRevision(); + $revisionUrl = $submissionDao->getProducer()->getRevisionUrl(); + $producerRevision = $submissionDao->getProducerRevision(); if (!is_null($revisionUrl)) { $producerRevisionUrl = preg_replace('/%revision/', $producerRevision, $revisionUrl); @@ -70,11 +77,11 @@ public function detailsAction() $this->view->revisionHtml = $producerRevision; } - $this->view->resultItems = $this->Tracker_Scalar->getAssociatedItems($scalarDao); - $this->view->otherValues = $this->Tracker_Scalar->getOtherValuesFromSubmission($scalarDao); + $this->view->resultItems = $this->Tracker_Submission->getAssociatedItems($submissionDao); + $this->view->otherValues = $this->Tracker_Submission->getValuesFromSubmission($submissionDao); - if ($scalarDao->getUserId() !== -1) { - $this->view->submittedBy = $scalarDao->getUser(); + if ($submissionDao->getUserId() !== -1) { + $this->view->submittedBy = $submissionDao->getUser(); } else { $this->view->submittedBy = null; } diff --git a/modules/tracker/controllers/TrendController.php b/modules/tracker/controllers/TrendController.php index 640807d1c..a0118727f 100644 --- a/modules/tracker/controllers/TrendController.php +++ b/modules/tracker/controllers/TrendController.php @@ -24,6 +24,7 @@ * @property Tracker_ScalarModel $Tracker_Scalar * @property Tracker_ThresholdNotificationModel $Tracker_ThresholdNotification * @property Tracker_TrendModel $Tracker_Trend + * @property Tracker_SubmissionModel $Tracker_Submission */ class Tracker_TrendController extends Tracker_AppController { @@ -31,7 +32,7 @@ class Tracker_TrendController extends Tracker_AppController public $_components = array('Breadcrumb'); /** @var array */ - public $_moduleModels = array('Producer', 'Scalar', 'ThresholdNotification', 'Trend'); + public $_moduleModels = array('Producer', 'Scalar', 'ThresholdNotification', 'Trend', 'Submission'); /** * View a given trend. @@ -81,7 +82,7 @@ public function viewAction() $userId = $this->userSession->Dao ? $this->userSession->Dao->getKey() : null; - $this->view->allBranches = $this->Tracker_Scalar->getDistinctBranches(); + $this->view->allBranches = $this->Tracker_Submission->getDistinctBranches(); $trendIds = explode(' ', trim(str_replace(',', ' ', $trendId))); $trendDaos = array(); diff --git a/modules/tracker/controllers/components/ApiComponent.php b/modules/tracker/controllers/components/ApiComponent.php index 76097bebc..36c14c747 100644 --- a/modules/tracker/controllers/components/ApiComponent.php +++ b/modules/tracker/controllers/components/ApiComponent.php @@ -56,9 +56,9 @@ private function _getUser($args) } /** - * Associate a result item with a particular scalar value. + * Associate a result item with a particular submission * - * @param scalarIds Comma separated list of scalar ids to associate the item with + * @param submissionId the submission to associate the item with * @param itemId The id of the item to associate with the scalar * @param label The label describing the nature of the association * @throws Exception @@ -72,7 +72,7 @@ public function itemAssociate($args) $itemModel = MidasLoader::loadModel('Item'); /** @var Tracker_ScalarModel $scalarModel */ - $scalarModel = MidasLoader::loadModel('Scalar', 'tracker'); + $submissionModel = MidasLoader::loadModel('Submission', 'tracker'); $this->_checkKeys(array('scalarIds', 'itemId', 'label'), $args); $user = $this->_getUser($args); @@ -85,26 +85,24 @@ public function itemAssociate($args) throw new Exception('Read permission on the item required', 403); } - $scalarIds = explode(',', $args['scalarIds']); + $submissionId = $args['submissionId']; - /** @var int $scalarId */ - foreach ($scalarIds as $scalarId) { - /** @var Tracker_ScalarDao $scalar */ - $scalar = $scalarModel->load($scalarId); + /** @var Tracker_SubmissionDao $submission */ + $submission = $submissionModel->load($submissionId); - if (!$scalar) { - throw new Exception('Invalid scalarId: '.$scalarId, 404); - } - if (!$communityModel->policyCheck( - $scalar->getTrend()->getProducer()->getCommunity(), - $user, - MIDAS_POLICY_ADMIN - ) - ) { - throw new Exception('Admin permission on the community required', 403); - } - $scalarModel->associateItem($scalar, $item, $args['label']); + if (!$submission) { + throw new Exception('Invalid submission id: '.$submissionId, 404); + } + + if (!$communityModel->policyCheck( + $submission->getProducer()->getCommunity(), + $user, + MIDAS_POLICY_ADMIN + )) { + throw new Exception('Admin permission on the community required', 403); } + + $submissionModel->associateItem($submission, $item, $args['label']); } /** @@ -113,22 +111,12 @@ public function itemAssociate($args) * @param communityId The id of the community that owns the producer * @param producerDisplayName The display name of the producer * @param metricName The metric name that identifies which trend this point belongs to - * @param producerRevision The repository revision of the producer that produced this value - * @param submitTime The submit timestamp. Must be parseable with PHP strtotime(). * @param value The value of the scalar - * @param submissionId (Optional) the id of the submission - * @param submissionUuid (Optional) the uuid of the submission - * @param buildResultsUrl (Optional) The URL where build results can be viewed - * @param extraUrls (Optional) JSON list of additional links - * @param params (Optional) JSON object of arbitrary key/value pairs to display - * @param branch (Optional) The branch name within the source repository + * @param submissionUuid the uuid of the submission * @param configItemId (Optional) If this value pertains to a specific configuration item, pass its id here * @param testDatasetId (Optional) If this value pertains to a specific test dataset, pass its id here * @param truthDatasetId (Optional) If this value pertains to a specific ground truth dataset, pass its id here - * @param silent (Optional) If set, do not perform threshold-based email notifications for this scalar - * @param unofficial (Optional) If passed, creates an unofficial scalar visible only to the user performing the submission * @param unit (Optional) If passed, the unit of the scalar value that identifies which trend this point belongs to. - * @param reproductionCommand (Optional) If passed, the command to produce this scalar * @return The scalar DAO that was created * @throws Exception */ @@ -140,19 +128,17 @@ public function scalarAdd($args) /** @var ItemModel $itemModel */ $itemModel = MidasLoader::loadModel('Item'); $this->_checkKeys( - array('communityId', 'producerDisplayName', 'metricName', 'value', 'producerRevision', 'submitTime'), + array('communityId', 'producerDisplayName', 'metricName', 'value'), $args ); $user = $this->_getUser($args); - $official = !array_key_exists('unofficial', $args); - /** @var CommunityDao $community */ $community = $communityModel->load($args['communityId']); if (!$community || !$communityModel->policyCheck( $community, $user, - $official ? MIDAS_POLICY_WRITE : MIDAS_POLICY_READ + MIDAS_POLICY_WRITE ) ) { throw new Exception('Write permission required on community', 403); @@ -230,21 +216,6 @@ public function scalarAdd($args) } } - if (isset($args['params'])) { - $extraParams = json_decode($args['params'], true); - } else { - $extraParams = null; - } - - if (isset($args['extraUrls'])) { - $extraUrls = json_decode($args['extraUrls'], true); - } else { - $extraUrls = null; - } - - $buildResultsUrl = isset($args['buildResultsUrl']) ? $args['buildResultsUrl'] : ''; - $branch = isset($args['branch']) ? $args['branch'] : ''; - if (isset($args['unit'])) { $unit = $args['unit']; } else { @@ -261,370 +232,19 @@ public function scalarAdd($args) $unit ); - $submitTime = strtotime($args['submitTime']); - if ($submitTime === false) { - throw new Exception('Invalid submitTime value: '.$args['submitTime'], -1); - } - $submitTime = date('Y-m-d H:i:s', $submitTime); - $value = (float) $args['value']; - $producerRevision = trim($args['producerRevision']); - - $submissionId = -1; - if (isset($args['submissionId'])) { - $submissionId = $args['submissionId']; - } elseif (isset($args['submissionUuid'])) { - $uuid = $args['submissionUuid']; - $submissionModel = MidasLoader::loadModel('Submission', 'tracker'); - $submissionDao = $submissionModel->getOrCreateSubmission($producer, $uuid); - $submissionId = $submissionDao->getKey(); - } - - $reproductionCommand = null; - if (isset($args['reproductionCommand'])) { - $reproductionCommand = $args['reproductionCommand']; - } + $uuid = $args['submissionUuid']; + $submissionModel = MidasLoader::loadModel('Submission', 'tracker'); + $submissionDao = $submissionModel->getOrCreateSubmission($producer, $uuid); /** @var Tracker_ScalarModel $scalarModel */ $scalarModel = MidasLoader::loadModel('Scalar', 'tracker'); - $scalar = $scalarModel->addToTrend( - $trend, - $submitTime, - $submissionId, - $producerRevision, - $value, - $user, - true, - $official, - $buildResultsUrl, - $branch, - $extraParams, - $extraUrls, - $reproductionCommand - ); - - if (!isset($args['silent'])) { - /** @var Tracker_ThresholdNotificationModel $notificationModel */ - $notificationModel = MidasLoader::loadModel('ThresholdNotification', 'tracker'); - $notifications = $notificationModel->getNotifications($scalar); - - /** @var Tracker_ThresholdNotificationComponent $notifyComponent */ - $notifyComponent = MidasLoader::loadComponent('ThresholdNotification', 'tracker'); - $notifyComponent->scheduleNotifications($scalar, $notifications); - } - if (!$official) { - /** @var Scheduler_JobModel $jobModel */ - $jobModel = MidasLoader::loadModel('Job', 'scheduler'); - - /** @var SettingModel $settingModel */ - $settingModel = MidasLoader::loadModel('Setting'); - $nHours = (int) $settingModel->getValueByName(MIDAS_TRACKER_TEMP_SCALAR_TTL_KEY, $this->moduleName); - if (!$nHours) { - $nHours = 24; // default to 24 hours - } - while (each($notifications)) { - /** @var Scheduler_JobDao $job */ - $job = MidasLoader::newDao('JobDao', 'scheduler'); - $job->setTask('TASK_TRACKER_DELETE_TEMP_SCALAR'); - $job->setPriority(1); - $job->setRunOnlyOnce(1); - $job->setFireTime(date('Y-m-d H:i:s', strtotime('+'.$nHours.' hours'))); - $job->setTimeInterval(0); - $job->setStatus(SCHEDULER_JOB_STATUS_TORUN); - $job->setCreatorId($user->getKey()); - $job->setParams(JsonComponent::encode(array('scalarId' => $scalar->getKey()))); - $jobModel->save($job); - } - } + $scalar = $scalarModel->addToTrend($trend, $submissionDao, $value); return $scalar; } - /** - * Upload a JSON file containing numeric scoring results to be added as scalars. File is parsed and then deleted from the server. - * - * @param communityId The id of the community that owns the producer - * @param producerDisplayName The display name of the producer - * @param producerRevision The repository revision of the producer that produced this value - * @param submitTime (Optional) The submit timestamp. Must be parseable with PHP strtotime(). If not set, uses current time. - * @param buildResultsUrl (Optional) The URL where build results can be viewed. - * @param branch (Optional) The branch name within the source repository - * @param extraUrls (Optional) JSON list of additional links - * @param params (Optional) JSON object of arbitrary key/value pairs to display - * @param configItemId (Optional) If this value pertains to a specific configuration item, pass its id here - * @param testDatasetId (Optional) If this value pertains to a specific test dataset, pass its id here - * @param truthDatasetId (Optional) If this value pertains to a specific ground truth dataset, pass its id here - * @param parentKeys (Optional) Semicolon-separated list of parent keys to look for numeric results under. Use '.' to denote nesting, like in normal JavaScript syntax. - * @param silent (Optional) If set, do not perform threshold-based email notifications for this scalar - * @param unofficial (Optional) If passed, creates an unofficial scalar visible only to the user performing the submission - * @return The list of scalars that were created. Non-numeric values are ignored. - * @throws Exception - */ - public function resultsUploadJson($args) - { - /** Change this to add a submission id or uuid. */ - $submissionId = -1; - /** @var CommunityModel $communityModel */ - $communityModel = MidasLoader::loadModel('Community'); - - /** @var ItemModel $itemModel */ - $itemModel = MidasLoader::loadModel('Item'); - $this->_checkKeys(array('communityId', 'producerDisplayName', 'producerRevision'), $args); - $user = $this->_getUser($args); - - $official = !array_key_exists('unofficial', $args); - if (!$official) { - /** @var Scheduler_JobModel $jobModel */ - $jobModel = MidasLoader::loadModel('Job', 'scheduler'); - - /** @var SettingModel $settingModel */ - $settingModel = MidasLoader::loadModel('Setting'); - $nHours = (int) $settingModel->getValueByName(MIDAS_TRACKER_TEMP_SCALAR_TTL_KEY, $this->moduleName); - if (!$nHours) { - $nHours = MIDAS_TRACKER_TEMP_SCALAR_TTL_DEFAULT_VALUE; // default to 24 hours - } - } - - // Unofficial submissions only require read access to the community - - /** @var CommunityDao $community */ - $community = $communityModel->load($args['communityId']); - if (!$community || !$communityModel->policyCheck( - $community, - $user, - $official ? MIDAS_POLICY_WRITE : MIDAS_POLICY_READ - ) - ) { - throw new Exception('Write permission required on community', 403); - } - - $producerDisplayName = trim($args['producerDisplayName']); - if ($producerDisplayName == '') { - throw new Exception('Producer display name must not be empty', -1); - } - - /** @var Tracker_ProducerModel $producerModel */ - $producerModel = MidasLoader::loadModel('Producer', 'tracker'); - $producer = $producerModel->createIfNeeded($community->getKey(), $producerDisplayName); - $buildResultsUrl = isset($args['buildResultsUrl']) ? $args['buildResultsUrl'] : ''; - $branch = isset($args['branch']) ? $args['branch'] : ''; - - list($configItemId, $testDatasetId, $truthDatasetId) = array(null, null, null); - if (isset($args['configItemId'])) { - /** @var int $configItemId */ - $configItemId = $args['configItemId']; - - /** @var ItemDao $configItem */ - $configItem = $itemModel->load($configItemId); - if (!$configItem || !$itemModel->policyCheck($configItem, $user, MIDAS_POLICY_READ) - ) { - throw new Exception('Read permission required on config item', 403); - } - } elseif (isset($args['configItemName'])) { - $configItem = $this->_createOrFindByName($args['configItemName'], $community); - $configItemId = $configItem->getKey(); - if (!$configItem || !$itemModel->policyCheck($configItem, $user, MIDAS_POLICY_READ) - ) { - throw new Exception('Read permission required on config item', 403); - } - } - - if (isset($args['testDatasetId'])) { - /** @var int $testDatasetId */ - $testDatasetId = $args['testDatasetId']; - - /** @var ItemDao $testDatasetItem */ - $testDatasetItem = $itemModel->load($testDatasetId); - if (!$testDatasetItem || !$itemModel->policyCheck($testDatasetItem, $user, MIDAS_POLICY_READ) - ) { - throw new Exception('Read permission required on test dataset item', 403); - } - } elseif (isset($args['testDatasetName'])) { - $testDatasetItem = $this->_createOrFindByName($args['testDatasetName'], $community); - $testDatasetId = $testDatasetItem->getKey(); - if (!$testDatasetItem || !$itemModel->policyCheck($testDatasetItem, $user, MIDAS_POLICY_READ) - ) { - throw new Exception('Read permission required on test dataset item', 403); - } - } - - if (isset($args['truthDatasetId'])) { - /** @var int $truthDatasetId */ - $truthDatasetId = $args['truthDatasetId']; - - /** @var ItemDao $truthDatasetItem */ - $truthDatasetItem = $itemModel->load($truthDatasetId); - if (!$truthDatasetItem || !$itemModel->policyCheck($truthDatasetItem, $user, MIDAS_POLICY_READ) - ) { - throw new Exception('Read permission required on truth dataset item', 403); - } - } elseif (isset($args['truthDatasetName'])) { - $truthDatasetItem = $this->_createOrFindByName($args['truthDatasetName'], $community); - $truthDatasetId = $truthDatasetItem->getKey(); - if (!$truthDatasetItem || !$itemModel->policyCheck($truthDatasetItem, $user, MIDAS_POLICY_READ) - ) { - throw new Exception('Read permission required on truth dataset item', 403); - } - } - - if (isset($args['params'])) { - $extraParams = json_decode($args['params'], true); - } else { - $extraParams = null; - } - - if (isset($args['extraUrls'])) { - $extraUrls = json_decode($args['extraUrls'], true); - } else { - $extraUrls = null; - } - - /** @var Tracker_TrendModel $trendModel */ - $trendModel = MidasLoader::loadModel('Trend', 'tracker'); - - if (isset($args['submitTime'])) { - $submitTime = strtotime($args['submitTime']); - if ($submitTime === false) { - throw new Exception('Invalid submitTime value: '.$args['submitTime'], -1); - } - $submitTime = date('Y-m-d H:i:s', $submitTime); - } else { - $submitTime = date('Y-m-d H:i:s'); // Use current time if no submit time is explicitly set - } - - $producerRevision = trim($args['producerRevision']); - - /** @var Tracker_ScalarModel $scalarModel */ - $scalarModel = MidasLoader::loadModel('Scalar', 'tracker'); - $json = json_decode(file_get_contents('php://input'), true); - if ($json === null) { - throw new Exception('Invalid JSON upload contents', -1); - } - $scalars = array(); - - if (isset($args['parentKeys'])) { // iterate through all child keys of the set of specified parent keys - $parentKeys = explode(';', $args['parentKeys']); - - /** @var string $parentKey */ - foreach ($parentKeys as $parentKey) { - $nodes = explode('.', $parentKey); - $currentArr = $json; - foreach ($nodes as $node) { - if (!isset($currentArr[$node]) || !is_array($currentArr[$node]) - ) { - throw new Exception( - 'Specified parent key "'.$parentKey.'" does not exist or is not an array type', -1 - ); - } - $currentArr = $currentArr[$node]; - } - - /** - * @var string $metricName - * @var float $value - */ - foreach ($currentArr as $metricName => $value) { // iterate through all children of this parent key - if (!is_numeric($value)) { // ignore non-numeric child keys - continue; - } - $trend = $trendModel->createIfNeeded( - $producer->getKey(), - $metricName, - $configItemId, - $testDatasetId, - $truthDatasetId - ); - $scalar = $scalarModel->addToTrend( - $trend, - $submitTime, - $submissionId, - $producerRevision, - $value, - $user, - true, - $official, - $buildResultsUrl, - $branch, - $extraParams, - $extraUrls - ); - $scalars[] = $scalar; - - if (!isset($args['silent'])) { - /** @var Tracker_ThresholdNotificationModel $notificationModel */ - $notificationModel = MidasLoader::loadModel('ThresholdNotification', 'tracker'); - $notifications = $notificationModel->getNotifications($scalar); - - /** @var Tracker_ThresholdNotificationComponent $notifyComponent */ - $notifyComponent = MidasLoader::loadComponent('ThresholdNotification', 'tracker'); - $notifyComponent->scheduleNotifications($scalar, $notifications); - } - if (!$official) { - while (each($notifications)) { - /** @var Scheduler_JobDao $job */ - $job = MidasLoader::newDao('JobDao', 'scheduler'); - $job->setTask('TASK_TRACKER_DELETE_TEMP_SCALAR'); - $job->setPriority(1); - $job->setRunOnlyOnce(1); - - /** @noinspection PhpUndefinedVariableInspection */ - $job->setFireTime(date('Y-m-d H:i:s', strtotime('+'.$nHours.' hours'))); - $job->setTimeInterval(0); - $job->setStatus(SCHEDULER_JOB_STATUS_TORUN); - $job->setCreatorId($user->getKey()); - $job->setParams(JsonComponent::encode(array('scalarId' => $scalar->getKey()))); - - /** @noinspection PhpUndefinedVariableInspection */ - $jobModel->save($job); - } - } - } - } - } else { // just read all the top level keys - - /** - * @var string $metricName - * @var float $value - */ - foreach ($json as $metricName => $value) { - if (!is_numeric($value)) { - continue; - } - $trend = $trendModel->createIfNeeded( - $producer->getKey(), - $metricName, - $configItemId, - $testDatasetId, - $truthDatasetId - ); - $scalar = $scalarModel->addToTrend( - $trend, - $submitTime, - $submissionId, - $producerRevision, - $value, - $user, - true, - $official - ); - $scalars[] = $scalar; - - if (!isset($args['silent'])) { - /** @var Tracker_ThresholdNotificationModel $notificationModel */ - $notificationModel = MidasLoader::loadModel('ThresholdNotification', 'tracker'); - $notifications = $notificationModel->getNotifications($scalar); - - /** @var Tracker_ThresholdNotificationComponent $notifyComponent */ - $notifyComponent = MidasLoader::loadComponent('ThresholdNotification', 'tracker'); - $notifyComponent->scheduleNotifications($scalar, $notifications); - } - } - } - - return $scalars; - } - /** * Create or find an item with the given name in the given community. * @@ -661,8 +281,17 @@ private function _createOrFindByName($itemName, $community) /** * Create a new submission. * + * @param producerRevision The repository revision of the producer that produced this value + * @param submitTime The submit timestamp. Must be parseable with PHP strtotime(). * @param uuid (Optional) A unique identifier for the submission * @param name (Optional) A name for the submission + * @param buildResultsUrl (Optional) The URL where build results can be viewed + * @param extraUrls (Optional) JSON list of additional links + * @param params (Optional) JSON object of arbitrary key/value pairs to display + * @param branch (Optional) The branch name within the source repository + * @param silent (Optional) If set, do not perform threshold-based email notifications for this scalar + * @param unofficial (Optional) If passed, creates an unofficial scalar visible only to the user performing the submission + * @param reproductionCommand (Optional) If passed, the command to produce this scalar * @return The submission DAO that was created * @throws Exception */ diff --git a/modules/tracker/controllers/components/ApiscalarComponent.php b/modules/tracker/controllers/components/ApiscalarComponent.php index 5023abecd..3f71f9980 100644 --- a/modules/tracker/controllers/components/ApiscalarComponent.php +++ b/modules/tracker/controllers/components/ApiscalarComponent.php @@ -121,16 +121,8 @@ public function index($args) * @path /tracker/scalar * @http POST * @param trend_id - * @param submission_id (Optional) - * @param user_id (Optional) - * @param official (Optional) - * @param build_results_url (Optional) - * @param params (Optional) - * @param extra_urls (Optional) - * @param branch (Optional) - * @param submit_time (Optional) - * @param value (Optional) - * @param producer_revision (Optional) + * @param submission_id + * @param value * @return array * * @param array $args parameters @@ -157,14 +149,6 @@ public function post($args) throw new Exception('The trend does not exist or you do not have the necessary permission', MIDAS_INVALID_POLICY); } - if (isset($args['params']) && !is_null($args['params']) && !is_string($args['params'])) { - $args['params'] = json_encode($args['params']); - } - - if (isset($args['extra_urls']) && !is_null($args['extra_urls']) && !is_string($args['extra_urls'])) { - $args['extra_urls'] = json_encode($args['extra_urls']); - } - /** @var Tracker_ScalarModel $scalarModel */ $scalarModel = MidasLoader::loadModel('Scalar', $this->moduleName); @@ -186,15 +170,7 @@ public function post($args) * @param id * @param trend_id * @param submission_id (Optional) - * @param user_id (Optional) - * @param official (Optional) - * @param build_results_url (Optional) - * @param params (Optional) - * @param extra_urls (Optional) - * @param branch (Optional) - * @param submit_time (Optional) * @param value (Optional) - * @param producer_revision (Optional) * @return array * * @param array $args parameters @@ -221,33 +197,11 @@ public function put($args) throw new Exception('The scalar does not exist or you do not have the necessary permission', MIDAS_INVALID_POLICY); } - if (isset($args['params']) && !is_null($args['params'])) { - $params = $args['params']; - unset($args['params']); - } - - if (isset($args['extra_urls']) && !is_null($args['extra_urls']) && !is_string($args['extra_urls'])) { - $args['extra_urls'] = json_encode($args['extra_urls']); - } - /** @var Tracker_ScalarDao $scalarDao */ $scalarDao = $scalarModel->initDao('Scalar', $args, $this->moduleName); $scalarDao->setScalarId($scalarId); $scalarModel->save($scalarDao); - if (isset($params) && is_string($params)) { - $params = json_decode($params); - $paramModel = MidasLoader::loadModel('Param', $this->moduleName); - foreach ($params as $paramName => $paramValue) { - /** @var Tracker_ParamDao $paramDao */ - $paramDao = MidasLoader::newDao('ParamDao', $this->moduleName); - $paramDao->setScalarId($scalarDao->getScalarId()); - $paramDao->setParamName($paramName); - $paramDao->setParamValue($paramValue); - $paramModel->save($paramDao); - } - } - /** @var Tracker_ScalarDao $scalarDao */ $scalarDao = $scalarModel->load($scalarId); diff --git a/modules/tracker/controllers/components/ApisubmissionComponent.php b/modules/tracker/controllers/components/ApisubmissionComponent.php index ff02b76bd..bf365eeb6 100644 --- a/modules/tracker/controllers/components/ApisubmissionComponent.php +++ b/modules/tracker/controllers/components/ApisubmissionComponent.php @@ -129,9 +129,17 @@ public function index($args) * * @path /tracker/submission * @http POST - * @param producer_id + * @param communityId + * @param producerDisplayName + * @param producerRevision * @param uuid (Optional) * @param name (Optional) + * @param submitTime (Optional) + * @param branch (Optional) + * @param buildResultsUrl (Optional) + * @param params (Optional) + * @param extraUrls (Optional) + * @param reproductionCommand (Optional) * @return array * * @param array $args parameters @@ -143,7 +151,7 @@ public function post($args) $apihelperComponent = MidasLoader::loadComponent('Apihelper'); $apihelperComponent->requirePolicyScopes( array(MIDAS_API_PERMISSION_SCOPE_WRITE_DATA)); - $apihelperComponent->validateParams($args, array('producer_id')); + $apihelperComponent->validateParams($args, array('communityId', 'producerDisplayName', 'producerRevision')); $this->_checkUser($args, 'Only authenticated users can create submissions.'); @@ -152,12 +160,33 @@ public function post($args) $submissionModel = MidasLoader::loadModel('Submission', $this->moduleName); + /** @var Tracker_ProducerModel $producerModel */ + $producerModel = MidasLoader::loadModel('Producer', $this->moduleName); + if (!isset($args['uuid'])) { /** @var UuidComponent $uuidComponent */ $uuidComponent = MidasLoader::loadComponent('UuidComponent'); $args['uuid'] = $uuidComponent->generate(); } + if (isset($args['extraUrls'])) { + $args['extraUrls'] = json_decode($args['extraUrls'], true); + } + + $args['buildResultsUrl'] = isset($args['buildResultsUrl']) ? $args['buildResultsUrl'] : ''; + $args['branch'] = isset($args['branch']) ? $args['branch'] : ''; + $args['reproductionCommand'] = isset($args['reproductionCommand']) ? $args['reproductionCommand'] : ''; + + $submitTime = strtotime($args['submitTime']); + if ($submitTime === false) { + throw new Exception('Invalid submitTime value: '.$args['submitTime'], -1); + } + $submitTime = date('Y-m-d H:i:s', $submitTime); + $args['submitTime'] = $submitTime; + $args['producerRevision'] = trim($args['producerRevision']); + $args['producer_id'] = $producerModel->getByCommunityIdAndName( + $args['communityId'], $args['producerDisplayName'])->getKey(); + /** @var Tracker_SubmissionDao $submissionDao */ $submissionDao = $submissionModel->initDao('Submission', $args, @@ -171,10 +200,23 @@ public function post($args) MIDAS_INVALID_PARAMETER); } - $submissionId = $submissionDao->getSubmissionId(); + if (isset($args['params']) && !is_null($args['params'])) { + $params = $args['params']; + unset($args['params']); + } - /** @var Tracker_SubmissionDao $submissionDao */ - $submissionDao = $submissionModel->load($submissionId); + if (isset($params) && is_string($params)) { + $params = json_decode($params); + $paramModel = MidasLoader::loadModel('Param', $this->moduleName); + foreach ($params as $paramName => $paramValue) { + /** @var Tracker_ParamDao $paramDao */ + $paramDao = MidasLoader::newDao('ParamDao', $this->moduleName); + $paramDao->setSubmissionId($submissionDao->getKey()); + $paramDao->setParamName($paramName); + $paramDao->setParamValue($paramValue); + $paramModel->save($paramDao); + } + } return $this->_toArray($submissionDao); } @@ -185,8 +227,13 @@ public function post($args) * @path /tracker/submission/{id} * @http PUT * @param id - * @param uuid (Optional) * @param name (Optional) + * @param submitTime (Optional) + * @param branch (Optional) + * @param buildResultsUrl (Optional) + * @param params (Optional) + * @param extraUrls (Optional) + * @param reproductionCommand (Optional) * @return array * * @param array $args parameters @@ -218,6 +265,15 @@ public function put($args) ' does not exist.', MIDAS_NOT_FOUND); } + if(isset($args['submitTime'])) { + $submitTime = strtotime($args['submitTime']); + if ($submitTime === false) { + throw new Exception('Invalid submitTime value: ' . $args['submitTime'], -1); + } + $submitTime = date('Y-m-d H:i:s', $submitTime); + $args['submitTime'] = $submitTime; + } + /** @var Tracker_SubmissionDao $submissionDao */ $submissionDao = $submissionModel->initDao('Submission', $args, $this->moduleName); diff --git a/modules/tracker/database/mysql/create_submissions.sql b/modules/tracker/database/mysql/create_submissions.sql index a390d5d20..cd7c5afa4 100644 --- a/modules/tracker/database/mysql/create_submissions.sql +++ b/modules/tracker/database/mysql/create_submissions.sql @@ -1,4 +1,4 @@ -CREATE DEFINER=`root`@`%` PROCEDURE `create_submissions`() +CREATE PROCEDURE `create_submissions`() BEGIN DECLARE finished INTEGER DEFAULT 0; DECLARE cur_id bigint(20) default -1; diff --git a/modules/tracker/database/mysql/migrate_items_to_submissions.sql b/modules/tracker/database/mysql/migrate_items_to_submissions.sql index 0ff3b34e2..a542d0ec4 100644 --- a/modules/tracker/database/mysql/migrate_items_to_submissions.sql +++ b/modules/tracker/database/mysql/migrate_items_to_submissions.sql @@ -1,4 +1,4 @@ -CREATE DEFINER=`root`@`%` PROCEDURE `migrate_items_to_submissions`() +CREATE PROCEDURE `migrate_items_to_submissions`() BEGIN DECLARE finished INTEGER DEFAULT 0; diff --git a/modules/tracker/database/mysql/migrate_params.sql b/modules/tracker/database/mysql/migrate_params.sql index a10f84d5c..632f423fd 100644 --- a/modules/tracker/database/mysql/migrate_params.sql +++ b/modules/tracker/database/mysql/migrate_params.sql @@ -1,4 +1,4 @@ -CREATE DEFINER=`root`@`%` PROCEDURE `migrate_params`() +CREATE PROCEDURE `migrate_params`() BEGIN DECLARE finished INTEGER DEFAULT 0; diff --git a/modules/tracker/database/mysql/scalar_to_submission.sql b/modules/tracker/database/mysql/scalar_to_submission.sql index 032ac28e5..bd5e0d74d 100644 --- a/modules/tracker/database/mysql/scalar_to_submission.sql +++ b/modules/tracker/database/mysql/scalar_to_submission.sql @@ -1,4 +1,4 @@ -CREATE DEFINER=`root`@`%` PROCEDURE `scalar_to_submission`() +CREATE PROCEDURE `scalar_to_submission`() BEGIN DECLARE finished INTEGER DEFAULT 0; diff --git a/modules/tracker/database/mysql/upgrade_to_2.0.0.sql b/modules/tracker/database/mysql/upgrade_to_2.0.0.sql index 13f91387f..c3339b19d 100644 --- a/modules/tracker/database/mysql/upgrade_to_2.0.0.sql +++ b/modules/tracker/database/mysql/upgrade_to_2.0.0.sql @@ -19,6 +19,17 @@ CREATE TABLE IF NOT EXISTS `tracker_submissionparam` ( KEY (`param_name`) ) DEFAULT CHARSET=utf8; +DROP PROCEDURE IF EXISTS `create_submissions`; +DROP PROCEDURE IF EXISTS `migrate_items_to_submissions`; +DROP PROCEDURE IF EXISTS `migrate_params`; +DROP PROCEDURE IF EXISTS `scalar_to_submission`; +DELIMITER '$$' +SOURCE create_submissions.sql +SOURCE migrate_items_to_submissions.sql +SOURCE migrate_params.sql +SOURCE scalar_to_submission.sql +DELIMITER ';' + ALTER TABLE tracker_submission ADD COLUMN `producer_revision` VARCHAR(255); ALTER TABLE tracker_submission ADD COLUMN `user_id` bigint(20) NOT NULL DEFAULT '-1'; ALTER TABLE tracker_submission ADD COLUMN `official` tinyint(4) NOT NULL DEFAULT '1'; @@ -37,7 +48,7 @@ CALL migrate_params(); CALL migrate_items_to_submissions(); -CALL scalar_to_submissions(); +CALL scalar_to_submission(); DROP TABLE IF EXISTS tracker_param; diff --git a/modules/tracker/models/base/ParamModelBase.php b/modules/tracker/models/base/ParamModelBase.php index 4705b7bc9..b33497267 100644 --- a/modules/tracker/models/base/ParamModelBase.php +++ b/modules/tracker/models/base/ParamModelBase.php @@ -30,17 +30,17 @@ public function __construct() $this->_key = 'param_id'; $this->_mainData = array( 'param_id' => array('type' => MIDAS_DATA), - 'scalar_id' => array('type' => MIDAS_DATA), + 'submission_id' => array('type' => MIDAS_DATA), 'param_name' => array('type' => MIDAS_DATA), 'param_type' => array('type' => MIDAS_DATA), 'text_value' => array('type' => MIDAS_DATA), 'numeric_value' => array('type' => MIDAS_DATA), - 'scalar' => array( + 'submission' => array( 'type' => MIDAS_MANY_TO_ONE, - 'model' => 'Scalar', + 'model' => 'Submission', 'module' => $this->moduleName, - 'parent_column' => 'scalar_id', - 'child_column' => 'scalar_id', + 'parent_column' => 'submission_id', + 'child_column' => 'submission_id', ), ); diff --git a/modules/tracker/models/base/ScalarModelBase.php b/modules/tracker/models/base/ScalarModelBase.php index a42f5f5b8..07d4a7b5f 100644 --- a/modules/tracker/models/base/ScalarModelBase.php +++ b/modules/tracker/models/base/ScalarModelBase.php @@ -31,16 +31,10 @@ public function __construct() $this->_mainData = array( 'scalar_id' => array('type' => MIDAS_DATA), 'trend_id' => array('type' => MIDAS_DATA), - 'user_id' => array('type' => MIDAS_DATA), 'submission_id' => array('type' => MIDAS_DATA), - 'official' => array('type' => MIDAS_DATA), - 'build_results_url' => array('type' => MIDAS_DATA), - 'extra_urls' => array('type' => MIDAS_DATA), - 'branch' => array('type' => MIDAS_DATA), - 'submit_time' => array('type' => MIDAS_DATA), + 'submit_time' => array('type' => MIDAS_DATA), // Not in the DB, from submission + 'official' => array('type' => MIDAS_DATA), // Not in the DB, from submission 'value' => array('type' => MIDAS_DATA), - 'producer_revision' => array('type' => MIDAS_DATA), - 'reproduction_command' => array('type' => MIDAS_DATA), 'trend' => array( 'type' => MIDAS_MANY_TO_ONE, 'model' => 'Trend', @@ -54,41 +48,12 @@ public function __construct() 'module' => $this->moduleName, 'parent_column' => 'submission_id', 'child_column' => 'submission_id', - ), - 'user' => array( - 'type' => MIDAS_MANY_TO_ONE, - 'model' => 'User', - 'parent_column' => 'user_id', - 'child_column' => 'user_id', - ), - 'params' => array( - 'type' => MIDAS_ONE_TO_MANY, - 'model' => 'Param', - 'module' => $this->moduleName, - 'parent_column' => 'scalar_id', - 'child_column' => 'scalar_id', - ), + ) ); $this->initialize(); } - /** - * Return any other scalars from the same submission as the given scalar. - * - * @param Tracker_ScalarDao $scalarDao scalar DAO - * @return array scalar DAOs - */ - abstract public function getOtherScalarsFromSubmission($scalarDao); - - /** - * Return any other values from the same submission as the given scalar. - * - * @param Tracker_ScalarDao $scalarDao scalar DAO - * @return array associative array with keys equal to the metric names - */ - abstract public function getOtherValuesFromSubmission($scalarDao); - /** * Return a scalar given a trend id, submit time, and user id. * @@ -100,88 +65,31 @@ abstract public function getOtherValuesFromSubmission($scalarDao); abstract public function getByTrendAndTimestamp($trendId, $submitTime, $userId = null); /** - * Return all distinct branch names of revisions producing scalars. + * Return any other scalars from the same submission as the given scalar. * - * @return array branch names + * @param Tracker_ScalarDao $scalarDao scalar DAO + * @return array scalar DAOs */ - abstract public function getDistinctBranches(); + abstract public function getOtherScalarsFromSubmission($scalarDao); /** - * Add a new scalar to the trend. If overwrite is true, and a scalar already exists on the trend with the same - * submit time and user, then this will replace that scalar. + * Add a new scalar to the trend. * * @param Tracker_TrendDao $trendDao trend DAO - * @param string $submitTime submit time - * @param string $producerRevision producer revision - * @param float $value scalar value - * @param UserDao $userDao user DAO - * @param bool $overwrite true if a scalar with the same trend, submit time, and user should be overwritten - * @param bool $official true if the submission containing the scalar should be official - * @param string $buildResultsUrl build results URL - * @param null|string $branch branch name - * @param null|string|array $params parameters - * @param null|string|array $extraUrls extra URLs - * @param null|string $reproductionCommand the command to reproduce this run + * @param Tracker_SubmissionDao $submissionDao submission DAO + * @param double $value * @return Tracker_ScalarDao scalar DAO */ - public function addToTrend( - $trendDao, - $submitTime, - $submissionId, - $producerRevision, - $value, - $userDao, - $overwrite = true, - $official = true, - $buildResultsUrl = '', - $branch = '', - $params = null, - $extraUrls = null, - $reproductionCommand = null - ) { - if ($overwrite === true) { - $scalarDao = $this->getByTrendAndTimestamp($trendDao->getKey(), $submitTime, $userDao->getKey()); - - if ($scalarDao !== false) { - $this->delete($scalarDao); - } - } - - if (empty($extraUrls)) { - $extraUrls = null; - } elseif (is_array($extraUrls)) { - $extraUrls = json_encode($extraUrls); - } - - $userId = (is_null($userDao) || $userDao === false) ? -1 : $userDao->getKey(); + public function addToTrend($trendDao, $submissionDao, $value) { /** @var Tracker_ScalarDao $scalarDao */ $scalarDao = MidasLoader::newDao('ScalarDao', $this->moduleName); - $scalarDao->setSubmissionId($submissionId); + + $scalarDao->setSubmissionId($submissionDao->getKey()); $scalarDao->setTrendId($trendDao->getKey()); - $scalarDao->setSubmitTime($submitTime); - $scalarDao->setProducerRevision($producerRevision); $scalarDao->setValue($value); - $scalarDao->setUserId($userId); - $scalarDao->setOfficial((int) $official); - $scalarDao->setBuildResultsUrl($buildResultsUrl); - $scalarDao->setBranch(trim($branch)); - $scalarDao->setExtraUrls($extraUrls); - $scalarDao->setReproductionCommand($reproductionCommand); $this->save($scalarDao); - if (!empty($params) && is_array($params)) { - $paramModel = MidasLoader::loadModel('Param', $this->moduleName); - foreach ($params as $paramName => $paramValue) { - /** @var Tracker_ParamDao $paramDao */ - $paramDao = MidasLoader::newDao('ParamDao', $this->moduleName); - $paramDao->setScalarId($scalarDao->getScalarId()); - $paramDao->setParamName($paramName); - $paramDao->setParamValue($paramValue); - $paramModel->save($paramDao); - } - } - return $scalarDao; } diff --git a/modules/tracker/models/base/SubmissionModelBase.php b/modules/tracker/models/base/SubmissionModelBase.php index 6c20d6890..5acc1551f 100644 --- a/modules/tracker/models/base/SubmissionModelBase.php +++ b/modules/tracker/models/base/SubmissionModelBase.php @@ -36,6 +36,13 @@ public function __construct() 'name' => array('type' => MIDAS_DATA), 'uuid' => array('type' => MIDAS_DATA), 'submit_time' => array('type' => MIDAS_DATA), + 'user_id' => array('type' => MIDAS_DATA), + 'official' => array('type' => MIDAS_DATA), + 'build_results_url' => array('type' => MIDAS_DATA), + 'extra_urls' => array('type' => MIDAS_DATA), + 'branch' => array('type' => MIDAS_DATA), + 'producer_revision' => array('type' => MIDAS_DATA), + 'reproduction_command' => array('type' => MIDAS_DATA), 'producer' => array( 'type' => MIDAS_MANY_TO_ONE, 'model' => 'Producer', @@ -43,6 +50,19 @@ public function __construct() 'parent_column' => 'producer_id', 'child_column' => 'producer_id', ), + 'params' => array( + 'type' => MIDAS_ONE_TO_MANY, + 'model' => 'Param', + 'module' => $this->moduleName, + 'parent_column' => 'submission_id', + 'child_column' => 'submission_id', + ), + 'user' => array( + 'type' => MIDAS_MANY_TO_ONE, + 'model' => 'User', + 'parent_column' => 'user_id', + 'child_column' => 'user_id', + ), ); $this->initialize(); @@ -63,7 +83,7 @@ abstract public function associateItem($submissionDao, $itemDao, $label); * @param Tracker_SubmissionDao $submissionDao submission DAO * @return array array of associative arrays with keys "item" and "label" */ - abstract public function getAssociatedItems($scalarDao); + abstract public function getAssociatedItems($submissionDao); /** * Create a submission. @@ -108,6 +128,14 @@ abstract public function getSubmissionsByProducer($producerDao); */ abstract public function getScalars($submissionDao, $key = false); + /** + * Return the values (trend name, value, and unit in an array) from a given submission. + * + * @param Tracker_SubmissionDao $submissionDao submission DAO + * @return array associative array with keys equal to the metric names + */ + abstract public function getValuesFromSubmission($submissionDao); + /** * Get the single latest submission associated with a given producer. * @@ -131,4 +159,11 @@ abstract public function getLatestSubmissionByProducerDateAndBranch($producerDao * @return array Tracker_TrendDaos */ abstract public function getTrends($submissionDao, $key = true); + + /** + * Return all distinct branch names of revisions producing submissions. + * + * @return array branch names + */ + abstract public function getDistinctBranches(); } diff --git a/modules/tracker/models/dao/ScalarDao.php b/modules/tracker/models/dao/ScalarDao.php index 4b053de52..08c2078d1 100644 --- a/modules/tracker/models/dao/ScalarDao.php +++ b/modules/tracker/models/dao/ScalarDao.php @@ -27,30 +27,10 @@ * @method void setSubmissionId(int $submissionId) * @method int getTrendId() * @method void setTrendId(int $trendId) - * @method int getUserId() - * @method void setUserId(int $userId) - * @method int getOfficial() - * @method void setOfficial(int $official) - * @method string getBuildResultsUrl() - * @method void setBuildResultsUrl(string $buildResultsUrl) - * @method string getParams() - * @method void setParams(string $params) - * @method string getExtraUrls() - * @method void setExtraUrls(string $extraUrls) - * @method string getBranch() - * @method void setBranch(string $branch) - * @method string getSubmitTime() - * @method void setSubmitTime(string $submitTime) * @method float getValue() * @method void setValue(float $value) - * @method string getProducerRevision() - * @method void setProducerRevision(string $producerRevision) * @method Tracker_TrendDao getTrend() * @method void setTrend(Tracker_TrendDao $trendDao) - * @method UserDao getUser() - * @method void setUser(UserDao $userDao) - * @method string getReproductionCommand() - * @method void setReproductionCommand(string $reproductionCommand) */ class Tracker_ScalarDao extends Tracker_AppDao { diff --git a/modules/tracker/models/dao/SubmissionDao.php b/modules/tracker/models/dao/SubmissionDao.php index a4c8f2e43..ddcdf6b83 100644 --- a/modules/tracker/models/dao/SubmissionDao.php +++ b/modules/tracker/models/dao/SubmissionDao.php @@ -31,6 +31,22 @@ * @method string setUuid(string $uuid) * @method array getScalars() * @method void setScalars(array $scalarDaos) + * @method int getOfficial() + * @method void setOfficial(int $official) + * @method string getBuildResultsUrl() + * @method void setBuildResultsUrl(string $buildResultsUrl) + * @method string getParams() + * @method void setParams(string $params) + * @method string getExtraUrls() + * @method void setExtraUrls(string $extraUrls) + * @method string getBranch() + * @method void setBranch(string $branch) + * @method string getSubmitTime() + * @method void setSubmitTime(string $submitTime) + * @method string getProducerRevision() + * @method void setProducerRevision(string $producerRevision) + * @method string getReproductionCommand() + * @method void setReproductionCommand(string $reproductionCommand) */ class Tracker_SubmissionDao extends Tracker_AppDao { diff --git a/modules/tracker/models/pdo/ScalarModel.php b/modules/tracker/models/pdo/ScalarModel.php index 02f6e781f..b3bae47fe 100644 --- a/modules/tracker/models/pdo/ScalarModel.php +++ b/modules/tracker/models/pdo/ScalarModel.php @@ -32,14 +32,10 @@ class Tracker_ScalarModel extends Tracker_ScalarModelBase */ public function getOtherScalarsFromSubmission($scalarDao) { - $sql = $this->database->select()->from('tracker_scalar')->join( - 'tracker_trend', - 'tracker_scalar.trend_id = tracker_trend.trend_id', - array() - )->where('tracker_scalar.submit_time = ?', $scalarDao->getSubmitTime())->where( - 'tracker_scalar.user_id = ?', - $scalarDao->getUserId() - )->where('tracker_trend.producer_id = ?', $scalarDao->getTrend()->getProducerId()); + $sql = $this->database->select()->from(array('s' => 'tracker_scalar'))->join( + array('u' => 'tracker_submission'), + 'tracker_scalar.submission_id = tracker_submission.submission_id' + )->where('s.submission_id = ?', $scalarDao->getSubmissionId()); $rows = $this->database->fetchAll($sql); $scalarDaos = array(); @@ -51,32 +47,6 @@ public function getOtherScalarsFromSubmission($scalarDao) return $scalarDaos; } - /** - * Return any other values from the same submission as the given scalar. - * - * @param Tracker_ScalarDao $scalarDao scalar DAO - * @return array associative array with keys equal to the metric names - */ - public function getOtherValuesFromSubmission($scalarDao) - { - $sql = $this->database->select()->setIntegrityCheck(false)->from(array('s' => 'tracker_scalar'))->join( - array('t' => 'tracker_trend'), - 's.trend_id = t.trend_id' - )->where('s.submit_time = ?', $scalarDao->getSubmitTime())->where( - 's.user_id = ?', - $scalarDao->getUserId() - )->where('t.producer_id = ?', $scalarDao->getTrend()->getProducerId())->order('metric_name ASC'); - $rows = $this->database->fetchAll($sql); - $scalarDaos = array(); - - /** @var Zend_Db_Table_Row_Abstract $row */ - foreach ($rows as $row) { - $scalarDaos[$row['metric_name']] = array('value' => number_format((float) $row['value'], 4, '.', ''), 'unit' => $row['unit']); - } - - return $scalarDaos; - } - /** * Delete the given scalar and any associations to items. * @@ -84,9 +54,6 @@ public function getOtherValuesFromSubmission($scalarDao) */ public function delete($scalarDao) { - $this->database->getDB()->delete('tracker_scalar2item', 'scalar_id = '.$scalarDao->getKey()); - $this->database->getDB()->delete('tracker_param', 'scalar_id = '.$scalarDao->getKey()); - parent::delete($scalarDao); } @@ -100,12 +67,13 @@ public function delete($scalarDao) */ public function getByTrendAndTimestamp($trendId, $submitTime, $userId = null) { - $sql = $this->database->select()->setIntegrityCheck(false)->where('trend_id = ?', $trendId)->where( - 'submit_time = ?', - $submitTime - ); + $sql = $this->database->select()->setIntegrityCheck(false)->from(array('s' => 'tracker_scalar'))->join( + array('u' => 'tracker_submission'), + 's.submission_id=u.submission_id' + )->where('s.trend_id = ?', $trendId + )->where('u.submit_time = ?', $submitTime); if (!is_null($userId)) { - $sql->where('user_id = ?', $userId); + $sql->where('u.user_id = ?', $userId); } return $this->initDao('Scalar', $this->database->fetchRow($sql), $this->moduleName); diff --git a/modules/tracker/models/pdo/SubmissionModel.php b/modules/tracker/models/pdo/SubmissionModel.php index 6143625e7..76099b2d8 100644 --- a/modules/tracker/models/pdo/SubmissionModel.php +++ b/modules/tracker/models/pdo/SubmissionModel.php @@ -123,6 +123,30 @@ public function getScalars($submissionDao, $key = false) return $scalarDaos; } + /** + * Return the values (trend name, value, and unit in an array) from a given submission. + * + * @param Tracker_SubmissionDao $submissionDao submission DAO + * @return array associative array with keys equal to the metric names + */ + public function getValuesFromSubmission($submissionDao) + { + $sql = $this->database->select()->setIntegrityCheck(false)->from(array('s' => 'tracker_scalar'))->join( + array('t' => 'tracker_trend'), + 's.trend_id = t.trend_id' + )->where('s.submission_id = ?', $submissionDao->getSubmissionId() + )->order('metric_name ASC'); + + $rows = $this->database->fetchAll($sql); + $scalarDaos = array(); + /** @var Zend_Db_Table_Row_Abstract $row */ + foreach ($rows as $row) { + $scalarDaos[$row['metric_name']] = array('value' => number_format((float) $row['value'], 4, '.', ''), 'unit' => $row['unit']); + } + return $scalarDaos; + } + + /** * Get submissions associated with a given producer. * @@ -269,4 +293,25 @@ public function getTrends($submissionDao, $key = true) return $trendDaos; } + + + /** + * Return all distinct branch names of revisions producing submissions. + * + * @return array branch names + */ + public function getDistinctBranches() + { + $sql = $this->database->select()->setIntegrityCheck(false)->from( + array('s' => 'tracker_submission'), + 'branch' + )->distinct(); + $rows = $this->database->fetchAll($sql); + $branches = array(); + /** @var Zend_Db_Table_Row_Abstract $row */ + foreach ($rows as $row) { + $branches[] = $row['branch']; + } + return $branches; + } } diff --git a/modules/tracker/models/pdo/TrendModel.php b/modules/tracker/models/pdo/TrendModel.php index ef8b252c6..d2e92acda 100644 --- a/modules/tracker/models/pdo/TrendModel.php +++ b/modules/tracker/models/pdo/TrendModel.php @@ -78,24 +78,26 @@ public function getMatch($producerId, $metricName, $configItemId, $testDatasetId */ public function getScalars($trendDao, $startDate = null, $endDate = null, $userId = null, $branch = null) { - $sql = $this->database->select()->setIntegrityCheck(false)->from('tracker_scalar')->where( + $sql = $this->database->select()->setIntegrityCheck(false)->from(array('s' => 'tracker_scalar') + )->join(array('u' => 'tracker_submission'), 's.submission_id = u.submission_id' + )->where( 'trend_id = ?', $trendDao->getKey() - )->order(array('submit_time ASC')); + )->order(array('u.submit_time ASC')); if (!is_null($startDate)) { - $sql->where('submit_time >= ?', $startDate); + $sql->where('u.submit_time >= ?', $startDate); } if (!is_null($endDate)) { - $sql->where('submit_time <= ?', $endDate); + $sql->where('u.submit_time <= ?', $endDate); } if (!is_null($branch)) { if (is_array($branch)) { - $sql->where('branch IN (?)', $branch); + $sql->where('u.branch IN (?)', $branch); } else { - $sql->where('branch = ?', $branch); + $sql->where('u.branch = ?', $branch); } } @@ -201,18 +203,20 @@ public function getAllByParams($params) public function getDistinctBranchesForMetricName($producerId, $metricName) { $sql = $this->database->select()->setIntegrityCheck(false)->from( - array('tracker_scalar'), + array('u' => 'tracker_submission'), 'branch' ) - ->distinct() - ->join( - 'tracker_trend', - 'tracker_scalar.trend_id = tracker_trend.trend_id', + ->distinct()->join( + array('s' => 'tracker_scalar'), + 's.submission_id = u.submission_id' + )->join( + array('t' => 'tracker_trend'), + 's.trend_id = t.trend_id', array() ) - ->where('tracker_trend.producer_id = ?', $producerId) - ->where('tracker_trend.key_metric = ?', 1) - ->where('tracker_trend.metric_name = ?', $metricName); + ->where('t.producer_id = ?', $producerId) + ->where('t.key_metric = ?', 1) + ->where('t.metric_name = ?', $metricName); $rows = $this->database->fetchAll($sql); $branches = array(); diff --git a/modules/tracker/views/scalar/details.phtml b/modules/tracker/views/scalar/details.phtml index 363ebf27e..31083ff57 100644 --- a/modules/tracker/views/scalar/details.phtml +++ b/modules/tracker/views/scalar/details.phtml @@ -41,13 +41,13 @@ Submitted: - escape($this->scalar->getSubmitTime()); ?> + escape($this->submission->getSubmitTime()); ?> submittedBy) { echo ' by '.$this->escape($this->submittedBy->getFullName()).' '; } - if (!$this->scalar->getOfficial()) { + if (!$this->submission->getOfficial()) { echo '(unofficial)'; } ?> @@ -60,21 +60,21 @@ scalar->getBranch()) { + if ($this->submission->getBranch()) { ?> Branch: - escape($this->scalar->getBranch()); ?> + escape($this->submission->getBranch()); ?> scalar->getBuildResultsUrl()) { + if ($this->submission->getBuildResultsUrl()) { ?> Build Results: Click here + href="escape($this->submission->getBuildResultsUrl()); ?>">Click here callback( 'CALLBACK_TRACKER_SCALAR_DETAIL_INFO', - array('scalar' => $this->scalar) + array('scalar' => $this->scalar, + 'submission' => $this->submission) ); /** @var string $html */ From e3002e1bff048f10c98e6252a0fd0fdd27a3bafd Mon Sep 17 00:00:00 2001 From: Patrick Reynolds Date: Wed, 16 Mar 2016 16:22:41 -0400 Subject: [PATCH 04/40] Upping version. --- modules/tracker/configs/module.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/tracker/configs/module.ini b/modules/tracker/configs/module.ini index 194489be5..dace2d381 100644 --- a/modules/tracker/configs/module.ini +++ b/modules/tracker/configs/module.ini @@ -6,4 +6,4 @@ description = "Track scalar results over time" category = "Visualization" dependencies = api,scheduler uuid = "3048a9fa-89ab-4e61-a55e-a49379fa6dc" -version = "1.2.4" +version = "2.0.0" From eb26aff5f848c421207aa984209ff766af3cd3cb Mon Sep 17 00:00:00 2001 From: Patrick Reynolds Date: Thu, 17 Mar 2016 11:40:26 -0400 Subject: [PATCH 05/40] Removing PGSQL and SQLite. Starting to fix the tests. --- .../components/ApisubmissionComponent.php | 19 +- modules/tracker/database/pgsql/1.0.0.sql | 61 ---- modules/tracker/database/pgsql/1.2.0.sql | 81 ------ modules/tracker/database/pgsql/1.2.1.sql | 82 ------ modules/tracker/database/pgsql/1.2.2.sql | 92 ------ modules/tracker/database/pgsql/1.2.3.sql | 93 ------- modules/tracker/database/pgsql/1.2.4.sql | 124 --------- modules/tracker/database/sqlite/1.2.0.sql | 80 ------ modules/tracker/database/sqlite/1.2.1.sql | 81 ------ modules/tracker/database/sqlite/1.2.2.sql | 90 ------ modules/tracker/database/sqlite/1.2.3.sql | 91 ------ modules/tracker/database/sqlite/1.2.4.sql | 122 -------- .../tests/controllers/ApiComponentTest.php | 60 ++-- .../tracker/tests/controllers/CMakeLists.txt | 6 +- .../tests/databaseDataset/aggregateMetric.xml | 262 +++++++++--------- .../tracker/tests/models/base/CMakeLists.txt | 8 +- 16 files changed, 188 insertions(+), 1164 deletions(-) delete mode 100644 modules/tracker/database/pgsql/1.0.0.sql delete mode 100644 modules/tracker/database/pgsql/1.2.0.sql delete mode 100644 modules/tracker/database/pgsql/1.2.1.sql delete mode 100644 modules/tracker/database/pgsql/1.2.2.sql delete mode 100644 modules/tracker/database/pgsql/1.2.3.sql delete mode 100644 modules/tracker/database/pgsql/1.2.4.sql delete mode 100644 modules/tracker/database/sqlite/1.2.0.sql delete mode 100644 modules/tracker/database/sqlite/1.2.1.sql delete mode 100644 modules/tracker/database/sqlite/1.2.2.sql delete mode 100644 modules/tracker/database/sqlite/1.2.3.sql delete mode 100644 modules/tracker/database/sqlite/1.2.4.sql diff --git a/modules/tracker/controllers/components/ApisubmissionComponent.php b/modules/tracker/controllers/components/ApisubmissionComponent.php index bf365eeb6..cace3c02a 100644 --- a/modules/tracker/controllers/components/ApisubmissionComponent.php +++ b/modules/tracker/controllers/components/ApisubmissionComponent.php @@ -187,24 +187,25 @@ public function post($args) $args['producer_id'] = $producerModel->getByCommunityIdAndName( $args['communityId'], $args['producerDisplayName'])->getKey(); + // Remove params from the submission args for later insertion in param table + if (isset($args['params']) && !is_null($args['params'])) { + $params = $args['params']; + unset($args['params']); + } + /** @var Tracker_SubmissionDao $submissionDao */ $submissionDao = $submissionModel->initDao('Submission', - $args, - $this->moduleName); + $args, + $this->moduleName); // Catch violation of the unique constraint. try { $submissionModel->save($submissionDao); } catch (Zend_Db_Statement_Exception $e) { - throw new Exception('That uuid is already in use.', + throw new Exception('That uuid is already in use', MIDAS_INVALID_PARAMETER); } - if (isset($args['params']) && !is_null($args['params'])) { - $params = $args['params']; - unset($args['params']); - } - if (isset($params) && is_string($params)) { $params = json_decode($params); $paramModel = MidasLoader::loadModel('Param', $this->moduleName); @@ -265,7 +266,7 @@ public function put($args) ' does not exist.', MIDAS_NOT_FOUND); } - if(isset($args['submitTime'])) { + if (isset($args['submitTime'])) { $submitTime = strtotime($args['submitTime']); if ($submitTime === false) { throw new Exception('Invalid submitTime value: ' . $args['submitTime'], -1); diff --git a/modules/tracker/database/pgsql/1.0.0.sql b/modules/tracker/database/pgsql/1.0.0.sql deleted file mode 100644 index 751055d8a..000000000 --- a/modules/tracker/database/pgsql/1.0.0.sql +++ /dev/null @@ -1,61 +0,0 @@ --- Midas Server. Copyright Kitware SAS. Licensed under the Apache License 2.0. - --- PostgreSQL database for the tracker module, version 1.0.0 - -SET client_encoding = 'UTF8'; -SET default_with_oids = FALSE; - -CREATE TABLE IF NOT EXISTS "tracker_producer" ( - "producer_id" serial PRIMARY KEY, - "community_id" bigint NOT NULL, - "repository" character varying(255) NOT NULL, - "executable_name" character varying(255) NOT NULL, - "display_name" character varying(255) NOT NULL, - "description" text NOT NULL -); - -CREATE INDEX "tracker_producer_community_id" ON "tracker_producer" ("community_id"); - -CREATE TABLE IF NOT EXISTS "tracker_scalar" ( - "scalar_id" serial PRIMARY KEY, - "trend_id" bigint NOT NULL, - value double precision, - "producer_revision" character varying(255), - "submit_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP -); - -CREATE INDEX "tracker_scalar_trend_id" ON "tracker_scalar" ("trend_id"); -CREATE INDEX "tracker_scalar_submit_time" ON "tracker_scalar" ("submit_time"); - -CREATE TABLE IF NOT EXISTS "tracker_scalar2item" ( - "id" serial PRIMARY KEY, - "scalar_id" bigint NOT NULL, - "item_id" bigint NOT NULL, - "label" character varying(255) NOT NULL -); - -CREATE INDEX "tracker_scalar2item_scalar_id" ON "tracker_scalar2item" ("scalar_id"); - -CREATE TABLE IF NOT EXISTS "tracker_threshold_notification" ( - "threshold_id" serial PRIMARY KEY, - "trend_id" bigint NOT NULL, - "value" double precision, - "comparison" character varying(2), - "action" character varying(80) NOT NULL, - "recipient_id" bigint NOT NULL -); - -CREATE INDEX "tracker_threshold_notification_trend_id" ON "tracker_threshold_notification" ("trend_id"); - -CREATE TABLE IF NOT EXISTS "tracker_trend" ( - "trend_id" serial PRIMARY KEY, - "producer_id" bigint NOT NULL, - "metric_name" character varying(255) NOT NULL, - "display_name" character varying(255) NOT NULL, - "unit" character varying(255) NOT NULL, - "config_item_id" bigint, - "test_dataset_id" bigint, - "truth_dataset_id" bigint -); - -CREATE INDEX "tracker_trend_producer_id" ON "tracker_trend" ("producer_id"); diff --git a/modules/tracker/database/pgsql/1.2.0.sql b/modules/tracker/database/pgsql/1.2.0.sql deleted file mode 100644 index deeac3f8d..000000000 --- a/modules/tracker/database/pgsql/1.2.0.sql +++ /dev/null @@ -1,81 +0,0 @@ --- Midas Server. Copyright Kitware SAS. Licensed under the Apache License 2.0. - --- PostgreSQL database for the tracker module, version 1.2.0 - -SET client_encoding = 'UTF8'; -SET default_with_oids = FALSE; - -CREATE TABLE IF NOT EXISTS "tracker_producer" ( - "producer_id" serial PRIMARY KEY, - "community_id" bigint NOT NULL, - "repository" character varying(255) NOT NULL, - "executable_name" character varying(255) NOT NULL, - "display_name" character varying(255) NOT NULL, - "description" text NOT NULL, - "revision_url" text NOT NULL -); - -CREATE INDEX "tracker_producer_community_id" ON "tracker_producer" ("community_id"); - -CREATE TABLE IF NOT EXISTS "tracker_scalar" ( - "scalar_id" serial PRIMARY KEY, - "trend_id" bigint NOT NULL, - "value" double precision, - "producer_revision" character varying(255), - "submit_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, - "user_id" bigint NOT NULL DEFAULT -1::bigint, - "submission_id" bigint NOT NULL DEFAULT -1::bigint, - "official" smallint NOT NULL DEFAULT 1::smallint, - "build_results_url" text NOT NULL, - "branch" character varying(255) NOT NULL DEFAULT ''::character varying, - "params" text, - "extra_urls" text -); - -CREATE INDEX "tracker_scalar_trend_id" ON "tracker_scalar" ("trend_id"); -CREATE INDEX "tracker_scalar_submit_time" ON "tracker_scalar" ("submit_time"); -CREATE INDEX "tracker_scalar_idx_branch" ON "tracker_scalar" ("branch"); -CREATE INDEX "tracker_scalar_idx_user_id" ON "tracker_scalar" ("user_id"); - -CREATE TABLE IF NOT EXISTS "tracker_submission" ( - "submission_id" serial PRIMARY KEY, - "producer_id" bigint, - "name" character varying(255) NOT NULL DEFAULT ''::character varying, - "uuid" character varying(255) NOT NULL DEFAULT ''::character varying, - "submit_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP -); -CREATE UNIQUE INDEX "tracker_submission_uuid" ON "tracker_submission" ("uuid"); -CREATE INDEX "tracker_submission_submit_time" ON "tracker_submission" ("submit_time"); - -CREATE TABLE IF NOT EXISTS "tracker_scalar2item" ( - "id" serial PRIMARY KEY, - "scalar_id" bigint NOT NULL, - "item_id" bigint NOT NULL, - "label" character varying(255) NOT NULL -); - -CREATE INDEX "tracker_scalar2item_scalar_id" ON "tracker_scalar2item" ("scalar_id"); - -CREATE TABLE IF NOT EXISTS "tracker_threshold_notification" ( - "threshold_id" serial PRIMARY KEY, - "trend_id" bigint NOT NULL, - "value" double precision, - "comparison" character varying(2), - "action" character varying(80) NOT NULL, - "recipient_id" bigint NOT NULL -); - -CREATE INDEX "tracker_threshold_notification_trend_id" ON "tracker_threshold_notification" ("trend_id"); - -CREATE TABLE IF NOT EXISTS "tracker_trend" ( - "trend_id" serial PRIMARY KEY, - "producer_id" bigint NOT NULL, - "metric_name" character varying(255) NOT NULL, - "display_name" character varying(255) NOT NULL, - "unit" character varying(255) NOT NULL, - "config_item_id" bigint, - "test_dataset_id" bigint, - "truth_dataset_id" bigint -); - -CREATE INDEX "tracker_trend_producer_id" ON "tracker_trend" ("producer_id"); diff --git a/modules/tracker/database/pgsql/1.2.1.sql b/modules/tracker/database/pgsql/1.2.1.sql deleted file mode 100644 index 18e09966d..000000000 --- a/modules/tracker/database/pgsql/1.2.1.sql +++ /dev/null @@ -1,82 +0,0 @@ --- Midas Server. Copyright Kitware SAS. Licensed under the Apache License 2.0. - --- PostgreSQL database for the tracker module, version 1.2.1 - -SET client_encoding = 'UTF8'; -SET default_with_oids = FALSE; - -CREATE TABLE IF NOT EXISTS "tracker_producer" ( - "producer_id" serial PRIMARY KEY, - "community_id" bigint NOT NULL, - "repository" character varying(255) NOT NULL, - "executable_name" character varying(255) NOT NULL, - "display_name" character varying(255) NOT NULL, - "description" text NOT NULL, - "revision_url" text NOT NULL -); - -CREATE INDEX "tracker_producer_community_id" ON "tracker_producer" ("community_id"); - -CREATE TABLE IF NOT EXISTS "tracker_scalar" ( - "scalar_id" serial PRIMARY KEY, - "trend_id" bigint NOT NULL, - "value" double precision, - "producer_revision" character varying(255), - "submit_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, - "user_id" bigint NOT NULL DEFAULT -1::bigint, - "submission_id" bigint NOT NULL DEFAULT -1::bigint, - "official" smallint NOT NULL DEFAULT 1::smallint, - "build_results_url" text NOT NULL, - "branch" character varying(255) NOT NULL DEFAULT ''::character varying, - "params" text, - "extra_urls" text -); - -CREATE INDEX "tracker_scalar_trend_id" ON "tracker_scalar" ("trend_id"); -CREATE INDEX "tracker_scalar_submit_time" ON "tracker_scalar" ("submit_time"); -CREATE INDEX "tracker_scalar_idx_branch" ON "tracker_scalar" ("branch"); -CREATE INDEX "tracker_scalar_idx_user_id" ON "tracker_scalar" ("user_id"); - -CREATE TABLE IF NOT EXISTS "tracker_submission" ( - "submission_id" serial PRIMARY KEY, - "producer_id" bigint, - "name" character varying(255) NOT NULL DEFAULT ''::character varying, - "uuid" character varying(255) NOT NULL DEFAULT ''::character varying, - "submit_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP -); -CREATE UNIQUE INDEX "tracker_submission_uuid" ON "tracker_submission" ("uuid"); -CREATE INDEX "tracker_submission_submit_time" ON "tracker_submission" ("submit_time"); - -CREATE TABLE IF NOT EXISTS "tracker_scalar2item" ( - "id" serial PRIMARY KEY, - "scalar_id" bigint NOT NULL, - "item_id" bigint NOT NULL, - "label" character varying(255) NOT NULL -); - -CREATE INDEX "tracker_scalar2item_scalar_id" ON "tracker_scalar2item" ("scalar_id"); - -CREATE TABLE IF NOT EXISTS "tracker_threshold_notification" ( - "threshold_id" serial PRIMARY KEY, - "trend_id" bigint NOT NULL, - "value" double precision, - "comparison" character varying(2), - "action" character varying(80) NOT NULL, - "recipient_id" bigint NOT NULL -); - -CREATE INDEX "tracker_threshold_notification_trend_id" ON "tracker_threshold_notification" ("trend_id"); - -CREATE TABLE IF NOT EXISTS "tracker_trend" ( - "trend_id" serial PRIMARY KEY, - "producer_id" bigint NOT NULL, - "metric_name" character varying(255) NOT NULL, - "display_name" character varying(255) NOT NULL, - "unit" character varying(255) NOT NULL, - "config_item_id" bigint, - "test_dataset_id" bigint, - "truth_dataset_id" bigint, - "key_metric" smallint NOT NULL DEFAULT 0::smallint -); - -CREATE INDEX "tracker_trend_producer_id" ON "tracker_trend" ("producer_id"); diff --git a/modules/tracker/database/pgsql/1.2.2.sql b/modules/tracker/database/pgsql/1.2.2.sql deleted file mode 100644 index 76d9dbe0c..000000000 --- a/modules/tracker/database/pgsql/1.2.2.sql +++ /dev/null @@ -1,92 +0,0 @@ --- Midas Server. Copyright Kitware SAS. Licensed under the Apache License 2.0. - --- PostgreSQL database for the tracker module, version 1.2.2 - -SET client_encoding = 'UTF8'; -SET default_with_oids = FALSE; - -CREATE TABLE IF NOT EXISTS "tracker_producer" ( - "producer_id" serial PRIMARY KEY, - "community_id" bigint NOT NULL, - "repository" character varying(255) NOT NULL, - "executable_name" character varying(255) NOT NULL, - "display_name" character varying(255) NOT NULL, - "description" text NOT NULL, - "revision_url" text NOT NULL -); - -CREATE INDEX "tracker_producer_community_id" ON "tracker_producer" ("community_id"); - -CREATE TABLE IF NOT EXISTS "tracker_scalar" ( - "scalar_id" serial PRIMARY KEY, - "trend_id" bigint NOT NULL, - "value" double precision, - "producer_revision" character varying(255), - "submit_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, - "user_id" bigint NOT NULL DEFAULT -1::bigint, - "submission_id" bigint NOT NULL DEFAULT -1::bigint, - "official" smallint NOT NULL DEFAULT 1::smallint, - "build_results_url" text NOT NULL, - "branch" character varying(255) NOT NULL DEFAULT ''::character varying, - "extra_urls" text -); - -CREATE INDEX "tracker_scalar_trend_id" ON "tracker_scalar" ("trend_id"); -CREATE INDEX "tracker_scalar_submit_time" ON "tracker_scalar" ("submit_time"); -CREATE INDEX "tracker_scalar_idx_branch" ON "tracker_scalar" ("branch"); -CREATE INDEX "tracker_scalar_idx_user_id" ON "tracker_scalar" ("user_id"); - -CREATE TABLE IF NOT EXISTS "tracker_submission" ( - "submission_id" serial PRIMARY KEY, - "producer_id" bigint, - "name" character varying(255) NOT NULL DEFAULT ''::character varying, - "uuid" character varying(255) NOT NULL DEFAULT ''::character varying, - "submit_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP -); -CREATE UNIQUE INDEX "tracker_submission_uuid" ON "tracker_submission" ("uuid"); -CREATE INDEX "tracker_submission_submit_time" ON "tracker_submission" ("submit_time"); - -CREATE TABLE IF NOT EXISTS "tracker_scalar2item" ( - "id" serial PRIMARY KEY, - "scalar_id" bigint NOT NULL, - "item_id" bigint NOT NULL, - "label" character varying(255) NOT NULL -); - -CREATE INDEX "tracker_scalar2item_scalar_id" ON "tracker_scalar2item" ("scalar_id"); - -CREATE TABLE IF NOT EXISTS "tracker_threshold_notification" ( - "threshold_id" serial PRIMARY KEY, - "trend_id" bigint NOT NULL, - "value" double precision, - "comparison" character varying(2), - "action" character varying(80) NOT NULL, - "recipient_id" bigint NOT NULL -); - -CREATE INDEX "tracker_threshold_notification_trend_id" ON "tracker_threshold_notification" ("trend_id"); - -CREATE TABLE IF NOT EXISTS "tracker_trend" ( - "trend_id" serial PRIMARY KEY, - "producer_id" bigint NOT NULL, - "metric_name" character varying(255) NOT NULL, - "display_name" character varying(255) NOT NULL, - "unit" character varying(255) NOT NULL, - "config_item_id" bigint, - "test_dataset_id" bigint, - "truth_dataset_id" bigint, - "key_metric" smallint NOT NULL DEFAULT 0::smallint -); - -CREATE INDEX "tracker_trend_producer_id" ON "tracker_trend" ("producer_id"); - -CREATE TABLE IF NOT EXISTS "tracker_param" ( - "param_id" serial PRIMARY KEY, - "scalar_id" bigint NOT NULL, - "param_name" character varying(255) NOT NULL, - "param_type" text CHECK (param_type IN ('text', 'numeric')), - "text_value" text, - "numeric_value" double precision -); - -CREATE INDEX "tracker_param_param_name_idx" ON "tracker_param" ("param_name"); diff --git a/modules/tracker/database/pgsql/1.2.3.sql b/modules/tracker/database/pgsql/1.2.3.sql deleted file mode 100644 index ed02a8029..000000000 --- a/modules/tracker/database/pgsql/1.2.3.sql +++ /dev/null @@ -1,93 +0,0 @@ --- Midas Server. Copyright Kitware SAS. Licensed under the Apache License 2.0. - --- PostgreSQL database for the tracker module, version 1.2.3 - -SET client_encoding = 'UTF8'; -SET default_with_oids = FALSE; - -CREATE TABLE IF NOT EXISTS "tracker_producer" ( - "producer_id" serial PRIMARY KEY, - "community_id" bigint NOT NULL, - "repository" character varying(255) NOT NULL, - "executable_name" character varying(255) NOT NULL, - "display_name" character varying(255) NOT NULL, - "description" text NOT NULL, - "revision_url" text NOT NULL -); - -CREATE INDEX "tracker_producer_community_id" ON "tracker_producer" ("community_id"); - -CREATE TABLE IF NOT EXISTS "tracker_scalar" ( - "scalar_id" serial PRIMARY KEY, - "trend_id" bigint NOT NULL, - "value" double precision, - "producer_revision" character varying(255), - "submit_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, - "user_id" bigint NOT NULL DEFAULT -1::bigint, - "submission_id" bigint NOT NULL DEFAULT -1::bigint, - "official" smallint NOT NULL DEFAULT 1::smallint, - "build_results_url" text NOT NULL, - "branch" character varying(255) NOT NULL DEFAULT ''::character varying, - "extra_urls" text, - "reproduction_command" text -); - -CREATE INDEX "tracker_scalar_trend_id" ON "tracker_scalar" ("trend_id"); -CREATE INDEX "tracker_scalar_submit_time" ON "tracker_scalar" ("submit_time"); -CREATE INDEX "tracker_scalar_idx_branch" ON "tracker_scalar" ("branch"); -CREATE INDEX "tracker_scalar_idx_user_id" ON "tracker_scalar" ("user_id"); - -CREATE TABLE IF NOT EXISTS "tracker_submission" ( - "submission_id" serial PRIMARY KEY, - "producer_id" bigint, - "name" character varying(255) NOT NULL DEFAULT ''::character varying, - "uuid" character varying(255) NOT NULL DEFAULT ''::character varying, - "submit_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP -); -CREATE UNIQUE INDEX "tracker_submission_uuid" ON "tracker_submission" ("uuid"); -CREATE INDEX "tracker_submission_submit_time" ON "tracker_submission" ("submit_time"); - -CREATE TABLE IF NOT EXISTS "tracker_scalar2item" ( - "id" serial PRIMARY KEY, - "scalar_id" bigint NOT NULL, - "item_id" bigint NOT NULL, - "label" character varying(255) NOT NULL -); - -CREATE INDEX "tracker_scalar2item_scalar_id" ON "tracker_scalar2item" ("scalar_id"); - -CREATE TABLE IF NOT EXISTS "tracker_threshold_notification" ( - "threshold_id" serial PRIMARY KEY, - "trend_id" bigint NOT NULL, - "value" double precision, - "comparison" character varying(2), - "action" character varying(80) NOT NULL, - "recipient_id" bigint NOT NULL -); - -CREATE INDEX "tracker_threshold_notification_trend_id" ON "tracker_threshold_notification" ("trend_id"); - -CREATE TABLE IF NOT EXISTS "tracker_trend" ( - "trend_id" serial PRIMARY KEY, - "producer_id" bigint NOT NULL, - "metric_name" character varying(255) NOT NULL, - "display_name" character varying(255) NOT NULL, - "unit" character varying(255) NOT NULL, - "config_item_id" bigint, - "test_dataset_id" bigint, - "truth_dataset_id" bigint, - "key_metric" smallint NOT NULL DEFAULT 0::smallint -); - -CREATE INDEX "tracker_trend_producer_id" ON "tracker_trend" ("producer_id"); - -CREATE TABLE IF NOT EXISTS "tracker_param" ( - "param_id" serial PRIMARY KEY, - "scalar_id" bigint NOT NULL, - "param_name" character varying(255) NOT NULL, - "param_type" text CHECK (param_type IN ('text', 'numeric')), - "text_value" text, - "numeric_value" double precision -); - -CREATE INDEX "tracker_param_param_name_idx" ON "tracker_param" ("param_name"); diff --git a/modules/tracker/database/pgsql/1.2.4.sql b/modules/tracker/database/pgsql/1.2.4.sql deleted file mode 100644 index 9f5d5cf15..000000000 --- a/modules/tracker/database/pgsql/1.2.4.sql +++ /dev/null @@ -1,124 +0,0 @@ --- Midas Server. Copyright Kitware SAS. Licensed under the Apache License 2.0. - --- PostgreSQL database for the tracker module, version 1.2.4 - -SET client_encoding = 'UTF8'; -SET default_with_oids = FALSE; - -CREATE TABLE IF NOT EXISTS "tracker_producer" ( - "producer_id" serial PRIMARY KEY, - "community_id" bigint NOT NULL, - "repository" character varying(255) NOT NULL, - "executable_name" character varying(255) NOT NULL, - "display_name" character varying(255) NOT NULL, - "description" text NOT NULL, - "revision_url" text NOT NULL -); - -CREATE INDEX "tracker_producer_community_id" ON "tracker_producer" ("community_id"); - -CREATE TABLE IF NOT EXISTS "tracker_scalar" ( - "scalar_id" serial PRIMARY KEY, - "trend_id" bigint NOT NULL, - "value" double precision, - "producer_revision" character varying(255), - "submit_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, - "user_id" bigint NOT NULL DEFAULT -1::bigint, - "submission_id" bigint NOT NULL DEFAULT -1::bigint, - "official" smallint NOT NULL DEFAULT 1::smallint, - "build_results_url" text NOT NULL, - "branch" character varying(255) NOT NULL DEFAULT ''::character varying, - "extra_urls" text, - "reproduction_command" text -); - -CREATE INDEX "tracker_scalar_trend_id" ON "tracker_scalar" ("trend_id"); -CREATE INDEX "tracker_scalar_submit_time" ON "tracker_scalar" ("submit_time"); -CREATE INDEX "tracker_scalar_idx_branch" ON "tracker_scalar" ("branch"); -CREATE INDEX "tracker_scalar_idx_user_id" ON "tracker_scalar" ("user_id"); - -CREATE TABLE IF NOT EXISTS "tracker_submission" ( - "submission_id" serial PRIMARY KEY, - "producer_id" bigint, - "name" character varying(255) NOT NULL DEFAULT ''::character varying, - "uuid" character varying(255) NOT NULL DEFAULT ''::character varying, - "submit_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP -); -CREATE UNIQUE INDEX "tracker_submission_uuid" ON "tracker_submission" ("uuid"); -CREATE INDEX "tracker_submission_submit_time" ON "tracker_submission" ("submit_time"); - -CREATE TABLE IF NOT EXISTS "tracker_scalar2item" ( - "id" serial PRIMARY KEY, - "scalar_id" bigint NOT NULL, - "item_id" bigint NOT NULL, - "label" character varying(255) NOT NULL -); - -CREATE INDEX "tracker_scalar2item_scalar_id" ON "tracker_scalar2item" ("scalar_id"); - -CREATE TABLE IF NOT EXISTS "tracker_threshold_notification" ( - "threshold_id" serial PRIMARY KEY, - "trend_id" bigint NOT NULL, - "value" double precision, - "comparison" character varying(2), - "action" character varying(80) NOT NULL, - "recipient_id" bigint NOT NULL -); - -CREATE INDEX "tracker_threshold_notification_trend_id" ON "tracker_threshold_notification" ("trend_id"); - -CREATE TABLE IF NOT EXISTS "tracker_trend" ( - "trend_id" serial PRIMARY KEY, - "producer_id" bigint NOT NULL, - "metric_name" character varying(255) NOT NULL, - "display_name" character varying(255) NOT NULL, - "unit" character varying(255) NOT NULL, - "config_item_id" bigint, - "test_dataset_id" bigint, - "truth_dataset_id" bigint, - "key_metric" smallint NOT NULL DEFAULT 0::smallint -); - -CREATE INDEX "tracker_trend_producer_id" ON "tracker_trend" ("producer_id"); - -CREATE TABLE IF NOT EXISTS "tracker_param" ( - "param_id" serial PRIMARY KEY, - "scalar_id" bigint NOT NULL, - "param_name" character varying(255) NOT NULL, - "param_type" text CHECK (param_type IN ('text', 'numeric')), - "text_value" text, - "numeric_value" double precision -); - -CREATE INDEX "tracker_param_param_name_idx" ON "tracker_param" ("param_name"); - -CREATE TABLE IF NOT EXISTS "tracker_aggregate_metric" ( - "aggregate_metric_id" serial PRIMARY KEY, - "aggregate_metric_spec_id" bigint NOT NULL, - "submission_id" bigint NOT NULL, - "value" double precision -); - -CREATE INDEX "tracker_aggregate_metric_aggregate_metric_spec_id" ON "tracker_aggregate_metric" ("aggregate_metric_spec_id"); -CREATE INDEX "tracker_aggregate_metric_submission_id" ON "tracker_aggregate_metric" ("submission_id"); - -CREATE TABLE IF NOT EXISTS "tracker_aggregate_metric_spec" ( - "aggregate_metric_spec_id" serial PRIMARY KEY, - "producer_id" bigint NOT NULL, - "branch" character varying(255) NOT NULL, - "name" character varying(255) NOT NULL, - "description" character varying(255) NOT NULL, - "spec" text, - "value" double precision, - "comparison" character varying(2) NOT NULL -); - -CREATE INDEX "tracker_aggregate_metric_spec_producer_id" ON "tracker_aggregate_metric_spec" ("producer_id"); -CREATE INDEX "tracker_aggregate_metric_spec_branch" ON "tracker_aggregate_metric_spec" ("branch"); - -CREATE TABLE IF NOT EXISTS "tracker_user2aggregate_metric_spec" ( - "id" serial PRIMARY KEY, - "user_id" bigint NOT NULL, - "aggregate_metric_spec_id" bigint NOT NULL, - UNIQUE ("user_id", "aggregate_metric_spec_id") -); diff --git a/modules/tracker/database/sqlite/1.2.0.sql b/modules/tracker/database/sqlite/1.2.0.sql deleted file mode 100644 index 9b4f0807b..000000000 --- a/modules/tracker/database/sqlite/1.2.0.sql +++ /dev/null @@ -1,80 +0,0 @@ --- Midas Server. Copyright Kitware SAS. Licensed under the Apache License 2.0. - --- SQLite database for the tracker module, version 1.2.0 - -CREATE TABLE IF NOT EXISTS "tracker_producer" ( - "producer_id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, - "community_id" INTEGER NOT NULL, - "repository" TEXT NOT NULL, - "executable_name" TEXT NOT NULL, - "display_name" TEXT NOT NULL, - "description" TEXT NOT NULL, - "revision_url" TEXT NOT NULL -); - -CREATE INDEX IF NOT EXISTS "tracker_producer_community_id_idx" ON "tracker_producer" ("community_id"); - -CREATE TABLE IF NOT EXISTS "tracker_scalar" ( - "scalar_id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, - "trend_id" INTEGER NOT NULL, - "value" REAL, - "producer_revision" TEXT, - "submit_time" TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP, - "user_id" INTEGER NOT NULL DEFAULT -1, - "submission_id" INTEGER NOT NULL DEFAULT -1, - "official" INTEGER NOT NULL DEFAULT 1, - "build_results_url" TEXT NOT NULL, - "branch" TEXT NOT NULL DEFAULT '', - "params" TEXT, - "extra_urls" TEXT -); - -CREATE INDEX IF NOT EXISTS "tracker_scalar_trend_id_idx" ON "tracker_scalar" ("trend_id"); -CREATE INDEX IF NOT EXISTS "tracker_scalar_submit_time_idx" ON "tracker_scalar" ("submit_time"); -CREATE INDEX IF NOT EXISTS "tracker_scalar_branch_idx" ON "tracker_scalar" ("branch"); -CREATE INDEX IF NOT EXISTS "tracker_scalar_user_id_idx" ON "tracker_scalar" ("user_id"); - - -CREATE TABLE IF NOT EXISTS "tracker_submission" ( - "submission_id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, - "producer_id" INTEGER NOT NULL, - "name" TEXT NOT NULL DEFAULT '', - "uuid" TEXT NOT NULL DEFAULT '', - "submit_time" TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP -); -CREATE UNIQUE INDEX IF NOT EXISTS "tracker_submission_uuid_idx" ON "tracker_submission" ("uuid"); -CREATE INDEX IF NOT EXISTS "tracker_submission_submit_time_idx" ON "tracker_submission" ("submit_time"); - - -CREATE TABLE IF NOT EXISTS "tracker_scalar2item" ( - "id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, - "scalar_id" INTEGER NOT NULL, - "item_id" INTEGER NOT NULL, - "label" TEXT NOT NULL -); - -CREATE INDEX IF NOT EXISTS "tracker_scalar2item_scalar_id_idx" ON "tracker_scalar2item" ("scalar_id"); - -CREATE TABLE IF NOT EXISTS "tracker_threshold_notification" ( - "threshold_id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, - "trend_id" INTEGER NOT NULL, - "value" REAL, - "comparison" TEXT, - "action" TEXT NOT NULL, - "recipient_id" INTEGER NOT NULL -); - -CREATE INDEX IF NOT EXISTS "tracker_threshold_notification_trend_id_idx" ON "tracker_threshold_notification" ("trend_id"); - -CREATE TABLE IF NOT EXISTS "tracker_trend" ( - "trend_id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, - "producer_id" INTEGER NOT NULL, - "metric_name" TEXT NOT NULL, - "display_name" TEXT NOT NULL, - "unit" TEXT NOT NULL, - "config_item_id" INTEGER, - "test_dataset_id" INTEGER, - "truth_dataset_id" INTEGER -); - -CREATE INDEX IF NOT EXISTS "tracker_trend_producer_id_idx" ON "tracker_trend" ("producer_id"); diff --git a/modules/tracker/database/sqlite/1.2.1.sql b/modules/tracker/database/sqlite/1.2.1.sql deleted file mode 100644 index bc77b7a00..000000000 --- a/modules/tracker/database/sqlite/1.2.1.sql +++ /dev/null @@ -1,81 +0,0 @@ --- Midas Server. Copyright Kitware SAS. Licensed under the Apache License 2.0. - --- SQLite database for the tracker module, version 1.2.1 - -CREATE TABLE IF NOT EXISTS "tracker_producer" ( - "producer_id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, - "community_id" INTEGER NOT NULL, - "repository" TEXT NOT NULL, - "executable_name" TEXT NOT NULL, - "display_name" TEXT NOT NULL, - "description" TEXT NOT NULL, - "revision_url" TEXT NOT NULL -); - -CREATE INDEX IF NOT EXISTS "tracker_producer_community_id_idx" ON "tracker_producer" ("community_id"); - -CREATE TABLE IF NOT EXISTS "tracker_scalar" ( - "scalar_id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, - "trend_id" INTEGER NOT NULL, - "value" REAL, - "producer_revision" TEXT, - "submit_time" TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP, - "user_id" INTEGER NOT NULL DEFAULT -1, - "submission_id" INTEGER NOT NULL DEFAULT -1, - "official" INTEGER NOT NULL DEFAULT 1, - "build_results_url" TEXT NOT NULL, - "branch" TEXT NOT NULL DEFAULT '', - "params" TEXT, - "extra_urls" TEXT -); - -CREATE INDEX IF NOT EXISTS "tracker_scalar_trend_id_idx" ON "tracker_scalar" ("trend_id"); -CREATE INDEX IF NOT EXISTS "tracker_scalar_submit_time_idx" ON "tracker_scalar" ("submit_time"); -CREATE INDEX IF NOT EXISTS "tracker_scalar_branch_idx" ON "tracker_scalar" ("branch"); -CREATE INDEX IF NOT EXISTS "tracker_scalar_user_id_idx" ON "tracker_scalar" ("user_id"); - - -CREATE TABLE IF NOT EXISTS "tracker_submission" ( - "submission_id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, - "producer_id" INTEGER NOT NULL, - "name" TEXT NOT NULL DEFAULT '', - "uuid" TEXT NOT NULL DEFAULT '', - "submit_time" TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP -); -CREATE UNIQUE INDEX IF NOT EXISTS "tracker_submission_uuid_idx" ON "tracker_submission" ("uuid"); -CREATE INDEX IF NOT EXISTS "tracker_submission_submit_time_idx" ON "tracker_submission" ("submit_time"); - - -CREATE TABLE IF NOT EXISTS "tracker_scalar2item" ( - "id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, - "scalar_id" INTEGER NOT NULL, - "item_id" INTEGER NOT NULL, - "label" TEXT NOT NULL -); - -CREATE INDEX IF NOT EXISTS "tracker_scalar2item_scalar_id_idx" ON "tracker_scalar2item" ("scalar_id"); - -CREATE TABLE IF NOT EXISTS "tracker_threshold_notification" ( - "threshold_id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, - "trend_id" INTEGER NOT NULL, - "value" REAL, - "comparison" TEXT, - "action" TEXT NOT NULL, - "recipient_id" INTEGER NOT NULL -); - -CREATE INDEX IF NOT EXISTS "tracker_threshold_notification_trend_id_idx" ON "tracker_threshold_notification" ("trend_id"); - -CREATE TABLE IF NOT EXISTS "tracker_trend" ( - "trend_id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, - "producer_id" INTEGER NOT NULL, - "metric_name" TEXT NOT NULL, - "display_name" TEXT NOT NULL, - "unit" TEXT NOT NULL, - "config_item_id" INTEGER, - "test_dataset_id" INTEGER, - "truth_dataset_id" INTEGER, - "key_metric" INTEGER NOT NULL DEFAULT 0 -); - -CREATE INDEX IF NOT EXISTS "tracker_trend_producer_id_idx" ON "tracker_trend" ("producer_id"); diff --git a/modules/tracker/database/sqlite/1.2.2.sql b/modules/tracker/database/sqlite/1.2.2.sql deleted file mode 100644 index 1857833ae..000000000 --- a/modules/tracker/database/sqlite/1.2.2.sql +++ /dev/null @@ -1,90 +0,0 @@ --- Midas Server. Copyright Kitware SAS. Licensed under the Apache License 2.0. - --- SQLite database for the tracker module, version 1.2.2 - -CREATE TABLE IF NOT EXISTS "tracker_producer" ( - "producer_id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, - "community_id" INTEGER NOT NULL, - "repository" TEXT NOT NULL, - "executable_name" TEXT NOT NULL, - "display_name" TEXT NOT NULL, - "description" TEXT NOT NULL, - "revision_url" TEXT NOT NULL -); - -CREATE INDEX IF NOT EXISTS "tracker_producer_community_id_idx" ON "tracker_producer" ("community_id"); - -CREATE TABLE IF NOT EXISTS "tracker_scalar" ( - "scalar_id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, - "trend_id" INTEGER NOT NULL, - "value" REAL, - "producer_revision" TEXT, - "submit_time" TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP, - "user_id" INTEGER NOT NULL DEFAULT -1, - "submission_id" INTEGER NOT NULL DEFAULT -1, - "official" INTEGER NOT NULL DEFAULT 1, - "build_results_url" TEXT NOT NULL, - "branch" TEXT NOT NULL DEFAULT '', - "extra_urls" TEXT -); - -CREATE INDEX IF NOT EXISTS "tracker_scalar_trend_id_idx" ON "tracker_scalar" ("trend_id"); -CREATE INDEX IF NOT EXISTS "tracker_scalar_submit_time_idx" ON "tracker_scalar" ("submit_time"); -CREATE INDEX IF NOT EXISTS "tracker_scalar_branch_idx" ON "tracker_scalar" ("branch"); -CREATE INDEX IF NOT EXISTS "tracker_scalar_user_id_idx" ON "tracker_scalar" ("user_id"); - - -CREATE TABLE IF NOT EXISTS "tracker_submission" ( - "submission_id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, - "producer_id" INTEGER NOT NULL, - "name" TEXT NOT NULL DEFAULT '', - "uuid" TEXT NOT NULL DEFAULT '', - "submit_time" TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP -); -CREATE UNIQUE INDEX IF NOT EXISTS "tracker_submission_uuid_idx" ON "tracker_submission" ("uuid"); -CREATE INDEX IF NOT EXISTS "tracker_submission_submit_time_idx" ON "tracker_submission" ("submit_time"); - - -CREATE TABLE IF NOT EXISTS "tracker_scalar2item" ( - "id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, - "scalar_id" INTEGER NOT NULL, - "item_id" INTEGER NOT NULL, - "label" TEXT NOT NULL -); - -CREATE INDEX IF NOT EXISTS "tracker_scalar2item_scalar_id_idx" ON "tracker_scalar2item" ("scalar_id"); - -CREATE TABLE IF NOT EXISTS "tracker_threshold_notification" ( - "threshold_id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, - "trend_id" INTEGER NOT NULL, - "value" REAL, - "comparison" TEXT, - "action" TEXT NOT NULL, - "recipient_id" INTEGER NOT NULL -); - -CREATE INDEX IF NOT EXISTS "tracker_threshold_notification_trend_id_idx" ON "tracker_threshold_notification" ("trend_id"); - -CREATE TABLE IF NOT EXISTS "tracker_trend" ( - "trend_id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, - "producer_id" INTEGER NOT NULL, - "metric_name" TEXT NOT NULL, - "display_name" TEXT NOT NULL, - "unit" TEXT NOT NULL, - "config_item_id" INTEGER, - "test_dataset_id" INTEGER, - "truth_dataset_id" INTEGER, - "key_metric" INTEGER NOT NULL DEFAULT 0 -); - -CREATE INDEX IF NOT EXISTS "tracker_trend_producer_id_idx" ON "tracker_trend" ("producer_id"); - -CREATE TABLE IF NOT EXISTS "tracker_param" ( - "param_id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, - "scalar_id" INTEGER NOT NULL, - "param_name" TEXT NOT NULL, - "param_type" TEXT CHECK( param_type in ('text', 'numeric') ) NOT NULL, - "text_value" text, - "numeric_value" REAL -); -CREATE INDEX IF NOT EXISTS "tracker_param_param_name" ON "tracker_param" ("param_name"); diff --git a/modules/tracker/database/sqlite/1.2.3.sql b/modules/tracker/database/sqlite/1.2.3.sql deleted file mode 100644 index cfdfc1e2f..000000000 --- a/modules/tracker/database/sqlite/1.2.3.sql +++ /dev/null @@ -1,91 +0,0 @@ --- Midas Server. Copyright Kitware SAS. Licensed under the Apache License 2.0. - --- SQLite database for the tracker module, version 1.2.3 - -CREATE TABLE IF NOT EXISTS "tracker_producer" ( - "producer_id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, - "community_id" INTEGER NOT NULL, - "repository" TEXT NOT NULL, - "executable_name" TEXT NOT NULL, - "display_name" TEXT NOT NULL, - "description" TEXT NOT NULL, - "revision_url" TEXT NOT NULL -); - -CREATE INDEX IF NOT EXISTS "tracker_producer_community_id_idx" ON "tracker_producer" ("community_id"); - -CREATE TABLE IF NOT EXISTS "tracker_scalar" ( - "scalar_id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, - "trend_id" INTEGER NOT NULL, - "value" REAL, - "producer_revision" TEXT, - "submit_time" TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP, - "user_id" INTEGER NOT NULL DEFAULT -1, - "submission_id" INTEGER NOT NULL DEFAULT -1, - "official" INTEGER NOT NULL DEFAULT 1, - "build_results_url" TEXT NOT NULL, - "branch" TEXT NOT NULL DEFAULT '', - "extra_urls" TEXT, - "reproduction_command" TEXT -); - -CREATE INDEX IF NOT EXISTS "tracker_scalar_trend_id_idx" ON "tracker_scalar" ("trend_id"); -CREATE INDEX IF NOT EXISTS "tracker_scalar_submit_time_idx" ON "tracker_scalar" ("submit_time"); -CREATE INDEX IF NOT EXISTS "tracker_scalar_branch_idx" ON "tracker_scalar" ("branch"); -CREATE INDEX IF NOT EXISTS "tracker_scalar_user_id_idx" ON "tracker_scalar" ("user_id"); - - -CREATE TABLE IF NOT EXISTS "tracker_submission" ( - "submission_id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, - "producer_id" INTEGER NOT NULL, - "name" TEXT NOT NULL DEFAULT '', - "uuid" TEXT NOT NULL DEFAULT '', - "submit_time" TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP -); -CREATE UNIQUE INDEX IF NOT EXISTS "tracker_submission_uuid_idx" ON "tracker_submission" ("uuid"); -CREATE INDEX IF NOT EXISTS "tracker_submission_submit_time_idx" ON "tracker_submission" ("submit_time"); - - -CREATE TABLE IF NOT EXISTS "tracker_scalar2item" ( - "id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, - "scalar_id" INTEGER NOT NULL, - "item_id" INTEGER NOT NULL, - "label" TEXT NOT NULL -); - -CREATE INDEX IF NOT EXISTS "tracker_scalar2item_scalar_id_idx" ON "tracker_scalar2item" ("scalar_id"); - -CREATE TABLE IF NOT EXISTS "tracker_threshold_notification" ( - "threshold_id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, - "trend_id" INTEGER NOT NULL, - "value" REAL, - "comparison" TEXT, - "action" TEXT NOT NULL, - "recipient_id" INTEGER NOT NULL -); - -CREATE INDEX IF NOT EXISTS "tracker_threshold_notification_trend_id_idx" ON "tracker_threshold_notification" ("trend_id"); - -CREATE TABLE IF NOT EXISTS "tracker_trend" ( - "trend_id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, - "producer_id" INTEGER NOT NULL, - "metric_name" TEXT NOT NULL, - "display_name" TEXT NOT NULL, - "unit" TEXT NOT NULL, - "config_item_id" INTEGER, - "test_dataset_id" INTEGER, - "truth_dataset_id" INTEGER, - "key_metric" INTEGER NOT NULL DEFAULT 0 -); - -CREATE INDEX IF NOT EXISTS "tracker_trend_producer_id_idx" ON "tracker_trend" ("producer_id"); - -CREATE TABLE IF NOT EXISTS "tracker_param" ( - "param_id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, - "scalar_id" INTEGER NOT NULL, - "param_name" TEXT NOT NULL, - "param_type" TEXT CHECK( param_type in ('text', 'numeric') ) NOT NULL, - "text_value" text, - "numeric_value" REAL -); -CREATE INDEX IF NOT EXISTS "tracker_param_param_name" ON "tracker_param" ("param_name"); diff --git a/modules/tracker/database/sqlite/1.2.4.sql b/modules/tracker/database/sqlite/1.2.4.sql deleted file mode 100644 index fdec8a76e..000000000 --- a/modules/tracker/database/sqlite/1.2.4.sql +++ /dev/null @@ -1,122 +0,0 @@ --- Midas Server. Copyright Kitware SAS. Licensed under the Apache License 2.0. - --- SQLite database for the tracker module, version 1.2.4 - -CREATE TABLE IF NOT EXISTS "tracker_producer" ( - "producer_id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, - "community_id" INTEGER NOT NULL, - "repository" TEXT NOT NULL, - "executable_name" TEXT NOT NULL, - "display_name" TEXT NOT NULL, - "description" TEXT NOT NULL, - "revision_url" TEXT NOT NULL -); - -CREATE INDEX IF NOT EXISTS "tracker_producer_community_id_idx" ON "tracker_producer" ("community_id"); - -CREATE TABLE IF NOT EXISTS "tracker_scalar" ( - "scalar_id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, - "trend_id" INTEGER NOT NULL, - "value" REAL, - "producer_revision" TEXT, - "submit_time" TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP, - "user_id" INTEGER NOT NULL DEFAULT -1, - "submission_id" INTEGER NOT NULL DEFAULT -1, - "official" INTEGER NOT NULL DEFAULT 1, - "build_results_url" TEXT NOT NULL, - "branch" TEXT NOT NULL DEFAULT '', - "extra_urls" TEXT, - "reproduction_command" TEXT -); - -CREATE INDEX IF NOT EXISTS "tracker_scalar_trend_id_idx" ON "tracker_scalar" ("trend_id"); -CREATE INDEX IF NOT EXISTS "tracker_scalar_submit_time_idx" ON "tracker_scalar" ("submit_time"); -CREATE INDEX IF NOT EXISTS "tracker_scalar_branch_idx" ON "tracker_scalar" ("branch"); -CREATE INDEX IF NOT EXISTS "tracker_scalar_user_id_idx" ON "tracker_scalar" ("user_id"); - - -CREATE TABLE IF NOT EXISTS "tracker_submission" ( - "submission_id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, - "producer_id" INTEGER NOT NULL, - "name" TEXT NOT NULL DEFAULT '', - "uuid" TEXT NOT NULL DEFAULT '', - "submit_time" TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP -); -CREATE UNIQUE INDEX IF NOT EXISTS "tracker_submission_uuid_idx" ON "tracker_submission" ("uuid"); -CREATE INDEX IF NOT EXISTS "tracker_submission_submit_time_idx" ON "tracker_submission" ("submit_time"); - - -CREATE TABLE IF NOT EXISTS "tracker_scalar2item" ( - "id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, - "scalar_id" INTEGER NOT NULL, - "item_id" INTEGER NOT NULL, - "label" TEXT NOT NULL -); - -CREATE INDEX IF NOT EXISTS "tracker_scalar2item_scalar_id_idx" ON "tracker_scalar2item" ("scalar_id"); - -CREATE TABLE IF NOT EXISTS "tracker_threshold_notification" ( - "threshold_id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, - "trend_id" INTEGER NOT NULL, - "value" REAL, - "comparison" TEXT, - "action" TEXT NOT NULL, - "recipient_id" INTEGER NOT NULL -); - -CREATE INDEX IF NOT EXISTS "tracker_threshold_notification_trend_id_idx" ON "tracker_threshold_notification" ("trend_id"); - -CREATE TABLE IF NOT EXISTS "tracker_trend" ( - "trend_id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, - "producer_id" INTEGER NOT NULL, - "metric_name" TEXT NOT NULL, - "display_name" TEXT NOT NULL, - "unit" TEXT NOT NULL, - "config_item_id" INTEGER, - "test_dataset_id" INTEGER, - "truth_dataset_id" INTEGER, - "key_metric" INTEGER NOT NULL DEFAULT 0 -); - -CREATE INDEX IF NOT EXISTS "tracker_trend_producer_id_idx" ON "tracker_trend" ("producer_id"); - -CREATE TABLE IF NOT EXISTS "tracker_param" ( - "param_id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, - "scalar_id" INTEGER NOT NULL, - "param_name" TEXT NOT NULL, - "param_type" TEXT CHECK( param_type in ('text', 'numeric') ) NOT NULL, - "text_value" text, - "numeric_value" REAL -); -CREATE INDEX IF NOT EXISTS "tracker_param_param_name" ON "tracker_param" ("param_name"); - -CREATE TABLE IF NOT EXISTS "tracker_aggregate_metric" ( - "aggregate_metric_id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, - "aggregate_metric_spec_id" INTEGER NOT NULL, - "submission_id" INTEGER NOT NULL, - "value" REAL -); - -CREATE INDEX IF NOT EXISTS "tracker_aggregate_metric_aggregate_metric_spec_id" ON "tracker_aggregate_metric" ("aggregate_metric_spec_id"); -CREATE INDEX IF NOT EXISTS "tracker_aggregate_metric_submission_id" ON "tracker_aggregate_metric" ("submission_id"); - -CREATE TABLE IF NOT EXISTS "tracker_aggregate_metric_spec" ( - "aggregate_metric_spec_id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, - "producer_id" INTEGER NOT NULL, - "branch" TEXT NOT NULL, - "name" TEXT NOT NULL, - "description" TEXT NOT NULL, - "spec" TEXT NOT NULL, - "value" REAL, - "comparison" TEXT NOT NULL -); - -CREATE INDEX IF NOT EXISTS "tracker_aggregate_metric_spec_producer_id" ON "tracker_aggregate_metric_spec" ("producer_id"); -CREATE INDEX IF NOT EXISTS "tracker_aggregate_metric_spec_branch" ON "tracker_aggregate_metric_spec" ("branch"); - -CREATE TABLE IF NOT EXISTS "tracker_user2aggregate_metric_spec" ( - "id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, - "user_id" INTEGER NOT NULL, - "aggregate_metric_spec_id" INTEGER NOT NULL, - UNIQUE ("user_id", "aggregate_metric_spec_id") -); diff --git a/modules/tracker/tests/controllers/ApiComponentTest.php b/modules/tracker/tests/controllers/ApiComponentTest.php index 64753d5de..4548b842a 100644 --- a/modules/tracker/tests/controllers/ApiComponentTest.php +++ b/modules/tracker/tests/controllers/ApiComponentTest.php @@ -35,14 +35,6 @@ public function setUp() $this->enabledModules = array('api', 'scheduler', $this->moduleName); $this->_models = array('Assetstore', 'Community', 'Setting', 'User'); - $db = Zend_Registry::get('dbAdapter'); - $configDatabase = Zend_Registry::get('configDatabase'); - if ($configDatabase->database->adapter == 'PDO_PGSQL') { - $db->query("SELECT setval('tracker_trend_trend_id_seq', (SELECT MAX(trend_id) FROM tracker_trend)+1);"); - $db->query("SELECT setval('tracker_submission_submission_id_seq', (SELECT MAX(submission_id) FROM tracker_submission)+1);"); - $db->query("SELECT setval('tracker_scalar_scalar_id_seq', (SELECT MAX(scalar_id) FROM tracker_scalar)+1);"); - } - ControllerTestCase::setUp(); } @@ -55,21 +47,33 @@ public function testUploadScalarWithSubmission() { $uuidComponent = MidasLoader::loadComponent('Uuid'); $uuid = $uuidComponent->generate(); + $uuid2 = $uuidComponent->generate(); + $uuid3 = $uuidComponent->generate(); $token = $this->_loginAsAdministrator(); - $outputs = array(); - $outputs['metric_0'] = $this->_submitScalar($token, $uuid, 'metric_0', '18'); $metric1Params = array('num_param' => 19.0, 'text_param' => 'metric1 text', 'null_param' => null); - $outputs['metric_1'] = $this->_submitScalar($token, $uuid, 'metric_1', '19', 'meters', $metric1Params); $metric2Params = array('num_param' => 20.0, 'text_param' => 'metric2 text', 'null_param' => null); - $outputs['metric_2'] = $this->_submitScalar($token, $uuid, 'metric_2', '20', 'mm', $metric2Params); + $this->_submitSubmission($token, $uuid); + $this->_submitSubmission($token, $uuid2, $metric1Params); + $this->_submitSubmission($token, $uuid3, $metric2Params); + $outputs = array(); + $outputs['metric_0'] = $this->_submitScalar($token, $uuid, 'metric_0', '18'); + $outputs['metric_1'] = $this->_submitScalar($token, $uuid2, 'metric_1', '19', 'meters'); + $outputs['metric_2'] = $this->_submitScalar($token, $uuid3, 'metric_2', '20', 'mm'); /** @var Tracker_SubmissionModel $submissionModel */ $submissionModel = MidasLoader::loadModel('Submission', 'tracker'); /** @var Tracker_SubmissionDao $submissionDao */ $submissionDao = $submissionModel->getSubmission($uuid); + + /** @var Tracker_SubmissionDao $submissionDao2 */ + $submissionDao2 = $submissionModel->getSubmission($uuid2); + + /** @var Tracker_SubmissionDao $submissionDao3 */ + $submissionDao3 = $submissionModel->getSubmission($uuid3); + $scalarDaos = $submissionModel->getScalars($submissionDao); // Maps the scalars for each metric. @@ -84,9 +88,9 @@ public function testUploadScalarWithSubmission() } // Params should be a zero element array here. - $this->assertTrue(!($metricToScalar['metric_0']->getParams())); + $this->assertTrue(!($submissionDao->getParams())); - $metric1Params = $metricToScalar['metric_1']->getParams(); + $metric1Params = $submissionDao2->getParams(); $metric1ParamChecks = array( 'num_param' => array('found' => false, 'type' => 'numeric', 'val' => 19.0), 'text_param' => array('found' => false, 'type' => 'text', 'val' => 'metric1 text'), @@ -110,7 +114,7 @@ public function testUploadScalarWithSubmission() $this->assertTrue($checks['found']); } - $metric2Params = $metricToScalar['metric_2']->getParams(); + $metric2Params = $submissionDao3->getParams(); $metric2ParamChecks = array( 'num_param' => array('found' => false, 'type' => 'numeric', 'val' => 20.0), 'text_param' => array('found' => false, 'type' => 'text', 'val' => 'metric2 text'), @@ -152,7 +156,6 @@ private function _submitScalar($token, $uuid, $metric, $value, $unit = false, $s $this->params['method'] = 'midas.tracker.scalar.add'; $this->params['token'] = $token; $this->params['communityId'] = '2000'; - $this->params['producerDisplayName'] = 'Test Producer'; $this->params['metricName'] = $metric; $this->params['value'] = $value; $this->params['producerRevision'] = 'deadbeef'; @@ -169,6 +172,23 @@ private function _submitScalar($token, $uuid, $metric, $value, $unit = false, $s return $res->data; } + private function _submitSubmission($token, $uuid, $params = false) + { + $this->resetAll(); + $this->params['method'] = 'midas.tracker.submission.add'; + $this->params['token'] = $token; + $this->params['communityId'] = '2000'; + $this->params['producerDisplayName'] = 'Test Producer'; + $this->params['producerRevision'] = 'deadbeef'; + $this->params['submitTime'] = 'now'; + $this->params['uuid'] = $uuid; + if ($params !== false) { + $this->params['params'] = json_encode($params); + } + $res = $this->_callJsonApi(); + return $res->data; + } + /** * Test listing the branch names tied to a producer and trend metric_name. * @@ -225,16 +245,16 @@ public function testAggregatemetricsUpdate() /** @var Tracker_TrendDao $greedyError1TrendDao */ $greedyError1TrendDao = $trendModel->load(1); - $scalarModel->addToTrend($greedyError1TrendDao, 'now', $submissionDao->getSubmissionId(), 'deadbeef', 101, $userDao, false, false, 'url', 'master'); + $scalarModel->addToTrend($greedyError1TrendDao, $submissionDao, 101); /** @var Tracker_TrendDao $greedyError2TrendDao */ $greedyError2TrendDao = $trendModel->load(2); - $scalarModel->addToTrend($greedyError2TrendDao, 'now', $submissionDao->getSubmissionId(), 'deadbeef', 102, $userDao, false, false, 'url', 'master'); + $scalarModel->addToTrend($greedyError2TrendDao, $submissionDao, 102); /** @var Tracker_TrendDao $greedyError3TrendDao */ $greedyError3TrendDao = $trendModel->load(3); - $scalarModel->addToTrend($greedyError3TrendDao, 'now', $submissionDao->getSubmissionId(), 'deadbeef', 103, $userDao, false, false, 'url', 'master'); + $scalarModel->addToTrend($greedyError3TrendDao, $submissionDao, 103); /** @var Tracker_TrendDao $greedyError4TrendDao */ $greedyError4TrendDao = $trendModel->load(4); - $scalarModel->addToTrend($greedyError4TrendDao, 'now', $submissionDao->getSubmissionId(), 'deadbeef', 104, $userDao, false, false, 'url', 'master'); + $scalarModel->addToTrend($greedyError4TrendDao, $submissionDao, 104); // Get existing aggregate metrics for this submission, there should be 0. diff --git a/modules/tracker/tests/controllers/CMakeLists.txt b/modules/tracker/tests/controllers/CMakeLists.txt index 72750b1d5..885228d77 100644 --- a/modules/tracker/tests/controllers/CMakeLists.txt +++ b/modules/tracker/tests/controllers/CMakeLists.txt @@ -20,6 +20,6 @@ set(module_name tracker) to_titlecase(${module_name} module_name_titlecase) -add_midas_test(${module_name_titlecase}ApiComponent ApiComponentTest.php) -add_midas_test(${module_name_titlecase}ApiAggregatemetricspecComponent ApiAggregatemetricspecComponentTest.php) -add_midas_test(${module_name_titlecase}ApiScalarComponent ApiScalarComponentTest.php) +add_midas_mysql_test(${module_name_titlecase}ApiComponent ApiComponentTest.php) +add_midas_mysql_test(${module_name_titlecase}ApiAggregatemetricspecComponent ApiAggregatemetricspecComponentTest.php) +add_midas_mysql_test(${module_name_titlecase}ApiScalarComponent ApiScalarComponentTest.php) diff --git a/modules/tracker/tests/databaseDataset/aggregateMetric.xml b/modules/tracker/tests/databaseDataset/aggregateMetric.xml index 2154557f5..dc7f9e6c2 100644 --- a/modules/tracker/tests/databaseDataset/aggregateMetric.xml +++ b/modules/tracker/tests/databaseDataset/aggregateMetric.xml @@ -92,155 +92,155 @@ test_dataset_id="1020" truth_dataset_id="1002" unit="mm" key_metric="1" /> - - + + - - - - - + + + + + /> - + - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + - - + + - - - - + + + + - - - - + + + + - - - - + + + + - - - - + + + + - - - - + + + + - - - - + + + + - - - - + + + + - - - - + + + + - - - - + + + + - - - - + + + + - + diff --git a/modules/tracker/tests/models/base/CMakeLists.txt b/modules/tracker/tests/models/base/CMakeLists.txt index bfad46de1..0f29e9f38 100644 --- a/modules/tracker/tests/models/base/CMakeLists.txt +++ b/modules/tracker/tests/models/base/CMakeLists.txt @@ -20,7 +20,7 @@ set(module_name tracker) to_titlecase(${module_name} module_name_titlecase) -add_midas_test(${module_name_titlecase}AggregateMetricModel AggregateMetricModelTest.php) -add_midas_test(${module_name_titlecase}AggregateMetricSpecModel AggregateMetricSpecModelTest.php) -add_midas_test(${module_name_titlecase}ScalarModel ScalarModelTest.php) -add_midas_test(${module_name_titlecase}TrendModel TrendModelTest.php) +add_midas_mysql_test(${module_name_titlecase}AggregateMetricModel AggregateMetricModelTest.php) +add_midas_mysql_test(${module_name_titlecase}AggregateMetricSpecModel AggregateMetricSpecModelTest.php) +add_midas_mysql_test(${module_name_titlecase}ScalarModel ScalarModelTest.php) +add_midas_mysql_test(${module_name_titlecase}TrendModel TrendModelTest.php) From 041ab15fa5b78614bcbb149a3645c9bccdd3f1f1 Mon Sep 17 00:00:00 2001 From: Patrick Reynolds Date: Thu, 17 Mar 2016 11:43:16 -0400 Subject: [PATCH 06/40] Applied fixes from StyleCI --- modules/tracker/controllers/components/ApiComponent.php | 2 +- .../controllers/components/ApisubmissionComponent.php | 2 +- modules/tracker/models/base/ScalarModelBase.php | 7 ++++--- modules/tracker/models/pdo/ScalarModel.php | 1 - modules/tracker/models/pdo/SubmissionModel.php | 4 ++-- modules/tracker/tests/controllers/ApiComponentTest.php | 1 + 6 files changed, 9 insertions(+), 8 deletions(-) diff --git a/modules/tracker/controllers/components/ApiComponent.php b/modules/tracker/controllers/components/ApiComponent.php index 36c14c747..263a896f4 100644 --- a/modules/tracker/controllers/components/ApiComponent.php +++ b/modules/tracker/controllers/components/ApiComponent.php @@ -56,7 +56,7 @@ private function _getUser($args) } /** - * Associate a result item with a particular submission + * Associate a result item with a particular submission. * * @param submissionId the submission to associate the item with * @param itemId The id of the item to associate with the scalar diff --git a/modules/tracker/controllers/components/ApisubmissionComponent.php b/modules/tracker/controllers/components/ApisubmissionComponent.php index cace3c02a..48ea11394 100644 --- a/modules/tracker/controllers/components/ApisubmissionComponent.php +++ b/modules/tracker/controllers/components/ApisubmissionComponent.php @@ -269,7 +269,7 @@ public function put($args) if (isset($args['submitTime'])) { $submitTime = strtotime($args['submitTime']); if ($submitTime === false) { - throw new Exception('Invalid submitTime value: ' . $args['submitTime'], -1); + throw new Exception('Invalid submitTime value: '.$args['submitTime'], -1); } $submitTime = date('Y-m-d H:i:s', $submitTime); $args['submitTime'] = $submitTime; diff --git a/modules/tracker/models/base/ScalarModelBase.php b/modules/tracker/models/base/ScalarModelBase.php index 07d4a7b5f..94801be43 100644 --- a/modules/tracker/models/base/ScalarModelBase.php +++ b/modules/tracker/models/base/ScalarModelBase.php @@ -48,7 +48,7 @@ public function __construct() 'module' => $this->moduleName, 'parent_column' => 'submission_id', 'child_column' => 'submission_id', - ) + ), ); $this->initialize(); @@ -77,10 +77,11 @@ abstract public function getOtherScalarsFromSubmission($scalarDao); * * @param Tracker_TrendDao $trendDao trend DAO * @param Tracker_SubmissionDao $submissionDao submission DAO - * @param double $value + * @param float $value * @return Tracker_ScalarDao scalar DAO */ - public function addToTrend($trendDao, $submissionDao, $value) { + public function addToTrend($trendDao, $submissionDao, $value) + { /** @var Tracker_ScalarDao $scalarDao */ $scalarDao = MidasLoader::newDao('ScalarDao', $this->moduleName); diff --git a/modules/tracker/models/pdo/ScalarModel.php b/modules/tracker/models/pdo/ScalarModel.php index b3bae47fe..2cd61c4a7 100644 --- a/modules/tracker/models/pdo/ScalarModel.php +++ b/modules/tracker/models/pdo/ScalarModel.php @@ -23,7 +23,6 @@ /** Scalar model for the tracker module. */ class Tracker_ScalarModel extends Tracker_ScalarModelBase { - /** * Return any other scalars from the same submission as the given scalar. * diff --git a/modules/tracker/models/pdo/SubmissionModel.php b/modules/tracker/models/pdo/SubmissionModel.php index 76099b2d8..bfad3e3b8 100644 --- a/modules/tracker/models/pdo/SubmissionModel.php +++ b/modules/tracker/models/pdo/SubmissionModel.php @@ -143,10 +143,10 @@ public function getValuesFromSubmission($submissionDao) foreach ($rows as $row) { $scalarDaos[$row['metric_name']] = array('value' => number_format((float) $row['value'], 4, '.', ''), 'unit' => $row['unit']); } + return $scalarDaos; } - /** * Get submissions associated with a given producer. * @@ -294,7 +294,6 @@ public function getTrends($submissionDao, $key = true) return $trendDaos; } - /** * Return all distinct branch names of revisions producing submissions. * @@ -312,6 +311,7 @@ public function getDistinctBranches() foreach ($rows as $row) { $branches[] = $row['branch']; } + return $branches; } } diff --git a/modules/tracker/tests/controllers/ApiComponentTest.php b/modules/tracker/tests/controllers/ApiComponentTest.php index 4548b842a..f8d488323 100644 --- a/modules/tracker/tests/controllers/ApiComponentTest.php +++ b/modules/tracker/tests/controllers/ApiComponentTest.php @@ -186,6 +186,7 @@ private function _submitSubmission($token, $uuid, $params = false) $this->params['params'] = json_encode($params); } $res = $this->_callJsonApi(); + return $res->data; } From ec6b465de1f09a38e11975877c1ccd8fd2314ae0 Mon Sep 17 00:00:00 2001 From: Patrick Reynolds Date: Thu, 17 Mar 2016 12:29:41 -0400 Subject: [PATCH 07/40] Fixing some more tests. --- modules/tracker/models/pdo/AggregateMetricModel.php | 13 +++++++++---- modules/tracker/models/pdo/TrendModel.php | 4 ++-- .../tracker/tests/controllers/ApiComponentTest.php | 1 + 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/modules/tracker/models/pdo/AggregateMetricModel.php b/modules/tracker/models/pdo/AggregateMetricModel.php index 30227ac52..a44f8d83c 100644 --- a/modules/tracker/models/pdo/AggregateMetricModel.php +++ b/modules/tracker/models/pdo/AggregateMetricModel.php @@ -105,10 +105,15 @@ public function getAggregateMetricInputValuesForSubmission($aggregateMetricSpecD // Get all the scalar values from these trends in the submission. $sql = $this->database->select()->setIntegrityCheck(false) - ->from('tracker_scalar', array('value')) - ->where('submission_id = ?', $submissionDao->getSubmissionId()) - ->where('branch = ?', $aggregateMetricSpecDao->getBranch()) - ->where('trend_id IN (?)', $trendIds); + ->from('tracker_scalar') + ->join( + 'tracker_submission', + 'tracker_scalar.submission_id = tracker_submission.submission_id', + array() + ) + ->where('tracker_submission.submission_id = ?', $submissionDao->getSubmissionId()) + ->where('tracker_submission.branch = ?', $aggregateMetricSpecDao->getBranch()) + ->where('tracker_scalar.trend_id IN (?)', $trendIds); $rows = $this->database->fetchAll($sql); if (count($rows) === 0) { return false; diff --git a/modules/tracker/models/pdo/TrendModel.php b/modules/tracker/models/pdo/TrendModel.php index d2e92acda..43ac51208 100644 --- a/modules/tracker/models/pdo/TrendModel.php +++ b/modules/tracker/models/pdo/TrendModel.php @@ -206,7 +206,7 @@ public function getDistinctBranchesForMetricName($producerId, $metricName) array('u' => 'tracker_submission'), 'branch' ) - ->distinct()->join( + ->join( array('s' => 'tracker_scalar'), 's.submission_id = u.submission_id' )->join( @@ -216,7 +216,7 @@ public function getDistinctBranchesForMetricName($producerId, $metricName) ) ->where('t.producer_id = ?', $producerId) ->where('t.key_metric = ?', 1) - ->where('t.metric_name = ?', $metricName); + ->where('t.metric_name = ?', $metricName)->group('branch'); $rows = $this->database->fetchAll($sql); $branches = array(); diff --git a/modules/tracker/tests/controllers/ApiComponentTest.php b/modules/tracker/tests/controllers/ApiComponentTest.php index f8d488323..242e364bc 100644 --- a/modules/tracker/tests/controllers/ApiComponentTest.php +++ b/modules/tracker/tests/controllers/ApiComponentTest.php @@ -271,6 +271,7 @@ public function testAggregatemetricsUpdate() $this->params['token'] = $token; $this->params['uuid'] = $uuid; $resp = $this->_callJsonApi(); + var_dump($resp); $aggregateMetrics = array(); /** stdClass $aggregateMetricStdClass */ foreach ($resp->data as $aggregateMetricStdClass) { From 210a8ea740ded0bac49ef2e8fd057151367c07ab Mon Sep 17 00:00:00 2001 From: Patrick Reynolds Date: Fri, 18 Mar 2016 13:13:34 -0400 Subject: [PATCH 08/40] Fix the tracker tests. --- .../models/base/SubmissionModelBase.php | 3 +- .../models/pdo/AggregateMetricModel.php | 4 +- .../tracker/models/pdo/SubmissionModel.php | 32 +++- .../ApiAggregatemetricspecComponentTest.php | 7 +- .../tests/controllers/ApiComponentTest.php | 19 ++- .../controllers/ApiScalarComponentTest.php | 114 ------------- .../tracker/tests/controllers/CMakeLists.txt | 1 - .../models/base/AggregateMetricModelTest.php | 35 ++-- .../tracker/tests/models/base/CMakeLists.txt | 1 + .../tests/models/base/ScalarModelTest.php | 105 +----------- .../tests/models/base/SubmissionModelTest.php | 156 ++++++++++++++++++ 11 files changed, 230 insertions(+), 247 deletions(-) delete mode 100644 modules/tracker/tests/controllers/ApiScalarComponentTest.php create mode 100644 modules/tracker/tests/models/base/SubmissionModelTest.php diff --git a/modules/tracker/models/base/SubmissionModelBase.php b/modules/tracker/models/base/SubmissionModelBase.php index 5acc1551f..eaa5821bc 100644 --- a/modules/tracker/models/base/SubmissionModelBase.php +++ b/modules/tracker/models/base/SubmissionModelBase.php @@ -91,9 +91,10 @@ abstract public function getAssociatedItems($submissionDao); * @param Tracker_ProducerDao $producerDao the producer to which the submission was submitted * @param string $uuid the uuid of the submission * @param string $name the name of the submission (defaults to '') + * @param array $params the parameters used to generate the submission (defaults to null) * @return Tracker_SubmissionDao */ - abstract public function createSubmission($producerDao, $uuid, $name = ''); + abstract public function createSubmission($producerDao, $uuid, $name = '', $params = null); /** * Get a submission from its uuid. diff --git a/modules/tracker/models/pdo/AggregateMetricModel.php b/modules/tracker/models/pdo/AggregateMetricModel.php index a44f8d83c..7c21b877a 100644 --- a/modules/tracker/models/pdo/AggregateMetricModel.php +++ b/modules/tracker/models/pdo/AggregateMetricModel.php @@ -111,11 +111,11 @@ public function getAggregateMetricInputValuesForSubmission($aggregateMetricSpecD 'tracker_scalar.submission_id = tracker_submission.submission_id', array() ) - ->where('tracker_submission.submission_id = ?', $submissionDao->getSubmissionId()) + ->where('tracker_submission.submission_id = ?', $submissionDao->getKey()) ->where('tracker_submission.branch = ?', $aggregateMetricSpecDao->getBranch()) ->where('tracker_scalar.trend_id IN (?)', $trendIds); $rows = $this->database->fetchAll($sql); - if (count($rows) === 0) { + if (count($rows) === 0) { return false; }; $values = array(); diff --git a/modules/tracker/models/pdo/SubmissionModel.php b/modules/tracker/models/pdo/SubmissionModel.php index bfad3e3b8..71d9641fc 100644 --- a/modules/tracker/models/pdo/SubmissionModel.php +++ b/modules/tracker/models/pdo/SubmissionModel.php @@ -79,9 +79,10 @@ function ($a, $b) { * @param Tracker_ProducerDao $producerDao the producer to which the submission was submitted * @param string $uuid the uuid of the submission * @param string $name the name of the submission (defaults to '') - * @return void + * @param array $params the parameters used to generate the submission (defaults to null) + * @return Tracker_SubmissionDao */ - public function createSubmission($producerDao, $uuid, $name = '') + public function createSubmission($producerDao, $uuid, $name = '', $params = null) { $data = array( 'producer_id' => $producerDao->getKey(), @@ -89,6 +90,19 @@ public function createSubmission($producerDao, $uuid, $name = '') 'name' => $name, ); $this->database->getDB()->insert('tracker_submission', $data); + $submissionDao = $this->getSubmission($uuid); + if (!empty($params) && is_array($params)) { + $paramModel = MidasLoader::loadModel('Param', $this->moduleName); + foreach ($params as $paramName => $paramValue) { + /** @var Tracker_ParamDao $paramDao */ + $paramDao = MidasLoader::newDao('ParamDao', $this->moduleName); + $paramDao->setSubmissionId($submissionDao->getKey()); + $paramDao->setParamName($paramName); + $paramDao->setParamValue($paramValue); + $paramModel->save($paramDao); + } + } + return $submissionDao; } /** @@ -314,4 +328,18 @@ public function getDistinctBranches() return $branches; } + + + /** + * Delete a given submission + * + * @param Tracker_SubmissionDao $submissionDao + */ + public function delete($submissionDao) + { + $this->database->getDB()->delete('tracker_submission2item', 'submission_id = '.$submissionDao->getKey()); + $this->database->getDB()->delete('tracker_param', 'submission_id = '.$submissionDao->getKey()); + + parent::delete($submissionDao); + } } diff --git a/modules/tracker/tests/controllers/ApiAggregatemetricspecComponentTest.php b/modules/tracker/tests/controllers/ApiAggregatemetricspecComponentTest.php index 448751d2f..da02cb30d 100644 --- a/modules/tracker/tests/controllers/ApiAggregatemetricspecComponentTest.php +++ b/modules/tracker/tests/controllers/ApiAggregatemetricspecComponentTest.php @@ -32,12 +32,7 @@ public function setUp() $this->_models = array('Assetstore', 'Community', 'Setting', 'User'); $this->setupDatabase(array('default')); $this->setupDatabase(array('aggregateMetric'), 'tracker'); - $db = Zend_Registry::get('dbAdapter'); - $configDatabase = Zend_Registry::get('configDatabase'); - if ($configDatabase->database->adapter == 'PDO_PGSQL') { - $db->query("SELECT setval('tracker_aggregate_metric_spec_aggregate_metric_spec_id_seq', (SELECT MAX(aggregate_metric_spec_id) FROM tracker_aggregate_metric_spec)+1);"); - $db->query("SELECT setval('tracker_scalar_scalar_id_seq', (SELECT MAX(scalar_id) FROM tracker_scalar)+1);"); - } + ControllerTestCase::setUp(); } diff --git a/modules/tracker/tests/controllers/ApiComponentTest.php b/modules/tracker/tests/controllers/ApiComponentTest.php index 242e364bc..1a9b7894c 100644 --- a/modules/tracker/tests/controllers/ApiComponentTest.php +++ b/modules/tracker/tests/controllers/ApiComponentTest.php @@ -137,6 +137,11 @@ public function testUploadScalarWithSubmission() foreach ($metric2ParamChecks as $checks) { $this->assertTrue($checks['found']); } + + // clean up + $submissionModel->delete($submissionDao); + $submissionModel->delete($submissionDao2); + $submissionModel->delete($submissionDao3); } /** @@ -230,6 +235,8 @@ public function testAggregatemetricsUpdate() $submissionModel->createSubmission($producerDao, $uuid, 'Tmp submission'); /** @var Tracker_SubmissionDao $submissionDao */ $submissionDao = $submissionModel->getSubmission($uuid); + $submissionDao->setBranch('master'); + $submissionModel->save($submissionDao); // Create 4 scalars on the submission. @@ -244,18 +251,21 @@ public function testAggregatemetricsUpdate() /** @var UserDao $userDao */ $userDao = $authComponent->getUser(array('token' => $token), null); + /** @var array $scalars */ + $scalars = array(); + /** @var Tracker_TrendDao $greedyError1TrendDao */ $greedyError1TrendDao = $trendModel->load(1); - $scalarModel->addToTrend($greedyError1TrendDao, $submissionDao, 101); + $scalars[] = $scalarModel->addToTrend($greedyError1TrendDao, $submissionDao, 101); /** @var Tracker_TrendDao $greedyError2TrendDao */ $greedyError2TrendDao = $trendModel->load(2); - $scalarModel->addToTrend($greedyError2TrendDao, $submissionDao, 102); + $scalars[] = $scalarModel->addToTrend($greedyError2TrendDao, $submissionDao, 102); /** @var Tracker_TrendDao $greedyError3TrendDao */ $greedyError3TrendDao = $trendModel->load(3); - $scalarModel->addToTrend($greedyError3TrendDao, $submissionDao, 103); + $scalars[] = $scalarModel->addToTrend($greedyError3TrendDao, $submissionDao, 103); /** @var Tracker_TrendDao $greedyError4TrendDao */ $greedyError4TrendDao = $trendModel->load(4); - $scalarModel->addToTrend($greedyError4TrendDao, $submissionDao, 104); + $scalars[] = $scalarModel->addToTrend($greedyError4TrendDao, $submissionDao, 104); // Get existing aggregate metrics for this submission, there should be 0. @@ -271,7 +281,6 @@ public function testAggregatemetricsUpdate() $this->params['token'] = $token; $this->params['uuid'] = $uuid; $resp = $this->_callJsonApi(); - var_dump($resp); $aggregateMetrics = array(); /** stdClass $aggregateMetricStdClass */ foreach ($resp->data as $aggregateMetricStdClass) { diff --git a/modules/tracker/tests/controllers/ApiScalarComponentTest.php b/modules/tracker/tests/controllers/ApiScalarComponentTest.php deleted file mode 100644 index 19f3fee4d..000000000 --- a/modules/tracker/tests/controllers/ApiScalarComponentTest.php +++ /dev/null @@ -1,114 +0,0 @@ -enabledModules = array('api', 'scheduler', $this->moduleName); - $this->_models = array('Assetstore', 'Community', 'Setting', 'User'); - $this->setupDatabase(array('default')); - $this->setupDatabase(array('default'), 'tracker'); - - $db = Zend_Registry::get('dbAdapter'); - $configDatabase = Zend_Registry::get('configDatabase'); - if ($configDatabase->database->adapter == 'PDO_PGSQL') { - $db->query("SELECT setval('tracker_aggregate_metric_spec_aggregate_metric_spec_id_seq', (SELECT MAX(aggregate_metric_spec_id) FROM tracker_aggregate_metric_spec)+1);"); - $db->query("SELECT setval('tracker_scalar_scalar_id_seq', (SELECT MAX(scalar_id) FROM tracker_scalar)+1);"); - } - - ControllerTestCase::setUp(); - } - - /** - * Test updating an existing scalar with a set of params, via PUT. - * - * @throws Zend_Exception - */ - public function testPUT() - { - $usersFile = $this->loadData('User', 'default'); - /** @var UserDao $userDao */ - $userDao = $this->User->load($usersFile[0]->getKey()); - - // Create a scalar attached to a trend. - /** @var Tracker_TrendModel $trendModel */ - $trendModel = MidasLoader::loadModel('Trend', 'tracker'); - /** @var Tracker_TrendDao $trend */ - $trend = $trendModel->load(1001); - - /** @var Tracker_ScalarModel $scalarModel */ - $scalarModel = MidasLoader::loadModel('Scalar', 'tracker'); - $scalarArgs = array( - 'trend_id' => $trend->getTrendId(), - 'value' => 42, - 'build_results_url' => 'http://localhost', - ); - /** @var Tracker_ScalarDao $scalar */ - $scalar = $scalarModel->initDao('Scalar', $scalarArgs, $this->moduleName); - $scalarModel->save($scalar); - - $token = $this->_loginAsAdministrator(); - - $params = array( - 'num_param' => 90, - 'text_param' => 'master', - 'null_param' => '', - ); - $restParams = array( - 'trend_id' => $trend->getTrendId(), - 'params' => json_encode($params), - 'token' => $token, - ); - - $this->resetAll(); - $this->params = $restParams; - $resp = $this->_callRestApi('PUT', '/tracker/scalar/'.$scalar->getScalarId()); - - // Ensure params are properly set on scalar. - $paramChecks = array( - 'num_param' => array('found' => false, 'type' => 'numeric', 'val' => 90), - 'text_param' => array('found' => false, 'type' => 'text', 'val' => 'master'), - 'null_param' => array('found' => false, 'type' => 'text', 'val' => ''), - ); - - /** @var Tracker_ParamModel $param */ - foreach ($scalar->getParams() as $param) { - $checks = $paramChecks[$param->getParamName()]; - $this->assertEquals($checks['type'], $param->getParamType()); - if ($checks['type'] === 'numeric') { - $this->assertEquals($checks['val'], $param->getNumericValue()); - } else { - $this->assertEquals($checks['val'], $param->getTextValue()); - } - $paramChecks[$param->getParamName()]['found'] = true; - } - - foreach ($paramChecks as $checks) { - $this->assertTrue($checks['found']); - } - } -} diff --git a/modules/tracker/tests/controllers/CMakeLists.txt b/modules/tracker/tests/controllers/CMakeLists.txt index 885228d77..12d58629e 100644 --- a/modules/tracker/tests/controllers/CMakeLists.txt +++ b/modules/tracker/tests/controllers/CMakeLists.txt @@ -22,4 +22,3 @@ to_titlecase(${module_name} module_name_titlecase) add_midas_mysql_test(${module_name_titlecase}ApiComponent ApiComponentTest.php) add_midas_mysql_test(${module_name_titlecase}ApiAggregatemetricspecComponent ApiAggregatemetricspecComponentTest.php) -add_midas_mysql_test(${module_name_titlecase}ApiScalarComponent ApiScalarComponentTest.php) diff --git a/modules/tracker/tests/models/base/AggregateMetricModelTest.php b/modules/tracker/tests/models/base/AggregateMetricModelTest.php index 83699c699..b4c35b0b8 100644 --- a/modules/tracker/tests/models/base/AggregateMetricModelTest.php +++ b/modules/tracker/tests/models/base/AggregateMetricModelTest.php @@ -27,24 +27,33 @@ public function setUp() $this->setupDatabase(array('default')); // core dataset $this->setupDatabase(array('aggregateMetric'), 'tracker'); // module dataset $this->enabledModules = array('tracker'); - $db = Zend_Registry::get('dbAdapter'); - $configDatabase = Zend_Registry::get('configDatabase'); - if ($configDatabase->database->adapter == 'PDO_PGSQL') { - $db->query("SELECT setval('tracker_aggregate_metric_spec_aggregate_metric_spec_id_seq', (SELECT MAX(aggregate_metric_spec_id) FROM tracker_aggregate_metric_spec)+1);"); - $db->query("SELECT setval('tracker_aggregate_metric_aggregate_metric_id_seq', (SELECT MAX(aggregate_metric_id) FROM tracker_aggregate_metric)+1);"); - $db->query("SELECT setval('tracker_trend_trend_id_seq', (SELECT MAX(trend_id) FROM tracker_trend)+1);"); - $db->query("SELECT setval('tracker_scalar_scalar_id_seq', (SELECT MAX(scalar_id) FROM tracker_scalar)+1);"); - } + parent::setUp(); } /** createAdditionalGreedyErrorSubmission1Scalars testing utility function. */ protected function createAdditionalGreedyErrorSubmission1Scalars() { + /** @var Tracker_ProducerModel $producerModel */ + $producerModel = MidasLoader::loadModel('Producer', 'tracker'); /** @var Tracker_TrendModel $trendModel */ $trendModel = MidasLoader::loadModel('Trend', 'tracker'); /** @var Tracker_ScalarModel $scalarModel */ $scalarModel = MidasLoader::loadModel('Scalar', 'tracker'); + /** @var Tracker_SubmissionModel $submissionModel */ + $submissionModel = MidasLoader::loadModel('Submission', 'tracker'); + + $producerDao = $producerModel->load(100); + + $submissionDao = $submissionModel->load(1); + $submissionDao->setSubmitTime(date('Y-m-d', time())); + $submissionDao->setProducerRevision(1); + + $submissionDao->setUserId(1); + $submissionDao->setOfficial((int) true); + $submissionDao->setBuildResultsUrl('build.results.url'); + $submissionDao->setBranch('master'); + $submissionModel->save($submissionDao); $extraTrends = array(); /** @var int $i */ @@ -55,15 +64,9 @@ protected function createAdditionalGreedyErrorSubmission1Scalars() $trendModel->save($trendDao); /** @var Tracker_ScalarDao $scalarDao */ $scalarDao = MidasLoader::newDao('ScalarDao', 'tracker'); - $scalarDao->setSubmissionId(1); + $scalarDao->setSubmissionId($submissionDao->getKey()); $scalarDao->setTrendId($trendDao->getKey()); - $scalarDao->setSubmitTime(date('Y-m-d', time())); - $scalarDao->setProducerRevision(1); $scalarDao->setValue(21.0 + $i); - $scalarDao->setUserId(1); - $scalarDao->setOfficial((int) true); - $scalarDao->setBuildResultsUrl('build.results.url'); - $scalarDao->setBranch('master'); $scalarModel->save($scalarDao); $extraTrends[] = $trendDao; } @@ -94,8 +97,6 @@ public function testGetAggregateMetricInputValuesForSubmission() /** @var AggregateMetricModel $aggregateMetricModel */ $aggregateMetricModel = MidasLoader::loadModel('AggregateMetric', 'tracker'); - /** @var Tracker_ProducerDao $producer100Dao */ - $producer100Dao = $producerModel->load(100); /** @var Tracker_SubmissionDao $submission1Dao */ $submission1Dao = $submissionModel->load(1); /** @var Tracker_SubmissionDao $submission2Dao */ diff --git a/modules/tracker/tests/models/base/CMakeLists.txt b/modules/tracker/tests/models/base/CMakeLists.txt index 0f29e9f38..f696365fb 100644 --- a/modules/tracker/tests/models/base/CMakeLists.txt +++ b/modules/tracker/tests/models/base/CMakeLists.txt @@ -23,4 +23,5 @@ to_titlecase(${module_name} module_name_titlecase) add_midas_mysql_test(${module_name_titlecase}AggregateMetricModel AggregateMetricModelTest.php) add_midas_mysql_test(${module_name_titlecase}AggregateMetricSpecModel AggregateMetricSpecModelTest.php) add_midas_mysql_test(${module_name_titlecase}ScalarModel ScalarModelTest.php) +add_midas_mysql_test(${module_name_titlecase}SubmissionModel SubmissionModelTest.php) add_midas_mysql_test(${module_name_titlecase}TrendModel TrendModelTest.php) diff --git a/modules/tracker/tests/models/base/ScalarModelTest.php b/modules/tracker/tests/models/base/ScalarModelTest.php index ec8e4e829..709241def 100644 --- a/modules/tracker/tests/models/base/ScalarModelTest.php +++ b/modules/tracker/tests/models/base/ScalarModelTest.php @@ -27,12 +27,7 @@ public function setUp() $this->setupDatabase(array('default')); // core dataset $this->setupDatabase(array('default'), 'tracker'); // module dataset $this->enabledModules = array('tracker'); - $db = Zend_Registry::get('dbAdapter'); - $configDatabase = Zend_Registry::get('configDatabase'); - if ($configDatabase->database->adapter == 'PDO_PGSQL') { - $db->query("SELECT setval('tracker_submission_submission_id_seq', (SELECT MAX(submission_id) FROM tracker_submission)+1);"); - $db->query("SELECT setval('tracker_scalar_scalar_id_seq', (SELECT MAX(scalar_id) FROM tracker_scalar)+1);"); - } + parent::setUp(); } @@ -42,10 +37,6 @@ public function testScalarModel() /** @var UuidComponent $uuidComponent */ $uuidComponent = MidasLoader::loadComponent('Uuid'); - $communityId = '2000'; - $producerDisplayName = 'Test Producer'; - $producerRevision = 'deadbeef'; - $submitTime = 'now'; $submissionUuid = $uuidComponent->generate(); /** @var UserModel $userModel */ @@ -83,40 +74,10 @@ public function testScalarModel() /** @var Tracker_ScalarDao $scalarDao0 */ $scalarDao0 = $scalarModel->addToTrend( $metricTrend0, - $submitTime, - $submissionId, - $producerRevision, - $scalarValue0, - $userDao, - true, - true, - 'http://buildresultsurl', - 'master', - $params0); - - // Ensure value and params are properly set on scalar. - $paramChecks = array( - 'num_param' => array('found' => false, 'type' => 'numeric', 'val' => 90), - 'text_param' => array('found' => false, 'type' => 'text', 'val' => 'master'), - 'emptystring_param' => array('found' => false, 'type' => 'text', 'val' => ''), - 'null_param' => array('found' => false, 'type' => 'text', 'val' => ''), + $submissionDao, + $scalarValue0 ); - $scalarDao0Params = $scalarDao0->getParams(); - foreach ($scalarDao0Params as $param) { - $checks = $paramChecks[$param->getParamName()]; - $this->assertEquals($checks['type'], $param->getParamType()); - if ($checks['type'] === 'numeric') { - $this->assertEquals($checks['val'], $param->getNumericValue()); - } else { - $this->assertEquals($checks['val'], $param->getTextValue()); - } - $paramChecks[$param->getParamName()]['found'] = true; - } - - foreach ($paramChecks as $checks) { - $this->assertTrue($checks['found']); - } $this->assertEquals($scalarDao0->getValue(), $scalarValue0); @@ -124,68 +85,14 @@ public function testScalarModel() /** @var Tracker_TrendDao $metricTrend1 */ $metricTrend1 = $trendModel->load(1002); $scalarValue1 = 1; - $params1 = array( - 'num_param' => 92, - 'text_param' => 'dev', - 'null_param' => null, - 'emptystring_param' => '', - ); + /** @var Tracker_ScalarDao $scalarDao1 */ $scalarDao1 = $scalarModel->addToTrend( $metricTrend1, - $submitTime, - $submissionId, - $producerRevision, - $scalarValue1, - $userDao, - true, - true, - 'http://buildresultsurl', - 'dev', - $params1); - - // Ensure value and params are properly set on scalar. - $paramChecks = array( - 'num_param' => array('found' => false, 'type' => 'numeric', 'val' => 92), - 'text_param' => array('found' => false, 'type' => 'text', 'val' => 'dev'), - 'emptystring_param' => array('found' => false, 'type' => 'text', 'val' => ''), - 'null_param' => array('found' => false, 'type' => 'text', 'val' => ''), + $submissionDao, + $scalarValue1 ); - $scalarDao1Params = $scalarDao1->getParams(); - /** @var Tracker_ParamModel $param */ - foreach ($scalarDao1Params as $param) { - $checks = $paramChecks[$param->getParamName()]; - $this->assertEquals($checks['type'], $param->getParamType()); - if ($checks['type'] === 'numeric') { - $this->assertEquals($checks['val'], $param->getNumericValue()); - } else { - $this->assertEquals($checks['val'], $param->getTextValue()); - } - $paramChecks[$param->getParamName()]['found'] = true; - } - - foreach ($paramChecks as $checks) { - $this->assertTrue($checks['found']); - } - $this->assertEquals($scalarDao1->getValue(), $scalarValue1); - - // Delete scalars and ensure params are deleted. - $scalarModel->delete($scalarDao0); - $scalarModel->delete($scalarDao1); - - /** @var Tracker_ParamModel $paramModel */ - $paramModel = MidasLoader::loadModel('Param', 'tracker'); - /** @var Tracker_ParamModel $scalarParam */ - foreach ($scalarDao0Params as $scalarParam) { - $scalarParamReloaded = $paramModel->load($scalarParam->getParamId()); - $this->assertFalse($scalarParamReloaded, 'Scalar param should have been deleted'); - } - /** @var Tracker_ParamModel $scalarParam */ - foreach ($scalarDao1Params as $scalarParam) { - $scalarParamReloaded = $paramModel->load($scalarParam->getParamId()); - $this->assertFalse($scalarParamReloaded, 'Scalar param should have been deleted'); - } } } diff --git a/modules/tracker/tests/models/base/SubmissionModelTest.php b/modules/tracker/tests/models/base/SubmissionModelTest.php new file mode 100644 index 000000000..1ec2d0879 --- /dev/null +++ b/modules/tracker/tests/models/base/SubmissionModelTest.php @@ -0,0 +1,156 @@ +setupDatabase(array('default')); // core dataset + $this->setupDatabase(array('default'), 'tracker'); // module dataset + $this->enabledModules = array('tracker'); + + parent::setUp(); + } + + /** testScalarModel */ + public function testSubmissionModel() + { + /** @var Tracker_ParamModel $paramModel */ + $paramModel = MidasLoader::loadModel('Param', 'tracker'); + + /** @var Tracker_SubmissionModel $submissionModel */ + $submissionModel = MidasLoader::loadModel('Submission', 'tracker'); + + /** @var Tracker_ProducerModel $producerModel */ + $producerModel = MidasLoader::loadModel('Producer', 'tracker'); + + /** @var UuidComponent $uuidComponent */ + $uuidComponent = MidasLoader::loadComponent('Uuid'); + + /** @var UserModel $userModel */ + $userModel = MidasLoader::loadModel('User'); + $usersFile = $this->loadData('User', 'default'); + /** @var UserDao $userDao */ + $userDao = $userModel->load($usersFile[0]->getKey()); + + + /** @var Tracker_ProducerDao $producerDao */ + $producerDao = $producerModel->load(100); + + $producerRevision = 'deadbeef'; + $uuid0 = $uuidComponent->generate(); + $uuid1 = $uuidComponent->generate(); + + $params0 = array( + 'num_param_subtest' => 90, + 'text_param_subtest' => 'master', + 'emptystring_param_subtest' => '', + 'null_param_subtest' => null, + ); + /** @var Tracker_SubmissionDao $submissionDao0 */ + $submissionDao0 = $submissionModel->createSubmission($producerDao, $uuid0, '', $params0); + $submissionDao0->setProducerRevision($producerRevision); + $submissionDao0->setUserId($userDao->getKey()); + $submissionDao0->setBuildResultsUrl('http://buildresultsurl'); + $submissionDao0->setBranch('master'); + $submissionModel->save($submissionDao0); + + // Ensure value and params are properly set on scalar. + $paramChecks = array( + 'num_param_subtest' => array('found' => false, 'type' => 'numeric', 'val' => 90), + 'text_param_subtest' => array('found' => false, 'type' => 'text', 'val' => 'master'), + 'emptystring_param_subtest' => array('found' => false, 'type' => 'text', 'val' => ''), + 'null_param_subtest' => array('found' => false, 'type' => 'text', 'val' => ''), + ); + + $submissionDao0Params = $submissionDao0->getParams(); + var_dump($submissionDao0Params); + foreach ($submissionDao0Params as $param) { + $checks = $paramChecks[$param->getParamName()]; + $this->assertEquals($checks['type'], $param->getParamType()); + if ($checks['type'] === 'numeric') { + $this->assertEquals($checks['val'], $param->getNumericValue()); + } else { + $this->assertEquals($checks['val'], $param->getTextValue()); + } + $paramChecks[$param->getParamName()]['found'] = true; + } + + foreach ($paramChecks as $checks) { + $this->assertTrue($checks['found']); + } + + $params1 = array( + 'num_param_subtest' => 92, + 'text_param_subtest' => 'dev', + 'null_param_subtest' => null, + 'emptystring_param_subtest' => '', + ); + /** @var Tracker_SubmissionDao $submissionDao0 */ + $submissionDao1 = $submissionModel->createSubmission($producerDao, $uuid1, '', $params1); + $submissionDao1->setProducerRevision($producerRevision); + $submissionDao1->setUserId($userDao->getKey()); + $submissionDao1->setBuildResultsUrl('http://buildresultsurl'); + $submissionDao1->setBranch('dev'); + $submissionModel->save($submissionDao1); + + // Ensure value and params are properly set on scalar. + $paramChecks = array( + 'num_param_subtest' => array('found' => false, 'type' => 'numeric', 'val' => 92), + 'text_param_subtest' => array('found' => false, 'type' => 'text', 'val' => 'dev'), + 'emptystring_param_subtest' => array('found' => false, 'type' => 'text', 'val' => ''), + 'null_param_subtest' => array('found' => false, 'type' => 'text', 'val' => ''), + ); + + $submissionDao1Params = $submissionDao1->getParams(); + /** @var Tracker_ParamModel $param */ + foreach ($submissionDao1Params as $param) { + $checks = $paramChecks[$param->getParamName()]; + $this->assertEquals($checks['type'], $param->getParamType()); + if ($checks['type'] === 'numeric') { + $this->assertEquals($checks['val'], $param->getNumericValue()); + } else { + $this->assertEquals($checks['val'], $param->getTextValue()); + } + $paramChecks[$param->getParamName()]['found'] = true; + } + + foreach ($paramChecks as $checks) { + $this->assertTrue($checks['found']); + } + + // Delete scalars and ensure params are deleted. + $submissionModel->delete($submissionDao0); + $submissionModel->delete($submissionDao1); + + /** @var Tracker_ParamModel $submissionParam */ + foreach ($submissionDao0Params as $submissionParam) { + $submissionParamReloaded = $paramModel->load($submissionParam->getParamId()); + $this->assertFalse($submissionParamReloaded, 'Submission param 0 should have been deleted'); + } + /** @var Tracker_ParamModel $submissionParam */ + foreach ($submissionDao1Params as $submissionParam) { + $submissionParamReloaded = $paramModel->load($submissionParam->getParamId()); + $this->assertFalse($submissionParamReloaded, 'Submission param 2 should have been deleted'); + } + } +} From 3ca6379062f25c57111b847d4c487a245bd8ea61 Mon Sep 17 00:00:00 2001 From: Patrick Reynolds Date: Fri, 18 Mar 2016 13:15:01 -0400 Subject: [PATCH 09/40] Applied fixes from StyleCI --- modules/tracker/models/pdo/AggregateMetricModel.php | 2 +- modules/tracker/models/pdo/SubmissionModel.php | 4 ++-- modules/tracker/tests/models/base/ScalarModelTest.php | 1 - modules/tracker/tests/models/base/SubmissionModelTest.php | 1 - 4 files changed, 3 insertions(+), 5 deletions(-) diff --git a/modules/tracker/models/pdo/AggregateMetricModel.php b/modules/tracker/models/pdo/AggregateMetricModel.php index 7c21b877a..7fa35d92a 100644 --- a/modules/tracker/models/pdo/AggregateMetricModel.php +++ b/modules/tracker/models/pdo/AggregateMetricModel.php @@ -115,7 +115,7 @@ public function getAggregateMetricInputValuesForSubmission($aggregateMetricSpecD ->where('tracker_submission.branch = ?', $aggregateMetricSpecDao->getBranch()) ->where('tracker_scalar.trend_id IN (?)', $trendIds); $rows = $this->database->fetchAll($sql); - if (count($rows) === 0) { + if (count($rows) === 0) { return false; }; $values = array(); diff --git a/modules/tracker/models/pdo/SubmissionModel.php b/modules/tracker/models/pdo/SubmissionModel.php index 71d9641fc..9ca94dc65 100644 --- a/modules/tracker/models/pdo/SubmissionModel.php +++ b/modules/tracker/models/pdo/SubmissionModel.php @@ -102,6 +102,7 @@ public function createSubmission($producerDao, $uuid, $name = '', $params = null $paramModel->save($paramDao); } } + return $submissionDao; } @@ -329,9 +330,8 @@ public function getDistinctBranches() return $branches; } - /** - * Delete a given submission + * Delete a given submission. * * @param Tracker_SubmissionDao $submissionDao */ diff --git a/modules/tracker/tests/models/base/ScalarModelTest.php b/modules/tracker/tests/models/base/ScalarModelTest.php index 709241def..49063fdc5 100644 --- a/modules/tracker/tests/models/base/ScalarModelTest.php +++ b/modules/tracker/tests/models/base/ScalarModelTest.php @@ -78,7 +78,6 @@ public function testScalarModel() $scalarValue0 ); - $this->assertEquals($scalarDao0->getValue(), $scalarValue0); // Scalar the second. diff --git a/modules/tracker/tests/models/base/SubmissionModelTest.php b/modules/tracker/tests/models/base/SubmissionModelTest.php index 1ec2d0879..bec727aba 100644 --- a/modules/tracker/tests/models/base/SubmissionModelTest.php +++ b/modules/tracker/tests/models/base/SubmissionModelTest.php @@ -52,7 +52,6 @@ public function testSubmissionModel() /** @var UserDao $userDao */ $userDao = $userModel->load($usersFile[0]->getKey()); - /** @var Tracker_ProducerDao $producerDao */ $producerDao = $producerModel->load(100); From 42b6e616084beb82aa309e84144ddd2bbad0a1ef Mon Sep 17 00:00:00 2001 From: Patrick Reynolds Date: Sat, 19 Mar 2016 01:44:33 -0400 Subject: [PATCH 10/40] Some api fixes for submission. --- .../controllers/components/ApisubmissionComponent.php | 10 +++++----- modules/tracker/models/dao/ScalarDao.php | 1 + 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/modules/tracker/controllers/components/ApisubmissionComponent.php b/modules/tracker/controllers/components/ApisubmissionComponent.php index 48ea11394..d76610b21 100644 --- a/modules/tracker/controllers/components/ApisubmissionComponent.php +++ b/modules/tracker/controllers/components/ApisubmissionComponent.php @@ -170,20 +170,20 @@ public function post($args) } if (isset($args['extraUrls'])) { - $args['extraUrls'] = json_decode($args['extraUrls'], true); + $args['extra_urls'] = json_decode($args['extraUrls'], true); } - $args['buildResultsUrl'] = isset($args['buildResultsUrl']) ? $args['buildResultsUrl'] : ''; + $args['build_results_url'] = isset($args['buildResultsUrl']) ? $args['buildResultsUrl'] : ''; $args['branch'] = isset($args['branch']) ? $args['branch'] : ''; - $args['reproductionCommand'] = isset($args['reproductionCommand']) ? $args['reproductionCommand'] : ''; + $args['reproduction_command'] = isset($args['reproductionCommand']) ? $args['reproductionCommand'] : ''; $submitTime = strtotime($args['submitTime']); if ($submitTime === false) { throw new Exception('Invalid submitTime value: '.$args['submitTime'], -1); } $submitTime = date('Y-m-d H:i:s', $submitTime); - $args['submitTime'] = $submitTime; - $args['producerRevision'] = trim($args['producerRevision']); + $args['submit_time'] = $submitTime; + $args['producer_revision'] = trim($args['producerRevision']); $args['producer_id'] = $producerModel->getByCommunityIdAndName( $args['communityId'], $args['producerDisplayName'])->getKey(); diff --git a/modules/tracker/models/dao/ScalarDao.php b/modules/tracker/models/dao/ScalarDao.php index 08c2078d1..2e2d46a91 100644 --- a/modules/tracker/models/dao/ScalarDao.php +++ b/modules/tracker/models/dao/ScalarDao.php @@ -25,6 +25,7 @@ * @method void setScalarId(int $scalarId) * @method int getSubmissionId() * @method void setSubmissionId(int $submissionId) + * @method Tracker_SubmissionDao getSubmission() * @method int getTrendId() * @method void setTrendId(int $trendId) * @method float getValue() From 9c14cc7bb9fd9b7b1e890e85a58c2d07b8dbc2e9 Mon Sep 17 00:00:00 2001 From: Patrick Reynolds Date: Tue, 22 Mar 2016 01:05:41 -0400 Subject: [PATCH 11/40] First pass at review response. --- modules/tracker/Notification.php | 6 +- .../tracker/controllers/ScalarController.php | 3 +- .../tracker/controllers/TrendController.php | 1 + .../controllers/components/ApiComponent.php | 65 +++++-------------- .../components/ApisubmissionComponent.php | 14 +++- modules/tracker/database/mysql/2.0.0.sql | 4 +- .../tracker/models/base/ScalarModelBase.php | 9 ++- modules/tracker/models/dao/ParamDao.php | 4 +- modules/tracker/models/dao/ScalarDao.php | 3 + .../tracker/models/pdo/SubmissionModel.php | 14 ++-- .../tests/controllers/ApiComponentTest.php | 21 ------ .../tracker/tests/models/base/CMakeLists.txt | 2 +- .../tests/models/base/SubmissionModelTest.php | 1 - .../tests/models/base/TrendModelTest.php | 43 ------------ 14 files changed, 54 insertions(+), 136 deletions(-) delete mode 100644 modules/tracker/tests/models/base/TrendModelTest.php diff --git a/modules/tracker/Notification.php b/modules/tracker/Notification.php index 1c1e378ee..df587f132 100644 --- a/modules/tracker/Notification.php +++ b/modules/tracker/Notification.php @@ -23,9 +23,11 @@ /** * Notification manager for the tracker module. * + * @property Tracker_AggregateMetricModel $Tracker_AggregateMetric + * @property Tracker_AggregateMetricSpecModel $Tracker_AggregateMetricSpec * @property Tracker_ScalarModel $Tracker_Scalar - * @property Tracker_TrendModel $Tracker_Trend * @property Tracker_SubmissionModel $Tracker_Submission + * @property Tracker_TrendModel $Tracker_Trend */ class Tracker_Notification extends ApiEnabled_Notification { @@ -36,7 +38,7 @@ class Tracker_Notification extends ApiEnabled_Notification public $_models = array('User'); /** @var array */ - public $_moduleModels = array('Scalar', 'Trend', 'AggregateMetricSpec', 'AggregateMetric', 'Submission'); + public $_moduleModels = array('AggregateMetric', 'AggregateMetricSpec', 'Scalar', 'Submission', 'Trend'); /** @var array */ public $_moduleComponents = array('Api'); diff --git a/modules/tracker/controllers/ScalarController.php b/modules/tracker/controllers/ScalarController.php index c5218324a..bd7ee666e 100644 --- a/modules/tracker/controllers/ScalarController.php +++ b/modules/tracker/controllers/ScalarController.php @@ -22,7 +22,7 @@ * Scalar controller for the tracker module. * * @property Tracker_ScalarModel $Tracker_Scalar - * @property Tracker_SubmissionModelModel $Tracker_Submission + * @property Tracker_SubmissionModel $Tracker_Submission */ class Tracker_ScalarController extends Tracker_AppController { @@ -59,7 +59,6 @@ public function detailsAction() throw new Zend_Exception('The scalar does not exist or you do not have the necessary permission', 403); } - // TODO(cpatrick): This may be a performance issue. $this->view->isAdmin = $this->Tracker_Scalar->policyCheck($scalarDao, $this->userSession->Dao, MIDAS_POLICY_ADMIN); $this->view->scalar = $scalarDao; diff --git a/modules/tracker/controllers/TrendController.php b/modules/tracker/controllers/TrendController.php index a0118727f..6071bafcf 100644 --- a/modules/tracker/controllers/TrendController.php +++ b/modules/tracker/controllers/TrendController.php @@ -25,6 +25,7 @@ * @property Tracker_ThresholdNotificationModel $Tracker_ThresholdNotification * @property Tracker_TrendModel $Tracker_Trend * @property Tracker_SubmissionModel $Tracker_Submission + * @property Tracker_ProducerModel $Tracker_Producer */ class Tracker_TrendController extends Tracker_AppController { diff --git a/modules/tracker/controllers/components/ApiComponent.php b/modules/tracker/controllers/components/ApiComponent.php index 263a896f4..baf8ea3bb 100644 --- a/modules/tracker/controllers/components/ApiComponent.php +++ b/modules/tracker/controllers/components/ApiComponent.php @@ -58,7 +58,7 @@ private function _getUser($args) /** * Associate a result item with a particular submission. * - * @param submissionId the submission to associate the item with + * @param submissionUuid the uuid of the submission to associate the item with * @param itemId The id of the item to associate with the scalar * @param label The label describing the nature of the association * @throws Exception @@ -73,7 +73,7 @@ public function itemAssociate($args) /** @var Tracker_ScalarModel $scalarModel */ $submissionModel = MidasLoader::loadModel('Submission', 'tracker'); - $this->_checkKeys(array('scalarIds', 'itemId', 'label'), $args); + $this->_checkKeys(array('submissionUuid', 'itemId', 'label'), $args); $user = $this->_getUser($args); /** @var ItemDao $item */ @@ -85,21 +85,21 @@ public function itemAssociate($args) throw new Exception('Read permission on the item required', 403); } - $submissionId = $args['submissionId']; + $submissionUuid = $args['submissionUuid']; /** @var Tracker_SubmissionDao $submission */ - $submission = $submissionModel->load($submissionId); + $submission = $submissionModel->findBy('uuid', $submissionUuid); if (!$submission) { - throw new Exception('Invalid submission id: '.$submissionId, 404); + throw new Exception('Invalid submission uuid: '.$submissionUuid, 404); } if (!$communityModel->policyCheck( $submission->getProducer()->getCommunity(), $user, - MIDAS_POLICY_ADMIN + MIDAS_POLICY_WRITE )) { - throw new Exception('Admin permission on the community required', 403); + throw new Exception('Write permission on the community required', 403); } $submissionModel->associateItem($submission, $item, $args['label']); @@ -112,7 +112,8 @@ public function itemAssociate($args) * @param producerDisplayName The display name of the producer * @param metricName The metric name that identifies which trend this point belongs to * @param value The value of the scalar - * @param submissionUuid the uuid of the submission + * @param submissionUuid the uuid of the submission. If a submission does not exist with the specified uuid, one + * will be created. * @param configItemId (Optional) If this value pertains to a specific configuration item, pass its id here * @param testDatasetId (Optional) If this value pertains to a specific test dataset, pass its id here * @param truthDatasetId (Optional) If this value pertains to a specific ground truth dataset, pass its id here @@ -128,7 +129,13 @@ public function scalarAdd($args) /** @var ItemModel $itemModel */ $itemModel = MidasLoader::loadModel('Item'); $this->_checkKeys( - array('communityId', 'producerDisplayName', 'metricName', 'value'), + array( + 'communityId', + 'metricName', + 'producerDisplayName', + 'submissionUuid', + 'value' + ), $args ); $user = $this->_getUser($args); @@ -283,7 +290,7 @@ private function _createOrFindByName($itemName, $community) * * @param producerRevision The repository revision of the producer that produced this value * @param submitTime The submit timestamp. Must be parseable with PHP strtotime(). - * @param uuid (Optional) A unique identifier for the submission + * @param uuid (Optional) A unique identifier for the submission. If none is passed, one will be generated. * @param name (Optional) A name for the submission * @param buildResultsUrl (Optional) The URL where build results can be viewed * @param extraUrls (Optional) JSON list of additional links @@ -304,44 +311,6 @@ public function submissionAdd($args) return $newApi->post($args); } - /** - * Return an array of branch names from scalars tied to the producer - * and tied to trends with metric names matching the passed trend metric name. - * - * @param producerId The id of the producer tied to the scalars - * @param trendMetricName The metric_name of the trends tied to the scalars - * @return An array of branch names - * @throws Exception - */ - public function branchesformetricnameList($args) - { - $this->_checkKeys(array('producerId', 'trendMetricName'), $args); - $user = $this->_getUser($args); - - $producerId = $args['producerId']; - /** @var Tracker_ProducerModel $producerModel */ - $producerModel = MidasLoader::loadModel('Producer', 'tracker'); - /** @var Tracker_ProducerDao $producerDao */ - $producerDao = $producerModel->load($producerId); - /** @var CommunityDao $communityDao */ - $communityDao = $producerDao->getCommunity(); - - /** @var CommunityModel $communityModel */ - $communityModel = MidasLoader::loadModel('Community'); - if ($communityDao === false || $communityModel->policyCheck($communityDao, $user, MIDAS_POLICY_ADMIN) === false - ) { - throw new Zend_Exception('The associated community does not exist or you do not Admin access to the community', 403); - } - - $trendMetricName = $args['trendMetricName']; - /** @var Tracker_TrendModel $trendModel */ - $trendModel = MidasLoader::loadModel('Trend', 'tracker'); - /** @var array $branches */ - $branches = $trendModel->getDistinctBranchesForMetricName($producerId, $trendMetricName); - - return $branches; - } - /** * Update and return an array of all aggregate metrics calculated on each * aggregate metric spec attached to the submission identified by the passed in diff --git a/modules/tracker/controllers/components/ApisubmissionComponent.php b/modules/tracker/controllers/components/ApisubmissionComponent.php index d76610b21..27945a170 100644 --- a/modules/tracker/controllers/components/ApisubmissionComponent.php +++ b/modules/tracker/controllers/components/ApisubmissionComponent.php @@ -184,8 +184,12 @@ public function post($args) $submitTime = date('Y-m-d H:i:s', $submitTime); $args['submit_time'] = $submitTime; $args['producer_revision'] = trim($args['producerRevision']); - $args['producer_id'] = $producerModel->getByCommunityIdAndName( - $args['communityId'], $args['producerDisplayName'])->getKey(); + /** @var Tracker_ProducerDao $producerDao */ + $producerDao = $producerModel->getByCommunityIdAndName( + $args['communityId'], + $args['producerDisplayName'] + ); + $args['producer_id'] = $producerDao->getKey(); // Remove params from the submission args for later insertion in param table if (isset($args['params']) && !is_null($args['params'])) { @@ -232,7 +236,6 @@ public function post($args) * @param submitTime (Optional) * @param branch (Optional) * @param buildResultsUrl (Optional) - * @param params (Optional) * @param extraUrls (Optional) * @param reproductionCommand (Optional) * @return array @@ -275,6 +278,11 @@ public function put($args) $args['submitTime'] = $submitTime; } + // Disallow modification of the uuid. + if (isset($args['uuid'])) { + unset($args['uuid']); + } + /** @var Tracker_SubmissionDao $submissionDao */ $submissionDao = $submissionModel->initDao('Submission', $args, $this->moduleName); diff --git a/modules/tracker/database/mysql/2.0.0.sql b/modules/tracker/database/mysql/2.0.0.sql index 82d91556d..d6fe02e7e 100644 --- a/modules/tracker/database/mysql/2.0.0.sql +++ b/modules/tracker/database/mysql/2.0.0.sql @@ -1,6 +1,6 @@ -- Midas Server. Copyright Kitware SAS. Licensed under the Apache License 2.0. --- MySQL database for the tracker module, version 1.2.4 +-- MySQL database for the tracker module, version 2.0.0 CREATE TABLE IF NOT EXISTS `tracker_producer` ( `producer_id` bigint(20) NOT NULL AUTO_INCREMENT, @@ -18,7 +18,7 @@ CREATE TABLE IF NOT EXISTS `tracker_scalar` ( `scalar_id` bigint(20) NOT NULL AUTO_INCREMENT, `trend_id` bigint(20) NOT NULL, `value` double, - `submission_id` bigint(20) NOT NULL DEFAULT '-1', + `submission_id` bigint(20) NOT NULL, PRIMARY KEY (`scalar_id`), KEY (`trend_id`), KEY (`submission_id`) diff --git a/modules/tracker/models/base/ScalarModelBase.php b/modules/tracker/models/base/ScalarModelBase.php index 94801be43..87fba41a2 100644 --- a/modules/tracker/models/base/ScalarModelBase.php +++ b/modules/tracker/models/base/ScalarModelBase.php @@ -32,8 +32,13 @@ public function __construct() 'scalar_id' => array('type' => MIDAS_DATA), 'trend_id' => array('type' => MIDAS_DATA), 'submission_id' => array('type' => MIDAS_DATA), - 'submit_time' => array('type' => MIDAS_DATA), // Not in the DB, from submission - 'official' => array('type' => MIDAS_DATA), // Not in the DB, from submission + /** + * submit_time and official are not actually present in the scalar table, + * but they are present here to be populated in the DAO when scalars are + * retrieved via a join query with submission. + */ + 'submit_time' => array('type' => MIDAS_DATA), // from submission + 'official' => array('type' => MIDAS_DATA), // from submission 'value' => array('type' => MIDAS_DATA), 'trend' => array( 'type' => MIDAS_MANY_TO_ONE, diff --git a/modules/tracker/models/dao/ParamDao.php b/modules/tracker/models/dao/ParamDao.php index 6cb54d430..79d5343dd 100644 --- a/modules/tracker/models/dao/ParamDao.php +++ b/modules/tracker/models/dao/ParamDao.php @@ -23,8 +23,8 @@ * * @method int getParamId() * @method void setParamId(int $paramId) - * @method int getScalarId() - * @method void setScalarId(int $scalarId) + * @method int getSubmissionId() + * @method void setSubmissionId(int $submissionId) * @method int getParamName() * @method void setParamName(int $paramName) * @method int getParamType() diff --git a/modules/tracker/models/dao/ScalarDao.php b/modules/tracker/models/dao/ScalarDao.php index 2e2d46a91..058592cd5 100644 --- a/modules/tracker/models/dao/ScalarDao.php +++ b/modules/tracker/models/dao/ScalarDao.php @@ -26,10 +26,13 @@ * @method int getSubmissionId() * @method void setSubmissionId(int $submissionId) * @method Tracker_SubmissionDao getSubmission() + * @method void setSubmission(Tracker_SubmissionDao $submissionDao) * @method int getTrendId() * @method void setTrendId(int $trendId) * @method float getValue() * @method void setValue(float $value) + * @method string getSubmitTime() // read-only from submission join + * @method int getOfficial() // read-only from submission join * @method Tracker_TrendDao getTrend() * @method void setTrend(Tracker_TrendDao $trendDao) */ diff --git a/modules/tracker/models/pdo/SubmissionModel.php b/modules/tracker/models/pdo/SubmissionModel.php index 9ca94dc65..1159f943a 100644 --- a/modules/tracker/models/pdo/SubmissionModel.php +++ b/modules/tracker/models/pdo/SubmissionModel.php @@ -259,17 +259,13 @@ public function getLatestSubmissionByProducerDateAndBranch($producerDao, $date = $dayBeforeQueryTime = date('Y-m-d H:i:s', strtotime($queryTime) - self::SEC_IN_DAY); $sql = $this->database->select()->setIntegrityCheck(false) ->from('tracker_submission') - ->join( - 'tracker_scalar', - 'tracker_submission.submission_id = tracker_scalar.submission_id', - array()) - ->where('tracker_submission.submit_time <= ?', $queryTime); + ->where('submit_time <= ?', $queryTime); if ($onlyOneDay) { - $sql = $sql->where('tracker_submission.submit_time > ?', $dayBeforeQueryTime); + $sql = $sql->where('submit_time > ?', $dayBeforeQueryTime); } - $sql = $sql->where('tracker_submission.producer_id = ?', $producerDao->getKey()) + $sql = $sql->where('producer_id = ?', $producerDao->getKey()) ->where('branch = ?', $branch) - ->order('tracker_submission.submit_time', 'DSC') + ->order('submit_time', 'DSC') ->limit(1); $res = $this->database->fetchAll($sql); if (count($res) === 1) { @@ -310,7 +306,7 @@ public function getTrends($submissionDao, $key = true) } /** - * Return all distinct branch names of revisions producing submissions. + * Return all distinct branch names from submissions. * * @return array branch names */ diff --git a/modules/tracker/tests/controllers/ApiComponentTest.php b/modules/tracker/tests/controllers/ApiComponentTest.php index 1a9b7894c..5facfcd35 100644 --- a/modules/tracker/tests/controllers/ApiComponentTest.php +++ b/modules/tracker/tests/controllers/ApiComponentTest.php @@ -195,27 +195,6 @@ private function _submitSubmission($token, $uuid, $params = false) return $res->data; } - /** - * Test listing the branch names tied to a producer and trend metric_name. - * - * @throws Zend_Exception - */ - public function testBranchesformetricnameList() - { - $token = $this->_loginAsAdministrator(); - $this->resetAll(); - $this->params['method'] = 'midas.tracker.branchesformetricname.list'; - $this->params['token'] = $token; - $this->params['producerId'] = '100'; - $this->params['trendMetricName'] = 'Greedy error'; - $res = $this->_callJsonApi(); - /** @var array branches */ - $branches = $res->data; - $this->assertEquals(count($branches), 2); - $this->assertTrue(in_array('master', $branches)); - $this->assertTrue(in_array('test', $branches)); - } - /** * Test updating the aggregate metrics tied to a submission. * diff --git a/modules/tracker/tests/models/base/CMakeLists.txt b/modules/tracker/tests/models/base/CMakeLists.txt index f696365fb..b3a6dd6cd 100644 --- a/modules/tracker/tests/models/base/CMakeLists.txt +++ b/modules/tracker/tests/models/base/CMakeLists.txt @@ -24,4 +24,4 @@ add_midas_mysql_test(${module_name_titlecase}AggregateMetricModel AggregateMetri add_midas_mysql_test(${module_name_titlecase}AggregateMetricSpecModel AggregateMetricSpecModelTest.php) add_midas_mysql_test(${module_name_titlecase}ScalarModel ScalarModelTest.php) add_midas_mysql_test(${module_name_titlecase}SubmissionModel SubmissionModelTest.php) -add_midas_mysql_test(${module_name_titlecase}TrendModel TrendModelTest.php) + diff --git a/modules/tracker/tests/models/base/SubmissionModelTest.php b/modules/tracker/tests/models/base/SubmissionModelTest.php index bec727aba..00a03bf3b 100644 --- a/modules/tracker/tests/models/base/SubmissionModelTest.php +++ b/modules/tracker/tests/models/base/SubmissionModelTest.php @@ -82,7 +82,6 @@ public function testSubmissionModel() ); $submissionDao0Params = $submissionDao0->getParams(); - var_dump($submissionDao0Params); foreach ($submissionDao0Params as $param) { $checks = $paramChecks[$param->getParamName()]; $this->assertEquals($checks['type'], $param->getParamType()); diff --git a/modules/tracker/tests/models/base/TrendModelTest.php b/modules/tracker/tests/models/base/TrendModelTest.php deleted file mode 100644 index f71a2f6c2..000000000 --- a/modules/tracker/tests/models/base/TrendModelTest.php +++ /dev/null @@ -1,43 +0,0 @@ -setupDatabase(array('default')); // core dataset - $this->setupDatabase(array('aggregateMetric'), 'tracker'); // module dataset - $this->enabledModules = array('tracker'); - parent::setUp(); - } - - /** testGetDistinctBranchesForMetricName */ - public function testGetDistinctBranchesForMetricName() - { - /** @var Tracker_TrendModel $trendModel */ - $trendModel = MidasLoader::loadModel('Trend', 'tracker'); - /** @var array $branches */ - $branches = $trendModel->getDistinctBranchesForMetricName(100, 'Greedy error'); - $this->assertEquals(count($branches), 2); - $this->assertTrue(in_array('master', $branches)); - $this->assertTrue(in_array('test', $branches)); - } -} From d11e1e28469c6a53320ea95df31f4a02fd64debd Mon Sep 17 00:00:00 2001 From: Patrick Reynolds Date: Tue, 22 Mar 2016 01:18:35 -0400 Subject: [PATCH 12/40] Applied fixes from StyleCI --- modules/tracker/controllers/components/ApiComponent.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/tracker/controllers/components/ApiComponent.php b/modules/tracker/controllers/components/ApiComponent.php index baf8ea3bb..179a108d5 100644 --- a/modules/tracker/controllers/components/ApiComponent.php +++ b/modules/tracker/controllers/components/ApiComponent.php @@ -134,7 +134,7 @@ public function scalarAdd($args) 'metricName', 'producerDisplayName', 'submissionUuid', - 'value' + 'value', ), $args ); From 96996d3d36792b14f843b91a21282182fb3ba5d7 Mon Sep 17 00:00:00 2001 From: Patrick Reynolds Date: Tue, 22 Mar 2016 21:07:03 -0400 Subject: [PATCH 13/40] Address review points. * Remove getDistinctBranchesForMetricName from TrendModel. * Fix bad ordering query in SubmissionModel. --- .../components/ApisubmissionComponent.php | 1 + .../tracker/models/base/TrendModelBase.php | 10 ------ .../tracker/models/pdo/SubmissionModel.php | 2 +- modules/tracker/models/pdo/TrendModel.php | 36 ------------------- 4 files changed, 2 insertions(+), 47 deletions(-) diff --git a/modules/tracker/controllers/components/ApisubmissionComponent.php b/modules/tracker/controllers/components/ApisubmissionComponent.php index 27945a170..e515fd74a 100644 --- a/modules/tracker/controllers/components/ApisubmissionComponent.php +++ b/modules/tracker/controllers/components/ApisubmissionComponent.php @@ -175,6 +175,7 @@ public function post($args) $args['build_results_url'] = isset($args['buildResultsUrl']) ? $args['buildResultsUrl'] : ''; $args['branch'] = isset($args['branch']) ? $args['branch'] : ''; + $args['name'] = isset($args['name']) ? $args['name'] : ''; $args['reproduction_command'] = isset($args['reproductionCommand']) ? $args['reproductionCommand'] : ''; $submitTime = strtotime($args['submitTime']); diff --git a/modules/tracker/models/base/TrendModelBase.php b/modules/tracker/models/base/TrendModelBase.php index 2027ab013..1e8f9c9e7 100644 --- a/modules/tracker/models/base/TrendModelBase.php +++ b/modules/tracker/models/base/TrendModelBase.php @@ -118,16 +118,6 @@ abstract public function getScalars($trendDao, $startDate = null, $endDate = nul */ abstract public function getTrendsGroupByDatasets($producerDao, $onlyKey = false); - /** - * Return all distinct branch names producing scalars, tied to a specific - * producer, for trends that are key_metrics, and matching a trend metric_name. - * - * @param int $producerId producer id - * @param string $metricName trend metric_name - * @return array branch names - */ - abstract public function getDistinctBranchesForMetricName($producerId, $metricName); - /** * Save the given trend. Ensure that null values are explicitly set in the database. * diff --git a/modules/tracker/models/pdo/SubmissionModel.php b/modules/tracker/models/pdo/SubmissionModel.php index 1159f943a..09c219cbf 100644 --- a/modules/tracker/models/pdo/SubmissionModel.php +++ b/modules/tracker/models/pdo/SubmissionModel.php @@ -265,7 +265,7 @@ public function getLatestSubmissionByProducerDateAndBranch($producerDao, $date = } $sql = $sql->where('producer_id = ?', $producerDao->getKey()) ->where('branch = ?', $branch) - ->order('submit_time', 'DSC') + ->order('submit_time DESC') ->limit(1); $res = $this->database->fetchAll($sql); if (count($res) === 1) { diff --git a/modules/tracker/models/pdo/TrendModel.php b/modules/tracker/models/pdo/TrendModel.php index 43ac51208..0e8a2a5e7 100644 --- a/modules/tracker/models/pdo/TrendModel.php +++ b/modules/tracker/models/pdo/TrendModel.php @@ -192,40 +192,4 @@ public function getAllByParams($params) return $trendDaos; } - /** - * Return all distinct branch names producing scalars, tied to a specific - * producer, for trends that are key_metrics, and matching a trend metric_name. - * - * @param int $producerId producer id - * @param string $metricName trend metric_name - * @return array branch names - */ - public function getDistinctBranchesForMetricName($producerId, $metricName) - { - $sql = $this->database->select()->setIntegrityCheck(false)->from( - array('u' => 'tracker_submission'), - 'branch' - ) - ->join( - array('s' => 'tracker_scalar'), - 's.submission_id = u.submission_id' - )->join( - array('t' => 'tracker_trend'), - 's.trend_id = t.trend_id', - array() - ) - ->where('t.producer_id = ?', $producerId) - ->where('t.key_metric = ?', 1) - ->where('t.metric_name = ?', $metricName)->group('branch'); - - $rows = $this->database->fetchAll($sql); - $branches = array(); - - /** @var Zend_Db_Table_Row_Abstract $row */ - foreach ($rows as $row) { - $branches[] = $row['branch']; - } - - return $branches; - } } From 7a455a5fbf5283fea4e51bbdfd0509c5708cb624 Mon Sep 17 00:00:00 2001 From: Patrick Reynolds Date: Tue, 22 Mar 2016 21:08:24 -0400 Subject: [PATCH 14/40] Applied fixes from StyleCI --- modules/tracker/models/pdo/TrendModel.php | 1 - 1 file changed, 1 deletion(-) diff --git a/modules/tracker/models/pdo/TrendModel.php b/modules/tracker/models/pdo/TrendModel.php index 0e8a2a5e7..ad20e414e 100644 --- a/modules/tracker/models/pdo/TrendModel.php +++ b/modules/tracker/models/pdo/TrendModel.php @@ -191,5 +191,4 @@ public function getAllByParams($params) return $trendDaos; } - } From e8103e626a8eaaafb97a9ac79662bfdc7c1b43ff Mon Sep 17 00:00:00 2001 From: Patrick Reynolds Date: Wed, 23 Mar 2016 14:45:09 -0400 Subject: [PATCH 15/40] Remove default value of submission_id on tracker_scalar. --- modules/tracker/database/mysql/upgrade_to_2.0.0.sql | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/tracker/database/mysql/upgrade_to_2.0.0.sql b/modules/tracker/database/mysql/upgrade_to_2.0.0.sql index c3339b19d..c0b90d383 100644 --- a/modules/tracker/database/mysql/upgrade_to_2.0.0.sql +++ b/modules/tracker/database/mysql/upgrade_to_2.0.0.sql @@ -54,6 +54,7 @@ DROP TABLE IF EXISTS tracker_param; RENAME TABLE tracker_submissionparam TO tracker_param; +ALTER TABLE tracker_scalar CHANGE `submission_id` `submission_id` bigint(20) NOT NULL; ALTER TABLE tracker_scalar DROP COLUMN `producer_revision`; ALTER TABLE tracker_scalar DROP COLUMN `user_id`; ALTER TABLE tracker_scalar DROP COLUMN `official`; From 3621b1b22a94b48ac705dbb4334503e4e01bc807 Mon Sep 17 00:00:00 2001 From: mgrauer Date: Wed, 23 Mar 2016 19:33:40 +0000 Subject: [PATCH 16/40] Remove incorrect migration comments --- modules/tracker/models/pdo/AggregateMetricModel.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/modules/tracker/models/pdo/AggregateMetricModel.php b/modules/tracker/models/pdo/AggregateMetricModel.php index d10a8eff5..ea5ceb53e 100644 --- a/modules/tracker/models/pdo/AggregateMetricModel.php +++ b/modules/tracker/models/pdo/AggregateMetricModel.php @@ -365,12 +365,10 @@ public function getAggregateMetricsSeries($producerDao, $lastDate = false, $days ->join(array('u' => 'tracker_submission'), 'am.submission_id = u.submission_id', array()) - // TODO Tracker 2.0 delete this join >> ->join(array('ams' => 'tracker_aggregate_metric_spec'), 'ams.aggregate_metric_spec_id = am.aggregate_metric_spec_id', array()) - // << TODO Tracker 2.0 delete this join - ->where('ams.branch = ?', $branch) // TODO Tracker 2.0 u.branch = ? + ->where('ams.branch = ?', $branch) ->where('u.producer_id = ?', $producerDao->getProducerId()) ->where('u.submit_time > ?', $firstDate->format('Y-m-d H:i:s')) ->where('u.submit_time <= ?', $lastDate) From cd62b628bfe9a984a15112769c44ecc3623e8269 Mon Sep 17 00:00:00 2001 From: mgrauer Date: Wed, 23 Mar 2016 21:33:28 +0000 Subject: [PATCH 17/40] Combine tracker_scalar drops into single alter statement --- .../tracker/database/mysql/upgrade_to_2.0.0.sql | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/modules/tracker/database/mysql/upgrade_to_2.0.0.sql b/modules/tracker/database/mysql/upgrade_to_2.0.0.sql index c0b90d383..fcc6b864d 100644 --- a/modules/tracker/database/mysql/upgrade_to_2.0.0.sql +++ b/modules/tracker/database/mysql/upgrade_to_2.0.0.sql @@ -55,13 +55,14 @@ DROP TABLE IF EXISTS tracker_param; RENAME TABLE tracker_submissionparam TO tracker_param; ALTER TABLE tracker_scalar CHANGE `submission_id` `submission_id` bigint(20) NOT NULL; -ALTER TABLE tracker_scalar DROP COLUMN `producer_revision`; -ALTER TABLE tracker_scalar DROP COLUMN `user_id`; -ALTER TABLE tracker_scalar DROP COLUMN `official`; -ALTER TABLE tracker_scalar DROP COLUMN `build_results_url`; -ALTER TABLE tracker_scalar DROP COLUMN `branch`; -ALTER TABLE tracker_scalar DROP COLUMN `extra_urls`; -ALTER TABLE tracker_scalar DROP COLUMN `reproduction_command`; -ALTER TABLE tracker_scalar DROP COLUMN `submit_time`; +ALTER TABLE tracker_scalar + DROP COLUMN `producer_revision`, + DROP COLUMN `user_id`, + DROP COLUMN `official`, + DROP COLUMN `build_results_url`, + DROP COLUMN `branch`, + DROP COLUMN `extra_urls`, + DROP COLUMN `reproduction_command`, + DROP COLUMN `submit_time`; DROP TABLE IF EXISTS `tracker_scalar2item`; From fc35df23d766797313b6ab0622e5f8fc5c3bb835 Mon Sep 17 00:00:00 2001 From: Patrick Reynolds Date: Thu, 24 Mar 2016 00:14:34 -0400 Subject: [PATCH 18/40] Add branch to scalar dao. --- modules/tracker/models/base/ScalarModelBase.php | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/modules/tracker/models/base/ScalarModelBase.php b/modules/tracker/models/base/ScalarModelBase.php index 87fba41a2..1f93098a3 100644 --- a/modules/tracker/models/base/ScalarModelBase.php +++ b/modules/tracker/models/base/ScalarModelBase.php @@ -33,11 +33,13 @@ public function __construct() 'trend_id' => array('type' => MIDAS_DATA), 'submission_id' => array('type' => MIDAS_DATA), /** - * submit_time and official are not actually present in the scalar table, - * but they are present here to be populated in the DAO when scalars are - * retrieved via a join query with submission. + * submit_time, branch, and official are not actually present in + * the scalar table, but they are present here to be populated in + * the DAO when scalars are retrieved via a join query with + * submission. */ 'submit_time' => array('type' => MIDAS_DATA), // from submission + 'branch' => array('type' => MIDAS_DATA), // from submission 'official' => array('type' => MIDAS_DATA), // from submission 'value' => array('type' => MIDAS_DATA), 'trend' => array( From 7167c312a5a281001140bfb353127c6337d01a3e Mon Sep 17 00:00:00 2001 From: Patrick Reynolds Date: Thu, 24 Mar 2016 00:21:27 -0400 Subject: [PATCH 19/40] Remove result items from scalar details dialog. --- .../tracker/controllers/ScalarController.php | 1 - modules/tracker/views/scalar/details.phtml | 21 ------------------- 2 files changed, 22 deletions(-) diff --git a/modules/tracker/controllers/ScalarController.php b/modules/tracker/controllers/ScalarController.php index bd7ee666e..5fe01149b 100644 --- a/modules/tracker/controllers/ScalarController.php +++ b/modules/tracker/controllers/ScalarController.php @@ -76,7 +76,6 @@ public function detailsAction() $this->view->revisionHtml = $producerRevision; } - $this->view->resultItems = $this->Tracker_Submission->getAssociatedItems($submissionDao); $this->view->otherValues = $this->Tracker_Submission->getValuesFromSubmission($submissionDao); if ($submissionDao->getUserId() !== -1) { diff --git a/modules/tracker/views/scalar/details.phtml b/modules/tracker/views/scalar/details.phtml index 31083ff57..11ee51136 100644 --- a/modules/tracker/views/scalar/details.phtml +++ b/modules/tracker/views/scalar/details.phtml @@ -145,27 +145,6 @@ if (count($this->extraParams)) { -
-
Result items -
- resultItems as $result) { - /** @var ItemDao $itemDao */ - $itemDao = $result['item']; - echo '
'.$this->escape($result['label']).': '; - echo ''.$this->escape($itemDao->getName()).''; - echo '
'; - } - if (empty($this->resultItems)) { - echo 'No result items submitted'; - } - ?> - -
-
isAdmin) { From de213814426bfa2382a3da438d844195c2d6c273 Mon Sep 17 00:00:00 2001 From: Patrick Reynolds Date: Fri, 8 Apr 2016 00:51:01 -0400 Subject: [PATCH 20/40] Add a first cut at trend groups. --- .../tracker/controllers/TrendController.php | 11 ++- modules/tracker/database/mysql/2.0.0.sql | 17 +++- .../database/mysql/create_trendgroups.sql | 32 +++++++ .../database/mysql/upgrade_to_2.0.0.sql | 26 ++++++ .../models/base/TrendGroupModelBase.php | 86 +++++++++++++++++++ .../tracker/models/base/TrendModelBase.php | 54 ++++-------- modules/tracker/models/dao/TrendDao.php | 21 ++--- modules/tracker/models/dao/TrendGroupDao.php | 51 +++++++++++ .../tracker/models/pdo/TrendGroupModel.php | 84 ++++++++++++++++++ modules/tracker/models/pdo/TrendModel.php | 32 +++---- modules/tracker/views/trend/view.phtml | 20 +++-- 11 files changed, 347 insertions(+), 87 deletions(-) create mode 100644 modules/tracker/database/mysql/create_trendgroups.sql create mode 100644 modules/tracker/models/base/TrendGroupModelBase.php create mode 100644 modules/tracker/models/dao/TrendGroupDao.php create mode 100644 modules/tracker/models/pdo/TrendGroupModel.php diff --git a/modules/tracker/controllers/TrendController.php b/modules/tracker/controllers/TrendController.php index 6071bafcf..060156ba4 100644 --- a/modules/tracker/controllers/TrendController.php +++ b/modules/tracker/controllers/TrendController.php @@ -106,7 +106,7 @@ public function viewAction() ); if (!isset($this->view->json['tracker']['producerId'])) { - $this->view->json['tracker']['producerId'] = $trendDao->getProducerId(); + $this->view->json['tracker']['producerId'] = $trendDao->getTrendgroup()->getProducerId(); } $trendDaos[] = $trendDao; @@ -114,7 +114,7 @@ public function viewAction() /** @var Tracker_TrendDao $trendDao */ $trendDao = $trendDaos[0]; - $producerDao = $trendDao->getProducer(); + $producerDao = $trendDao->getTrendgroup()->getProducer(); $communityDao = $producerDao->getCommunity(); if (count($trendDaos) === 1) { @@ -133,7 +133,7 @@ public function viewAction() /** @var Tracker_TrendDao $rightTrendDao */ $rightTrendDao = $this->Tracker_Trend->load($rightTrendId); - if ($communityDao !== false && $communityDao->getKey() !== $rightTrendDao->getProducer()->getCommunityId() + if ($communityDao !== false && $communityDao->getKey() !== $rightTrendDao->getTrendgroup()->getProducer()->getCommunityId() ) { throw new Zend_Exception('The right trend must belong to the same community as the other trends', 403); } @@ -557,8 +557,11 @@ public function setkeymetricAction() /** @var Tracker_TrendDao $trendDao */ $trendDao = $this->Tracker_Trend->load($trendId); + /** @var Tracker_TrendgroupDao $trendGroup */ + $trendGroup = $trendDao->getTrendgroup(); + /** @var Tracker_ProducerDao $producerDao */ - $producerDao = $trendDao->getProducer(); + $producerDao = $trendGroup->getProducer(); if ($this->Tracker_Producer->policyCheck($producerDao, $this->userSession->Dao, MIDAS_POLICY_ADMIN) === false ) { diff --git a/modules/tracker/database/mysql/2.0.0.sql b/modules/tracker/database/mysql/2.0.0.sql index d6fe02e7e..6a4ea6729 100644 --- a/modules/tracker/database/mysql/2.0.0.sql +++ b/modules/tracker/database/mysql/2.0.0.sql @@ -64,18 +64,27 @@ CREATE TABLE IF NOT EXISTS `tracker_threshold_notification` ( CREATE TABLE IF NOT EXISTS `tracker_trend` ( `trend_id` bigint(20) NOT NULL AUTO_INCREMENT, - `producer_id` bigint(20) NOT NULL, + `trendgroup_id` bigint(20), `metric_name` varchar(255) NOT NULL, `display_name` varchar(255) NOT NULL, `unit` varchar(255) NOT NULL, - `config_item_id` bigint(20), - `test_dataset_id` bigint(20), - `truth_dataset_id` bigint(20), `key_metric` tinyint(4) NOT NULL DEFAULT '0', PRIMARY KEY (`trend_id`), KEY (`producer_id`) ) DEFAULT CHARSET=utf8; +CREATE TABLE IF NOT EXISTS `tracker_trendgroup` ( + `trendgroup_id` bigint(20) NOT NULL AUTO_INCREMENT, + `producer_id` bigint(20) NOT NULL, + `config_item_id` bigint(20), + `test_dataset_id` bigint(20), + `truth_dataset_id` bigint(20), + PRIMARY KEY (`trendgroup_id`), + KEY (`config_item_id`), + KEY (`test_dataset_id`), + KEY (`truth_dataset_id`) +) DEFAULT CHARSET=utf8; + CREATE TABLE IF NOT EXISTS `tracker_param` ( `param_id` bigint(20) NOT NULL AUTO_INCREMENT, `submission_id` bigint(20) NOT NULL, diff --git a/modules/tracker/database/mysql/create_trendgroups.sql b/modules/tracker/database/mysql/create_trendgroups.sql new file mode 100644 index 000000000..59f822abe --- /dev/null +++ b/modules/tracker/database/mysql/create_trendgroups.sql @@ -0,0 +1,32 @@ +CREATE PROCEDURE `create_trendgroups`() + BEGIN + DECLARE finished INTEGER DEFAULT 0; + DECLARE cur_producer_id bigint(20) default -1; + DECLARE cur_config_item_id bigint(20) default NULL; + DECLARE cur_test_dataset_id bigint(20) default NULL; + DECLARE cur_truth_dataset_id bigint(20) default NULL; + + DECLARE curs CURSOR FOR SELECT producer_id, config_item_id, test_dataset_id, truth_dataset_id + FROM tracker_trend + WHERE trendgroup_id=-1 GROUP BY config_item_id, test_dataset_id, truth_dataset_id, producer_id; + DECLARE CONTINUE HANDLER FOR NOT FOUND SET finished = 1; + + OPEN curs; + + get_trends: LOOP + FETCH curs INTO cur_producer_id, cur_config_item_id, cur_test_dataset_id, cur_truth_dataset_id; + IF finished = 1 THEN + LEAVE get_trends; + END IF; + + INSERT INTO tracker_trendgroup (producer_id, config_item_id, test_dataset_id, truth_dataset_id) + VALUES (cur_producer_id, cur_config_item_id, cur_test_dataset_id, cur_truth_dataset_id); + UPDATE tracker_trend SET trendgroup_id=LAST_INSERT_ID() + WHERE + producer_id=cur_producer_id AND + (config_item_id=cur_config_item_id OR (config_item_id IS NULL AND cur_config_item_id IS NULL)) AND + (test_dataset_id=cur_test_dataset_id OR (test_dataset_id IS NULL AND cur_test_dataset_id IS NULL)) AND + (truth_dataset_id=cur_truth_dataset_id OR (truth_dataset_id IS NULL AND cur_truth_dataset_id IS NULL)); + END LOOP get_trends; + CLOSE curs; + END diff --git a/modules/tracker/database/mysql/upgrade_to_2.0.0.sql b/modules/tracker/database/mysql/upgrade_to_2.0.0.sql index fcc6b864d..c17d3b805 100644 --- a/modules/tracker/database/mysql/upgrade_to_2.0.0.sql +++ b/modules/tracker/database/mysql/upgrade_to_2.0.0.sql @@ -19,15 +19,31 @@ CREATE TABLE IF NOT EXISTS `tracker_submissionparam` ( KEY (`param_name`) ) DEFAULT CHARSET=utf8; +CREATE TABLE IF NOT EXISTS `tracker_trendgroup` ( + `trendgroup_id` bigint(20) NOT NULL AUTO_INCREMENT, + `producer_id` bigint(20) NOT NULL, + `config_item_id` bigint(20), + `test_dataset_id` bigint(20), + `truth_dataset_id` bigint(20), + PRIMARY KEY (`trendgroup_id`), + KEY (`config_item_id`), + KEY (`test_dataset_id`), + KEY (`truth_dataset_id`) +) DEFAULT CHARSET=utf8; + + DROP PROCEDURE IF EXISTS `create_submissions`; DROP PROCEDURE IF EXISTS `migrate_items_to_submissions`; DROP PROCEDURE IF EXISTS `migrate_params`; DROP PROCEDURE IF EXISTS `scalar_to_submission`; +DROP PROCEDURE IF EXISTS `create_trendgroups`; + DELIMITER '$$' SOURCE create_submissions.sql SOURCE migrate_items_to_submissions.sql SOURCE migrate_params.sql SOURCE scalar_to_submission.sql +SOURCE create_trendgroups.sql DELIMITER ';' ALTER TABLE tracker_submission ADD COLUMN `producer_revision` VARCHAR(255); @@ -42,6 +58,8 @@ ALTER TABLE tracker_submission ADD KEY (`user_id`); ALTER TABLE tracker_submission ADD KEY(`submit_time`); ALTER TABLE tracker_submission ADD KEY (`branch`); +ALTER TABLE tracker_trend ADD COLUMN `trendgroup_id` bigint(20) NOT NULL DEFAULT '-1'; + CALL create_submissions(); CALL migrate_params(); @@ -50,6 +68,8 @@ CALL migrate_items_to_submissions(); CALL scalar_to_submission(); +CALL create_trendgroups(); + DROP TABLE IF EXISTS tracker_param; RENAME TABLE tracker_submissionparam TO tracker_param; @@ -66,3 +86,9 @@ ALTER TABLE tracker_scalar DROP COLUMN `submit_time`; DROP TABLE IF EXISTS `tracker_scalar2item`; + +ALTER TABLE tracker_trend + DROP COLUMN `producer_id`, + DROP COLUMN `config_item_id`, + DROP COLUMN `test_dataset_id`, + DROP COLUMN `truth_dataset_id`; \ No newline at end of file diff --git a/modules/tracker/models/base/TrendGroupModelBase.php b/modules/tracker/models/base/TrendGroupModelBase.php new file mode 100644 index 000000000..e9be92d61 --- /dev/null +++ b/modules/tracker/models/base/TrendGroupModelBase.php @@ -0,0 +1,86 @@ +_name = 'tracker_trendgroup'; + $this->_key = 'trendgroup_id'; + $this->_mainData = array( + 'trendgroup_id' => array('type' => MIDAS_DATA), + 'producer_id' => array('type' => MIDAS_DATA), + 'config_item_id' => array('type' => MIDAS_DATA), + 'test_dataset_id' => array('type' => MIDAS_DATA), + 'truth_dataset_id' => array('type' => MIDAS_DATA), + 'producer' => array( + 'type' => MIDAS_MANY_TO_ONE, + 'model' => 'Producer', + 'module' => $this->moduleName, + 'parent_column' => 'producer_id', + 'child_column' => 'producer_id', + ), + 'config_item' => array( + 'type' => MIDAS_MANY_TO_ONE, + 'model' => 'Item', + 'parent_column' => 'config_item_id', + 'child_column' => 'item_id', + ), + 'test_dataset_item' => array( + 'type' => MIDAS_MANY_TO_ONE, + 'model' => 'Item', + 'parent_column' => 'test_dataset_id', + 'child_column' => 'item_id', + ), + 'truth_dataset_item' => array( + 'type' => MIDAS_MANY_TO_ONE, + 'model' => 'Item', + 'parent_column' => 'truth_dataset_id', + 'child_column' => 'item_id', + ), + 'trends' => array( + 'type' => MIDAS_ONE_TO_MANY, + 'model' => 'Scalar', + 'module' => $this->moduleName, + 'parent_column' => 'trendgroup_id', + 'child_column' => 'trendgroup_id', + ), + ); + + $this->initialize(); + } + + /** + * Return the trendgroup DAO that matches the given producer id and associated item if the trendgroup exists. + * Otherwise, create the trend DAO. + * + * @param int $producerId producer id + * @param null|int $configItemId configuration item id + * @param null|int $testDatasetId test dataset item id + * @param null|int $truthDatasetId truth dataset item id + * @return Tracker_TrendgroupDao trend DAO + */ + public abstract function createIfNeeded($producerId, $configItemId, $testDatasetId, $truthDatasetId); + +} diff --git a/modules/tracker/models/base/TrendModelBase.php b/modules/tracker/models/base/TrendModelBase.php index 1e8f9c9e7..d406a1868 100644 --- a/modules/tracker/models/base/TrendModelBase.php +++ b/modules/tracker/models/base/TrendModelBase.php @@ -30,38 +30,17 @@ public function __construct() $this->_key = 'trend_id'; $this->_mainData = array( 'trend_id' => array('type' => MIDAS_DATA), - 'producer_id' => array('type' => MIDAS_DATA), 'metric_name' => array('type' => MIDAS_DATA), 'display_name' => array('type' => MIDAS_DATA), 'unit' => array('type' => MIDAS_DATA), - 'config_item_id' => array('type' => MIDAS_DATA), - 'test_dataset_id' => array('type' => MIDAS_DATA), - 'truth_dataset_id' => array('type' => MIDAS_DATA), 'key_metric' => array('type' => MIDAS_DATA), - 'producer' => array( + 'trendgroup_id' => array('type' => MIDAS_DATA), + 'trendgroup' => array( 'type' => MIDAS_MANY_TO_ONE, - 'model' => 'Producer', + 'model' => 'Trendgroup', 'module' => $this->moduleName, - 'parent_column' => 'producer_id', - 'child_column' => 'producer_id', - ), - 'config_item' => array( - 'type' => MIDAS_MANY_TO_ONE, - 'model' => 'Item', - 'parent_column' => 'config_item_id', - 'child_column' => 'item_id', - ), - 'test_dataset_item' => array( - 'type' => MIDAS_MANY_TO_ONE, - 'model' => 'Item', - 'parent_column' => 'test_dataset_id', - 'child_column' => 'item_id', - ), - 'truth_dataset_item' => array( - 'type' => MIDAS_MANY_TO_ONE, - 'model' => 'Item', - 'parent_column' => 'truth_dataset_id', - 'child_column' => 'item_id', + 'parent_column' => 'trendgroup_id', + 'child_column' => 'trendgroup_id', ), 'scalars' => array( 'type' => MIDAS_ONE_TO_MANY, @@ -147,9 +126,16 @@ public function createIfNeeded($producerId, $metricName, $configItemId, $testDat $trendDao = $this->getMatch($producerId, $metricName, $configItemId, $testDatasetId, $truthDatasetId, $unit); if ($trendDao === false) { + + /** @var Tracker_TrendGroupModel $trendGroupModel */ + $trendGroupModel = MidasLoader::loadModel('TrendGroup', $this->moduleName); + /** @var Tracker_TrendDao $trendDao */ $trendDao = MidasLoader::newDao('TrendDao', $this->moduleName); - $trendDao->setProducerId($producerId); + + /** @var Tracker_TrendGroupDao $trendGroupDao */ + $trendGroupDao = $trendGroupModel->createIfNeeded($producerId, $configItemId, $testDatasetId, $truthDatasetId); + $trendDao->setMetricName($metricName); $trendDao->setDisplayName($metricName); if ($unit === false) { @@ -157,17 +143,7 @@ public function createIfNeeded($producerId, $metricName, $configItemId, $testDat } $trendDao->setUnit($unit); - if (!is_null($configItemId)) { - $trendDao->setConfigItemId($configItemId); - } - - if (!is_null($testDatasetId)) { - $trendDao->setTestDatasetId($testDatasetId); - } - - if (!is_null($truthDatasetId)) { - $trendDao->setTruthDatasetId($truthDatasetId); - } + $trendDao->setTrendGroupId($trendGroupDao->getKey()); // Our pgsql code can't handle ACTUAL booleans :deep_sigh: $trendDao->setKeyMetric('0'); @@ -243,7 +219,7 @@ public function policyCheck($trendDao, $userDao = null, $policy = MIDAS_POLICY_R /** @var Tracker_ProducerModel $producerModel */ $producerModel = MidasLoader::loadModel('Producer', $this->moduleName); - $producerDao = $trendDao->getProducer(); + $producerDao = $trendDao->getTrendgroup()->getProducer(); return $producerModel->policyCheck($producerDao, $userDao, $policy); } diff --git a/modules/tracker/models/dao/TrendDao.php b/modules/tracker/models/dao/TrendDao.php index 74e1647f4..055a0ecac 100644 --- a/modules/tracker/models/dao/TrendDao.php +++ b/modules/tracker/models/dao/TrendDao.php @@ -23,32 +23,20 @@ * * @method int getTrendId() * @method void setTrendId(int $trendId) - * @method int getProducerId() - * @method void setProducerId(int $producerId) + * @method int getTrendGroupId() + * @method void setTrendGroupId(int $trendGroupId) * @method string getMetricName() * @method void setMetricName(string $metricName) * @method string getDisplayName() * @method void setDisplayName(string $displayName) * @method string getUnit() * @method void setUnit(string $unit) - * @method int getConfigItemId() - * @method void setConfigItemId(int $configItemId) - * @method int getTestDatasetId() - * @method void setTestDatasetId(int $testDatasetId) - * @method int getTruthDatasetId() - * @method void setTruthDatasetId(int $truthDatasetId) - * @method Tracker_ProducerDao getProducer() - * @method void setProducer(Tracker_ProducerDao $producerDao) - * @method ItemDao getConfigItem() - * @method void setConfigItem(ItemDao $configItemDao) - * @method ItemDao getTestDatasetItem() - * @method void setTestDatasetItem(ItemDao $testDatasetItemDao) - * @method ItemDao getTruthDatasetItem() - * @method void setTruthDatasetItem(ItemDao $truthDatasetItemDao) * @method array getScalars() * @method void setScalars(array $scalarDaos) * @method void setKeyMetric(int $keyMetric) * @method int getKeyMetric() + * @method Tracker_TrendgroupDao getTrendgroup() + * @method void setTrendgroup(Tracker_TrendgroupDao $trendgroup) */ class Tracker_TrendDao extends Tracker_AppDao { @@ -66,4 +54,5 @@ public function isKeyMetric() { return (int) $this->getKeyMetric() === 1; } + } diff --git a/modules/tracker/models/dao/TrendGroupDao.php b/modules/tracker/models/dao/TrendGroupDao.php new file mode 100644 index 000000000..0e4e8545b --- /dev/null +++ b/modules/tracker/models/dao/TrendGroupDao.php @@ -0,0 +1,51 @@ +database->select()->setIntegrityCheck(false + )->where('producer_id = ?', $producerId); + + if (is_null($configItemId)) { + $sql->where('g.config_item_id IS NULL'); + } else { + $sql->where('g.config_item_id = ?', $configItemId); + } + + if (is_null($truthDatasetId)) { + $sql->where('g.truth_dataset_id IS NULL'); + } else { + $sql->where('g.truth_dataset_id = ?', $truthDatasetId); + } + + if (is_null($testDatasetId)) { + $sql->where('g.test_dataset_id IS NULL'); + } else { + $sql->where('g.test_dataset_id = ?', $testDatasetId); + } + + /** @var Tracker_TrendGroupDao $trendGroupDao */ + $trendgroupDao = $this->initDao('Trendgroup', $this->database->fetchRow($sql), $this->moduleName); + + if ($trendgroupDao === false) { + + $trendGroupDao = MidasLoader::newDao('TrendgroupDao', $this->moduleName); + + $trendGroupDao->setProducerId($producerId); + + if (!is_null($configItemId)) { + $trendGroupDao->setConfigItemId($configItemId); + } + + if (!is_null($testDatasetId)) { + $trendGroupDao->setTestDatasetId($testDatasetId); + } + + if (!is_null($truthDatasetId)) { + $trendGroupDao->setTruthDatasetId($truthDatasetId); + } + + $this->save($trendGroupDao); + } + return $trendgroupDao; + } +} diff --git a/modules/tracker/models/pdo/TrendModel.php b/modules/tracker/models/pdo/TrendModel.php index ad20e414e..594175a35 100644 --- a/modules/tracker/models/pdo/TrendModel.php +++ b/modules/tracker/models/pdo/TrendModel.php @@ -36,32 +36,35 @@ class Tracker_TrendModel extends Tracker_TrendModelBase */ public function getMatch($producerId, $metricName, $configItemId, $testDatasetId, $truthDatasetId, $unit = false) { - $sql = $this->database->select()->setIntegrityCheck(false)->where('producer_id = ?', $producerId)->where( - 'metric_name = ?', + $sql = $this->database->select()->setIntegrityCheck(false)->from(array('t' => 'tracker_trend') + )->join(array('g' => 'tracker_trendgroup'), 't.trendgroup_id = g.trendgroup_id' + )->where('g.producer_id = ?', $producerId)->where( + 't.metric_name = ?', $metricName ); if (is_null($configItemId)) { - $sql->where('config_item_id IS NULL'); + $sql->where('g.config_item_id IS NULL'); } else { - $sql->where('config_item_id = ?', $configItemId); + $sql->where('g.config_item_id = ?', $configItemId); } if (is_null($truthDatasetId)) { - $sql->where('truth_dataset_id IS NULL'); + $sql->where('g.truth_dataset_id IS NULL'); } else { - $sql->where('truth_dataset_id = ?', $truthDatasetId); + $sql->where('g.truth_dataset_id = ?', $truthDatasetId); } if (is_null($testDatasetId)) { - $sql->where('test_dataset_id IS NULL'); + $sql->where('g.test_dataset_id IS NULL'); } else { - $sql->where('test_dataset_id = ?', $testDatasetId); + $sql->where('g.test_dataset_id = ?', $testDatasetId); } - if ($unit !== false) { + // TODO(cpatrick): I don't think this is needed. + /* if ($unit !== false) { $sql->where('unit = ?', $unit); - } + }*/ return $this->initDao('Trend', $this->database->fetchRow($sql), $this->moduleName); } @@ -122,10 +125,9 @@ public function getScalars($trendDao, $startDate = null, $endDate = null, $userI */ public function getTrendsGroupByDatasets($producerDao, $onlyKey = false) { - $sql = $this->database->select()->setIntegrityCheck(false)->from( - $this->_name, - array('config_item_id', 'test_dataset_id', 'truth_dataset_id') - )->where('producer_id = ?', $producerDao->getKey())->distinct(); + $sql = $this->database->select()->setIntegrityCheck(false)->from(array('t' => 'tracker_trend'), array('trendgroup_id') + )->join(array('g' => 'tracker_trendgroup'), 't.trendgroup_id = g.trendgroup_id' + )->where('g.producer_id = ?', $producerDao->getKey())->distinct(); /** @var ItemModel $itemModel */ $itemModel = MidasLoader::loadModel('Item'); @@ -166,7 +168,7 @@ public function getTrendsGroupByDatasets($producerDao, $onlyKey = false) */ public function getAllByParams($params) { - $sql = $this->database->select()->setIntegrityCheck(false); + $sql = $this->database->select()->from(array('t' => 'tracker_trend'))->join(array('g' => 'tracker_trendgroup'), 't.trendgroup_id=g.trendgroup_id')->setIntegrityCheck(false); /** * @var string $column diff --git a/modules/tracker/views/trend/view.phtml b/modules/tracker/views/trend/view.phtml index 4f0f50d33..964b0d3d3 100644 --- a/modules/tracker/views/trend/view.phtml +++ b/modules/tracker/views/trend/view.phtml @@ -41,12 +41,14 @@ $this->headScript()->appendFile($this->coreWebroot.'/public/js/jquery/jqplot/jqp if (count($this->trends) === 1) { /** @var Tracker_TrendDao $trendDao */ $trendDao = $this->trends[0]; + /** @var Tracker_TrendgroupDao $trendGroup */ + $trendGroup = $trendDao->getTrendgroup(); ?> Configuration data: getConfigItemId()) { - echo ''.$this->escape($trendDao->getConfigItem()->getName()).''; + if ($trendGroup->getConfigItemId()) { + echo ''.$this->escape($trendGroup->getConfigItem()->getName()).''; } else { echo 'none'; } @@ -55,9 +57,9 @@ $this->headScript()->appendFile($this->coreWebroot.'/public/js/jquery/jqplot/jqp
Test data: getTestDatasetId()) { - echo ''.$this->escape($trendDao->getTestDatasetItem()->getName()).''; + if ($trendGroup->getTestDatasetId()) { + echo ''.$this->escape($trendGroup->getTestDatasetItem()->getName()).''; } else { echo 'none'; } @@ -66,9 +68,9 @@ $this->headScript()->appendFile($this->coreWebroot.'/public/js/jquery/jqplot/jqp
Ground truth data: getTruthDatasetId()) { - echo ''.$this->escape($trendDao->getTruthDatasetItem()->getName()).''; + if ($trendGroup->getTruthDatasetId()) { + echo ''.$this->escape($trendGroup->getTruthDatasetItem()->getName()).''; } else { echo 'none'; } From fddb28bf9751d1ed848da57d63c74c7aaa8bcf71 Mon Sep 17 00:00:00 2001 From: Patrick Reynolds Date: Fri, 8 Apr 2016 00:52:23 -0400 Subject: [PATCH 21/40] Applied fixes from StyleCI --- modules/tracker/models/base/TrendGroupModelBase.php | 3 +-- modules/tracker/models/dao/TrendDao.php | 1 - modules/tracker/models/dao/TrendGroupDao.php | 1 - modules/tracker/models/pdo/AggregateMetricModel.php | 8 ++++---- modules/tracker/models/pdo/TrendGroupModel.php | 4 ++-- 5 files changed, 7 insertions(+), 10 deletions(-) diff --git a/modules/tracker/models/base/TrendGroupModelBase.php b/modules/tracker/models/base/TrendGroupModelBase.php index e9be92d61..1c0fb5fa1 100644 --- a/modules/tracker/models/base/TrendGroupModelBase.php +++ b/modules/tracker/models/base/TrendGroupModelBase.php @@ -81,6 +81,5 @@ public function __construct() * @param null|int $truthDatasetId truth dataset item id * @return Tracker_TrendgroupDao trend DAO */ - public abstract function createIfNeeded($producerId, $configItemId, $testDatasetId, $truthDatasetId); - + abstract public function createIfNeeded($producerId, $configItemId, $testDatasetId, $truthDatasetId); } diff --git a/modules/tracker/models/dao/TrendDao.php b/modules/tracker/models/dao/TrendDao.php index 055a0ecac..e9fb3e15d 100644 --- a/modules/tracker/models/dao/TrendDao.php +++ b/modules/tracker/models/dao/TrendDao.php @@ -54,5 +54,4 @@ public function isKeyMetric() { return (int) $this->getKeyMetric() === 1; } - } diff --git a/modules/tracker/models/dao/TrendGroupDao.php b/modules/tracker/models/dao/TrendGroupDao.php index 0e4e8545b..1d7e6db2e 100644 --- a/modules/tracker/models/dao/TrendGroupDao.php +++ b/modules/tracker/models/dao/TrendGroupDao.php @@ -47,5 +47,4 @@ class Tracker_TrendgroupDao extends Tracker_AppDao /** @var string */ public $_module = 'tracker'; - } diff --git a/modules/tracker/models/pdo/AggregateMetricModel.php b/modules/tracker/models/pdo/AggregateMetricModel.php index ea5ceb53e..4f42451f9 100644 --- a/modules/tracker/models/pdo/AggregateMetricModel.php +++ b/modules/tracker/models/pdo/AggregateMetricModel.php @@ -96,7 +96,7 @@ public function getAggregateMetricInputValuesForSubmission($aggregateMetricSpecD $rows = $this->database->fetchAll($sql); if (count($rows) === 0) { return false; - }; + } $trendIds = array(); /** @var Zend_Db_Table_Row_Abstract $row */ foreach ($rows as $row) { @@ -117,7 +117,7 @@ public function getAggregateMetricInputValuesForSubmission($aggregateMetricSpecD $rows = $this->database->fetchAll($sql); if (count($rows) === 0) { return false; - }; + } $values = array(); /** @var Zend_Db_Table_Row_Abstract $row */ foreach ($rows as $row) { @@ -309,7 +309,7 @@ public function getAggregateMetricsForSubmissions($aggregateMetricSpecDao, $subm $rows = $this->database->fetchAll($sql); if (count($rows) === 0) { return false; - }; + } $aggregateMetricDaosBySubmissionId = array(); /** @var Zend_Db_Table_Row_Abstract $row */ foreach ($rows as $row) { @@ -379,7 +379,7 @@ public function getAggregateMetricsSeries($producerDao, $lastDate = false, $days $rows = $this->database->fetchAll($sql); if (count($rows) === 0) { return array(); - }; + } $metricsSeries = array(); /** @var Zend_Db_Table_Row_Abstract $row */ diff --git a/modules/tracker/models/pdo/TrendGroupModel.php b/modules/tracker/models/pdo/TrendGroupModel.php index d67a2a4a9..b59c32229 100644 --- a/modules/tracker/models/pdo/TrendGroupModel.php +++ b/modules/tracker/models/pdo/TrendGroupModel.php @@ -18,7 +18,7 @@ limitations under the License. =========================================================================*/ -require_once BASE_PATH . '/modules/tracker/models/base/TrendgroupModelBase.php'; +require_once BASE_PATH.'/modules/tracker/models/base/TrendgroupModelBase.php'; /** Trend Group model for the tracker module. */ class Tracker_TrendgroupModel extends Tracker_TrendgroupModelBase @@ -60,7 +60,6 @@ public function createIfNeeded($producerId, $configItemId, $testDatasetId, $trut $trendgroupDao = $this->initDao('Trendgroup', $this->database->fetchRow($sql), $this->moduleName); if ($trendgroupDao === false) { - $trendGroupDao = MidasLoader::newDao('TrendgroupDao', $this->moduleName); $trendGroupDao->setProducerId($producerId); @@ -79,6 +78,7 @@ public function createIfNeeded($producerId, $configItemId, $testDatasetId, $trut $this->save($trendGroupDao); } + return $trendgroupDao; } } From 3ca3bb6c5791c2facac3753a4a197fac8ee57ce8 Mon Sep 17 00:00:00 2001 From: Patrick Reynolds Date: Fri, 8 Apr 2016 18:20:12 -0400 Subject: [PATCH 22/40] Remove pgsql relics from db upgrade. --- modules/tracker/database/upgrade/1.0.1.php | 8 ----- modules/tracker/database/upgrade/1.0.2.php | 6 ---- modules/tracker/database/upgrade/1.0.3.php | 6 ---- modules/tracker/database/upgrade/1.0.4.php | 7 ---- modules/tracker/database/upgrade/1.0.5.php | 7 ---- modules/tracker/database/upgrade/1.2.0.php | 16 --------- modules/tracker/database/upgrade/1.2.1.php | 7 ---- modules/tracker/database/upgrade/1.2.2.php | 17 ---------- modules/tracker/database/upgrade/1.2.3.php | 6 ---- modules/tracker/database/upgrade/1.2.4.php | 38 ---------------------- 10 files changed, 118 deletions(-) diff --git a/modules/tracker/database/upgrade/1.0.1.php b/modules/tracker/database/upgrade/1.0.1.php index 42eb1eede..9e5ef2ae8 100644 --- a/modules/tracker/database/upgrade/1.0.1.php +++ b/modules/tracker/database/upgrade/1.0.1.php @@ -33,12 +33,4 @@ public function mysql() $this->db->query("ALTER TABLE `tracker_scalar` ADD COLUMN `official` tinyint(4) NOT NULL DEFAULT '1';"); $this->db->query('ALTER TABLE `tracker_scalar` ADD KEY (`user_id`);'); } - - /** Upgrade a PostgreSQL database. */ - public function pgsql() - { - $this->db->query('ALTER TABLE tracker_scalar ADD COLUMN user_id bigint NOT NULL DEFAULT -1::bigint;'); - $this->db->query('ALTER TABLE tracker_scalar ADD COLUMN official smallint NOT NULL DEFAULT 1::smallint;'); - $this->db->query('CREATE INDEX tracker_scalar_idx_user_id ON tracker_scalar (user_id);'); - } } diff --git a/modules/tracker/database/upgrade/1.0.2.php b/modules/tracker/database/upgrade/1.0.2.php index c6a66fe22..8fb82f783 100644 --- a/modules/tracker/database/upgrade/1.0.2.php +++ b/modules/tracker/database/upgrade/1.0.2.php @@ -29,10 +29,4 @@ public function mysql() { $this->db->query('ALTER TABLE `tracker_producer` ADD COLUMN `revision_url` text NOT NULL;'); } - - /** Upgrade a PostgreSQL database. */ - public function pgsql() - { - $this->db->query("ALTER TABLE tracker_producer ADD COLUMN revision_url text NOT NULL DEFAULT '';"); - } } diff --git a/modules/tracker/database/upgrade/1.0.3.php b/modules/tracker/database/upgrade/1.0.3.php index a38e939e3..5e2c61f27 100644 --- a/modules/tracker/database/upgrade/1.0.3.php +++ b/modules/tracker/database/upgrade/1.0.3.php @@ -26,10 +26,4 @@ public function mysql() { $this->db->query('ALTER TABLE `tracker_scalar` ADD COLUMN `build_results_url` text NOT NULL;'); } - - /** Upgrade a PostgreSQL database. */ - public function pgsql() - { - $this->db->query('ALTER TABLE tracker_scalar ADD COLUMN build_results_url text NOT NULL;'); - } } diff --git a/modules/tracker/database/upgrade/1.0.4.php b/modules/tracker/database/upgrade/1.0.4.php index e4fbe71ac..699fd1464 100644 --- a/modules/tracker/database/upgrade/1.0.4.php +++ b/modules/tracker/database/upgrade/1.0.4.php @@ -30,11 +30,4 @@ public function mysql() $this->db->query("ALTER TABLE `tracker_scalar` ADD COLUMN `branch` varchar(255) NOT NULL DEFAULT '';"); $this->db->query('ALTER TABLE `tracker_scalar` ADD KEY (`branch`);'); } - - /** Upgrade a PostgreSQL database. */ - public function pgsql() - { - $this->db->query("ALTER TABLE tracker_scalar ADD COLUMN branch character varying(255) NOT NULL DEFAULT ''::character varying;"); - $this->db->query('CREATE INDEX tracker_scalar_idx_branch ON tracker_scalar (branch);'); - } } diff --git a/modules/tracker/database/upgrade/1.0.5.php b/modules/tracker/database/upgrade/1.0.5.php index 5ffc3f7bd..6148ea671 100644 --- a/modules/tracker/database/upgrade/1.0.5.php +++ b/modules/tracker/database/upgrade/1.0.5.php @@ -27,11 +27,4 @@ public function mysql() $this->db->query('ALTER TABLE `tracker_scalar` ADD COLUMN `params` text;'); $this->db->query('ALTER TABLE `tracker_scalar` ADD COLUMN `extra_urls` text;'); } - - /** Upgrade a PostgreSQL database. */ - public function pgsql() - { - $this->db->query('ALTER TABLE tracker_scalar ADD COLUMN params text;'); - $this->db->query('ALTER TABLE tracker_scalar ADD COLUMN extra_urls text;'); - } } diff --git a/modules/tracker/database/upgrade/1.2.0.php b/modules/tracker/database/upgrade/1.2.0.php index af98c8275..b23b3d0aa 100644 --- a/modules/tracker/database/upgrade/1.2.0.php +++ b/modules/tracker/database/upgrade/1.2.0.php @@ -38,20 +38,4 @@ public function mysql() ' UNIQUE KEY (`uuid`)'. ') DEFAULT CHARSET=utf8;'); } - - /** Upgrade a PostgreSQL database. */ - public function pgsql() - { - $this->db->query('ALTER TABLE tracker_scalar ADD COLUMN submission_id bigint NOT NULL DEFAULT -1::bigint;'); - $this->db->query( - 'CREATE TABLE IF NOT EXISTS "tracker_submission" ('. - ' "submission_id" serial PRIMARY KEY,'. - ' "producer_id" bigint,'. - ' "name" character varying(255) NOT NULL DEFAULT \'\'::character varying,'. - ' "uuid" character varying(255) NOT NULL DEFAULT \'\'::character varying,'. - ' "submit_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP);' - ); - $this->db->query('CREATE UNIQUE INDEX "tracker_submission_uuid" ON "tracker_submission" ("uuid");'); - $this->db->query('CREATE INDEX "tracker_submission_submit_time" ON "tracker_submission" ("submit_time");'); - } } diff --git a/modules/tracker/database/upgrade/1.2.1.php b/modules/tracker/database/upgrade/1.2.1.php index aad70a8a1..a573f37ae 100644 --- a/modules/tracker/database/upgrade/1.2.1.php +++ b/modules/tracker/database/upgrade/1.2.1.php @@ -27,11 +27,4 @@ public function mysql() $this->db->query( 'ALTER TABLE `tracker_trend` ADD COLUMN `key_metric` tinyint(4) NOT NULL DEFAULT \'0\''); } - - /** Upgrade a PostgreSQL database. */ - public function pgsql() - { - $this->db->query( - 'ALTER TABLE tracker_trend ADD COLUMN key_metric smallint NOT NULL DEFAULT 0::smallint'); - } } diff --git a/modules/tracker/database/upgrade/1.2.2.php b/modules/tracker/database/upgrade/1.2.2.php index 52031f772..66271a957 100644 --- a/modules/tracker/database/upgrade/1.2.2.php +++ b/modules/tracker/database/upgrade/1.2.2.php @@ -39,23 +39,6 @@ public function mysql() $this->db->query('ALTER TABLE `tracker_scalar` DROP `params`;'); } - /** Upgrade a PostgreSQL database. */ - public function pgsql() - { - $this->db->query( - "CREATE TABLE IF NOT EXISTS tracker_param ( - param_id serial PRIMARY KEY, - scalar_id bigint NOT NULL, - param_name character varying(255) NOT NULL, - param_type text CHECK (param_type in ('text', 'numeric')), - text_value text, - numeric_value double precision);" - ); - $this->db->query('CREATE INDEX tracker_param_param_name_idx ON tracker_param (param_name);'); - $this->migrateScalarParams(); - $this->db->query('ALTER TABLE tracker_scalar DROP COLUMN params;'); - } - /** Migrate tracker_scalar params to tracker_param. */ private function migrateScalarParams() { diff --git a/modules/tracker/database/upgrade/1.2.3.php b/modules/tracker/database/upgrade/1.2.3.php index 2ba0b8c21..043252eda 100644 --- a/modules/tracker/database/upgrade/1.2.3.php +++ b/modules/tracker/database/upgrade/1.2.3.php @@ -26,10 +26,4 @@ public function mysql() { $this->db->query('ALTER TABLE `tracker_scalar` ADD COLUMN `reproduction_command` text;'); } - - /** Upgrade a PostgreSQL database. */ - public function pgsql() - { - $this->db->query('ALTER TABLE tracker_scalar ADD COLUMN reproduction_command text;'); - } } diff --git a/modules/tracker/database/upgrade/1.2.4.php b/modules/tracker/database/upgrade/1.2.4.php index d0088b450..570fdb43f 100644 --- a/modules/tracker/database/upgrade/1.2.4.php +++ b/modules/tracker/database/upgrade/1.2.4.php @@ -58,42 +58,4 @@ public function mysql() ') DEFAULT CHARSET=utf8;' ); } - - /** Upgrade a PostgreSQL database. */ - public function pgsql() - { - $this->db->query( - 'CREATE TABLE IF NOT EXISTS "tracker_aggregate_metric" ('. - ' "aggregate_metric_id" serial PRIMARY KEY,'. - ' "aggregate_metric_spec_id" bigint NOT NULL,'. - ' "submission_id" bigint NOT NULL,'. - ' "value" double precision'. - ');' - ); - $this->db->query('CREATE INDEX "tracker_aggregate_metric_aggregate_metric_spec_id" ON "tracker_aggregate_metric" ("aggregate_metric_spec_id");'); - $this->db->query('CREATE INDEX "tracker_aggregate_metric_submission_id" ON "tracker_aggregate_metric" ("submission_id");'); - $this->db->query( - 'CREATE TABLE IF NOT EXISTS "tracker_aggregate_metric_spec" ('. - ' "aggregate_metric_spec_id" serial PRIMARY KEY,'. - ' "producer_id" bigint NOT NULL,'. - ' "branch" character varying(255) NOT NULL,'. - ' "name" character varying(255) NOT NULL,'. - ' "description" character varying(255) NOT NULL,'. - ' "spec" text,'. - ' "value" double precision,'. - ' "comparison" character varying(2) NOT NULL'. - ');' - ); - $this->db->query('CREATE INDEX "tracker_aggregate_metric_spec_producer_id" ON "tracker_aggregate_metric_spec" ("producer_id");'); - $this->db->query('CREATE INDEX "tracker_aggregate_metric_spec_branch" ON "tracker_aggregate_metric_spec" ("branch");'); - $this->db->query( - 'CREATE TABLE IF NOT EXISTS "tracker_user2aggregate_metric_spec" ('. - ' "id" serial PRIMARY KEY,'. - ' "user_id" bigint NOT NULL,'. - ' "aggregate_metric_spec_id" bigint NOT NULL,'. - ' PRIMARY_KEY("user_id", "aggregate_metric_spec_id")'. - ');' - ); - $this->db->query('CREATE INDEX "tracker_user2aggregate_metric_spec_ams_id_idx" ON "tracker_user2aggregate_metric_spec" ("aggregate_metric_spec_id");'); - } } From f7705ed6580b0374af3dbabe278a8a7e84552422 Mon Sep 17 00:00:00 2001 From: Patrick Reynolds Date: Fri, 8 Apr 2016 18:24:54 -0400 Subject: [PATCH 23/40] Add trendgroup to submission2item. --- .../controllers/components/ApiComponent.php | 21 ++++++++++++++++++- modules/tracker/database/mysql/2.0.0.sql | 5 ++++- .../mysql/migrate_items_to_submissions.sql | 12 ++++++----- .../database/mysql/upgrade_to_2.0.0.sql | 9 +++++--- .../models/base/SubmissionModelBase.php | 6 ++++-- .../tracker/models/pdo/SubmissionModel.php | 16 +++++++++++--- 6 files changed, 54 insertions(+), 15 deletions(-) diff --git a/modules/tracker/controllers/components/ApiComponent.php b/modules/tracker/controllers/components/ApiComponent.php index 179a108d5..14ccc0c5f 100644 --- a/modules/tracker/controllers/components/ApiComponent.php +++ b/modules/tracker/controllers/components/ApiComponent.php @@ -61,6 +61,9 @@ private function _getUser($args) * @param submissionUuid the uuid of the submission to associate the item with * @param itemId The id of the item to associate with the scalar * @param label The label describing the nature of the association + * @param testDatasetId the id for the test dataset + * @param truthDatasetId the id of the truth dataset + * @param configItemId the id of the config dataset * @throws Exception */ public function itemAssociate($args) @@ -73,6 +76,10 @@ public function itemAssociate($args) /** @var Tracker_ScalarModel $scalarModel */ $submissionModel = MidasLoader::loadModel('Submission', 'tracker'); + + /** @var Tracker_TrendgroupModel $trendgroupModel */ + $trendgroupModel = MidasLoader::loadModel('Trendgroup', 'tracker'); + $this->_checkKeys(array('submissionUuid', 'itemId', 'label'), $args); $user = $this->_getUser($args); @@ -102,7 +109,19 @@ public function itemAssociate($args) throw new Exception('Write permission on the community required', 403); } - $submissionModel->associateItem($submission, $item, $args['label']); + $configItemId = $args['configItemId']; + $testDatasetId = $args['testDatasetId']; + $truthDatasetId = $args['truthDatasetId']; + + /** @var Tracker_TrendgroupDao $trendgroup */ + $trendgroup = $trendgroupModel->createIfNeeded( + $submission->getProducer()->getKey(), + $configItemId, + $testDatasetId, + $truthDatasetId + ); + + $submissionModel->associateItem($submission, $item, $args['label'], $trendgroup); } /** diff --git a/modules/tracker/database/mysql/2.0.0.sql b/modules/tracker/database/mysql/2.0.0.sql index 6a4ea6729..4324adc96 100644 --- a/modules/tracker/database/mysql/2.0.0.sql +++ b/modules/tracker/database/mysql/2.0.0.sql @@ -48,7 +48,10 @@ CREATE TABLE IF NOT EXISTS `tracker_submission2item` ( `submission_id` bigint(20) NOT NULL, `item_id` bigint(20) NOT NULL, `label` varchar(255) NOT NULL, - KEY (`submission_id`) + `trendgroup_id` bigint(20) NOT NULL, + KEY (`submission_id`), + KEY (`item_id`), + KEY (`trendgroup_id`) ) DEFAULT CHARSET=utf8; CREATE TABLE IF NOT EXISTS `tracker_threshold_notification` ( diff --git a/modules/tracker/database/mysql/migrate_items_to_submissions.sql b/modules/tracker/database/mysql/migrate_items_to_submissions.sql index a542d0ec4..d17330702 100644 --- a/modules/tracker/database/mysql/migrate_items_to_submissions.sql +++ b/modules/tracker/database/mysql/migrate_items_to_submissions.sql @@ -5,22 +5,24 @@ BEGIN DECLARE cur_item_id bigint(20) default -1; DECLARE cur_submission_id bigint(20) default -1; DECLARE cur_label varchar(255) default ''; + DECLARE cur_trendgroup_id bigint(20) default -1; DECLARE curs CURSOR FOR - SELECT DISTINCT ti.item_id, ti.label, tu.submission_id FROM - tracker_scalar AS ts, tracker_submission AS tu, tracker_scalar2item AS ti WHERE - ts.submission_id=tu.submission_id AND ts.scalar_id=ti.scalar_id; + SELECT DISTINCT ti.item_id, ti.label, tu.submission_id, tt.trendgroup_id FROM + tracker_scalar AS ts, tracker_submission AS tu, tracker_scalar2item AS ti, tracker_trend as tt WHERE + ts.submission_id=tu.submission_id AND ts.scalar_id=ti.scalar_id AND ts.trend_id=tt.trend_id; DECLARE CONTINUE HANDLER FOR NOT FOUND SET finished = 1; OPEN curs; get_items: LOOP - FETCH curs INTO cur_item_id, cur_label, cur_submission_id; + FETCH curs INTO cur_item_id, cur_label, cur_submission_id, cur_trendgroup_id; IF finished = 1 THEN LEAVE get_items; END IF; - INSERT INTO tracker_submission2item (submission_id, item_id, label) VALUES (cur_submission_id, cur_item_id, cur_label); + INSERT INTO tracker_submission2item (submission_id, item_id, label, trendgroup_id) + VALUES (cur_submission_id, cur_item_id, cur_label, cur_trendgroup_id); END LOOP get_items; diff --git a/modules/tracker/database/mysql/upgrade_to_2.0.0.sql b/modules/tracker/database/mysql/upgrade_to_2.0.0.sql index c17d3b805..614315f22 100644 --- a/modules/tracker/database/mysql/upgrade_to_2.0.0.sql +++ b/modules/tracker/database/mysql/upgrade_to_2.0.0.sql @@ -4,7 +4,10 @@ CREATE TABLE IF NOT EXISTS `tracker_submission2item` ( `submission_id` bigint(20) NOT NULL, `item_id` bigint(20) NOT NULL, `label` varchar(255) NOT NULL, - KEY (`submission_id`) + `trendgroup_id` bigint(20) NOT NULL, + KEY (`submission_id`), + KEY (`item_id`), + KEY (`trendgroup_id`) ) DEFAULT CHARSET=utf8; CREATE TABLE IF NOT EXISTS `tracker_submissionparam` ( @@ -64,12 +67,12 @@ CALL create_submissions(); CALL migrate_params(); +CALL create_trendgroups(); + CALL migrate_items_to_submissions(); CALL scalar_to_submission(); -CALL create_trendgroups(); - DROP TABLE IF EXISTS tracker_param; RENAME TABLE tracker_submissionparam TO tracker_param; diff --git a/modules/tracker/models/base/SubmissionModelBase.php b/modules/tracker/models/base/SubmissionModelBase.php index eaa5821bc..52b6127ae 100644 --- a/modules/tracker/models/base/SubmissionModelBase.php +++ b/modules/tracker/models/base/SubmissionModelBase.php @@ -74,16 +74,18 @@ public function __construct() * @param Tracker_SubmissionDao $submissionDao submission DAO * @param ItemDao $itemDao item DAO * @param string $label label + * @param Tracker_TrendgroupDao $trendgroupDao trendgroup DAO */ - abstract public function associateItem($submissionDao, $itemDao, $label); + abstract public function associateItem($submissionDao, $itemDao, $label, $trendgroupDao); /** * Return the items associated with the given submission. * * @param Tracker_SubmissionDao $submissionDao submission DAO + * @param Tracker_TrendgroupDao $trendgroupDao trendgroup DAO * @return array array of associative arrays with keys "item" and "label" */ - abstract public function getAssociatedItems($submissionDao); + abstract public function getAssociatedItems($submissionDao, $trendgroupDao); /** * Create a submission. diff --git a/modules/tracker/models/pdo/SubmissionModel.php b/modules/tracker/models/pdo/SubmissionModel.php index 09c219cbf..ab2b6e262 100644 --- a/modules/tracker/models/pdo/SubmissionModel.php +++ b/modules/tracker/models/pdo/SubmissionModel.php @@ -33,10 +33,16 @@ class Tracker_SubmissionModel extends Tracker_SubmissionModelBase * @param Tracker_SubmissionDao $submissionDao submission DAO * @param ItemDao $itemDao item DAO * @param string $label label + * @param Tracker_TrendgroupDao $trendgroupDao trendgroup DAO */ - public function associateItem($submissionDao, $itemDao, $label) + public function associateItem($submissionDao, $itemDao, $label, $trendgroupDao) { - $data = array('submission_id' => $submissionDao->getKey(), 'item_id' => $itemDao->getKey(), 'label' => $label); + $data = array( + 'submission_id' => $submissionDao->getKey(), + 'item_id' => $itemDao->getKey(), + 'label' => $label, + 'trendgroup_id' => $trendgroupDao->getKey() + ); $this->database->getDB()->insert('tracker_submission2item', $data); } @@ -44,13 +50,17 @@ public function associateItem($submissionDao, $itemDao, $label) * Return the items associated with the given submission. * * @param Tracker_SubmissionDao $submissionDao submission DAO + * @param Tracker_TrendgroupDao $trendgroupDao trendgroup DAO * @return array array of associative arrays with keys "item" and "label" */ - public function getAssociatedItems($submissionDao) + public function getAssociatedItems($submissionDao, $trendgroupDao) { $sql = $this->database->select()->setIntegrityCheck(false)->from('tracker_submission2item')->where( 'submission_id = ?', $submissionDao->getKey() + )->where( + 'trendgroup_id = ?', + $trendgroupDao->getKey() ); $rows = $this->database->fetchAll($sql); $results = array(); From aa2709cb79aa4e017dda5a1ac9f02a914f7cf92c Mon Sep 17 00:00:00 2001 From: Patrick Reynolds Date: Fri, 8 Apr 2016 20:05:08 -0400 Subject: [PATCH 24/40] Applied fixes from StyleCI --- modules/tracker/models/pdo/SubmissionModel.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/tracker/models/pdo/SubmissionModel.php b/modules/tracker/models/pdo/SubmissionModel.php index ab2b6e262..7ab147175 100644 --- a/modules/tracker/models/pdo/SubmissionModel.php +++ b/modules/tracker/models/pdo/SubmissionModel.php @@ -41,7 +41,7 @@ public function associateItem($submissionDao, $itemDao, $label, $trendgroupDao) 'submission_id' => $submissionDao->getKey(), 'item_id' => $itemDao->getKey(), 'label' => $label, - 'trendgroup_id' => $trendgroupDao->getKey() + 'trendgroup_id' => $trendgroupDao->getKey(), ); $this->database->getDB()->insert('tracker_submission2item', $data); } From e3e9eb6f76dde5874467e597bd0f517c808d1014 Mon Sep 17 00:00:00 2001 From: Patrick Reynolds Date: Fri, 8 Apr 2016 21:15:44 -0400 Subject: [PATCH 25/40] Fix tracker tests due to trend group additions. This also uncovered some implementation issues. Hurray tests and thanks to @mgrauer for writing them! --- modules/tracker/database/mysql/2.0.0.sql | 3 +- .../tracker/models/base/TrendModelBase.php | 4 +- .../models/pdo/AggregateMetricModel.php | 1 + .../tracker/models/pdo/TrendGroupModel.php | 24 +-- .../tests/databaseDataset/aggregateMetric.xml | 169 +++++++++--------- .../tracker/tests/databaseDataset/default.xml | 11 +- 6 files changed, 106 insertions(+), 106 deletions(-) diff --git a/modules/tracker/database/mysql/2.0.0.sql b/modules/tracker/database/mysql/2.0.0.sql index 4324adc96..9a5d56a84 100644 --- a/modules/tracker/database/mysql/2.0.0.sql +++ b/modules/tracker/database/mysql/2.0.0.sql @@ -72,8 +72,7 @@ CREATE TABLE IF NOT EXISTS `tracker_trend` ( `display_name` varchar(255) NOT NULL, `unit` varchar(255) NOT NULL, `key_metric` tinyint(4) NOT NULL DEFAULT '0', - PRIMARY KEY (`trend_id`), - KEY (`producer_id`) + PRIMARY KEY (`trend_id`) ) DEFAULT CHARSET=utf8; CREATE TABLE IF NOT EXISTS `tracker_trendgroup` ( diff --git a/modules/tracker/models/base/TrendModelBase.php b/modules/tracker/models/base/TrendModelBase.php index d406a1868..a43c37e45 100644 --- a/modules/tracker/models/base/TrendModelBase.php +++ b/modules/tracker/models/base/TrendModelBase.php @@ -128,7 +128,7 @@ public function createIfNeeded($producerId, $metricName, $configItemId, $testDat if ($trendDao === false) { /** @var Tracker_TrendGroupModel $trendGroupModel */ - $trendGroupModel = MidasLoader::loadModel('TrendGroup', $this->moduleName); + $trendGroupModel = MidasLoader::loadModel('Trendgroup', $this->moduleName); /** @var Tracker_TrendDao $trendDao */ $trendDao = MidasLoader::newDao('TrendDao', $this->moduleName); @@ -143,7 +143,7 @@ public function createIfNeeded($producerId, $metricName, $configItemId, $testDat } $trendDao->setUnit($unit); - $trendDao->setTrendGroupId($trendGroupDao->getKey()); + $trendDao->setTrendgroupId($trendGroupDao->getKey()); // Our pgsql code can't handle ACTUAL booleans :deep_sigh: $trendDao->setKeyMetric('0'); diff --git a/modules/tracker/models/pdo/AggregateMetricModel.php b/modules/tracker/models/pdo/AggregateMetricModel.php index 4f42451f9..9ffd6ed18 100644 --- a/modules/tracker/models/pdo/AggregateMetricModel.php +++ b/modules/tracker/models/pdo/AggregateMetricModel.php @@ -90,6 +90,7 @@ public function getAggregateMetricInputValuesForSubmission($aggregateMetricSpecD // Get the list of relevant trend_ids. $sql = $this->database->select()->setIntegrityCheck(false) ->from('tracker_trend', array('trend_id')) + ->join('tracker_trendgroup', 'tracker_trendgroup.trendgroup_id=tracker_trend.trendgroup_id') ->where('key_metric = ?', 1) ->where('producer_id = ?', $aggregateMetricSpecDao->getProducerId()) ->where('metric_name = ?', $metricName); diff --git a/modules/tracker/models/pdo/TrendGroupModel.php b/modules/tracker/models/pdo/TrendGroupModel.php index b59c32229..544b5be7e 100644 --- a/modules/tracker/models/pdo/TrendGroupModel.php +++ b/modules/tracker/models/pdo/TrendGroupModel.php @@ -39,44 +39,44 @@ public function createIfNeeded($producerId, $configItemId, $testDatasetId, $trut )->where('producer_id = ?', $producerId); if (is_null($configItemId)) { - $sql->where('g.config_item_id IS NULL'); + $sql->where('config_item_id IS NULL'); } else { - $sql->where('g.config_item_id = ?', $configItemId); + $sql->where('config_item_id = ?', $configItemId); } if (is_null($truthDatasetId)) { - $sql->where('g.truth_dataset_id IS NULL'); + $sql->where('truth_dataset_id IS NULL'); } else { - $sql->where('g.truth_dataset_id = ?', $truthDatasetId); + $sql->where('truth_dataset_id = ?', $truthDatasetId); } if (is_null($testDatasetId)) { - $sql->where('g.test_dataset_id IS NULL'); + $sql->where('test_dataset_id IS NULL'); } else { - $sql->where('g.test_dataset_id = ?', $testDatasetId); + $sql->where('test_dataset_id = ?', $testDatasetId); } /** @var Tracker_TrendGroupDao $trendGroupDao */ $trendgroupDao = $this->initDao('Trendgroup', $this->database->fetchRow($sql), $this->moduleName); if ($trendgroupDao === false) { - $trendGroupDao = MidasLoader::newDao('TrendgroupDao', $this->moduleName); + $trendgroupDao = MidasLoader::newDao('TrendgroupDao', $this->moduleName); - $trendGroupDao->setProducerId($producerId); + $trendgroupDao->setProducerId($producerId); if (!is_null($configItemId)) { - $trendGroupDao->setConfigItemId($configItemId); + $trendgroupDao->setConfigItemId($configItemId); } if (!is_null($testDatasetId)) { - $trendGroupDao->setTestDatasetId($testDatasetId); + $trendgroupDao->setTestDatasetId($testDatasetId); } if (!is_null($truthDatasetId)) { - $trendGroupDao->setTruthDatasetId($truthDatasetId); + $trendgroupDao->setTruthDatasetId($truthDatasetId); } - $this->save($trendGroupDao); + $this->save($trendgroupDao); } return $trendgroupDao; diff --git a/modules/tracker/tests/databaseDataset/aggregateMetric.xml b/modules/tracker/tests/databaseDataset/aggregateMetric.xml index dc7f9e6c2..04117f9a1 100644 --- a/modules/tracker/tests/databaseDataset/aggregateMetric.xml +++ b/modules/tracker/tests/databaseDataset/aggregateMetric.xml @@ -2,94 +2,95 @@ + - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + - + - + diff --git a/modules/tracker/tests/databaseDataset/default.xml b/modules/tracker/tests/databaseDataset/default.xml index feb9d99b8..8236ad9f8 100644 --- a/modules/tracker/tests/databaseDataset/default.xml +++ b/modules/tracker/tests/databaseDataset/default.xml @@ -2,10 +2,9 @@ - - - + + + + From 63834146f3360981c98a886b934662ddcb3e4fd1 Mon Sep 17 00:00:00 2001 From: Patrick Reynolds Date: Fri, 8 Apr 2016 21:41:43 -0400 Subject: [PATCH 26/40] Fix case of trend model filenames. --- .../base/{TrendGroupModelBase.php => TrendgroupModelBase.php} | 0 .../tracker/models/dao/{TrendGroupDao.php => TrendgroupDao.php} | 0 .../models/pdo/{TrendGroupModel.php => TrendgroupModel.php} | 0 3 files changed, 0 insertions(+), 0 deletions(-) rename modules/tracker/models/base/{TrendGroupModelBase.php => TrendgroupModelBase.php} (100%) rename modules/tracker/models/dao/{TrendGroupDao.php => TrendgroupDao.php} (100%) rename modules/tracker/models/pdo/{TrendGroupModel.php => TrendgroupModel.php} (100%) diff --git a/modules/tracker/models/base/TrendGroupModelBase.php b/modules/tracker/models/base/TrendgroupModelBase.php similarity index 100% rename from modules/tracker/models/base/TrendGroupModelBase.php rename to modules/tracker/models/base/TrendgroupModelBase.php diff --git a/modules/tracker/models/dao/TrendGroupDao.php b/modules/tracker/models/dao/TrendgroupDao.php similarity index 100% rename from modules/tracker/models/dao/TrendGroupDao.php rename to modules/tracker/models/dao/TrendgroupDao.php diff --git a/modules/tracker/models/pdo/TrendGroupModel.php b/modules/tracker/models/pdo/TrendgroupModel.php similarity index 100% rename from modules/tracker/models/pdo/TrendGroupModel.php rename to modules/tracker/models/pdo/TrendgroupModel.php From 6ef450c7917889385a81060d3670248cd0f60706 Mon Sep 17 00:00:00 2001 From: Patrick Reynolds Date: Sat, 9 Apr 2016 11:10:07 -0400 Subject: [PATCH 27/40] Add indices for producer page performance. --- modules/tracker/database/mysql/2.0.0.sql | 4 +++- modules/tracker/database/mysql/upgrade_to_2.0.0.sql | 6 ++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/modules/tracker/database/mysql/2.0.0.sql b/modules/tracker/database/mysql/2.0.0.sql index 9a5d56a84..9f483a2dc 100644 --- a/modules/tracker/database/mysql/2.0.0.sql +++ b/modules/tracker/database/mysql/2.0.0.sql @@ -72,7 +72,8 @@ CREATE TABLE IF NOT EXISTS `tracker_trend` ( `display_name` varchar(255) NOT NULL, `unit` varchar(255) NOT NULL, `key_metric` tinyint(4) NOT NULL DEFAULT '0', - PRIMARY KEY (`trend_id`) + PRIMARY KEY (`trend_id`), + KEY (`trendgroup_id`) ) DEFAULT CHARSET=utf8; CREATE TABLE IF NOT EXISTS `tracker_trendgroup` ( @@ -82,6 +83,7 @@ CREATE TABLE IF NOT EXISTS `tracker_trendgroup` ( `test_dataset_id` bigint(20), `truth_dataset_id` bigint(20), PRIMARY KEY (`trendgroup_id`), + KEY (`producer_id`), KEY (`config_item_id`), KEY (`test_dataset_id`), KEY (`truth_dataset_id`) diff --git a/modules/tracker/database/mysql/upgrade_to_2.0.0.sql b/modules/tracker/database/mysql/upgrade_to_2.0.0.sql index 614315f22..e7101faa9 100644 --- a/modules/tracker/database/mysql/upgrade_to_2.0.0.sql +++ b/modules/tracker/database/mysql/upgrade_to_2.0.0.sql @@ -29,6 +29,7 @@ CREATE TABLE IF NOT EXISTS `tracker_trendgroup` ( `test_dataset_id` bigint(20), `truth_dataset_id` bigint(20), PRIMARY KEY (`trendgroup_id`), + KEY (`producer_id`), KEY (`config_item_id`), KEY (`test_dataset_id`), KEY (`truth_dataset_id`) @@ -62,6 +63,7 @@ ALTER TABLE tracker_submission ADD KEY(`submit_time`); ALTER TABLE tracker_submission ADD KEY (`branch`); ALTER TABLE tracker_trend ADD COLUMN `trendgroup_id` bigint(20) NOT NULL DEFAULT '-1'; +ALTER TABLE tracker_trend ADD KEY (`trendgroup_id`); CALL create_submissions(); @@ -91,7 +93,7 @@ ALTER TABLE tracker_scalar DROP TABLE IF EXISTS `tracker_scalar2item`; ALTER TABLE tracker_trend - DROP COLUMN `producer_id`, + DROP COLUMN `producer_id`, DROP COLUMN `config_item_id`, DROP COLUMN `test_dataset_id`, - DROP COLUMN `truth_dataset_id`; \ No newline at end of file + DROP COLUMN `truth_dataset_id`; From 8782d155ca9205bd5f0190b0a0d8b7c69f9f1410 Mon Sep 17 00:00:00 2001 From: Patrick Reynolds Date: Mon, 11 Apr 2016 18:34:06 -0400 Subject: [PATCH 28/40] Respond to review from @mgrauer. --- .../controllers/ProducerController.php | 2 +- .../controllers/components/ApiComponent.php | 8 ++--- modules/tracker/database/mysql/2.0.0.sql | 1 + .../tracker/models/base/TrendModelBase.php | 15 +++++----- .../models/base/TrendgroupModelBase.php | 2 +- modules/tracker/models/pdo/TrendModel.php | 29 +++++++------------ 6 files changed, 24 insertions(+), 33 deletions(-) diff --git a/modules/tracker/controllers/ProducerController.php b/modules/tracker/controllers/ProducerController.php index e3fc25dc7..f27eea86f 100644 --- a/modules/tracker/controllers/ProducerController.php +++ b/modules/tracker/controllers/ProducerController.php @@ -92,7 +92,7 @@ public function viewAction() } $this->view->producer = $producerDao; - $this->view->trendGroups = $this->Tracker_Trend->getTrendsGroupByDatasets($producerDao); + $this->view->trendGroups = $this->Tracker_Trend->getTrendsByGroup($producerDao); $this->view->isAdmin = $this->Tracker_Producer->policyCheck($producerDao, $this->userSession->Dao, MIDAS_POLICY_ADMIN); $this->view->json['tracker']['producer'] = $producerDao; diff --git a/modules/tracker/controllers/components/ApiComponent.php b/modules/tracker/controllers/components/ApiComponent.php index 14ccc0c5f..1da890101 100644 --- a/modules/tracker/controllers/components/ApiComponent.php +++ b/modules/tracker/controllers/components/ApiComponent.php @@ -59,11 +59,11 @@ private function _getUser($args) * Associate a result item with a particular submission. * * @param submissionUuid the uuid of the submission to associate the item with - * @param itemId The id of the item to associate with the scalar + * @param itemId The id of the item to associate with the submission * @param label The label describing the nature of the association - * @param testDatasetId the id for the test dataset - * @param truthDatasetId the id of the truth dataset - * @param configItemId the id of the config dataset + * @param testDatasetId (Optional) the id for the test dataset + * @param truthDatasetId (Optional) the id of the truth dataset + * @param configItemId (Optional) the id of the config dataset * @throws Exception */ public function itemAssociate($args) diff --git a/modules/tracker/database/mysql/2.0.0.sql b/modules/tracker/database/mysql/2.0.0.sql index 9f483a2dc..2dc965dd5 100644 --- a/modules/tracker/database/mysql/2.0.0.sql +++ b/modules/tracker/database/mysql/2.0.0.sql @@ -97,6 +97,7 @@ CREATE TABLE IF NOT EXISTS `tracker_param` ( `text_value` text, `numeric_value` double, PRIMARY KEY (`param_id`), + KEY (`submission_id`), KEY (`param_name`) ) DEFAULT CHARSET=utf8; diff --git a/modules/tracker/models/base/TrendModelBase.php b/modules/tracker/models/base/TrendModelBase.php index a43c37e45..0a25df14a 100644 --- a/modules/tracker/models/base/TrendModelBase.php +++ b/modules/tracker/models/base/TrendModelBase.php @@ -55,17 +55,16 @@ public function __construct() } /** - * Return the trend DAO that matches the given the producer id, metric name, associated items, and unit. + * Return the trend DAO that matches the given the producer id, metric name, and associated items. * * @param int $producerId producer id * @param string $metricName metric name * @param null|int $configItemId configuration item id * @param null|int $testDatasetId test dataset item id * @param null|int $truthDatasetId truth dataset item id - * @param false|string $unit (Optional) scalar value unit, defaults to false * @return false|Tracker_TrendDao trend DAO or false if none exists */ - abstract public function getMatch($producerId, $metricName, $configItemId, $testDatasetId, $truthDatasetId, $unit = false); + abstract public function getMatch($producerId, $metricName, $configItemId, $testDatasetId, $truthDatasetId); /** * Return the trend DAOs that match the given associative array of database columns and values. @@ -88,14 +87,14 @@ abstract public function getAllByParams($params); abstract public function getScalars($trendDao, $startDate = null, $endDate = null, $userId = null, $branch = null); /** - * Return all trends corresponding to the given producer. They will be grouped by distinct - * config/test/truth dataset combinations. + * Return all trends corresponding to the given producer. They will be grouped by their trend + * group and returned along with the test, truth, and config item DAOs. * * @param Tracker_ProducerDao $producerDao producer DAO * @param bool $onlyKey whether to return only key trends - * @return array + * @return array array of associative arrays with keys "configItem", "testDataset", "truthDataset", and "trends" */ - abstract public function getTrendsGroupByDatasets($producerDao, $onlyKey = false); + abstract public function getTrendsByGroup($producerDao, $onlyKey = false); /** * Save the given trend. Ensure that null values are explicitly set in the database. @@ -123,7 +122,7 @@ public function save($trendDao) */ public function createIfNeeded($producerId, $metricName, $configItemId, $testDatasetId, $truthDatasetId, $unit = false) { - $trendDao = $this->getMatch($producerId, $metricName, $configItemId, $testDatasetId, $truthDatasetId, $unit); + $trendDao = $this->getMatch($producerId, $metricName, $configItemId, $testDatasetId, $truthDatasetId); if ($trendDao === false) { diff --git a/modules/tracker/models/base/TrendgroupModelBase.php b/modules/tracker/models/base/TrendgroupModelBase.php index 1c0fb5fa1..c0d062f73 100644 --- a/modules/tracker/models/base/TrendgroupModelBase.php +++ b/modules/tracker/models/base/TrendgroupModelBase.php @@ -61,7 +61,7 @@ public function __construct() ), 'trends' => array( 'type' => MIDAS_ONE_TO_MANY, - 'model' => 'Scalar', + 'model' => 'Trend', 'module' => $this->moduleName, 'parent_column' => 'trendgroup_id', 'child_column' => 'trendgroup_id', diff --git a/modules/tracker/models/pdo/TrendModel.php b/modules/tracker/models/pdo/TrendModel.php index 594175a35..c187604bb 100644 --- a/modules/tracker/models/pdo/TrendModel.php +++ b/modules/tracker/models/pdo/TrendModel.php @@ -24,17 +24,16 @@ class Tracker_TrendModel extends Tracker_TrendModelBase { /** - * Return the trend DAO that matches the given the producer id, metric name, associated items, and unit. + * Return the trend DAO that matches the given the producer id, metric name, and associated items. * * @param int $producerId producer id * @param string $metricName metric name * @param null|int $configItemId configuration item id * @param null|int $testDatasetId test dataset item id * @param null|int $truthDatasetId truth dataset item id - * @param false|string $unit (Optional) scalar value unit, defaults to false * @return false|Tracker_TrendDao trend DAO or false if none exists */ - public function getMatch($producerId, $metricName, $configItemId, $testDatasetId, $truthDatasetId, $unit = false) + public function getMatch($producerId, $metricName, $configItemId, $testDatasetId, $truthDatasetId) { $sql = $this->database->select()->setIntegrityCheck(false)->from(array('t' => 'tracker_trend') )->join(array('g' => 'tracker_trendgroup'), 't.trendgroup_id = g.trendgroup_id' @@ -61,11 +60,6 @@ public function getMatch($producerId, $metricName, $configItemId, $testDatasetId $sql->where('g.test_dataset_id = ?', $testDatasetId); } - // TODO(cpatrick): I don't think this is needed. - /* if ($unit !== false) { - $sql->where('unit = ?', $unit); - }*/ - return $this->initDao('Trend', $this->database->fetchRow($sql), $this->moduleName); } @@ -116,23 +110,23 @@ public function getScalars($trendDao, $startDate = null, $endDate = null, $userI } /** - * Return all trends corresponding to the given producer. They will be grouped by distinct - * config/test/truth dataset combinations. + * Return all trends corresponding to the given producer. They will be grouped by their trend + * group and returned along with the test, truth, and config item DAOs. * * @param Tracker_ProducerDao $producerDao producer DAO * @param bool $onlyKey whether to return only key trends * @return array array of associative arrays with keys "configItem", "testDataset", "truthDataset", and "trends" */ - public function getTrendsGroupByDatasets($producerDao, $onlyKey = false) + public function getTrendsByGroup($producerDao, $onlyKey = false) { - $sql = $this->database->select()->setIntegrityCheck(false)->from(array('t' => 'tracker_trend'), array('trendgroup_id') - )->join(array('g' => 'tracker_trendgroup'), 't.trendgroup_id = g.trendgroup_id' - )->where('g.producer_id = ?', $producerDao->getKey())->distinct(); + $sql = $this->database->select()->setIntegrityCheck(false) + ->from('tracker_trendgroup') + ->where('producer_id = ?', $producerDao->getKey()); + $rows = $this->database->fetchAll($sql); /** @var ItemModel $itemModel */ $itemModel = MidasLoader::loadModel('Item'); $results = array(); - $rows = $this->database->fetchAll($sql); /** @var Zend_Db_Table_Row_Abstract $row */ foreach ($rows as $row) { @@ -145,10 +139,7 @@ public function getTrendsGroupByDatasets($producerDao, $onlyKey = false) 'truthDataset' => $truthDatasetItemDao, ); $queryParams = array( - 'producer_id' => $producerDao->getKey(), - 'config_item_id' => $row['config_item_id'], - 'test_dataset_id' => $row['test_dataset_id'], - 'truth_dataset_id' => $row['truth_dataset_id'], + 't.trendgroup_id' => $row['trendgroup_id'] ); if ($onlyKey !== false) { $queryParams['key_metric'] = '1'; From 1ee80e8ab70f248ef683681c9c6394ef6bbc59e5 Mon Sep 17 00:00:00 2001 From: Patrick Reynolds Date: Mon, 11 Apr 2016 18:58:54 -0400 Subject: [PATCH 29/40] Add support for limiting scalars from a submission by trendgroup. --- .../models/base/SubmissionModelBase.php | 9 +++++--- .../tracker/models/pdo/SubmissionModel.php | 22 ++++++++++--------- 2 files changed, 18 insertions(+), 13 deletions(-) diff --git a/modules/tracker/models/base/SubmissionModelBase.php b/modules/tracker/models/base/SubmissionModelBase.php index 52b6127ae..e43216615 100644 --- a/modules/tracker/models/base/SubmissionModelBase.php +++ b/modules/tracker/models/base/SubmissionModelBase.php @@ -124,12 +124,15 @@ abstract public function getOrCreateSubmission($producerDao, $uuid); abstract public function getSubmissionsByProducer($producerDao); /** - * Get the scalars associated with a submission. + * Return the scalars for a given submission. + * * @param Tracker_SubmissionDao $submissionDao submission DAO * @param bool $key whether to only retrieve scalars of key trends - * @return array submission DAOs + * @param bool|false|Tracker_TrendgroupDao $trendGroup dao of trend group to limit scalars + * @return array scalar DAOs + * @throws Zend_Exception */ - abstract public function getScalars($submissionDao, $key = false); + abstract public function getScalars($submissionDao, $key = false, $trendGroup = false); /** * Return the values (trend name, value, and unit in an array) from a given submission. diff --git a/modules/tracker/models/pdo/SubmissionModel.php b/modules/tracker/models/pdo/SubmissionModel.php index 7ab147175..acdae2c10 100644 --- a/modules/tracker/models/pdo/SubmissionModel.php +++ b/modules/tracker/models/pdo/SubmissionModel.php @@ -121,20 +121,22 @@ public function createSubmission($producerDao, $uuid, $name = '', $params = null * * @param Tracker_SubmissionDao $submissionDao submission DAO * @param bool $key whether to only retrieve scalars of key trends + * @param bool|false|Tracker_TrendgroupDao $trendGroup dao of trend group to limit scalars * @return array scalar DAOs + * @throws Zend_Exception */ - public function getScalars($submissionDao, $key = false) + public function getScalars($submissionDao, $key = false, $trendGroup = false) { + $sql = $this->database->select()->setIntegrityCheck(false)->from('tracker_scalar')->join( + 'tracker_trend', + 'tracker_scalar.trend_id = tracker_trend.trend_id', + array() + )->where('submission_id = ?', $submissionDao->getKey()); if ($key) { - $sql = $this->database->select()->setIntegrityCheck(false)->from('tracker_scalar')->join( - 'tracker_trend', - 'tracker_scalar.trend_id = tracker_trend.trend_id', - array() - )->where('submission_id = ?', $submissionDao->getKey() - )->where('key_metric = ?', 1); - } else { - $sql = $this->database->select()->setIntegrityCheck(false)->from('tracker_scalar') - ->where('submission_id = ?', $submissionDao->getKey()); + $sql = $sql->where('key_metric = ?', 1); + } + if ($trendGroup) { + $sql = $sql->where('trendgroup_id = ?', $trendGroup->getKey()); } $scalarDaos = array(); From c7f59882b58b16d0d10d246812e92707c550e4e5 Mon Sep 17 00:00:00 2001 From: mgrauer Date: Tue, 12 Apr 2016 10:38:51 -0400 Subject: [PATCH 30/40] Applied fixes from StyleCI --- modules/tracker/models/pdo/TrendModel.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/tracker/models/pdo/TrendModel.php b/modules/tracker/models/pdo/TrendModel.php index c187604bb..782dc874c 100644 --- a/modules/tracker/models/pdo/TrendModel.php +++ b/modules/tracker/models/pdo/TrendModel.php @@ -139,7 +139,7 @@ public function getTrendsByGroup($producerDao, $onlyKey = false) 'truthDataset' => $truthDatasetItemDao, ); $queryParams = array( - 't.trendgroup_id' => $row['trendgroup_id'] + 't.trendgroup_id' => $row['trendgroup_id'], ); if ($onlyKey !== false) { $queryParams['key_metric'] = '1'; From daf9083e2d78fa72eaae1de6aa52997abd0497d5 Mon Sep 17 00:00:00 2001 From: mgrauer Date: Wed, 13 Apr 2016 02:03:33 +0000 Subject: [PATCH 31/40] Separate notification from aggregate metric spec model, upgrade Tracker to 2.0.1 --- modules/tracker/configs/module.ini | 2 +- modules/tracker/database/mysql/2.0.1.sql | 139 +++++++++ modules/tracker/database/upgrade/2.0.1.php | 77 +++++ .../AggregateMetricNotificationModelBase.php | 93 ++++++ .../base/AggregateMetricSpecModelBase.php | 57 +--- .../dao/AggregateMetricNotificationDao.php | 42 +++ .../models/dao/AggregateMetricSpecDao.php | 2 - .../models/pdo/AggregateMetricModel.php | 3 +- .../pdo/AggregateMetricNotificationModel.php | 220 ++++++++++++++ .../models/pdo/AggregateMetricSpecModel.php | 177 +----------- .../tests/databaseDataset/aggregateMetric.xml | 39 ++- .../models/base/AggregateMetricModelTest.php | 29 +- .../AggregateMetricNotificationModelTest.php | 268 ++++++++++++++++++ .../base/AggregateMetricSpecModelTest.php | 106 ++----- .../tracker/tests/models/base/CMakeLists.txt | 2 +- 15 files changed, 903 insertions(+), 353 deletions(-) create mode 100644 modules/tracker/database/mysql/2.0.1.sql create mode 100644 modules/tracker/database/upgrade/2.0.1.php create mode 100644 modules/tracker/models/base/AggregateMetricNotificationModelBase.php create mode 100644 modules/tracker/models/dao/AggregateMetricNotificationDao.php create mode 100644 modules/tracker/models/pdo/AggregateMetricNotificationModel.php create mode 100644 modules/tracker/tests/models/base/AggregateMetricNotificationModelTest.php diff --git a/modules/tracker/configs/module.ini b/modules/tracker/configs/module.ini index dace2d381..7b5138fc9 100644 --- a/modules/tracker/configs/module.ini +++ b/modules/tracker/configs/module.ini @@ -6,4 +6,4 @@ description = "Track scalar results over time" category = "Visualization" dependencies = api,scheduler uuid = "3048a9fa-89ab-4e61-a55e-a49379fa6dc" -version = "2.0.0" +version = "2.0.1" diff --git a/modules/tracker/database/mysql/2.0.1.sql b/modules/tracker/database/mysql/2.0.1.sql new file mode 100644 index 000000000..239034638 --- /dev/null +++ b/modules/tracker/database/mysql/2.0.1.sql @@ -0,0 +1,139 @@ +-- Midas Server. Copyright Kitware SAS. Licensed under the Apache License 2.0. + +-- MySQL database for the tracker module, version 2.0.1 + +CREATE TABLE IF NOT EXISTS `tracker_producer` ( + `producer_id` bigint(20) NOT NULL AUTO_INCREMENT, + `community_id` bigint(20) NOT NULL, + `repository` varchar(255) NOT NULL, + `executable_name` varchar(255) NOT NULL, + `display_name` varchar(255) NOT NULL, + `description` text NOT NULL, + `revision_url` text NOT NULL, + PRIMARY KEY (`producer_id`), + KEY (`community_id`) +) DEFAULT CHARSET=utf8; + +CREATE TABLE IF NOT EXISTS `tracker_scalar` ( + `scalar_id` bigint(20) NOT NULL AUTO_INCREMENT, + `trend_id` bigint(20) NOT NULL, + `value` double, + `submission_id` bigint(20) NOT NULL, + PRIMARY KEY (`scalar_id`), + KEY (`trend_id`), + KEY (`submission_id`) +) DEFAULT CHARSET=utf8; + +CREATE TABLE IF NOT EXISTS `tracker_submission` ( + `submission_id` bigint(20) NOT NULL AUTO_INCREMENT, + `producer_id` bigint(20) NOT NULL, + `name` varchar(255) NOT NULL DEFAULT '', + `uuid` varchar(255) NOT NULL DEFAULT '', + `submit_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + `producer_revision` varchar(255), + `user_id` bigint(20) NOT NULL DEFAULT '-1', + `official` tinyint(4) NOT NULL DEFAULT '1', + `build_results_url` text NOT NULL, + `branch` varchar(255) NOT NULL DEFAULT '', + `extra_urls` text, + `reproduction_command` text, + PRIMARY KEY (`submission_id`), + UNIQUE KEY (`uuid`), + KEY (`user_id`), + KEY (`submit_time`), + KEY (`branch`) +) DEFAULT CHARSET=utf8; + +CREATE TABLE IF NOT EXISTS `tracker_submission2item` ( + `submission_id` bigint(20) NOT NULL, + `item_id` bigint(20) NOT NULL, + `label` varchar(255) NOT NULL, + `trendgroup_id` bigint(20) NOT NULL, + KEY (`submission_id`), + KEY (`item_id`), + KEY (`trendgroup_id`) +) DEFAULT CHARSET=utf8; + +CREATE TABLE IF NOT EXISTS `tracker_threshold_notification` ( + `threshold_id` bigint(20) NOT NULL AUTO_INCREMENT, + `trend_id` bigint(20) NOT NULL, + `value` double, + `comparison` varchar(2), + `action` varchar(80) NOT NULL, + `recipient_id` bigint(20) NOT NULL, + PRIMARY KEY (`threshold_id`), + KEY (`trend_id`) +) DEFAULT CHARSET=utf8; + +CREATE TABLE IF NOT EXISTS `tracker_trend` ( + `trend_id` bigint(20) NOT NULL AUTO_INCREMENT, + `trendgroup_id` bigint(20), + `metric_name` varchar(255) NOT NULL, + `display_name` varchar(255) NOT NULL, + `unit` varchar(255) NOT NULL, + `key_metric` tinyint(4) NOT NULL DEFAULT '0', + PRIMARY KEY (`trend_id`), + KEY (`trendgroup_id`) +) DEFAULT CHARSET=utf8; + +CREATE TABLE IF NOT EXISTS `tracker_trendgroup` ( + `trendgroup_id` bigint(20) NOT NULL AUTO_INCREMENT, + `producer_id` bigint(20) NOT NULL, + `config_item_id` bigint(20), + `test_dataset_id` bigint(20), + `truth_dataset_id` bigint(20), + PRIMARY KEY (`trendgroup_id`), + KEY (`producer_id`), + KEY (`config_item_id`), + KEY (`test_dataset_id`), + KEY (`truth_dataset_id`) +) DEFAULT CHARSET=utf8; + +CREATE TABLE IF NOT EXISTS `tracker_param` ( + `param_id` bigint(20) NOT NULL AUTO_INCREMENT, + `submission_id` bigint(20) NOT NULL, + `param_name` varchar(255) NOT NULL, + `param_type` enum('text', 'numeric') NOT NULL, + `text_value` text, + `numeric_value` double, + PRIMARY KEY (`param_id`), + KEY (`submission_id`), + KEY (`param_name`) +) DEFAULT CHARSET=utf8; + +CREATE TABLE IF NOT EXISTS `tracker_aggregate_metric` ( + `aggregate_metric_id` bigint(20) NOT NULL AUTO_INCREMENT, + `aggregate_metric_spec_id` bigint(20) NOT NULL, + `submission_id` bigint(20) NOT NULL, + `value` double, + PRIMARY KEY (`aggregate_metric_id`), + KEY (`aggregate_metric_spec_id`), + KEY (`submission_id`) +) DEFAULT CHARSET=utf8; + +CREATE TABLE IF NOT EXISTS `tracker_aggregate_metric_spec` ( + `aggregate_metric_spec_id` bigint(20) NOT NULL AUTO_INCREMENT, + `producer_id` bigint(20) NOT NULL, + `name` varchar(255) NOT NULL DEFAULT '', + `description` varchar(255) NOT NULL DEFAULT '', + `spec` text NOT NULL DEFAULT '', + PRIMARY KEY (`aggregate_metric_spec_id`), + KEY (`producer_id`) +) DEFAULT CHARSET=utf8; + +CREATE TABLE IF NOT EXISTS `tracker_aggregate_metric_notification` ( + `aggregate_metric_notification_id` bigint(20) NOT NULL AUTO_INCREMENT, + `aggregate_metric_spec_id` bigint(20) NOT NULL, + `branch` varchar(255) NOT NULL DEFAULT '', + `value` double, + `comparison` varchar(2) NOT NULL DEFAULT '', + PRIMARY KEY (`aggregate_metric_notification_id`), + KEY (`aggregate_metric_spec_id`), + KEY (`branch`) +) DEFAULT CHARSET=utf8; + +CREATE TABLE IF NOT EXISTS `tracker_user2aggregate_metric_notification` ( + `user_id` bigint(20) NOT NULL, + `aggregate_metric_notification_id` bigint(20) NOT NULL, + PRIMARY KEY (`user_id`, `aggregate_metric_notification_id`) +) DEFAULT CHARSET=utf8; diff --git a/modules/tracker/database/upgrade/2.0.1.php b/modules/tracker/database/upgrade/2.0.1.php new file mode 100644 index 000000000..1f2a8b9d1 --- /dev/null +++ b/modules/tracker/database/upgrade/2.0.1.php @@ -0,0 +1,77 @@ +db->query( + 'CREATE TABLE IF NOT EXISTS `tracker_aggregate_metric_notification` ('. + ' `aggregate_metric_notification_id` bigint(20) NOT NULL AUTO_INCREMENT,'. + ' `aggregate_metric_spec_id` bigint(20) NOT NULL,'. + " `branch` varchar(255) NOT NULL DEFAULT '',". + ' `value` double,'. + " `comparison` varchar(2) NOT NULL DEFAULT '',". + ' PRIMARY KEY (`aggregate_metric_notification_id`),'. + ' KEY (`aggregate_metric_spec_id`),'. + ' KEY (`branch`)'. + ') DEFAULT CHARSET=utf8;' + ); + + $this->db->query( + 'CREATE TABLE IF NOT EXISTS `tracker_user2aggregate_metric_notification` ('. + ' `user_id` bigint(20) NOT NULL,'. + ' `aggregate_metric_notification_id` bigint(20) NOT NULL,'. + ' PRIMARY KEY (`user_id`, `aggregate_metric_notification_id`)'. + ') DEFAULT CHARSET=utf8;' + ); + + // Migrate AMS (comparison, value, branch) to tracker_aggregate_metric_notification. + $this->db->query( + 'INSERT INTO `tracker_aggregate_metric_notification` '. + ' (`aggregate_metric_spec_id`, `branch`, `value`, `comparison`) '. + 'SELECT '. + ' `aggregate_metric_spec_id`, `branch`, `value`, `comparison` '. + 'from `tracker_aggregate_metric_spec`;' + ); + + // Migrate notified users. + $this->db->query( + 'INSERT INTO `tracker_user2aggregate_metric_notification` '. + ' (`user_id`, `aggregate_metric_notification_id`) '. + 'SELECT '. + ' `user_id`, `aggregate_metric_notification_id` '. + 'FROM `tracker_aggregate_metric_notification` AS `amn`, `tracker_user2aggregate_metric_spec` AS `u2ams` WHERE '. + ' `amn`.`aggregate_metric_spec_id` = `u2ams`.`aggregate_metric_spec_id`;' + ); + + // Drop migrated columns and tables. + $this->db->query( + 'ALTER TABLE `tracker_aggregate_metric_spec` '. + ' DROP COLUMN `branch`, '. + ' DROP COLUMN `comparison`, '. + ' DROP COLUMN `value`;' + ); + + $this->db->query('DROP TABLE `tracker_user2aggregate_metric_spec`;'); + } +} diff --git a/modules/tracker/models/base/AggregateMetricNotificationModelBase.php b/modules/tracker/models/base/AggregateMetricNotificationModelBase.php new file mode 100644 index 000000000..f8bac87b8 --- /dev/null +++ b/modules/tracker/models/base/AggregateMetricNotificationModelBase.php @@ -0,0 +1,93 @@ +_name = 'tracker_aggregate_metric_notification'; + $this->_daoName = 'AggregateMetricNotificationDao'; + $this->_key = 'aggregate_metric_notification_id'; + $this->_mainData = array( + 'aggregate_metric_notification_id' => array('type' => MIDAS_DATA), + 'aggregate_metric_spec_id' => array('type' => MIDAS_DATA), + 'branch' => array('type' => MIDAS_DATA), + 'value' => array('type' => MIDAS_DATA), + 'comparison' => array('type' => MIDAS_DATA), + 'aggregate_metric_spec' => array( + 'type' => MIDAS_MANY_TO_ONE, + 'model' => 'AggregateMetricSpec', + 'module' => $this->moduleName, + 'parent_column' => 'aggregate_metric_spec_id', + 'child_column' => 'aggregate_metric_spec_id', + ), + ); + + $this->initialize(); + } + + /** + * Create a user notification tied to the aggregate metric notification. + * + * @param Tracker_AggregateMetricNotificationDao $aggregateMetricNotificationDao aggregateMetricNotification DAO + * @param UserDao $userDao user DAO + * @return bool true if the notification could be created, false otherwise + */ + abstract public function createUserNotification($aggregateMetricNotificationDao, $userDao); + + /** + * Delete a user notification tied to the aggregate metric notification. + * + * @param Tracker_AggregateMetricNotificationDao $aggregateMetricNotificationDao aggregateMetricNotification DAO + * @param UserDao $userDao user DAO + * @return bool true if the user and aggregate metric notification are valid and a + * notification does not exist for this user and aggregate metric notification upon + * returning, false otherwise + */ + abstract public function deleteUserNotification($aggregateMetricNotificationDao, $userDao); + + /** + * Return a list of User Daos for all users with notifications on this aggregate metric notification. + * + * @param Tracker_AggregateMetricNotificationDao $aggregateMetricNotificationDao aggregateMetricNotification DAO + * @return false|array of UserDao for all users with notification on the passed in $aggregateMetricNotificationDao, + * or false if the passed in notification is invalid + */ + abstract public function getAllNotifiedUsers($aggregateMetricNotificationDao); + + /** + * Return a list of Jobs scheduled to notify users, if the passed aggregate metric + * is beyond the threshold of any notifications tied to the aggregate metric spec + * that generated the aggregate metric. + * + * @param Tracker_AggregateMetricNotificationDao $aggregateMetricNotification + * @return false|array of Scheduler_JobDao for all users with a notification + * created, which will only be populated if the aggregate metric is beyond + * the threshold defined on any aggregate metric notification tied to the + * aggregate metric spec that generated the aggregate metric and there exist + * users to be notified on the aggregate metric notification, + * or false if the inputs are invalid. + */ + abstract public function scheduleNotificationJobs($aggregateMetricDao); +} diff --git a/modules/tracker/models/base/AggregateMetricSpecModelBase.php b/modules/tracker/models/base/AggregateMetricSpecModelBase.php index 24e55985a..74a95ffee 100644 --- a/modules/tracker/models/base/AggregateMetricSpecModelBase.php +++ b/modules/tracker/models/base/AggregateMetricSpecModelBase.php @@ -32,7 +32,6 @@ public function __construct() $this->_mainData = array( 'aggregate_metric_spec_id' => array('type' => MIDAS_DATA), 'producer_id' => array('type' => MIDAS_DATA), - 'branch' => array('type' => MIDAS_DATA), 'name' => array('type' => MIDAS_DATA), 'description' => array('type' => MIDAS_DATA), 'spec' => array('type' => MIDAS_DATA), @@ -50,61 +49,16 @@ public function __construct() $this->initialize(); } - /** - * Create a user notification tied to the aggregate metric spec. - * - * @param Tracker_AggregateMetricSpecDao $aggregateMetricSpecDao aggregateMetricSpec DAO - * @param UserDao $userDao user DAO - * @return bool true if the notification could be created, false otherwise - */ - abstract public function createUserNotification($aggregateMetricSpecDao, $userDao); - - /** - * Delete a user notification tied to the aggregate metric spec. - * - * @param Tracker_AggregateMetricSpecDao $aggregateMetricSpecDao aggregateMetricSpec DAO - * @param UserDao $userDao user DAO - * @return bool true if the user and aggregate metric spec are valid and a - * notification does not exist for this user and aggregate metric spec upon - * returning, false otherwise - */ - abstract public function deleteUserNotification($aggregateMetricSpecDao, $userDao); - - /** - * Return a list of User Daos for all users with notifications on this aggregate metric spec. - * - * @param Tracker_AggregateMetricSpecDao $aggregateMetricSpecDao aggregateMetricSpec DAO - * @return false|array of UserDao for all users with notification on the passed in $aggregateMetricSpecDao, - * or false if the passed in spec is invalid - */ - abstract public function getAllNotifiedUsers($aggregateMetricSpecDao); - - /** - * Return a list of Jobs scheduled to notify users that the passed aggregate metric is above - * the threshold defined in the passed aggregate metric spec. - * - * @param Tracker_AggregateMetricSpecDao $aggregateMetricSpecDao aggregateMetricSpec DAO - * @param Tracker_AggregateMetricDao $aggregateMetricDao aggregateMetric DAO - * @return false|array of Scheduler_JobDao for all users with a notification created, which will only - * be populated if the aggregate metric is above the threshold defined on the aggregate metric spec and - * there exist users to be notified on the aggregate metric spec, or false if the inputs are invalid. - */ - abstract public function scheduleNotificationJobs($aggregateMetricSpecDao, $aggregateMetricDao); - /** * Create an AggregateMetricSpecDao from the inputs. * * @param Tracker_ProducerDao $producerDao producer DAO * @param string $name the name of the aggregate metric spec * @param string $spec the spec for the aggregate metric spec - * @param string $branch the branch of the aggregate metric spec (defaults to 'master') * @param false | string $description the description for the aggregate metric spec - * @param false | string $value the value for the aggregate metric spec threshold - * @param false | string $comparison the comparison for the aggregate metric spec threshold, - * one of ['>', '<', '>=', '<', '<=', '==', '!='] * @return false | Tracker_AggregateMetricSpecDao created from inputs */ - public function createAggregateMetricSpec($producerDao, $name, $spec, $branch = 'master', $description = false, $value = false, $comparison = false) + public function createAggregateMetricSpec($producerDao, $name, $spec, $description = false) { if (is_null($producerDao) || $producerDao === false) { return false; @@ -113,7 +67,6 @@ public function createAggregateMetricSpec($producerDao, $name, $spec, $branch = /** @var Tracker_AggregateMetricSpecDao $aggregateMetricSpecDao */ $aggregateMetricSpecDao = MidasLoader::newDao('AggregateMetricSpecDao', 'tracker'); $aggregateMetricSpecDao->setProducerId($producerDao->getProducerId()); - $aggregateMetricSpecDao->setBranch($branch); $aggregateMetricSpecDao->setName($name); $aggregateMetricSpecDao->setSpec($spec); if ($description) { @@ -121,14 +74,6 @@ public function createAggregateMetricSpec($producerDao, $name, $spec, $branch = } else { $aggregateMetricSpecDao->setDescription(''); } - if ($value) { - $aggregateMetricSpecDao->setValue($value); - } - if ($comparison) { - $aggregateMetricSpecDao->setComparison($comparison); - } else { - $aggregateMetricSpecDao->setComparison(''); - } $this->save($aggregateMetricSpecDao); return $aggregateMetricSpecDao; diff --git a/modules/tracker/models/dao/AggregateMetricNotificationDao.php b/modules/tracker/models/dao/AggregateMetricNotificationDao.php new file mode 100644 index 000000000..b0d04e5f5 --- /dev/null +++ b/modules/tracker/models/dao/AggregateMetricNotificationDao.php @@ -0,0 +1,42 @@ +where('tracker_submission.submission_id = ?', $submissionDao->getKey()) - ->where('tracker_submission.branch = ?', $aggregateMetricSpecDao->getBranch()) ->where('tracker_scalar.trend_id IN (?)', $trendIds); $rows = $this->database->fetchAll($sql); if (count($rows) === 0) { @@ -369,7 +368,7 @@ public function getAggregateMetricsSeries($producerDao, $lastDate = false, $days ->join(array('ams' => 'tracker_aggregate_metric_spec'), 'ams.aggregate_metric_spec_id = am.aggregate_metric_spec_id', array()) - ->where('ams.branch = ?', $branch) + ->where('u.branch = ?', $branch) ->where('u.producer_id = ?', $producerDao->getProducerId()) ->where('u.submit_time > ?', $firstDate->format('Y-m-d H:i:s')) ->where('u.submit_time <= ?', $lastDate) diff --git a/modules/tracker/models/pdo/AggregateMetricNotificationModel.php b/modules/tracker/models/pdo/AggregateMetricNotificationModel.php new file mode 100644 index 000000000..b2c02fdd0 --- /dev/null +++ b/modules/tracker/models/pdo/AggregateMetricNotificationModel.php @@ -0,0 +1,220 @@ +database->select()->setIntegrityCheck(false) + ->from('tracker_user2aggregate_metric_notification') + ->where('aggregate_metric_notification_id = ?', $aggregateMetricNotificationDao->getAggregateMetricNotificationId()) + ->where('user_id = ?', $userDao->getUserId()); + /** @var Zend_Db_Table_Row_Abstract $row */ + $row = $this->database->fetchRow($sql); + if (!is_null($row)) { + return true; + } else { + $data = array( + 'aggregate_metric_notification_id' => $aggregateMetricNotificationDao->getAggregateMetricNotificationId(), + 'user_id' => $userDao->getUserId(), + ); + $this->database->getdb()->insert('tracker_user2aggregate_metric_notification', $data); + + return true; + } + } + + /** + * Delete a user notification tied to the aggregate metric notification. + * + * @param Tracker_AggregateMetricNotificationDao $aggregateMetricNotificationDao aggregateMetricNotification DAO + * @param UserDao $userDao user DAO + * @return bool true if the user and aggregate metric notification are valid and a + * notification does not exist for this user and aggregate metric notification upon + * returning, false otherwise + */ + public function deleteUserNotification($aggregateMetricNotificationDao, $userDao) + { + if (is_null($aggregateMetricNotificationDao) || $aggregateMetricNotificationDao === false) { + return false; + } + if (is_null($userDao) || $userDao === false) { + return false; + } + $this->database->getDB()->delete('tracker_user2aggregate_metric_notification', array( + 'aggregate_metric_notification_id = ?' => $aggregateMetricNotificationDao->getAggregateMetricNotificationId(), + 'user_id = ?' => $userDao->getUserId(), + )); + + return true; + } + + /** + * Return a list of User Daos for all users with notifications on this aggregate metric notification. + * + * @param Tracker_AggregateMetricNotificationDao $aggregateMetricNotificationDao aggregateMetricNotification DAO + * @return false|array of UserDao for all users with notification on the passed in $aggregateMetricNotificationDao, + * or false if the passed in notification is invalid + */ + public function getAllNotifiedUsers($aggregateMetricNotificationDao) + { + if (is_null($aggregateMetricNotificationDao) || $aggregateMetricNotificationDao === false) { + return false; + } + $sql = $this->database->select()->setIntegrityCheck(false) + ->from('tracker_user2aggregate_metric_notification', array('user_id')) + ->where('aggregate_metric_notification_id = ?', $aggregateMetricNotificationDao->getAggregateMetricNotificationId()); + $rows = $this->database->fetchAll($sql); + + $userDaos = array(); + /** @var userModel $userModel */ + $userModel = MidasLoader::loadModel('User'); + /** @var Zend_Db_Table_Row_Abstract $row */ + foreach ($rows as $row) { + $userDaos[] = $userModel->load($row['user_id']); + } + + return $userDaos; + } + + /** + * Return a list of Jobs scheduled to notify users, if the passed aggregate metric + * is beyond the threshold of any notifications tied to the aggregate metric spec + * that generated the aggregate metric. + * + * @param Tracker_AggregateMetricNotificationDao $aggregateMetricNotification + * @return false|array of Scheduler_JobDao for all users with a notification + * created, which will only be populated if the aggregate metric is beyond + * the threshold defined on any aggregate metric notification tied to the + * aggregate metric spec that generated the aggregate metric and there exist + * users to be notified on the aggregate metric notification, + * or false if the inputs are invalid. + */ + public function scheduleNotificationJobs($aggregateMetricDao) + { + if (is_null($aggregateMetricDao) || $aggregateMetricDao === false) { + return false; + } + + /** @var string $branch */ + $branch = $aggregateMetricDao->getSubmission()->getBranch(); + /** @var Tracker_AggregateMetricSpecDao $aggregateMetricSpecDao */ + $aggregateMetricSpecDao = $aggregateMetricDao->getAggregateMetricSpec(); + $jobs = array(); + + // Get all notifications tied to that spec and branch. + $sql = $this->database->select()->setIntegrityCheck(false) + ->from('tracker_aggregate_metric_notification') + ->where('aggregate_metric_spec_id = ?', $aggregateMetricSpecDao->getAggregateMetricSpecId()) + ->where('branch = ?', $branch); + $rows = $this->database->fetchAll($sql); + /** @var Zend_Db_Table_Row_Abstract $row */ + foreach ($rows as $row) { + $aggregateMetricNotificationDao = $this->initDao('AggregateMetricNotification', $row, $this->moduleName); + $value = floatval($aggregateMetricDao->getValue()); + $thresholdValue = floatval($aggregateMetricNotificationDao->getValue()); + /** @var bool $aboveThreshold */ + $aboveThreshold = false; + switch ($aggregateMetricNotificationDao->getComparison()) { + case '>': + $aboveThreshold = $value > $thresholdValue; + break; + case '<': + $aboveThreshold = $value < $thresholdValue; + break; + case '>=': + $aboveThreshold = $value >= $thresholdValue; + break; + case '<=': + $aboveThreshold = $value <= $thresholdValue; + break; + case '==': + $aboveThreshold = $value === $thresholdValue; + break; + case '!=': + $aboveThreshold = $value !== $thresholdValue; + break; + default: + $aboveThreshold = false; + } + + if ($aboveThreshold) { + $notifiedUsers = $this->getAllNotifiedUsers($aggregateMetricNotificationDao); + if ($notifiedUsers && count($notifiedUsers) > 0) { + /** @var Scheduler_JobModel $jobModel */ + $jobModel = MidasLoader::loadModel('Job', 'scheduler'); + /** @var userDao $userDao */ + foreach ($notifiedUsers as $userDao) { + /** @var Scheduler_JobDao $jobDao */ + $jobDao = MidasLoader::newDao('JobDao', 'scheduler'); + $jobDao->setTask('TASK_TRACKER_SEND_AGGREGATE_METRIC_NOTIFICATION'); + $jobDao->setPriority(MIDAS_EVENT_PRIORITY_HIGH); + $jobDao->setRunOnlyOnce(1); + $jobDao->setFireTime(date('Y-m-d H:i:s')); + $jobDao->setTimeInterval(0); + $jobDao->setStatus(SCHEDULER_JOB_STATUS_TORUN); + $jobDao->setCreatorId($userDao->getUserId()); + $jobDao->setParams(JsonComponent::encode(array( + 'aggregate_metric_notification_id' => $aggregateMetricNotificationDao->getAggregateMetricNotificationId(), + 'aggregate_metric_id' => $aggregateMetricDao->getAggregateMetricId(), + 'recipient_id' => $userDao->getUserId(), + ))); + $jobModel->save($jobDao); + $jobs[] = $jobDao; + } + } + } + } + + return $jobs; + } + + /** + * Delete the given aggregate metric notification, and any associated user + * notifications. + * + * @param Tracker_AggregateMetricNotificationDao $aggregateMetricNotificationDao aggregateMetricNotification DAO + */ + public function delete($aggregateMetricNotificationDao) + { + if (is_null($aggregateMetricNotificationDao) || $aggregateMetricNotificationDao === false) { + return; + } + $this->database->getDB()->delete('tracker_user2aggregate_metric_notification', 'aggregate_metric_notification_id = '.$aggregateMetricNotificationDao->getAggregateMetricNotificationId()); + parent::delete($aggregateMetricNotificationDao); + } +} diff --git a/modules/tracker/models/pdo/AggregateMetricSpecModel.php b/modules/tracker/models/pdo/AggregateMetricSpecModel.php index 91877496f..be0e34d4a 100644 --- a/modules/tracker/models/pdo/AggregateMetricSpecModel.php +++ b/modules/tracker/models/pdo/AggregateMetricSpecModel.php @@ -23,172 +23,6 @@ /** AggregateMetricSpec model for the tracker module. */ class Tracker_AggregateMetricSpecModel extends Tracker_AggregateMetricSpecModelBase { - /** - * Create a user notification tied to the aggregate metric spec. - * - * @param Tracker_AggregateMetricSpecDao $aggregateMetricSpecDao aggregateMetricSpec DAO - * @param UserDao $userDao user DAO - * @return bool true if the notification could be created, false otherwise - */ - public function createUserNotification($aggregateMetricSpecDao, $userDao) - { - if (is_null($aggregateMetricSpecDao) || $aggregateMetricSpecDao === false) { - return false; - } - if (is_null($userDao) || $userDao === false) { - return false; - } - // Don't insert if it exists already. - $sql = $this->database->select()->setIntegrityCheck(false) - ->from('tracker_user2aggregate_metric_spec') - ->where('aggregate_metric_spec_id = ?', $aggregateMetricSpecDao->getAggregateMetricSpecId()) - ->where('user_id = ?', $userDao->getUserId()); - /** @var Zend_Db_Table_Row_Abstract $row */ - $row = $this->database->fetchRow($sql); - if (!is_null($row)) { - return true; - } else { - $data = array( - 'aggregate_metric_spec_id' => $aggregateMetricSpecDao->getAggregateMetricSpecId(), - 'user_id' => $userDao->getUserId(), - ); - $this->database->getdb()->insert('tracker_user2aggregate_metric_spec', $data); - - return true; - } - } - - /** - * Delete a user notification tied to the aggregate metric spec. - * - * @param Tracker_AggregateMetricSpecDao $aggregateMetricSpecDao aggregateMetricSpec DAO - * @param UserDao $userDao user DAO - * @return bool true if the user and aggregate metric spec are valid and a - * notification does not exist for this user and aggregate metric spec upon - * returning, false otherwise - */ - public function deleteUserNotification($aggregateMetricSpecDao, $userDao) - { - if (is_null($aggregateMetricSpecDao) || $aggregateMetricSpecDao === false) { - return false; - } - if (is_null($userDao) || $userDao === false) { - return false; - } - $this->database->getDB()->delete('tracker_user2aggregate_metric_spec', array( - 'aggregate_metric_spec_id = ?' => $aggregateMetricSpecDao->getAggregateMetricSpecId(), - 'user_id = ?' => $userDao->getUserId(), - )); - - return true; - } - - /** - * Return a list of User Daos for all users with notifications on this aggregate metric spec. - * - * @param Tracker_AggregateMetricSpecDao $aggregateMetricSpecDao aggregateMetricSpec DAO - * @return false|array of UserDao for all users with notification on the passed in $aggregateMetricSpecDao, - * or false if the passed in spec is invalid - */ - public function getAllNotifiedUsers($aggregateMetricSpecDao) - { - if (is_null($aggregateMetricSpecDao) || $aggregateMetricSpecDao === false) { - return false; - } - $sql = $this->database->select()->setIntegrityCheck(false) - ->from('tracker_user2aggregate_metric_spec', array('user_id')) - ->where('aggregate_metric_spec_id = ?', $aggregateMetricSpecDao->getAggregateMetricSpecId()); - $rows = $this->database->fetchAll($sql); - - $userDaos = array(); - /** @var userModel $userModel */ - $userModel = MidasLoader::loadModel('User'); - /** @var Zend_Db_Table_Row_Abstract $row */ - foreach ($rows as $row) { - $userDaos[] = $userModel->load($row['user_id']); - } - - return $userDaos; - } - - /** - * Return a list of Jobs scheduled to notify users that the passed aggregate metric is above - * the threshold defined in the passed aggregate metric spec. - * - * @param Tracker_AggregateMetricSpecDao $aggregateMetricSpecDao aggregateMetricSpec DAO - * @param Tracker_AggregateMetricDao $aggregateMetricDao aggregateMetric DAO - * @return false|array of Scheduler_JobDao for all users with a notification created, which will only - * be populated if the aggregate metric is above the threshold defined on the aggregate metric spec and - * there exist users to be notified on the aggregate metric spec, or false if the inputs are invalid. - */ - public function scheduleNotificationJobs($aggregateMetricSpecDao, $aggregateMetricDao) - { - if (is_null($aggregateMetricSpecDao) || $aggregateMetricSpecDao === false) { - return false; - } - if (is_null($aggregateMetricDao) || $aggregateMetricDao === false) { - return false; - } - - // if the value exists and the threshold exists, test it - $value = $aggregateMetricDao->getValue(); - $thresholdValue = $aggregateMetricSpecDao->getValue(); - /** @var bool $aboveThreshold */ - $aboveThreshold = false; - switch ($aggregateMetricSpecDao->getComparison()) { - case '>': - $aboveThreshold = $value > $thresholdValue; - break; - case '<': - $aboveThreshold = $value < $thresholdValue; - break; - case '>=': - $aboveThreshold = $value >= $thresholdValue; - break; - case '<=': - $aboveThreshold = $value <= $thresholdValue; - break; - case '==': - $aboveThreshold = $value === $thresholdValue; - break; - case '!=': - $aboveThreshold = $value !== $thresholdValue; - break; - default: - $aboveThreshold = false; - } - - $jobs = array(); - if ($aboveThreshold) { - $notifiedUsers = $this->getAllNotifiedUsers($aggregateMetricSpecDao); - if ($notifiedUsers && count($notifiedUsers) > 0) { - /** @var Scheduler_JobModel $jobModel */ - $jobModel = MidasLoader::loadModel('Job', 'scheduler'); - /** @var userDao $userDao */ - foreach ($notifiedUsers as $userDao) { - /** @var Scheduler_JobDao $jobDao */ - $jobDao = MidasLoader::newDao('JobDao', 'scheduler'); - $jobDao->setTask('TASK_TRACKER_SEND_AGGREGATE_METRIC_NOTIFICATION'); - $jobDao->setPriority(MIDAS_EVENT_PRIORITY_HIGH); - $jobDao->setRunOnlyOnce(1); - $jobDao->setFireTime(date('Y-m-d H:i:s')); - $jobDao->setTimeInterval(0); - $jobDao->setStatus(SCHEDULER_JOB_STATUS_TORUN); - $jobDao->setCreatorId($userDao->getUserId()); - $jobDao->setParams(JsonComponent::encode(array( - 'aggregate_metric_spec_id' => $aggregateMetricSpecDao->getAggregateMetricSpecId(), - 'aggregate_metric_id' => $aggregateMetricDao->getAggregateMetricId(), - 'recipient_id' => $userDao->getUserId(), - ))); - $jobModel->save($jobDao); - $jobs[] = $jobDao; - } - } - } - - return $jobs; - } - /** * Delete the given aggregate metric spec, any metrics calculated based on that spec, * and any associated notifications. @@ -200,10 +34,15 @@ public function delete($aggregateMetricSpecDao) if (is_null($aggregateMetricSpecDao) || $aggregateMetricSpecDao === false) { return; } - $this->database->getDB()->delete('tracker_user2aggregate_metric_spec', 'aggregate_metric_spec_id = '.$aggregateMetricSpecDao->getAggregateMetricSpecId()); + /** @var Tracker_AggregateMetricNotificationModel $aggregateMetricNotificationModel */ + $aggregateMetricNotificationModel = MidasLoader::loadModel('AggregateMetricNotification', 'tracker'); + $aggregateMetricNotifications = $aggregateMetricNotificationModel->findBy('aggregate_metric_spec_id', $aggregateMetricSpecDao->getAggregateMetricSpecId()); + /** @var Tracker_AggregateMetricNotificationDao $aggregateMetricNotificationDao */ + foreach ($aggregateMetricNotifications as $aggregateMetricNotificationDao) { + $aggregateMetricNotificationModel->delete($aggregateMetricNotificationDao); + } + // Delete all associated metrics. $this->database->getDB()->delete('tracker_aggregate_metric', 'aggregate_metric_spec_id = '.$aggregateMetricSpecDao->getAggregateMetricSpecId()); - $this->database->getDB()->delete('tracker_aggregate_metric_spec', 'aggregate_metric_spec_id = '.$aggregateMetricSpecDao->getAggregateMetricSpecId()); - parent::delete($aggregateMetricSpecDao); } } diff --git a/modules/tracker/tests/databaseDataset/aggregateMetric.xml b/modules/tracker/tests/databaseDataset/aggregateMetric.xml index 04117f9a1..edb2ab8a3 100644 --- a/modules/tracker/tests/databaseDataset/aggregateMetric.xml +++ b/modules/tracker/tests/databaseDataset/aggregateMetric.xml @@ -242,26 +242,21 @@ - - - - - - - - - - - - + + + + + + + + + + diff --git a/modules/tracker/tests/models/base/AggregateMetricModelTest.php b/modules/tracker/tests/models/base/AggregateMetricModelTest.php index e5100a3e9..1f7e7fbeb 100644 --- a/modules/tracker/tests/models/base/AggregateMetricModelTest.php +++ b/modules/tracker/tests/models/base/AggregateMetricModelTest.php @@ -320,24 +320,17 @@ public function testComputeAggregateMetricForSubmission() $aggregateMetricDao = $aggregateMetricModel->computeAggregateMetricForSubmission($optimalDistance55thPercentileAMSDao, $submission1Dao); $this->assertEquals($aggregateMetricDao, false); - // AMSes that match branch 'test', with only one scalar. - + // Submissions tied to branch 'test', with only one scalar. /** @var Tracker_SubmissionDao $submission8Dao */ $submission8Dao = $submissionModel->load(8); - /** @var Tracker_AggregateMetricSpecDao $greedyErrorTest0thPercentileAMSDao */ - $greedyErrorTest0thPercentileAMSDao = $aggregateMetricSpecModel->load(8); - $aggregateMetricDao = $aggregateMetricModel->computeAggregateMetricForSubmission($greedyErrorTest0thPercentileAMSDao, $submission8Dao); + $aggregateMetricDao = $aggregateMetricModel->computeAggregateMetricForSubmission($greedyError0thPercentileAMSDao, $submission8Dao); $this->assertEquals($aggregateMetricDao->getValue(), 654.0); - /** @var Tracker_AggregateMetricSpecDao $greedyErrorTest55thPercentileAMSDao */ - $greedyErrorTest55thPercentileAMSDao = $aggregateMetricSpecModel->load(9); - $aggregateMetricDao = $aggregateMetricModel->computeAggregateMetricForSubmission($greedyErrorTest55thPercentileAMSDao, $submission8Dao); + $aggregateMetricDao = $aggregateMetricModel->computeAggregateMetricForSubmission($greedyError55thPercentileAMSDao, $submission8Dao); $this->assertEquals($aggregateMetricDao->getValue(), 654.0); - /** @var Tracker_AggregateMetricSpecDao $greedyErrorTest99thPercentileAMSDao */ - $greedyErrorTest99thPercentileAMSDao = $aggregateMetricSpecModel->load(10); - $aggregateMetricDao = $aggregateMetricModel->computeAggregateMetricForSubmission($greedyErrorTest99thPercentileAMSDao, $submission8Dao); + $aggregateMetricDao = $aggregateMetricModel->computeAggregateMetricForSubmission($greedyError95thPercentileAMSDao, $submission8Dao); $this->assertEquals($aggregateMetricDao->getValue(), 654.0); // AMS that doesn't match any trends. @@ -348,13 +341,6 @@ public function testComputeAggregateMetricForSubmission() $aggregateMetricDao = $aggregateMetricModel->computeAggregateMetricForSubmission($noopDistance95thPercentileAMSDao, $submission1Dao); $this->assertEquals($aggregateMetricDao, false); - // AMS that doesn't match any branches. - /** @var Tracker_AggregateMetricSpecDao $noopDistance95thPercentileTestAMSDao */ - $branch = 'test'; - $noopDistance95thPercentileTestAMSDao = $aggregateMetricSpecModel->createAggregateMetricSpec($producer100Dao, $name, $spec, $branch); - $aggregateMetricDao = $aggregateMetricModel->computeAggregateMetricForSubmission($noopDistance95thPercentileTestAMSDao, $submission1Dao); - $this->assertEquals($aggregateMetricDao, false); - // AMS with missing percentile param. /** @var Tracker_AggregateMetricSpecDao $greedyErrorMissingPercentileAMSDao */ $name = 'Percentile Greedy error'; @@ -482,13 +468,6 @@ public function testUpdateAggregateMetricForSubmission() $aggregateMetricDao = $aggregateMetricModel->updateAggregateMetricForSubmission($noopDistance95thPercentileAMSDao, $submission1Dao); $this->assertEquals($aggregateMetricDao, false); - // AMS that doesn't match any branches. - /** @var Tracker_AggregateMetricSpecDao $noopDistance95thPercentileTestAMSDao */ - $branch = 'test'; - $noopDistance95thPercentileTestAMSDao = $aggregateMetricSpecModel->createAggregateMetricSpec($producer100Dao, $name, $spec, $branch); - $aggregateMetricDao = $aggregateMetricModel->updateAggregateMetricForSubmission($noopDistance95thPercentileTestAMSDao, $submission1Dao); - $this->assertEquals($aggregateMetricDao, false); - // AMS with missing percentile param. /** @var Tracker_AggregateMetricSpecDao $greedyErrorMissingPercentileAMSDao */ $name = 'Percentile Greedy error'; diff --git a/modules/tracker/tests/models/base/AggregateMetricNotificationModelTest.php b/modules/tracker/tests/models/base/AggregateMetricNotificationModelTest.php new file mode 100644 index 000000000..348b1b4ce --- /dev/null +++ b/modules/tracker/tests/models/base/AggregateMetricNotificationModelTest.php @@ -0,0 +1,268 @@ +setupDatabase(array('default')); // core dataset + $this->setupDatabase(array('aggregateMetric'), 'tracker'); // module dataset + $this->enabledModules = array('scheduler', 'tracker'); + $this->_components = array('Json'); + + parent::setUp(); + } + + /** tearDown tester method. */ + public function tearDown() + { + // Delete notified users. + $db = Zend_Registry::get('dbAdapter'); + $db->delete('scheduler_job', "task = 'TASK_TRACKER_SEND_AGGREGATE_METRIC_NOTIFICATION'"); + parent::tearDown(); + } + + /** testUserNotifications */ + public function testUserNotifications() + { + /** @var Tracker_AggregateMetricNotificationModel $aggregateMetricNotificationModel */ + $aggregateMetricNotificationModel = MidasLoader::loadModel('AggregateMetricNotification', 'tracker'); + + /** @var Tracker_AggregateMetricNotificationDao $amn95thPercentileGreedyError */ + $amn95thPercentileGreedyError = $aggregateMetricNotificationModel->load(1); + /** @var Tracker_AggregateMetricNotificationDao $amn55thPercentileGreedyError */ + $amn55thPercentileGreedyError = $aggregateMetricNotificationModel->load(2); + + // At first there are no notified users. + $this->assertEquals(0, count($aggregateMetricNotificationModel->getAllNotifiedUsers($amn95thPercentileGreedyError))); + $this->assertEquals(0, count($aggregateMetricNotificationModel->getAllNotifiedUsers($amn55thPercentileGreedyError))); + + /** @var UserModel $userModel */ + $userModel = MidasLoader::loadModel('User'); + /** @var UserDao $user1Dao */ + $user1Dao = $userModel->load(1); + /** @var UserDao $user2Dao */ + $user2Dao = $userModel->load(2); + /** @var UserDao $user3Dao */ + $user3Dao = $userModel->load(3); + + // Add users to 95th percentile greedy error AMS. + + $expectedNotifiedUsers95thGreedyError = array( + $user1Dao->getUserId() => false, + $user2Dao->getUserId() => false + ); + + $aggregateMetricNotificationModel->createUserNotification($amn95thPercentileGreedyError, $user1Dao); + $aggregateMetricNotificationModel->createUserNotification($amn95thPercentileGreedyError, $user2Dao); + + $actualNotifiedUsers95thGreedyError = $aggregateMetricNotificationModel->getAllNotifiedUsers($amn95thPercentileGreedyError); + $this->assertEquals(count($expectedNotifiedUsers95thGreedyError), count($actualNotifiedUsers95thGreedyError)); + /** @var $UserDao $notifiedUser */ + foreach ($actualNotifiedUsers95thGreedyError as $notifiedUser) { + $expectedNotifiedUsers95thGreedyError[$notifiedUser->getUserId()] = true; + } + // Ensure that the users tied to the notification are who we expect. + /** @var $UserDao $expectedUser */ + /** @var bool $present */ + foreach ($expectedNotifiedUsers95thGreedyError as $notifiedUser => $present) { + $this->assertTrue($present); + } + + // Add a different set of users to 55th percentile greedy error AMS. + + $expectedNotifiedUsers55thGreedyError = array( + $user1Dao->getUserId() => false, + $user3Dao->getUserId() => false + ); + + $aggregateMetricNotificationModel->createUserNotification($amn55thPercentileGreedyError, $user1Dao); + $aggregateMetricNotificationModel->createUserNotification($amn55thPercentileGreedyError, $user3Dao); + + $actualNotifiedUsers55thGreedyError = $aggregateMetricNotificationModel->getAllNotifiedUsers($amn55thPercentileGreedyError); + $this->assertEquals(count($expectedNotifiedUsers55thGreedyError), count($actualNotifiedUsers55thGreedyError)); + /** @var $UserDao $notifiedUser */ + foreach ($actualNotifiedUsers55thGreedyError as $notifiedUser) { + $expectedNotifiedUsers55thGreedyError[$notifiedUser->getUserId()] = true; + } + // Ensure that the users tied to the notification are who we expect. + /** @var $UserDao $expectedUser */ + /** @var bool $present */ + foreach ($expectedNotifiedUsers55thGreedyError as $notifiedUser => $present) { + $this->assertTrue($present); + } + + // Test that scheduler jobs are created for notifications. + + /** @var Tracker_AggregateMetricSpecModel $aggregateMetricSpecModel */ + $aggregateMetricSpecModel = MidasLoader::loadModel('AggregateMetricSpec', 'tracker'); + /** @var Tracker_AggregateMetricSpecDao $greedyError95thPercentileAMSDao */ + $greedyError95thPercentileAMSDao = $aggregateMetricSpecModel->load(1); + /** @var Tracker_AggregateMetricSpecDao $greedyError55thPercentileAMSDao */ + $greedyError55thPercentileAMSDao = $aggregateMetricSpecModel->load(2); + + /** @var Tracker_SubmissionModel $submissionModel */ + $submissionModel = MidasLoader::loadModel('Submission', 'tracker'); + + // Submissions 1 and 2 are tied to branch 'master', submission 8 to 'test'. + // Metrics should be calculated regardless of branch. + // Notifications are tied to branches. + + /** @var Tracker_SubmissionDao $submission1Dao */ + $submission1Dao = $submissionModel->load(1); + /** @var Tracker_SubmissionDao $submission2Dao */ + $submission2Dao = $submissionModel->load(2); + /** @var Tracker_SubmissionDao $submission8Dao */ + $submission8Dao = $submissionModel->load(8); + + /** @var Tracker_AggregateMetricModel $aggregateMetricModel */ + $aggregateMetricModel = MidasLoader::loadModel('AggregateMetric', 'tracker'); + + // Sadly, enabling a module does not import its constants. + require_once BASE_PATH.'/modules/scheduler/constant/module.php'; + /** @var Scheduler_JobModel $jobModel */ + $jobModel = MidasLoader::loadModel('Job', 'scheduler'); + // Ensure there aren't any notification jobs existing. + $this->assertEquals(0, count($jobModel->findBy('task', 'TASK_TRACKER_SEND_AGGREGATE_METRIC_NOTIFICATION'))); + + /** @var Tracker_AggregateMetricDao $greedyError95thSubmission1Metric */ + $greedyError95thSubmission1Metric = $aggregateMetricModel->updateAggregateMetricForSubmission($greedyError95thPercentileAMSDao, $submission1Dao); + $this->assertEquals($greedyError95thSubmission1Metric->getValue(), 19.0); + $notificationJobs = $aggregateMetricNotificationModel->scheduleNotificationJobs($greedyError95thSubmission1Metric); + $this->assertEquals(0, count($notificationJobs)); + + $expectedNotifiedUsers95thGreedyError = array( + $user1Dao->getUserId() => false, + $user2Dao->getUserId() => false + ); + + /** @var Tracker_AggregateMetricDao $greedyError95thSubmission2Metric */ + $greedyError95thSubmission2Metric = $aggregateMetricModel->updateAggregateMetricForSubmission($greedyError95thPercentileAMSDao, $submission2Dao); + $this->assertEquals($greedyError95thSubmission2Metric->getValue(), 38.0); + $notificationJobs = $aggregateMetricNotificationModel->scheduleNotificationJobs($greedyError95thSubmission2Metric); + $this->assertEquals(2, count($notificationJobs)); + foreach ($notificationJobs as $job) { + preg_match("/\"recipient_id\":\"(\d+)\"/", $job->getParams(), $matches); + $userId = $matches[1]; + $expectedNotifiedUsers95thGreedyError[$userId] = true; + } + // Ensure notifications are created for the correct users. + /** @var $UserDao $notifiedUser */ + /** @var bool $present */ + foreach ($expectedNotifiedUsers95thGreedyError as $notifiedUser => $present) { + $this->assertTrue($present); + } + + /** @var Tracker_AggregateMetricDao $greedyError95thSubmission8Metric */ + $greedyError95thSubmission8Metric = $aggregateMetricModel->updateAggregateMetricForSubmission($greedyError95thPercentileAMSDao, $submission8Dao); + $this->assertEquals($greedyError95thSubmission8Metric->getValue(), 654.0); + // Even though the value is above threshold, it is not a branch that will notify. + $this->assertEquals(0, count($aggregateMetricNotificationModel->scheduleNotificationJobs($greedyError95thSubmission8Metric))); + + /** @var Tracker_AggregateMetricDao $greedyError55thSubmission1Metric */ + $greedyError55thSubmission1Metric = $aggregateMetricModel->updateAggregateMetricForSubmission($greedyError55thPercentileAMSDao, $submission1Dao); + $this->assertEquals($greedyError55thSubmission1Metric->getValue(), 11.0); + $this->assertEquals(0, count($aggregateMetricNotificationModel->scheduleNotificationJobs($greedyError55thSubmission1Metric))); + + $expectedNotifiedUsers55thGreedyError = array( + $user1Dao->getUserId() => false, + $user3Dao->getUserId() => false + ); + + /** @var Tracker_AggregateMetricDao $greedyError55thSubmission2Metric */ + $greedyError55thSubmission2Metric = $aggregateMetricModel->updateAggregateMetricForSubmission($greedyError55thPercentileAMSDao, $submission2Dao); + $this->assertEquals($greedyError55thSubmission2Metric->getValue(), 22.0); + $notificationJobs = $aggregateMetricNotificationModel->scheduleNotificationJobs($greedyError55thSubmission2Metric); + $this->assertEquals(2, count($notificationJobs)); + foreach ($notificationJobs as $job) { + preg_match("/\"recipient_id\":\"(\d+)\"/", $job->getParams(), $matches); + $userId = $matches[1]; + $expectedNotifiedUsers55thGreedyError[$userId] = true; + } + // Ensure notifications are created for the correct users. + /** @var $UserDao $notifiedUser */ + /** @var bool $present */ + foreach ($expectedNotifiedUsers55thGreedyError as $notifiedUser => $present) { + $this->assertTrue($present); + } + + /** @var Tracker_AggregateMetricDao $greedyError55thSubmission8Metric */ + $greedyError55thSubmission8Metric = $aggregateMetricModel->computeAggregateMetricForSubmission($greedyError55thPercentileAMSDao, $submission8Dao); + $this->assertEquals($greedyError55thSubmission8Metric->getValue(), 654.0); + // Even though the value is above threshold, it is not a branch that will notify. + $this->assertEquals(0, count($aggregateMetricNotificationModel->scheduleNotificationJobs($greedyError55thSubmission8Metric))); + + // Clean up after the test. + $aggregateMetricModel->delete($greedyError95thSubmission1Metric); + $aggregateMetricModel->delete($greedyError55thSubmission1Metric); + + // Ensure that removing a user from a notification actually removes them. + $aggregateMetricNotificationModel->deleteUserNotification($amn95thPercentileGreedyError, $user1Dao); + $aggregateMetricNotificationModel->deleteUserNotification($amn95thPercentileGreedyError, $user2Dao); + $actualNotifiedUsers95thGreedyError = $aggregateMetricNotificationModel->getAllNotifiedUsers($amn95thPercentileGreedyError); + $this->assertEquals(0, count($actualNotifiedUsers95thGreedyError)); + + // Ensure that removing a user from a notification actually removes them. + $aggregateMetricNotificationModel->deleteUserNotification($amn55thPercentileGreedyError, $user1Dao); + $aggregateMetricNotificationModel->deleteUserNotification($amn55thPercentileGreedyError, $user3Dao); + $actualNotifiedUsers55thGreedyError = $aggregateMetricNotificationModel->getAllNotifiedUsers($amn55thPercentileGreedyError); + $this->assertEquals(0, count($actualNotifiedUsers55thGreedyError)); + } + + /** testDelete */ + public function testDelete() + { + /** @var Tracker_AggregateMetricNotificationModel $aggregateMetricNotificationModel */ + $aggregateMetricNotificationModel = MidasLoader::loadModel('AggregateMetricNotification', 'tracker'); + + // Create a notification, tie 2 users to it, then delete it. + $args = array( + 'aggregate_metric_spec_id' => 1, + 'branch' => 'blaster', + 'comparison' => '>', + 'value' => 1, + ); + + /** @var Tracker_AggregateMetricNotificationDao $aggregateMetricNotificationDao */ + $aggregateMetricNotificationDao = $aggregateMetricNotificationModel->initDao('AggregateMetricNotification', $args, 'tracker'); + $aggregateMetricNotificationModel->save($aggregateMetricNotificationDao); + $amnId = $aggregateMetricNotificationDao->getAggregateMetricNotificationId(); + + /** @var UserModel $userModel */ + $userModel = MidasLoader::loadModel('User'); + /** @var UserDao $user1Dao */ + $user1Dao = $userModel->load(1); + /** @var UserDao $user2Dao */ + $user2Dao = $userModel->load(2); + + $aggregateMetricNotificationModel->createUserNotification($aggregateMetricNotificationDao, $user1Dao); + $aggregateMetricNotificationModel->createUserNotification($aggregateMetricNotificationDao, $user2Dao); + + $aggregateMetricNotificationModel->delete($aggregateMetricNotificationDao); + + // Ensure the linked users are deleted. + $db = Zend_Registry::get('dbAdapter'); + $row = $db->query('select count(*) as count from tracker_user2aggregate_metric_notification where aggregate_metric_notification_id = '. $amnId)->fetch(); + $this->assertEquals($row['count'], 0); + $this->assertFalse($aggregateMetricNotificationModel->load($amnId)); + } +} diff --git a/modules/tracker/tests/models/base/AggregateMetricSpecModelTest.php b/modules/tracker/tests/models/base/AggregateMetricSpecModelTest.php index 6f2b78e61..7b0a50235 100644 --- a/modules/tracker/tests/models/base/AggregateMetricSpecModelTest.php +++ b/modules/tracker/tests/models/base/AggregateMetricSpecModelTest.php @@ -21,18 +21,14 @@ /** Test the AggregateMetricSpec. */ class Tracker_AggregateMetricSpecModelTest extends DatabaseTestCase { + public $moduleName = 'tracker'; + /** Set up tests. */ public function setUp() { $this->setupDatabase(array('default')); // core dataset $this->setupDatabase(array('aggregateMetric'), 'tracker'); // module dataset $this->enabledModules = array('tracker'); - $db = Zend_Registry::get('dbAdapter'); - $configDatabase = Zend_Registry::get('configDatabase'); - if ($configDatabase->database->adapter == 'PDO_PGSQL') { - $db->query("SELECT setval('tracker_aggregate_metric_spec_aggregate_metric_spec_id_seq', (SELECT MAX(aggregate_metric_spec_id) FROM tracker_aggregate_metric_spec)+1);"); - $db->query("SELECT setval('tracker_aggregate_metric_aggregate_metric_id_seq', (SELECT MAX(aggregate_metric_id) FROM tracker_aggregate_metric)+1);"); - } parent::setUp(); } @@ -162,62 +158,6 @@ public function testGetAggregateMetricSpecsForSubmission() $this->assertFalse($submissionAggregateMetricSpecDaos); } - /** test AggregateMetricSpecModel notification related functions */ - public function testAggregateMetricSpecNotificationFunctions() - { - /** @var AggregateMetricSpecModel $aggregateMetricSpecModel */ - $aggregateMetricSpecModel = MidasLoader::loadModel('AggregateMetricSpec', 'tracker'); - - $name = '67th Percentile Greedy distance '; - $spec = "percentile('Greedy distance', 67)"; - - /** @var Tracker_ProducerModel $producerModel */ - $producerModel = MidasLoader::loadModel('Producer', 'tracker'); - /** @var Tracker_ProducerDao $producer100Dao */ - $producer100Dao = $producerModel->load(100); - - /** @var AggregateMetricSpecDao $validAMSDao */ - $validAMSDao = $aggregateMetricSpecModel->createAggregateMetricSpec($producer100Dao, $name, $spec); - - // There should be no notifications. - $this->assertEquals(0, count($aggregateMetricSpecModel->getAllNotifiedUsers($validAMSDao))); - - /** @var UserModel $userModel */ - $userModel = MidasLoader::loadModel('User'); - /** @var UserDao $user1Dao */ - $user1Dao = $userModel->load(1); - /** @var UserDao $user2Dao */ - $user2Dao = $userModel->load(2); - /** @var UserDao $user3Dao */ - $user3Dao = $userModel->load(3); - - // Create 3 notifications. - $aggregateMetricSpecModel->createUserNotification($validAMSDao, $user1Dao); - // Try to repeat a creation, should not fail. - $aggregateMetricSpecModel->createUserNotification($validAMSDao, $user1Dao); - $aggregateMetricSpecModel->createUserNotification($validAMSDao, $user2Dao); - $aggregateMetricSpecModel->createUserNotification($validAMSDao, $user3Dao); - - $this->assertEquals(3, count($aggregateMetricSpecModel->getAllNotifiedUsers($validAMSDao))); - - // Delete and check. - $aggregateMetricSpecModel->deleteUserNotification($validAMSDao, $user3Dao); - $this->assertEquals(2, count($aggregateMetricSpecModel->getAllNotifiedUsers($validAMSDao))); - - $aggregateMetricSpecModel->deleteUserNotification($validAMSDao, $user1Dao); - /** @var array $notifications */ - $notifications = $aggregateMetricSpecModel->getAllNotifiedUsers($validAMSDao); - $this->assertEquals(1, count($notifications)); - // Deleted 1 and 3, 2 should be left. - $this->assertEquals($notifications[0]->user_id, 2); - - $aggregateMetricSpecModel->deleteUserNotification($validAMSDao, $user2Dao); - $this->assertEquals(0, count($aggregateMetricSpecModel->getAllNotifiedUsers($validAMSDao))); - - // Clean up the created spec. - $aggregateMetricSpecModel->delete($validAMSDao); - } - /** test AggregateMetricSpecModel delete function */ public function testAggregateMetricSpecDelete() { @@ -256,8 +196,7 @@ public function testAggregateMetricSpecDelete() /** @var AggregateMetricSpecDao $validAMSDao */ $validAMSDao = $aggregateMetricSpecModel->createAggregateMetricSpec($producer100Dao, $name, $spec); - // There should be no notifications. - $this->assertEquals(0, count($aggregateMetricSpecModel->getAllNotifiedUsers($validAMSDao))); + // Create A notification, tied to 2 users. /** @var UserModel $userModel */ $userModel = MidasLoader::loadModel('User'); @@ -265,15 +204,28 @@ public function testAggregateMetricSpecDelete() $user1Dao = $userModel->load(1); /** @var UserDao $user2Dao */ $user2Dao = $userModel->load(2); - /** @var UserDao $user3Dao */ - $user3Dao = $userModel->load(3); - // Create 3 notifications. - $aggregateMetricSpecModel->createUserNotification($validAMSDao, $user1Dao); - $aggregateMetricSpecModel->createUserNotification($validAMSDao, $user2Dao); - $aggregateMetricSpecModel->createUserNotification($validAMSDao, $user3Dao); + /** @var Tracker_AggregateMetricNotificationModel $aggregateMetricNotificationModel */ + $aggregateMetricNotificationModel = MidasLoader::loadModel('AggregateMetricNotification', 'tracker'); + + $notificationProperties = array( + 'aggregate_metric_spec_id' => $validAMSDao->getAggregateMetricSpecId(), + 'branch' => 'notify 1', + 'comparison' => '==', + 'value' => '16.0', + ); + /** @var Tracker_AggregateMetricNotificationDao $notification1Dao */ + $notification1Dao = $aggregateMetricNotificationModel->initDao('AggregateMetricNotification', $notificationProperties, $this->moduleName); + $aggregateMetricNotificationModel->save($notification1Dao); + $aggregateMetricNotificationModel->createUserNotification($notification1Dao, $user1Dao); + $aggregateMetricNotificationModel->createUserNotification($notification1Dao, $user2Dao); + + $this->assertEquals(2, count($aggregateMetricNotificationModel->getAllNotifiedUsers($notification1Dao))); - $this->assertEquals(3, count($aggregateMetricSpecModel->getAllNotifiedUsers($validAMSDao))); + /** @var AggregateMetricSpecDao $cachedAMSDao */ + $cachedAMSDao = $aggregateMetricSpecModel->load($validAMSDao->getAggregateMetricSpecId()); + + // Compute some aggregate metrics to check that they will be deleted. /** @var AggregateMetricModel $aggregateMetricModel */ $aggregateMetricModel = MidasLoader::loadModel('AggregateMetric', 'tracker'); @@ -285,27 +237,31 @@ public function testAggregateMetricSpecDelete() $aggregateMetricDaos = $aggregateMetricModel->getAggregateMetricsForSubmission($submission1Dao); $this->assertEquals(1, count($aggregateMetricDaos)); $this->assertEquals($aggregateMetricDaos[0]->getValue(), 7.0); - $aggregateMetricDao = $aggregateMetricModel->updateAggregateMetricForSubmission($validAMSDao, $submission2Dao); $this->assertEquals($aggregateMetricDao->getValue(), 14.0); $aggregateMetricDaos = $aggregateMetricModel->getAggregateMetricsForSubmission($submission2Dao); $this->assertEquals(1, count($aggregateMetricDaos)); $this->assertEquals($aggregateMetricDaos[0]->getValue(), 14.0); - // Delete the created spec. /** @var AggregateMetricSpecDao $cachedAMSDao */ $cachedAMSDao = $aggregateMetricSpecModel->load($validAMSDao->getAggregateMetricSpecId()); + + // Delete the created spec, which should cascade to the metrics, the notifications, and the notification users. $aggregateMetricSpecModel->delete($validAMSDao); $aggregateMetricDaos = $aggregateMetricModel->getAggregateMetricsForSubmission($submission1Dao); $this->assertEquals(0, count($aggregateMetricDaos)); $aggregateMetricDaos = $aggregateMetricModel->getAggregateMetricsForSubmission($submission2Dao); $this->assertEquals(0, count($aggregateMetricDaos)); - // The AMS is deleted in the DB, but we have cached a DAO so we can ensure there are no notifications. - $this->assertEquals(0, count($aggregateMetricSpecModel->getAllNotifiedUsers($cachedAMSDao))); /** @var AggregateMetricSpecDao $loadedAMSDao */ $loadedAMSDao = $aggregateMetricSpecModel->load($cachedAMSDao->getAggregateMetricSpecId()); $this->assertFalse($loadedAMSDao); + + // There shouldn't be any linked users. + $this->assertEquals(0, count($aggregateMetricNotificationModel->getAllNotifiedUsers($notification1Dao))); + // Reloading the notification DAO should produce false. + $notification1Dao = $aggregateMetricNotificationModel->load($notification1Dao->getAggregateMetricNotificationId()); + $this->assertFalse($notification1Dao); } } diff --git a/modules/tracker/tests/models/base/CMakeLists.txt b/modules/tracker/tests/models/base/CMakeLists.txt index b3a6dd6cd..db0d926a7 100644 --- a/modules/tracker/tests/models/base/CMakeLists.txt +++ b/modules/tracker/tests/models/base/CMakeLists.txt @@ -21,7 +21,7 @@ set(module_name tracker) to_titlecase(${module_name} module_name_titlecase) add_midas_mysql_test(${module_name_titlecase}AggregateMetricModel AggregateMetricModelTest.php) +add_midas_mysql_test(${module_name_titlecase}AggregateMetricNotificationModel AggregateMetricNotificationModelTest.php) add_midas_mysql_test(${module_name_titlecase}AggregateMetricSpecModel AggregateMetricSpecModelTest.php) add_midas_mysql_test(${module_name_titlecase}ScalarModel ScalarModelTest.php) add_midas_mysql_test(${module_name_titlecase}SubmissionModel SubmissionModelTest.php) - From ce1627045f233074b19ba5aef71341eaaa7334dc Mon Sep 17 00:00:00 2001 From: mgrauer Date: Wed, 13 Apr 2016 02:04:56 +0000 Subject: [PATCH 32/40] Split notification from specs in API --- .../AggregatemetricnotificationController.php | 103 ++++++++ .../controllers/components/ApiComponent.php | 78 +++--- ...piaggregatemetricnotificationComponent.php | 232 ++++++++++++++++++ .../ApiaggregatemetricspecComponent.php | 6 - ...gregatemetricnotificationComponentTest.php | 228 +++++++++++++++++ .../ApiAggregatemetricspecComponentTest.php | 21 -- .../tests/controllers/ApiComponentTest.php | 87 +++++-- .../tracker/tests/controllers/CMakeLists.txt | 1 + 8 files changed, 675 insertions(+), 81 deletions(-) create mode 100644 modules/tracker/controllers/api/AggregatemetricnotificationController.php create mode 100644 modules/tracker/controllers/components/ApiaggregatemetricnotificationComponent.php create mode 100644 modules/tracker/tests/controllers/ApiAggregatemetricnotificationComponentTest.php diff --git a/modules/tracker/controllers/api/AggregatemetricnotificationController.php b/modules/tracker/controllers/api/AggregatemetricnotificationController.php new file mode 100644 index 000000000..d2c697002 --- /dev/null +++ b/modules/tracker/controllers/api/AggregatemetricnotificationController.php @@ -0,0 +1,103 @@ +_genericAction( + $this->_request->getParams(), + $this->_request->getControllerName(), + $this->_request->getActionName(), + array('default' => $this->_request->getActionName()), + $this->moduleName, + false + ); + } + + /** Handle HTTP GET requests. Requires an id parameter. */ + public function getAction() + { + $this->_genericAction( + $this->_request->getParams(), + $this->_request->getControllerName(), + $this->_request->getActionName(), + array('default' => $this->_request->getActionName()), + $this->moduleName, + false + ); + } + + /** Handle HTTP HEAD requests. */ + public function headAction() + { + $this->_response->setHttpResponseCode(200); // 200 OK + } + + /** Handle HTTP GET index or list requests. */ + public function indexAction() + { + $this->_genericAction( + $this->_request->getParams(), + $this->_request->getControllerName(), + $this->_request->getActionName(), + array('default' => $this->_request->getActionName()), + $this->moduleName, + false + ); + } + + /** Handle HTTP OPTIONS requests. */ + public function optionsAction() + { + $this->_response->setHeader('Allow', 'DELETE, GET, HEAD, OPTIONS, POST, PUT'); + } + + /** Handle HTTP POST requests. */ + public function postAction() + { + $this->_genericAction( + $this->_request->getParams(), + $this->_request->getControllerName(), + $this->_request->getActionName(), + array('default' => $this->_request->getActionName()), + $this->moduleName, + false + ); + } + + /** Handle HTTP PUT requests. Requires an id parameter. */ + public function putAction() + { + $this->_genericAction( + $this->_request->getParams(), + $this->_request->getControllerName(), + $this->_request->getActionName(), + array('default' => $this->_request->getActionName()), + $this->moduleName, + false + ); + } +} diff --git a/modules/tracker/controllers/components/ApiComponent.php b/modules/tracker/controllers/components/ApiComponent.php index 1da890101..630b5c453 100644 --- a/modules/tracker/controllers/components/ApiComponent.php +++ b/modules/tracker/controllers/components/ApiComponent.php @@ -409,85 +409,103 @@ private function _loadAggregateMetricSpec($userDao, $aggregateMetricSpecId, $pol } /** - * Create a notification for a user against an aggregate metric spec, so that - * whenever an aggregate metric created from that aggregate metric spec + * Create a notification for a user against an aggregate metric notification, + * so that whenever an aggregate metric created from that aggregate metric spec * is beyond the notification threshold, the user will be notified by email. * - * @param userId The id of the user to create a notification for - * @param aggregateMetricSpecId The id of the aggregate metric spec + * @param userId The id of the user to tie to the notification + * @param aggregateMetricNotificationId The id of the aggregate metric notification * @return UserDao the user DAO of the user who will be alerted * @throws Exception */ public function aggregatemetricspecnotifieduserCreate($args) { - $this->_checkKeys(array('userId', 'aggregateMetricSpecId'), $args); + $this->_checkKeys(array('userId', 'aggregateMetricNotificationId'), $args); $user = $this->_getUser($args); - $aggregateMetricSpecId = $args['aggregateMetricSpecId']; - $aggregateMetricSpecDao = $this->_loadAggregateMetricSpec($user, $aggregateMetricSpecId, MIDAS_POLICY_ADMIN); + $aggregateMetricNotificationId = $args['aggregateMetricNotificationId']; + /** @var Tracker_AggregateMetricNotificationModel $aggregateMetricNotificationModel */ + $aggregateMetricNotificationModel = MidasLoader::loadModel('AggregateMetricNotification', 'tracker'); + /** @var Tracker_AggregateMetricNotificationDao $aggregateMetricNotificationDao */ + $aggregateMetricNotificationDao = $aggregateMetricNotificationModel->load($aggregateMetricNotificationId); + + /** @var Tracker_AggregateMetricSpecDao $aggregateMetricSpecDao */ + $aggregateMetricSpecDao = $this->_loadAggregateMetricSpec($user, $aggregateMetricNotificationDao->getAggregateMetricSpecId(), MIDAS_POLICY_ADMIN); /** @var UserModel $userModel */ $userModel = MidasLoader::loadModel('User'); /** @var UserDao $notificationUserDao */ $notificationUserDao = $userModel->load($args['userId']); - /** @var Tracker_AggregateMetricSpecModel $aggregateMetricSpecModel */ - $aggregateMetricSpecModel = MidasLoader::loadModel('AggregateMetricSpec', 'tracker'); - $aggregateMetricSpecModel->createUserNotification($aggregateMetricSpecDao, $notificationUserDao); + $aggregateMetricNotificationModel->createUserNotification($aggregateMetricNotificationDao, $notificationUserDao); return $notificationUserDao; } /** - * Delete a notification for a user against an aggregate metric spec, so that - * the user will no longer receive notifications from aggregate metrics created - * from that aggregate metric spec. + * Delete a user from an aggregate metric notification, + * the user will no longer receive notifications when aggregate metrics created + * from the associated aggregate metric spec are beyond the notification threshold of the + * notification. * - * @param userId The id of the user to delete a notification for - * @param aggregateMetricSpecId The id of the aggregate metric spec + * @param userId The id of the user to delete from the notification + * @param aggregateMetricNotificationId The id of the aggregate metric notification * @return UserDao the user DAO of the user who will no longer be alerted * @throws Exception */ public function aggregatemetricspecnotifieduserDelete($args) { - $this->_checkKeys(array('userId', 'aggregateMetricSpecId'), $args); + $this->_checkKeys(array('userId', 'aggregateMetricNotificationId'), $args); $user = $this->_getUser($args); - $aggregateMetricSpecId = $args['aggregateMetricSpecId']; - $aggregateMetricSpecDao = $this->_loadAggregateMetricSpec($user, $aggregateMetricSpecId, MIDAS_POLICY_ADMIN); + $aggregateMetricNotificationId = $args['aggregateMetricNotificationId']; + /** @var Tracker_AggregateMetricNotificationModel $aggregateMetricNotificationModel */ + $aggregateMetricNotificationModel = MidasLoader::loadModel('AggregateMetricNotification', 'tracker'); + /** @var Tracker_AggregateMetricNotificationDao $aggregateMetricNotificationDao */ + $aggregateMetricNotificationDao = $aggregateMetricNotificationModel->load($aggregateMetricNotificationId); + + /** @var Tracker_AggregateMetricSpecDao $aggregateMetricSpecDao */ + $aggregateMetricSpecDao = $this->_loadAggregateMetricSpec($user, $aggregateMetricNotificationDao->getAggregateMetricSpecId(), MIDAS_POLICY_ADMIN); /** @var UserModel $userModel */ $userModel = MidasLoader::loadModel('User'); /** @var UserDao $notificationUserDao */ $notificationUserDao = $userModel->load($args['userId']); - /** @var Tracker_AggregateMetricSpecModel $aggregateMetricSpecModel */ - $aggregateMetricSpecModel = MidasLoader::loadModel('AggregateMetricSpec', 'tracker'); - $aggregateMetricSpecModel->deleteUserNotification($aggregateMetricSpecDao, $notificationUserDao); + $aggregateMetricNotificationModel->deleteUserNotification($aggregateMetricNotificationDao, $notificationUserDao); return $notificationUserDao; } /** - * Return a list of User Daos for all users with notifications on this aggregate metric spec. + * Return an array of associative arrays, with keys 'notification' => an AggregateMetricNotificationDao + * and 'users' => an array of UserDaos tied to the AggregateMetricNotificationDao, for each + * AggregateMetricNotification tied to the passed in AggregateMetricSpecId. * * @param aggregateMetricSpecId the id of the aggregate metric spec - * @return array of UserDao for all users with notification on the passed in aggregateMetricSpecId + * @return array of associative arrays with keys 'notification' and 'users' */ - public function aggregatemetricspecnotifiedusersList($args) + public function aggregatemetricspecnotificationsList($args) { $this->_checkKeys(array('aggregateMetricSpecId'), $args); $user = $this->_getUser($args); + /** @var Tracker_AggregateMetricSpecDao $aggregateMetricSpecDao */ $aggregateMetricSpecDao = $this->_loadAggregateMetricSpec($user, $args['aggregateMetricSpecId']); - /** @var Tracker_AggregateMetricSpecModel $aggregateMetricSpecModel */ - $aggregateMetricSpecModel = MidasLoader::loadModel('AggregateMetricSpec', 'tracker'); - $notifiedUsers = $aggregateMetricSpecModel->getAllNotifiedUsers($aggregateMetricSpecDao); - if ($notifiedUsers === false) { - $notifiedUsers = array(); + /** @var Tracker_AggregateMetricNotificationModel $aggregateMetricNotificationModel */ + $aggregateMetricNotificationModel = MidasLoader::loadModel('AggregateMetricNotification', 'tracker'); + /** @var array $notifications */ + $notifications = $aggregateMetricNotificationModel->findBy('aggregate_metric_spec_id', $aggregateMetricSpecDao->getAggregateMetricSpecId()); + $response = array(); + /** @var Tracker_AggregateMetricNotificationDao $notification */ + foreach ($notifications as $notification) { + $response[] = array( + 'notification' => $notification, + 'users' => $aggregateMetricNotificationModel->getAllNotifiedUsers($notification), + ); } - return $notifiedUsers; + return $response; } } diff --git a/modules/tracker/controllers/components/ApiaggregatemetricnotificationComponent.php b/modules/tracker/controllers/components/ApiaggregatemetricnotificationComponent.php new file mode 100644 index 000000000..e85b51060 --- /dev/null +++ b/modules/tracker/controllers/components/ApiaggregatemetricnotificationComponent.php @@ -0,0 +1,232 @@ +validateParams($args, array('id')); + $apihelperComponent->requirePolicyScopes(array(MIDAS_API_PERMISSION_SCOPE_ADMIN_DATA)); + + /** @var int $aggregateMetricNotificationId */ + $aggregateMetricNotificationId = $args['id']; + + /** @var Tracker_AggregateMetricNotificationModel $aggregateMetricNotificationModel */ + $aggregateMetricNotificationModel = MidasLoader::loadModel('AggregateMetricNotification', $this->moduleName); + /** @var Tracker_AggregateMetricSpecModel $aggregateMetricSpecModel */ + $aggregateMetricSpecModel = MidasLoader::loadModel('AggregateMetricSpec', $this->moduleName); + + /** @var Tracker_AggregateMetricNotificationDao $aggregateMetricNotificationDao */ + $aggregateMetricNotificationDao = $aggregateMetricNotificationModel->load($aggregateMetricNotificationId); + $userDao = $apihelperComponent->getUser($args); + if ($aggregateMetricSpecModel->policyCheck($aggregateMetricNotificationDao->getAggregateMetricSpec(), $userDao, MIDAS_POLICY_WRITE) === false) { + throw new Exception('The aggregateMetricNotification does not exist or you do not have the necessary permission', MIDAS_INVALID_POLICY); + } + + $aggregateMetricNotificationModel->delete($aggregateMetricNotificationDao); + } + + /** + * Retrieve the given aggregateMetricNotification. + * + * @path /tracker/aggregatemetricnotification/{id} + * @http GET + * @param id + * @return array + * + * @param array $args parameters + * @throws Exception + */ + public function get($args) + { + /** @var ApihelperComponent $apihelperComponent */ + $apihelperComponent = MidasLoader::loadComponent('Apihelper'); + $apihelperComponent->validateParams($args, array('id')); + $apihelperComponent->requirePolicyScopes(array(MIDAS_API_PERMISSION_SCOPE_READ_DATA)); + + /** @var int $aggregateMetricNotificationId */ + $aggregateMetricNotificationId = $args['id']; + + /** @var Tracker_AggregateMetricNotificationModel $aggregateMetricNotificationModel */ + $aggregateMetricNotificationModel = MidasLoader::loadModel('AggregateMetricNotification', $this->moduleName); + /** @var Tracker_AggregateMetricSpecModel $aggregateMetricSpecModel */ + $aggregateMetricSpecModel = MidasLoader::loadModel('AggregateMetricSpec', $this->moduleName); + + /** @var Tracker_AggregateMetricNotificationDao $aggregateMetricNotificationDao */ + $aggregateMetricNotificationDao = $aggregateMetricNotificationModel->load($aggregateMetricNotificationId); + $userDao = $apihelperComponent->getUser($args); + if ($aggregateMetricSpecModel->policyCheck($aggregateMetricNotificationDao->getAggregateMetricSpec(), $userDao, MIDAS_POLICY_WRITE) === false) { + throw new Exception('The aggregateMetricNotification does not exist or you do not have the necessary permission', MIDAS_INVALID_POLICY); + } + + return $this->_toArray($aggregateMetricNotificationDao); + } + + /** + * TODO. + * + * @path /tracker/aggregatemetricnotification/{id} + * @http GET + * @return array + * + * @param array $args parameters + * @throws Exception + */ + public function index($args) + { + /** @var ApihelperComponent $apihelperComponent */ + $apihelperComponent = MidasLoader::loadComponent('Apihelper'); + $apihelperComponent->validateParams($args, array()); + $apihelperComponent->requirePolicyScopes(array(MIDAS_API_PERMISSION_SCOPE_READ_DATA)); + + // TODO: Implement index(). + + return array(); + } + + /** + * Create a new aggregateMetricNotification. + * + * @path /tracker/aggregatemetricnotification + * @http POST + * @param aggregate_metric_spec_id + * @param branch + * @param comparison + * @param value + * @return array + * + * @param array $args parameters + * @throws Exception + */ + public function post($args) + { + /** @var ApihelperComponent $apihelperComponent */ + $apihelperComponent = MidasLoader::loadComponent('Apihelper'); + $apihelperComponent->validateParams($args, array('aggregate_metric_spec_id', 'branch', 'comparison', 'value')); + $apihelperComponent->requirePolicyScopes(array(MIDAS_API_PERMISSION_SCOPE_WRITE_DATA)); + + /** @var int $aggregateMetricSpecId */ + $aggregateMetricSpecId = $args['aggregate_metric_spec_id']; + + /** @var Tracker_AggregateMetricSpecModel $aggregateMetricSpecModel */ + $aggregateMetricSpecModel = MidasLoader::loadModel('AggregateMetricSpec', $this->moduleName); + + /** @var Tracker_AggregateMetricNotificationDao $aggregateMetricNotificationDao */ + $aggregateMetricSpecDao = $aggregateMetricSpecModel->load($aggregateMetricSpecId); + $userDao = $apihelperComponent->getUser($args); + if ($aggregateMetricSpecModel->policyCheck($aggregateMetricSpecDao, $userDao, MIDAS_POLICY_WRITE) === false) { + throw new Exception('The aggregateMetricSpec does not exist or you do not have the necessary permission', MIDAS_INVALID_POLICY); + } + + /** @var Tracker_AggregateMetricNotificationModel $aggregateMetricNotificationModel */ + $aggregateMetricNotificationModel = MidasLoader::loadModel('AggregateMetricNotification', $this->moduleName); + /** @var Tracker_AggregateMetricNotificationDao $aggregateMetricNotificationDao */ + $aggregateMetricNotificationDao = $aggregateMetricNotificationModel->initDao('AggregateMetricNotification', $args, $this->moduleName); + $aggregateMetricNotificationModel->save($aggregateMetricNotificationDao); + + return $this->_toArray($aggregateMetricNotificationDao); + } + + /** + * Update the given aggregateMetricNotification. + * + * @path /tracker/aggregatemetricnotification/{id} + * @http PUT + * @param id + * @param branch(Optional) + * @param value (Optional) + * @param comparison (Optional) + * @return array + * + * @param array $args parameters + * @throws Exception + */ + public function put($args) + { + /** @var ApihelperComponent $apihelperComponent */ + $apihelperComponent = MidasLoader::loadComponent('Apihelper'); + $apihelperComponent->validateParams($args, array('id')); + $apihelperComponent->requirePolicyScopes(array(MIDAS_API_PERMISSION_SCOPE_WRITE_DATA)); + + /** @var int $aggregateMetricNotificationId */ + $aggregateMetricNotificationId = $args['id']; + + /** @var Tracker_AggregateMetricNotificationModel $aggregateMetricNotificationModel */ + $aggregateMetricNotificationModel = MidasLoader::loadModel('AggregateMetricNotification', $this->moduleName); + /** @var Tracker_AggregateMetricSpecModel $aggregateMetricSpecModel */ + $aggregateMetricSpecModel = MidasLoader::loadModel('AggregateMetricSpec', $this->moduleName); + + /** @var Tracker_AggregateMetricNotificationDao $aggregateMetricNotificationDao */ + $aggregateMetricNotificationDao = $aggregateMetricNotificationModel->load($aggregateMetricNotificationId); + $userDao = $apihelperComponent->getUser($args); + if ($aggregateMetricSpecModel->policyCheck($aggregateMetricNotificationDao->getAggregateMetricSpec(), $userDao, MIDAS_POLICY_WRITE) === false) { + throw new Exception('The aggregateMetricNotification does not exist or you do not have the necessary permission', MIDAS_INVALID_POLICY); + } + + // Disallow modification of the aggregate_metric_spec_id. + if (isset($args['aggregate_metric_spec_id'])) { + unset($args['aggregate_metric_spec_id']); + } + + /** @var string $name */ + /** @var mixed $option */ + foreach ($aggregateMetricNotificationModel->getMainData() as $name => $option) { + if (isset($args[$name])) { + $aggregateMetricNotificationDao->$name = $args[$name]; + } + } + $aggregateMetricNotificationModel->save($aggregateMetricNotificationDao); + + return $this->_toArray($aggregateMetricNotificationDao); + } + + /** + * Convert the given aggregateMetricNotification DAO to an array and prepend metadata. + * + * @param Tracker_AggregateMetricNotificationDao $aggregateMetricNotificationDao aggregateMetricNotification DAO + * @return array associative array representation of the aggregateMetricNotification DAO with metadata prepended + */ + protected function _toArray($aggregateMetricNotificationDao) + { + $aggregateMetricNotificationArray = array( + '_id' => $aggregateMetricNotificationDao->getKey(), + '_type' => 'Tracker_AggregateMetricNotification', + ); + + return array_merge($aggregateMetricNotificationArray, $aggregateMetricNotificationDao->toArray()); + } +} diff --git a/modules/tracker/controllers/components/ApiaggregatemetricspecComponent.php b/modules/tracker/controllers/components/ApiaggregatemetricspecComponent.php index eb967579f..537636a5f 100644 --- a/modules/tracker/controllers/components/ApiaggregatemetricspecComponent.php +++ b/modules/tracker/controllers/components/ApiaggregatemetricspecComponent.php @@ -122,12 +122,9 @@ public function index($args) * @path /tracker/aggregatemetricspec * @http POST * @param producer_id - * @param branch * @param name * @param spec * @param description (Optional) - * @param value (Optional) - * @param comparison (Optional) * @return array * * @param array $args parameters @@ -171,12 +168,9 @@ public function post($args) * @http PUT * @param id * @param producer_id (Optional) - * @param branch (Optional) * @param name (Optional) * @param spec (Optional) * @param description (Optional) - * @param value (Optional) - * @param comparison (Optional) * @return array * * @param array $args parameters diff --git a/modules/tracker/tests/controllers/ApiAggregatemetricnotificationComponentTest.php b/modules/tracker/tests/controllers/ApiAggregatemetricnotificationComponentTest.php new file mode 100644 index 000000000..1d7387b47 --- /dev/null +++ b/modules/tracker/tests/controllers/ApiAggregatemetricnotificationComponentTest.php @@ -0,0 +1,228 @@ +enabledModules = array('api', 'scheduler', $this->moduleName); + $this->_models = array('Assetstore', 'Community', 'Setting', 'User'); + $this->setupDatabase(array('default')); + $this->setupDatabase(array('aggregateMetric'), 'tracker'); + + ControllerTestCase::setUp(); + } + + /** + * Test getting an existing existing aggregate metric notification with a set of params, via GET. + * + * @throws Zend_Exception + */ + public function testGET() + { + $usersFile = $this->loadData('User', 'default'); + /** @var UserDao $userDao */ + $userDao = $this->User->load($usersFile[0]->getKey()); + $token = $this->_loginAsAdministrator(); + + $restParams = array( + 'token' => $token, + ); + $this->resetAll(); + $this->params = $restParams; + $resp = $this->_callRestApi('GET', '/tracker/aggregatemetricnotification/1'); + + /** @var Tracker_AggregateMetricNotificationModel $aggregateMetricNotificationModel */ + $aggregateMetricNotificationModel = MidasLoader::loadModel('AggregateMetricNotification', 'tracker'); + /** @var Tracker_AggregateMetricNotificationDao $notificationDao */ + $notificationDao = $aggregateMetricNotificationModel->initDao('AggregateMetricNotification', json_decode(json_encode($resp['body']), true), $this->moduleName); + + $this->assertEquals($notificationDao->getAggregateMetricSpecId(), '1'); + $this->assertEquals($notificationDao->getBranch(), 'master'); + $this->assertEquals($notificationDao->getComparison(), '>'); + $this->assertEquals($notificationDao->getValue(), '19.0'); + } + + /** + * Test creating an existing aggregate metric notification with a set of params, via POST. + * + * @throws Zend_Exception + */ + public function testPOST() + { + $usersFile = $this->loadData('User', 'default'); + /** @var UserDao $userDao */ + $userDao = $this->User->load($usersFile[0]->getKey()); + $token = $this->_loginAsAdministrator(); + + $restParams = array( + 'token' => $token, + 'aggregate_metric_spec_id' => 1, + 'branch' => 'POST TEST', + 'comparison' => '==', + 'value' => '16.0', + ); + + $this->resetAll(); + $this->params = $restParams; + $resp = $this->_callRestApi('POST', '/tracker/aggregatemetricnotification/'); + + /** @var Tracker_AggregateMetricNotificationModel $aggregateMetricNotificationModel */ + $aggregateMetricNotificationModel = MidasLoader::loadModel('AggregateMetricNotification', 'tracker'); + /** @var Tracker_AggregateMetricNotificationDao $notificationDao */ + $notificationDao = $aggregateMetricNotificationModel->initDao('AggregateMetricNotification', json_decode(json_encode($resp['body']), true), $this->moduleName); + + // Test the result of the API call. + $this->assertEquals($notificationDao->getAggregateMetricSpecId(), $restParams['aggregate_metric_spec_id']); + $this->assertEquals($notificationDao->getValue(), $restParams['value']); + $this->assertEquals($notificationDao->getComparison(), $restParams['comparison']); + $this->assertEquals($notificationDao->getBranch(), $restParams['branch']); + + // Load from the DB and test again. + $notificationDao = $aggregateMetricNotificationModel->load($notificationDao->getAggregateMetricNotificationId()); + + $this->assertEquals($notificationDao->getAggregateMetricSpecId(), $restParams['aggregate_metric_spec_id']); + $this->assertEquals($notificationDao->getValue(), $restParams['value']); + $this->assertEquals($notificationDao->getComparison(), $restParams['comparison']); + $this->assertEquals($notificationDao->getBranch(), $restParams['branch']); + + // Delete to clean up. + $aggregateMetricNotificationModel->delete($notificationDao); + } + + /** + * Test updating an existing aggregate metric notification with a set of params, via PUT. + * + * @throws Zend_Exception + */ + public function testPUT() + { + $usersFile = $this->loadData('User', 'default'); + /** @var UserDao $userDao */ + $userDao = $this->User->load($usersFile[0]->getKey()); + $token = $this->_loginAsAdministrator(); + + $originalParams = array( + 'token' => $token, + 'aggregate_metric_spec_id' => 1, + 'branch' => 'master', + 'comparison' => '>', + 'value' => 19.0, + ); + + $restParams = array( + 'token' => $token, + 'aggregate_metric_spec_id' => 2, + 'branch' => 'retsam', + 'comparison' => '!=', + 'value' => 21.0, + ); + + $this->resetAll(); + $this->params = $restParams; + $resp = $this->_callRestApi('PUT', '/tracker/aggregatemetricnotification/1'); + + /** @var Tracker_AggregateMetricNotificationModel $aggregateMetricNotificationModel */ + $aggregateMetricNotificationModel = MidasLoader::loadModel('AggregateMetricNotification', 'tracker'); + /** @var Tracker_AggregateMetricNotificationDao $notificationDao */ + $notificationDao = $aggregateMetricNotificationModel->initDao('AggregateMetricNotification', json_decode(json_encode($resp['body']), true), $this->moduleName); + + // Test the result of the API call. + // The aggregate_metric_spec_id should not have changed. + $this->assertEquals($notificationDao->getAggregateMetricSpecId(), $originalParams['aggregate_metric_spec_id']); + $this->assertEquals($notificationDao->getValue(), $restParams['value']); + $this->assertEquals($notificationDao->getComparison(), $restParams['comparison']); + $this->assertEquals($notificationDao->getBranch(), $restParams['branch']); + + // Load from the DB and test again. + $notificationDao = $aggregateMetricNotificationModel->load($notificationDao->getAggregateMetricNotificationId()); + + // The aggregate_metric_spec_id should not have changed. + $this->assertEquals($notificationDao->getAggregateMetricSpecId(), $originalParams['aggregate_metric_spec_id']); + $this->assertEquals($notificationDao->getValue(), $restParams['value']); + $this->assertEquals($notificationDao->getComparison(), $restParams['comparison']); + $this->assertEquals($notificationDao->getBranch(), $restParams['branch']); + + // Reset via PUT to the original state. + $this->resetAll(); + $this->params = $originalParams; + $resp = $this->_callRestApi('PUT', '/tracker/aggregatemetricnotification/1'); + + // Load from the DB and test again. + $notificationDao = $aggregateMetricNotificationModel->load($notificationDao->getAggregateMetricNotificationId()); + + $this->assertEquals($notificationDao->getAggregateMetricSpecId(), $originalParams['aggregate_metric_spec_id']); + $this->assertEquals($notificationDao->getValue(), $originalParams['value']); + $this->assertEquals($notificationDao->getComparison(), $originalParams['comparison']); + $this->assertEquals($notificationDao->getBranch(), $originalParams['branch']); + } + + /** + * Test deleting an existing aggregate metric spec, via DELETE. + * + * @throws Zend_Exception + */ + public function testDELETE() + { + $usersFile = $this->loadData('User', 'default'); + /** @var UserDao $userDao */ + $userDao = $this->User->load($usersFile[0]->getKey()); + $token = $this->_loginAsAdministrator(); + + // Create a notification via POST. + + $restParams = array( + 'token' => $token, + 'aggregate_metric_spec_id' => 1, + 'branch' => 'DELETE TEST', + 'comparison' => '==', + 'value' => '16.0', + ); + + $this->resetAll(); + $this->params = $restParams; + $resp = $this->_callRestApi('POST', '/tracker/aggregatemetricnotification/'); + + /** @var Tracker_AggregateMetricNotificationModel $aggregateMetricNotificationModel */ + $aggregateMetricNotificationModel = MidasLoader::loadModel('AggregateMetricNotification', 'tracker'); + /** @var Tracker_AggregateMetricNotificationDao $notificationDao */ + $notificationDao = $aggregateMetricNotificationModel->initDao('AggregateMetricNotification', json_decode(json_encode($resp['body']), true), $this->moduleName); + + // Load from the DB and test properties. + $notificationDao = $aggregateMetricNotificationModel->load($notificationDao->getAggregateMetricNotificationId()); + $this->assertEquals($notificationDao->getAggregateMetricSpecId(), $restParams['aggregate_metric_spec_id']); + $this->assertEquals($notificationDao->getValue(), $restParams['value']); + $this->assertEquals($notificationDao->getComparison(), $restParams['comparison']); + $this->assertEquals($notificationDao->getBranch(), $restParams['branch']); + + + $notificationId = $notificationDao->getAggregateMetricNotificationId(); + $resp = $this->_callRestApi('DELETE', '/tracker/aggregatemetricnotification/'.$notificationId); + + $notificationDao = $aggregateMetricNotificationModel->load($notificationId); + $this->assertEquals($notificationDao, false); + } +} diff --git a/modules/tracker/tests/controllers/ApiAggregatemetricspecComponentTest.php b/modules/tracker/tests/controllers/ApiAggregatemetricspecComponentTest.php index da02cb30d..b42eef728 100644 --- a/modules/tracker/tests/controllers/ApiAggregatemetricspecComponentTest.php +++ b/modules/tracker/tests/controllers/ApiAggregatemetricspecComponentTest.php @@ -61,9 +61,6 @@ public function testGET() $specDao = $aggregateMetricSpecModel->initDao('AggregateMetricSpec', json_decode(json_encode($resp['body']), true), $this->moduleName); $this->assertEquals($specDao->getProducerId(), '100'); - $this->assertEquals($specDao->getComparison(), '!='); - $this->assertEquals($specDao->getValue(), '1.0'); - $this->assertEquals($specDao->getBranch(), 'master'); $this->assertEquals($specDao->getName(), '95th Percentile Greedy error'); $this->assertEquals($specDao->getDescription(), '95th Percentile Greedy error'); $this->assertEquals($specDao->getSpec(), "percentile('Greedy error', 95)"); @@ -84,11 +81,8 @@ public function testPOST() $restParams = array( 'token' => $token, 'producer_id' => 100, - 'branch' => 'newbranch', 'name' => 'POST 23 percentile', 'description' => 'opaque', - 'value' => '23', - 'comparison' => '==', 'spec' => "percentile('POST', 23)", ); @@ -103,9 +97,6 @@ public function testPOST() // Test the result of the API call. $this->assertEquals($specDao->getProducerId(), $restParams['producer_id']); - $this->assertEquals($specDao->getComparison(), $restParams['comparison']); - $this->assertEquals($specDao->getValue(), $restParams['value']); - $this->assertEquals($specDao->getBranch(), $restParams['branch']); $this->assertEquals($specDao->getName(), $restParams['name']); $this->assertEquals($specDao->getDescription(), $restParams['description']); $this->assertEquals($specDao->getSpec(), $restParams['spec']); @@ -114,9 +105,6 @@ public function testPOST() $specDao = $aggregateMetricSpecModel->load($specDao->getAggregateMetricSpecId()); $this->assertEquals($specDao->getProducerId(), $restParams['producer_id']); - $this->assertEquals($specDao->getComparison(), $restParams['comparison']); - $this->assertEquals($specDao->getValue(), $restParams['value']); - $this->assertEquals($specDao->getBranch(), $restParams['branch']); $this->assertEquals($specDao->getName(), $restParams['name']); $this->assertEquals($specDao->getDescription(), $restParams['description']); $this->assertEquals($specDao->getSpec(), $restParams['spec']); @@ -137,11 +125,8 @@ public function testPUT() $restParams = array( 'token' => $token, 'producer_id' => 200, - 'branch' => 'splitter', 'name' => 'NewAlgo 23 percentile', 'description' => 'vivid', - 'value' => '23', - // Don't change comparison, to test that an unset value won't change. 'spec' => "percentile('NewAlgo', 23)", ); @@ -156,9 +141,6 @@ public function testPUT() // Test the result of the API call. $this->assertEquals($specDao->getProducerId(), $restParams['producer_id']); - $this->assertEquals($specDao->getComparison(), '!='); - $this->assertEquals($specDao->getValue(), $restParams['value']); - $this->assertEquals($specDao->getBranch(), $restParams['branch']); $this->assertEquals($specDao->getName(), $restParams['name']); $this->assertEquals($specDao->getDescription(), $restParams['description']); $this->assertEquals($specDao->getSpec(), $restParams['spec']); @@ -167,9 +149,6 @@ public function testPUT() $specDao = $aggregateMetricSpecModel->load(1); $this->assertEquals($specDao->getProducerId(), $restParams['producer_id']); - $this->assertEquals($specDao->getComparison(), '!='); - $this->assertEquals($specDao->getValue(), $restParams['value']); - $this->assertEquals($specDao->getBranch(), $restParams['branch']); $this->assertEquals($specDao->getName(), $restParams['name']); $this->assertEquals($specDao->getDescription(), $restParams['description']); $this->assertEquals($specDao->getSpec(), $restParams['spec']); diff --git a/modules/tracker/tests/controllers/ApiComponentTest.php b/modules/tracker/tests/controllers/ApiComponentTest.php index 5facfcd35..897bd3b97 100644 --- a/modules/tracker/tests/controllers/ApiComponentTest.php +++ b/modules/tracker/tests/controllers/ApiComponentTest.php @@ -336,13 +336,23 @@ public function testAggregatemetricspecNotificationEndpoints() $userDao = $authComponent->getUser(array('token' => $token), null); $this->resetAll(); - $this->params['method'] = 'midas.tracker.aggregatemetricspecnotifiedusers.list'; + $this->params['method'] = 'midas.tracker.aggregatemetricspecnotifications.list'; $this->params['token'] = $token; $this->params['aggregateMetricSpecId'] = 1; $resp = $this->_callJsonApi(); /** @var array $notifiedUsers */ - $notifiedUsers = $resp->data; - $this->assertEquals(0, count($notifiedUsers)); + $notifications = $resp->data; + // Initialliy there is one notification with zero users. + $this->assertEquals(1, count($notifications)); + $this->assertEquals(0, count($notifications[0]->users)); + /** @var Tracker_AggregateMetricNotificationModel $aggregateMetricNotificationModel */ + $aggregateMetricNotificationModel = MidasLoader::loadModel('AggregateMetricNotification', 'tracker'); + /** @var Tracker_AggregateMetricNotificationDao $notificationDao */ + $notificationDao = $aggregateMetricNotificationModel->initDao('AggregateMetricNotification', json_decode(json_encode($notifications[0]->notification), true), $this->moduleName); + $this->assertEquals($notificationDao->getAggregateMetricSpecId(), 1); + $this->assertEquals($notificationDao->getValue(), 19.0); + $this->assertEquals($notificationDao->getComparison(), '>'); + $this->assertEquals($notificationDao->getBranch(), 'master'); // Create one notified user. @@ -350,17 +360,22 @@ public function testAggregatemetricspecNotificationEndpoints() $this->params['method'] = 'midas.tracker.aggregatemetricspecnotifieduser.create'; $this->params['token'] = $token; $this->params['userId'] = 1; - $this->params['aggregateMetricSpecId'] = 1; + $this->params['aggregateMetricNotificationId'] = $notificationDao->getAggregateMetricNotificationId(); $resp = $this->_callJsonApi(); $this->assertEquals(1, $resp->data->user_id); $this->resetAll(); - $this->params['method'] = 'midas.tracker.aggregatemetricspecnotifiedusers.list'; + $this->params['method'] = 'midas.tracker.aggregatemetricspecnotifications.list'; $this->params['token'] = $token; $this->params['aggregateMetricSpecId'] = 1; $resp = $this->_callJsonApi(); + /** @var array $notifications */ + $notifications = $resp->data; + // There should be one user on this notification. + $this->assertEquals(1, count($notifications)); + $this->assertEquals(1, count($notifications[0]->users)); /** @var array $notifiedUsers */ - $notifiedUsers = $resp->data; + $notifiedUsers = $notifications[0]->users; /** @var array $expectedUserIds */ $expectedUserIds = array( 1 => false, @@ -374,6 +389,12 @@ public function testAggregatemetricspecNotificationEndpoints() foreach ($expectedUserIds as $expectedUserId) { $this->assertTrue($expectedUserIds[$expectedUserId]); } + /** @var Tracker_AggregateMetricNotificationDao $notificationDao */ + $notificationDao = $aggregateMetricNotificationModel->initDao('AggregateMetricNotification', json_decode(json_encode($notifications[0]->notification), true), $this->moduleName); + $this->assertEquals($notificationDao->getAggregateMetricSpecId(), 1); + $this->assertEquals($notificationDao->getValue(), 19.0); + $this->assertEquals($notificationDao->getComparison(), '>'); + $this->assertEquals($notificationDao->getBranch(), 'master'); // Create a notification with the same user. @@ -381,16 +402,18 @@ public function testAggregatemetricspecNotificationEndpoints() $this->params['method'] = 'midas.tracker.aggregatemetricspecnotifieduser.create'; $this->params['token'] = $token; $this->params['userId'] = 1; - $this->params['aggregateMetricSpecId'] = 1; + $this->params['aggregateMetricNotificationId'] = 1; $resp = $this->_callJsonApi(); $this->resetAll(); - $this->params['method'] = 'midas.tracker.aggregatemetricspecnotifiedusers.list'; + $this->params['method'] = 'midas.tracker.aggregatemetricspecnotifications.list'; $this->params['token'] = $token; $this->params['aggregateMetricSpecId'] = 1; $resp = $this->_callJsonApi(); + /** @var array $notifications */ + $notifications = $resp->data; /** @var array $notifiedUsers */ - $notifiedUsers = $resp->data; + $notifiedUsers = $notifications[0]->users; /** @var array $expectedUserIds */ $expectedUserIds = array( 1 => false, @@ -404,6 +427,12 @@ public function testAggregatemetricspecNotificationEndpoints() foreach ($expectedUserIds as $expectedUserId) { $this->assertTrue($expectedUserIds[$expectedUserId]); } + /** @var Tracker_AggregateMetricNotificationDao $notificationDao */ + $notificationDao = $aggregateMetricNotificationModel->initDao('AggregateMetricNotification', json_decode(json_encode($notifications[0]->notification), true), $this->moduleName); + $this->assertEquals($notificationDao->getAggregateMetricSpecId(), 1); + $this->assertEquals($notificationDao->getValue(), 19.0); + $this->assertEquals($notificationDao->getComparison(), '>'); + $this->assertEquals($notificationDao->getBranch(), 'master'); // Create a notification with a second user. @@ -411,17 +440,19 @@ public function testAggregatemetricspecNotificationEndpoints() $this->params['method'] = 'midas.tracker.aggregatemetricspecnotifieduser.create'; $this->params['token'] = $token; $this->params['userId'] = 2; - $this->params['aggregateMetricSpecId'] = 1; + $this->params['aggregateMetricNotificationId'] = 1; $resp = $this->_callJsonApi(); $this->assertEquals(2, $resp->data->user_id); $this->resetAll(); - $this->params['method'] = 'midas.tracker.aggregatemetricspecnotifiedusers.list'; + $this->params['method'] = 'midas.tracker.aggregatemetricspecnotifications.list'; $this->params['token'] = $token; $this->params['aggregateMetricSpecId'] = 1; $resp = $this->_callJsonApi(); + /** @var array $notifications */ + $notifications = $resp->data; /** @var array $notifiedUsers */ - $notifiedUsers = $resp->data; + $notifiedUsers = $notifications[0]->users; /** @var array $expectedUserIds */ $expectedUserIds = array( 1 => false, @@ -443,16 +474,18 @@ public function testAggregatemetricspecNotificationEndpoints() $this->params['method'] = 'midas.tracker.aggregatemetricspecnotifieduser.create'; $this->params['token'] = $token; $this->params['userId'] = 3; - $this->params['aggregateMetricSpecId'] = 1; + $this->params['aggregateMetricNotificationId'] = 1; $resp = $this->_callJsonApi(); $this->resetAll(); - $this->params['method'] = 'midas.tracker.aggregatemetricspecnotifiedusers.list'; + $this->params['method'] = 'midas.tracker.aggregatemetricspecnotifications.list'; $this->params['token'] = $token; $this->params['aggregateMetricSpecId'] = 1; $resp = $this->_callJsonApi(); + /** @var array $notifications */ + $notifications = $resp->data; /** @var array $notifiedUsers */ - $notifiedUsers = $resp->data; + $notifiedUsers = $notifications[0]->users; /** @var array $expectedUserIds */ $expectedUserIds = array( 1 => false, @@ -475,17 +508,19 @@ public function testAggregatemetricspecNotificationEndpoints() $this->params['method'] = 'midas.tracker.aggregatemetricspecnotifieduser.delete'; $this->params['token'] = $token; $this->params['userId'] = 2; - $this->params['aggregateMetricSpecId'] = 1; + $this->params['aggregateMetricNotificationId'] = 1; $resp = $this->_callJsonApi(); $this->assertEquals(2, $resp->data->user_id); $this->resetAll(); - $this->params['method'] = 'midas.tracker.aggregatemetricspecnotifiedusers.list'; + $this->params['method'] = 'midas.tracker.aggregatemetricspecnotifications.list'; $this->params['token'] = $token; $this->params['aggregateMetricSpecId'] = 1; $resp = $this->_callJsonApi(); + /** @var array $notifications */ + $notifications = $resp->data; /** @var array $notifiedUsers */ - $notifiedUsers = $resp->data; + $notifiedUsers = $notifications[0]->users; /** @var array $expectedUserIds */ $expectedUserIds = array( 1 => false, @@ -508,17 +543,19 @@ public function testAggregatemetricspecNotificationEndpoints() $this->params['method'] = 'midas.tracker.aggregatemetricspecnotifieduser.delete'; $this->params['token'] = $token; $this->params['userId'] = 1; - $this->params['aggregateMetricSpecId'] = 1; + $this->params['aggregateMetricNotificationId'] = 1; $resp = $this->_callJsonApi(); $this->assertEquals(1, $resp->data->user_id); $this->resetAll(); - $this->params['method'] = 'midas.tracker.aggregatemetricspecnotifiedusers.list'; + $this->params['method'] = 'midas.tracker.aggregatemetricspecnotifications.list'; $this->params['token'] = $token; $this->params['aggregateMetricSpecId'] = 1; $resp = $this->_callJsonApi(); + /** @var array $notifications */ + $notifications = $resp->data; /** @var array $notifiedUsers */ - $notifiedUsers = $resp->data; + $notifiedUsers = $notifications[0]->users; /** @var array $expectedUserIds */ $expectedUserIds = array( 3 => false, @@ -540,16 +577,18 @@ public function testAggregatemetricspecNotificationEndpoints() $this->params['method'] = 'midas.tracker.aggregatemetricspecnotifieduser.delete'; $this->params['token'] = $token; $this->params['userId'] = 3; - $this->params['aggregateMetricSpecId'] = 1; + $this->params['aggregateMetricNotificationId'] = 1; $resp = $this->_callJsonApi(); $this->resetAll(); - $this->params['method'] = 'midas.tracker.aggregatemetricspecnotifiedusers.list'; + $this->params['method'] = 'midas.tracker.aggregatemetricspecnotifications.list'; $this->params['token'] = $token; $this->params['aggregateMetricSpecId'] = 1; $resp = $this->_callJsonApi(); + /** @var array $notifications */ + $notifications = $resp->data; /** @var array $notifiedUsers */ - $notifiedUsers = $resp->data; + $notifiedUsers = $notifications[0]->users; $this->assertEquals(0, count($notifiedUsers)); } } diff --git a/modules/tracker/tests/controllers/CMakeLists.txt b/modules/tracker/tests/controllers/CMakeLists.txt index 12d58629e..7f93fb2de 100644 --- a/modules/tracker/tests/controllers/CMakeLists.txt +++ b/modules/tracker/tests/controllers/CMakeLists.txt @@ -22,3 +22,4 @@ to_titlecase(${module_name} module_name_titlecase) add_midas_mysql_test(${module_name_titlecase}ApiComponent ApiComponentTest.php) add_midas_mysql_test(${module_name_titlecase}ApiAggregatemetricspecComponent ApiAggregatemetricspecComponentTest.php) +add_midas_mysql_test(${module_name_titlecase}ApiAggregatemetricnotificationComponent ApiAggregatemetricnotificationComponentTest.php) From d265627c4cdd82370df35a5fa4d3dc75e52ad063 Mon Sep 17 00:00:00 2001 From: mgrauer Date: Wed, 13 Apr 2016 02:05:57 +0000 Subject: [PATCH 33/40] Split notification from spec in tracker Notification email --- modules/tracker/Notification.php | 30 ++++++++++++++++++++---------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/modules/tracker/Notification.php b/modules/tracker/Notification.php index 92139a96a..ec84f3abb 100644 --- a/modules/tracker/Notification.php +++ b/modules/tracker/Notification.php @@ -38,7 +38,7 @@ class Tracker_Notification extends ApiEnabled_Notification public $_models = array('User'); /** @var array */ - public $_moduleModels = array('AggregateMetric', 'AggregateMetricSpec', 'Scalar', 'Submission', 'Trend'); + public $_moduleModels = array('AggregateMetric', 'AggregateMetricNotification', 'AggregateMetricSpec', 'Scalar', 'Submission', 'Trend'); /** @var array */ public $_moduleComponents = array('Api'); @@ -224,27 +224,37 @@ public function sendAggregateEmail($params) $userDao = $this->User->load($params['recipient_id']); if ($userDao === false) { $this->getLogger()->warn( - 'Attempting to send aggregate metric threshold notification to user id '.$params['recipientId'].': No such user.' + 'Attempting to send aggregate metric threshold notification to user id '.$params['recipient_id'].': No such user.' + ); + + return; + } + + /** @var Tracker_AggregateMetricDao $aggregateMetricDao */ + $aggregateMetricDao = $this->Tracker_AggregateMetric->load($params['aggregate_metric_id']); + if ($aggregateMetricDao === false) { + $this->getLogger()->warn( + 'Attempting to send aggregate metric threshold notification with aggregate metric '.$params['aggregate_metric_id'].': No such metric.' ); return; } /** @var Tracker_AggregateMetricSpecDao $aggregateMetricSpecDao */ - $aggregateMetricSpecDao = $this->Tracker_AggregateMetricSpec->load($params['aggregate_metric_spec_id']); + $aggregateMetricSpecDao = $aggregateMetricDao->getAggregateMetricSpec(); if ($aggregateMetricSpecDao === false) { $this->getLogger()->warn( - 'Attempting to send aggregate metric threshold notification with aggregate metric spec '.$params['aggregateMetricSpecId'].': No such spec.' + 'Attempting to send aggregate metric threshold notification with aggregate metric spec that does not exist.' ); return; } - /** @var Tracker_AggregateMetricDao $aggregateMetricDao */ - $aggregateMetricDao = $this->Tracker_AggregateMetric->load($params['aggregate_metric_id']); + /** @var Tracker_AggregateMetricNotificationDao $aggregateMetricNotificationDao */ + $aggregateMetricNotificationDao = $this->Tracker_AggregateMetricNotification->load($params['aggregate_metric_notification_id']); if ($aggregateMetricDao === false) { $this->getLogger()->warn( - 'Attempting to send aggregate metric threshold notification with aggregate metric '.$params['aggregateMetricId'].': No such metric.' + 'Attempting to send aggregate metric threshold notification with aggregate metric notification id '.$params['aggregate_metric_notification_id'].': No such notification.' ); return; @@ -257,9 +267,9 @@ public function sendAggregateEmail($params) $producerName = $producerDao->getDisplayName(); $metricName = $aggregateMetricSpecDao->getName(); - $branch = $aggregateMetricSpecDao->getBranch(); - $thresholdValue = $aggregateMetricSpecDao->getValue(); - $thresholdComparison = $aggregateMetricSpecDao->getComparison(); + $thresholdValue = $aggregateMetricNotificationDao->getValue(); + $thresholdComparison = $aggregateMetricNotificationDao->getComparison(); + $branch = $aggregateMetricNotificationDao->getBranch(); $metricValue = $aggregateMetricDao->getValue(); $subject = 'Threshold Alert: '.$producerName.': '.$metricName; From 5d0bc1c17739ec6978a88cdfc92d33e6e0a3a19b Mon Sep 17 00:00:00 2001 From: mgrauer Date: Wed, 13 Apr 2016 02:07:36 +0000 Subject: [PATCH 34/40] Split notification from spec in management UI --- .../css/producer/producer.aggregatemetric.css | 2 +- .../js/producer/producer.aggregateMetric.js | 357 +++++++++++++++--- .../producer/producer.aggregatemetric.scss | 277 +++++--------- .../views/producer/aggregatemetric.phtml | 142 +++---- 4 files changed, 463 insertions(+), 315 deletions(-) diff --git a/modules/tracker/public/css/producer/producer.aggregatemetric.css b/modules/tracker/public/css/producer/producer.aggregatemetric.css index 4f83149fd..b1067d425 100644 --- a/modules/tracker/public/css/producer/producer.aggregatemetric.css +++ b/modules/tracker/public/css/producer/producer.aggregatemetric.css @@ -1 +1 @@ -a.aggregateMetricSpecAction{color:#56758b}a.aggregateMetricSpecAction:hover{background-color:#e5e5e5;cursor:pointer}a.alertedUsersAction{color:#56758b}a.alertedUsersAction:hover{background-color:#e5e5e5;cursor:pointer}div#addAggregateMetricSpec{margin-top:10px}div#aggregateMetricSpecList{margin-top:10px}div.aggregateMetricSpecCreate{border-top:2px solid darkblue !important}div.aggregateMetricSpecEdit{border-top:2px solid darkblue !important}div#aggregateMetricSpecEditWarning{padding-top:10px;padding-bottom:10px;color:orange}div#aggregateMetricUserAlerts{border-top:2px solid darkblue;color:#555;font-size:13px;margin-top:15px;margin-bottom:10px;padding-top:10px;text-align:center}div#aggregateMetricUserAlerts div#aggregateMetricUserAlertsThreshold{margin-top:15px;margin-bottom:10px}div#aggregateMetricUserAlerts div#aggregateMetricUserAlertsThreshold table#aggregateMetricUserAlertsThresholdDefinition{margin-top:10px}div#aggregateMetricUserAlerts div#aggregateMetricUserAlertsThreshold table#aggregateMetricUserAlertsThresholdDefinition td:first-of-type{text-align:left}div#aggregateMetricUserAlerts textarea#aggregateMetricUserAlertsSpec{margin-top:10px;width:100%}div#aggregateMetricUserAlerts div#addAggregateMetricSpecAlertUser{margin-top:15px;text-align:center}div#aggregateMetricUserAlerts div.alertUserSearch{margin-top:10px}div#aggregateMetricUserAlerts div.alertUserSearch input{width:100%}div.aggregateMetricSectionTitle{border-top:1px solid #d7d7d7;color:#555;font-size:13px;margin-top:15px;margin-bottom:10px;padding-top:10px;text-align:center}div.resultingMetricText{color:#555;font-size:12px;margin-top:10px;text-align:center}div#aggregateMetricSpecUserAlertsSaveState{margin-top:20px}div#aggregateMetricSpecUserAlertsSaveState input{background:#f6f9fe;border:1px solid #808080;color:#2e6e9e;cursor:pointer;float:right;margin-left:10px}div#aggregateMetricSpecSaveState{margin-top:20px}div#aggregateMetricSpecSaveState input{background:#f6f9fe;border:1px solid #808080;color:#2e6e9e;cursor:pointer;float:right;margin-left:10px}div#aggregateMetricSpecSaveState input:disabled{color:#c0c0c0;cursor:not-allowed}label#aggregateMetricSpecValidationError{color:crimson}img#aggregateMetricSpecSaveLoading{float:left;margin-right:15px}img#aggregateMetricSpecDeleteLoading{float:right;margin-right:40px}img#aggregateMetricSpecAlertsLoading{float:left}table#aggregateMetricSpecAlertedUsers{table-layout:fixed;border:2px solid #ddd;width:100%}table#aggregateMetricSpecAlertedUsers th{border-bottom:solid 1px black;text-align:center}table#aggregateMetricSpecAlertedUsers th:first-of-type{width:70%;border-right:dotted 1px black}table#aggregateMetricSpecAlertedUsers tr.even{background-color:#f4f4f4}table#aggregateMetricSpecAlertedUsers td.userName{border-right:dotted 1px black;text-align:left}table#aggregateMetricSpecAlertedUsers tr.activeRow{border:2px solid darkblue;background-color:#c0d1fe}table#aggregateMetricSpecListTable{table-layout:fixed;border:2px solid #ddd;width:100%}table#aggregateMetricSpecListTable th{border-bottom:solid 1px black;text-align:center}table#aggregateMetricSpecListTable th:first-of-type{width:70%;border-right:dotted 1px black}table#aggregateMetricSpecListTable td.specName{border-right:dotted 1px black}table#aggregateMetricSpecListTable tr.even{background-color:#f4f4f4}table#aggregateMetricSpecListTable tr.activeRow{border:2px solid darkblue;background-color:#c0d1fe}table#aggregateMetricSpecListTable span.actionsList{display:flex;justify-content:space-around}table#aggregateMetricSpecListTable span.actionsList a:first-of-type{padding-left:5px} +div#aggregateMetricSpecManage table{width:100%}div#aggregateMetricSpecManage table.actionTable{table-layout:fixed;border:2px solid #ddd;margin-top:15px;margin-bottom:15px}div#aggregateMetricSpecManage table.actionTable tr.activeRow{border:2px solid darkblue;background-color:#c0d1fe !important}div#aggregateMetricSpecManage table.actionTable tr.even{background-color:#f4f4f4}div#aggregateMetricSpecManage table.actionTable th{border-bottom:solid 1px black}div#aggregateMetricSpecManage table.actionTable th:last-of-type{text-align:center;border-left:dotted 1px black;width:30%}div#aggregateMetricSpecManage table.actionTable td:last-of-type{border-left:dotted 1px black}div#aggregateMetricSpecManage table.actionTable span.actionsList{display:flex;justify-content:space-around}div#aggregateMetricSpecManage table.actionTable span.actionsList a:first-of-type{padding-left:5px}div#aggregateMetricSpecManage table.fieldTable input{width:100%}div#aggregateMetricSpecManage table.fieldTable select{width:100%}div#aggregateMetricSpecManage a.actionLink{color:#56758b}div#aggregateMetricSpecManage a.actionLink:hover{background-color:#e5e5e5;cursor:pointer}div#aggregateMetricSpecManage label.validationError{color:crimson}div#aggregateMetricSpecManage div.subsectionTitle{border-top:2px solid darkblue;margin-top:15px;margin-bottom:15px;padding-top:10px;color:#555;font-size:13px;text-align:center;font-weight:bold}div#aggregateMetricSpecManage div.subsubsectionTitle{color:#555;font-size:12px;margin-top:10px;margin-bottom:10px;text-align:center}div#aggregateMetricSpecManage div.saveState{margin-top:15px}div#aggregateMetricSpecManage div.saveState input{background:#f6f9fe;border:1px solid #808080;color:#2e6e9e;cursor:pointer;float:right;margin-left:10px}div#aggregateMetricSpecManage div.saveState input:disabled{color:#c0c0c0;cursor:not-allowed}div#aggregateMetricSpecManage div#aggregateMetricSpecEditWarning{padding-top:10px;padding-bottom:10px;color:orange}div#aggregateMetricSpecManage img.loadingImg{float:left}div#aggregateMetricSpecManage img.loadingImg#aggregateMetricSpecDeleteLoading{float:right;margin-right:40px}div#aggregateMetricSpecManage textarea#aggregateMetricUserAlertsSpec{margin-top:10px;width:100%}div#aggregateMetricSpecManage input#addAlertUserSearch{width:100%} diff --git a/modules/tracker/public/js/producer/producer.aggregateMetric.js b/modules/tracker/public/js/producer/producer.aggregateMetric.js index f24f959f8..79b7e28e1 100644 --- a/modules/tracker/public/js/producer/producer.aggregateMetric.js +++ b/modules/tracker/public/js/producer/producer.aggregateMetric.js @@ -8,27 +8,30 @@ var midas = midas || {}; $(document).ready(function () { 'use strict'; + var activeNotification = null; + var activeSpecNotifications = {}; + //:~ Server API interfaces /** - * Interface to server side AggregateMetricSpec REST API. + * Interface to server side midas REST API. * @param method The HTTP method {'POST'|'PUT'|'DELETE'|'GET'} - * @param aggregateMetricSpecId (Required for all except POST) - * @param args an object containing key value pairs for the AggregateMetricSpec object for PUT calls (Optional except for PUT) + * @param resourceId (Required for all except POST) + * @param args an object containing key value pairs for the resource object for PUT calls (Optional except for PUT) * @param sCb success callback, passed the return value (Optional) * @param eCb error callback, passed the return value (Optional) * @param cCb complete callback, passed the return value (Optional) */ - function aggregatemetricspecRest(method, aggregateMetricSpecId, args, sCb, eCb, cCb) { - var url = json.global.webroot + '/rest/tracker/aggregatemetricspec'; - if (aggregateMetricSpecId) { - url += '/' + aggregateMetricSpecId; + function midasRest(httpMethod, path, resourceId, args, sCb, eCb, cCb) { + var url = json.global.webroot + path; + if (resourceId) { + url += '/' + resourceId; } url += '?useSession=true'; var restCall = { url: url, - type: method, + type: httpMethod, dataType: 'json', success: function (retVal) { if (sCb) { sCb(retVal); } @@ -51,6 +54,34 @@ $(document).ready(function () { $.ajax(restCall); } + /** + * Interface to server side AggregateMetricSpec REST API. + * @param method The HTTP method {'POST'|'PUT'|'DELETE'|'GET'} + * @param aggregateMetricSpecId (Required for all except POST) + * @param args an object containing key value pairs for the AggregateMetricSpec object for PUT calls (Optional except for PUT) + * @param sCb success callback, passed the return value (Optional) + * @param eCb error callback, passed the return value (Optional) + * @param cCb complete callback, passed the return value (Optional) + */ + function aggregatemetricspecRest(method, aggregateMetricSpecId, args, sCb, eCb, cCb) { + var path = '/rest/tracker/aggregatemetricspec'; + midasRest(method, path, aggregateMetricSpecId, args, sCb, eCb, cCb); + } + + /** + * Interface to server side AggregateMetricNotification REST API. + * @param method The HTTP method {'POST'|'PUT'|'DELETE'|'GET'} + * @param aggregateMetricNotificationId (Required for all except POST) + * @param args an object containing key value pairs for the AggregateMetricNotification object for PUT calls (Optional except for PUT) + * @param sCb success callback, passed the return value (Optional) + * @param eCb error callback, passed the return value (Optional) + * @param cCb complete callback, passed the return value (Optional) + */ + function aggregatemetricnotificationRest(method, aggregateMetricNotificationId, args, sCb, eCb, cCb) { + var path = '/rest/tracker/aggregatemetricnotification'; + midasRest(method, path, aggregateMetricNotificationId, args, sCb, eCb, cCb); + } + /** * Additional wrapper around ajaxWebApi.ajax to provide some defaults. * @param string jsonMethod the midas json method @@ -150,8 +181,8 @@ $(document).ready(function () { function addToSpecTable(aggregateMetricSpec) { function createActionLink(qtip, actionClass, imgPath, label) { - var actionLink = ' '; - actionLink += ' '+label+''; + var actionLink = ' '; + actionLink += ' '+label+''; return actionLink; } @@ -226,6 +257,7 @@ $(document).ready(function () { /** Handler for Alerts button, show the panel to edit the alerted users. */ $('#aggregateMetricSpecListTable').on('click', 'a.editAggregateMetricSpecNotificationUsers', function() { activateRow($(this)); + unhighlightActiveAlertRow(); var amsName = $('td:first', $(this).closest('tr')).text(); $('#aggregateMetricUserAlerts').show(); var aggregateMetricSpecId = $(this).data('aggregate_metric_spec_id'); @@ -235,25 +267,25 @@ $(document).ready(function () { $('#aggregateMetricSpecAlertComparison').val(''); $('#aggregateMetricUserAlertsSpec').val(''); $('#aggregateMetricSpecAlertedUsers').find('tr:gt(0)').remove(); - $('#aggregateMetricSpecAlertsLoading').show(); + $('#aggregateMetricNotificationsTable').find('tr:gt(0)').remove(); + $('#aggregateMetricNotificationRemoveLoading').show(); $('#addAlertUserSearch').val('Start typing a name or email address...'); $('#addAlertUserSearchValue').val('init'); var successCallback = function (aggregateMetricSpec) { $('#aggregateMetricUserAlertsSpecName').text(aggregateMetricSpec.name); - $('#aggregateMetricUserAlertsBranch').text(aggregateMetricSpec.branch); - $('#aggregateMetricSpecAlertValue').val(aggregateMetricSpec.value); - $('#aggregateMetricSpecAlertComparison').val(aggregateMetricSpec.comparison); $('#aggregateMetricUserAlertsSpec').val(aggregateMetricSpec.spec); - var jsonMethod = 'midas.tracker.aggregatemetricspecnotifiedusers.list'; + var jsonMethod = 'midas.tracker.aggregatemetricspecnotifications.list'; var args = 'aggregateMetricSpecId=' + aggregateMetricSpecId; callAjaxWebApi(jsonMethod, 'GET', args, function (retVal) { - for (var userInd = 0; userInd < retVal.data.length; userInd++) { - var user = retVal.data[userInd]; - addToAlertedUsersTable(user.firstname + ' ' + user.lastname, user.user_id); + activeSpecNotifications = {}; + for (var notifInd = 0; notifInd < retVal.data.length; notifInd++) { + var notification = retVal.data[notifInd]; + addToNotificationTable(notification.notification); + activeSpecNotifications[notification.notification.aggregate_metric_notification_id] = notification; } - addClassesToTableRows('aggregateMetricSpecAlertedUsers'); - $('#aggregateMetricSpecAlertsLoading').hide(); + addClassesToTableRows('aggregateMetricNotificationsTable'); + $('#aggregateMetricNotificationRemoveLoading').hide(); }); }; aggregatemetricspecRest('GET', aggregateMetricSpecId, null, successCallback); @@ -277,7 +309,6 @@ $(document).ready(function () { var requiredFields = [ {'value': specValues.aggregateMetricSpec.name, 'name': 'Name'}, {'value': specValues.specInputs.metricName, 'name': 'Metric name'}, - {'value': specValues.aggregateMetricSpec.branch, 'name': 'Branch'}, {'value': specValues.specInputs.aggregateMetric, 'name': 'Aggregate metric'}, {'value': specValues.specInputs.param, 'name': 'Param (percentile)'} ]; @@ -296,19 +327,6 @@ $(document).ready(function () { $('div#aggregateMetricSpecSaveState input').prop('disabled', false); return; } - // Comparison and valid must be empty or not together. - var comparisonEmpty = (!specValues.aggregateMetricSpec.comparison || specValues.aggregateMetricSpec.comparison === ''); - var valueEmpty = (!specValues.aggregateMetricSpec.value || specValues.aggregateMetricSpec.value === ''); - if (comparisonEmpty !== valueEmpty) { - $('#aggregateMetricSpecValidationError').text('Comparison and value must be set together'); - $('div#aggregateMetricSpecSaveState input').prop('disabled', false); - return; - } else if (!valueEmpty && !$.isNumeric(specValues.aggregateMetricSpec.value)) { - // The case where comparison and value are provided. - $('#aggregateMetricSpecValidationError').text('Value must be numeric'); - $('div#aggregateMetricSpecSaveState input').prop('disabled', false); - return; - } // Save the AMS on the server. $('#aggregateMetricSpecSaveLoading').show(); @@ -332,8 +350,6 @@ $(document).ready(function () { $('#aggregateMetricSpecValidationError').text(''); $('#aggregateMetricSpecSpec').val(''); $('#aggregateMetricSpecMetricName option:disabled').attr('selected', 'selected'); - $('#aggregateMetricSpecComparison option:disabled').attr('selected', 'selected'); - $('#aggregateMetricSpecBranch').val('master'); } /** Update display of disabled composite spec input from individual elements. */ @@ -374,10 +390,7 @@ $(document).ready(function () { 'producer_id': $('#producerId').val(), 'name': $('#aggregateMetricSpecName').val(), 'description': $('#aggregateMetricSpecDescription').val(), - 'branch': $('#aggregateMetricSpecBranch').val(), 'spec': $('#aggregateMetricSpecSpec').val(), - 'value': $('#aggregateMetricSpecValue').val(), - 'comparison': $('#aggregateMetricSpecComparison').val() }, 'specInputs': { 'metricName': $('#aggregateMetricSpecMetricName').val(), @@ -391,7 +404,7 @@ $(document).ready(function () { /** * Populate the input elements with the values from the passed in aggregateMetricSpec, * including some validation in case the passed in spec was created out of data that is - * no longer valid, e.g. a branch name that no longer has scalars tied to the metric_name. + * no longer valid. * @param aggregateMetricSpec object with AggregateMetricSpecDao key value pairs */ function populateSpecInputs(aggregateMetricSpec) { @@ -399,15 +412,6 @@ $(document).ready(function () { $('#aggregateMetricSpecName').val(aggregateMetricSpec.name); $('#aggregateMetricSpecDescription').val(aggregateMetricSpec.description); $('#aggregateMetricSpecSpec').val(aggregateMetricSpec.spec); - // Skip value if it is 0 and comparison is empty, this was added as a DB - // default and wouldn't be allowed by the UI validation logic. - if (aggregateMetricSpec.value && - (aggregateMetricSpec.value != 0 || aggregateMetricSpec.comparison)) { - $('#aggregateMetricSpecValue').val(aggregateMetricSpec.value); - } - if (aggregateMetricSpec.comparison) { - $('#aggregateMetricSpecComparison').val(aggregateMetricSpec.comparison); - } var specParts = parseMetricSpec(aggregateMetricSpec.spec); $('#aggregateMetricSpecParam').val(specParts.param); $('#aggregateMetricSpecAggregateMetric').val(specParts.metric); @@ -416,7 +420,6 @@ $(document).ready(function () { $('#aggregateMetricSpecValidationError').text("Loaded metric name '"+specParts.metricName+"' is invalid"); } else { $('#aggregateMetricSpecMetricName').val(specParts.metricName); - $('#aggregateMetricSpecBranch').val(aggregateMetricSpec.branch); } $('#aggregateMetricSpecSaveLoading').hide(); } @@ -466,6 +469,241 @@ $(document).ready(function () { unhighlightActiveRow(); }); + //:~ Notification/Alerts panel + + /** + * Add a row to the notifications table for a given spec, based on the + * passed in AggregateMetricNotification object. + * @param aggregateMetricNotification object with AggregateMetricNotificationDao key value pairs + */ + function addToNotificationTable(notification) { + + var notificationId = notification.aggregate_metric_notification_id; + function createActionLink(qtip, actionClass, imgPath, label) { + var actionLink = ' '; + actionLink += ' '+label+''; + return actionLink; + } + + var row = '' + notification.branch + ''; + row += '' + notification.comparison + ''; + row += '' + notification.value + ''; + row += createActionLink('Edit notification', 'editAggregateMetricNotification', '/public/images/icons/edit.png', 'Edit'); + row += createActionLink('Edit users', 'editAggregateMetricNotificationUsers', '/public/images/icons/email_error.png', 'Users'); + row += createActionLink('Remove notification', 'removeAggregateMetricNotification', '/public/images/icons/close.png', 'Delete'); + row += ''; + $('#aggregateMetricNotificationsTable tbody').append(row); + } + + /** Remove highlight from active notification row. */ + function unhighlightActiveAlertRow() { + $('#aggregateMetricNotificationsTable tbody tr').each(function (ind, elem) { + $(this).removeClass('activeRow'); + }); + $('#aggregateMetricNotificationEdit').hide(); + $('#aggregateMetricNotificationUsers').hide(); + $('#aggregateMetricNotificationCancel').show(); + } + + /** + * Highlight the alert row which houses the current action in the Notifications table, + * sets the activeNotification closure variable to the alert in the row. + * @param element actionLink the anchor element that was clicked. + */ + function activateAlertRow(actionLink) { + unhighlightActiveAlertRow(); + $('#aggregateMetricNotificationValidationError').text(''); + actionLink.closest('tr').addClass('activeRow'); + $('#aggregateMetricNotificationCancel').hide(); + var notificationId = actionLink.data('aggregate_metric_notification_id'); + activeNotification = activeSpecNotifications[notificationId]; + } + + /** + * Validates the current notification input fields, whether for an edited + * notification or a new one. + * @return bool indicating whether validation succeeded. + */ + function validateNotification() { + var branch = $('#aggregateMetricNotificationBranch').val(); + if (branch === null || branch === '') { + $('#aggregateMetricNotificationValidationError').text('branch cannot be empty'); + return false; + } + var comparison = $('#aggregateMetricNotificationComparison').val(); + if (comparison === null || comparison === '') { + $('#aggregateMetricNotificationValidationError').text('comparison cannot be empty'); + return false; + } + var value = $('#aggregateMetricNotificationValue').val(); + if (value === null || value === '' || !$.isNumeric(value)) { + $('#aggregateMetricNotificationValidationError').text('value must be numeric'); + return false; + } + $('#aggregateMetricNotificationValidationError').text(''); + return true; + } + + /** + * Deactivate the current notification and hide any notification details panels. + */ + function hideNotificationDetailPanel() { + $('.editAlert').hide(); + $('.createAlert').hide(); + $('#aggregateMetricNotificationSaveLoading').hide(); + $('div#aggregateMetricNotificationSaveState input').prop('disabled', false); + unhighlightActiveAlertRow(); + $('#aggregateMetricNotificationEdit').hide(); + $('#aggregateMetricNotificationCancel').show(); + } + + // Notification panel handlers + // Notifications and Alerts are considered equivalent, "Alert" is shorter + + /** + * Handler for edit notification users action, activates the notification + * and loads any users tied to the notification to display them in the + * users table. + * The handler is tied to a static parent as the links can be + * dynamically generated through creation of new alerts. + */ + $('#aggregateMetricNotificationsTable').on('click', 'a.editAggregateMetricNotificationUsers', function() { + activateAlertRow($(this)); + $('#aggregateMetricNotificationUsers').show(); + $('#aggregateMetricSpecAlertedUsers').find('tr:gt(0)').remove(); + for(var userInd = 0; userInd < activeNotification.users.length; userInd += 1) { + var user = activeNotification.users[userInd]; + addToAlertedUsersTable(user.firstname +' '+user.lastname, user.user_id); + } + addClassesToTableRows('aggregateMetricSpecAlertedUsers'); + }); + + /** + * Handler for edit notification action, activates the notification + * and loads the notification into fields such that it can be edited. + * The handler is tied to a static parent as the links can be + * dynamically generated through creation of new alerts. + */ + $('#aggregateMetricNotificationsTable').on('click', 'a.editAggregateMetricNotification', function() { + activateAlertRow($(this)); + $('#aggregateMetricNotificationEdit').show(); + $('#aggregateMetricNotificationBranch').val(activeNotification.notification.branch); + $('#aggregateMetricNotificationValue').val(activeNotification.notification.value); + $('#aggregateMetricNotificationComparison').val(activeNotification.notification.comparison); + $('#aggregateMetricNotificationCreate').hide(); + $('#aggregateMetricNotificationUpdate').show(); + $('.editAlert').show(); + $('.createAlert').hide(); + }); + + /** + * Handler for Remove notification action, delete the notification and + * any associated alerted users. + * The handler is tied to a static parent as the links can be + * dynamically generated through creation of new alerts. + */ + $('#aggregateMetricNotificationsTable').on('click', 'a.removeAggregateMetricNotification', function() { + hideNotificationDetailPanel(); + var row = $(this).closest('tr'); + activateAlertRow($(this)); + var notificationId = $(this).data('aggregate_metric_notification_id'); + $('#aggregateMetricNotificationRemoveLoading').show(); + aggregatemetricnotificationRest('DELETE', notificationId, {}, function (retVal) { + row.remove(); + $('#aggregateMetricNotificationRemoveLoading').hide(); + delete activeSpecNotifications[notificationId]; + unhighlightActiveAlertRow(); + addClassesToTableRows('aggregateMetricNotificationsTable'); + }); + }); + + /** + * Handler for adding a new notification to the active Spec. + */ + $('#addAggregateMetricNotification').click(function () { + unhighlightActiveAlertRow(); + $('#aggregateMetricNotificationUpdate').hide(); + $('#aggregateMetricNotificationBranch').val(''); + $('#aggregateMetricNotificationComparison').val(''); + $('#aggregateMetricNotificationValue').val(''); + $('#aggregateMetricNotificationCreate').show(); + $('#aggregateMetricNotificationEdit').show(); + $('div#aggregateMetricNotificationSaveState input').prop('disabled', false); + $('#aggregateMetricNotificationValidationError').text(''); + $('#aggregateMetricNotificationSaveState').show(); + $('#aggregateMetricNotificationCancel').hide(); + $('.editAlert').hide(); + $('.createAlert').show(); + }); + + // Notification panel button handlers + + /** + * Handler for Cancel button: + * hide any notification detail panel and de-activate any notification row. + */ + $('#aggregateMetricNotificationCancel').click(function () { + $('#aggregateMetricUserAlerts').hide(); + unhighlightActiveAlertRow(); + unhighlightActiveRow(); + hideNotificationDetailPanel(); + }); + + /** + * Update the active notification with the input fields. + */ + $('input#aggregateMetricNotificationUpdate').click(function () { + if (validateNotification()) { + $('div#aggregateMetricNotificationSaveState input').prop('disabled', true); + $('#aggregateMetricNotificationSaveLoading').show(); + var notificationUpdates = { + branch: $('#aggregateMetricNotificationBranch').val(), + comparison: $('#aggregateMetricNotificationComparison').val(), + value: $('#aggregateMetricNotificationValue').val() + }; + var notificationId = activeNotification.notification.aggregate_metric_notification_id; + aggregatemetricnotificationRest('PUT', notificationId, notificationUpdates, function (retVal) { + activeSpecNotifications[notificationId].notification = retVal; + $('#aggregateMetricNotificationsTable td#amnBranch'+notificationId).html(retVal.branch); + $('#aggregateMetricNotificationsTable td#amnValue'+notificationId).html(retVal.value); + $('#aggregateMetricNotificationsTable td#amnComparison'+notificationId).html(retVal.comparison); + hideNotificationDetailPanel(); + }); + } + }); + + /** + * Cancel editing or creating a notification. + */ + $('#aggregateMetricNotificationSaveCancel').click(function () { + hideNotificationDetailPanel(); + }); + + /** + * Create a new notification with the input fields tied to the active Spec. + */ + $('input#aggregateMetricNotificationCreate').click(function () { + if (validateNotification()) { + $('div#aggregateMetricNotificationSaveState input').prop('disabled', true); + var notificationProperties = { + aggregate_metric_spec_id: $('#aggregateMetricSpecEditId').val(), + branch: $('#aggregateMetricNotificationBranch').val(), + comparison: $('#aggregateMetricNotificationComparison').val(), + value: $('#aggregateMetricNotificationValue').val() + }; + $('#aggregateMetricNotificationSaveLoading').show(); + aggregatemetricnotificationRest('POST', null, notificationProperties, function (retVal) { + hideNotificationDetailPanel(); + addToNotificationTable(retVal); + activeSpecNotifications[retVal.aggregate_metric_notification_id] = { + notification: retVal, + users: [] + }; + addClassesToTableRows('aggregateMetricNotificationsTable'); + }); + } + }); + //:~ Alerted Users panel /** @@ -476,13 +714,13 @@ $(document).ready(function () { function addToAlertedUsersTable(userName, userId) { function createActionLink(qtip, actionClass, imgPath, label) { - var actionLink = ' '; - actionLink += ' '+label+''; + var actionLink = ' '; + actionLink += ' '+label+''; return actionLink; } var row = '' + userName + ''; - row += createActionLink('Remove user from alerts', 'removeAlertedUser', '/public/images/icons/close.png', 'Remove alerts'); + row += createActionLink('Remove user from alerts', 'removeAlertedUser', '/public/images/icons/close.png', 'Remove alert'); row += ''; $('#aggregateMetricSpecAlertedUsers tbody').append(row); } @@ -497,12 +735,10 @@ $(document).ready(function () { $('#aggregateMetricSpecAlertedUsers').on('click', 'a.removeAlertedUser', function() { var row = $(this).closest('tr'); row.addClass('activeRow'); - var aggregateMetricSpecId = $('#aggregateMetricSpecEditId').val(); $('#aggregateMetricSpecAlertsLoading').show(); var userId = $(this).data('user_id'); - var jsonMethod = 'midas.tracker.aggregatemetricspecnotifieduser.delete'; - var args = 'aggregateMetricSpecId=' + aggregateMetricSpecId + '&userId=' + userId; + var args = 'aggregateMetricNotificationId=' + activeNotification.notification.aggregate_metric_notification_id + '&userId=' + userId; callAjaxWebApi(jsonMethod, 'POST', args, function (retVal) { if (retVal.data && retVal.data.user_id == userId) { row.remove(); @@ -516,6 +752,7 @@ $(document).ready(function () { }); // Live search for users + $.widget('custom.catcomplete', $.ui.autocomplete, { _renderMenu: function (ul, items) { 'use strict'; @@ -570,12 +807,11 @@ $(document).ready(function () { $('#aggregateMetricSpecAlertsLoading').show(); var userId = ui.item.userid; var userName = ui.item.value; - var aggregateMetricSpecId = $('#aggregateMetricSpecEditId').val(); - var jsonMethod = 'midas.tracker.aggregatemetricspecnotifieduser.create'; - var args = 'aggregateMetricSpecId=' + aggregateMetricSpecId + '&userId=' + userId; + var args = 'aggregateMetricNotificationId=' + activeNotification.notification.aggregate_metric_notification_id + '&userId=' + userId; callAjaxWebApi(jsonMethod, 'POST', args, function (retVal) { if (retVal.data && retVal.data.user_id == userId) { + activeNotification.users.push(retVal.data); addToAlertedUsersTable(userName, userId); addClassesToTableRows('aggregateMetricSpecAlertedUsers'); $('#addAlertUserSearchValue').val('init'); @@ -606,8 +842,7 @@ $(document).ready(function () { /** Handler for Alerts Users Done button, hide the alerts panel. */ $('input#aggregateMetricSpecUserAlertsDone').click(function () { - $('div#aggregateMetricUserAlerts').hide(); - unhighlightActiveRow(); + hideNotificationDetailPanel(); }); // Initialize the dialog now that it is loaded. diff --git a/modules/tracker/public/scss/producer/producer.aggregatemetric.scss b/modules/tracker/public/scss/producer/producer.aggregatemetric.scss index da5fafc90..dcb6ed6fd 100644 --- a/modules/tracker/public/scss/producer/producer.aggregatemetric.scss +++ b/modules/tracker/public/scss/producer/producer.aggregatemetric.scss @@ -1,232 +1,129 @@ // Midas Server. Copyright Kitware SAS. Licensed under the Apache License 2.0. -a { - &.aggregateMetricSpecAction { - color: #56758b; - - &:hover { - background-color: #E5E5E5; - cursor: pointer; - } - } - - &.alertedUsersAction { - color: #56758b; - - &:hover { - background-color: #E5E5E5; - cursor: pointer; - } - } -} - -div { - &#addAggregateMetricSpec { - margin-top: 10px; - } - - &#aggregateMetricSpecList { - margin-top: 10px; - } - - &.aggregateMetricSpecCreate { - border-top: 2px solid darkblue !important; - } +div#aggregateMetricSpecManage { + table { + width: 100%; - &.aggregateMetricSpecEdit { - border-top: 2px solid darkblue !important; - } + &.actionTable { + table-layout: fixed; + border: 2px solid #ddd; + margin-top: 15px; + margin-bottom: 15px; - &#aggregateMetricSpecEditWarning { - padding-top: 10px; - padding-bottom: 10px; - color: orange; - } + tr.activeRow { + border: 2px solid darkblue; + background-color: #c0d1fe !important; + } - &#aggregateMetricUserAlerts { - border-top: 2px solid darkblue; - color: #555; - font-size: 13px; - margin-top: 15px; - margin-bottom: 10px; - padding-top: 10px; - text-align: center; + tr.even { + background-color: #f4f4f4; + } - div#aggregateMetricUserAlertsThreshold { - margin-top: 15px; - margin-bottom: 10px; + th { + border-bottom: solid 1px black; - table#aggregateMetricUserAlertsThresholdDefinition { - margin-top: 10px; + &:last-of-type { + text-align: center; + border-left: dotted 1px black; + width: 30%; + } + } - td:first-of-type { - text-align: left; + td { + &:last-of-type { + border-left: dotted 1px black; } } - } - textarea#aggregateMetricUserAlertsSpec { - margin-top: 10px; - width: 100%; - } + span.actionsList { + display: flex; + justify-content: space-around; - div#addAggregateMetricSpecAlertUser { - margin-top: 15px; - text-align: center; + a:first-of-type { + padding-left: 5px; + } + } } - - div.alertUserSearch { - margin-top: 10px; - + &.fieldTable { input { width: 100%; } + select { + width: 100%; + } } } - &.aggregateMetricSectionTitle { - border-top: 1px solid #d7d7d7; - color: #555; - font-size: 13px; - margin-top: 15px; - margin-bottom: 10px; - padding-top: 10px; - text-align: center; - } - - - &.resultingMetricText { - color: #555; - font-size: 12px; - margin-top: 10px; - text-align: center; - } - - &#aggregateMetricSpecUserAlertsSaveState { - margin-top: 20px; - - input { - background: #f6f9fe; - border: 1px solid #808080; - color: #2e6e9e; - cursor: pointer; - float: right; - margin-left: 10px; - } - } - - &#aggregateMetricSpecSaveState { - margin-top: 20px; + a.actionLink { + color: #56758b; - input { - background: #f6f9fe; - border: 1px solid #808080; - color: #2e6e9e; + &:hover { + background-color: #E5E5E5; cursor: pointer; - float: right; - margin-left: 10px; - } - - input:disabled { - color: #c0c0c0; - cursor: not-allowed; } } - - -} - -label { - &#aggregateMetricSpecValidationError { + label.validationError { color: crimson; } -} - -img { - &#aggregateMetricSpecSaveLoading { - float: left; - margin-right: 15px; - } - - &#aggregateMetricSpecDeleteLoading { - float: right; - margin-right: 40px; - } - - &#aggregateMetricSpecAlertsLoading { - float: left; - } -} - -table { - - &#aggregateMetricSpecAlertedUsers { - table-layout: fixed; - border: 2px solid #ddd; - width: 100%; - th { - border-bottom: solid 1px black; + div { + &.subsectionTitle { + border-top: 2px solid darkblue; + margin-top: 15px; + margin-bottom: 15px; + padding-top: 10px; + color: #555; + font-size: 13px; text-align: center; - - &:first-of-type { - width: 70%; - border-right: dotted 1px black; - } + font-weight: bold; } - - tr.even { - background-color: #f4f4f4; - } - - td.userName { - border-right: dotted 1px black; - text-align: left; - } - - tr.activeRow { - border: 2px solid darkblue; - background-color: #c0d1fe; + &.subsubsectionTitle { + color: #555; + font-size: 12px; + margin-top: 10px; + margin-bottom: 10px; + text-align: center; } - } - - - &#aggregateMetricSpecListTable { - table-layout: fixed; - border: 2px solid #ddd; - width: 100%; + &.saveState { + margin-top: 15px; - th { - border-bottom: solid 1px black; - text-align: center; + input { + background: #f6f9fe; + border: 1px solid #808080; + color: #2e6e9e; + cursor: pointer; + float: right; + margin-left: 10px; + } - &:first-of-type { - width: 70%; - border-right: dotted 1px black; + input:disabled { + color: #c0c0c0; + cursor: not-allowed; } } - - td.specName { - border-right: dotted 1px black; + &#aggregateMetricSpecEditWarning { + padding-top: 10px; + padding-bottom: 10px; + color: orange; } + } - tr.even { - background-color: #f4f4f4; - } + img.loadingImg { + float: left; - tr.activeRow { - border: 2px solid darkblue; - background-color: #c0d1fe; + &#aggregateMetricSpecDeleteLoading { + float: right; + margin-right: 40px; } + } - span.actionsList { - display: flex; - justify-content: space-around; + textarea#aggregateMetricUserAlertsSpec { + margin-top: 10px; + width: 100%; + } - a:first-of-type { - padding-left: 5px; - } - } + input#addAlertUserSearch { + width: 100% } } diff --git a/modules/tracker/views/producer/aggregatemetric.phtml b/modules/tracker/views/producer/aggregatemetric.phtml index fe62a2f21..7873ff99c 100644 --- a/modules/tracker/views/producer/aggregatemetric.phtml +++ b/modules/tracker/views/producer/aggregatemetric.phtml @@ -30,7 +30,7 @@ echo '