server/tests/lib/LoggerTest.php
Christoph Wurst ad757805ca Pass the exception context to the crash reporter
This should allow better reports as often the app id is passed
as context. While this is not used right now, I'd like to have this
for NC13 as adding it later will break the interface for existing apps

Signed-off-by: Christoph Wurst <christoph@winzerhof-wurst.at>
2017-11-14 14:28:04 +01:00

208 lines
5.5 KiB
PHP

<?php
/**
* Copyright (c) 2014 Thomas Müller <thomas.mueller@tmit.eu>
* This file is licensed under the Affero General Public License version 3 or
* later.
* See the COPYING-README file.
*/
namespace Test;
use OC\Log;
class LoggerTest extends TestCase {
/** @var \OC\SystemConfig|\PHPUnit_Framework_MockObject_MockObject */
private $config;
/** @var \OCP\Support\CrashReport\IRegistry|\PHPUnit_Framework_MockObject_MockObject */
private $registry;
/** @var \OCP\ILogger */
private $logger;
/** @var array */
static private $logs = array();
protected function setUp() {
parent::setUp();
self::$logs = array();
$this->config = $this->createMock(\OC\SystemConfig::class);
$this->registry = $this->createMock(\OCP\Support\CrashReport\IRegistry::class);
$this->logger = new Log('Test\LoggerTest', $this->config, null, $this->registry);
}
public function testInterpolation() {
$logger = $this->logger;
$logger->warning('{Message {nothing} {user} {foo.bar} a}', array('user' => 'Bob', 'foo.bar' => 'Bar'));
$expected = array('2 {Message {nothing} Bob Bar a}');
$this->assertEquals($expected, $this->getLogs());
}
public function testAppCondition() {
$this->config->expects($this->any())
->method('getValue')
->will(($this->returnValueMap([
['loglevel', \OCP\Util::WARN, \OCP\Util::WARN],
['log.condition', [], ['apps' => ['files']]]
])));
$logger = $this->logger;
$logger->info('Don\'t display info messages');
$logger->info('Show info messages of files app', ['app' => 'files']);
$logger->warning('Show warning messages of other apps');
$expected = [
'1 Show info messages of files app',
'2 Show warning messages of other apps',
];
$this->assertEquals($expected, $this->getLogs());
}
private function getLogs() {
return self::$logs;
}
public static function write($app, $message, $level) {
self::$logs[]= "$level $message";
}
public function userAndPasswordData() {
return [
['abc', 'def'],
['mySpecialUsername', 'MySuperSecretPassword'],
['my-user', '324324()#ä234'],
['my-user', ')qwer'],
['my-user', 'qwer)asdf'],
['my-user', 'qwer)'],
['my-user', '(qwer'],
['my-user', 'qwer(asdf'],
['my-user', 'qwer('],
];
}
/**
* @dataProvider userAndPasswordData
*/
public function testDetectlogin($user, $password) {
$e = new \Exception('test');
$this->registry->expects($this->once())
->method('delegateReport')
->with($e, []);
$this->logger->logException($e);
$logLines = $this->getLogs();
foreach($logLines as $logLine) {
$this->assertNotContains($user, $logLine);
$this->assertNotContains($password, $logLine);
$this->assertContains('login(*** sensitive parameters replaced ***)', $logLine);
}
}
/**
* @dataProvider userAndPasswordData
*/
public function testDetectcheckPassword($user, $password) {
$e = new \Exception('test');
$this->registry->expects($this->once())
->method('delegateReport')
->with($e, []);
$this->logger->logException($e);
$logLines = $this->getLogs();
foreach($logLines as $logLine) {
$this->assertNotContains($user, $logLine);
$this->assertNotContains($password, $logLine);
$this->assertContains('checkPassword(*** sensitive parameters replaced ***)', $logLine);
}
}
/**
* @dataProvider userAndPasswordData
*/
public function testDetectvalidateUserPass($user, $password) {
$e = new \Exception('test');
$this->registry->expects($this->once())
->method('delegateReport')
->with($e, []);
$this->logger->logException($e);
$logLines = $this->getLogs();
foreach($logLines as $logLine) {
$this->assertNotContains($user, $logLine);
$this->assertNotContains($password, $logLine);
$this->assertContains('validateUserPass(*** sensitive parameters replaced ***)', $logLine);
}
}
/**
* @dataProvider userAndPasswordData
*/
public function testDetecttryLogin($user, $password) {
$e = new \Exception('test');
$this->registry->expects($this->once())
->method('delegateReport')
->with($e, []);
$this->logger->logException($e);
$logLines = $this->getLogs();
foreach($logLines as $logLine) {
$this->assertNotContains($user, $logLine);
$this->assertNotContains($password, $logLine);
$this->assertContains('tryLogin(*** sensitive parameters replaced ***)', $logLine);
}
}
/**
* @dataProvider userAndPasswordData
*/
public function testDetectclosure($user, $password) {
$a = function($user, $password) {
throw new \Exception('test');
};
$this->registry->expects($this->once())
->method('delegateReport');
try {
$a($user, $password);
} catch (\Exception $e) {
$this->logger->logException($e);
}
$logLines = $this->getLogs();
foreach($logLines as $logLine) {
$log = explode('\n', $logLine);
unset($log[1]); // Remove `testDetectclosure(` because we are not testing this here, but the closure on stack trace 0
$logLine = implode('\n', $log);
$this->assertNotContains($user, $logLine);
$this->assertNotContains($password, $logLine);
$this->assertContains('{closure}(*** sensitive parameters replaced ***)', $logLine);
}
}
public function dataGetLogClass() {
return [
['file', \OC\Log\File::class],
['errorlog', \OC\Log\Errorlog::class],
['syslog', \OC\Log\Syslog::class],
['owncloud', \OC\Log\File::class],
['nextcloud', \OC\Log\File::class],
['foobar', \OC\Log\File::class],
];
}
/**
* @dataProvider dataGetLogClass
*/
public function testGetLogClass($type, $class) {
$this->assertEquals($class, Log::getLogClass($type));
}
}