diff --git a/core/Tracker.php b/core/Tracker.php
index 72bd3cd2891..bd72e049209 100644
--- a/core/Tracker.php
+++ b/core/Tracker.php
@@ -44,9 +44,6 @@ class Tracker
const LENGTH_HEX_ID_STRING = 16;
const LENGTH_BINARY_ID = 8;
- protected static $forcedDateTime = null;
- protected static $forcedIpString = null;
-
protected static $pluginsNotToLoad = array();
protected static $pluginsToLoad = array();
@@ -90,21 +87,9 @@ protected function outputAccessControlHeaders()
public function clear()
{
- self::$forcedIpString = null;
- self::$forcedDateTime = null;
$this->stateValid = self::STATE_NOTHING_TO_NOTICE;
}
- public static function setForceIp($ipString)
- {
- self::$forcedIpString = $ipString;
- }
-
- public static function setForceDateTime($dateTime)
- {
- self::$forcedDateTime = $dateTime;
- }
-
/**
* Do not load the specified plugins (used during testing, to disable Provider plugin)
* @param array $plugins
@@ -488,15 +473,13 @@ public static function getDatetimeFromTimestamp($timestamp)
/**
* Initialization
+ * @param Request $request
*/
protected function init(Request $request)
{
$this->loadTrackerPlugins($request);
- $this->handleTrackingApi($request);
$this->handleDisabledTracker();
$this->handleEmptyRequest($request);
-
- Common::printDebug("Current datetime: " . date("Y-m-d H:i:s", $request->getCurrentTimestamp()));
}
/**
@@ -748,29 +731,6 @@ protected function getTokenAuth()
return Common::getRequestVar('token_auth', false);
}
- /**
- * This method allows to set custom IP + server time + visitor ID, when using Tracking API.
- * These two attributes can be only set by the Super User (passing token_auth).
- */
- protected function handleTrackingApi(Request $request)
- {
- if (!$request->isAuthenticated()) {
- return;
- }
-
- // Custom IP to use for this visitor
- $customIp = $request->getParam('cip');
- if (!empty($customIp)) {
- $this->setForceIp($customIp);
- }
-
- // Custom server date time to use
- $customDatetime = $request->getParam('cdt');
- if (!empty($customDatetime)) {
- $this->setForceDateTime($customDatetime);
- }
- }
-
public static function setTestEnvironment($args = null, $requestMethod = null)
{
if (is_null($args)) {
@@ -816,18 +776,6 @@ public static function setTestEnvironment($args = null, $requestMethod = null)
\Piwik\Plugins\PrivacyManager\IPAnonymizer::activate();
}
- // Custom IP to use for this visitor
- $customIp = Common::getRequestVar('cip', false, null, $args);
- if (!empty($customIp)) {
- self::setForceIp($customIp);
- }
-
- // Custom server date time to use
- $customDatetime = Common::getRequestVar('cdt', false, null, $args);
- if (!empty($customDatetime)) {
- self::setForceDateTime($customDatetime);
- }
-
$pluginsDisabled = array('Provider');
// Disable provider plugin, because it is so slow to do many reverse ip lookups
@@ -870,8 +818,7 @@ protected function trackRequest($params, $tokenAuth)
try {
if ($this->isVisitValid()) {
- $request->setForceDateTime(self::$forcedDateTime);
- $request->setForceIp(self::$forcedIpString);
+ Common::printDebug("Current datetime: " . date("Y-m-d H:i:s", $request->getCurrentTimestamp()));
$visit = $this->getNewVisitObject();
$visit->setRequest($request);
diff --git a/core/Tracker/Request.php b/core/Tracker/Request.php
index 212abbd0d26..aad200660f3 100644
--- a/core/Tracker/Request.php
+++ b/core/Tracker/Request.php
@@ -35,6 +35,8 @@ class Request
const UNKNOWN_RESOLUTION = 'unknown';
+ const CUSTOM_TIMESTAMP_DOES_NOT_REQUIRE_TOKENAUTH_WHEN_NEWER_THAN = 14400; // 4 hours
+
/**
* @param $params
* @param bool|string $tokenAuth
@@ -47,7 +49,6 @@ public function __construct($params, $tokenAuth = false)
$this->params = $params;
$this->tokenAuth = $tokenAuth;
$this->timestamp = time();
- $this->enforcedIp = false;
// When the 'url' and referrer url parameter are not given, we might be in the 'Simple Image Tracker' mode.
// The URL can default to the Referrer, which will be in this case
@@ -319,13 +320,54 @@ public function getParams()
public function getCurrentTimestamp()
{
+ $cdt = $this->getCustomTimestamp();
+ if(!empty($cdt)) {
+ return $cdt;
+ }
return $this->timestamp;
}
- protected function isTimestampValid($time)
+ protected function getCustomTimestamp()
+ {
+ $cdt = $this->getParam('cdt');
+ if (empty($cdt)) {
+ return false;
+ }
+ if (!is_numeric($cdt)) {
+ $cdt = strtotime($cdt);
+ }
+ if (!$this->isTimestampValid($cdt, $this->timestamp)) {
+ Common::printDebug(sprintf("Datetime %s is not valid", date("Y-m-d H:i:m", $cdt)));
+ return false;
+ }
+
+ // If timestamp in the past, token_auth is required
+ $timeFromNow = $this->timestamp - $cdt;
+ $isTimestampRecent = $timeFromNow < self::CUSTOM_TIMESTAMP_DOES_NOT_REQUIRE_TOKENAUTH_WHEN_NEWER_THAN;
+ if (!$isTimestampRecent) {
+ if(!$this->isAuthenticated()) {
+ Common::printDebug(sprintf("Custom timestamp is %s seconds old, requires &token_auth...", $timeFromNow));
+ Common::printDebug("WARN: Tracker API 'cdt' was used with invalid token_auth");
+ return false;
+ }
+ }
+ return $cdt;
+ }
+
+ /**
+ * Returns true if the timestamp is valid ie. timestamp is sometime in the last 10 years and is not in the future.
+ *
+ * @param $time int Timestamp to test
+ * @param $now int Current timestamp
+ * @return bool
+ */
+ protected function isTimestampValid($time, $now = null)
{
- return $time <= $this->getCurrentTimestamp()
- && $time > $this->getCurrentTimestamp() - 10 * 365 * 86400;
+ if(empty($now)) {
+ $now = $this->getCurrentTimestamp();
+ }
+ return $time <= $now
+ && $time > $now - 10 * 365 * 86400;
}
public function getIdSite()
@@ -521,33 +563,11 @@ public function getVisitorId()
public function getIp()
{
- if (!empty($this->enforcedIp)) {
- $ipString = $this->enforcedIp;
- } else {
- $ipString = IP::getIpFromHeader();
- }
-
+ $ipString = $this->getIpString();
$ip = IP::P2N($ipString);
return $ip;
}
- public function setForceIp($ip)
- {
- if (!empty($ip)) {
- $this->enforcedIp = $ip;
- }
- }
-
- public function setForceDateTime($dateTime)
- {
- if (!is_numeric($dateTime)) {
- $dateTime = strtotime($dateTime);
- }
- if (!empty($dateTime)) {
- $this->timestamp = $dateTime;
- }
- }
-
public function getForcedUserId()
{
$userId = $this->getParam('uid');
@@ -611,4 +631,23 @@ public function getUserIdHashed($userId)
{
return substr( sha1( $userId ), 0, 16);
}
+
+ /**
+ * @return mixed|string
+ * @throws Exception
+ */
+ private function getIpString()
+ {
+ $cip = $this->getParam('cip');
+
+ if(empty($cip)) {
+ return IP::getIpFromHeader();
+ }
+
+ if(!$this->isAuthenticated()) {
+ Common::printDebug("WARN: Tracker API 'cip' was used with invalid token_auth");
+ return IP::getIpFromHeader();
+ }
+ return $cip;
+ }
}
diff --git a/core/Tracker/Visit.php b/core/Tracker/Visit.php
index 0ce45c3659d..c8fb12d3897 100644
--- a/core/Tracker/Visit.php
+++ b/core/Tracker/Visit.php
@@ -467,6 +467,7 @@ private function printVisitorInformation()
$debugVisitInfo = $this->visitorInfo;
$debugVisitInfo['idvisitor'] = bin2hex($debugVisitInfo['idvisitor']);
$debugVisitInfo['config_id'] = bin2hex($debugVisitInfo['config_id']);
+ $debugVisitInfo['location_ip'] = IP::N2P($debugVisitInfo['location_ip']);
Common::printDebug($debugVisitInfo);
}
diff --git a/core/testMinimumPhpVersion.php b/core/testMinimumPhpVersion.php
index 542279f8723..8fcface7f81 100644
--- a/core/testMinimumPhpVersion.php
+++ b/core/testMinimumPhpVersion.php
@@ -91,7 +91,11 @@ function Piwik_ExitWithMessage($message, $optionalTrace = false, $optionalLinks
{
if (!headers_sent()) {
header('Content-Type: text/html; charset=utf-8');
- header('HTTP/1.1 500 Internal Server Error');
+
+ $isInternalServerError = preg_match('/(sql|database|mysql)/i', $message);
+ if($isInternalServerError) {
+ header('HTTP/1.1 500 Internal Server Error');
+ }
}
if ($optionalTrace) {
diff --git a/misc/log-analytics/README.md b/misc/log-analytics/README.md
index 6c4aadf6752..a9d53d8dfc1 100644
--- a/misc/log-analytics/README.md
+++ b/misc/log-analytics/README.md
@@ -20,7 +20,7 @@ and will not track bots, static files, or error requests.
If you wish to track all requests the following command would be used:
- python /path/to/piwik/misc/log-analytics/import_logs.py --url=http://mysite/piwik/ access.log --idsite=1234 --recorders=4 --enable-http-errors --enable-http-redirects --enable-static --enable-bots
+ python /path/to/piwik/misc/log-analytics/import_logs.py --url=http://mysite/piwik/ --idsite=1234 --recorders=4 --enable-http-errors --enable-http-redirects --enable-static --enable-bots access.log
## How to import your logs automatically every day?
diff --git a/plugins/CoreConsole/Commands/TestsRun.php b/plugins/CoreConsole/Commands/TestsRun.php
index 41783370576..de32f0b5347 100644
--- a/plugins/CoreConsole/Commands/TestsRun.php
+++ b/plugins/CoreConsole/Commands/TestsRun.php
@@ -90,7 +90,7 @@ protected function execute(InputInterface $input, OutputInterface $output)
private function executeTestFile($testFile, $options, $command, OutputInterface $output)
{
$params = $options . " " . $testFile;
- $cmd = sprintf("cd %s/tests/PHPUnit && %s %s", PIWIK_DOCUMENT_ROOT, $command, $params);
+ $cmd = $this->getCommand($command, $params);
$output->writeln('Executing command: ' . $cmd . '');
passthru($cmd);
$output->writeln("");
@@ -104,11 +104,12 @@ private function executeTestGroups($suite, $groups, $options, $command, OutputIn
foreach ($groups as $group) {
$params = '--group ' . $group . ' ' . str_replace('%group%', $group, $options);
+
if (!empty($suite)) {
$params .= ' --testsuite ' . $suite;
}
-
- $cmd = sprintf('cd %s/tests/PHPUnit && %s %s', PIWIK_DOCUMENT_ROOT, $command, $params);
+
+ $cmd = $this->getCommand($command, $params);
$output->writeln('Executing command: ' . $cmd . '');
passthru($cmd);
$output->writeln("");
@@ -119,4 +120,15 @@ private function getTestsGroups()
{
return array('Core', 'Plugins', 'UI');
}
+
+ /**
+ * @param $command
+ * @param $params
+ * @return string
+ */
+ private function getCommand($command, $params)
+ {
+ $cmd = sprintf('cd %s/tests/PHPUnit && %s %s', PIWIK_DOCUMENT_ROOT, $command, $params);
+ return $cmd;
+ }
}
\ No newline at end of file
diff --git a/plugins/UserSettings/tests/Fixtures/LanguageFixture.php b/plugins/UserSettings/tests/Fixtures/LanguageFixture.php
index dc6b4fcb0b2..6cbd9d8343f 100644
--- a/plugins/UserSettings/tests/Fixtures/LanguageFixture.php
+++ b/plugins/UserSettings/tests/Fixtures/LanguageFixture.php
@@ -54,6 +54,7 @@ private function trackVisits() {
$this->dateTime,
$defaultInit = false
);
+ $tracker->setTokenAuth(self::getTokenAuth());
$hour = 1;
foreach ($this->getBrowserLangs() as $browserLang) {
diff --git a/tests/LocalTracker.php b/tests/LocalTracker.php
index afa0a6a4bcc..ecddbe5c9f9 100755
--- a/tests/LocalTracker.php
+++ b/tests/LocalTracker.php
@@ -45,8 +45,6 @@ protected function sendRequest($url, $method = 'GET', $data = null, $force = fal
// unset cached values
Cache::$trackerCache = null;
- Tracker::setForceIp(null);
- Tracker::setForceDateTime(null);
// save some values
$plugins = Config::getInstance()->Plugins['Plugins'];
diff --git a/tests/PHPUnit/Fixtures/OneVisitWithAbnormalPageviewUrls.php b/tests/PHPUnit/Fixtures/OneVisitWithAbnormalPageviewUrls.php
index 56c3e294045..22999000ee4 100644
--- a/tests/PHPUnit/Fixtures/OneVisitWithAbnormalPageviewUrls.php
+++ b/tests/PHPUnit/Fixtures/OneVisitWithAbnormalPageviewUrls.php
@@ -41,7 +41,7 @@ private function trackVisits()
{
$dateTime = $this->dateTime;
$idSite = $this->idSite;
- $t = self::getTracker($idSite, $dateTime, $defaultInit = true, $useThirdPartyCookie = 1);
+ $t = self::getTracker($idSite, $dateTime, $defaultInit = true);
$t->setUrlReferrer('http://www.google.com/search?q=piwik');
$t->setUrl('http://example.org/foo/bar.html');
diff --git a/tests/PHPUnit/Fixtures/SomeVisitsCustomVariablesCampaignsNotHeuristics.php b/tests/PHPUnit/Fixtures/SomeVisitsCustomVariablesCampaignsNotHeuristics.php
index 9682dd086ba..1985b9090cc 100644
--- a/tests/PHPUnit/Fixtures/SomeVisitsCustomVariablesCampaignsNotHeuristics.php
+++ b/tests/PHPUnit/Fixtures/SomeVisitsCustomVariablesCampaignsNotHeuristics.php
@@ -63,6 +63,7 @@ private function trackVisits()
// Create a new Tracker object, with different attributes
$t2 = self::getTracker($idSite, $dateTime, $defaultInit = false);
+ $t2->setTokenAuth(self::getTokenAuth());
// Make sure the ID is different at first
$visitorId2 = $t2->getVisitorId();
diff --git a/tests/PHPUnit/Integration/Tracker/ActionTest.php b/tests/PHPUnit/Integration/Tracker/ActionTest.php
index 1246fb15f64..17da150bd69 100644
--- a/tests/PHPUnit/Integration/Tracker/ActionTest.php
+++ b/tests/PHPUnit/Integration/Tracker/ActionTest.php
@@ -22,6 +22,7 @@
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
*
* @group Core
+ * @group ActionTest
*/
class Core_Tracker_ActionTest extends IntegrationTestCase
{
diff --git a/tests/PHPUnit/Integration/Tracker/Visit2Test.php b/tests/PHPUnit/Integration/Tracker/Visit2Test.php
index e28c3ba410d..a5b3c0541cd 100644
--- a/tests/PHPUnit/Integration/Tracker/Visit2Test.php
+++ b/tests/PHPUnit/Integration/Tracker/Visit2Test.php
@@ -135,6 +135,7 @@ protected function updateExistingVisit($valuesToUpdate)
/**
* @group Core
+ * @group VisitTest
*/
class VisitTest extends IntegrationTestCase
{
@@ -157,7 +158,6 @@ public function tearDown()
public function test_handleNewVisitWithoutConversion_shouldTriggerDimensions()
{
$request = new \Piwik\Tracker\Request(array());
- $request->setForceIp('127.0.0.1');
$visitor = new \Piwik\Tracker\Visitor($request, '');
$visit = new FakeTrackerVisit($request);
@@ -180,7 +180,6 @@ public function test_handleNewVisitWithoutConversion_shouldTriggerDimensions()
public function test_handleNewVisitWithConversion_shouldTriggerDimensions()
{
$request = new \Piwik\Tracker\Request(array());
- $request->setForceIp('127.0.0.1');
$visitor = new \Piwik\Tracker\Visitor($request, '');
$visit = new FakeTrackerVisit($request);
@@ -199,7 +198,6 @@ public function test_handleNewVisitWithConversion_shouldTriggerDimensions()
public function test_handleExistingVisitWithoutConversion_shouldTriggerDimensions()
{
$request = new \Piwik\Tracker\Request(array());
- $request->setForceIp('127.0.0.1');
$visitor = new \Piwik\Tracker\Visitor($request, '');
$visit = new FakeTrackerVisit($request);
@@ -223,7 +221,6 @@ public function test_handleExistingVisitWithoutConversion_shouldTriggerDimension
public function test_handleExistingVisitWithConversion_shouldTriggerDimensions()
{
$request = new \Piwik\Tracker\Request(array());
- $request->setForceIp('127.0.0.1');
$visitor = new \Piwik\Tracker\Visitor($request, '');
$visit = new FakeTrackerVisit($request);
diff --git a/tests/PHPUnit/System/BackwardsCompatibility1XTest.php b/tests/PHPUnit/System/BackwardsCompatibility1XTest.php
index 5b27b2e2796..0ed7dc208d2 100644
--- a/tests/PHPUnit/System/BackwardsCompatibility1XTest.php
+++ b/tests/PHPUnit/System/BackwardsCompatibility1XTest.php
@@ -43,19 +43,31 @@ public static function setUpBeforeClass()
Db::query("TRUNCATE TABLE " . Common::prefixTable($table));
}
- // add two visits from same visitor on dec. 29
- $t = Fixture::getTracker(1, '2012-12-29 01:01:30', $defaultInit = true);
+ self::trackTwoVisitsOnSameDay();
+
+ // launch archiving
+ VisitFrequencyApi::getInstance()->get(1, 'year', '2012-12-29');
+ }
+
+
+ /**
+ * add two visits from same visitor on dec. 29
+ */
+ private static function trackTwoVisitsOnSameDay()
+ {
+ $t = Fixture::getTracker(1, '2012-12-29 01:01:30', $defaultInit = true, $useLocal = true);
+ $t->enableBulkTracking();
+
$t->setUrl('http://site.com/index.htm');
$t->setIp('136.5.3.2');
- Fixture::checkResponse($t->doTrackPageView('incredible title!'));
+ $t->doTrackPageView('incredible title!');
$t->setForceVisitDateTime('2012-12-29 03:01:30');
$t->setUrl('http://site.com/other/index.htm');
$t->DEBUG_APPEND_URL = '&_idvc=2'; // make sure visit is marked as returning
- Fixture::checkResponse($t->doTrackPageView('other incredible title!'));
+ $t->doTrackPageView('other incredible title!');
- // launch archiving
- VisitFrequencyApi::getInstance()->get(1, 'year', '2012-12-29');
+ $t->doBulkTrack();
}
/**
diff --git a/tests/README.md b/tests/README.md
index 1e1299eae77..8a418cb143c 100644
--- a/tests/README.md
+++ b/tests/README.md
@@ -161,7 +161,6 @@ By default tests running on Travis CI will log all messages of at least `INFO` l
Note: `DEBUG` and `VERBOSE` messages are not logged by default (to keep Travis page loading fast). At any time you can temporarirly enable logging by [modifying this file](https://github.com/piwik/piwik/blob/master/tests/PHPUnit/config.ini.travis.php#L23-27) and changing `log_level = info` to `log_level = debug` or `log_level = verbose`.
-
### Screenshot tests build artifacts
The screenshot tests generated by the continuous integration server are uploaded in [builds-artifacts.piwik.org/ui-tests.master/](http://builds-artifacts.piwik.org/ui-tests.master/?C=M;O=D)
@@ -171,6 +170,12 @@ The screenshot tests generated by the continuous integration server are uploaded
See [tests/README.troubleshooting.md](https://github.com/piwik/piwik/blob/master/tests/README.troubleshooting.md) for troubleshooting the tests.
## Advanced users
+
+### Debugging tests
+
+As a software developer writing tests it can be useful to be able to set breakpoints and debug while running tests. If you use Phpstorm [read this answer](http://stackoverflow.com/a/14998884/3759928) to learn to configure Phpstorm with the PHPUnit from Composer.
+
+
### Benchmarks
See [tests/PHPUnit/Benchmarks/README.md](https://github.com/piwik/piwik/blob/master/tests/PHPUnit/Benchmarks/README.md) to learn about running Benchmark tests.
diff --git a/tests/README.testing-data.md b/tests/README.testing-data.md
index 5ab7b4a67d3..63431a39668 100644
--- a/tests/README.testing-data.md
+++ b/tests/README.testing-data.md
@@ -5,7 +5,7 @@ As a developer it may be useful to generate test data. Follow these steps:
3. Create a Goal eg. URL Contains "blog"
4. Import data from an anonimized test log file in piwik/tests/resources/ directory. Run the following command:
- $ python /home/piwik/misc/log-analytics/import_logs.py --url=http://localhost/path/ /path/to/piwik/tests/resources/access.log-dev-anon-9-days-nov-2012.log.bz2 --idsite=1 --enable-http-errors --enable-http-redirects --enable-static --enable-bots
+ $ python /home/piwik/misc/log-analytics/import_logs.py --url=http://localhost/path/ --idsite=1 --enable-http-errors --enable-http-redirects --enable-static --enable-bots /path/to/piwik/tests/resources/access.log-dev-anon-9-days-nov-2012.log.bz2
This will import 9 days worth of data from Nov 20th-Nov 29th 2012.