aboutsummaryrefslogtreecommitdiffstats
path: root/tests/lib/Log
diff options
context:
space:
mode:
Diffstat (limited to 'tests/lib/Log')
-rw-r--r--tests/lib/Log/ExceptionSerializerTest.php67
-rw-r--r--tests/lib/Log/FileTest.php67
-rw-r--r--tests/lib/Log/LogFactoryTest.php72
-rw-r--r--tests/lib/Log/PsrLoggerAdapterTest.php82
4 files changed, 221 insertions, 67 deletions
diff --git a/tests/lib/Log/ExceptionSerializerTest.php b/tests/lib/Log/ExceptionSerializerTest.php
new file mode 100644
index 00000000000..6d5bc5cf19f
--- /dev/null
+++ b/tests/lib/Log/ExceptionSerializerTest.php
@@ -0,0 +1,67 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * SPDX-FileCopyrightText: 2021 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+
+namespace lib\Log;
+
+use OC\Log\ExceptionSerializer;
+use OC\SystemConfig;
+use Test\TestCase;
+
+class ExceptionSerializerTest extends TestCase {
+ private ExceptionSerializer $serializer;
+
+ public function setUp(): void {
+ parent::setUp();
+
+ $config = $this->createMock(SystemConfig::class);
+ $this->serializer = new ExceptionSerializer($config);
+ }
+
+ private function emit($arguments) {
+ \call_user_func_array([$this, 'bind'], $arguments);
+ }
+
+ private function bind(array &$myValues): void {
+ throw new \Exception('my exception');
+ }
+
+ private function customMagicAuthThing(string $login, string $parole): void {
+ throw new \Exception('expected custom auth exception');
+ }
+
+ /**
+ * this test ensures that the serializer does not overwrite referenced
+ * variables. It is crafted after a scenario we experienced: the DAV server
+ * emitting the "validateTokens" event, of which later on a handled
+ * exception was passed to the logger. The token was replaced, the original
+ * variable overwritten.
+ */
+ public function testSerializer(): void {
+ try {
+ $secret = ['Secret'];
+ $this->emit([&$secret]);
+ } catch (\Exception $e) {
+ $serializedData = $this->serializer->serializeException($e);
+ $this->assertSame(['Secret'], $secret);
+ $this->assertSame(ExceptionSerializer::SENSITIVE_VALUE_PLACEHOLDER, $serializedData['Trace'][0]['args'][0]);
+ }
+ }
+
+ public function testSerializerWithRegisteredMethods(): void {
+ $this->serializer->enlistSensitiveMethods(self::class, ['customMagicAuthThing']);
+ try {
+ $this->customMagicAuthThing('u57474', 'Secret');
+ } catch (\Exception $e) {
+ $serializedData = $this->serializer->serializeException($e);
+ $this->assertSame('customMagicAuthThing', $serializedData['Trace'][0]['function']);
+ $this->assertSame(ExceptionSerializer::SENSITIVE_VALUE_PLACEHOLDER, $serializedData['Trace'][0]['args'][0]);
+ $this->assertFalse(isset($serializedData['Trace'][0]['args'][1]));
+ }
+ }
+}
diff --git a/tests/lib/Log/FileTest.php b/tests/lib/Log/FileTest.php
index 937b3c75448..3f030665fb4 100644
--- a/tests/lib/Log/FileTest.php
+++ b/tests/lib/Log/FileTest.php
@@ -1,24 +1,18 @@
<?php
+
/**
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU AFFERO GENERAL PUBLIC LICENSE for more details.
- *
- * You should have received a copy of the GNU Affero General Public
- * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace Test\Log;
use OC\Log\File;
+use OC\SystemConfig;
+use OCP\IConfig;
use OCP\ILogger;
+use OCP\Server;
use Test\TestCase;
/**
@@ -33,31 +27,52 @@ class FileTest extends TestCase {
protected function setUp(): void {
parent::setUp();
- $config = \OC::$server->getSystemConfig();
- $this->restore_logfile = $config->getValue("logfile");
+ $config = Server::get(SystemConfig::class);
+ $this->restore_logfile = $config->getValue('logfile');
$this->restore_logdateformat = $config->getValue('logdateformat');
-
- $config->setValue("logfile", $config->getValue('datadirectory') . "/logtest.log");
+
+ $config->setValue('logfile', $config->getValue('datadirectory') . '/logtest.log');
$this->logFile = new File($config->getValue('datadirectory') . '/logtest.log', '', $config);
}
protected function tearDown(): void {
- $config = \OC::$server->getSystemConfig();
+ $config = Server::get(SystemConfig::class);
if (isset($this->restore_logfile)) {
- $config->getValue("logfile", $this->restore_logfile);
+ $config->getValue('logfile', $this->restore_logfile);
} else {
- $config->deleteValue("logfile");
+ $config->deleteValue('logfile');
}
if (isset($this->restore_logdateformat)) {
- $config->getValue("logdateformat", $this->restore_logdateformat);
+ $config->getValue('logdateformat', $this->restore_logdateformat);
} else {
- $config->deleteValue("logdateformat");
+ $config->deleteValue('logdateformat');
}
$this->logFile = new File($this->restore_logfile, '', $config);
parent::tearDown();
}
-
- public function testMicrosecondsLogTimestamp() {
- $config = \OC::$server->getConfig();
+
+ public function testLogging(): void {
+ $config = Server::get(IConfig::class);
+ # delete old logfile
+ unlink($config->getSystemValue('logfile'));
+
+ # set format & write log line
+ $config->setSystemValue('logdateformat', 'u');
+ $this->logFile->write('code', ['something' => 'extra', 'message' => 'Testing logging'], ILogger::ERROR);
+
+ # read log line
+ $handle = @fopen($config->getSystemValue('logfile'), 'r');
+ $line = fread($handle, 1000);
+ fclose($handle);
+
+ # check log has data content
+ $values = (array)json_decode($line, true);
+ $this->assertArrayNotHasKey('message', $values['data']);
+ $this->assertEquals('extra', $values['data']['something']);
+ $this->assertEquals('Testing logging', $values['message']);
+ }
+
+ public function testMicrosecondsLogTimestamp(): void {
+ $config = Server::get(IConfig::class);
# delete old logfile
unlink($config->getSystemValue('logfile'));
@@ -69,9 +84,9 @@ class FileTest extends TestCase {
$handle = @fopen($config->getSystemValue('logfile'), 'r');
$line = fread($handle, 1000);
fclose($handle);
-
+
# check timestamp has microseconds part
- $values = (array) json_decode($line);
+ $values = (array)json_decode($line);
$microseconds = $values['time'];
$this->assertNotEquals(0, $microseconds);
}
diff --git a/tests/lib/Log/LogFactoryTest.php b/tests/lib/Log/LogFactoryTest.php
index 91ff79369bf..b1adbd0e823 100644
--- a/tests/lib/Log/LogFactoryTest.php
+++ b/tests/lib/Log/LogFactoryTest.php
@@ -1,25 +1,8 @@
<?php
+
/**
- * @copyright Copyright (c) 2018 Arthur Schiwon <blizzz@arthur-schiwon.de>
- *
- * @author Arthur Schiwon <blizzz@arthur-schiwon.de>
- * @author Johannes Ernst <jernst@indiecomputing.com>
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
+ * SPDX-FileCopyrightText: 2018 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace Test\Log;
@@ -30,6 +13,7 @@ use OC\Log\LogFactory;
use OC\Log\Syslog;
use OC\Log\Systemdlog;
use OC\SystemConfig;
+use OCP\AppFramework\QueryException;
use OCP\IServerContainer;
use Test\TestCase;
@@ -57,7 +41,7 @@ class LogFactoryTest extends TestCase {
$this->factory = new LogFactory($this->c, $this->systemConfig);
}
- public function fileTypeProvider(): array {
+ public static function fileTypeProvider(): array {
return [
[
'file'
@@ -76,23 +60,26 @@ class LogFactoryTest extends TestCase {
/**
* @param string $type
- * @dataProvider fileTypeProvider
- * @throws \OCP\AppFramework\QueryException
+ * @throws QueryException
*/
- public function testFile(string $type) {
- $datadir = \OC::$SERVERROOT.'/data';
+ #[\PHPUnit\Framework\Attributes\DataProvider('fileTypeProvider')]
+ public function testFile(string $type): void {
+ $datadir = \OC::$SERVERROOT . '/data';
$defaultLog = $datadir . '/nextcloud.log';
$this->systemConfig->expects($this->exactly(3))
->method('getValue')
- ->withConsecutive(['datadirectory', $datadir], ['logfile', $defaultLog], ['logfilemode', 0640])
- ->willReturnOnConsecutiveCalls($datadir, $defaultLog, 0640);
+ ->willReturnMap([
+ ['datadirectory', $datadir, $datadir],
+ ['logfile', $defaultLog, $defaultLog],
+ ['logfilemode', 0640, 0640],
+ ]);
$log = $this->factory->get($type);
$this->assertInstanceOf(File::class, $log);
}
- public function logFilePathProvider():array {
+ public static function logFilePathProvider():array {
return [
[
'/dev/null',
@@ -100,23 +87,26 @@ class LogFactoryTest extends TestCase {
],
[
'/xdev/youshallfallback',
- \OC::$SERVERROOT.'/data/nextcloud.log'
+ \OC::$SERVERROOT . '/data/nextcloud.log'
]
];
}
/**
- * @dataProvider logFilePathProvider
- * @throws \OCP\AppFramework\QueryException
+ * @throws QueryException
*/
- public function testFileCustomPath($path, $expected) {
- $datadir = \OC::$SERVERROOT.'/data';
+ #[\PHPUnit\Framework\Attributes\DataProvider('logFilePathProvider')]
+ public function testFileCustomPath($path, $expected): void {
+ $datadir = \OC::$SERVERROOT . '/data';
$defaultLog = $datadir . '/nextcloud.log';
$this->systemConfig->expects($this->exactly(3))
->method('getValue')
- ->withConsecutive(['datadirectory', $datadir], ['logfile', $defaultLog], ['logfilemode', 0640])
- ->willReturnOnConsecutiveCalls($datadir, $path, 0640);
+ ->willReturnMap([
+ ['datadirectory', $datadir, $datadir],
+ ['logfile', $defaultLog, $path],
+ ['logfilemode', 0640, 0640],
+ ]);
$log = $this->factory->get('file');
$this->assertInstanceOf(File::class, $log);
@@ -124,17 +114,17 @@ class LogFactoryTest extends TestCase {
}
/**
- * @throws \OCP\AppFramework\QueryException
+ * @throws QueryException
*/
- public function testErrorLog() {
+ public function testErrorLog(): void {
$log = $this->factory->get('errorlog');
$this->assertInstanceOf(Errorlog::class, $log);
}
/**
- * @throws \OCP\AppFramework\QueryException
+ * @throws QueryException
*/
- public function testSystemLog() {
+ public function testSystemLog(): void {
$this->c->expects($this->once())
->method('resolve')
->with(Syslog::class)
@@ -145,9 +135,9 @@ class LogFactoryTest extends TestCase {
}
/**
- * @throws \OCP\AppFramework\QueryException
+ * @throws QueryException
*/
- public function testSystemdLog() {
+ public function testSystemdLog(): void {
$this->c->expects($this->once())
->method('resolve')
->with(Systemdlog::class)
diff --git a/tests/lib/Log/PsrLoggerAdapterTest.php b/tests/lib/Log/PsrLoggerAdapterTest.php
new file mode 100644
index 00000000000..c11af7a12c2
--- /dev/null
+++ b/tests/lib/Log/PsrLoggerAdapterTest.php
@@ -0,0 +1,82 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+
+namespace Test\Log;
+
+use OC\Log;
+use OC\Log\PsrLoggerAdapter;
+use OCP\ILogger;
+use PHPUnit\Framework\MockObject\MockObject;
+use Psr\Log\InvalidArgumentException;
+use Psr\Log\LogLevel;
+use Test\TestCase;
+
+class PsrLoggerAdapterTest extends TestCase {
+ protected Log&MockObject $logger;
+ protected PsrLoggerAdapter $loggerAdapter;
+
+ protected function setUp(): void {
+ parent::setUp();
+
+ $this->logger = $this->createMock(Log::class);
+ $this->loggerAdapter = new PsrLoggerAdapter($this->logger);
+ }
+
+ #[\PHPUnit\Framework\Attributes\DataProvider('dataPsrLoggingLevels')]
+ public function testLoggingWithPsrLogLevels(string $level, int $expectedLevel): void {
+ $this->logger->expects(self::once())
+ ->method('log')
+ ->with($expectedLevel, 'test message', ['app' => 'test']);
+ $this->loggerAdapter->log($level, 'test message', ['app' => 'test']);
+ }
+
+ #[\PHPUnit\Framework\Attributes\DataProvider('dataPsrLoggingLevels')]
+ public function testLogLevelToInt(string $level, int $expectedLevel): void {
+ $this->assertEquals($expectedLevel, PsrLoggerAdapter::logLevelToInt($level));
+ }
+
+ public static function dataPsrLoggingLevels(): array {
+ return [
+ [LogLevel::ALERT, ILogger::ERROR],
+ [LogLevel::CRITICAL, ILogger::ERROR],
+ [LogLevel::DEBUG, ILogger::DEBUG],
+ [LogLevel::EMERGENCY, ILogger::FATAL],
+ [LogLevel::ERROR, ILogger::ERROR],
+ [LogLevel::INFO, ILogger::INFO],
+ [LogLevel::NOTICE, ILogger::INFO],
+ [LogLevel::WARNING, ILogger::WARN],
+ ];
+ }
+
+ #[\PHPUnit\Framework\Attributes\DataProvider('dataInvalidLoggingLevel')]
+ public function testInvalidLoggingLevel($level): void {
+ $this->logger->expects(self::never())
+ ->method('log');
+ $this->expectException(InvalidArgumentException::class);
+
+ $this->loggerAdapter->log($level, 'valid message');
+ }
+
+ public static function dataInvalidLoggingLevel(): array {
+ return [
+ // invalid string
+ ['this is not a level'],
+ // int out of range
+ [ILogger::DEBUG - 1],
+ [ILogger::FATAL + 1],
+ // float is not allowed
+ [1.2345],
+ // boolean is not a level
+ [true],
+ [false],
+ //
+ [null],
+ ];
+ }
+}