Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/matomo-org/matomo.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordizzy <diosmosis@users.noreply.github.com>2021-04-12 06:23:28 +0300
committerGitHub <noreply@github.com>2021-04-12 06:23:28 +0300
commit5573d22a459d65749ebdfc257ac773979ae12ea4 (patch)
treed3eac59ac3228b0e31848ab170bea793c43b03a5
parent375af64031844e6161d8ce6e778da304e0680230 (diff)
Initiate range archiving if an archive is invalidated, the request is from the browser, and browser archiving is authorized (#17379)
* Initiate archiving if an archive is invalidated, the request is from the browser, and browser archiving for the current request is authorized. * add test that was strangely removed and add tests for period = range * Add test for tracking data in the past and fix invalidation issue in core:archive. * Add test for default use case of core:archive w/ browser initiated range archiving. * actually just dont perform the check if the period does not include today * undo isPeriodIncludesToday change * Fix ArchiveInvalidationTest and get to work, fix bug in Loader causing it to fail * fix tests * add comment to test * Fix CronArchiveTest, make sure we do not use a TTL when running invalidateRecentDate("yesterday"). * tweak comment * make sure invalid ranges only rearchive when authorized to rearchive child archive or when all child archives are usable while still respecting ttl for periods that include today * instead of previous change, make range ttl get respected if range period is used and archiving is enabled for the current request/period * remove dead code + tweak test * add check for invalidated archive * move new invalidation check to Loader from ArchiveSelector since getArchiveIdAndVisits is used in multiple code paths now * remove TODO * remove use * apply pr feedback * get tests to pass * Fix strange test failure on travis-ci (class was loaded before mock file methods used in next test were loaded)
-rw-r--r--core/Archive.php2
-rw-r--r--core/ArchiveProcessor/Loader.php72
-rw-r--r--core/ArchiveProcessor/Parameters.php2
-rw-r--r--core/ArchiveProcessor/Rules.php6
-rw-r--r--core/CronArchive.php25
-rw-r--r--core/DataAccess/ArchiveSelector.php11
-rw-r--r--plugins/CoreConsole/tests/System/ArchiveCronTest.php87
-rw-r--r--plugins/CoreConsole/tests/System/expected/test_ArchiveCronTest_noOptions__Goals.get_month.xml14
-rw-r--r--plugins/CoreConsole/tests/System/expected/test_ArchiveCronTest_noOptions__VisitFrequency.get_month.xml10
-rw-r--r--plugins/CoreConsole/tests/System/expected/test_ArchiveCronTest_noOptions__VisitsSummary.get_day.xml10
-rw-r--r--plugins/CoreConsole/tests/System/expected/test_ArchiveCronTest_noOptions__VisitsSummary.get_month.xml10
-rw-r--r--plugins/CoreConsole/tests/System/expected/test_ArchiveCronTest_noOptions__VisitsSummary.get_week.xml12
-rw-r--r--plugins/CoreConsole/tests/System/expected/test_ArchiveCronTest_noOptions__VisitsSummary.get_year.xml12
-rw-r--r--plugins/CoreConsole/tests/System/expected/test_ArchiveCronTest_range_archive__Actions.get_range.xml4
-rw-r--r--plugins/CoreConsole/tests/System/expected/test_ArchiveCronTest_range_archive__DevicesDetection.getType_range.xml20
-rw-r--r--plugins/CoreConsole/tests/System/expected/test_ArchiveCronTest_range_archive__VisitsSummary.get_range.xml10
-rw-r--r--plugins/CoreConsole/tests/System/expected/test_ArchiveCronTest_range_archive_before_invalidate__Actions.get_range.xml11
-rw-r--r--plugins/CoreConsole/tests/System/expected/test_ArchiveCronTest_range_archive_before_invalidate__DevicesDetection.getType_range.xml140
-rw-r--r--plugins/CoreConsole/tests/System/expected/test_ArchiveCronTest_range_archive_before_invalidate__VisitsSummary.get_range.xml12
-rw-r--r--plugins/CoreConsole/tests/System/expected/test_ArchiveCronTest_range_archive_rearchived__Actions.get_range.xml11
-rw-r--r--plugins/CoreConsole/tests/System/expected/test_ArchiveCronTest_range_archive_rearchived__DevicesDetection.getType_range.xml140
-rw-r--r--plugins/CoreConsole/tests/System/expected/test_ArchiveCronTest_range_archive_rearchived__VisitsSummary.get_range.xml12
-rw-r--r--tests/PHPUnit/Framework/Fixture.php2
-rw-r--r--tests/PHPUnit/Framework/TestCase/SystemTestCase.php6
-rw-r--r--tests/PHPUnit/Framework/TestingEnvironmentVariables.php5
-rw-r--r--tests/PHPUnit/Integration/ArchiveProcessor/LoaderTest.php16
-rw-r--r--tests/PHPUnit/Integration/ArchiveTest.php195
-rw-r--r--tests/PHPUnit/Integration/CronArchiveTest.php31
-rw-r--r--tests/PHPUnit/Integration/DataAccess/ArchiveSelectorTest.php119
-rw-r--r--tests/PHPUnit/System/ArchiveInvalidationTest.php53
-rw-r--r--tests/PHPUnit/System/expected/test_Archive_InvalidationWebsite2_NewDataShouldAppear__Actions.getPageUrls_day.xml32
-rw-r--r--tests/PHPUnit/System/expected/test_Archive_InvalidationWebsite2_NewDataShouldAppear__Actions.getPageUrls_month.xml32
-rw-r--r--tests/PHPUnit/System/expected/test_Archive_InvalidationWebsite2_NewDataShouldAppear__VisitsSummary.get_day.xml6
-rw-r--r--tests/PHPUnit/System/expected/test_Archive_InvalidationWebsite2_NewDataShouldAppear__VisitsSummary.get_month.xml6
34 files changed, 971 insertions, 165 deletions
diff --git a/core/Archive.php b/core/Archive.php
index f1398266b2..0c0651a029 100644
--- a/core/Archive.php
+++ b/core/Archive.php
@@ -565,7 +565,7 @@ class Archive implements ArchiveQuery
// cache id archives for plugins we haven't processed yet
if (!empty($archiveGroups)) {
- if (!Rules::isArchivingDisabledFor($this->params->getIdSites(), $this->params->getSegment(), $this->getPeriodLabel())
+ if (Rules::isArchivingEnabledFor($this->params->getIdSites(), $this->params->getSegment(), $this->getPeriodLabel())
&& !$this->forceFetchingWithoutLaunchingArchiving
) {
$this->cacheArchiveIdsAfterLaunching($archiveGroups, $plugins);
diff --git a/core/ArchiveProcessor/Loader.php b/core/ArchiveProcessor/Loader.php
index ee764cff83..4180f659b8 100644
--- a/core/ArchiveProcessor/Loader.php
+++ b/core/ArchiveProcessor/Loader.php
@@ -16,10 +16,12 @@ use Piwik\Container\StaticContainer;
use Piwik\Context;
use Piwik\DataAccess\ArchiveSelector;
use Piwik\DataAccess\ArchiveTableCreator;
+use Piwik\DataAccess\ArchiveWriter;
use Piwik\DataAccess\Model;
use Piwik\DataAccess\RawLogDao;
use Piwik\Date;
use Piwik\Db;
+use Piwik\Option;
use Piwik\Period;
use Piwik\Piwik;
use Piwik\SettingsServer;
@@ -113,12 +115,21 @@ class Loader
}
}
+ // invalidate existing archives before we start archiving in case data was tracked in the past. if the archive is
+ // made invalid, we will correctly re-archive below.
+ if ($this->invalidateBeforeArchiving
+ && Rules::isBrowserTriggerEnabled()
+ ) {
+ $this->invalidatedReportsIfNeeded();
+ }
+
// NOTE: $idArchives will contain the latest DONE_OK/DONE_INVALIDATED archive as well as any partial archives
// with a ts_archived >= the DONE_OK/DONE_INVALIDATED date.
- list($idArchives, $visits, $visitsConverted, $isAnyArchiveExists) = $this->loadExistingArchiveIdFromDb();
+ list($idArchives, $visits, $visitsConverted, $isAnyArchiveExists, $tsArchived, $value) = $this->loadExistingArchiveIdFromDb();
if (!empty($idArchives)
&& !$this->params->getArchiveOnlyReport()
&& !Rules::isForceArchivingSinglePlugin()
+ && !$this->shouldForceInvalidatedArchive($value, $tsArchived)
) {
// we have a usable idarchive (it's not invalidated and it's new enough), and we are not archiving
// a single report
@@ -135,14 +146,6 @@ class Loader
return [false, 0];
}
- // if there is an archive, but we can't use it for some reason, invalidate existing archives before
- // we start archiving. if the archive is made invalid, we will correctly re-archive below.
- if ($this->invalidateBeforeArchiving
- && $isAnyArchiveExists
- ) {
- $this->invalidatedReportsIfNeeded();
- }
-
if (SettingsServer::isArchivePhpTriggered()) {
$this->logger->info("initiating archiving via core:archive for " . $this->params);
}
@@ -257,7 +260,7 @@ class Loader
// return no usable archive found, and no existing archive. this will skip invalidation, which should
// be fine since we just force archiving.
- return [false, false, false, false];
+ return [false, false, false, false, false, false];
}
$minDatetimeArchiveProcessedUTC = $this->getMinTimeArchiveProcessed();
@@ -272,11 +275,18 @@ class Loader
*/
protected function getMinTimeArchiveProcessed()
{
- $endDateTimestamp = self::determineIfArchivePermanent($this->params->getDateEnd());
- if ($endDateTimestamp) {
- // past archive
- return $endDateTimestamp;
+ // for range periods we can archive in a browser request request, make sure to check for the ttl no matter what
+ $isRangeArchiveAndArchivingEnabled = $this->params->getPeriod()->getLabel() == 'range'
+ && Rules::isArchivingEnabledFor([$this->params->getSite()->getId()], $this->params->getSegment(), $this->params->getPeriod()->getLabel());
+
+ if (!$isRangeArchiveAndArchivingEnabled) {
+ $endDateTimestamp = self::determineIfArchivePermanent($this->params->getDateEnd());
+ if ($endDateTimestamp) {
+ // past archive
+ return $endDateTimestamp;
+ }
}
+
$dateStart = $this->params->getDateStart();
$period = $this->params->getPeriod();
$segment = $this->params->getSegment();
@@ -429,4 +439,38 @@ class Loader
{
return self::$archivingDepth;
}
+
+ private function shouldForceInvalidatedArchive($value, $tsArchived)
+ {
+ $params = $this->params;
+
+ // the archive is invalidated and we are in a browser request that is allowed archive it
+ if ($value == ArchiveWriter::DONE_INVALIDATED
+ && Rules::isArchivingEnabledFor([$params->getSite()->getId()], $params->getSegment(), $params->getPeriod()->getLabel())
+ ) {
+ // if coming from core:archive, force rearchiving, since if we don't the entry will be removed from archive_invalidations
+ // w/o being rearchived
+ if (SettingsServer::isArchivePhpTriggered()) {
+ return true;
+ }
+
+ // if coming from a browser request, and period does not contain today, force rearchiving
+ $timezone = $params->getSite()->getTimezone();
+ if (!$params->getPeriod()->isDateInPeriod(Date::factoryInTimezone('today', $timezone))) {
+ return true;
+ }
+
+ // if coming from a browser request, and period does contain today, check the ttl for the period (done just below this)
+ $minDatetimeArchiveProcessedUTC = Rules::getMinTimeProcessedForInProgressArchive(
+ $params->getDateStart(), $params->getPeriod(), $params->getSegment(), $params->getSite());
+ $minDatetimeArchiveProcessedUTC = Date::factory($minDatetimeArchiveProcessedUTC);
+ if ($minDatetimeArchiveProcessedUTC
+ && Date::factory($tsArchived)->isEarlier($minDatetimeArchiveProcessedUTC)
+ ) {
+ return false;
+ }
+ }
+
+ return false;
+ }
}
diff --git a/core/ArchiveProcessor/Parameters.php b/core/ArchiveProcessor/Parameters.php
index 127064b071..c328170637 100644
--- a/core/ArchiveProcessor/Parameters.php
+++ b/core/ArchiveProcessor/Parameters.php
@@ -308,7 +308,7 @@ class Parameters
*/
public function isPartialArchive()
{
- if (!$this->getRequestedPlugin()) { // sanity check, partial archives are only for
+ if (!$this->getRequestedPlugin()) { // sanity check, partial archives are only for single reports
return false;
}
diff --git a/core/ArchiveProcessor/Rules.php b/core/ArchiveProcessor/Rules.php
index d179718da7..27d505a7ea 100644
--- a/core/ArchiveProcessor/Rules.php
+++ b/core/ArchiveProcessor/Rules.php
@@ -12,6 +12,7 @@ use Exception;
use Piwik\Common;
use Piwik\Config;
use Piwik\DataAccess\ArchiveWriter;
+use Piwik\DataAccess\Model;
use Piwik\Date;
use Piwik\Log;
use Piwik\Option;
@@ -196,6 +197,11 @@ class Rules
return !$generalConfig['browser_archiving_disabled_enforce'];
}
+ public static function isArchivingEnabledFor(array $idSites, Segment $segment, $periodLabel)
+ {
+ return !self::isArchivingDisabledFor($idSites, $segment, $periodLabel);
+ }
+
public static function isArchivingDisabledFor(array $idSites, Segment $segment, $periodLabel)
{
$generalConfig = Config::getInstance()->General;
diff --git a/core/CronArchive.php b/core/CronArchive.php
index 0475067ce9..ddbc74e743 100644
--- a/core/CronArchive.php
+++ b/core/CronArchive.php
@@ -857,10 +857,14 @@ class CronArchive
'date' => $date->getDatetime(),
]);
- $this->invalidateWithSegments([$idSite], $date->toString(), 'day');
+ // if we are invalidating yesterday here, we are only interested in checking if there is no archive for yesterday, or the day has changed since
+ // the last archive was archived (in which there may have been more visits before midnight). so we disable the ttl check, since any archive
+ // will be good enough, if the date hasn't changed.
+ $isYesterday = $dateStr == 'yesterday';
+ $this->invalidateWithSegments([$idSite], $date->toString(), 'day', false, $doNotIncludeTtlInExistingArchiveCheck = $isYesterday);
}
- private function invalidateWithSegments($idSites, $date, $period, $_forceInvalidateNonexistant = false)
+ private function invalidateWithSegments($idSites, $date, $period, $_forceInvalidateNonexistant = false, $doNotIncludeTtlInExistingArchiveCheck = false)
{
if ($date instanceof Date) {
$date = $date->toString();
@@ -878,7 +882,7 @@ class CronArchive
foreach ($idSites as $idSite) {
$params = new Parameters(new Site($idSite), $periodObj, new Segment('', [$idSite], $periodObj->getDateStart(), $periodObj->getDateEnd()));
- if ($this->isThereExistingValidPeriod($params)) {
+ if ($this->canWeSkipInvalidatingBecauseThereIsAUsablePeriod($params, $doNotIncludeTtlInExistingArchiveCheck)) {
$this->logger->debug(' Found usable archive for {archive}, skipping invalidation.', ['archive' => $params]);
} else {
$this->getApiToInvalidateArchivedReport()->invalidateArchivedReports($idSite, $date, $period, $segment = false, $cascadeDown = false,
@@ -887,7 +891,7 @@ class CronArchive
foreach ($this->segmentArchiving->getAllSegmentsToArchive($idSite) as $segmentDefinition) {
$params = new Parameters(new Site($idSite), $periodObj, new Segment(urlencode($segmentDefinition), [$idSite], $periodObj->getDateStart(), $periodObj->getDateEnd()));
- if ($this->isThereExistingValidPeriod($params)) {
+ if ($this->canWeSkipInvalidatingBecauseThereIsAUsablePeriod($params, $doNotIncludeTtlInExistingArchiveCheck)) {
$this->logger->debug(' Found usable archive for {archive}, skipping invalidation.', ['archive' => $params]);
} else {
$this->getApiToInvalidateArchivedReport()->invalidateArchivedReports($idSite, $date, $period, urlencode($segmentDefinition),
@@ -897,14 +901,23 @@ class CronArchive
}
}
- public function isThereExistingValidPeriod(Parameters $params)
+ /**
+ * Returns true if there is an existing valid period we can use, or false if there isn't and the invalidation should go through.
+ *
+ * Note: this method should only be used in the context of invalidation.
+ *
+ * @params Parameters $params The parameters for the archive we want to invalidate.
+ */
+ public function canWeSkipInvalidatingBecauseThereIsAUsablePeriod(Parameters $params, $doNotIncludeTtlInExistingArchiveCheck = false)
{
$today = Date::factoryInTimezone('today', Site::getTimezoneFor($params->getSite()->getId()));
$isYesterday = $params->getPeriod()->getLabel() == 'day' && $params->getPeriod()->getDateStart()->toString() == Date::factory('yesterday')->toString();
$isPeriodIncludesToday = $params->getPeriod()->isDateInPeriod($today);
- $minArchiveProcessedTime = $isPeriodIncludesToday ? Date::now()->subSeconds(Rules::getPeriodArchiveTimeToLiveDefault($params->getPeriod()->getLabel())) : null;
+
+ $minArchiveProcessedTime = $doNotIncludeTtlInExistingArchiveCheck ? null :
+ Date::now()->subSeconds(Rules::getPeriodArchiveTimeToLiveDefault($params->getPeriod()->getLabel()));
// empty plugins param since we only check for an 'all' archive
list($idArchive, $visits, $visitsConverted, $ignore, $tsArchived) = ArchiveSelector::getArchiveIdAndVisits($params, $minArchiveProcessedTime, $includeInvalidated = $isPeriodIncludesToday);
diff --git a/core/DataAccess/ArchiveSelector.php b/core/DataAccess/ArchiveSelector.php
index e4147e90dd..1e7ad4117a 100644
--- a/core/DataAccess/ArchiveSelector.php
+++ b/core/DataAccess/ArchiveSelector.php
@@ -19,6 +19,7 @@ use Piwik\Db;
use Piwik\Period;
use Piwik\Period\Range;
use Piwik\Segment;
+use Piwik\SettingsServer;
/**
* Data Access object used to query archives
@@ -76,11 +77,12 @@ class ArchiveSelector
$requestedPluginDoneFlags = empty($requestedPlugin) ? [] : Rules::getDoneFlags([$requestedPlugin], $segment);
$allPluginsDoneFlag = Rules::getDoneFlagArchiveContainsAllPlugins($segment);
+
$doneFlagValues = Rules::getSelectableDoneFlagValues($includeInvalidated === null ? true : $includeInvalidated, $params, $includeInvalidated === null);
$results = self::getModel()->getArchiveIdAndVisits($numericTable, $idSite, $period, $dateStartIso, $dateEndIso, null, $doneFlags);
if (empty($results)) { // no archive found
- return [false, false, false, false, false];
+ return [false, false, false, false, false, false];
}
$result = self::findArchiveDataWithLatestTsArchived($results, $requestedPluginDoneFlags, $allPluginsDoneFlag);
@@ -88,6 +90,7 @@ class ArchiveSelector
$tsArchived = isset($result['ts_archived']) ? $result['ts_archived'] : false;
$visits = isset($result['nb_visits']) ? $result['nb_visits'] : false;
$visitsConverted = isset($result['nb_visits_converted']) ? $result['nb_visits_converted'] : false;
+ $value = isset($result['value']) ? $result['value'] : false;
$result['idarchive'] = empty($result['idarchive']) ? [] : [$result['idarchive']];
if (isset($result['partial'])) {
@@ -98,7 +101,7 @@ class ArchiveSelector
|| (isset($result['value'])
&& !in_array($result['value'], $doneFlagValues))
) { // the archive cannot be considered valid for this request (has wrong done flag value)
- return [false, $visits, $visitsConverted, true, $tsArchived];
+ return [false, $visits, $visitsConverted, true, $tsArchived, $value];
}
if (!empty($minDatetimeArchiveProcessedUTC) && !is_object($minDatetimeArchiveProcessedUTC)) {
@@ -110,12 +113,12 @@ class ArchiveSelector
&& !empty($result['idarchive'])
&& Date::factory($tsArchived)->isEarlier($minDatetimeArchiveProcessedUTC)
) {
- return [false, $visits, $visitsConverted, true, $tsArchived];
+ return [false, $visits, $visitsConverted, true, $tsArchived, $value];
}
$idArchives = !empty($result['idarchive']) ? $result['idarchive'] : false;
- return [$idArchives, $visits, $visitsConverted, true, $tsArchived];
+ return [$idArchives, $visits, $visitsConverted, true, $tsArchived, $value];
}
/**
diff --git a/plugins/CoreConsole/tests/System/ArchiveCronTest.php b/plugins/CoreConsole/tests/System/ArchiveCronTest.php
index cd9acd7db3..1872a55157 100644
--- a/plugins/CoreConsole/tests/System/ArchiveCronTest.php
+++ b/plugins/CoreConsole/tests/System/ArchiveCronTest.php
@@ -7,7 +7,11 @@
*/
namespace Piwik\Plugins\CoreConsole\tests\System;
+use Piwik\Archive\ArchivePurger;
+use Piwik\ArchiveProcessor\Rules;
use Piwik\CronArchive;
+use Piwik\DataAccess\ArchiveWriter;
+use Piwik\DataAccess\Model;
use Piwik\Http;
use Piwik\Plugins\SegmentEditor\API;
use Piwik\Site;
@@ -58,6 +62,21 @@ class ArchiveCronTest extends SystemTestCase
Site::clearCache();
}
+ private static function trackVisitInPast($ip = null)
+ {
+ $t = Fixture::getTracker(self::$fixture->idSite, '2012-08-09 16:00:00');
+ if ($ip) {
+ $t->setIp($ip);
+ }
+ $t->setUserAgent('Mozilla/5.0 (iPhone; CPU iPhone OS 12_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148');
+ $t->setUrl('http://pastwebsite.com/here/we/go');
+ Fixture::checkResponse($t->doTrackPageView('a page title'));
+
+ // update ts_archived for archives in 2012_08 so they will be invalidated and rearchived
+ $sql = "UPDATE " . ArchiveTableCreator::getNumericTable(Date::factory('2012-08-01')) . " SET ts_archived = ?";
+ Db::query($sql, [Date::now()->subHour(2)->getDatetime()]);
+ }
+
private static function addNewSegmentToPast()
{
Config::getInstance()->General['enable_browser_archiving_triggering'] = 0;
@@ -218,6 +237,7 @@ class ArchiveCronTest extends SystemTestCase
self::forceCurlCliMulti();
self::addNewSegmentToPast();
self::trackVisitsForToday();
+ self::trackVisitInPast(); // track in the past so we end up invalidating and rearchiving a past month
$output = $this->runArchivePhpCron();
} finally {
self::undoForceCurlCliMulti();
@@ -288,6 +308,9 @@ class ArchiveCronTest extends SystemTestCase
$this->assertEquals([5, 1], array_values($archiveValues));
}
+ /**
+ * @depends testArchivePhpCronWithSingleReportRearchive
+ */
public function testArchivePhpCronArchivesFullRanges()
{
self::$fixture->getTestEnvironment()->overrideConfig('General', 'enable_browser_archiving_triggering', 0);
@@ -319,6 +342,70 @@ class ArchiveCronTest extends SystemTestCase
);
}
+ /**
+ * @depends testArchivePhpCronArchivesFullRanges
+ */
+ public function testRangeBrowserArchivingWorksWhenInvalidatedByVisit()
+ {
+ self::$fixture->getTestEnvironment()->overrideConfig('General', 'enable_browser_archiving_triggering', 0);
+ // remove the value, since the default is to always force archiving on browser request
+ self::$fixture->getTestEnvironment()->removeOverriddenConfig('General', 'archiving_range_force_on_browser_request');
+ self::$fixture->getTestEnvironment()->save();
+
+ Config::getInstance()->General['enable_browser_archiving_triggering'] = 0;
+ unset(Config::getInstance()->General['archiving_range_force_on_browser_request']);
+
+ $table = ArchiveTableCreator::getNumericTable(Date::factory('2012-08-09'));
+ $blobTable = ArchiveTableCreator::getBlobTable(Date::factory('2012-08-09'));
+
+ // remove existing range archives
+ $idArchives = Db::fetchAll("SELECT DISTINCT idarchive FROM $table WHERE period = 5");
+ $idArchives = array_column($idArchives, 'idarchive');
+
+ $model = new Model();
+ $model->deleteArchiveIds($table, $blobTable, $idArchives);
+
+ // process archives once
+ $this->runApiTests(array(
+ 'VisitsSummary.get', 'Actions.get', 'DevicesDetection.getType'),
+ array('idSite' => '1',
+ 'date' => '2012-08-09,2012-08-13',
+ 'periods' => array('range'),
+ 'testSuffix' => '_range_archive_before_invalidate')
+ );
+
+ $this->trackVisitInPast($ip = '124.56.23.23');
+
+ $cronArchive = new CronArchive();
+ $cronArchive->init();
+ $cronArchive->invalidateArchivedReportsForSitesThatNeedToBeArchivedAgain(1);
+
+ // process day archive so range archive will process below (if we don't, then we'll skip processing the range archive,
+ // since it wouldn't trigger the child day archive. then later the day archive would be updated, and not the range, resulting
+ // in inaccurate data)
+ Rules::setBrowserTriggerArchiving(true);
+ \Piwik\Plugins\VisitsSummary\API::getInstance()->get(1, 'day', '2012-08-09');
+ Rules::setBrowserTriggerArchiving(false);
+
+ $rangeArchivesInvalid = Db::fetchAll("SELECT idarchive, name, date1, date2 FROM " . $table . " WHERE period = 5 and name LIKE 'done.%' and value = " . ArchiveWriter::DONE_INVALIDATED);
+ $this->assertNotEmpty($rangeArchivesInvalid);
+
+ // cron archive not run, but ranges should still be rearchived
+ $this->runApiTests(array(
+ 'VisitsSummary.get', 'Actions.get', 'DevicesDetection.getType'),
+ array('idSite' => '1',
+ 'date' => '2012-08-09,2012-08-13',
+ 'periods' => array('range'),
+ 'testSuffix' => '_range_archive_rearchived')
+ );
+
+ $archivePurger = StaticContainer::get(ArchivePurger::class);
+ $archivePurger->purgeInvalidatedArchivesFrom(Date::factory('2020-08-09'));
+
+ $rangeArchivesStillInvalid = Db::fetchAll("SELECT idarchive, name, date1, date2 FROM " . $table . " WHERE period = 5 and name = 'done.%' and value = " . ArchiveWriter::DONE_INVALIDATED);
+ $this->assertEmpty($rangeArchivesStillInvalid);
+ }
+
public function test_archivePhpScript_DoesNotFail_WhenCommandHelpRequested()
{
$output = $this->runArchivePhpCron(array('--help' => null), PIWIK_INCLUDE_PATH . '/misc/cron/archive.php');
diff --git a/plugins/CoreConsole/tests/System/expected/test_ArchiveCronTest_noOptions__Goals.get_month.xml b/plugins/CoreConsole/tests/System/expected/test_ArchiveCronTest_noOptions__Goals.get_month.xml
index dab33abb44..28c3435722 100644
--- a/plugins/CoreConsole/tests/System/expected/test_ArchiveCronTest_noOptions__Goals.get_month.xml
+++ b/plugins/CoreConsole/tests/System/expected/test_ArchiveCronTest_noOptions__Goals.get_month.xml
@@ -1,14 +1,14 @@
<?xml version="1.0" encoding="utf-8" ?>
<results>
<result idSite="1">
- <nb_conversions>31</nb_conversions>
- <nb_visits_converted>31</nb_visits_converted>
- <revenue>155</revenue>
- <conversion_rate>93.94%</conversion_rate>
- <nb_conversions_new_visit>31</nb_conversions_new_visit>
+ <nb_conversions>32</nb_conversions>
+ <nb_visits_converted>32</nb_visits_converted>
+ <revenue>160</revenue>
+ <conversion_rate>94.12%</conversion_rate>
+ <nb_conversions_new_visit>32</nb_conversions_new_visit>
<nb_visits_converted_new_visit>31</nb_visits_converted_new_visit>
- <revenue_new_visit>155</revenue_new_visit>
- <conversion_rate_new_visit>93.94%</conversion_rate_new_visit>
+ <revenue_new_visit>160</revenue_new_visit>
+ <conversion_rate_new_visit>91.18%</conversion_rate_new_visit>
</result>
<result idSite="2">
<nb_conversions>0</nb_conversions>
diff --git a/plugins/CoreConsole/tests/System/expected/test_ArchiveCronTest_noOptions__VisitFrequency.get_month.xml b/plugins/CoreConsole/tests/System/expected/test_ArchiveCronTest_noOptions__VisitFrequency.get_month.xml
index 56f4cd45a2..e35d80da08 100644
--- a/plugins/CoreConsole/tests/System/expected/test_ArchiveCronTest_noOptions__VisitFrequency.get_month.xml
+++ b/plugins/CoreConsole/tests/System/expected/test_ArchiveCronTest_noOptions__VisitFrequency.get_month.xml
@@ -1,12 +1,12 @@
<?xml version="1.0" encoding="utf-8" ?>
<results>
<result idSite="1">
- <nb_uniq_visitors_new>33</nb_uniq_visitors_new>
+ <nb_uniq_visitors_new>34</nb_uniq_visitors_new>
<nb_users_new>1</nb_users_new>
- <nb_visits_new>33</nb_visits_new>
- <nb_actions_new>36</nb_actions_new>
- <nb_visits_converted_new>31</nb_visits_converted_new>
- <bounce_count_new>31</bounce_count_new>
+ <nb_visits_new>34</nb_visits_new>
+ <nb_actions_new>37</nb_actions_new>
+ <nb_visits_converted_new>32</nb_visits_converted_new>
+ <bounce_count_new>32</bounce_count_new>
<sum_visit_length_new>305</sum_visit_length_new>
<max_actions_new>3</max_actions_new>
<bounce_rate_new>94%</bounce_rate_new>
diff --git a/plugins/CoreConsole/tests/System/expected/test_ArchiveCronTest_noOptions__VisitsSummary.get_day.xml b/plugins/CoreConsole/tests/System/expected/test_ArchiveCronTest_noOptions__VisitsSummary.get_day.xml
index 37a8f92b6c..358388e453 100644
--- a/plugins/CoreConsole/tests/System/expected/test_ArchiveCronTest_noOptions__VisitsSummary.get_day.xml
+++ b/plugins/CoreConsole/tests/System/expected/test_ArchiveCronTest_noOptions__VisitsSummary.get_day.xml
@@ -1,12 +1,12 @@
<?xml version="1.0" encoding="utf-8" ?>
<results>
<result idSite="1">
- <nb_uniq_visitors>11</nb_uniq_visitors>
+ <nb_uniq_visitors>12</nb_uniq_visitors>
<nb_users>0</nb_users>
- <nb_visits>11</nb_visits>
- <nb_actions>11</nb_actions>
- <nb_visits_converted>11</nb_visits_converted>
- <bounce_count>11</bounce_count>
+ <nb_visits>12</nb_visits>
+ <nb_actions>12</nb_actions>
+ <nb_visits_converted>12</nb_visits_converted>
+ <bounce_count>12</bounce_count>
<sum_visit_length>0</sum_visit_length>
<max_actions>1</max_actions>
<bounce_rate>100%</bounce_rate>
diff --git a/plugins/CoreConsole/tests/System/expected/test_ArchiveCronTest_noOptions__VisitsSummary.get_month.xml b/plugins/CoreConsole/tests/System/expected/test_ArchiveCronTest_noOptions__VisitsSummary.get_month.xml
index 3526826240..972ae44a47 100644
--- a/plugins/CoreConsole/tests/System/expected/test_ArchiveCronTest_noOptions__VisitsSummary.get_month.xml
+++ b/plugins/CoreConsole/tests/System/expected/test_ArchiveCronTest_noOptions__VisitsSummary.get_month.xml
@@ -1,12 +1,12 @@
<?xml version="1.0" encoding="utf-8" ?>
<results>
<result idSite="1">
- <nb_uniq_visitors>33</nb_uniq_visitors>
+ <nb_uniq_visitors>34</nb_uniq_visitors>
<nb_users>1</nb_users>
- <nb_visits>33</nb_visits>
- <nb_actions>36</nb_actions>
- <nb_visits_converted>31</nb_visits_converted>
- <bounce_count>31</bounce_count>
+ <nb_visits>34</nb_visits>
+ <nb_actions>37</nb_actions>
+ <nb_visits_converted>32</nb_visits_converted>
+ <bounce_count>32</bounce_count>
<sum_visit_length>305</sum_visit_length>
<max_actions>3</max_actions>
<bounce_rate>94%</bounce_rate>
diff --git a/plugins/CoreConsole/tests/System/expected/test_ArchiveCronTest_noOptions__VisitsSummary.get_week.xml b/plugins/CoreConsole/tests/System/expected/test_ArchiveCronTest_noOptions__VisitsSummary.get_week.xml
index 425d6d909d..4d2cc269e2 100644
--- a/plugins/CoreConsole/tests/System/expected/test_ArchiveCronTest_noOptions__VisitsSummary.get_week.xml
+++ b/plugins/CoreConsole/tests/System/expected/test_ArchiveCronTest_noOptions__VisitsSummary.get_week.xml
@@ -1,15 +1,15 @@
<?xml version="1.0" encoding="utf-8" ?>
<results>
<result idSite="1">
- <nb_uniq_visitors>30</nb_uniq_visitors>
+ <nb_uniq_visitors>31</nb_uniq_visitors>
<nb_users>1</nb_users>
- <nb_visits>30</nb_visits>
- <nb_actions>33</nb_actions>
- <nb_visits_converted>28</nb_visits_converted>
- <bounce_count>28</bounce_count>
+ <nb_visits>31</nb_visits>
+ <nb_actions>34</nb_actions>
+ <nb_visits_converted>29</nb_visits_converted>
+ <bounce_count>29</bounce_count>
<sum_visit_length>305</sum_visit_length>
<max_actions>3</max_actions>
- <bounce_rate>93%</bounce_rate>
+ <bounce_rate>94%</bounce_rate>
<nb_actions_per_visit>1.1</nb_actions_per_visit>
<avg_time_on_site>10</avg_time_on_site>
</result>
diff --git a/plugins/CoreConsole/tests/System/expected/test_ArchiveCronTest_noOptions__VisitsSummary.get_year.xml b/plugins/CoreConsole/tests/System/expected/test_ArchiveCronTest_noOptions__VisitsSummary.get_year.xml
index 79f53c6e57..b503a22410 100644
--- a/plugins/CoreConsole/tests/System/expected/test_ArchiveCronTest_noOptions__VisitsSummary.get_year.xml
+++ b/plugins/CoreConsole/tests/System/expected/test_ArchiveCronTest_noOptions__VisitsSummary.get_year.xml
@@ -1,15 +1,15 @@
<?xml version="1.0" encoding="utf-8" ?>
<results>
<result idSite="1">
- <nb_visits>34</nb_visits>
- <nb_actions>46</nb_actions>
- <nb_visits_converted>32</nb_visits_converted>
- <bounce_count>31</bounce_count>
+ <nb_visits>35</nb_visits>
+ <nb_actions>47</nb_actions>
+ <nb_visits_converted>33</nb_visits_converted>
+ <bounce_count>32</bounce_count>
<sum_visit_length>359</sum_visit_length>
<max_actions>10</max_actions>
<bounce_rate>91%</bounce_rate>
- <nb_actions_per_visit>1.4</nb_actions_per_visit>
- <avg_time_on_site>11</avg_time_on_site>
+ <nb_actions_per_visit>1.3</nb_actions_per_visit>
+ <avg_time_on_site>10</avg_time_on_site>
</result>
<result idSite="2">
<nb_visits>1</nb_visits>
diff --git a/plugins/CoreConsole/tests/System/expected/test_ArchiveCronTest_range_archive__Actions.get_range.xml b/plugins/CoreConsole/tests/System/expected/test_ArchiveCronTest_range_archive__Actions.get_range.xml
index 8ea3b42ae1..0f379fee74 100644
--- a/plugins/CoreConsole/tests/System/expected/test_ArchiveCronTest_range_archive__Actions.get_range.xml
+++ b/plugins/CoreConsole/tests/System/expected/test_ArchiveCronTest_range_archive__Actions.get_range.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8" ?>
<result>
- <nb_pageviews>29</nb_pageviews>
- <nb_uniq_pageviews>29</nb_uniq_pageviews>
+ <nb_pageviews>30</nb_pageviews>
+ <nb_uniq_pageviews>30</nb_uniq_pageviews>
<nb_downloads>4</nb_downloads>
<nb_uniq_downloads>4</nb_uniq_downloads>
<nb_outlinks>0</nb_outlinks>
diff --git a/plugins/CoreConsole/tests/System/expected/test_ArchiveCronTest_range_archive__DevicesDetection.getType_range.xml b/plugins/CoreConsole/tests/System/expected/test_ArchiveCronTest_range_archive__DevicesDetection.getType_range.xml
index 70f93c6789..98df5eb177 100644
--- a/plugins/CoreConsole/tests/System/expected/test_ArchiveCronTest_range_archive__DevicesDetection.getType_range.xml
+++ b/plugins/CoreConsole/tests/System/expected/test_ArchiveCronTest_range_archive__DevicesDetection.getType_range.xml
@@ -24,22 +24,22 @@
</row>
<row>
<label>Smartphone</label>
- <nb_visits>2</nb_visits>
- <nb_actions>2</nb_actions>
+ <nb_visits>3</nb_visits>
+ <nb_actions>3</nb_actions>
<max_actions>1</max_actions>
<sum_visit_length>0</sum_visit_length>
- <bounce_count>2</bounce_count>
- <nb_visits_converted>2</nb_visits_converted>
+ <bounce_count>3</bounce_count>
+ <nb_visits_converted>3</nb_visits_converted>
<goals>
<row idgoal='1'>
- <nb_conversions>2</nb_conversions>
- <nb_visits_converted>2</nb_visits_converted>
- <revenue>10</revenue>
+ <nb_conversions>3</nb_conversions>
+ <nb_visits_converted>3</nb_visits_converted>
+ <revenue>15</revenue>
</row>
</goals>
- <nb_conversions>2</nb_conversions>
- <revenue>10</revenue>
- <sum_daily_nb_uniq_visitors>2</sum_daily_nb_uniq_visitors>
+ <nb_conversions>3</nb_conversions>
+ <revenue>15</revenue>
+ <sum_daily_nb_uniq_visitors>3</sum_daily_nb_uniq_visitors>
<sum_daily_nb_users>0</sum_daily_nb_users>
<segment>deviceType==smartphone</segment>
<logo>plugins/Morpheus/icons/dist/devices/smartphone.png</logo>
diff --git a/plugins/CoreConsole/tests/System/expected/test_ArchiveCronTest_range_archive__VisitsSummary.get_range.xml b/plugins/CoreConsole/tests/System/expected/test_ArchiveCronTest_range_archive__VisitsSummary.get_range.xml
index 8cf54e7a39..af0d9b8c73 100644
--- a/plugins/CoreConsole/tests/System/expected/test_ArchiveCronTest_range_archive__VisitsSummary.get_range.xml
+++ b/plugins/CoreConsole/tests/System/expected/test_ArchiveCronTest_range_archive__VisitsSummary.get_range.xml
@@ -1,12 +1,12 @@
<?xml version="1.0" encoding="utf-8" ?>
<result>
- <nb_visits>30</nb_visits>
- <nb_actions>33</nb_actions>
- <nb_visits_converted>28</nb_visits_converted>
- <bounce_count>28</bounce_count>
+ <nb_visits>31</nb_visits>
+ <nb_actions>34</nb_actions>
+ <nb_visits_converted>29</nb_visits_converted>
+ <bounce_count>29</bounce_count>
<sum_visit_length>305</sum_visit_length>
<max_actions>3</max_actions>
- <bounce_rate>93%</bounce_rate>
+ <bounce_rate>94%</bounce_rate>
<nb_actions_per_visit>1.1</nb_actions_per_visit>
<avg_time_on_site>10</avg_time_on_site>
</result> \ No newline at end of file
diff --git a/plugins/CoreConsole/tests/System/expected/test_ArchiveCronTest_range_archive_before_invalidate__Actions.get_range.xml b/plugins/CoreConsole/tests/System/expected/test_ArchiveCronTest_range_archive_before_invalidate__Actions.get_range.xml
new file mode 100644
index 0000000000..0f379fee74
--- /dev/null
+++ b/plugins/CoreConsole/tests/System/expected/test_ArchiveCronTest_range_archive_before_invalidate__Actions.get_range.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<result>
+ <nb_pageviews>30</nb_pageviews>
+ <nb_uniq_pageviews>30</nb_uniq_pageviews>
+ <nb_downloads>4</nb_downloads>
+ <nb_uniq_downloads>4</nb_uniq_downloads>
+ <nb_outlinks>0</nb_outlinks>
+ <nb_uniq_outlinks>0</nb_uniq_outlinks>
+ <nb_searches>0</nb_searches>
+ <nb_keywords>0</nb_keywords>
+</result> \ No newline at end of file
diff --git a/plugins/CoreConsole/tests/System/expected/test_ArchiveCronTest_range_archive_before_invalidate__DevicesDetection.getType_range.xml b/plugins/CoreConsole/tests/System/expected/test_ArchiveCronTest_range_archive_before_invalidate__DevicesDetection.getType_range.xml
new file mode 100644
index 0000000000..98df5eb177
--- /dev/null
+++ b/plugins/CoreConsole/tests/System/expected/test_ArchiveCronTest_range_archive_before_invalidate__DevicesDetection.getType_range.xml
@@ -0,0 +1,140 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<result>
+ <row>
+ <label>Desktop</label>
+ <nb_visits>26</nb_visits>
+ <nb_actions>29</nb_actions>
+ <max_actions>3</max_actions>
+ <sum_visit_length>305</sum_visit_length>
+ <bounce_count>24</bounce_count>
+ <nb_visits_converted>25</nb_visits_converted>
+ <goals>
+ <row idgoal='1'>
+ <nb_conversions>25</nb_conversions>
+ <nb_visits_converted>25</nb_visits_converted>
+ <revenue>125</revenue>
+ </row>
+ </goals>
+ <nb_conversions>25</nb_conversions>
+ <revenue>125</revenue>
+ <sum_daily_nb_uniq_visitors>26</sum_daily_nb_uniq_visitors>
+ <sum_daily_nb_users>1</sum_daily_nb_users>
+ <segment>deviceType==desktop</segment>
+ <logo>plugins/Morpheus/icons/dist/devices/desktop.png</logo>
+ </row>
+ <row>
+ <label>Smartphone</label>
+ <nb_visits>3</nb_visits>
+ <nb_actions>3</nb_actions>
+ <max_actions>1</max_actions>
+ <sum_visit_length>0</sum_visit_length>
+ <bounce_count>3</bounce_count>
+ <nb_visits_converted>3</nb_visits_converted>
+ <goals>
+ <row idgoal='1'>
+ <nb_conversions>3</nb_conversions>
+ <nb_visits_converted>3</nb_visits_converted>
+ <revenue>15</revenue>
+ </row>
+ </goals>
+ <nb_conversions>3</nb_conversions>
+ <revenue>15</revenue>
+ <sum_daily_nb_uniq_visitors>3</sum_daily_nb_uniq_visitors>
+ <sum_daily_nb_users>0</sum_daily_nb_users>
+ <segment>deviceType==smartphone</segment>
+ <logo>plugins/Morpheus/icons/dist/devices/smartphone.png</logo>
+ </row>
+ <row>
+ <label>Unknown</label>
+ <nb_visits>2</nb_visits>
+ <nb_actions>2</nb_actions>
+ <max_actions>1</max_actions>
+ <sum_visit_length>0</sum_visit_length>
+ <bounce_count>2</bounce_count>
+ <nb_visits_converted>1</nb_visits_converted>
+ <goals>
+ <row idgoal='1'>
+ <nb_conversions>1</nb_conversions>
+ <nb_visits_converted>1</nb_visits_converted>
+ <revenue>5</revenue>
+ </row>
+ </goals>
+ <nb_conversions>1</nb_conversions>
+ <revenue>5</revenue>
+ <sum_daily_nb_uniq_visitors>2</sum_daily_nb_uniq_visitors>
+ <sum_daily_nb_users>0</sum_daily_nb_users>
+ <logo>plugins/Morpheus/icons/dist/devices/unknown.png</logo>
+ </row>
+ <row>
+ <label>Camera</label>
+ <nb_visits>0</nb_visits>
+ <segment>deviceType==camera</segment>
+ <logo>plugins/Morpheus/icons/dist/devices/camera.png</logo>
+ </row>
+ <row>
+ <label>Car browser</label>
+ <nb_visits>0</nb_visits>
+ <segment>deviceType==car+browser</segment>
+ <logo>plugins/Morpheus/icons/dist/devices/car_browser.png</logo>
+ </row>
+ <row>
+ <label>Console</label>
+ <nb_visits>0</nb_visits>
+ <segment>deviceType==console</segment>
+ <logo>plugins/Morpheus/icons/dist/devices/console.png</logo>
+ </row>
+ <row>
+ <label>Feature phone</label>
+ <nb_visits>0</nb_visits>
+ <segment>deviceType==feature+phone</segment>
+ <logo>plugins/Morpheus/icons/dist/devices/feature_phone.png</logo>
+ </row>
+ <row>
+ <label>Peripheral</label>
+ <nb_visits>0</nb_visits>
+ <segment>deviceType==peripheral</segment>
+ <logo>plugins/Morpheus/icons/dist/devices/peripheral.png</logo>
+ </row>
+ <row>
+ <label>Phablet</label>
+ <nb_visits>0</nb_visits>
+ <segment>deviceType==phablet</segment>
+ <logo>plugins/Morpheus/icons/dist/devices/phablet.png</logo>
+ </row>
+ <row>
+ <label>Portable media player</label>
+ <nb_visits>0</nb_visits>
+ <segment>deviceType==portable+media+player</segment>
+ <logo>plugins/Morpheus/icons/dist/devices/portable_media_player.png</logo>
+ </row>
+ <row>
+ <label>Smart display</label>
+ <nb_visits>0</nb_visits>
+ <segment>deviceType==smart+display</segment>
+ <logo>plugins/Morpheus/icons/dist/devices/smart_display.png</logo>
+ </row>
+ <row>
+ <label>Smart speaker</label>
+ <nb_visits>0</nb_visits>
+ <segment>deviceType==smart+speaker</segment>
+ <logo>plugins/Morpheus/icons/dist/devices/smart_speaker.png</logo>
+ </row>
+ <row>
+ <label>Tablet</label>
+ <nb_visits>0</nb_visits>
+ <segment>deviceType==tablet</segment>
+ <logo>plugins/Morpheus/icons/dist/devices/tablet.png</logo>
+ </row>
+ <row>
+ <label>Tv</label>
+ <nb_visits>0</nb_visits>
+ <segment>deviceType==tv</segment>
+ <logo>plugins/Morpheus/icons/dist/devices/tv.png</logo>
+ </row>
+ <row>
+ <label>Wearable</label>
+ <nb_visits>0</nb_visits>
+ <segment>deviceType==wearable</segment>
+ <logo>plugins/Morpheus/icons/dist/devices/wearable.png</logo>
+ </row>
+</result> \ No newline at end of file
diff --git a/plugins/CoreConsole/tests/System/expected/test_ArchiveCronTest_range_archive_before_invalidate__VisitsSummary.get_range.xml b/plugins/CoreConsole/tests/System/expected/test_ArchiveCronTest_range_archive_before_invalidate__VisitsSummary.get_range.xml
new file mode 100644
index 0000000000..af0d9b8c73
--- /dev/null
+++ b/plugins/CoreConsole/tests/System/expected/test_ArchiveCronTest_range_archive_before_invalidate__VisitsSummary.get_range.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<result>
+ <nb_visits>31</nb_visits>
+ <nb_actions>34</nb_actions>
+ <nb_visits_converted>29</nb_visits_converted>
+ <bounce_count>29</bounce_count>
+ <sum_visit_length>305</sum_visit_length>
+ <max_actions>3</max_actions>
+ <bounce_rate>94%</bounce_rate>
+ <nb_actions_per_visit>1.1</nb_actions_per_visit>
+ <avg_time_on_site>10</avg_time_on_site>
+</result> \ No newline at end of file
diff --git a/plugins/CoreConsole/tests/System/expected/test_ArchiveCronTest_range_archive_rearchived__Actions.get_range.xml b/plugins/CoreConsole/tests/System/expected/test_ArchiveCronTest_range_archive_rearchived__Actions.get_range.xml
new file mode 100644
index 0000000000..b3451748fd
--- /dev/null
+++ b/plugins/CoreConsole/tests/System/expected/test_ArchiveCronTest_range_archive_rearchived__Actions.get_range.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<result>
+ <nb_pageviews>31</nb_pageviews>
+ <nb_uniq_pageviews>31</nb_uniq_pageviews>
+ <nb_downloads>4</nb_downloads>
+ <nb_uniq_downloads>4</nb_uniq_downloads>
+ <nb_outlinks>0</nb_outlinks>
+ <nb_uniq_outlinks>0</nb_uniq_outlinks>
+ <nb_searches>0</nb_searches>
+ <nb_keywords>0</nb_keywords>
+</result> \ No newline at end of file
diff --git a/plugins/CoreConsole/tests/System/expected/test_ArchiveCronTest_range_archive_rearchived__DevicesDetection.getType_range.xml b/plugins/CoreConsole/tests/System/expected/test_ArchiveCronTest_range_archive_rearchived__DevicesDetection.getType_range.xml
new file mode 100644
index 0000000000..a8f2821894
--- /dev/null
+++ b/plugins/CoreConsole/tests/System/expected/test_ArchiveCronTest_range_archive_rearchived__DevicesDetection.getType_range.xml
@@ -0,0 +1,140 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<result>
+ <row>
+ <label>Desktop</label>
+ <nb_visits>26</nb_visits>
+ <nb_actions>29</nb_actions>
+ <max_actions>3</max_actions>
+ <sum_visit_length>305</sum_visit_length>
+ <bounce_count>24</bounce_count>
+ <nb_visits_converted>25</nb_visits_converted>
+ <goals>
+ <row idgoal='1'>
+ <nb_conversions>25</nb_conversions>
+ <nb_visits_converted>25</nb_visits_converted>
+ <revenue>125</revenue>
+ </row>
+ </goals>
+ <nb_conversions>25</nb_conversions>
+ <revenue>125</revenue>
+ <sum_daily_nb_uniq_visitors>26</sum_daily_nb_uniq_visitors>
+ <sum_daily_nb_users>1</sum_daily_nb_users>
+ <segment>deviceType==desktop</segment>
+ <logo>plugins/Morpheus/icons/dist/devices/desktop.png</logo>
+ </row>
+ <row>
+ <label>Smartphone</label>
+ <nb_visits>4</nb_visits>
+ <nb_actions>4</nb_actions>
+ <max_actions>1</max_actions>
+ <sum_visit_length>0</sum_visit_length>
+ <bounce_count>4</bounce_count>
+ <nb_visits_converted>4</nb_visits_converted>
+ <goals>
+ <row idgoal='1'>
+ <nb_conversions>4</nb_conversions>
+ <nb_visits_converted>4</nb_visits_converted>
+ <revenue>20</revenue>
+ </row>
+ </goals>
+ <nb_conversions>4</nb_conversions>
+ <revenue>20</revenue>
+ <sum_daily_nb_uniq_visitors>4</sum_daily_nb_uniq_visitors>
+ <sum_daily_nb_users>0</sum_daily_nb_users>
+ <segment>deviceType==smartphone</segment>
+ <logo>plugins/Morpheus/icons/dist/devices/smartphone.png</logo>
+ </row>
+ <row>
+ <label>Unknown</label>
+ <nb_visits>2</nb_visits>
+ <nb_actions>2</nb_actions>
+ <max_actions>1</max_actions>
+ <sum_visit_length>0</sum_visit_length>
+ <bounce_count>2</bounce_count>
+ <nb_visits_converted>1</nb_visits_converted>
+ <goals>
+ <row idgoal='1'>
+ <nb_conversions>1</nb_conversions>
+ <nb_visits_converted>1</nb_visits_converted>
+ <revenue>5</revenue>
+ </row>
+ </goals>
+ <nb_conversions>1</nb_conversions>
+ <revenue>5</revenue>
+ <sum_daily_nb_uniq_visitors>2</sum_daily_nb_uniq_visitors>
+ <sum_daily_nb_users>0</sum_daily_nb_users>
+ <logo>plugins/Morpheus/icons/dist/devices/unknown.png</logo>
+ </row>
+ <row>
+ <label>Camera</label>
+ <nb_visits>0</nb_visits>
+ <segment>deviceType==camera</segment>
+ <logo>plugins/Morpheus/icons/dist/devices/camera.png</logo>
+ </row>
+ <row>
+ <label>Car browser</label>
+ <nb_visits>0</nb_visits>
+ <segment>deviceType==car+browser</segment>
+ <logo>plugins/Morpheus/icons/dist/devices/car_browser.png</logo>
+ </row>
+ <row>
+ <label>Console</label>
+ <nb_visits>0</nb_visits>
+ <segment>deviceType==console</segment>
+ <logo>plugins/Morpheus/icons/dist/devices/console.png</logo>
+ </row>
+ <row>
+ <label>Feature phone</label>
+ <nb_visits>0</nb_visits>
+ <segment>deviceType==feature+phone</segment>
+ <logo>plugins/Morpheus/icons/dist/devices/feature_phone.png</logo>
+ </row>
+ <row>
+ <label>Peripheral</label>
+ <nb_visits>0</nb_visits>
+ <segment>deviceType==peripheral</segment>
+ <logo>plugins/Morpheus/icons/dist/devices/peripheral.png</logo>
+ </row>
+ <row>
+ <label>Phablet</label>
+ <nb_visits>0</nb_visits>
+ <segment>deviceType==phablet</segment>
+ <logo>plugins/Morpheus/icons/dist/devices/phablet.png</logo>
+ </row>
+ <row>
+ <label>Portable media player</label>
+ <nb_visits>0</nb_visits>
+ <segment>deviceType==portable+media+player</segment>
+ <logo>plugins/Morpheus/icons/dist/devices/portable_media_player.png</logo>
+ </row>
+ <row>
+ <label>Smart display</label>
+ <nb_visits>0</nb_visits>
+ <segment>deviceType==smart+display</segment>
+ <logo>plugins/Morpheus/icons/dist/devices/smart_display.png</logo>
+ </row>
+ <row>
+ <label>Smart speaker</label>
+ <nb_visits>0</nb_visits>
+ <segment>deviceType==smart+speaker</segment>
+ <logo>plugins/Morpheus/icons/dist/devices/smart_speaker.png</logo>
+ </row>
+ <row>
+ <label>Tablet</label>
+ <nb_visits>0</nb_visits>
+ <segment>deviceType==tablet</segment>
+ <logo>plugins/Morpheus/icons/dist/devices/tablet.png</logo>
+ </row>
+ <row>
+ <label>Tv</label>
+ <nb_visits>0</nb_visits>
+ <segment>deviceType==tv</segment>
+ <logo>plugins/Morpheus/icons/dist/devices/tv.png</logo>
+ </row>
+ <row>
+ <label>Wearable</label>
+ <nb_visits>0</nb_visits>
+ <segment>deviceType==wearable</segment>
+ <logo>plugins/Morpheus/icons/dist/devices/wearable.png</logo>
+ </row>
+</result> \ No newline at end of file
diff --git a/plugins/CoreConsole/tests/System/expected/test_ArchiveCronTest_range_archive_rearchived__VisitsSummary.get_range.xml b/plugins/CoreConsole/tests/System/expected/test_ArchiveCronTest_range_archive_rearchived__VisitsSummary.get_range.xml
new file mode 100644
index 0000000000..9af550f04d
--- /dev/null
+++ b/plugins/CoreConsole/tests/System/expected/test_ArchiveCronTest_range_archive_rearchived__VisitsSummary.get_range.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<result>
+ <nb_visits>32</nb_visits>
+ <nb_actions>35</nb_actions>
+ <nb_visits_converted>30</nb_visits_converted>
+ <bounce_count>30</bounce_count>
+ <sum_visit_length>305</sum_visit_length>
+ <max_actions>3</max_actions>
+ <bounce_rate>94%</bounce_rate>
+ <nb_actions_per_visit>1.1</nb_actions_per_visit>
+ <avg_time_on_site>10</avg_time_on_site>
+</result> \ No newline at end of file
diff --git a/tests/PHPUnit/Framework/Fixture.php b/tests/PHPUnit/Framework/Fixture.php
index 9358b9d8c6..fefe641240 100644
--- a/tests/PHPUnit/Framework/Fixture.php
+++ b/tests/PHPUnit/Framework/Fixture.php
@@ -48,6 +48,7 @@ use Piwik\Singleton;
use Piwik\Site;
use Piwik\Tests;
use Piwik\Tests\Framework\Mock\FakeAccess;
+use Piwik\Tests\Framework\Mock\File as MockFileMethods;
use Piwik\Tests\Framework\TestCase\SystemTestCase;
use Piwik\Tracker;
use Piwik\Tracker\Cache;
@@ -393,6 +394,7 @@ class Fixture extends \PHPUnit\Framework\Assert
Date::$now = null;
FrontController::$requestId = null;
Cache::$cache = null;
+ MockFileMethods::reset();
Archive::clearStaticCache();
DataTableManager::getInstance()->deleteAll();
Option::clearCache();
diff --git a/tests/PHPUnit/Framework/TestCase/SystemTestCase.php b/tests/PHPUnit/Framework/TestCase/SystemTestCase.php
index 802b22ecf5..85a2e85326 100644
--- a/tests/PHPUnit/Framework/TestCase/SystemTestCase.php
+++ b/tests/PHPUnit/Framework/TestCase/SystemTestCase.php
@@ -25,6 +25,7 @@ use Piwik\ReportRenderer;
use Piwik\Site;
use Piwik\Tests\Framework\Constraint\ResponseCode;
use Piwik\Tests\Framework\Constraint\HttpResponseText;
+use Piwik\Tests\Framework\Mock\File as MockFileMethods;
use Piwik\Tests\Framework\TestRequest\ApiTestConfig;
use Piwik\Tests\Framework\TestRequest\Collection;
use Piwik\Tests\Framework\TestRequest\Response;
@@ -75,6 +76,11 @@ abstract class SystemTestCase extends TestCase
{
Log::debug("Setting up " . get_called_class());
+ // NOTE: it is important to reference this class in a test framework class like Fixture so the mocks
+ // will be loaded before any testable classed load, otherwise some tests may fail w/o any obvious reason.
+ // (the actual reason being )
+ MockFileMethods::reset();
+
if (!isset(static::$fixture)) {
$fixture = new Fixture();
} else {
diff --git a/tests/PHPUnit/Framework/TestingEnvironmentVariables.php b/tests/PHPUnit/Framework/TestingEnvironmentVariables.php
index 697caf7a95..b14cd693f3 100644
--- a/tests/PHPUnit/Framework/TestingEnvironmentVariables.php
+++ b/tests/PHPUnit/Framework/TestingEnvironmentVariables.php
@@ -84,6 +84,11 @@ class TestingEnvironmentVariables
$this->configOverride = $config;
}
+ public function removeOverriddenConfig($group, $name)
+ {
+ unset($this->configOverride[$group][$name]);
+ }
+
public function save()
{
$includePath = __DIR__ . '/../../..';
diff --git a/tests/PHPUnit/Integration/ArchiveProcessor/LoaderTest.php b/tests/PHPUnit/Integration/ArchiveProcessor/LoaderTest.php
index cb5d2f931d..bf4b1a0c72 100644
--- a/tests/PHPUnit/Integration/ArchiveProcessor/LoaderTest.php
+++ b/tests/PHPUnit/Integration/ArchiveProcessor/LoaderTest.php
@@ -885,7 +885,7 @@ class LoaderTest extends IntegrationTestCase
$archiveInfo = $loader->loadExistingArchiveIdFromDb();
- $this->assertEquals([false, false, false, false, false], $archiveInfo);
+ $this->assertEquals([false, false, false, false, false, false], $archiveInfo);
}
/**
@@ -904,13 +904,14 @@ class LoaderTest extends IntegrationTestCase
$this->assertNotEmpty($archiveInfo[4]);
$this->assertLessThanOrEqual(time(), strtotime($archiveInfo[4]));
unset($archiveInfo[4]);
+ $archiveInfo = array_values($archiveInfo);
- $this->assertNotEquals([false, false, false, false], $archiveInfo);
+ $this->assertNotEquals([false, false, false, false, false, false], $archiveInfo);
Config::getInstance()->Debug[$configSetting] = 1;
$archiveInfo = $loader->loadExistingArchiveIdFromDb();
- $this->assertEquals([false, false, false, false], $archiveInfo);
+ $this->assertEquals([false, false, false, false, false, false], $archiveInfo);
}
public function getTestDataForLoadExistingArchiveIdFromDbDebugConfig()
@@ -935,8 +936,9 @@ class LoaderTest extends IntegrationTestCase
$this->assertNotEmpty($archiveInfo[4]);
unset($archiveInfo[4]);
+ $archiveInfo = array_values($archiveInfo);
- $this->assertEquals([['1'], '10', '0', true], $archiveInfo);
+ $this->assertEquals([['1'], '10', '0', true, '1'], $archiveInfo);
}
public function test_loadExistingArchiveIdFromDb_returnsArchiveIfForACurrentPeriod_AndNewEnough()
@@ -950,8 +952,9 @@ class LoaderTest extends IntegrationTestCase
$this->assertNotEmpty($archiveInfo[4]);
unset($archiveInfo[4]);
+ $archiveInfo = array_values($archiveInfo);
- $this->assertEquals([['1'], '10', '0', true], $archiveInfo);
+ $this->assertEquals([['1'], '10', '0', true, '1'], $archiveInfo);
}
public function test_loadExistingArchiveIdFromDb_returnsNoArchiveIfForACurrentPeriod_AndNoneAreNewEnough()
@@ -965,8 +968,9 @@ class LoaderTest extends IntegrationTestCase
$this->assertNotEmpty($archiveInfo[4]);
unset($archiveInfo[4]);
+ $archiveInfo = array_values($archiveInfo);
- $this->assertEquals([false, '10', '0', true], $archiveInfo); // visits are still returned as this was the original behavior
+ $this->assertEquals([false, '10', '0', true, '1'], $archiveInfo); // visits are still returned as this was the original behavior
}
/**
diff --git a/tests/PHPUnit/Integration/ArchiveTest.php b/tests/PHPUnit/Integration/ArchiveTest.php
index bc02d27711..66ecd17355 100644
--- a/tests/PHPUnit/Integration/ArchiveTest.php
+++ b/tests/PHPUnit/Integration/ArchiveTest.php
@@ -7,15 +7,19 @@
*
*/
-namespace PHPUnit\Integration;
+namespace Piwik\Tests\Integration;
use Piwik\Archive;
use Piwik\ArchiveProcessor\Parameters;
use Piwik\ArchiveProcessor\Rules;
+use Piwik\Common;
use Piwik\Config;
+use Piwik\CronArchive;
use Piwik\DataAccess\ArchiveWriter;
+use Piwik\Date;
use Piwik\Db;
use Piwik\Period\Factory;
+use Piwik\Plugins\VisitsSummary\API;
use Piwik\Segment;
use Piwik\Site;
use Piwik\Tests\Framework\Fixture;
@@ -98,4 +102,193 @@ class ArchiveTest extends IntegrationTestCase
$this->test_pluginSpecificArchiveUsed_EvenIfAllArchiveExists_IfThereAreNoDataInAllArchive();
}
+
+ public function test_archivingInvalidRange_doesNotReprocessInvalidDay()
+ {
+ $idSite = 1;
+
+ self::$fixture->getTestEnvironment()->overrideConfig('General', 'browser_archiving_disabled_enforce', 0);
+ self::$fixture->getTestEnvironment()->overrideConfig('General', 'archiving_range_force_on_browser_request', 1);
+ self::$fixture->getTestEnvironment()->save();
+
+ Config::getInstance()->General['browser_archiving_disabled_enforce'] = 0;
+ Config::getInstance()->General['archiving_range_force_on_browser_request'] = 1;
+
+ // track some visits
+ $t = Fixture::getTracker($idSite, '2020-03-04 05:05:05');
+ $t->setUrl('http://abc.com/mypage');
+ Fixture::checkResponse($t->doTrackPageView('page title'));
+
+ $t->setForceVisitDateTime('2020-03-05 06:06:06');
+ $t->setUrl('http://abc.com/myotherpage');
+ Fixture::checkResponse($t->doTrackPageView('another page'));
+
+ // clear invalidations from above tracking
+ $cronArchive = new CronArchive();
+ $cronArchive->init();
+ $cronArchive->invalidateArchivedReportsForSitesThatNeedToBeArchivedAgain(1);
+
+ // archive range and day
+ Rules::setBrowserTriggerArchiving(true);
+ API::getInstance()->get(1, 'range', '2020-03-04,2020-03-05');
+
+ // check expected archives were created
+ $archives = Db::fetchAll("SELECT date1, date2, name, value FROM " . Common::prefixTable('archive_numeric_2020_03')
+ . " WHERE `name` IN ('done', 'done.VisitsSummary')");
+ $expected = [
+ ['date1' => '2020-03-04', 'date2' => '2020-03-05', 'name' => 'done.VisitsSummary', 'value' => '1'],
+ ['date1' => '2020-03-04', 'date2' => '2020-03-04', 'name' => 'done', 'value' => '1'],
+ ['date1' => '2020-03-05', 'date2' => '2020-03-05', 'name' => 'done', 'value' => '1'],
+ ];
+ $this->assertEquals($expected, $archives);
+
+ // update ts_archived of archives so invalidating will work
+ Db::query("UPDATE " . Common::prefixTable('archive_numeric_2020_03') . " SET ts_archived = ?", [Date::now()->subHour(2)->getDatetime()]);
+
+ // track a visit and invalidate a day in the range
+ $t->setIp('50.123.45.67');
+ $t->setForceVisitDateTime('2020-03-05 06:06:06');
+ $t->setUrl('http://abc.com/myotherpage');
+ Fixture::checkResponse($t->doTrackPageView('my other page'));
+
+ $cronArchive = new CronArchive();
+ $cronArchive->init();
+ $cronArchive->invalidateArchivedReportsForSitesThatNeedToBeArchivedAgain(1);
+
+ // check correct archives are invalidated
+ $archives = Db::fetchAll("SELECT date1, date2, name, value FROM " . Common::prefixTable('archive_numeric_2020_03')
+ . " WHERE `name` IN ('done', 'done.VisitsSummary')");
+ $expected = [
+ ['date1' => '2020-03-04', 'date2' => '2020-03-05', 'name' => 'done.VisitsSummary', 'value' => '4'],
+ ['date1' => '2020-03-04', 'date2' => '2020-03-04', 'name' => 'done', 'value' => '1'],
+ ['date1' => '2020-03-05', 'date2' => '2020-03-05', 'name' => 'done', 'value' => '4'],
+ ];
+ $this->assertEquals($expected, $archives);
+
+ // archive range again since it is invalid and we updated the ts_archived to a older time
+ Rules::setBrowserTriggerArchiving(false);
+ API::getInstance()->get(1, 'range', '2020-03-04,2020-03-05');
+
+ // check that range was rearchived
+ $archives = Db::fetchAll("SELECT idarchive, date1, date2, name, value FROM " . Common::prefixTable('archive_numeric_2020_03')
+ . " WHERE `name` IN ('done', 'done.VisitsSummary')");
+ $expected = [
+ ['idarchive' => '2', 'date1' => '2020-03-04', 'date2' => '2020-03-04', 'name' => 'done', 'value' => '1'],
+ ['idarchive' => '7', 'date1' => '2020-03-05', 'date2' => '2020-03-05', 'name' => 'done', 'value' => '4'],
+ ['idarchive' => '12', 'date1' => '2020-03-04', 'date2' => '2020-03-05', 'name' => 'done.VisitsSummary', 'value' => '1'],
+ ];
+ $this->assertEquals($expected, $archives);
+
+ // rearchive day and check range does not rearchive
+ Rules::setBrowserTriggerArchiving(true);
+ API::getInstance()->get(1, 'day', '2020-03-05');
+ Rules::setBrowserTriggerArchiving(false);
+ API::getInstance()->get(1, 'range', '2020-03-04,2020-03-05');
+
+ $archives = Db::fetchAll("SELECT idarchive, date1, date2, name, value FROM " . Common::prefixTable('archive_numeric_2020_03')
+ . " WHERE `name` IN ('done', 'done.VisitsSummary')");
+ $expected = [
+ ['idarchive' => '2', 'date1' => '2020-03-04', 'date2' => '2020-03-04', 'name' => 'done', 'value' => '1'],
+ ['idarchive' => '12', 'date1' => '2020-03-04', 'date2' => '2020-03-05', 'name' => 'done.VisitsSummary', 'value' => '1'],
+ ['idarchive' => '13', 'date1' => '2020-03-05', 'date2' => '2020-03-05', 'name' => 'done', 'value' => '1'],
+ ];
+ $this->assertEquals($expected, $archives);
+
+ // update range archive ts_archived to be beyond and check that range was rearchived
+ Db::query("UPDATE " . Common::prefixTable('archive_numeric_2020_03') . " SET ts_archived = ? WHERE period = 5", [Date::now()->subHour(2)->getDatetime()]);
+ API::getInstance()->get(1, 'range', '2020-03-04,2020-03-05');
+
+ $archives = Db::fetchAll("SELECT idarchive, date1, date2, name, value FROM " . Common::prefixTable('archive_numeric_2020_03')
+ . " WHERE `name` IN ('done', 'done.VisitsSummary')");
+ $expected = [
+ ['idarchive' => '2', 'date1' => '2020-03-04', 'date2' => '2020-03-04', 'name' => 'done', 'value' => '1'],
+ ['idarchive' => '13', 'date1' => '2020-03-05', 'date2' => '2020-03-05', 'name' => 'done', 'value' => '1'],
+ ['idarchive' => '16', 'date1' => '2020-03-04', 'date2' => '2020-03-05', 'name' => 'done.VisitsSummary', 'value' => '1'],
+ ];
+ $this->assertEquals($expected, $archives);
+ }
+
+ public function test_archivingInvalidWeekWithSegment_doesReprocessInvalidDayWIthSegment()
+ {
+ $idSite = 1;
+
+ $segment = 'browserCode==FF';
+ $segmentHash = md5($segment);
+
+ self::$fixture->getTestEnvironment()->overrideConfig('General', 'browser_archiving_disabled_enforce', 0);
+ self::$fixture->getTestEnvironment()->overrideConfig('General', 'archiving_range_force_on_browser_request', 1);
+ self::$fixture->getTestEnvironment()->save();
+
+ Config::getInstance()->General['browser_archiving_disabled_enforce'] = 0;
+ Config::getInstance()->General['archiving_range_force_on_browser_request'] = 1;
+
+ // track some visits
+ $t = Fixture::getTracker($idSite, '2020-03-04 05:05:05');
+ $t->setUrl('http://abc.com/mypage');
+ Fixture::checkResponse($t->doTrackPageView('page title'));
+
+ $t->setForceVisitDateTime('2020-03-05 06:06:06');
+ $t->setUrl('http://abc.com/myotherpage');
+ Fixture::checkResponse($t->doTrackPageView('another page'));
+
+ // clear invalidations from above tracking
+ $cronArchive = new CronArchive();
+ $cronArchive->init();
+ $cronArchive->invalidateArchivedReportsForSitesThatNeedToBeArchivedAgain(1);
+
+ // archive week and day
+ Rules::setBrowserTriggerArchiving(true);
+ API::getInstance()->get(1, 'week', '2020-03-04', $segment);
+
+ // check expected archives were created
+ $archives = Db::fetchAll("SELECT date1, date2, name, value FROM " . Common::prefixTable('archive_numeric_2020_03')
+ . " WHERE `name` = 'done$segmentHash.VisitsSummary'");
+ $expected = [
+ ['date1' => '2020-03-02', 'date2' => '2020-03-08', 'name' => 'done' . $segmentHash . '.VisitsSummary', 'value' => '1'],
+ ['date1' => '2020-03-04', 'date2' => '2020-03-04', 'name' => 'done' . $segmentHash . '.VisitsSummary', 'value' => '1'],
+ ['date1' => '2020-03-05', 'date2' => '2020-03-05', 'name' => 'done' . $segmentHash . '.VisitsSummary', 'value' => '1'],
+ ];
+ $this->assertEquals($expected, $archives);
+
+ // update ts_archived of archives so invalidating will work
+ Db::query("UPDATE " . Common::prefixTable('archive_numeric_2020_03') . " SET ts_archived = ?", [Date::now()->subHour(2)->getDatetime()]);
+
+ // track a visit and invalidate a day in the week
+ $t->setIp('50.123.45.67');
+ $t->setForceVisitDateTime('2020-03-05 06:06:06');
+ $t->setUrl('http://abc.com/myotherpage');
+ Fixture::checkResponse($t->doTrackPageView('my other page'));
+
+ $cronArchive->invalidateArchivedReportsForSitesThatNeedToBeArchivedAgain(1);
+
+ // check correct archives are invalidated
+ $archives = Db::fetchAll("SELECT date1, date2, name, value FROM " . Common::prefixTable('archive_numeric_2020_03')
+ . " WHERE `name` = 'done$segmentHash.VisitsSummary'");
+ $expected = [
+ ['date1' => '2020-03-02', 'date2' => '2020-03-08', 'name' => 'done' . $segmentHash . '.VisitsSummary', 'value' => '4'],
+ ['date1' => '2020-03-04', 'date2' => '2020-03-04', 'name' => 'done' . $segmentHash . '.VisitsSummary', 'value' => '1'],
+ ['date1' => '2020-03-05', 'date2' => '2020-03-05', 'name' => 'done' . $segmentHash . '.VisitsSummary', 'value' => '4'],
+ ];
+ $this->assertEquals($expected, $archives);
+
+ // archive segment again
+ Rules::setBrowserTriggerArchiving(false);
+ API::getInstance()->get(1, 'week', '2020-03-04,2020-03-05', $segment);
+
+ // check that segment was rearchived, because day was allowed to be rearchived
+ $archives = Db::fetchAll("SELECT date1, date2, name, value FROM " . Common::prefixTable('archive_numeric_2020_03')
+ . " WHERE `name` = 'done$segmentHash.VisitsSummary'");
+ $expected = [
+ ['date1' => '2020-03-04', 'date2' => '2020-03-04', 'name' => 'done' . $segmentHash . '.VisitsSummary', 'value' => '1'],
+ ['date1' => '2020-03-02', 'date2' => '2020-03-08', 'name' => 'done' . $segmentHash . '.VisitsSummary', 'value' => '1'],
+ ['date1' => '2020-03-05', 'date2' => '2020-03-05', 'name' => 'done' . $segmentHash . '.VisitsSummary', 'value' => '1'],
+ ];
+ $this->assertEquals($expected, $archives);
+ }
+
+ protected static function configureFixture($fixture)
+ {
+ parent::configureFixture($fixture);
+ $fixture->createSuperUser = true;
+ }
} \ No newline at end of file
diff --git a/tests/PHPUnit/Integration/CronArchiveTest.php b/tests/PHPUnit/Integration/CronArchiveTest.php
index 2d282c9238..9ffe5e0b83 100644
--- a/tests/PHPUnit/Integration/CronArchiveTest.php
+++ b/tests/PHPUnit/Integration/CronArchiveTest.php
@@ -427,7 +427,7 @@ class CronArchiveTest extends IntegrationTestCase
return $mock;
}
- public function test_isThereExistingValidPeriod_returnsTrueIfPeriodHasToday_AndExistingArchiveIsNewEnough()
+ public function test_canWeSkipInvalidatingBecauseThereIsAUsablePeriod_returnsTrueIfPeriodHasToday_AndExistingArchiveIsNewEnough()
{
Fixture::createWebsite('2019-04-04 03:45:45');
@@ -444,12 +444,14 @@ class CronArchiveTest extends IntegrationTestCase
1, 1,2, '2020-03-30', '2020-04-05', 'done', ArchiveWriter::DONE_OK, $tsArchived
]);
- $actual =$archiver->isThereExistingValidPeriod($params);
+ $actual =$archiver->canWeSkipInvalidatingBecauseThereIsAUsablePeriod($params);
$this->assertTrue($actual);
}
- public function test_isThereExistingValidPeriod_returnsTrueIfPeriodHasToday_AndExistingArchiveIsNewEnoughAndInvalidated()
+ public function test_canWeSkipInvalidatingBecauseThereIsAUsablePeriod_returnsTrueIfPeriodHasToday_AndExistingArchiveIsNewEnoughAndInvalidated()
{
+ Rules::setBrowserTriggerArchiving(false);
+
Fixture::createWebsite('2019-04-04 03:45:45');
Date::$now = strtotime('2020-04-05');
@@ -465,12 +467,14 @@ class CronArchiveTest extends IntegrationTestCase
1, 1,2, '2020-03-30', '2020-04-05', 'done', ArchiveWriter::DONE_INVALIDATED, $tsArchived
]);
- $actual =$archiver->isThereExistingValidPeriod($params, $isYesterday = false);
+ $actual =$archiver->canWeSkipInvalidatingBecauseThereIsAUsablePeriod($params);
$this->assertTrue($actual);
}
- public function test_isThereExistingValidPeriod_returnsTrueIfPeriodDoesNotHaveToday_AndExistingArchiveIsOk()
+ public function test_canWeSkipInvalidatingBecauseThereIsAUsablePeriod_returnsIfPeriodDoesNotHaveToday_AndExistingArchiveIsOk()
{
+ Rules::setBrowserTriggerArchiving(false);
+
Fixture::createWebsite('2019-04-04 03:45:45');
Date::$now = strtotime('2020-04-05');
@@ -479,19 +483,21 @@ class CronArchiveTest extends IntegrationTestCase
$params = new Parameters(new Site(1), Factory::build('day', '2020-03-05'), new Segment('', [1]));
- $tsArchived = Date::now()->subDay(1)->getDatetime();
+ $tsArchived = Date::now()->subHour(0.1)->getDatetime();
$archiveTable = ArchiveTableCreator::getNumericTable(Date::factory('2020-03-05'));
Db::query("INSERT INTO $archiveTable (idarchive, idsite, period, date1, date2, name, value, ts_archived) VALUES (?, ?, ?, ?, ?, ?, ?, ?)", [
1, 1, 1, '2020-03-05', '2020-03-05', 'done', ArchiveWriter::DONE_OK, $tsArchived
]);
- $actual =$archiver->isThereExistingValidPeriod($params, $isYesterday = false);
+ $actual = $archiver->canWeSkipInvalidatingBecauseThereIsAUsablePeriod($params);
$this->assertTrue($actual);
}
- public function test_isThereExistingValidPeriod_returnsFalseIfDayHasChangedAndDateIsYesterday()
+ public function test_canWeSkipInvalidatingBecauseThereIsAUsablePeriod_returnsFalseIfDayHasChangedAndDateIsYesterday()
{
+ Rules::setBrowserTriggerArchiving(false);
+
Fixture::createWebsite('2019-04-04 03:45:45');
Date::$now = strtotime('2020-04-05');
@@ -507,12 +513,14 @@ class CronArchiveTest extends IntegrationTestCase
1, 1, 1, '2020-04-04', '2020-04-04', 'done', ArchiveWriter::DONE_OK, $tsArchived
]);
- $actual =$archiver->isThereExistingValidPeriod($params, $isYesterday = true);
+ $actual =$archiver->canWeSkipInvalidatingBecauseThereIsAUsablePeriod($params);
$this->assertFalse($actual);
}
- public function test_isThereExistingValidPeriod_returnsTrueIfDayHasNotChangedAndDateIsYesterday()
+ public function test_canWeSkipInvalidatingBecauseThereIsAUsablePeriod_returnsTrueIfDayHasNotChangedAndDateIsYesterday()
{
+ Rules::setBrowserTriggerArchiving(false);
+
Fixture::createWebsite('2019-04-04 03:45:45');
Date::$now = strtotime('2020-04-05 06:23:40');
@@ -528,7 +536,8 @@ class CronArchiveTest extends IntegrationTestCase
1, 1, 1, '2020-04-04', '2020-04-04', 'done', ArchiveWriter::DONE_OK, $tsArchived
]);
- $actual = $archiver->isThereExistingValidPeriod($params, $isYesterday = true);
+ // $doNotIncludeTtlInExistingArchiveCheck is set to true when running invalidateRecentDate('yesterday');
+ $actual = $archiver->canWeSkipInvalidatingBecauseThereIsAUsablePeriod($params, $doNotIncludeTtlInExistingArchiveCheck = true);
$this->assertTrue($actual);
}
diff --git a/tests/PHPUnit/Integration/DataAccess/ArchiveSelectorTest.php b/tests/PHPUnit/Integration/DataAccess/ArchiveSelectorTest.php
index ddb42a247f..f57b1b123c 100644
--- a/tests/PHPUnit/Integration/DataAccess/ArchiveSelectorTest.php
+++ b/tests/PHPUnit/Integration/DataAccess/ArchiveSelectorTest.php
@@ -11,18 +11,27 @@ namespace Piwik\Tests\Integration\DataAccess;
use Piwik\ArchiveProcessor\Parameters;
+use Piwik\ArchiveProcessor\Rules;
+use Piwik\Config;
use Piwik\DataAccess\ArchiveSelector;
use Piwik\DataAccess\ArchiveTableCreator;
use Piwik\Date;
use Piwik\Db;
use Piwik\Period\Factory;
+use Piwik\Plugins\SegmentEditor\API;
use Piwik\Segment;
use Piwik\Site;
use Piwik\Tests\Framework\Fixture;
use Piwik\Tests\Framework\TestCase\IntegrationTestCase;
+/**
+ * @group Core
+ * @group Integration
+ */
class ArchiveSelectorTest extends IntegrationTestCase
{
+ const TEST_SEGMENT = 'operatingSystemCode==WIN';
+
protected static function configureFixture($fixture)
{
parent::configureFixture($fixture);
@@ -126,19 +135,51 @@ class ArchiveSelectorTest extends IntegrationTestCase
}
}
+ /**
+ * @dataProvider getTestDataForGetArchiveIdAndVisits
+ */
+ public function test_getArchiveIdAndVisits_returnsCorrectResult($period, $date, $archiveRows, $segment, $minDateProcessed, $includeInvalidated, $expected)
+ {
+ Fixture::createWebsite('2010-02-02 00:00:00');
+
+ Rules::setBrowserTriggerArchiving(false);
+ API::getInstance()->add('test segment', self::TEST_SEGMENT, 0, 0); // processed in real time
+
+ $this->insertArchiveData($archiveRows);
+
+ $params = new \Piwik\ArchiveProcessor\Parameters(new Site(1), Factory::build($period, $date), new Segment($segment, [1]));
+ $result = ArchiveSelector::getArchiveIdAndVisits($params, $minDateProcessed, $includeInvalidated);
+
+ if ($result[4] !== false) {
+ Date::factory($result[4]);
+ }
+
+ unset($result[4]);
+ $result = array_values($result);
+
+ $this->assertEquals($expected, $result);
+ }
+
public function getTestDataForGetArchiveIdAndVisits()
{
+ $segment = urlencode(self::TEST_SEGMENT);
+ $segmentHash = md5(self::TEST_SEGMENT);
+
$minDateProcessed = Date::factory('2020-03-04 00:00:00')->subSeconds(900)->getDatetime();
return [
// no archive data found
[ // nothing in the db
+ 'day',
+ '2019-10-05',
[],
'',
$minDateProcessed,
true,
- [false, false, false, false],
+ [false, false, false, false, false],
],
[
+ 'day',
+ '2019-10-05',
[
['idarchive' => 1, 'idsite' => 1, 'period' => 2, 'date1' => '2019-10-05', 'date2' => '2019-10-05', 'name' => 'done', 'value' => 1],
['idarchive' => 2, 'idsite' => 1, 'period' => 1, 'date1' => '2019-10-06', 'date2' => '2019-10-06', 'name' => 'done', 'value' => 1],
@@ -147,11 +188,13 @@ class ArchiveSelectorTest extends IntegrationTestCase
'',
$minDateProcessed,
true,
- [false, false, false, false],
+ [false, false, false, false, false],
],
// value is not valid
[
+ 'day',
+ '2019-10-05',
[
['idarchive' => 1, 'idsite' => 1, 'period' => 1, 'date1' => '2019-10-05', 'date2' => '2019-10-05', 'name' => 'done', 'value' => 4],
['idarchive' => 2, 'idsite' => 1, 'period' => 1, 'date1' => '2019-10-05', 'date2' => '2019-10-05', 'name' => 'done', 'value' => 2],
@@ -161,9 +204,11 @@ class ArchiveSelectorTest extends IntegrationTestCase
'',
$minDateProcessed,
false,
- [false, false, false, true],
+ [false, false, false, true, '99'],
],
[
+ 'day',
+ '2019-10-05',
[
['idarchive' => 1, 'idsite' => 1, 'period' => 1, 'date1' => '2019-10-05', 'date2' => '2019-10-05', 'name' => 'done', 'value' => 4],
['idarchive' => 1, 'idsite' => 1, 'period' => 1, 'date1' => '2019-10-05', 'date2' => '2019-10-05', 'name' => 'nb_visits', 'value' => 20],
@@ -175,9 +220,11 @@ class ArchiveSelectorTest extends IntegrationTestCase
'',
$minDateProcessed,
false,
- [false, 0, 0, true],
+ [false, 0, 0, true, '99'],
],
[
+ 'day',
+ '2019-10-05',
[
['idarchive' => 1, 'idsite' => 1, 'period' => 1, 'date1' => '2019-10-05', 'date2' => '2019-10-05', 'name' => 'done.VisitsSummary', 'value' => 4],
['idarchive' => 1, 'idsite' => 1, 'period' => 1, 'date1' => '2019-10-05', 'date2' => '2019-10-05', 'name' => 'nb_visits', 'value' => 20],
@@ -186,9 +233,11 @@ class ArchiveSelectorTest extends IntegrationTestCase
'',
$minDateProcessed,
false,
- [false, 20, 40, true],
+ [false, 20, 40, true, false],
],
[
+ 'day',
+ '2019-10-05',
[
['idarchive' => 1, 'idsite' => 1, 'period' => 1, 'date1' => '2019-10-05', 'date2' => '2019-10-05', 'name' => 'done.VisitsSummary', 'value' => 1],
['idarchive' => 1, 'idsite' => 1, 'period' => 1, 'date1' => '2019-10-05', 'date2' => '2019-10-05', 'name' => 'nb_visits', 'value' => 30],
@@ -197,9 +246,11 @@ class ArchiveSelectorTest extends IntegrationTestCase
'',
$minDateProcessed,
false,
- [false, 30, 50, true],
+ [false, 30, 50, true, false],
],
[
+ 'day',
+ '2019-10-05',
[
['idarchive' => 1, 'idsite' => 1, 'period' => 1, 'date1' => '2019-10-05', 'date2' => '2019-10-05', 'name' => 'done.VisitsSummary', 'value' => 1],
['idarchive' => 1, 'idsite' => 1, 'period' => 1, 'date1' => '2019-10-05', 'date2' => '2019-10-05', 'name' => 'nb_visits', 'value' => 30],
@@ -209,11 +260,13 @@ class ArchiveSelectorTest extends IntegrationTestCase
'',
$minDateProcessed,
false,
- [false, false, false, true],
+ [false, false, false, true, false],
],
// archive is too old
[
+ 'day',
+ '2019-10-05',
[
['idarchive' => 1, 'idsite' => 1, 'period' => 1, 'date1' => '2019-10-05', 'date2' => '2019-10-05', 'name' => 'done', 'value' => 1,
'ts_archived' => Date::factory($minDateProcessed)->subSeconds(1)->getDatetime()],
@@ -221,9 +274,11 @@ class ArchiveSelectorTest extends IntegrationTestCase
'',
$minDateProcessed,
false,
- [false, false, false, true],
+ [false, false, false, true, '1'],
],
[
+ 'day',
+ '2019-10-05',
[
['idarchive' => 1, 'idsite' => 1, 'period' => 1, 'date1' => '2019-10-05', 'date2' => '2019-10-05', 'name' => 'done', 'value' => 1,
'ts_archived' => Date::factory($minDateProcessed)->subSeconds(1)->getDatetime()],
@@ -233,11 +288,13 @@ class ArchiveSelectorTest extends IntegrationTestCase
'',
$minDateProcessed,
false,
- [false, 1, false, true],
+ [false, 1, false, true, '1'],
],
// no archive done flags, but metric
[
+ 'day',
+ '2019-10-05',
[
['idarchive' => 1, 'idsite' => 1, 'period' => 1, 'date1' => '2019-10-05', 'date2' => '2019-10-05', 'name' => 'nb_visits_converted', 'value' => 10],
['idarchive' => 1, 'idsite' => 1, 'period' => 1, 'date1' => '2019-10-05', 'date2' => '2019-10-05', 'name' => 'nb_visits', 'value' => 1],
@@ -245,9 +302,11 @@ class ArchiveSelectorTest extends IntegrationTestCase
'',
$minDateProcessed,
false,
- [false, false, false, false],
+ [false, false, false, false, false],
],
[
+ 'day',
+ '2019-10-05',
[
['idarchive' => 1, 'idsite' => 1, 'period' => 1, 'date1' => '2019-10-05', 'date2' => '2019-10-05', 'name' => 'nb_visits_converted', 'value' => 10],
['idarchive' => 1, 'idsite' => 1, 'period' => 1, 'date1' => '2019-10-05', 'date2' => '2019-10-05', 'name' => 'nb_visits', 'value' => 3],
@@ -256,20 +315,24 @@ class ArchiveSelectorTest extends IntegrationTestCase
'',
$minDateProcessed,
false,
- [false, false, false, false],
+ [false, false, false, false, false],
],
// archive exists and is usable
[
+ 'day',
+ '2019-10-05',
[
['idarchive' => 1, 'idsite' => 1, 'period' => 1, 'date1' => '2019-10-05', 'date2' => '2019-10-05', 'name' => 'done', 'value' => 1],
],
'',
$minDateProcessed,
false,
- [[1], 0, 0, true],
+ [[1], 0, 0, true, '1'],
],
[
+ 'day',
+ '2019-10-05',
[
['idarchive' => 1, 'idsite' => 1, 'period' => 1, 'date1' => '2019-10-05', 'date2' => '2019-10-05', 'name' => 'done', 'value' => 1],
['idarchive' => 1, 'idsite' => 1, 'period' => 1, 'date1' => '2019-10-05', 'date2' => '2019-10-05', 'name' => 'nb_visits', 'value' => 5],
@@ -278,7 +341,37 @@ class ArchiveSelectorTest extends IntegrationTestCase
'',
$minDateProcessed,
false,
- [[1], 5, 10, true],
+ [[1], 5, 10, true, '1'],
+ ],
+
+ // range archive, valid
+ [
+ 'day',
+ '2019-10-05,2019-10-09',
+ [
+ ['idarchive' => 1, 'idsite' => 1, 'period' => 5, 'date1' => '2019-10-05', 'date2' => '2019-10-09', 'name' => 'done', 'value' => 1],
+ ['idarchive' => 1, 'idsite' => 1, 'period' => 5, 'date1' => '2019-10-05', 'date2' => '2019-10-09', 'name' => 'nb_visits', 'value' => 5],
+ ['idarchive' => 1, 'idsite' => 1, 'period' => 5, 'date1' => '2019-10-05', 'date2' => '2019-10-09', 'name' => 'nb_visits_converted', 'value' => 10],
+ ],
+ '',
+ $minDateProcessed,
+ false,
+ [[1], 5, 10, true, '1'],
+ ],
+
+ // range archive, invalid
+ [
+ 'day',
+ '2019-10-05,2019-10-09',
+ [
+ ['idarchive' => 1, 'idsite' => 1, 'period' => 5, 'date1' => '2019-10-05', 'date2' => '2019-10-09', 'name' => 'done', 'value' => 4],
+ ['idarchive' => 1, 'idsite' => 1, 'period' => 5, 'date1' => '2019-10-05', 'date2' => '2019-10-09', 'name' => 'nb_visits', 'value' => 5],
+ ['idarchive' => 1, 'idsite' => 1, 'period' => 5, 'date1' => '2019-10-05', 'date2' => '2019-10-09', 'name' => 'nb_visits_converted', 'value' => 10],
+ ],
+ '',
+ $minDateProcessed,
+ false,
+ [false, 5, 10, true, '4'], // forcing archiving since invalid + browser archiving of ranges allowed
],
];
}
diff --git a/tests/PHPUnit/System/ArchiveInvalidationTest.php b/tests/PHPUnit/System/ArchiveInvalidationTest.php
index 95d756c2ce..4e537f9562 100644
--- a/tests/PHPUnit/System/ArchiveInvalidationTest.php
+++ b/tests/PHPUnit/System/ArchiveInvalidationTest.php
@@ -8,8 +8,12 @@
namespace Piwik\Tests\System;
use Piwik\API\Request;
+use Piwik\ArchiveProcessor\Rules;
+use Piwik\Common;
use Piwik\Config;
use Piwik\Date;
+use Piwik\Db;
+use Piwik\Plugins\SegmentEditor\API;
use Piwik\Tests\Fixtures\VisitsTwoWebsitesWithAdditionalVisits;
use Piwik\Tests\Framework\TestCase\SystemTestCase;
@@ -25,6 +29,8 @@ use Piwik\Tests\Framework\TestCase\SystemTestCase;
*/
class ArchiveInvalidationTest extends SystemTestCase
{
+ const TEST_SEGMENT = 'pageUrl=@category%252F';
+
/**
* @var VisitsTwoWebsitesWithAdditionalVisits
*/
@@ -32,6 +38,20 @@ class ArchiveInvalidationTest extends SystemTestCase
protected $suffix = '_NewDataShouldNotAppear';
+ public static function setUpBeforeClass(): void
+ {
+ parent::setUpBeforeClass();
+
+ self::addSegments();
+ }
+
+ private static function addSegments()
+ {
+ Rules::setBrowserTriggerArchiving(false);
+ API::getInstance()->add('segment 1', urlencode(self::TEST_SEGMENT));
+ Rules::setBrowserTriggerArchiving(true);
+ }
+
/**
* @dataProvider getApiForTesting
*/
@@ -55,7 +75,7 @@ class ArchiveInvalidationTest extends SystemTestCase
'testSuffix' => 'Website' . self::$fixture->idSite2 . $this->suffix,
'date' => self::$fixture->dateTimeFirstDateWebsite2,
'periods' => 'day',
- 'segment' => 'pageUrl=@category/',
+ 'segment' => self::TEST_SEGMENT,
'setDateLastN' => 4, // 4months ahead
'otherRequestParameters' => array('expanded' => 1))
),
@@ -71,7 +91,7 @@ class ArchiveInvalidationTest extends SystemTestCase
'testSuffix' => 'Website' . self::$fixture->idSite2 . $this->suffix,
'date' => self::$fixture->dateTimeFirstDateWebsite2,
'periods' => 'month',
- 'segment' => 'pageUrl=@category/',
+ 'segment' => self::TEST_SEGMENT,
'setDateLastN' => 4, // 4months ahead
'otherRequestParameters' => array('expanded' => 1))
)
@@ -79,33 +99,33 @@ class ArchiveInvalidationTest extends SystemTestCase
}
/**
+ * test same api w/o invalidating or tracking (which also invalidates), (NewDataShouldNotAppear)
+ *
* @depends testApi
* @dataProvider getApiForTesting
*/
public function testSameApi($api, $params)
{
- $this->setBrowserArchivingTriggering(0);
- self::$fixture->trackMoreVisits($params['idSite']);
-
- $this->invalidateTestArchives();
+ Rules::setBrowserTriggerArchiving(false);
$this->runApiTests($api, $params);
}
/**
+ * test same api after invalidating (NewDataShouldAppear)
+ *
* @depends testApi
* @depends testSameApi
- * @dataProvider getAnotherApiForTesting
*/
- public function testAnotherApi($api, $params)
+ public function testAnotherApi()
{
- if ($params['periods'] === 'month') {
- // we do now need to invalidate days as well since weeks are based on weeks
- $this->invalidateTestArchive(self::$fixture->idSite2, 'week', self::$fixture->dateTimeFirstDateWebsite2, true);
- }
+ self::$fixture->trackMoreVisits(self::$fixture->idSite1);
+ self::$fixture->trackMoreVisits(self::$fixture->idSite2);
- $this->setBrowserArchivingTriggering(1);
+ Rules::setBrowserTriggerArchiving(true);
- $this->runApiTests($api, $params);
+ foreach ($this->getAnotherApiForTesting() as list($api, $params)) {
+ $this->runApiTests($api, $params);
+ }
}
/**
@@ -123,11 +143,6 @@ class ArchiveInvalidationTest extends SystemTestCase
return 'Archive_Invalidation';
}
- protected function setBrowserArchivingTriggering($value)
- {
- Config::getInstance()->General['enable_browser_archiving_triggering'] = $value;
- }
-
protected function invalidateTestArchives()
{
$dateToInvalidate1 = new \DateTime(self::$fixture->dateTimeFirstDateWebsite1);
diff --git a/tests/PHPUnit/System/expected/test_Archive_InvalidationWebsite2_NewDataShouldAppear__Actions.getPageUrls_day.xml b/tests/PHPUnit/System/expected/test_Archive_InvalidationWebsite2_NewDataShouldAppear__Actions.getPageUrls_day.xml
index e91a63b485..dbe050e5c2 100644
--- a/tests/PHPUnit/System/expected/test_Archive_InvalidationWebsite2_NewDataShouldAppear__Actions.getPageUrls_day.xml
+++ b/tests/PHPUnit/System/expected/test_Archive_InvalidationWebsite2_NewDataShouldAppear__Actions.getPageUrls_day.xml
@@ -4,14 +4,14 @@
<row>
<label>category</label>
<nb_visits>6</nb_visits>
- <nb_hits>9</nb_hits>
+ <nb_hits>6</nb_hits>
<sum_time_spent>0</sum_time_spent>
<sum_bandwidth>0</sum_bandwidth>
<nb_hits_with_bandwidth>0</nb_hits_with_bandwidth>
<min_bandwidth />
<max_bandwidth />
<entry_nb_visits>2</entry_nb_visits>
- <entry_nb_actions>18</entry_nb_actions>
+ <entry_nb_actions>12</entry_nb_actions>
<entry_sum_visit_length>2</entry_sum_visit_length>
<entry_bounce_count>0</entry_bounce_count>
<avg_bandwidth>0</avg_bandwidth>
@@ -24,8 +24,8 @@
<row>
<label>/Page1</label>
<nb_visits>2</nb_visits>
- <nb_uniq_visitors>3</nb_uniq_visitors>
- <nb_hits>3</nb_hits>
+ <nb_uniq_visitors>2</nb_uniq_visitors>
+ <nb_hits>2</nb_hits>
<sum_time_spent>0</sum_time_spent>
<sum_bandwidth>0</sum_bandwidth>
<nb_hits_with_bandwidth>0</nb_hits_with_bandwidth>
@@ -33,7 +33,7 @@
<max_bandwidth />
<entry_nb_uniq_visitors>2</entry_nb_uniq_visitors>
<entry_nb_visits>2</entry_nb_visits>
- <entry_nb_actions>18</entry_nb_actions>
+ <entry_nb_actions>12</entry_nb_actions>
<entry_sum_visit_length>2</entry_sum_visit_length>
<entry_bounce_count>0</entry_bounce_count>
<avg_time_on_page>0</avg_time_on_page>
@@ -45,8 +45,8 @@
<row>
<label>/Page2</label>
<nb_visits>2</nb_visits>
- <nb_uniq_visitors>3</nb_uniq_visitors>
- <nb_hits>3</nb_hits>
+ <nb_uniq_visitors>2</nb_uniq_visitors>
+ <nb_hits>2</nb_hits>
<sum_time_spent>0</sum_time_spent>
<sum_bandwidth>0</sum_bandwidth>
<nb_hits_with_bandwidth>0</nb_hits_with_bandwidth>
@@ -61,8 +61,8 @@
<row>
<label>/NewPage</label>
<nb_visits>1</nb_visits>
- <nb_uniq_visitors>2</nb_uniq_visitors>
- <nb_hits>2</nb_hits>
+ <nb_uniq_visitors>1</nb_uniq_visitors>
+ <nb_hits>1</nb_hits>
<sum_time_spent>0</sum_time_spent>
<sum_bandwidth>0</sum_bandwidth>
<nb_hits_with_bandwidth>0</nb_hits_with_bandwidth>
@@ -95,8 +95,8 @@
<row>
<label>/Contact</label>
<nb_visits>2</nb_visits>
- <nb_uniq_visitors>3</nb_uniq_visitors>
- <nb_hits>3</nb_hits>
+ <nb_uniq_visitors>2</nb_uniq_visitors>
+ <nb_hits>2</nb_hits>
<sum_time_spent>0</sum_time_spent>
<sum_bandwidth>0</sum_bandwidth>
<nb_hits_with_bandwidth>0</nb_hits_with_bandwidth>
@@ -113,8 +113,8 @@
<row>
<label>/Home</label>
<nb_visits>2</nb_visits>
- <nb_uniq_visitors>3</nb_uniq_visitors>
- <nb_hits>3</nb_hits>
+ <nb_uniq_visitors>2</nb_uniq_visitors>
+ <nb_hits>2</nb_hits>
<sum_time_spent>0</sum_time_spent>
<sum_bandwidth>0</sum_bandwidth>
<nb_hits_with_bandwidth>0</nb_hits_with_bandwidth>
@@ -131,7 +131,7 @@
<row>
<label>Contact</label>
<nb_visits>2</nb_visits>
- <nb_hits>3</nb_hits>
+ <nb_hits>2</nb_hits>
<sum_time_spent>0</sum_time_spent>
<sum_bandwidth>0</sum_bandwidth>
<nb_hits_with_bandwidth>0</nb_hits_with_bandwidth>
@@ -148,8 +148,8 @@
<row>
<label>/ThankYou</label>
<nb_visits>2</nb_visits>
- <nb_uniq_visitors>3</nb_uniq_visitors>
- <nb_hits>3</nb_hits>
+ <nb_uniq_visitors>2</nb_uniq_visitors>
+ <nb_hits>2</nb_hits>
<sum_time_spent>0</sum_time_spent>
<sum_bandwidth>0</sum_bandwidth>
<nb_hits_with_bandwidth>0</nb_hits_with_bandwidth>
diff --git a/tests/PHPUnit/System/expected/test_Archive_InvalidationWebsite2_NewDataShouldAppear__Actions.getPageUrls_month.xml b/tests/PHPUnit/System/expected/test_Archive_InvalidationWebsite2_NewDataShouldAppear__Actions.getPageUrls_month.xml
index 154dd2715e..9deb547436 100644
--- a/tests/PHPUnit/System/expected/test_Archive_InvalidationWebsite2_NewDataShouldAppear__Actions.getPageUrls_month.xml
+++ b/tests/PHPUnit/System/expected/test_Archive_InvalidationWebsite2_NewDataShouldAppear__Actions.getPageUrls_month.xml
@@ -4,14 +4,14 @@
<row>
<label>category</label>
<nb_visits>6</nb_visits>
- <nb_hits>9</nb_hits>
+ <nb_hits>6</nb_hits>
<sum_time_spent>0</sum_time_spent>
<sum_bandwidth>0</sum_bandwidth>
<nb_hits_with_bandwidth>0</nb_hits_with_bandwidth>
<min_bandwidth />
<max_bandwidth />
<entry_nb_visits>2</entry_nb_visits>
- <entry_nb_actions>18</entry_nb_actions>
+ <entry_nb_actions>12</entry_nb_actions>
<entry_sum_visit_length>2</entry_sum_visit_length>
<entry_bounce_count>0</entry_bounce_count>
<avg_bandwidth>0</avg_bandwidth>
@@ -24,17 +24,17 @@
<row>
<label>/Page1</label>
<nb_visits>2</nb_visits>
- <nb_hits>3</nb_hits>
+ <nb_hits>2</nb_hits>
<sum_time_spent>0</sum_time_spent>
<sum_bandwidth>0</sum_bandwidth>
<nb_hits_with_bandwidth>0</nb_hits_with_bandwidth>
<min_bandwidth />
<max_bandwidth />
<entry_nb_visits>2</entry_nb_visits>
- <entry_nb_actions>18</entry_nb_actions>
+ <entry_nb_actions>12</entry_nb_actions>
<entry_sum_visit_length>2</entry_sum_visit_length>
<entry_bounce_count>0</entry_bounce_count>
- <sum_daily_nb_uniq_visitors>3</sum_daily_nb_uniq_visitors>
+ <sum_daily_nb_uniq_visitors>2</sum_daily_nb_uniq_visitors>
<sum_daily_entry_nb_uniq_visitors>2</sum_daily_entry_nb_uniq_visitors>
<avg_time_on_page>0</avg_time_on_page>
<bounce_rate>0%</bounce_rate>
@@ -45,13 +45,13 @@
<row>
<label>/Page2</label>
<nb_visits>2</nb_visits>
- <nb_hits>3</nb_hits>
+ <nb_hits>2</nb_hits>
<sum_time_spent>0</sum_time_spent>
<sum_bandwidth>0</sum_bandwidth>
<nb_hits_with_bandwidth>0</nb_hits_with_bandwidth>
<min_bandwidth />
<max_bandwidth />
- <sum_daily_nb_uniq_visitors>3</sum_daily_nb_uniq_visitors>
+ <sum_daily_nb_uniq_visitors>2</sum_daily_nb_uniq_visitors>
<avg_time_on_page>0</avg_time_on_page>
<bounce_rate>0%</bounce_rate>
<exit_rate>0%</exit_rate>
@@ -61,13 +61,13 @@
<row>
<label>/NewPage</label>
<nb_visits>1</nb_visits>
- <nb_hits>2</nb_hits>
+ <nb_hits>1</nb_hits>
<sum_time_spent>0</sum_time_spent>
<sum_bandwidth>0</sum_bandwidth>
<nb_hits_with_bandwidth>0</nb_hits_with_bandwidth>
<min_bandwidth />
<max_bandwidth />
- <sum_daily_nb_uniq_visitors>2</sum_daily_nb_uniq_visitors>
+ <sum_daily_nb_uniq_visitors>1</sum_daily_nb_uniq_visitors>
<avg_time_on_page>0</avg_time_on_page>
<bounce_rate>0%</bounce_rate>
<exit_rate>0%</exit_rate>
@@ -95,13 +95,13 @@
<row>
<label>/Contact</label>
<nb_visits>2</nb_visits>
- <nb_hits>3</nb_hits>
+ <nb_hits>2</nb_hits>
<sum_time_spent>0</sum_time_spent>
<sum_bandwidth>0</sum_bandwidth>
<nb_hits_with_bandwidth>0</nb_hits_with_bandwidth>
<min_bandwidth />
<max_bandwidth />
- <sum_daily_nb_uniq_visitors>3</sum_daily_nb_uniq_visitors>
+ <sum_daily_nb_uniq_visitors>2</sum_daily_nb_uniq_visitors>
<avg_bandwidth>0</avg_bandwidth>
<avg_page_load_time>0</avg_page_load_time>
<avg_time_on_page>0</avg_time_on_page>
@@ -113,13 +113,13 @@
<row>
<label>/Home</label>
<nb_visits>2</nb_visits>
- <nb_hits>3</nb_hits>
+ <nb_hits>2</nb_hits>
<sum_time_spent>0</sum_time_spent>
<sum_bandwidth>0</sum_bandwidth>
<nb_hits_with_bandwidth>0</nb_hits_with_bandwidth>
<min_bandwidth />
<max_bandwidth />
- <sum_daily_nb_uniq_visitors>3</sum_daily_nb_uniq_visitors>
+ <sum_daily_nb_uniq_visitors>2</sum_daily_nb_uniq_visitors>
<avg_bandwidth>0</avg_bandwidth>
<avg_page_load_time>0</avg_page_load_time>
<avg_time_on_page>0</avg_time_on_page>
@@ -131,7 +131,7 @@
<row>
<label>Contact</label>
<nb_visits>2</nb_visits>
- <nb_hits>3</nb_hits>
+ <nb_hits>2</nb_hits>
<sum_time_spent>0</sum_time_spent>
<sum_bandwidth>0</sum_bandwidth>
<nb_hits_with_bandwidth>0</nb_hits_with_bandwidth>
@@ -148,14 +148,14 @@
<row>
<label>/ThankYou</label>
<nb_visits>2</nb_visits>
- <nb_hits>3</nb_hits>
+ <nb_hits>2</nb_hits>
<sum_time_spent>0</sum_time_spent>
<sum_bandwidth>0</sum_bandwidth>
<nb_hits_with_bandwidth>0</nb_hits_with_bandwidth>
<min_bandwidth />
<max_bandwidth />
<exit_nb_visits>2</exit_nb_visits>
- <sum_daily_nb_uniq_visitors>3</sum_daily_nb_uniq_visitors>
+ <sum_daily_nb_uniq_visitors>2</sum_daily_nb_uniq_visitors>
<sum_daily_exit_nb_uniq_visitors>2</sum_daily_exit_nb_uniq_visitors>
<avg_time_on_page>0</avg_time_on_page>
<bounce_rate>0%</bounce_rate>
diff --git a/tests/PHPUnit/System/expected/test_Archive_InvalidationWebsite2_NewDataShouldAppear__VisitsSummary.get_day.xml b/tests/PHPUnit/System/expected/test_Archive_InvalidationWebsite2_NewDataShouldAppear__VisitsSummary.get_day.xml
index bfd375c5c9..bce9f8af20 100644
--- a/tests/PHPUnit/System/expected/test_Archive_InvalidationWebsite2_NewDataShouldAppear__VisitsSummary.get_day.xml
+++ b/tests/PHPUnit/System/expected/test_Archive_InvalidationWebsite2_NewDataShouldAppear__VisitsSummary.get_day.xml
@@ -4,13 +4,13 @@
<nb_uniq_visitors>2</nb_uniq_visitors>
<nb_users>0</nb_users>
<nb_visits>2</nb_visits>
- <nb_actions>18</nb_actions>
+ <nb_actions>12</nb_actions>
<nb_visits_converted>0</nb_visits_converted>
<bounce_count>0</bounce_count>
<sum_visit_length>2</sum_visit_length>
- <max_actions>12</max_actions>
+ <max_actions>6</max_actions>
<bounce_rate>0%</bounce_rate>
- <nb_actions_per_visit>9</nb_actions_per_visit>
+ <nb_actions_per_visit>6</nb_actions_per_visit>
<avg_time_on_site>1</avg_time_on_site>
</result>
<result date="2010-01-07" />
diff --git a/tests/PHPUnit/System/expected/test_Archive_InvalidationWebsite2_NewDataShouldAppear__VisitsSummary.get_month.xml b/tests/PHPUnit/System/expected/test_Archive_InvalidationWebsite2_NewDataShouldAppear__VisitsSummary.get_month.xml
index 1e897c6120..3d09bf99a2 100644
--- a/tests/PHPUnit/System/expected/test_Archive_InvalidationWebsite2_NewDataShouldAppear__VisitsSummary.get_month.xml
+++ b/tests/PHPUnit/System/expected/test_Archive_InvalidationWebsite2_NewDataShouldAppear__VisitsSummary.get_month.xml
@@ -4,13 +4,13 @@
<nb_uniq_visitors>2</nb_uniq_visitors>
<nb_users>0</nb_users>
<nb_visits>2</nb_visits>
- <nb_actions>18</nb_actions>
+ <nb_actions>12</nb_actions>
<nb_visits_converted>0</nb_visits_converted>
<bounce_count>0</bounce_count>
<sum_visit_length>2</sum_visit_length>
- <max_actions>12</max_actions>
+ <max_actions>6</max_actions>
<bounce_rate>0%</bounce_rate>
- <nb_actions_per_visit>9</nb_actions_per_visit>
+ <nb_actions_per_visit>6</nb_actions_per_visit>
<avg_time_on_site>1</avg_time_on_site>
</result>
<result date="2010-02" />