From 89d3985573c7eb58ef7fce624c6623a9f0cb94fe Mon Sep 17 00:00:00 2001 From: benakamoorthi <benaka.moorthi@gmail.com> Date: Wed, 29 Aug 2012 02:57:12 +0000 Subject: [PATCH] Refs #3227, speed up PrivacyManager some more. git-svn-id: http://dev.piwik.org/svn/trunk@6882 59fd770c-687e-43c8-a1e3-f5a4ff64c105 --- tests/PHPUnit/IntegrationTestCase.php | 77 +++++++++ tests/PHPUnit/Plugins/PrivacyManagerTest.php | 162 +++++++++---------- 2 files changed, 152 insertions(+), 87 deletions(-) diff --git a/tests/PHPUnit/IntegrationTestCase.php b/tests/PHPUnit/IntegrationTestCase.php index 4a6fd0462b..a548c1bb04 100755 --- a/tests/PHPUnit/IntegrationTestCase.php +++ b/tests/PHPUnit/IntegrationTestCase.php @@ -993,4 +993,81 @@ abstract class IntegrationTestCase extends PHPUnit_Framework_TestCase //return dirname(__FILE__).DIRECTORY_SEPARATOR.'Integration'; return dirname(dirname(__FILE__)).DIRECTORY_SEPARATOR.'integration'; } + + /** + * Returns an array associating table names w/ lists of row data. + * + * @return array + */ + protected static function getDbTablesWithData() + { + $result = array(); + foreach (Piwik::getTablesInstalled() as $tableName) + { + $result[$tableName] = Piwik_FetchAll("SELECT * FROM $tableName"); + } + return $result; + } + + /** + * Truncates all tables then inserts the data in $tables into each + * mapped table. + * + * @param array $tables Array mapping table names with arrays of row data. + */ + protected static function restoreDbTables( $tables ) + { + // truncate existing tables + Piwik::truncateAllTables(); + + // insert data + $existingTables = Piwik::getTablesInstalled(); + foreach ($tables as $table => $rows) + { + // create table if it's an archive table + if (strpos($table, 'archive_') !== false && !in_array($table, $existingTables)) + { + $tableType = strpos($table, 'archive_numeric') !== false ? 'archive_numeric' : 'archive_blob'; + + $createSql = Piwik::getTableCreateSql($tableType); + $createSql = str_replace(Piwik_Common::prefixTable($tableType), $table, $createSql); + Piwik_Query($createSql); + } + + if (empty($rows)) + { + continue; + } + + $rowsSql = array(); + foreach ($rows as $row) + { + $values = array(); + foreach ($row as $name => $value) + { + if (is_null($value)) + { + $values[] = 'NULL'; + } + else if (is_numeric($value)) + { + $values[] = $value; + } + else if (!ctype_print($value)) + { + $values[] = "x'".bin2hex(substr($value, 1))."'"; + } + else + { + $values[] = "'$value'"; + } + } + + $rowsSql[] = "(".implode(',', $values).")"; + } + + $sql = "INSERT INTO $table VALUES ".implode(',', $rowsSql); + Piwik_Query($sql); + } + } } diff --git a/tests/PHPUnit/Plugins/PrivacyManagerTest.php b/tests/PHPUnit/Plugins/PrivacyManagerTest.php index 6a0330dcce..a2c34932ba 100755 --- a/tests/PHPUnit/Plugins/PrivacyManagerTest.php +++ b/tests/PHPUnit/Plugins/PrivacyManagerTest.php @@ -8,7 +8,7 @@ */ require_once 'PrivacyManager/PrivacyManager.php'; -class PrivacyManagerTest extends DatabaseTestCase +class PrivacyManagerTest extends IntegrationTestCase { // constants used in checking whether numeric tables are populated correctly. // 'done' entries exist for every period, even if there's no metric data, so we need the @@ -24,44 +24,49 @@ class PrivacyManagerTest extends DatabaseTestCase // fake metric/report name used to make sure unwanted metrics are purged const GARBAGE_FIELD = 'abcdefg'; - private $idSite = null; - private $dateTime = null; + private static $idSite = 1; + private static $dateTime = '2012-02-28'; + private static $daysAgoStart = 50; + + // maps table names w/ array rows + private static $dbData = null; + /** * @var Piwik_PrivacyManager */ private $instance = null; - private $daysAgoStart = 50; private $settings = null; private $unusedIdAction = null; + public static function setUpBeforeClass() + { + parent::setUpBeforeClass(); + + self::_addLogData(); + self::_addReportData(); + + self::$dbData = self::getDbTablesWithData(); + } + public function setUp() { - parent::setUp(); - - $this->dateTime = Piwik_Date::factory('2012-02-28'); - - Piwik_PluginsManager::getInstance()->loadPlugins( array('API', 'PrivacyManager', 'VisitsSummary', 'VisitorInterest', 'UserSettings', 'Goals') ); - Piwik_PluginsManager::getInstance()->installLoadedPlugins(); - - Piwik::createAccessObject(); - Piwik_PostEvent('FrontController.initAuthenticationObject'); - - // We need to be SU to create websites for tests - Piwik::setUserIsSuperUser(); - - Piwik_TablePartitioning::$tablesAlreadyInstalled = null; - + parent::setUp(); + Piwik_PrivacyManager_LogDataPurger::$selectSegmentSize = 2; Piwik_PrivacyManager_ReportsPurger::$selectSegmentSize = 2; Piwik::$lockPrivilegeGranted = null; - + + self::restoreDbTables(self::$dbData); + + $dateTime = Piwik_Date::factory(self::$dateTime); + // purging depends upon today's date, so 'older_than' parts must be dependent upon today $today = Piwik_Date::factory('today'); - $daysSinceToday = ($today->getTimestamp() - $this->dateTime->getTimestamp()) / (24 * 60 * 60); + $daysSinceToday = ($today->getTimestamp() - $dateTime->getTimestamp()) / (24 * 60 * 60); $monthsSinceToday = 0; - for ($date = $today; $date->toString('Y-m') != $this->dateTime->toString('Y-m'); $date = $date->subMonth(1)) + for ($date = $today; $date->toString('Y-m') != $dateTime->toString('Y-m'); $date = $date->subMonth(1)) { ++$monthsSinceToday; } @@ -69,6 +74,7 @@ class PrivacyManagerTest extends DatabaseTestCase // set default config $settings = array(); $settings['delete_logs_enable'] = 1; + // purging log data from before 2012-01-24 $settings['delete_logs_older_than'] = 35 + $daysSinceToday; $settings['delete_logs_schedule_lowest_interval'] = 7; @@ -88,6 +94,19 @@ class PrivacyManagerTest extends DatabaseTestCase $this->instance = new Piwik_PrivacyManager(); } + public function tearDown() + { + parent::tearDown(); + Piwik_DataTable_Manager::getInstance()->deleteAll(); + Piwik_Option::getInstance()->clearCache(); + Piwik_Site::clearCache(); + Piwik_Common::deleteTrackerCache(); + Piwik_TablePartitioning::$tablesAlreadyInstalled = null; + + $tempTableName = Piwik_Common::prefixTable(Piwik_PrivacyManager_LogDataPurger::TEMP_TABLE_NAME); + Piwik_Query("DROP TABLE IF EXISTS ".$tempTableName); + } + /** * Make sure the first time deleteLogData is run, nothing happens. * @@ -96,9 +115,6 @@ class PrivacyManagerTest extends DatabaseTestCase */ public function testDeleteLogDataInitialRun() { - $this->_addLogData(); - $this->_addReportData(); - $this->instance->deleteLogData(); // check that initial option is set @@ -117,9 +133,6 @@ class PrivacyManagerTest extends DatabaseTestCase */ public function testDeleteReportDataInitialRun() { - $this->_addLogData(); - $this->_addReportData(); - $this->instance->deleteReportData(); // check that initial option is set @@ -137,9 +150,6 @@ class PrivacyManagerTest extends DatabaseTestCase */ public function testPurgeDataNotTimeToRun() { - $this->_addLogData(); - $this->_addReportData(); - $yesterdaySecs = Piwik_Date::factory('yesterday')->getTimestamp(); Piwik_SetOption(Piwik_PrivacyManager::OPTION_LAST_DELETE_PIWIK_LOGS_INITIAL, 1); @@ -160,9 +170,6 @@ class PrivacyManagerTest extends DatabaseTestCase */ public function testPurgeDataNotInitialAndTimeToRun() { - $this->_addLogData(); - $this->_addReportData(); - // get purge data prediction $prediction = Piwik_PrivacyManager::getPurgeEstimate(); @@ -185,7 +192,7 @@ class PrivacyManagerTest extends DatabaseTestCase // perform checks $this->checkLogDataPurged(); - $archiveTables = $this->_getArchiveTableNames(); + $archiveTables = self::_getArchiveTableNames(); // January numeric table should be dropped $this->assertFalse($this->_tableExists($archiveTables['numeric'][0])); // January @@ -215,9 +222,6 @@ class PrivacyManagerTest extends DatabaseTestCase 'delete_reports_enable' => 0 )); - $this->_addLogData(); - $this->_addReportData(); - // get purge data prediction $prediction = Piwik_PrivacyManager::getPurgeEstimate(); @@ -242,6 +246,12 @@ class PrivacyManagerTest extends DatabaseTestCase */ public function testPurgeDataDeleteLogsNoData() { + Piwik::truncateAllTables(); + foreach (Piwik::getTablesArchivesInstalled() as $table) + { + Piwik_Exec("DROP TABLE $table"); + } + // get purge data prediction $prediction = Piwik_PrivacyManager::getPurgeEstimate(); @@ -260,7 +270,7 @@ class PrivacyManagerTest extends DatabaseTestCase $this->assertEquals(0, $this->_getTableCount('log_link_visit_action')); $this->assertEquals(0, $this->_getTableCount('log_conversion_item')); - $archiveTables = $this->_getArchiveTableNames(); + $archiveTables = self::_getArchiveTableNames(); $this->assertFalse($this->_tableExists($archiveTables['numeric'][0])); // January $this->assertFalse($this->_tableExists($archiveTables['numeric'][1])); // February $this->assertFalse($this->_tableExists($archiveTables['blob'][0])); // January @@ -279,9 +289,6 @@ class PrivacyManagerTest extends DatabaseTestCase 'delete_reports_keep_basic_metrics' => 1 )); - $this->_addLogData(); - $this->_addReportData(); - // get purge data prediction $prediction = Piwik_PrivacyManager::getPurgeEstimate(); @@ -304,7 +311,7 @@ class PrivacyManagerTest extends DatabaseTestCase // perform checks $this->checkLogDataPurged(); - $archiveTables = $this->_getArchiveTableNames(); + $archiveTables = self::_getArchiveTableNames(); // all numeric metrics should be saved except the garbage metric $janRowCount = $this->_getExpectedNumericArchiveCountJan() - 1; @@ -333,9 +340,6 @@ class PrivacyManagerTest extends DatabaseTestCase 'delete_reports_keep_day_reports' => 1 )); - $this->_addLogData(); - $this->_addReportData(); - // get purge data prediction $prediction = Piwik_PrivacyManager::getPurgeEstimate(); @@ -372,9 +376,6 @@ class PrivacyManagerTest extends DatabaseTestCase 'delete_reports_keep_week_reports' => 1 )); - $this->_addLogData(); - $this->_addReportData(); - // get purge data prediction $prediction = Piwik_PrivacyManager::getPurgeEstimate(); @@ -411,9 +412,6 @@ class PrivacyManagerTest extends DatabaseTestCase 'delete_reports_keep_month_reports' => 1 )); - $this->_addLogData(); - $this->_addReportData(); - // get purge data prediction $prediction = Piwik_PrivacyManager::getPurgeEstimate(); @@ -450,9 +448,6 @@ class PrivacyManagerTest extends DatabaseTestCase 'delete_reports_keep_year_reports' => 1 )); - $this->_addLogData(); - $this->_addReportData(); - // get purge data prediction $prediction = Piwik_PrivacyManager::getPurgeEstimate(); @@ -487,8 +482,6 @@ class PrivacyManagerTest extends DatabaseTestCase { Piwik_AddAction("LogDataPurger.actionsToKeepInserted.olderThan", array($this, 'addReferenceToUnusedAction')); - $this->_addLogData(); - $purger = Piwik_PrivacyManager_LogDataPurger::make($this->settings, true); $this->unusedIdAction = Piwik_FetchOne( @@ -523,9 +516,6 @@ class PrivacyManagerTest extends DatabaseTestCase 'delete_reports_keep_range_reports' => 1 )); - $this->_addLogData(); - $this->_addReportData(); - // get purge data prediction $prediction = Piwik_PrivacyManager::getPurgeEstimate(); @@ -563,9 +553,6 @@ class PrivacyManagerTest extends DatabaseTestCase 'delete_reports_keep_segment_reports' => 1 )); - $this->_addLogData(); - $this->_addReportData(); - // get purge data prediction $prediction = Piwik_PrivacyManager::getPurgeEstimate(); @@ -592,7 +579,7 @@ class PrivacyManagerTest extends DatabaseTestCase // --- utility functions follow --- - protected function _addLogData() + protected static function _addLogData() { // tracks visits on the following days: // - 2012-01-09 @@ -618,14 +605,14 @@ class PrivacyManagerTest extends DatabaseTestCase // - http://whatever.com/_{$daysSinceLastVisit} // - http://whatever.com/42/{$daysSinceLastVisit} - $start = $this->dateTime; - $this->idSite = IntegrationTestCase::createWebsite('2012-01-01', $ecommerce=1); - $idGoal = Piwik_Goals_API::getInstance()->addGoal($this->idSite, 'match all', 'url', 'http', 'contains'); + $start = Piwik_Date::factory(self::$dateTime); + self::createWebsite('2012-01-01', $ecommerce=1); + $idGoal = Piwik_Goals_API::getInstance()->addGoal(self::$idSite, 'match all', 'url', 'http', 'contains'); - $t = IntegrationTestCase::getTracker($this->idSite, $start, $defaultInit = true); + $t = IntegrationTestCase::getTracker(self::$idSite, $start, $defaultInit = true); $t->enableBulkTracking(); $t->setTokenAuth(IntegrationTestCase::getTokenAuth()); - for ($daysAgo = $this->daysAgoStart; $daysAgo >= 0; $daysAgo -= 5) // one visit every 5 days + for ($daysAgo = self::$daysAgoStart; $daysAgo >= 0; $daysAgo -= 5) // one visit every 5 days { $dateTime = $start->subDay($daysAgo)->toString(); @@ -648,52 +635,53 @@ class PrivacyManagerTest extends DatabaseTestCase $t->doBulkTrack(); } - protected function _addReportData() + protected static function _addReportData() { - $archive = Piwik_Archive::build($this->idSite, 'year', $this->dateTime); + $date = Piwik_Date::factory(self::$dateTime); + + $archive = Piwik_Archive::build(self::$idSite, 'year', $date); $archive->getNumeric('nb_visits', 'nb_hits'); - Piwik_VisitorInterest_API::getInstance()->getNumberOfVisitsPerVisitDuration( - $this->idSite, 'year', $this->dateTime); + Piwik_VisitorInterest_API::getInstance()->getNumberOfVisitsPerVisitDuration(self::$idSite, 'year', $date); // months are added via the 'year' period, but weeks must be done manually - for ($daysAgo = $this->daysAgoStart; $daysAgo > 0; $daysAgo -= 7) // every week + for ($daysAgo = self::$daysAgoStart; $daysAgo > 0; $daysAgo -= 7) // every week { - $dateTime = $this->dateTime->subDay($daysAgo); + $dateTime = $date->subDay($daysAgo); - $archive = Piwik_Archive::build($this->idSite, 'week', $dateTime); + $archive = Piwik_Archive::build(self::$idSite, 'week', $dateTime); $archive->getNumeric('nb_visits'); Piwik_VisitorInterest_API::getInstance()->getNumberOfVisitsPerVisitDuration( - $this->idSite, 'week', $dateTime); + self::$idSite, 'week', $dateTime); } // add segment for one day - $archive = Piwik_Archive::build($this->idSite, 'day', '2012-01-14', 'browserName==FF'); + $archive = Piwik_Archive::build(self::$idSite, 'day', '2012-01-14', 'browserName==FF'); $archive->getNumeric('nb_visits', 'nb_hits'); Piwik_VisitorInterest_API::getInstance()->getNumberOfVisitsPerVisitDuration( - $this->idSite, 'day', '2012-01-14', 'browserName==FF'); + self::$idSite, 'day', '2012-01-14', 'browserName==FF'); // add range within January $rangeEnd = Piwik_Date::factory('2012-01-29'); $rangeStart = $rangeEnd->subDay(1); $range = $rangeStart->toString('Y-m-d').",".$rangeEnd->toString('Y-m-d'); - $rangeArchive = Piwik_Archive::build($this->idSite, 'range', $range); + $rangeArchive = Piwik_Archive::build(self::$idSite, 'range', $range); $rangeArchive->getNumeric('nb_visits', 'nb_hits'); - Piwik_VisitorInterest_API::getInstance()->getNumberOfVisitsPerVisitDuration($this->idSite, 'range', $range); + Piwik_VisitorInterest_API::getInstance()->getNumberOfVisitsPerVisitDuration(self::$idSite, 'range', $range); // add range between January & February $rangeStart = $rangeEnd; $rangeEnd = $rangeStart->addDay(3); $range = $rangeStart->toString('Y-m-d').",".$rangeEnd->toString('Y-m-d'); - $rangeArchive = Piwik_Archive::build($this->idSite, 'range', $range); + $rangeArchive = Piwik_Archive::build(self::$idSite, 'range', $range); $rangeArchive->getNumeric('nb_visits', 'nb_hits'); - Piwik_VisitorInterest_API::getInstance()->getNumberOfVisitsPerVisitDuration($this->idSite, 'range', $range); + Piwik_VisitorInterest_API::getInstance()->getNumberOfVisitsPerVisitDuration(self::$idSite, 'range', $range); // when archiving is initiated, the archive metrics & reports for EVERY loaded plugin // are archived. don't want this test to depend on every possible metric, so get rid of @@ -706,7 +694,7 @@ class PrivacyManagerTest extends DatabaseTestCase Piwik_Goals::getRecordName('revenue', Piwik_Tracker_GoalManager::IDGOAL_ORDER) ); - $archiveTables = $this->_getArchiveTableNames(); + $archiveTables = self::_getArchiveTableNames(); foreach ($archiveTables['numeric'] as $table) { $realTable = Piwik_Common::prefixTable($table); @@ -747,7 +735,7 @@ class PrivacyManagerTest extends DatabaseTestCase $this->assertEquals(11, $this->_getTableCount('log_conversion_item')); $this->assertEquals(27, $this->_getTableCount('log_action')); - $archiveTables = $this->_getArchiveTableNames(); + $archiveTables = self::_getArchiveTableNames(); $janMetricCount = $this->_getExpectedNumericArchiveCountJan(); $this->assertEquals($janMetricCount, $this->_getTableCount($archiveTables['numeric'][0])); // January @@ -768,7 +756,7 @@ class PrivacyManagerTest extends DatabaseTestCase */ protected function _checkReportsAndMetricsPurged( $janBlobsRemaining ) { - $archiveTables = $this->_getArchiveTableNames(); + $archiveTables = self::_getArchiveTableNames(); // check that the january numeric table was dropped $this->assertFalse($this->_tableExists($archiveTables['numeric'][0])); // January @@ -846,7 +834,7 @@ class PrivacyManagerTest extends DatabaseTestCase return Piwik_FetchOne($sql, array($dbName, Piwik_Common::prefixTable($tableName))) == 1; } - protected function _getArchiveTableNames() + protected static function _getArchiveTableNames() { return array( 'numeric' => array( -- GitLab