From f4ff556a9b1dbdba06ff612cd0d27e262e0dbd76 Mon Sep 17 00:00:00 2001
From: benakamoorthi <benaka.moorthi@gmail.com>
Date: Thu, 24 Nov 2011 23:43:45 +0000
Subject: [PATCH] Refs #1077. Improved speed of the IndexedBySite archive type
 by optimizing the case when launching the archiving process is disabled.
 Instead of selecting archive IDs one at a time, IndexedBySite will now select
 them all at once.

Notes:
* Also added an integration test that will test whether Piwik works when archiving is disabled.
* Modified getKnownSegmentsToArchive() to cache its result as static function data instead of having ArchiveProcessing cache it as instance data.
* Changed several instance methods in ArchiveProcessing to static methods. These methods are responsible for determining if archiving is disabled.
* Removed meaningless idSite related code from TablePartitioning.


git-svn-id: http://dev.piwik.org/svn/trunk@5475 59fd770c-687e-43c8-a1e3-f5a4ff64c105
---
 core/Archive.php                              |   2 +-
 core/Archive/Array/IndexedBySite.php          | 124 ++++++++++++++++--
 core/Archive/Single.php                       |  11 ++
 core/ArchiveProcessing.php                    | 116 +++++++++++-----
 core/Piwik.php                                |  13 +-
 core/TablePartitioning.php                    |   8 +-
 tests/integration/Main.test.php               |  84 ++++++++----
 ...d_disabledAfter__VisitsSummary.get_day.xml |  14 ++
 ...disabledAfter__VisitsSummary.get_month.xml |  24 ++++
 ..._disabledAfter__VisitsSummary.get_week.xml |  14 ++
 ..._disabledAfter__VisitsSummary.get_year.xml |  22 ++++
 ..._disabledBefore__VisitsSummary.get_day.xml |   5 +
 ...isabledBefore__VisitsSummary.get_month.xml |   5 +
 ...disabledBefore__VisitsSummary.get_week.xml |   5 +
 ...disabledBefore__VisitsSummary.get_year.xml |   5 +
 ...isabled_enabled__VisitsSummary.get_day.xml |  14 ++
 ...abled_enabled__VisitsSummary.get_month.xml |  24 ++++
 ...sabled_enabled__VisitsSummary.get_week.xml |  14 ++
 ...sabled_enabled__VisitsSummary.get_year.xml |  22 ++++
 19 files changed, 446 insertions(+), 80 deletions(-)
 create mode 100755 tests/integration/expected/test_TwoVisitors_twoWebsites_differentDays_ArchivingDisabled_disabledAfter__VisitsSummary.get_day.xml
 create mode 100755 tests/integration/expected/test_TwoVisitors_twoWebsites_differentDays_ArchivingDisabled_disabledAfter__VisitsSummary.get_month.xml
 create mode 100755 tests/integration/expected/test_TwoVisitors_twoWebsites_differentDays_ArchivingDisabled_disabledAfter__VisitsSummary.get_week.xml
 create mode 100755 tests/integration/expected/test_TwoVisitors_twoWebsites_differentDays_ArchivingDisabled_disabledAfter__VisitsSummary.get_year.xml
 create mode 100755 tests/integration/expected/test_TwoVisitors_twoWebsites_differentDays_ArchivingDisabled_disabledBefore__VisitsSummary.get_day.xml
 create mode 100755 tests/integration/expected/test_TwoVisitors_twoWebsites_differentDays_ArchivingDisabled_disabledBefore__VisitsSummary.get_month.xml
 create mode 100755 tests/integration/expected/test_TwoVisitors_twoWebsites_differentDays_ArchivingDisabled_disabledBefore__VisitsSummary.get_week.xml
 create mode 100755 tests/integration/expected/test_TwoVisitors_twoWebsites_differentDays_ArchivingDisabled_disabledBefore__VisitsSummary.get_year.xml
 create mode 100755 tests/integration/expected/test_TwoVisitors_twoWebsites_differentDays_ArchivingDisabled_enabled__VisitsSummary.get_day.xml
 create mode 100755 tests/integration/expected/test_TwoVisitors_twoWebsites_differentDays_ArchivingDisabled_enabled__VisitsSummary.get_month.xml
 create mode 100755 tests/integration/expected/test_TwoVisitors_twoWebsites_differentDays_ArchivingDisabled_enabled__VisitsSummary.get_week.xml
 create mode 100755 tests/integration/expected/test_TwoVisitors_twoWebsites_differentDays_ArchivingDisabled_enabled__VisitsSummary.get_year.xml

diff --git a/core/Archive.php b/core/Archive.php
index 62f58e0433..1ba7e18833 100644
--- a/core/Archive.php
+++ b/core/Archive.php
@@ -321,7 +321,7 @@ abstract class Piwik_Archive
 		return $dataTable;
 	}
 	
-	protected function getSegment()
+	public function getSegment()
 	{
 	    return $this->segment;
 	}
diff --git a/core/Archive/Array/IndexedBySite.php b/core/Archive/Array/IndexedBySite.php
index 55d256dd27..692a344d3c 100644
--- a/core/Archive/Array/IndexedBySite.php
+++ b/core/Archive/Array/IndexedBySite.php
@@ -16,6 +16,14 @@
  */
 class Piwik_Archive_Array_IndexedBySite extends Piwik_Archive_Array 
 {
+	/**
+	 * Used to cache the name of the table that holds the data this archive.
+	 * 
+	 * This will only be used if the archives held by this instance are instances of
+	 * Piwik_Archive_Single.
+	 */
+	private $tableName = null;
+
 	/**
 	 * @param Piwik_Site $oSite 
 	 * @param string $strPeriod eg. 'day' 'week' etc.
@@ -79,12 +87,6 @@ class Piwik_Archive_Array_IndexedBySite extends Piwik_Archive_Array
 
 	private function getValues($fields)
 	{
-		foreach($this->archives as $archive)
-		{
-			$archive->setRequestedReport( is_string($fields) ? $fields : current($fields) );
-			$archive->prepareArchive();
-		}
-		
 		$arrayValues = array();
 		foreach($this->loadValuesFromDB($fields) as $value)
  		{
@@ -95,12 +97,28 @@ class Piwik_Archive_Array_IndexedBySite extends Piwik_Archive_Array
 	
 	private function loadValuesFromDB($fields)
 	{
+		$requestedReport = is_string($fields) ? $fields : current($fields);
 		$inNames = Piwik_Common::getSqlStringFieldsArray($fields);
-		$archiveIds = $this->getArchiveIds();
+
+		// get the archive ids
+		if (!$this->getFirstArchive()->isArchivingDisabled())
+		{
+			$archiveIds = $this->getArchiveIdsAfterLaunching($requestedReport);
+		}
+		else
+		{
+			$archiveIds = $this->getArchiveIdsWithoutLaunching($requestedReport);
+		}
+
+		$archiveIds = implode(', ', array_filter($archiveIds));
+
+		// if no archive ids are found, avoid executing any SQL queries
 		if(empty($archiveIds))
 		{
 			return array();
 		}
+
+		// select archive data
  		$sql = "SELECT value, name, idarchive, idsite
 								FROM {$this->getNumericTableName()}
 								WHERE idarchive IN ( $archiveIds )
@@ -110,12 +128,26 @@ class Piwik_Archive_Array_IndexedBySite extends Piwik_Archive_Array
 
 	private function getFirstArchive()
 	{
-		reset($this->archives);
-		return current($this->archives);
+		return reset($this->archives);
 	}
 
-	private function getArchiveIds()
+	/**
+	 * Gets the archive id of every Single archive this archive holds. This method
+	 * will launch the archiving process if appropriate.
+	 * 
+	 * @param string $requestedReport The requested archive report.
+	 * @return array
+	 */
+	private function getArchiveIdsAfterLaunching( $requestedReport )
 	{
+		// prepare archives (this will launch archiving when appropriate)
+		foreach($this->archives as $archive)
+		{
+			$archive->setRequestedReport( $requestedReport );
+			$archive->prepareArchive();
+		}
+
+		// collect archive ids for archives that have visits
 		$archiveIds = array();
 		foreach($this->archives as $archive)
  		{
@@ -125,17 +157,83 @@ class Piwik_Archive_Array_IndexedBySite extends Piwik_Archive_Array
  			}
  			
 			$archiveIds[] = $archive->getIdArchive();
-			
+		
  			if( $this->getNumericTableName() != $archive->archiveProcessing->getTableArchiveNumericName())
 			{
 				throw new Exception("Piwik_Archive_Array_IndexedBySite::getDataTableFromNumeric() algorithm won't work if data is stored in different tables");
 			}
  		}
-		return implode(', ', array_filter($archiveIds));
+ 		
+ 		return $archiveIds;
+	}
+
+	/**
+	 * Gets the archive id of every Single archive this archive holds. This method
+	 * will not launch the archiving process.
+	 * 
+	 * @param string $requestedReport The requested archive report.
+	 * @return array
+	 */
+	private function getArchiveIdsWithoutLaunching( $requestedReport )
+	{
+		$firstArchive = $this->getFirstArchive();
+		$segment = $firstArchive->getSegment();
+		$period = $firstArchive->getPeriod();
+		
+		// the flags used to tell how the archiving process for a specific archive was completed,
+		// if it was completed
+		$done = Piwik_ArchiveProcessing::getDoneStringFlagFor($segment, $period, $requestedReport);
+		$donePlugins = Piwik_ArchiveProcessing::getDoneStringFlagFor($segment, $period, $requestedReport, true);
+
+		// create the SQL to query every archive ID
+		$nameConditionSuffix = '';
+		if ($done != $donePlugins)
+		{
+			$nameConditionSuffix = "OR name = '$donePlugins'";
+		}
+
+		$nameCondition = "(name = '$done' $nameConditionSuffix) AND
+						  (value = '".Piwik_ArchiveProcessing::DONE_OK."' OR
+						   value = '".Piwik_ArchiveProcessing::DONE_OK_TEMPORARY."')";
+
+		$sql = "SELECT idsite,
+		               MAX(idarchive) AS idarchive
+		          FROM ".$this->getNumericTableName()."
+		         WHERE date1 = ?
+		           AND date2 = ?
+		           AND period = ?
+		           AND $nameCondition
+		           AND idsite IN (".implode(',', array_keys($this->archives)).")
+		      GROUP BY idsite";
+		
+		$bind = array($period->getDateStart()->toString('Y-m-d'),
+					  $period->getDateEnd()->toString('Y-m-d'),
+					  $period->getId());
+
+		// execute the query and process the results.
+		$archiveIds = array();
+		foreach (Piwik_FetchAll($sql, $bind) as $row)
+		{
+			$archiveIds[] = $row['idarchive'];
+		}
+		
+		return $archiveIds;
 	}
 	
+	/**
+	 * Gets the name of the database table that holds the numeric archive data for
+	 * this archive.
+	 *
+	 * @return string
+	 */
 	private function getNumericTableName()
 	{
-		return $this->getFirstArchive()->archiveProcessing->getTableArchiveNumericName();
+		if (is_null($this->tableName))
+		{
+			$table = Piwik_ArchiveProcessing::makeNumericArchiveTable($this->getFirstArchive()->getPeriod());
+			$this->tableName = $table->getTableName();
+		}
+
+		return $this->tableName;
 	}
 }
diff --git a/core/Archive/Single.php b/core/Archive/Single.php
index d6abba58ea..d029a2b524 100644
--- a/core/Archive/Single.php
+++ b/core/Archive/Single.php
@@ -569,4 +569,15 @@ class Piwik_Archive_Single extends Piwik_Archive
 		$this->freeBlob($name);
 		return $dataTableToLoad;		
 	}
+	
+	/**
+	 * Returns true if Piwik can launch the archiving process for this archive,
+	 * false if otherwise.
+	 * 
+	 * @return bool
+	 */
+	public function isArchivingDisabled()
+	{
+		return Piwik_ArchiveProcessing::isArchivingDisabledFor($this->segment, $this->period);
+	}
 }
diff --git a/core/ArchiveProcessing.php b/core/ArchiveProcessing.php
index b550a67f31..534c2f7a71 100644
--- a/core/ArchiveProcessing.php
+++ b/core/ArchiveProcessing.php
@@ -200,7 +200,10 @@ abstract class Piwik_ArchiveProcessing
 	protected $startTimestampUTC;
 	protected $endTimestampUTC;
 	
-	protected $segmentsToProcess = null;
+	/**
+	 * TODO
+	 */
+	public static $forceDisableArchiving = false;
 	
 	/**
 	 * Constructor
@@ -315,12 +318,8 @@ abstract class Piwik_ArchiveProcessing
 		$dateStartLocalTimezone = $this->period->getDateStart();
 		$dateEndLocalTimezone = $this->period->getDateEnd();
 		
-		$this->tableArchiveNumeric = new Piwik_TablePartitioning_Monthly('archive_numeric');
-		$this->tableArchiveNumeric->setIdSite($this->idsite);
-		$this->tableArchiveNumeric->setTimestamp($dateStartLocalTimezone->getTimestamp());
-		$this->tableArchiveBlob = new Piwik_TablePartitioning_Monthly('archive_blob');
-		$this->tableArchiveBlob->setIdSite($this->idsite);	
-		$this->tableArchiveBlob->setTimestamp($dateStartLocalTimezone->getTimestamp());
+		$this->tableArchiveNumeric = self::makeNumericArchiveTable($this->period);
+		$this->tableArchiveBlob = self::makeBlobArchiveTable($this->period);
 
 		$dateStartUTC = $dateStartLocalTimezone->setTimezone($this->site->getTimezone());
 		$dateEndUTC = $dateEndLocalTimezone->setTimezone($this->site->getTimezone());
@@ -333,6 +332,34 @@ abstract class Piwik_ArchiveProcessing
 		$db = Zend_Registry::get('db');
 		$this->compressBlob = $db->hasBlobDataType();
 	}
+	
+	/**
+	 * Utility function which creates a TablePartitioning instance for the numeric
+	 * archive data of a given period.
+	 * 
+	 * @param $period The time period of the archive data.
+	 * @return Piwik_TablePartitioning_Monthly
+	 */
+	public static function makeNumericArchiveTable($period)
+	{
+		$result = new Piwik_TablePartitioning_Monthly('archive_numeric');
+		$result->setTimestamp($period->getDateStart()->getTimestamp());
+		return $result;
+	}
+	
+	/**
+	 * Utility function which creates a TablePartitioning instance for the blob
+	 * archive data of a given period.
+	 * 
+	 * @param $period The time period of the archive data.
+	 * @return Piwik_TablePartitioning_Monthly
+	 */
+	public static function makeBlobArchiveTable($period)
+	{
+		$result = new Piwik_TablePartitioning_Monthly('archive_blob');
+		$result->setTimestamp($period->getDateStart()->getTimestamp());
+		return $result;
+	}
 
 	public function getStartDatetimeUTC()
 	{
@@ -452,22 +479,41 @@ abstract class Piwik_ArchiveProcessing
 	
 	abstract public function isThereSomeVisits();
 	
-	protected function getDoneStringFlag($flagArchiveAsAllPlugins = false)
+	/**
+	 * Returns the name of the archive field used to tell the status of an archive, (ie,
+	 * whether the archive was created succesfully or not).
+	 * 
+	 * @param bool $flagArchiveAsAllPlugins
+	 * @return string
+	 */
+	public function getDoneStringFlag($flagArchiveAsAllPlugins = false)
 	{
-		$segment = $this->getSegment()->getHash();
-		if(!$this->shouldProcessReportsAllPlugins($this->getSegment(), $this->period))
+		return self::getDoneStringFlagFor(
+			$this->getSegment(), $this->period, $this->getRequestedReport(), $flagArchiveAsAllPlugins);
+	}
+	
+	/**
+	 * Returns the name of the archive field used to tell the status of an archive, (ie,
+	 * whether the archive was created succesfully or not).
+	 * 
+	 * @param bool $flagArchiveAsAllPlugins
+	 * @return string
+	 */
+	public static function getDoneStringFlagFor($segment, $period, $requestedReport, $flagArchiveAsAllPlugins = false)
+	{
+		$segmentHash = $segment->getHash();
+		if(!self::shouldProcessReportsAllPluginsFor($segment, $period))
 		{
-			$pluginProcessed = self::getPluginBeingProcessed($this->getRequestedReport());
-//			Piwik::log("Plugin processed: $pluginProcessed");
+			$pluginProcessed = self::getPluginBeingProcessed($requestedReport);
 			if(!Piwik_PluginsManager::getInstance()->isPluginLoaded($pluginProcessed)
 				|| $flagArchiveAsAllPlugins 
 				)
 			{
 				$pluginProcessed = 'all';
 			}
-			$segment .= '.'.$pluginProcessed;
+			$segmentHash .= '.'.$pluginProcessed;
 		}
-	    return 'done' . $segment;
+	    return 'done' . $segmentHash;
 	}
 	
 	/**
@@ -880,14 +926,19 @@ abstract class Piwik_ArchiveProcessing
 	 */
 	public function isArchivingDisabled()
 	{
-		$processOneReportOnly = !$this->shouldProcessReportsAllPlugins($this->getSegment(), $this->period);
+		return self::isArchivingDisabledFor($this->getSegment(), $this->period);
+	}
+	
+	public static function isArchivingDisabledFor($segment, $period)
+	{
+		$processOneReportOnly = !self::shouldProcessReportsAllPluginsFor($segment, $period);
 		if($processOneReportOnly)
 		{
 			// When there is a segment, archiving is not necessary allowed
 			// If browser archiving is allowed, then archiving is enabled
 			// if browser archiving is not allowed, then archiving is disabled
-			if(!$this->getSegment()->isEmpty()
-				&& !$this->isRequestAuthorizedToArchive()
+			if(!$segment->isEmpty()
+				&& !self::isRequestAuthorizedToArchive()
 				&& Zend_Registry::get('config')->General->browser_archiving_disabled_enforce
 			)
 			{
@@ -896,16 +947,17 @@ abstract class Piwik_ArchiveProcessing
 			}
 			return false;
 		}
-		$isDisabled = !$this->isRequestAuthorizedToArchive();
+		$isDisabled = !self::isRequestAuthorizedToArchive();
 		return $isDisabled;
 	}
 	
-	protected function isRequestAuthorizedToArchive()
+	protected static function isRequestAuthorizedToArchive()
 	{
-		return self::isBrowserTriggerArchivingEnabled()
-				|| Piwik_Common::isPhpCliMode()
-				|| (Piwik::isUserIsSuperUser() 
-					&& Piwik_Common::isArchivePhpTriggered())
+		return !self::$forceDisableArchiving &&
+				(self::isBrowserTriggerArchivingEnabled()
+				 || Piwik_Common::isPhpCliMode()
+				 || (Piwik::isUserIsSuperUser() 
+					&& Piwik_Common::isArchivePhpTriggered()))
 					;
 	}
 	
@@ -915,29 +967,31 @@ abstract class Piwik_ArchiveProcessing
 	 * - there is a segment that is part of the preprocessed [Segments] list
 	 */
 	protected function shouldProcessReportsAllPlugins($segment, $period)
+	{
+		return self::shouldProcessReportsAllPluginsFor($segment, $period);
+	}
+	
+	protected static function shouldProcessReportsAllPluginsFor($segment, $period)
 	{
 		if($segment->isEmpty() && $period->getLabel() != 'range')
 		{
 			return true;
 		}
 		
-		if(is_null($this->segmentsToProcess))
-		{
-			$this->segmentsToProcess = Piwik::getKnownSegmentsToArchive();
-		}
-		if(!empty($this->segmentsToProcess))
+		$segmentsToProcess = Piwik::getKnownSegmentsToArchive();
+		if(!empty($segmentsToProcess))
 		{
 			// If the requested segment is one of the segments to pre-process
 			// we ensure that any call to the API will trigger archiving of all reports for this segment
-			$segment = $this->getSegment()->getString();
-			if(in_array($segment, $this->segmentsToProcess))
+			$segment = $segment->getString();
+			if(in_array($segment, $segmentsToProcess))
 			{
 				return true;
 			}
 		}
 		return false;
 	}
-	
+
 	/**
 	 * When a segment is set, we shall only process the requested report (no more).
 	 * The requested data set will return a lot faster if we only process these reports rather than all plugins.
diff --git a/core/Piwik.php b/core/Piwik.php
index 2827e7de78..fa4a295abc 100644
--- a/core/Piwik.php
+++ b/core/Piwik.php
@@ -1552,14 +1552,21 @@ class Piwik
 					Zend_Registry::get('config')->General->autocomplete_min_sites);
 		return (int)$count;
 	}
-	
+
 	/**
 	 * Segments to pre-process
 	 */
 	static public function getKnownSegmentsToArchive()
 	{
-		$segments = Zend_Registry::get('config')->Segments->toArray();
-		return isset($segments['Segments']) ? $segments['Segments'] : '';
+		static $cachedResult = null;
+
+		if (is_null($cachedResult))
+		{
+			$segments = Zend_Registry::get('config')->Segments->toArray();
+			$cachedResult = isset($segments['Segments']) ? $segments['Segments'] : '';
+		}
+		
+		return $cachedResult;
 	}
 
 /*
diff --git a/core/TablePartitioning.php b/core/TablePartitioning.php
index 7712e82b3a..5473d20a49 100644
--- a/core/TablePartitioning.php
+++ b/core/TablePartitioning.php
@@ -23,8 +23,7 @@ abstract class Piwik_TablePartitioning
 	protected $tableName = null;
 	protected $generatedTableName = null;
 	protected $timestamp = null;
-	protected $idSite = null;
-	
+
 	static public $tablesAlreadyInstalled = null;
 	
 	public function __construct( $tableName )
@@ -40,11 +39,6 @@ abstract class Piwik_TablePartitioning
 		$this->generatedTableName = null;
 		$this->getTableName();
 	}
-	
-	public function setIdSite($idSite)
-	{
-		$this->idSite = $idSite;
-	}
 		
 	public function getTableName()
 	{
diff --git a/tests/integration/Main.test.php b/tests/integration/Main.test.php
index 20fb76011f..399368d126 100644
--- a/tests/integration/Main.test.php
+++ b/tests/integration/Main.test.php
@@ -580,8 +580,38 @@ class Test_Piwik_Integration_Main extends Test_Integration
 	private function doTest_TwoVisitors_twoWebsites_differentDays(
 		$function, $apiToCall, $allowConversions = false, $testGetProcessedReport = true)
 	{
-		// tests run in UTC, the Tracker in UTC
     	$dateTime = '2010-01-03 11:22:33';
+		$idSites = $this->setup_TwoVisitors_twoWebsites_differentDays($dateTime, $allowConversions);
+    	$this->setApiToCall($apiToCall);
+        
+    	$periods = array('day', 'week', 'month', 'year');
+    	// Request data for the last 6 periods and idSite=all
+        $this->callGetApiCompareOutput($function, 'xml', $allSites = 'all', $dateTime, $periods, $setDateLastN = true);
+        
+    	// Request data for the last 6 periods and idSite=1
+        $this->callGetApiCompareOutput($function.'_idSiteOne_', 'xml', $idSites[0], $dateTime, array('day','week','month','year'), $setDateLastN = true);
+        
+        // We also test a single period to check that this use case (Reports per idSite in the response) works
+    	$this->setApiToCall(array('VisitsSummary.get', 'Goals.get'));
+    	$this->callGetApiCompareOutput($function . '_NotLastNPeriods', 'xml', $allSites = 'all', $dateTime, array('day', 'month'), $setDateLastN = false);
+		
+		// testing metadata API for multiple periods
+		$this->setApiNotToCall(array());
+		if ($testGetProcessedReport)
+		{
+			$this->setApiToCall( array('API.getProcessedReport'	) );
+		}
+		$apiToCall = array_diff($apiToCall, array('Actions.getPageTitle', 'Actions.getPageUrl'));
+		foreach($apiToCall as $api)
+		{
+			list($apiModule, $apiAction) = explode(".", $api);
+			$this->callGetApiCompareOutput($function . '_'.$api.'_firstSite_lastN', 'xml', $idSites[0], $dateTime, $periods = array('day'), $setDateLastN = true, $language = false, $segment = false, $visitorId = false, $abandonedCarts = false, $idGoal = false, $apiModule, $apiAction);
+		}
+	}
+	
+	private function setup_TwoVisitors_twoWebsites_differentDays($dateTime, $allowConversions = false)
+	{
+		// tests run in UTC, the Tracker in UTC
     	$idSite = $this->createWebsite($dateTime);
     	$idSite2 = $this->createWebsite($dateTime);
     	if ($allowConversions)
@@ -589,7 +619,6 @@ class Test_Piwik_Integration_Main extends Test_Integration
     		Piwik_Goals_API::getInstance()->addGoal($idSite, 'all', 'url', 'http', 'contains');
     		Piwik_Goals_API::getInstance()->addGoal($idSite2, 'all', 'url', 'http', 'contains');
     	}
-    	$this->setApiToCall($apiToCall);
     	// -
     	// First visitor on Idsite 1: two page views
     	$datetimeSpanOverTwoDays = '2010-01-03 23:55:00'; 
@@ -659,30 +688,35 @@ class Test_Piwik_Integration_Main extends Test_Integration
 //        $t2->setUrlReferrer('http://www.baidu.com/s?wd=%D0%C2+%CE%C5&n=2');
 //        $t2->setUrl('http://example2.com/home');
 //        $this->checkResponse($t2->doTrackPageView('I\'m a returning visitor...'));
-        
-    	$periods = array('day', 'week', 'month', 'year');
-    	// Request data for the last 6 periods and idSite=all
-        $this->callGetApiCompareOutput($function, 'xml', $allSites = 'all', $dateTime, $periods, $setDateLastN = true);
-        
-    	// Request data for the last 6 periods and idSite=1
-        $this->callGetApiCompareOutput($function.'_idSiteOne_', 'xml', $idSite, $dateTime, array('day','week','month','year'), $setDateLastN = true);
-        
-        // We also test a single period to check that this use case (Reports per idSite in the response) works
-    	$this->setApiToCall(array('VisitsSummary.get', 'Goals.get'));
-    	$this->callGetApiCompareOutput($function . '_NotLastNPeriods', 'xml', $allSites = 'all', $dateTime, array('day', 'month'), $setDateLastN = false);
+		return array($idSite, $idSite2);
+	}
+	
+	public function test_TwoVisitors_twoWebsites_differentDays_ArchivingDisabled()
+	{
+		$apiToCall = array('VisitsSummary.get');
+
+    	$dateTime = '2010-01-03 11:22:33';
+		$periods = array('day', 'week', 'month', 'year');
+		$idSites = $this->setup_TwoVisitors_twoWebsites_differentDays($dateTime, false);
+		$this->setApiToCall($apiToCall);
 		
-		// testing metadata API for multiple periods
-		$this->setApiNotToCall(array());
-		if ($testGetProcessedReport)
-		{
-			$this->setApiToCall( array('API.getProcessedReport'	) );
-		}
-		$apiToCall = array_diff($apiToCall, array('Actions.getPageTitle', 'Actions.getPageUrl'));
-		foreach($apiToCall as $api)
-		{
-			list($apiModule, $apiAction) = explode(".", $api);
-			$this->callGetApiCompareOutput($function . '_'.$api.'_firstSite_lastN', 'xml', $idSite, $dateTime, $periods = array('day'), $setDateLastN = true, $language = false, $segment = false, $visitorId = false, $abandonedCarts = false, $idGoal = false, $apiModule, $apiAction);
-		}
+		// disable archiving & check that there is no archive data
+		Piwik_ArchiveProcessing::$forceDisableArchiving = true;
+
+		$this->callGetApiCompareOutput(__FUNCTION__ . '_disabledBefore', 'xml', $allSites = 'all', $dateTime, $periods);
+
+		// re-enable archiving & check the output
+		Piwik_ArchiveProcessing::$forceDisableArchiving = false;
+
+		$this->callGetApiCompareOutput(__FUNCTION__ . '_enabled', 'xml', $allSites = 'all', $dateTime, $periods);
+
+		// disable archiving again & check the output
+		Piwik_ArchiveProcessing::$forceDisableArchiving = true;
+
+		$this->callGetApiCompareOutput(__FUNCTION__ . '_disabledAfter', 'xml', $allSites = 'all', $dateTime, $periods);
+		
+		// re-enable archiving
+		Piwik_ArchiveProcessing::$forceDisableArchiving = false;
 	}
 	
 	private function doTest_twoVisitsWithCustomVariables($dateTime, $width=1111, $height=222)
diff --git a/tests/integration/expected/test_TwoVisitors_twoWebsites_differentDays_ArchivingDisabled_disabledAfter__VisitsSummary.get_day.xml b/tests/integration/expected/test_TwoVisitors_twoWebsites_differentDays_ArchivingDisabled_disabledAfter__VisitsSummary.get_day.xml
new file mode 100755
index 0000000000..c01069b78a
--- /dev/null
+++ b/tests/integration/expected/test_TwoVisitors_twoWebsites_differentDays_ArchivingDisabled_disabledAfter__VisitsSummary.get_day.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<results>
+	<result idSite="1">
+		<bounce_count>1</bounce_count>
+		<max_actions>1</max_actions>
+		<nb_actions>1</nb_actions>
+		<nb_uniq_visitors>1</nb_uniq_visitors>
+		<nb_visits>1</nb_visits>
+		<bounce_rate>100%</bounce_rate>
+		<nb_actions_per_visit>1</nb_actions_per_visit>
+		<avg_time_on_site>0</avg_time_on_site>
+	</result>
+	<result idSite="2" />
+</results>
\ No newline at end of file
diff --git a/tests/integration/expected/test_TwoVisitors_twoWebsites_differentDays_ArchivingDisabled_disabledAfter__VisitsSummary.get_month.xml b/tests/integration/expected/test_TwoVisitors_twoWebsites_differentDays_ArchivingDisabled_disabledAfter__VisitsSummary.get_month.xml
new file mode 100755
index 0000000000..4cc41d864e
--- /dev/null
+++ b/tests/integration/expected/test_TwoVisitors_twoWebsites_differentDays_ArchivingDisabled_disabledAfter__VisitsSummary.get_month.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<results>
+	<result idSite="1">
+		<bounce_count>1</bounce_count>
+		<max_actions>5</max_actions>
+		<nb_actions>8</nb_actions>
+		<nb_uniq_visitors>2</nb_uniq_visitors>
+		<nb_visits>3</nb_visits>
+		<sum_visit_length>1262</sum_visit_length>
+		<bounce_rate>33%</bounce_rate>
+		<nb_actions_per_visit>2.7</nb_actions_per_visit>
+		<avg_time_on_site>421</avg_time_on_site>
+	</result>
+	<result idSite="2">
+		<max_actions>2</max_actions>
+		<nb_actions>2</nb_actions>
+		<nb_uniq_visitors>1</nb_uniq_visitors>
+		<nb_visits>1</nb_visits>
+		<sum_visit_length>1</sum_visit_length>
+		<bounce_rate>0%</bounce_rate>
+		<nb_actions_per_visit>2</nb_actions_per_visit>
+		<avg_time_on_site>1</avg_time_on_site>
+	</result>
+</results>
\ No newline at end of file
diff --git a/tests/integration/expected/test_TwoVisitors_twoWebsites_differentDays_ArchivingDisabled_disabledAfter__VisitsSummary.get_week.xml b/tests/integration/expected/test_TwoVisitors_twoWebsites_differentDays_ArchivingDisabled_disabledAfter__VisitsSummary.get_week.xml
new file mode 100755
index 0000000000..524f36b46d
--- /dev/null
+++ b/tests/integration/expected/test_TwoVisitors_twoWebsites_differentDays_ArchivingDisabled_disabledAfter__VisitsSummary.get_week.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<results>
+	<result idSite="1">
+		<nb_uniq_visitors>1</nb_uniq_visitors>
+		<nb_visits>1</nb_visits>
+		<nb_actions>1</nb_actions>
+		<bounce_count>1</bounce_count>
+		<max_actions>1</max_actions>
+		<bounce_rate>100%</bounce_rate>
+		<nb_actions_per_visit>1</nb_actions_per_visit>
+		<avg_time_on_site>0</avg_time_on_site>
+	</result>
+	<result idSite="2" />
+</results>
\ No newline at end of file
diff --git a/tests/integration/expected/test_TwoVisitors_twoWebsites_differentDays_ArchivingDisabled_disabledAfter__VisitsSummary.get_year.xml b/tests/integration/expected/test_TwoVisitors_twoWebsites_differentDays_ArchivingDisabled_disabledAfter__VisitsSummary.get_year.xml
new file mode 100755
index 0000000000..c0e9dad200
--- /dev/null
+++ b/tests/integration/expected/test_TwoVisitors_twoWebsites_differentDays_ArchivingDisabled_disabledAfter__VisitsSummary.get_year.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<results>
+	<result idSite="1">
+		<bounce_count>1</bounce_count>
+		<max_actions>5</max_actions>
+		<nb_actions>8</nb_actions>
+		<nb_visits>3</nb_visits>
+		<sum_visit_length>1262</sum_visit_length>
+		<bounce_rate>33%</bounce_rate>
+		<nb_actions_per_visit>2.7</nb_actions_per_visit>
+		<avg_time_on_site>421</avg_time_on_site>
+	</result>
+	<result idSite="2">
+		<max_actions>2</max_actions>
+		<nb_actions>2</nb_actions>
+		<nb_visits>1</nb_visits>
+		<sum_visit_length>1</sum_visit_length>
+		<bounce_rate>0%</bounce_rate>
+		<nb_actions_per_visit>2</nb_actions_per_visit>
+		<avg_time_on_site>1</avg_time_on_site>
+	</result>
+</results>
\ No newline at end of file
diff --git a/tests/integration/expected/test_TwoVisitors_twoWebsites_differentDays_ArchivingDisabled_disabledBefore__VisitsSummary.get_day.xml b/tests/integration/expected/test_TwoVisitors_twoWebsites_differentDays_ArchivingDisabled_disabledBefore__VisitsSummary.get_day.xml
new file mode 100755
index 0000000000..1c7f2179e5
--- /dev/null
+++ b/tests/integration/expected/test_TwoVisitors_twoWebsites_differentDays_ArchivingDisabled_disabledBefore__VisitsSummary.get_day.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<results>
+	<result idSite="1" />
+	<result idSite="2" />
+</results>
\ No newline at end of file
diff --git a/tests/integration/expected/test_TwoVisitors_twoWebsites_differentDays_ArchivingDisabled_disabledBefore__VisitsSummary.get_month.xml b/tests/integration/expected/test_TwoVisitors_twoWebsites_differentDays_ArchivingDisabled_disabledBefore__VisitsSummary.get_month.xml
new file mode 100755
index 0000000000..1c7f2179e5
--- /dev/null
+++ b/tests/integration/expected/test_TwoVisitors_twoWebsites_differentDays_ArchivingDisabled_disabledBefore__VisitsSummary.get_month.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<results>
+	<result idSite="1" />
+	<result idSite="2" />
+</results>
\ No newline at end of file
diff --git a/tests/integration/expected/test_TwoVisitors_twoWebsites_differentDays_ArchivingDisabled_disabledBefore__VisitsSummary.get_week.xml b/tests/integration/expected/test_TwoVisitors_twoWebsites_differentDays_ArchivingDisabled_disabledBefore__VisitsSummary.get_week.xml
new file mode 100755
index 0000000000..1c7f2179e5
--- /dev/null
+++ b/tests/integration/expected/test_TwoVisitors_twoWebsites_differentDays_ArchivingDisabled_disabledBefore__VisitsSummary.get_week.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<results>
+	<result idSite="1" />
+	<result idSite="2" />
+</results>
\ No newline at end of file
diff --git a/tests/integration/expected/test_TwoVisitors_twoWebsites_differentDays_ArchivingDisabled_disabledBefore__VisitsSummary.get_year.xml b/tests/integration/expected/test_TwoVisitors_twoWebsites_differentDays_ArchivingDisabled_disabledBefore__VisitsSummary.get_year.xml
new file mode 100755
index 0000000000..1c7f2179e5
--- /dev/null
+++ b/tests/integration/expected/test_TwoVisitors_twoWebsites_differentDays_ArchivingDisabled_disabledBefore__VisitsSummary.get_year.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<results>
+	<result idSite="1" />
+	<result idSite="2" />
+</results>
\ No newline at end of file
diff --git a/tests/integration/expected/test_TwoVisitors_twoWebsites_differentDays_ArchivingDisabled_enabled__VisitsSummary.get_day.xml b/tests/integration/expected/test_TwoVisitors_twoWebsites_differentDays_ArchivingDisabled_enabled__VisitsSummary.get_day.xml
new file mode 100755
index 0000000000..c01069b78a
--- /dev/null
+++ b/tests/integration/expected/test_TwoVisitors_twoWebsites_differentDays_ArchivingDisabled_enabled__VisitsSummary.get_day.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<results>
+	<result idSite="1">
+		<bounce_count>1</bounce_count>
+		<max_actions>1</max_actions>
+		<nb_actions>1</nb_actions>
+		<nb_uniq_visitors>1</nb_uniq_visitors>
+		<nb_visits>1</nb_visits>
+		<bounce_rate>100%</bounce_rate>
+		<nb_actions_per_visit>1</nb_actions_per_visit>
+		<avg_time_on_site>0</avg_time_on_site>
+	</result>
+	<result idSite="2" />
+</results>
\ No newline at end of file
diff --git a/tests/integration/expected/test_TwoVisitors_twoWebsites_differentDays_ArchivingDisabled_enabled__VisitsSummary.get_month.xml b/tests/integration/expected/test_TwoVisitors_twoWebsites_differentDays_ArchivingDisabled_enabled__VisitsSummary.get_month.xml
new file mode 100755
index 0000000000..4cc41d864e
--- /dev/null
+++ b/tests/integration/expected/test_TwoVisitors_twoWebsites_differentDays_ArchivingDisabled_enabled__VisitsSummary.get_month.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<results>
+	<result idSite="1">
+		<bounce_count>1</bounce_count>
+		<max_actions>5</max_actions>
+		<nb_actions>8</nb_actions>
+		<nb_uniq_visitors>2</nb_uniq_visitors>
+		<nb_visits>3</nb_visits>
+		<sum_visit_length>1262</sum_visit_length>
+		<bounce_rate>33%</bounce_rate>
+		<nb_actions_per_visit>2.7</nb_actions_per_visit>
+		<avg_time_on_site>421</avg_time_on_site>
+	</result>
+	<result idSite="2">
+		<max_actions>2</max_actions>
+		<nb_actions>2</nb_actions>
+		<nb_uniq_visitors>1</nb_uniq_visitors>
+		<nb_visits>1</nb_visits>
+		<sum_visit_length>1</sum_visit_length>
+		<bounce_rate>0%</bounce_rate>
+		<nb_actions_per_visit>2</nb_actions_per_visit>
+		<avg_time_on_site>1</avg_time_on_site>
+	</result>
+</results>
\ No newline at end of file
diff --git a/tests/integration/expected/test_TwoVisitors_twoWebsites_differentDays_ArchivingDisabled_enabled__VisitsSummary.get_week.xml b/tests/integration/expected/test_TwoVisitors_twoWebsites_differentDays_ArchivingDisabled_enabled__VisitsSummary.get_week.xml
new file mode 100755
index 0000000000..c01069b78a
--- /dev/null
+++ b/tests/integration/expected/test_TwoVisitors_twoWebsites_differentDays_ArchivingDisabled_enabled__VisitsSummary.get_week.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<results>
+	<result idSite="1">
+		<bounce_count>1</bounce_count>
+		<max_actions>1</max_actions>
+		<nb_actions>1</nb_actions>
+		<nb_uniq_visitors>1</nb_uniq_visitors>
+		<nb_visits>1</nb_visits>
+		<bounce_rate>100%</bounce_rate>
+		<nb_actions_per_visit>1</nb_actions_per_visit>
+		<avg_time_on_site>0</avg_time_on_site>
+	</result>
+	<result idSite="2" />
+</results>
\ No newline at end of file
diff --git a/tests/integration/expected/test_TwoVisitors_twoWebsites_differentDays_ArchivingDisabled_enabled__VisitsSummary.get_year.xml b/tests/integration/expected/test_TwoVisitors_twoWebsites_differentDays_ArchivingDisabled_enabled__VisitsSummary.get_year.xml
new file mode 100755
index 0000000000..c0e9dad200
--- /dev/null
+++ b/tests/integration/expected/test_TwoVisitors_twoWebsites_differentDays_ArchivingDisabled_enabled__VisitsSummary.get_year.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<results>
+	<result idSite="1">
+		<bounce_count>1</bounce_count>
+		<max_actions>5</max_actions>
+		<nb_actions>8</nb_actions>
+		<nb_visits>3</nb_visits>
+		<sum_visit_length>1262</sum_visit_length>
+		<bounce_rate>33%</bounce_rate>
+		<nb_actions_per_visit>2.7</nb_actions_per_visit>
+		<avg_time_on_site>421</avg_time_on_site>
+	</result>
+	<result idSite="2">
+		<max_actions>2</max_actions>
+		<nb_actions>2</nb_actions>
+		<nb_visits>1</nb_visits>
+		<sum_visit_length>1</sum_visit_length>
+		<bounce_rate>0%</bounce_rate>
+		<nb_actions_per_visit>2</nb_actions_per_visit>
+		<avg_time_on_site>1</avg_time_on_site>
+	</result>
+</results>
\ No newline at end of file
-- 
GitLab