1
0
mirror of https://github.com/Seldaek/monolog.git synced 2025-08-12 08:04:02 +02:00

Merge branch 'master' into feature/elasticsearch

# Conflicts:
#	composer.json
#	src/Monolog/Handler/ElasticSearchHandler.php
This commit is contained in:
Avtandil Kikabidze
2018-06-24 20:43:55 +04:00
83 changed files with 1210 additions and 336 deletions

View File

@@ -40,7 +40,7 @@ class FluentdFormatterTest extends TestCase
$formatter = new FluentdFormatter();
$this->assertEquals(
'["test",0,{"message":"test","extra":[],"level":300,"level_name":"WARNING"}]',
'["test",0,{"message":"test","context":[],"extra":[],"level":300,"level_name":"WARNING"}]',
$formatter->format($record)
);
}
@@ -55,7 +55,7 @@ class FluentdFormatterTest extends TestCase
$formatter = new FluentdFormatter(true);
$this->assertEquals(
'["test.error",0,{"message":"test","extra":[]}]',
'["test.error",0,{"message":"test","context":[],"extra":[]}]',
$formatter->format($record)
);
}

View File

@@ -234,7 +234,7 @@ class GelfMessageFormatterTest extends \PHPUnit\Framework\TestCase
'context' => array('exception' => str_repeat(' ', 32767 * 2)),
'datetime' => new \DateTime("@0"),
'extra' => array('key' => str_repeat(' ', 32767 * 2)),
'message' => 'log'
'message' => 'log',
);
$message = $formatter->format($record);
$messageArray = $message->toArray();

View File

@@ -38,11 +38,12 @@ class JsonFormatterTest extends TestCase
{
$formatter = new JsonFormatter();
$record = $this->getRecord();
$record['context'] = $record['extra'] = new \stdClass;
$this->assertEquals(json_encode($record)."\n", $formatter->format($record));
$formatter = new JsonFormatter(JsonFormatter::BATCH_MODE_JSON, false);
$record = $this->getRecord();
$this->assertEquals('{"message":"test","context":[],"level":300,"level_name":"WARNING","channel":"test","datetime":"'.$record['datetime']->format('Y-m-d\TH:i:s.uP').'","extra":[]}', $formatter->format($record));
$this->assertEquals('{"message":"test","context":{},"level":300,"level_name":"WARNING","channel":"test","datetime":"'.$record['datetime']->format('Y-m-d\TH:i:s.uP').'","extra":{}}', $formatter->format($record));
}
/**
@@ -71,6 +72,7 @@ class JsonFormatterTest extends TestCase
$this->getRecord(Logger::DEBUG),
];
array_walk($expected, function (&$value, $key) {
$value['context'] = $value['extra'] = new \stdClass;
$value = json_encode($value);
});
$this->assertEquals(implode("\n", $expected), $formatter->formatBatch($records));
@@ -110,6 +112,47 @@ class JsonFormatterTest extends TestCase
$this->assertContextContainsFormattedException($formattedThrowable, $message);
}
public function testMaxNormalizeDepth()
{
$formatter = new JsonFormatter(JsonFormatter::BATCH_MODE_JSON, true);
$formatter->setMaxNormalizeDepth(1);
$throwable = new \Error('Foo');
$message = $this->formatRecordWithExceptionInContext($formatter, $throwable);
$this->assertContextContainsFormattedException('"Over 1 levels deep, aborting normalization"', $message);
}
public function testMaxNormalizeItemCountWith0ItemsMax()
{
$formatter = new JsonFormatter(JsonFormatter::BATCH_MODE_JSON, true);
$formatter->setMaxNormalizeDepth(9);
$formatter->setMaxNormalizeItemCount(0);
$throwable = new \Error('Foo');
$message = $this->formatRecordWithExceptionInContext($formatter, $throwable);
$this->assertEquals(
'{"...":"Over 0 items (6 total), aborting normalization"}'."\n",
$message
);
}
public function testMaxNormalizeItemCountWith2ItemsMax()
{
$formatter = new JsonFormatter(JsonFormatter::BATCH_MODE_JSON, true);
$formatter->setMaxNormalizeDepth(9);
$formatter->setMaxNormalizeItemCount(2);
$throwable = new \Error('Foo');
$message = $this->formatRecordWithExceptionInContext($formatter, $throwable);
$this->assertEquals(
'{"level_name":"CRITICAL","channel":"core","...":"Over 2 items (6 total), aborting normalization"}'."\n",
$message
);
}
/**
* @param string $expected
* @param string $actual
@@ -119,18 +162,18 @@ class JsonFormatterTest extends TestCase
private function assertContextContainsFormattedException($expected, $actual)
{
$this->assertEquals(
'{"level_name":"CRITICAL","channel":"core","context":{"exception":'.$expected.'},"datetime":null,"extra":[],"message":"foobar"}'."\n",
'{"level_name":"CRITICAL","channel":"core","context":{"exception":'.$expected.'},"datetime":null,"extra":{},"message":"foobar"}'."\n",
$actual
);
}
/**
* @param JsonFormatter $formatter
* @param \Exception|\Throwable $exception
* @param JsonFormatter $formatter
* @param \Throwable $exception
*
* @return string
*/
private function formatRecordWithExceptionInContext(JsonFormatter $formatter, $exception)
private function formatRecordWithExceptionInContext(JsonFormatter $formatter, \Throwable $exception)
{
$message = $formatter->format([
'level_name' => 'CRITICAL',
@@ -176,4 +219,40 @@ class JsonFormatterTest extends TestCase
return $formattedException;
}
public function testNormalizeHandleLargeArraysWithExactly1000Items()
{
$formatter = new NormalizerFormatter();
$largeArray = range(1, 1000);
$res = $formatter->format(array(
'level_name' => 'CRITICAL',
'channel' => 'test',
'message' => 'bar',
'context' => array($largeArray),
'datetime' => new \DateTime,
'extra' => array(),
));
$this->assertCount(1000, $res['context'][0]);
$this->assertArrayNotHasKey('...', $res['context'][0]);
}
public function testNormalizeHandleLargeArrays()
{
$formatter = new NormalizerFormatter();
$largeArray = range(1, 2000);
$res = $formatter->format(array(
'level_name' => 'CRITICAL',
'channel' => 'test',
'message' => 'bar',
'context' => array($largeArray),
'datetime' => new \DateTime,
'extra' => array(),
));
$this->assertCount(1001, $res['context'][0]);
$this->assertEquals('Over 1000 items (2000 total), aborting normalization', $res['context'][0]['...']);
}
}

View File

@@ -170,7 +170,7 @@ class LineFormatterTest extends \PHPUnit\Framework\TestCase
$path = str_replace('\\/', '/', json_encode(__FILE__));
$this->assertEquals('['.date('Y-m-d').'] core.CRITICAL: foobar {"exception":"[object] (RuntimeException(code: 0): Foo at '.substr($path, 1, -1).':'.(__LINE__ - 8).', LogicException(code: 0): Wut? at '.substr($path, 1, -1).':'.(__LINE__ - 12).')"} []'."\n", $message);
$this->assertEquals('['.date('Y-m-d').'] core.CRITICAL: foobar {"exception":"[object] (RuntimeException(code: 0): Foo at '.substr($path, 1, -1).':'.(__LINE__ - 8).')\n[previous exception] [object] (LogicException(code: 0): Wut? at '.substr($path, 1, -1).':'.(__LINE__ - 12).')"} []'."\n", $message);
}
public function testBatchFormat()

View File

@@ -17,7 +17,7 @@ class LogstashFormatterTest extends \PHPUnit\Framework\TestCase
{
public function tearDown()
{
\PHPUnit_Framework_Error_Warning::$enabled = true;
\PHPUnit\Framework\Error\Warning::$enabled = true;
return parent::tearDown();
}
@@ -27,7 +27,7 @@ class LogstashFormatterTest extends \PHPUnit\Framework\TestCase
*/
public function testDefaultFormatterV1()
{
$formatter = new LogstashFormatter('test', 'hostname', null, 'ctxt_');
$formatter = new LogstashFormatter('test', 'hostname');
$record = [
'level' => Logger::ERROR,
'level_name' => 'ERROR',
@@ -49,7 +49,7 @@ class LogstashFormatterTest extends \PHPUnit\Framework\TestCase
$this->assertEquals('test', $message['type']);
$this->assertEquals('hostname', $message['host']);
$formatter = new LogstashFormatter('mysystem', null, null, 'ctxt_');
$formatter = new LogstashFormatter('mysystem');
$message = json_decode($formatter->format($record), true);
@@ -61,7 +61,7 @@ class LogstashFormatterTest extends \PHPUnit\Framework\TestCase
*/
public function testFormatWithFileAndLineV1()
{
$formatter = new LogstashFormatter('test', null, null, 'ctxt_');
$formatter = new LogstashFormatter('test');
$record = [
'level' => Logger::ERROR,
'level_name' => 'ERROR',
@@ -83,7 +83,7 @@ class LogstashFormatterTest extends \PHPUnit\Framework\TestCase
*/
public function testFormatWithContextV1()
{
$formatter = new LogstashFormatter('test', null, null, 'ctxt_');
$formatter = new LogstashFormatter('test');
$record = [
'level' => Logger::ERROR,
'level_name' => 'ERROR',
@@ -96,17 +96,17 @@ class LogstashFormatterTest extends \PHPUnit\Framework\TestCase
$message = json_decode($formatter->format($record), true);
$this->assertArrayHasKey('ctxt_context', $message);
$this->assertArrayHasKey('from', $message['ctxt_context']);
$this->assertEquals('logger', $message['ctxt_context']['from']);
$this->assertArrayHasKey('context', $message);
$this->assertArrayHasKey('from', $message['context']);
$this->assertEquals('logger', $message['context']['from']);
// Test with extraPrefix
$formatter = new LogstashFormatter('test', null, null, 'CTX');
$formatter = new LogstashFormatter('test', null, 'extra', 'CTX');
$message = json_decode($formatter->format($record), true);
$this->assertArrayHasKey('CTXcontext', $message);
$this->assertArrayHasKey('from', $message['CTXcontext']);
$this->assertEquals('logger', $message['CTXcontext']['from']);
$this->assertArrayHasKey('CTX', $message);
$this->assertArrayHasKey('from', $message['CTX']);
$this->assertEquals('logger', $message['CTX']['from']);
}
/**
@@ -114,7 +114,7 @@ class LogstashFormatterTest extends \PHPUnit\Framework\TestCase
*/
public function testFormatWithExtraV1()
{
$formatter = new LogstashFormatter('test', null, null, 'ctxt_');
$formatter = new LogstashFormatter('test');
$record = [
'level' => Logger::ERROR,
'level_name' => 'ERROR',
@@ -132,17 +132,17 @@ class LogstashFormatterTest extends \PHPUnit\Framework\TestCase
$this->assertEquals('pair', $message['extra']['key']);
// Test with extraPrefix
$formatter = new LogstashFormatter('test', null, 'EXT', 'ctxt_');
$formatter = new LogstashFormatter('test', null, 'EXTRA');
$message = json_decode($formatter->format($record), true);
$this->assertArrayHasKey('EXTextra', $message);
$this->assertArrayHasKey('key', $message['EXTextra']);
$this->assertEquals('pair', $message['EXTextra']['key']);
$this->assertArrayHasKey('EXTRA', $message);
$this->assertArrayHasKey('key', $message['EXTRA']);
$this->assertEquals('pair', $message['EXTRA']['key']);
}
public function testFormatWithApplicationNameV1()
{
$formatter = new LogstashFormatter('app', 'test', null, 'ctxt_');
$formatter = new LogstashFormatter('app', 'test');
$record = [
'level' => Logger::ERROR,
'level_name' => 'ERROR',

View File

@@ -18,7 +18,7 @@ class NormalizerFormatterTest extends \PHPUnit\Framework\TestCase
{
public function tearDown()
{
\PHPUnit_Framework_Error_Warning::$enabled = true;
\PHPUnit\Framework\Error\Warning::$enabled = true;
return parent::tearDown();
}
@@ -227,6 +227,24 @@ class NormalizerFormatterTest extends \PHPUnit\Framework\TestCase
$this->assertEquals(@json_encode([$resource]), $res);
}
public function testNormalizeHandleLargeArraysWithExactly1000Items()
{
$formatter = new NormalizerFormatter();
$largeArray = range(1, 1000);
$res = $formatter->format(array(
'level_name' => 'CRITICAL',
'channel' => 'test',
'message' => 'bar',
'context' => array($largeArray),
'datetime' => new \DateTime,
'extra' => array(),
));
$this->assertCount(1000, $res['context'][0]);
$this->assertArrayNotHasKey('...', $res['context'][0]);
}
public function testNormalizeHandleLargeArrays()
{
$formatter = new NormalizerFormatter();
@@ -241,7 +259,7 @@ class NormalizerFormatterTest extends \PHPUnit\Framework\TestCase
'extra' => array(),
));
$this->assertCount(1000, $res['context'][0]);
$this->assertCount(1001, $res['context'][0]);
$this->assertEquals('Over 1000 items (2000 total), aborting normalization', $res['context'][0]['...']);
}
@@ -271,6 +289,48 @@ class NormalizerFormatterTest extends \PHPUnit\Framework\TestCase
$this->assertSame('{"message":"€ŠšŽžŒœŸ"}', $res);
}
public function testMaxNormalizeDepth()
{
$formatter = new NormalizerFormatter();
$formatter->setMaxNormalizeDepth(1);
$throwable = new \Error('Foo');
$message = $this->formatRecordWithExceptionInContext($formatter, $throwable);
$this->assertEquals(
'Over 1 levels deep, aborting normalization',
$message['context']['exception']
);
}
public function testMaxNormalizeItemCountWith0ItemsMax()
{
$formatter = new NormalizerFormatter();
$formatter->setMaxNormalizeDepth(9);
$formatter->setMaxNormalizeItemCount(0);
$throwable = new \Error('Foo');
$message = $this->formatRecordWithExceptionInContext($formatter, $throwable);
$this->assertEquals(
["..." => "Over 0 items (6 total), aborting normalization"],
$message
);
}
public function testMaxNormalizeItemCountWith3ItemsMax()
{
$formatter = new NormalizerFormatter();
$formatter->setMaxNormalizeDepth(9);
$formatter->setMaxNormalizeItemCount(2);
$throwable = new \Error('Foo');
$message = $this->formatRecordWithExceptionInContext($formatter, $throwable);
$this->assertEquals(
["level_name" => "CRITICAL", "channel" => "core", "..." => "Over 2 items (6 total), aborting normalization"],
$message
);
}
/**
* @param mixed $in Input
* @param mixed $expect Expected output
@@ -333,10 +393,6 @@ class NormalizerFormatterTest extends \PHPUnit\Framework\TestCase
// and no file or line are included in the trace because it's treated as internal function
public function testExceptionTraceWithArgs()
{
if (defined('HHVM_VERSION')) {
$this->markTestSkipped('Not supported in HHVM since it detects errors differently');
}
try {
// This will contain $resource and $wrappedResource as arguments in the trace item
$resource = fopen('php://memory', 'rw+');
@@ -356,19 +412,54 @@ class NormalizerFormatterTest extends \PHPUnit\Framework\TestCase
$record = ['context' => ['exception' => $e]];
$result = $formatter->format($record);
$this->assertRegExp(
'%\[resource\(stream\)\]%',
$this->assertSame(
'{"function":"Monolog\\\\Formatter\\\\{closure}","class":"Monolog\\\\Formatter\\\\NormalizerFormatterTest","type":"->","args":["[object] (Monolog\\\\Formatter\\\\TestFooNorm)","[resource(stream)]"]}',
$result['context']['exception']['trace'][0]
);
}
$pattern = '%\[\{"Monolog\\\\\\\\Formatter\\\\\\\\TestFooNorm":"JSON_ERROR"\}%';
/**
* @param NormalizerFormatter $formatter
* @param \Throwable $exception
*
* @return string
*/
private function formatRecordWithExceptionInContext(NormalizerFormatter $formatter, \Throwable $exception)
{
$message = $formatter->format([
'level_name' => 'CRITICAL',
'channel' => 'core',
'context' => ['exception' => $exception],
'datetime' => null,
'extra' => [],
'message' => 'foobar',
]);
// Tests that the wrapped resource is ignored while encoding, only works for PHP <= 5.4
$this->assertRegExp(
$pattern,
return $message;
}
public function testExceptionTraceDoesNotLeakCallUserFuncArgs()
{
try {
$arg = new TestInfoLeak;
call_user_func(array($this, 'throwHelper'), $arg, $dt = new \DateTime());
} catch (\Exception $e) {
}
$formatter = new NormalizerFormatter();
$record = array('context' => array('exception' => $e));
$result = $formatter->format($record);
$this->assertSame(
'{"function":"throwHelper","class":"Monolog\\\\Formatter\\\\NormalizerFormatterTest","type":"->","args":["[object] (Monolog\\\\Formatter\\\\TestInfoLeak)","'.$dt->format('Y-m-d\TH:i:sP').'"]}',
$result['context']['exception']['trace'][0]
);
}
private function throwHelper($arg)
{
throw new \RuntimeException('Thrown');
}
}
class TestFooNorm
@@ -410,3 +501,11 @@ class TestToStringError
throw new \RuntimeException('Could not convert to string');
}
}
class TestInfoLeak
{
public function __toString()
{
return 'Sensitive information';
}
}

View File

@@ -153,4 +153,9 @@ class TestChromePHPHandler extends ChromePHPHandler
{
return $this->headers;
}
protected function isWebRequest(): bool
{
return true;
}
}

View File

@@ -201,6 +201,7 @@ class ElasticSearchHandlerTest extends TestCase
->setHosts($hosts)
->build();
$handler = new ElasticSearchHandler($client, $this->options);
try {
$handler->handleBatch([$msg]);
} catch (\RuntimeException $e) {

View File

@@ -32,7 +32,7 @@ class ErrorLogHandlerTest extends TestCase
* @expectedException InvalidArgumentException
* @expectedExceptionMessage The given message type "42" is not supported
*/
public function testShouldNotAcceptAnInvalidTypeOnContructor()
public function testShouldNotAcceptAnInvalidTypeOnConstructor()
{
new ErrorLogHandler(42);
}

View File

@@ -146,7 +146,10 @@ class FilterHandlerTest extends TestCase
$handler = new FilterHandler(
function ($record, $handler) use ($test) {
return $test;
}, Logger::INFO, Logger::NOTICE, false
},
Logger::INFO,
Logger::NOTICE,
false
);
$handler->handle($this->getRecord(Logger::DEBUG));
$handler->handle($this->getRecord(Logger::INFO));

View File

@@ -93,4 +93,9 @@ class TestFirePHPHandler extends FirePHPHandler
{
return $this->headers;
}
protected function isWebRequest(): bool
{
return true;
}
}

View File

@@ -0,0 +1,79 @@
<?php declare(strict_types=1);
/*
* This file is part of the Monolog package.
*
* (c) Jordi Boggiano <j.boggiano@seld.be>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Monolog\Handler;
use Monolog\Test\TestCase;
use Monolog\Logger;
/**
* @author Robert Kaufmann III <rok3@rok3.me>
* @author Gabriel Machado <gabriel.ms1@hotmail.com>
*/
class InsightOpsHandlerTest extends TestCase
{
/**
* @var resource
*/
private $resource;
/**
* @var LogEntriesHandler
*/
private $handler;
public function testWriteContent()
{
$this->createHandler();
$this->handler->handle($this->getRecord(Logger::CRITICAL, 'Critical write test'));
fseek($this->resource, 0);
$content = fread($this->resource, 1024);
$this->assertRegexp('/testToken \[\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{6}\+00:00\] test.CRITICAL: Critical write test/', $content);
}
public function testWriteBatchContent()
{
$this->createHandler();
$this->handler->handleBatch($this->getMultipleRecords());
fseek($this->resource, 0);
$content = fread($this->resource, 1024);
$this->assertRegexp('/(testToken \[\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{6}\+00:00\] .* \[\] \[\]\n){3}/', $content);
}
private function createHandler()
{
$useSSL = extension_loaded('openssl');
$args = array('testToken', 'us', $useSSL, Logger::DEBUG, true);
$this->resource = fopen('php://memory', 'a');
$this->handler = $this->getMockBuilder(InsightOpsHandler::class)
->setMethods(array('fsockopen', 'streamSetTimeout', 'closeSocket'))
->setConstructorArgs($args)
->getMock();
$reflectionProperty = new \ReflectionProperty('\Monolog\Handler\SocketHandler', 'connectionString');
$reflectionProperty->setAccessible(true);
$reflectionProperty->setValue($this->handler, 'localhost:1234');
$this->handler->expects($this->any())
->method('fsockopen')
->will($this->returnValue($this->resource));
$this->handler->expects($this->any())
->method('streamSetTimeout')
->will($this->returnValue(true));
$this->handler->expects($this->any())
->method('closeSocket')
->will($this->returnValue(true));
}
}

View File

@@ -37,7 +37,7 @@ class LogmaticHandlerTest extends TestCase
fseek($this->res, 0);
$content = fread($this->res, 1024);
$this->assertRegexp('/testToken {"message":"Critical write test","context":\[\],"level":500,"level_name":"CRITICAL","channel":"test","datetime":"(.*)","extra":\[\],"hostname":"testHostname","appname":"testAppname","@marker":\["sourcecode","php"\]}/', $content);
$this->assertRegexp('/testToken {"message":"Critical write test","context":{},"level":500,"level_name":"CRITICAL","channel":"test","datetime":"(.*)","extra":{},"hostname":"testHostname","appname":"testAppname","@marker":\["sourcecode","php"\]}/', $content);
}
public function testWriteBatchContent()
@@ -53,7 +53,7 @@ class LogmaticHandlerTest extends TestCase
fseek($this->res, 0);
$content = fread($this->res, 1024);
$this->assertRegexp('/testToken {"message":"test","context":\[\],"level":300,"level_name":"WARNING","channel":"test","datetime":"(.*)","extra":\[\],"hostname":"testHostname","appname":"testAppname","@marker":\["sourcecode","php"\]}/', $content);
$this->assertRegexp('/testToken {"message":"test","context":{},"level":300,"level_name":"WARNING","channel":"test","datetime":"(.*)","extra":{},"hostname":"testHostname","appname":"testAppname","@marker":\["sourcecode","php"\]}/', $content);
}
private function createHandler()

View File

@@ -77,7 +77,7 @@ class ProcessHandlerTest extends TestCase
*/
public function testConstructWithInvalidCommandThrowsInvalidArgumentException($invalidCommand, $expectedExcep)
{
$this->setExpectedException($expectedExcep);
$this->expectException($expectedExcep);
new ProcessHandler($invalidCommand, Logger::DEBUG);
}
@@ -102,7 +102,7 @@ class ProcessHandlerTest extends TestCase
*/
public function testConstructWithInvalidCwdThrowsInvalidArgumentException($invalidCwd, $expectedExcep)
{
$this->setExpectedException($expectedExcep);
$this->expectException($expectedExcep);
new ProcessHandler(self::DUMMY_COMMAND, Logger::DEBUG, true, $invalidCwd);
}
@@ -135,7 +135,7 @@ class ProcessHandlerTest extends TestCase
->method('selectErrorStream')
->will($this->returnValue(false));
$this->setExpectedException('\UnexpectedValueException');
$this->expectException('\UnexpectedValueException');
/** @var ProcessHandler $handler */
$handler->handle($this->getRecord(Logger::WARNING, 'stream failing, whoops'));
}
@@ -147,7 +147,7 @@ class ProcessHandlerTest extends TestCase
public function testStartupWithErrorsThrowsUnexpectedValueException()
{
$handler = new ProcessHandler('>&2 echo "some fake error message"');
$this->setExpectedException('\UnexpectedValueException');
$this->expectException('\UnexpectedValueException');
$handler->handle($this->getRecord(Logger::WARNING, 'some warning in the house'));
}
@@ -167,7 +167,7 @@ class ProcessHandlerTest extends TestCase
->method('readProcessErrors')
->willReturnOnConsecutiveCalls('', $this->returnValue('some fake error message here'));
$this->setExpectedException('\UnexpectedValueException');
$this->expectException('\UnexpectedValueException');
/** @var ProcessHandler $handler */
$handler->handle($this->getRecord(Logger::WARNING, 'some test stuff'));
}

View File

@@ -15,6 +15,7 @@ use Exception;
use Monolog\Test\TestCase;
use Monolog\Logger;
use PHPUnit_Framework_MockObject_MockObject as MockObject;
use Rollbar\RollbarLogger;
/**
* @author Erik Johansson <erik.pm.johansson@gmail.com>
@@ -27,7 +28,7 @@ class RollbarHandlerTest extends TestCase
/**
* @var MockObject
*/
private $rollbarNotifier;
private $rollbarLogger;
/**
* @var array
@@ -38,7 +39,7 @@ class RollbarHandlerTest extends TestCase
{
parent::setUp();
$this->setupRollbarNotifierMock();
$this->setupRollbarLoggerMock();
}
/**
@@ -54,15 +55,21 @@ class RollbarHandlerTest extends TestCase
$this->assertEquals('debug', $this->reportedExceptionArguments['payload']['level']);
}
private function setupRollbarNotifierMock()
private function setupRollbarLoggerMock()
{
$this->rollbarNotifier = $this->getMockBuilder('RollbarNotifier')
->setMethods(array('report_message', 'report_exception', 'flush'))
$config = array(
'access_token' => 'ad865e76e7fb496fab096ac07b1dbabb',
'environment' => 'test',
);
$this->rollbarLogger = $this->getMockBuilder(RollbarLogger::class)
->setConstructorArgs(array($config))
->setMethods(array('log'))
->getMock();
$this->rollbarNotifier
$this->rollbarLogger
->expects($this->any())
->method('report_exception')
->method('log')
->willReturnCallback(function ($exception, $context, $payload) {
$this->reportedExceptionArguments = compact('exception', 'context', 'payload');
});
@@ -70,7 +77,7 @@ class RollbarHandlerTest extends TestCase
private function createHandler(): RollbarHandler
{
return new RollbarHandler($this->rollbarNotifier, Logger::DEBUG);
return new RollbarHandler($this->rollbarLogger, Logger::DEBUG);
}
private function createExceptionRecord($level = Logger::DEBUG, $message = 'test', $exception = null): array

View File

@@ -102,10 +102,10 @@ class RotatingFileHandlerTest extends TestCase
$dayCallback = function ($ago) use ($now) {
return $now + 86400 * $ago;
};
$monthCallback = function($ago) {
$monthCallback = function ($ago) {
return gmmktime(0, 0, 0, (int) (date('n') + $ago), 1, (int) date('Y'));
};
$yearCallback = function($ago) {
$yearCallback = function ($ago) {
return gmmktime(0, 0, 0, 1, 1, (int) (date('Y') + $ago));
};
@@ -134,7 +134,8 @@ class RotatingFileHandlerTest extends TestCase
{
$handler = new RotatingFileHandler(__DIR__.'/Fixtures/foo.rot', 2);
if (!$valid) {
$this->setExpectedExceptionRegExp(InvalidArgumentException::class, '~^Invalid date format~');
$this->expectException(InvalidArgumentException::class);
$this->expectExceptionMessageRegExp('~^Invalid date format~');
}
$handler->setFilenameFormat('{filename}-{date}', $dateFormat);
$this->assertTrue(true);
@@ -174,7 +175,8 @@ class RotatingFileHandlerTest extends TestCase
{
$handler = new RotatingFileHandler(__DIR__.'/Fixtures/foo.rot', 2);
if (!$valid) {
$this->setExpectedExceptionRegExp(InvalidArgumentException::class, '~^Invalid filename format~');
$this->expectException(InvalidArgumentException::class);
$this->expectExceptionMessageRegExp('~^Invalid filename format~');
}
$handler->setFilenameFormat($filenameFormat, RotatingFileHandler::FILE_PER_DAY);
@@ -193,6 +195,39 @@ class RotatingFileHandlerTest extends TestCase
];
}
/**
* @dataProvider rotationWhenSimilarFilesExistTests
*/
public function testRotationWhenSimilarFileNamesExist($dateFormat)
{
touch($old1 = __DIR__.'/Fixtures/foo-foo-'.date($dateFormat).'.rot');
touch($old2 = __DIR__.'/Fixtures/foo-bar-'.date($dateFormat).'.rot');
$log = __DIR__.'/Fixtures/foo-'.date($dateFormat).'.rot';
$handler = new RotatingFileHandler(__DIR__.'/Fixtures/foo.rot', 2);
$handler->setFormatter($this->getIdentityFormatter());
$handler->setFilenameFormat('{filename}-{date}', $dateFormat);
$handler->handle($this->getRecord());
$handler->close();
$this->assertTrue(file_exists($log));
}
public function rotationWhenSimilarFilesExistTests()
{
return array(
'Rotation is triggered when the file of the current day is not present but similar exists'
=> array(RotatingFileHandler::FILE_PER_DAY),
'Rotation is triggered when the file of the current month is not present but similar exists'
=> array(RotatingFileHandler::FILE_PER_MONTH),
'Rotation is triggered when the file of the current year is not present but similar exists'
=> array(RotatingFileHandler::FILE_PER_YEAR),
);
}
public function testReuseCurrentFile()
{
$log = __DIR__.'/Fixtures/foo-'.date('Y-m-d').'.rot';

View File

@@ -324,12 +324,12 @@ class SlackRecordTest extends TestCase
'short' => false,
),
array(
'title' => 'tags',
'title' => 'Tags',
'value' => sprintf('```%s```', json_encode($extra['tags'])),
'short' => false,
),
array(
'title' => 'test',
'title' => 'Test',
'value' => $context['test'],
'short' => false,
),
@@ -357,6 +357,14 @@ class SlackRecordTest extends TestCase
$this->assertSame($record['datetime']->getTimestamp(), $attachment['ts']);
}
public function testContextHasException()
{
$record = $this->getRecord(Logger::CRITICAL, 'This is a critical message.', array('exception' => new \Exception()));
$slackRecord = new SlackRecord(null, null, true, null, false, true);
$data = $slackRecord->getSlackData($record);
$this->assertInternalType('string', $data['attachments'][0]['fields'][1]['value']);
}
public function testExcludeExtraAndContextFields()
{
$record = $this->getRecord(
@@ -372,12 +380,12 @@ class SlackRecordTest extends TestCase
$expected = array(
array(
'title' => 'info',
'title' => 'Info',
'value' => sprintf('```%s```', json_encode(array('author' => 'Jordi'), $this->jsonPrettyPrintFlag)),
'short' => false,
),
array(
'title' => 'tags',
'title' => 'Tags',
'value' => sprintf('```%s```', json_encode(array('web'))),
'short' => false,
),

View File

@@ -77,6 +77,13 @@ class SocketHandlerTest extends TestCase
$this->assertEquals(10.25, $this->handler->getWritingTimeout());
}
public function testSetChunkSize()
{
$this->createHandler('localhost:1234');
$this->handler->setChunkSize(1025);
$this->assertEquals(1025, $this->handler->getChunkSize());
}
public function testSetConnectionString()
{
$this->createHandler('tcp://localhost:9090');
@@ -120,6 +127,19 @@ class SocketHandlerTest extends TestCase
$this->writeRecord('Hello world');
}
/**
* @expectedException UnexpectedValueException
*/
public function testExceptionIsThrownIfCannotSetChunkSize()
{
$this->setMockHandler(array('streamSetChunkSize'));
$this->handler->setChunkSize(8192);
$this->handler->expects($this->once())
->method('streamSetChunkSize')
->will($this->returnValue(false));
$this->writeRecord('Hello world');
}
/**
* @expectedException RuntimeException
*/
@@ -277,7 +297,7 @@ class SocketHandlerTest extends TestCase
{
$this->res = fopen('php://memory', 'a');
$defaultMethods = ['fsockopen', 'pfsockopen', 'streamSetTimeout'];
$defaultMethods = ['fsockopen', 'pfsockopen', 'streamSetTimeout', 'streamSetChunkSize'];
$newMethods = array_diff($methods, $defaultMethods);
$finalMethods = array_merge($defaultMethods, $newMethods);
@@ -305,6 +325,12 @@ class SocketHandlerTest extends TestCase
->will($this->returnValue(true));
}
if (!in_array('streamSetChunkSize', $methods)) {
$this->handler->expects($this->any())
->method('streamSetChunkSize')
->will($this->returnValue(8192));
}
$this->handler->setFormatter($this->getIdentityFormatter());
}
}

View File

@@ -54,6 +54,54 @@ class TestHandlerTest extends TestCase
$this->assertEquals([$record], $records);
}
public function testHandlerAssertEmptyContext()
{
$handler = new TestHandler;
$record = $this->getRecord(Logger::WARNING, 'test', []);
$this->assertFalse($handler->hasWarning([
'message' => 'test',
'context' => [],
]));
$handler->handle($record);
$this->assertTrue($handler->hasWarning([
'message' => 'test',
'context' => [],
]));
$this->assertFalse($handler->hasWarning([
'message' => 'test',
'context' => [
'foo' => 'bar',
],
]));
}
public function testHandlerAssertNonEmptyContext()
{
$handler = new TestHandler;
$record = $this->getRecord(Logger::WARNING, 'test', ['foo' => 'bar']);
$this->assertFalse($handler->hasWarning([
'message' => 'test',
'context' => [
'foo' => 'bar',
],
]));
$handler->handle($record);
$this->assertTrue($handler->hasWarning([
'message' => 'test',
'context' => [
'foo' => 'bar',
],
]));
$this->assertFalse($handler->hasWarning([
'message' => 'test',
'context' => [],
]));
}
public function methodProvider()
{
return [

View File

@@ -87,6 +87,29 @@ class WhatFailureGroupHandlerTest extends TestCase
$this->assertTrue($records[0]['extra']['foo']);
}
/**
* @covers Monolog\Handler\WhatFailureGroupHandler::handleBatch
*/
public function testHandleBatchUsesProcessors()
{
$testHandlers = array(new TestHandler(), new TestHandler());
$handler = new WhatFailureGroupHandler($testHandlers);
$handler->pushProcessor(function ($record) {
$record['extra']['foo'] = true;
return $record;
});
$handler->handleBatch(array($this->getRecord(Logger::DEBUG), $this->getRecord(Logger::INFO)));
foreach ($testHandlers as $test) {
$this->assertTrue($test->hasDebugRecords());
$this->assertTrue($test->hasInfoRecords());
$this->assertTrue(count($test->getRecords()) === 2);
$records = $test->getRecords();
$this->assertTrue($records[0]['extra']['foo']);
$this->assertTrue($records[1]['extra']['foo']);
}
}
/**
* @covers Monolog\Handler\WhatFailureGroupHandler::handle
*/

View File

@@ -576,4 +576,63 @@ class LoggerTest extends \PHPUnit\Framework\TestCase
'without microseconds' => [false, PHP_VERSION_ID >= 70100 ? 'assertNotSame' : 'assertSame', 'Y-m-d\TH:i:sP'],
];
}
/**
* @covers Monolog\Logger::setExceptionHandler
*/
public function testSetExceptionHandler()
{
$logger = new Logger(__METHOD__);
$this->assertNull($logger->getExceptionHandler());
$callback = function ($ex) {
};
$logger->setExceptionHandler($callback);
$this->assertEquals($callback, $logger->getExceptionHandler());
}
/**
* @covers Monolog\Logger::handleException
* @expectedException Exception
*/
public function testDefaultHandleException()
{
$logger = new Logger(__METHOD__);
$handler = $this->getMockBuilder('Monolog\Handler\HandlerInterface')->getMock();
$handler->expects($this->any())
->method('isHandling')
->will($this->returnValue(true))
;
$handler->expects($this->any())
->method('handle')
->will($this->throwException(new \Exception('Some handler exception')))
;
$logger->pushHandler($handler);
$logger->info('test');
}
/**
* @covers Monolog\Logger::handleException
* @covers Monolog\Logger::addRecord
*/
public function testCustomHandleException()
{
$logger = new Logger(__METHOD__);
$that = $this;
$logger->setExceptionHandler(function ($e, $record) use ($that) {
$that->assertEquals($e->getMessage(), 'Some handler exception');
$that->assertTrue(is_array($record));
$that->assertEquals($record['message'], 'test');
});
$handler = $this->getMockBuilder('Monolog\Handler\HandlerInterface')->getMock();
$handler->expects($this->any())
->method('isHandling')
->will($this->returnValue(true))
;
$handler->expects($this->any())
->method('handle')
->will($this->throwException(new \Exception('Some handler exception')))
;
$logger->pushHandler($handler);
$logger->info('test');
}
}

View File

@@ -0,0 +1,30 @@
<?php declare(strict_types=1);
/*
* This file is part of the Monolog package.
*
* (c) Jordi Boggiano <j.boggiano@seld.be>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Monolog\Processor;
use Monolog\Test\TestCase;
class HostnameProcessorTest extends TestCase
{
/**
* @covers Monolog\Processor\HostnameProcessor::__invoke
*/
public function testProcessor()
{
$processor = new HostnameProcessor();
$record = $processor($this->getRecord());
$this->assertArrayHasKey('hostname', $record['extra']);
$this->assertInternalType('string', $record['extra']['hostname']);
$this->assertNotEmpty($record['extra']['hostname']);
$this->assertEquals(gethostname(), $record['extra']['hostname']);
}
}

View File

@@ -25,6 +25,19 @@ class PsrLogMessageProcessorTest extends \PHPUnit\Framework\TestCase
'context' => ['foo' => $val],
]);
$this->assertEquals($expected, $message['message']);
$this->assertSame(['foo' => $val], $message['context']);
}
public function testReplacementWithContextRemoval()
{
$proc = new PsrLogMessageProcessor($dateFormat = null, $removeUsedContextFields = true);
$message = $proc([
'message' => '{foo}',
'context' => ['foo' => 'bar', 'lorem' => 'ipsum'],
]);
$this->assertSame('bar', $message['message']);
$this->assertSame(['lorem' => 'ipsum'], $message['context']);
}
public function testCustomDateFormat()
@@ -39,6 +52,7 @@ class PsrLogMessageProcessorTest extends \PHPUnit\Framework\TestCase
'context' => ['foo' => $date],
]);
$this->assertEquals($date->format($format), $message['message']);
$this->assertSame(['foo' => $date], $message['context']);
}
public function getPairs()
@@ -54,7 +68,11 @@ class PsrLogMessageProcessorTest extends \PHPUnit\Framework\TestCase
[false, ''],
[$date, $date->format(PsrLogMessageProcessor::SIMPLE_DATE)],
[new \stdClass, '[object stdClass]'],
[[], '[array]'],
[[], 'array[]'],
[[], 'array[]'],
[[1, 2, 3], 'array[1,2,3]'],
[['foo' => 'bar'], 'array{"foo":"bar"}'],
[stream_context_create(), '[resource]'],
];
}
}

View File

@@ -12,3 +12,9 @@
date_default_timezone_set('UTC');
require __DIR__.'/../vendor/autoload.php';
// B.C. for PSR Log's old inheritance
// see https://github.com/php-fig/log/pull/52
if (!class_exists('\\PHPUnit_Framework_TestCase', true)) {
class_alias('\\PHPUnit\\Framework\\TestCase', '\\PHPUnit_Framework_TestCase');
}