assertInstanceOf( FileHandler::class, $file_handler ); } /** * It is enabled if the File Manager is ready */ public function test_enabled() { $file_handler = new FileHandler( new FileManager() ); $this->assertTrue( $file_handler->enabled() ); } /** * It is not enabled if the File Manager is not ready */ public function test_not_enabled() { $file_manager_double = \Mockery::mock( FileManager::class )->makePartial(); $file_manager_double->shouldReceive( 'ready' )->andReturn( false ); $file_handler = new FileHandler( $file_manager_double ); $this->assertFalse( $file_handler->enabled() ); } /** * It creates log files to write logs to */ public function test_log_file_create() { $file_handler = new FileHandler( new FileManager() ); $logger = Logger::create( 'test', self::$plugin_options, $file_handler ); $logger->info( 'New Log' ); $manager = new FileManager(); $log_files = glob( $manager->logs_dir . '/*.log' ); $this->assertCount( 1, $log_files ); $log_file = $log_files[0]; $this->assertFileExists( $log_file ); } /** * It writes logs to a file it has created */ public function test_log_file_write() { $file_handler = new FileHandler( new FileManager() ); $logger = Logger::create( 'test', self::$plugin_options, $file_handler ); $logger->info( 'New Log' ); $manager = new FileManager(); $log_files = glob( $manager->logs_dir . '/*.log' ); $this->assertCount( 1, $log_files ); $log_file = $log_files[0]; $last_entry = shell_exec( "tail -n 1 $log_file" ); $this->assertMatchesRegularExpression( '/New Log/', $last_entry ); } /** * It writes multiple logs to the same file */ public function test_log_file_multiple() { $file_manager = new FileManager(); $file_handler = new FileHandler( $file_manager ); $logger = Logger::create( 'test', self::$plugin_options, $file_handler ); for ( $i = 1; $i <= 10; $i++ ) { $logger->warning( "Multi Log $i" ); } $log_files = glob( $file_manager->logs_dir . '/*.log' ); $this->assertCount( 1, $log_files ); $matching_line_count = 0; $handle = fopen( $log_files[0], 'r' ); while ( ! feof( $handle ) ) { $line = fgets( $handle ); if ( strpos( $line, 'Multi Log' ) !== false ) { ++$matching_line_count; } } fclose( $handle ); $this->assertEquals( 10, $matching_line_count ); } /** * It rotates log files every day. */ public function test_log_file_date_rotation() { $file_manager = new FileManager(); $file_handler = new FileHandler( $file_manager ); $logger = Logger::create( 'test', self::$plugin_options, $file_handler ); $logger->warning( "Today's Log" ); $todays_datetime = new \DateTimeImmutable( 'now' ); $tomorrows_datetime = new \DateTimeImmutable( 'tomorrow' ); // Make file handler think it's tomorrow. $tomorrows_file_handler = new FileHandler( $file_manager, null, null, $tomorrows_datetime ); // Make logger think it's tomorrow. $tomorrows_logger = Logger::create( 'test', self::$plugin_options, $tomorrows_file_handler ); $tomorrows_logger->pushProcessor( function ( $record ) use ( $tomorrows_datetime ) { $record['datetime'] = $tomorrows_datetime; return $record; } ); $tomorrows_logger->warning( "Tomorrow's Log" ); $tomorrows_date = $tomorrows_datetime->format( FileHandler::DATE_FORMAT ); $todays_date = $todays_datetime->format( FileHandler::DATE_FORMAT ); $files = $file_handler->list_files(); $this->assertMatchesRegularExpression( '/' . $tomorrows_date . '/', $files[0] ); $this->assertMatchesRegularExpression( '/' . $todays_date . '/', $files[1] ); } /** * It rotates logs when size limit is reached. */ public function test_log_file_size_limit_rotation() { $file_manager = new FileManager(); $file_handler = new FileHandler( $file_manager ); $logger = Logger::create( 'high-volume', self::$plugin_options, $file_handler ); $logger->warning( 'High volume log' ); // It's inefficient to create a large file via individual logs, so we're // stuffing the log file with filler data so it's almost up to the limit // then taking it over the limit with normal logs. $handle = fopen( $file_handler->getUrl(), 'wb' ); $limit = $file_handler->get_file_size_limit(); while ( fstat( $handle )['size'] < ( $limit - ( 1024 * 30 * 1 ) ) ) { fwrite( $handle, str_repeat( "filler line taking up 30 bts\n", 1024 ) ); } for ( $i = 1; $i <= 300; $i++ ) { $logger->warning( 'High volume log' ); } $this->assertLessThanOrEqual( $limit, fstat( $handle )['size'] ); $this->assertCount( 2, $file_handler->list_files() ); } /** * It increments file numbers on each rotation. */ public function test_log_file_number() { $file_manager = new FileManager(); // Size limit to restrict each file to a single line. $low_limit_file_handler = new FileHandler( $file_manager, 200 ); $logger = Logger::create( 'one-log-per-file', self::$plugin_options, $low_limit_file_handler ); for ( $i = 1; $i <= 7; $i++ ) { $logger->warning( 'A line long enough to take it over 100 bytes with log metadata' ); } $this->assertCount( 7, $low_limit_file_handler->list_files() ); $this->assertEquals( 7, $low_limit_file_handler->current_file_number() ); } /** * It respects the max_files limit. */ public function test_log_max_files() { $file_manager = new FileManager(); // Size limit to restrict each file to a single line. $handler = new FileHandler( $file_manager, 200 ); $logger = Logger::create( 'one-log-per-file', self::$plugin_options, $handler ); for ( $i = 1; $i <= 15; $i++ ) { $logger->warning( 'A line long enough to take it over 100 bytes with log metadata' ); } $files = $handler->list_files(); $this->assertCount( 10, $files ); // Ensure the right files have been removed. $this->assertEquals( 15, $handler->get_number_from_url( $files[0] ) ); $this->assertEquals( 6, $handler->get_number_from_url( end( $files ) ) ); } }