@Override public void log( @Nonnull String format, @Nonnull Object... arguments ) { matcher = builder.warn( messageMatcher( format ), arguments ); }
private boolean authFailureLoggedToUserLog() { String boltPackageName = BoltServer.class.getPackage().getName(); return logProvider.containsMatchingLogCall( inLog( containsString( boltPackageName ) ) .warn( containsString( "The client is unauthorized due to authentication failure." ) ) ); }
@Test public void shouldNotAuthorizeInvalidCredentials() throws Exception { // Given final AuthorizationEnabledFilter filter = new AuthorizationEnabledFilter( () -> authManager, logProvider ); String credentials = Base64.encodeBase64String( "foo:bar".getBytes( StandardCharsets.UTF_8 ) ); BasicLoginContext loginContext = mock( BasicLoginContext.class ); AuthSubject authSubject = mock( AuthSubject.class ); when( servletRequest.getMethod() ).thenReturn( "GET" ); when( servletRequest.getContextPath() ).thenReturn( "/db/data" ); when( servletRequest.getHeader( HttpHeaders.AUTHORIZATION ) ).thenReturn( "BASIC " + credentials ); when( servletRequest.getRemoteAddr() ).thenReturn( "remote_ip_address" ); when( authManager.login( authTokenArgumentMatcher( authToken( "foo", "bar" ) ) ) ).thenReturn( loginContext ); when( loginContext.subject() ).thenReturn( authSubject ); when( authSubject.getAuthenticationResult() ).thenReturn( AuthenticationResult.FAILURE ); // When filter.doFilter( servletRequest, servletResponse, filterChain ); // Then verifyNoMoreInteractions( filterChain ); logProvider.assertExactly( inLog( AuthorizationEnabledFilter.class ) .warn( "Failed authentication attempt for '%s' from %s", "foo", "remote_ip_address" ) ); verify( servletResponse ).setStatus( 401 ); verify( servletResponse ).addHeader( HttpHeaders.CONTENT_TYPE, "application/json; charset=UTF-8" ); assertThat( outputStream.toString( StandardCharsets.UTF_8.name() ), containsString( "\"code\" : \"Neo.ClientError.Security.Unauthorized\"" ) ); assertThat( outputStream.toString( StandardCharsets.UTF_8.name() ), containsString( "\"message\" : \"Invalid username or password.\"" ) ); }
@Test public void largeNumberOfSlowRunningJobsShouldChangeAutoReadState() throws Exception { int numberOfRunDiscardPairs = 1000; String largeString = StringUtils.repeat( " ", 8 * 1024 ); connection.connect( address ) .send( util.defaultAcceptedVersions() ) .send( util.chunk( new InitMessage( "TestClient/1.1", emptyMap() ) ) ); assertThat( connection, util.eventuallyReceivesSelectedProtocolVersion() ); assertThat( connection, util.eventuallyReceives( msgSuccess() ) ); // when for ( int i = 0; i < numberOfRunDiscardPairs; i++ ) { connection.send( util.chunk( new RunMessage( "CALL boltissue.sleep( $data )", ValueUtils.asMapValue( singletonMap( "data", largeString ) ) ), DiscardAllMessage.INSTANCE ) ); } // expect for ( int i = 0; i < numberOfRunDiscardPairs; i++ ) { assertThat( connection, util.eventuallyReceives( msgSuccess(), msgSuccess() ) ); } logProvider.assertAtLeastOnce( AssertableLogProvider.inLog( BoltConnectionReadLimiter.class ).warn( containsString( "disabled" ), anything(), anything() ) ); logProvider.assertAtLeastOnce( AssertableLogProvider.inLog( BoltConnectionReadLimiter.class ).warn( containsString( "enabled" ), anything(), anything() ) ); }
@Test public void logModuleSetUpError() { Config config = Config.defaults(); IdGeneratorFactory idGeneratorFactory = mock( IdGeneratorFactory.class ); Throwable openStoresError = new RuntimeException( "Can't set up modules" ); doThrow( openStoresError ).when( idGeneratorFactory ).create( any( File.class ), anyLong(), anyBoolean() ); CommunityIdTypeConfigurationProvider idTypeConfigurationProvider = new CommunityIdTypeConfigurationProvider(); AssertableLogProvider logProvider = new AssertableLogProvider(); SimpleLogService logService = new SimpleLogService( logProvider, logProvider ); PageCache pageCache = pageCacheRule.getPageCache( fs.get() ); Dependencies dependencies = new Dependencies(); dependencies.satisfyDependencies( idGeneratorFactory, idTypeConfigurationProvider, config, logService ); NeoStoreDataSource dataSource = dsRule.getDataSource( dir.databaseLayout(), fs.get(), pageCache, dependencies ); try { dataSource.start(); fail( "Exception expected" ); } catch ( Exception e ) { assertEquals( openStoresError, e ); } logProvider.assertAtLeastOnce( inLog( NeoStoreDataSource.class ).warn( equalTo( "Exception occurred while setting up store modules. Attempting to close things down." ), equalTo( openStoresError ) ) ); }
@Test public void shouldRebuildMissingCountsStoreAfterRecovery() throws IOException, TransactionFailureException { // given createAliensAndHumans(); // when rotateLog(); deleteHumans(); FileSystemAbstraction fs = crash(); deleteCounts( fs ); restart( fs ); // then try ( org.neo4j.internal.kernel.api.Transaction tx = ((GraphDatabaseAPI)db).getDependencyResolver().resolveDependency( Kernel.class ) .beginTransaction( explicit, AUTH_DISABLED ) ) { assertEquals( ALIENS, tx.dataRead().countsForNode( -1 ) ); assertEquals( ALIENS, tx.dataRead().countsForNode( labelId( ALIEN ) ) ); assertEquals( 0, tx.dataRead().countsForNode( labelId( HUMAN ) ) ); } // and also LogMatcherBuilder matcherBuilder = inLog( MetaDataStore.class ); internalLogProvider.assertAtLeastOnce( matcherBuilder.warn( "Missing counts store, rebuilding it." ) ); internalLogProvider.assertAtLeastOnce( matcherBuilder.warn( "Counts store rebuild completed." ) ); }
@Test public void shouldRebuildMissingCountsStoreOnStart() throws IOException, TransactionFailureException { // given createAliensAndHumans(); // when FileSystemAbstraction fs = shutdown(); deleteCounts( fs ); restart( fs ); // then try ( org.neo4j.internal.kernel.api.Transaction tx = ((GraphDatabaseAPI)db).getDependencyResolver().resolveDependency( Kernel.class ) .beginTransaction( explicit, AUTH_DISABLED ) ) { assertEquals( ALIENS + HUMANS, tx.dataRead().countsForNode( -1 ) ); assertEquals( ALIENS, tx.dataRead().countsForNode( labelId( ALIEN ) ) ); assertEquals( HUMANS, tx.dataRead().countsForNode( labelId( HUMAN ) ) ); } // and also LogMatcherBuilder matcherBuilder = inLog( MetaDataStore.class ); internalLogProvider.assertAtLeastOnce( matcherBuilder.warn( "Missing counts store, rebuilding it." ) ); internalLogProvider.assertAtLeastOnce( matcherBuilder.warn( "Counts store rebuild completed." ) ); }
@Test public void shouldLogShortWarningOnClientDisconnectMidwayThroughQuery() throws Exception { // Connections dying is not exceptional per-se, so we don't need to fill the log with // eye-catching stack traces; but it could be indicative of some issue, so log a brief // warning in the debug log at least. // Given PackOutputClosedException outputClosed = new PackOutputClosedException( "Output closed", "<client>" ); Neo4jError txTerminated = Neo4jError.from( new TransactionTerminatedException( Status.Transaction.Terminated ) ); // When AssertableLogProvider logProvider = emulateFailureWritingError( txTerminated, outputClosed ); // Then logProvider.assertExactly( inLog( "Test" ).warn( equalTo( "Client %s disconnected while query was running. Session has been cleaned up. " + "This can be caused by temporary network problems, but if you see this often, ensure your " + "applications are properly waiting for operations to complete before exiting." ), equalTo( "<client>" ) ) ); }
@Test public void shouldNotLogConnectionResetErrors() throws Exception { // Given AssertableLogProvider logProvider = new AssertableLogProvider(); HouseKeeper keeper = new HouseKeeper( null, logProvider.getLog( HouseKeeper.class ) ); Channel channel = mock( Channel.class ); when( channel.toString() ).thenReturn( "[some channel info]" ); ChannelHandlerContext ctx = mock( ChannelHandlerContext.class ); when( ctx.channel() ).thenReturn( channel ); when( ctx.executor() ).thenReturn( mock( EventExecutor.class ) ); IOException connResetError = new IOException( "Connection reset by peer" ); // When keeper.exceptionCaught( ctx, connResetError ); // Then logProvider.assertExactly( AssertableLogProvider.inLog( HouseKeeper.class ).warn( "Fatal error occurred when handling a client connection, " + "remote peer unexpectedly closed connection: %s", channel ) ); }
@Test public void shouldRejectIfHttp() { // Given BoltProtocol protocol = newBoltProtocol( 1 ); BoltProtocolFactory handlerFactory = newProtocolFactory( 1, protocol ); EmbeddedChannel channel = new EmbeddedChannel( new ProtocolHandshaker( handlerFactory, boltChannel, logProvider, false, true ) ); // When FullHttpRequest request = new DefaultFullHttpRequest( HttpVersion.HTTP_1_1, HttpMethod.POST, "http://hello_world:10000" ); request.headers().setInt( HttpHeaderNames.CONTENT_LENGTH, 0 ); channel.writeInbound( request ); // Then assertEquals( 0, channel.outboundMessages().size() ); assertFalse( channel.isActive() ); verify( protocol, never() ).install(); logProvider.assertExactly( AssertableLogProvider.inLog( ProtocolHandshaker.class ).warn( "Unsupported connection type: 'HTTP'. Bolt protocol only operates over a TCP connection or WebSocket." ) ); }
private AssertableLogProvider.LogMatcher currentLog( AssertableLogProvider.LogMatcherBuilder logMatcherBuilder, Matcher<String> stringMatcher ) { switch ( logName ) { case "debug": return logMatcherBuilder.debug( stringMatcher ); case "info": return logMatcherBuilder.info( stringMatcher ); case "warn": return logMatcherBuilder.warn( stringMatcher ); case "error": return logMatcherBuilder.error( stringMatcher ); default: throw new RuntimeException( "Unknown log name" ); } }
@Test public void shouldLogConnectionResetErrorsAtWarningLevelAndClosesContext() throws Exception { // Given ChannelHandlerContext context = channelHandlerContextMock(); AssertableLogProvider logging = new AssertableLogProvider(); TransportSelectionHandler handler = new TransportSelectionHandler( null, null, false, false, logging, null ); IOException connResetError = new IOException( "Connection reset by peer" ); // When handler.exceptionCaught( context, connResetError ); // Then verify( context ).close(); logging.assertExactly( inLog( TransportSelectionHandler.class ) .warn( "Fatal error occurred when initialising pipeline, " + "remote peer unexpectedly closed connection: %s", context.channel() ) ); }
@Test public void shouldLogBoltConnectionAuthFatalityError() { BoltConnection connection = newConnection(); connection.enqueue( machine -> { throw new BoltConnectionAuthFatality( new AuthenticationException( Status.Security.Unauthorized, "inner error" ) ); } ); connection.processNextBatch(); verify( stateMachine ).close(); logProvider.assertExactly( AssertableLogProvider.inLog( containsString( BoltServer.class.getPackage().getName() ) ).warn( containsString( "inner error" ) ) ); }
public LogMatcher warn( String format, Object... arguments ) { return warn( equalTo( format ), arguments ); }
@Override public void log( @Nonnull String message, @Nonnull Throwable throwable ) { matcher = builder.warn( messageMatcher( message ), sameInstance( throwable ) ); }
private void assertWarning( String implementationName ) { logProvider.assertExactly( AssertableLogProvider.inLog( getClass() ).warn( "Using default tracer implementations instead of '%s'", implementationName ) ); } }
@Test void shouldFormatWarningForRecord() { // when logger.warning( RecordType.NEO_STORE, new NeoStoreRecord(), "sample message", 1, 2 ); // then logProvider.assertExactly( INLOG.warn( join( "sample message", neoStoreRecord( true, -1 ), "Inconsistent with: 1 2" ) ) ); }
private static void testLoggingOfOriginalErrorWhenOutputIsClosed( Neo4jError original ) throws Exception { PackOutputClosedException outputClosed = new PackOutputClosedException( "Output closed", "<client>" ); AssertableLogProvider logProvider = emulateFailureWritingError( original, outputClosed ); logProvider.assertExactly( inLog( "Test" ).warn( startsWith( "Unable to send error back to the client" ), equalTo( original.cause() ) ) ); }
@Override public void log( @Nonnull String message ) { matcher = builder.warn( messageMatcher( message ) ); }
@Test public void processNextBatchShouldCloseConnectionOnFatalAuthenticationError() { BoltConnection connection = newConnection(); connection.enqueue( machine -> { throw new BoltConnectionAuthFatality( "auth failure", new RuntimeException( "inner error" ) ); } ); connection.processNextBatch(); verify( stateMachine ).close(); logProvider.assertNone( AssertableLogProvider.inLog( containsString( BoltServer.class.getPackage().getName() ) ).warn( any( String.class ) ) ); }