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.php93
-rw-r--r--tests/lib/Log/LogFactoryTest.php149
-rw-r--r--tests/lib/Log/PsrLoggerAdapterTest.php82
4 files changed, 391 insertions, 0 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
new file mode 100644
index 00000000000..3f030665fb4
--- /dev/null
+++ b/tests/lib/Log/FileTest.php
@@ -0,0 +1,93 @@
+<?php
+
+/**
+ *
+ * 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;
+
+/**
+ * Class FileTest
+ */
+class FileTest extends TestCase {
+ private $restore_logfile;
+ private $restore_logdateformat;
+
+ /** @var File */
+ protected $logFile;
+
+ protected function setUp(): void {
+ parent::setUp();
+ $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');
+ $this->logFile = new File($config->getValue('datadirectory') . '/logtest.log', '', $config);
+ }
+ protected function tearDown(): void {
+ $config = Server::get(SystemConfig::class);
+ if (isset($this->restore_logfile)) {
+ $config->getValue('logfile', $this->restore_logfile);
+ } else {
+ $config->deleteValue('logfile');
+ }
+ if (isset($this->restore_logdateformat)) {
+ $config->getValue('logdateformat', $this->restore_logdateformat);
+ } else {
+ $config->deleteValue('logdateformat');
+ }
+ $this->logFile = new File($this->restore_logfile, '', $config);
+ parent::tearDown();
+ }
+
+ 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'));
+
+ # set format & write log line
+ $config->setSystemValue('logdateformat', 'u');
+ $this->logFile->write('test', 'message', ILogger::ERROR);
+
+ # read log line
+ $handle = @fopen($config->getSystemValue('logfile'), 'r');
+ $line = fread($handle, 1000);
+ fclose($handle);
+
+ # check timestamp has microseconds part
+ $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
new file mode 100644
index 00000000000..b1adbd0e823
--- /dev/null
+++ b/tests/lib/Log/LogFactoryTest.php
@@ -0,0 +1,149 @@
+<?php
+
+/**
+ * SPDX-FileCopyrightText: 2018 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+
+namespace Test\Log;
+
+use OC\Log\Errorlog;
+use OC\Log\File;
+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;
+
+/**
+ * Class LogFactoryTest
+ *
+ * @package Test\Log
+ */
+class LogFactoryTest extends TestCase {
+ /** @var IServerContainer|\PHPUnit\Framework\MockObject\MockObject */
+ protected $c;
+
+ /** @var LogFactory */
+ protected $factory;
+
+ /** @var SystemConfig|\PHPUnit\Framework\MockObject\MockObject */
+ protected $systemConfig;
+
+ protected function setUp(): void {
+ parent::setUp();
+
+ $this->c = $this->createMock(IServerContainer::class);
+ $this->systemConfig = $this->createMock(SystemConfig::class);
+
+ $this->factory = new LogFactory($this->c, $this->systemConfig);
+ }
+
+ public static function fileTypeProvider(): array {
+ return [
+ [
+ 'file'
+ ],
+ [
+ 'nextcloud'
+ ],
+ [
+ 'owncloud'
+ ],
+ [
+ 'krzxkyr_default'
+ ]
+ ];
+ }
+
+ /**
+ * @param string $type
+ * @throws QueryException
+ */
+ #[\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')
+ ->willReturnMap([
+ ['datadirectory', $datadir, $datadir],
+ ['logfile', $defaultLog, $defaultLog],
+ ['logfilemode', 0640, 0640],
+ ]);
+
+ $log = $this->factory->get($type);
+ $this->assertInstanceOf(File::class, $log);
+ }
+
+ public static function logFilePathProvider():array {
+ return [
+ [
+ '/dev/null',
+ '/dev/null'
+ ],
+ [
+ '/xdev/youshallfallback',
+ \OC::$SERVERROOT . '/data/nextcloud.log'
+ ]
+ ];
+ }
+
+ /**
+ * @throws QueryException
+ */
+ #[\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')
+ ->willReturnMap([
+ ['datadirectory', $datadir, $datadir],
+ ['logfile', $defaultLog, $path],
+ ['logfilemode', 0640, 0640],
+ ]);
+
+ $log = $this->factory->get('file');
+ $this->assertInstanceOf(File::class, $log);
+ $this->assertSame($expected, $log->getLogFilePath());
+ }
+
+ /**
+ * @throws QueryException
+ */
+ public function testErrorLog(): void {
+ $log = $this->factory->get('errorlog');
+ $this->assertInstanceOf(Errorlog::class, $log);
+ }
+
+ /**
+ * @throws QueryException
+ */
+ public function testSystemLog(): void {
+ $this->c->expects($this->once())
+ ->method('resolve')
+ ->with(Syslog::class)
+ ->willReturn($this->createMock(Syslog::class));
+
+ $log = $this->factory->get('syslog');
+ $this->assertInstanceOf(Syslog::class, $log);
+ }
+
+ /**
+ * @throws QueryException
+ */
+ public function testSystemdLog(): void {
+ $this->c->expects($this->once())
+ ->method('resolve')
+ ->with(Systemdlog::class)
+ ->willReturn($this->createMock(Systemdlog::class));
+
+ $log = $this->factory->get('systemd');
+ $this->assertInstanceOf(Systemdlog::class, $log);
+ }
+}
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],
+ ];
+ }
+}