diff --git a/community/io/src/main/java/org/neo4j/io/fs/DefaultFileSystemAbstraction.java b/community/io/src/main/java/org/neo4j/io/fs/DefaultFileSystemAbstraction.java
index d5f612f41afb3..b8f1736ebd8c1 100644
--- a/community/io/src/main/java/org/neo4j/io/fs/DefaultFileSystemAbstraction.java
+++ b/community/io/src/main/java/org/neo4j/io/fs/DefaultFileSystemAbstraction.java
@@ -51,7 +51,7 @@ public StoreFileChannel open( File fileName, String mode ) throws IOException
{
// Returning only the channel is ok, because the channel, when close()d will close its parent File.
FileChannel channel = new RandomAccessFile( fileName, mode ).getChannel();
- return new StoreFileChannel( channel );
+ return getStoreFileChannel( channel );
}
@Override
@@ -194,4 +194,9 @@ public void truncate( File path, long size ) throws IOException
{
FileUtils.truncateFile( path, size );
}
+
+ protected StoreFileChannel getStoreFileChannel( FileChannel channel )
+ {
+ return new StoreFileChannel( channel );
+ }
}
diff --git a/community/io/src/test/java/org/neo4j/adversaries/fs/AdversarialChannelDefaultFileSystemAbstraction.java b/community/io/src/test/java/org/neo4j/adversaries/fs/AdversarialChannelDefaultFileSystemAbstraction.java
new file mode 100644
index 0000000000000..7f551f2120370
--- /dev/null
+++ b/community/io/src/test/java/org/neo4j/adversaries/fs/AdversarialChannelDefaultFileSystemAbstraction.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2002-2016 "Neo Technology,"
+ * Network Engine for Objects in Lund AB [http://neotechnology.com]
+ *
+ * This file is part of Neo4j.
+ *
+ * Neo4j is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+package org.neo4j.adversaries.fs;
+
+import java.nio.channels.FileChannel;
+
+import org.neo4j.adversaries.RandomAdversary;
+import org.neo4j.io.fs.DefaultFileSystemAbstraction;
+import org.neo4j.io.fs.StoreFileChannel;
+
+/**
+ * File system abstraction that behaves exactly like {@link DefaultFileSystemAbstraction} except instead of
+ * default {@link FileChannel} implementation {@link AdversarialFileChannel} will be used.
+ *
+ * This abstraction should be used in cases when it's desirable to have default file system implementation
+ * and only verify handling of inconsistent channel operations.
+ * Otherwise consider {@link AdversarialFileSystemAbstraction} since it should produce more failure cases.
+ */
+public class AdversarialChannelDefaultFileSystemAbstraction extends DefaultFileSystemAbstraction
+{
+ private final RandomAdversary adversary;
+
+ public AdversarialChannelDefaultFileSystemAbstraction()
+ {
+ this( new RandomAdversary( 0.5, 0.0, 0.0 ) );
+ }
+
+ public AdversarialChannelDefaultFileSystemAbstraction( RandomAdversary adversary )
+ {
+ this.adversary = adversary;
+ }
+
+ protected StoreFileChannel getStoreFileChannel( FileChannel channel )
+ {
+ return AdversarialFileChannel.wrap( super.getStoreFileChannel( channel ), adversary );
+ }
+}
diff --git a/community/io/src/test/java/org/neo4j/adversaries/fs/AdversarialFileChannel.java b/community/io/src/test/java/org/neo4j/adversaries/fs/AdversarialFileChannel.java
index 22969a1a0158c..0b03d467a352e 100644
--- a/community/io/src/test/java/org/neo4j/adversaries/fs/AdversarialFileChannel.java
+++ b/community/io/src/test/java/org/neo4j/adversaries/fs/AdversarialFileChannel.java
@@ -19,56 +19,28 @@
*/
package org.neo4j.adversaries.fs;
-import sun.nio.ch.FileChannelImpl;
-
import java.io.IOException;
-import java.lang.reflect.Field;
import java.nio.ByteBuffer;
-import java.nio.channels.FileChannel;
import java.nio.channels.FileLock;
import org.neo4j.adversaries.Adversary;
import org.neo4j.io.fs.StoreChannel;
import org.neo4j.io.fs.StoreFileChannel;
-import org.neo4j.io.fs.StoreFileChannelUnwrapper;
-
-import static org.neo4j.adversaries.fs.AdversarialFileDispatcherFactory.makeFileDispatcherAdversarial;
@SuppressWarnings( "unchecked" )
-public class AdversarialFileChannel implements StoreChannel
+public class AdversarialFileChannel extends StoreFileChannel
{
- public static volatile boolean useAdversarialFileDispatcherHack;
-
private final StoreChannel delegate;
private final Adversary adversary;
- public static StoreChannel wrap( StoreChannel channel, Adversary adversary )
+ public static StoreFileChannel wrap( StoreFileChannel channel, Adversary adversary )
{
- if ( useAdversarialFileDispatcherHack && channel.getClass() == StoreFileChannel.class )
- {
- FileChannel innerChannel = StoreFileChannelUnwrapper.unwrap( channel );
- if ( innerChannel.getClass() == FileChannelImpl.class )
- {
- FileChannelImpl channelImpl = (FileChannelImpl) innerChannel;
- try
- {
- Field nd = FileChannelImpl.class.getDeclaredField( "nd" );
- nd.setAccessible( true );
- Object fileDispatcher = nd.get( channelImpl );
- nd.set( channelImpl, makeFileDispatcherAdversarial( fileDispatcher, adversary ) );
- return new StoreFileChannel( innerChannel );
- }
- catch ( Exception e )
- {
- e.printStackTrace();
- }
- }
- }
return new AdversarialFileChannel( channel, adversary );
}
- private AdversarialFileChannel( StoreChannel channel, Adversary adversary )
+ private AdversarialFileChannel( StoreFileChannel channel, Adversary adversary )
{
+ super( channel );
this.delegate = channel;
this.adversary = adversary;
}
@@ -130,17 +102,17 @@ public long write( ByteBuffer[] srcs, int offset, int length ) throws IOExceptio
}
@Override
- public StoreChannel truncate( long size ) throws IOException
+ public StoreFileChannel truncate( long size ) throws IOException
{
adversary.injectFailure( IOException.class );
- return delegate.truncate( size );
+ return (StoreFileChannel) delegate.truncate( size );
}
@Override
- public StoreChannel position( long newPosition ) throws IOException
+ public StoreFileChannel position( long newPosition ) throws IOException
{
adversary.injectFailure( IOException.class );
- return delegate.position( newPosition );
+ return (StoreFileChannel) delegate.position( newPosition );
}
@Override
diff --git a/community/io/src/test/java/org/neo4j/adversaries/fs/AdversarialFileDispatcherFactory.java b/community/io/src/test/java/org/neo4j/adversaries/fs/AdversarialFileDispatcherFactory.java
deleted file mode 100644
index 4563d94765b84..0000000000000
--- a/community/io/src/test/java/org/neo4j/adversaries/fs/AdversarialFileDispatcherFactory.java
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * Copyright (c) 2002-2016 "Neo Technology,"
- * Network Engine for Objects in Lund AB [http://neotechnology.com]
- *
- * This file is part of Neo4j.
- *
- * Neo4j is free software: you can redistribute it and/or modify
- * it under the terms of the GNU 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-package org.neo4j.adversaries.fs;
-
-import sun.nio.ch.DelegateFileDispatcher;
-
-import java.io.FileDescriptor;
-import java.io.IOException;
-import java.util.concurrent.ThreadLocalRandom;
-
-import org.neo4j.adversaries.Adversary;
-
-@SuppressWarnings( "unchecked" )
-public class AdversarialFileDispatcherFactory
-{
- public static Object makeFileDispatcherAdversarial(
- final Object delegateFileDispatcher,
- final Adversary adversary ) throws Exception
- {
- return new DelegateFileDispatcher( delegateFileDispatcher )
- {
- private int mischievousLength( int len )
- {
- if ( adversary.injectFailureOrMischief( IOException.class ) )
- {
- // We cannot pass zero lengths, because they are checked for and
- // circumvented in higher-level NIO code.
- len = len == 1? 1 : ThreadLocalRandom.current().nextInt( 1, len );
- }
- return len;
- }
-
- @Override
- public long readv( FileDescriptor fd, long address, int len ) throws IOException
- {
- return super.readv( fd, address, mischievousLength( len ) );
- }
-
- @Override
- public int read( FileDescriptor fd, long address, int len ) throws IOException
- {
- return super.read( fd, address, mischievousLength( len ) );
- }
-
- @Override
- public int pwrite( FileDescriptor fd, long address, int len, long position ) throws IOException
- {
- return super.pwrite( fd, address, mischievousLength( len ), position );
- }
-
- @Override
- public int truncate( FileDescriptor fd, long size ) throws IOException
- {
- adversary.injectFailure( IOException.class );
- return super.truncate( fd, size );
- }
-
- @Override
- public int pread( FileDescriptor fd, long address, int len, long position ) throws IOException
- {
- return super.pread( fd, address, mischievousLength( len ), position );
- }
-
- @Override
- public long writev( FileDescriptor fd, long address, int len ) throws IOException
- {
- return super.writev( fd, address, mischievousLength( len ) );
- }
-
- @Override
- public int write( FileDescriptor fd, long address, int len ) throws IOException
- {
- return super.write( fd, address, mischievousLength( len ) );
- }
- };
- }
-}
diff --git a/community/io/src/test/java/org/neo4j/adversaries/fs/AdversarialFileSystemAbstraction.java b/community/io/src/test/java/org/neo4j/adversaries/fs/AdversarialFileSystemAbstraction.java
index d9acd05d62a9d..5846026f9cbe2 100644
--- a/community/io/src/test/java/org/neo4j/adversaries/fs/AdversarialFileSystemAbstraction.java
+++ b/community/io/src/test/java/org/neo4j/adversaries/fs/AdversarialFileSystemAbstraction.java
@@ -40,6 +40,7 @@
import org.neo4j.io.fs.DefaultFileSystemAbstraction;
import org.neo4j.io.fs.FileSystemAbstraction;
import org.neo4j.io.fs.StoreChannel;
+import org.neo4j.io.fs.StoreFileChannel;
/**
* Used by the robustness suite to check for partial failures.
@@ -64,7 +65,7 @@ public AdversarialFileSystemAbstraction( Adversary adversary, FileSystemAbstract
public StoreChannel open( File fileName, String mode ) throws IOException
{
adversary.injectFailure( FileNotFoundException.class, IOException.class, SecurityException.class );
- return AdversarialFileChannel.wrap( delegate.open( fileName, mode ), adversary );
+ return AdversarialFileChannel.wrap( (StoreFileChannel) delegate.open( fileName, mode ), adversary );
}
public boolean renameFile( File from, File to ) throws IOException
@@ -82,7 +83,7 @@ public OutputStream openAsOutputStream( File fileName, boolean append ) throws I
public StoreChannel create( File fileName ) throws IOException
{
adversary.injectFailure( FileNotFoundException.class, IOException.class, SecurityException.class );
- return AdversarialFileChannel.wrap( delegate.create( fileName ), adversary );
+ return AdversarialFileChannel.wrap( (StoreFileChannel) delegate.create( fileName ), adversary );
}
public boolean mkdir( File fileName )
diff --git a/community/io/src/test/java/org/neo4j/io/pagecache/PageCacheTest.java b/community/io/src/test/java/org/neo4j/io/pagecache/PageCacheTest.java
index 0f0a7457bb607..6b64e5dbb6bbb 100644
--- a/community/io/src/test/java/org/neo4j/io/pagecache/PageCacheTest.java
+++ b/community/io/src/test/java/org/neo4j/io/pagecache/PageCacheTest.java
@@ -79,6 +79,7 @@
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
+import static org.junit.Assume.assumeTrue;
import static org.neo4j.io.pagecache.PagedFile.PF_NO_FAULT;
import static org.neo4j.io.pagecache.PagedFile.PF_NO_GROW;
import static org.neo4j.io.pagecache.PagedFile.PF_SHARED_READ_LOCK;
@@ -1565,24 +1566,6 @@ public void pagesAddedWithNextWithPageIdMustBeAccessibleWithNoGrowSpecified() th
pagedFile.close();
}
- @RepeatRule.Repeat( times = 10 )
- @Test( timeout = SEMI_LONG_TIMEOUT_MILLIS )
- public void readsAndWritesMustBeMutuallyConsistent() throws Exception
- {
- int filePageCount = 100;
- RandomPageCacheTestHarness harness = new RandomPageCacheTestHarness();
- harness.disableCommands( FlushCache, FlushFile, MapFile, UnmapFile );
- harness.setCommandProbabilityFactor( ReadRecord, 0.5 );
- harness.setCommandProbabilityFactor( WriteRecord, 0.5 );
- harness.setConcurrencyLevel( 8 );
- harness.setFilePageCount( filePageCount );
- harness.setInitialMappedFiles( 1 );
- harness.setCachePageSize( pageCachePageSize );
- harness.setFilePageSize( pageCachePageSize );
- harness.setVerification( filesAreCorrectlyWrittenVerification( new StandardRecordFormat(), filePageCount ) );
- harness.run( SEMI_LONG_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS );
- }
-
@Test( timeout = SHORT_TIMEOUT_MILLIS )
public void writesOfDifferentUnitsMustHaveCorrectEndianess() throws Exception
{
@@ -3174,137 +3157,6 @@ public void optimisticReadLockMustFaultOnRetryIfPageHasBeenEvicted() throws Exce
pagedFileB.close();
}
- @Test( timeout = SEMI_LONG_TIMEOUT_MILLIS )
- public void concurrentPageFaultingMustNotPutInterleavedDataIntoPages() throws Exception
- {
- final int filePageCount = 11;
- final RecordFormat recordFormat = new PageCountRecordFormat();
- RandomPageCacheTestHarness harness = new RandomPageCacheTestHarness();
- harness.setConcurrencyLevel( 11 );
- harness.setUseAdversarialIO( false );
- harness.setCachePageCount( 3 );
- harness.setCachePageSize( pageCachePageSize );
- harness.setFilePageCount( filePageCount );
- harness.setFilePageSize( pageCachePageSize );
- harness.setInitialMappedFiles( 1 );
- harness.setCommandCount( 10000 );
- harness.setRecordFormat( recordFormat );
- harness.setFileSystem( fs );
- harness.disableCommands( FlushCache, FlushFile, MapFile, UnmapFile, WriteRecord, WriteMulti );
- harness.setPreparation( ( pageCache1, fs1, filesTouched ) -> {
- File file = filesTouched.iterator().next();
- try ( PagedFile pf = pageCache1.map( file, pageCachePageSize );
- PageCursor cursor = pf.io( 0, PF_SHARED_WRITE_LOCK ) )
- {
- for ( int pageId = 0; pageId < filePageCount; pageId++ )
- {
- cursor.next();
- recordFormat.fillWithRecords( cursor );
- }
- }
- } );
-
- harness.run( SEMI_LONG_TIMEOUT_MILLIS, MILLISECONDS );
- }
-
- @Test( timeout = SEMI_LONG_TIMEOUT_MILLIS )
- public void concurrentFlushingMustNotPutInterleavedDataIntoFile() throws Exception
- {
- final RecordFormat recordFormat = new StandardRecordFormat();
- final int filePageCount = 2_000;
- RandomPageCacheTestHarness harness = new RandomPageCacheTestHarness();
- harness.setConcurrencyLevel( 16 );
- harness.setUseAdversarialIO( false );
- harness.setCachePageCount( filePageCount / 2 );
- harness.setFilePageCount( filePageCount );
- harness.setCachePageSize( pageCachePageSize );
- harness.setFilePageSize( pageCachePageSize );
- harness.setInitialMappedFiles( 3 );
- harness.setCommandCount( 15_000 );
- harness.setFileSystem( fs );
- harness.disableCommands( MapFile, UnmapFile, ReadRecord, ReadMulti );
- harness.setVerification( filesAreCorrectlyWrittenVerification( recordFormat, filePageCount ) );
-
- harness.run( SEMI_LONG_TIMEOUT_MILLIS, MILLISECONDS );
- }
-
- @Test( timeout = SEMI_LONG_TIMEOUT_MILLIS )
- public void concurrentFlushingWithMischiefMustNotPutInterleavedDataIntoFile() throws Exception
- {
- final RecordFormat recordFormat = new StandardRecordFormat();
- final int filePageCount = 2_000;
- RandomPageCacheTestHarness harness = new RandomPageCacheTestHarness();
- harness.setConcurrencyLevel( 16 );
- harness.setUseAdversarialIO( true );
- harness.setMischiefRate( 0.5 );
- harness.setFailureRate( 0.0 );
- harness.setErrorRate( 0.0 );
- harness.setCachePageCount( filePageCount / 2 );
- harness.setFilePageCount( filePageCount );
- harness.setCachePageSize( pageCachePageSize );
- harness.setFilePageSize( pageCachePageSize );
- harness.setInitialMappedFiles( 3 );
- harness.setCommandCount( 15_000 );
- harness.setFileSystem( fs );
- harness.disableCommands( MapFile, UnmapFile, ReadRecord, ReadMulti );
- harness.setVerification( filesAreCorrectlyWrittenVerification( recordFormat, filePageCount ) );
-
- harness.run( SEMI_LONG_TIMEOUT_MILLIS, MILLISECONDS );
- }
-
- @Test( timeout = SEMI_LONG_TIMEOUT_MILLIS )
- public void concurrentFlushingWithFailuresMustNotPutInterleavedDataIntoFile() throws Exception
- {
- final RecordFormat recordFormat = new StandardRecordFormat();
- final int filePageCount = 20_000;
- RandomPageCacheTestHarness harness = new RandomPageCacheTestHarness();
- harness.setConcurrencyLevel( 16 );
- harness.setUseAdversarialIO( true );
- harness.setMischiefRate( 0.0 );
- harness.setFailureRate( 0.5 );
- harness.setErrorRate( 0.0 );
- harness.setCachePageCount( filePageCount / 2 );
- harness.setFilePageCount( filePageCount );
- harness.setCachePageSize( pageCachePageSize );
- harness.setFilePageSize( pageCachePageSize );
- harness.setInitialMappedFiles( 3 );
- harness.setCommandCount( 150_000 );
- harness.setFileSystem( fs );
- harness.disableCommands( MapFile, UnmapFile, ReadRecord, ReadMulti );
- harness.setVerification( filesAreCorrectlyWrittenVerification( recordFormat, filePageCount ) );
-
- harness.run( SEMI_LONG_TIMEOUT_MILLIS, MILLISECONDS );
- }
-
- private Phase filesAreCorrectlyWrittenVerification( final RecordFormat recordFormat, final int filePageCount )
- {
- return ( pageCache1, fs1, filesTouched ) -> {
- for ( File file : filesTouched )
- {
- try ( PagedFile pf = pageCache1.map( file, pageCachePageSize );
- PageCursor cursor = pf.io( 0, PF_SHARED_READ_LOCK ) )
- {
- for ( int pageId = 0; pageId < filePageCount && cursor.next(); pageId++ )
- {
- try
- {
- recordFormat.assertRecordsWrittenCorrectly( cursor );
- }
- catch ( Throwable th )
- {
- th.addSuppressed( new Exception( "pageId = " + pageId ) );
- throw th;
- }
- }
- }
- try ( StoreChannel channel = fs1.open( file, "r" ) )
- {
- recordFormat.assertRecordsWrittenCorrectly( file, channel );
- }
- }
- };
- }
-
@Test( timeout = SEMI_LONG_TIMEOUT_MILLIS )
public void backgroundThreadsMustGracefullyShutDown() throws Exception
{
diff --git a/community/io/src/test/java/org/neo4j/io/pagecache/PageCacheTestSupport.java b/community/io/src/test/java/org/neo4j/io/pagecache/PageCacheTestSupport.java
index 3ffaf89728d0b..51b21016b38da 100644
--- a/community/io/src/test/java/org/neo4j/io/pagecache/PageCacheTestSupport.java
+++ b/community/io/src/test/java/org/neo4j/io/pagecache/PageCacheTestSupport.java
@@ -284,19 +284,6 @@ protected void verifyRecordsInFile( File file, int recordCount ) throws IOExcept
};
}
- /**
- * We implement 'assumeTrue' ourselves because JUnit insist on adding hamcrest matchers to the
- * AssumptionViolatedException instances it throws. This is a problem because those matchers are not serializable,
- * so they cannot be used together with the BootClassPathRunner, because it uses RMI under the hood.
- */
- protected void assumeTrue( String description, boolean test )
- {
- if ( !test )
- {
- throw new AssumptionViolatedException( description );
- }
- }
-
public static abstract class Fixture
{
public abstract T createPageCache(
diff --git a/community/io/src/test/java/org/neo4j/io/pagecache/harness/MuninnPageCacheHarnessWithRealFileSystemIT.java b/community/io/src/test/java/org/neo4j/io/pagecache/harness/MuninnPageCacheHarnessWithRealFileSystemIT.java
new file mode 100644
index 0000000000000..65bb129efe280
--- /dev/null
+++ b/community/io/src/test/java/org/neo4j/io/pagecache/harness/MuninnPageCacheHarnessWithRealFileSystemIT.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2002-2016 "Neo Technology,"
+ * Network Engine for Objects in Lund AB [http://neotechnology.com]
+ *
+ * This file is part of Neo4j.
+ *
+ * Neo4j is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+package org.neo4j.io.pagecache.harness;
+
+import org.junit.Rule;
+
+import org.neo4j.io.fs.DefaultFileSystemAbstraction;
+import org.neo4j.io.pagecache.impl.muninn.MuninnPageCache;
+import org.neo4j.test.TargetDirectory;
+
+public class MuninnPageCacheHarnessWithRealFileSystemIT extends MunninPageCacheHarnessTest
+{
+ @Rule
+ public TargetDirectory.TestDirectory directory = TargetDirectory.testDirForTest( getClass() );
+
+ @Override
+ protected Fixture createFixture()
+ {
+ return super.createFixture()
+ .withFileSystemAbstraction( DefaultFileSystemAbstraction::new )
+ .withFileConstructor( pathname -> directory.file( pathname ) );
+ }
+}
diff --git a/community/io/src/test/java/org/neo4j/io/pagecache/harness/MunninPageCacheHarnessTest.java b/community/io/src/test/java/org/neo4j/io/pagecache/harness/MunninPageCacheHarnessTest.java
new file mode 100644
index 0000000000000..787a022b1f7ac
--- /dev/null
+++ b/community/io/src/test/java/org/neo4j/io/pagecache/harness/MunninPageCacheHarnessTest.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2002-2016 "Neo Technology,"
+ * Network Engine for Objects in Lund AB [http://neotechnology.com]
+ *
+ * This file is part of Neo4j.
+ *
+ * Neo4j is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+package org.neo4j.io.pagecache.harness;
+
+import org.neo4j.io.pagecache.impl.muninn.MuninnPageCache;
+import org.neo4j.io.pagecache.impl.muninn.MuninnPageCacheFixture;
+
+public class MunninPageCacheHarnessTest extends PageCacheHarnessTest
+{
+ @Override
+ protected Fixture createFixture()
+ {
+ return new MuninnPageCacheFixture();
+ }
+}
diff --git a/community/io/src/test/java/org/neo4j/io/pagecache/harness/PageCacheHarnessTest.java b/community/io/src/test/java/org/neo4j/io/pagecache/harness/PageCacheHarnessTest.java
new file mode 100644
index 0000000000000..8719a8f147e5c
--- /dev/null
+++ b/community/io/src/test/java/org/neo4j/io/pagecache/harness/PageCacheHarnessTest.java
@@ -0,0 +1,202 @@
+/*
+ * Copyright (c) 2002-2016 "Neo Technology,"
+ * Network Engine for Objects in Lund AB [http://neotechnology.com]
+ *
+ * This file is part of Neo4j.
+ *
+ * Neo4j is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+package org.neo4j.io.pagecache.harness;
+
+import org.junit.Test;
+
+import java.io.File;
+import java.util.concurrent.TimeUnit;
+
+import org.neo4j.io.fs.StoreChannel;
+import org.neo4j.io.pagecache.PageCache;
+import org.neo4j.io.pagecache.PageCacheTestSupport;
+import org.neo4j.io.pagecache.PageCursor;
+import org.neo4j.io.pagecache.PagedFile;
+import org.neo4j.io.pagecache.randomharness.PageCountRecordFormat;
+import org.neo4j.io.pagecache.randomharness.Phase;
+import org.neo4j.io.pagecache.randomharness.RandomPageCacheTestHarness;
+import org.neo4j.io.pagecache.randomharness.RecordFormat;
+import org.neo4j.io.pagecache.randomharness.StandardRecordFormat;
+import org.neo4j.test.RepeatRule;
+
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+import static org.neo4j.io.pagecache.PagedFile.PF_SHARED_READ_LOCK;
+import static org.neo4j.io.pagecache.PagedFile.PF_SHARED_WRITE_LOCK;
+import static org.neo4j.io.pagecache.randomharness.Command.FlushCache;
+import static org.neo4j.io.pagecache.randomharness.Command.FlushFile;
+import static org.neo4j.io.pagecache.randomharness.Command.MapFile;
+import static org.neo4j.io.pagecache.randomharness.Command.ReadMulti;
+import static org.neo4j.io.pagecache.randomharness.Command.ReadRecord;
+import static org.neo4j.io.pagecache.randomharness.Command.UnmapFile;
+import static org.neo4j.io.pagecache.randomharness.Command.WriteMulti;
+import static org.neo4j.io.pagecache.randomharness.Command.WriteRecord;
+
+abstract class PageCacheHarnessTest extends PageCacheTestSupport
+{
+ @RepeatRule.Repeat( times = 10 )
+ @Test( timeout = SEMI_LONG_TIMEOUT_MILLIS )
+ public void readsAndWritesMustBeMutuallyConsistent() throws Exception
+ {
+ int filePageCount = 100;
+ RandomPageCacheTestHarness harness = new RandomPageCacheTestHarness();
+ harness.disableCommands( FlushCache, FlushFile, MapFile, UnmapFile );
+ harness.setCommandProbabilityFactor( ReadRecord, 0.5 );
+ harness.setCommandProbabilityFactor( WriteRecord, 0.5 );
+ harness.setConcurrencyLevel( 8 );
+ harness.setFilePageCount( filePageCount );
+ harness.setInitialMappedFiles( 1 );
+ harness.setCachePageSize( pageCachePageSize );
+ harness.setFilePageSize( pageCachePageSize );
+ harness.setVerification( filesAreCorrectlyWrittenVerification( new StandardRecordFormat(), filePageCount ) );
+ harness.run( SEMI_LONG_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS );
+ }
+
+ @Test( timeout = SEMI_LONG_TIMEOUT_MILLIS )
+ public void concurrentPageFaultingMustNotPutInterleavedDataIntoPages() throws Exception
+ {
+ final int filePageCount = 11;
+ final RecordFormat recordFormat = new PageCountRecordFormat();
+ RandomPageCacheTestHarness harness = new RandomPageCacheTestHarness();
+ harness.setConcurrencyLevel( 11 );
+ harness.setUseAdversarialIO( false );
+ harness.setCachePageCount( 3 );
+ harness.setCachePageSize( pageCachePageSize );
+ harness.setFilePageCount( filePageCount );
+ harness.setFilePageSize( pageCachePageSize );
+ harness.setInitialMappedFiles( 1 );
+ harness.setCommandCount( 10000 );
+ harness.setRecordFormat( recordFormat );
+ harness.setFileSystem( fs );
+ harness.disableCommands( FlushCache, FlushFile, MapFile, UnmapFile, WriteRecord, WriteMulti );
+ harness.setPreparation( ( pageCache1, fs1, filesTouched ) -> {
+ File file = filesTouched.iterator().next();
+ try ( PagedFile pf = pageCache1.map( file, pageCachePageSize );
+ PageCursor cursor = pf.io( 0, PF_SHARED_WRITE_LOCK ) )
+ {
+ for ( int pageId = 0; pageId < filePageCount; pageId++ )
+ {
+ cursor.next();
+ recordFormat.fillWithRecords( cursor );
+ }
+ }
+ } );
+
+ harness.run( SEMI_LONG_TIMEOUT_MILLIS, MILLISECONDS );
+ }
+
+ @Test( timeout = SEMI_LONG_TIMEOUT_MILLIS )
+ public void concurrentFlushingMustNotPutInterleavedDataIntoFile() throws Exception
+ {
+ final RecordFormat recordFormat = new StandardRecordFormat();
+ final int filePageCount = 2_000;
+ RandomPageCacheTestHarness harness = new RandomPageCacheTestHarness();
+ harness.setConcurrencyLevel( 16 );
+ harness.setUseAdversarialIO( false );
+ harness.setCachePageCount( filePageCount / 2 );
+ harness.setFilePageCount( filePageCount );
+ harness.setCachePageSize( pageCachePageSize );
+ harness.setFilePageSize( pageCachePageSize );
+ harness.setInitialMappedFiles( 3 );
+ harness.setCommandCount( 15_000 );
+ harness.setFileSystem( fs );
+ harness.disableCommands( MapFile, UnmapFile, ReadRecord, ReadMulti );
+ harness.setVerification( filesAreCorrectlyWrittenVerification( recordFormat, filePageCount ) );
+
+ harness.run( SEMI_LONG_TIMEOUT_MILLIS, MILLISECONDS );
+ }
+
+ @Test( timeout = SEMI_LONG_TIMEOUT_MILLIS )
+ public void concurrentFlushingWithMischiefMustNotPutInterleavedDataIntoFile() throws Exception
+ {
+ final RecordFormat recordFormat = new StandardRecordFormat();
+ final int filePageCount = 2_000;
+ RandomPageCacheTestHarness harness = new RandomPageCacheTestHarness();
+ harness.setConcurrencyLevel( 16 );
+ harness.setUseAdversarialIO( true );
+ harness.setMischiefRate( 0.5 );
+ harness.setFailureRate( 0.0 );
+ harness.setErrorRate( 0.0 );
+ harness.setCachePageCount( filePageCount / 2 );
+ harness.setFilePageCount( filePageCount );
+ harness.setCachePageSize( pageCachePageSize );
+ harness.setFilePageSize( pageCachePageSize );
+ harness.setInitialMappedFiles( 3 );
+ harness.setCommandCount( 15_000 );
+ harness.setFileSystem( fs );
+ harness.disableCommands( MapFile, UnmapFile, ReadRecord, ReadMulti );
+ harness.setVerification( filesAreCorrectlyWrittenVerification( recordFormat, filePageCount ) );
+
+ harness.run( SEMI_LONG_TIMEOUT_MILLIS, MILLISECONDS );
+ }
+
+ @Test( timeout = SEMI_LONG_TIMEOUT_MILLIS )
+ public void concurrentFlushingWithFailuresMustNotPutInterleavedDataIntoFile() throws Exception
+ {
+ final RecordFormat recordFormat = new StandardRecordFormat();
+ final int filePageCount = 20_000;
+ RandomPageCacheTestHarness harness = new RandomPageCacheTestHarness();
+ harness.setConcurrencyLevel( 16 );
+ harness.setUseAdversarialIO( true );
+ harness.setMischiefRate( 0.0 );
+ harness.setFailureRate( 0.5 );
+ harness.setErrorRate( 0.0 );
+ harness.setCachePageCount( filePageCount / 2 );
+ harness.setFilePageCount( filePageCount );
+ harness.setCachePageSize( pageCachePageSize );
+ harness.setFilePageSize( pageCachePageSize );
+ harness.setInitialMappedFiles( 3 );
+ harness.setCommandCount( 150_000 );
+ harness.setFileSystem( fs );
+ harness.disableCommands( MapFile, UnmapFile, ReadRecord, ReadMulti );
+ harness.setVerification( filesAreCorrectlyWrittenVerification( recordFormat, filePageCount ) );
+
+ harness.run( SEMI_LONG_TIMEOUT_MILLIS, MILLISECONDS );
+ }
+
+ private Phase filesAreCorrectlyWrittenVerification( final RecordFormat recordFormat, final int filePageCount )
+ {
+ return ( pageCache1, fs1, filesTouched ) -> {
+ for ( File file : filesTouched )
+ {
+ try ( PagedFile pf = pageCache1.map( file, pageCachePageSize );
+ PageCursor cursor = pf.io( 0, PF_SHARED_READ_LOCK ) )
+ {
+ for ( int pageId = 0; pageId < filePageCount && cursor.next(); pageId++ )
+ {
+ try
+ {
+ recordFormat.assertRecordsWrittenCorrectly( cursor );
+ }
+ catch ( Throwable th )
+ {
+ th.addSuppressed( new Exception( "pageId = " + pageId ) );
+ throw th;
+ }
+ }
+ }
+ try ( StoreChannel channel = fs1.open( file, "r" ) )
+ {
+ recordFormat.assertRecordsWrittenCorrectly( file, channel );
+ }
+ }
+ };
+ }
+
+}
diff --git a/community/io/src/test/java/org/neo4j/io/pagecache/impl/SingleFilePageSwapperWithAdversarialFileDispatcherIT.java b/community/io/src/test/java/org/neo4j/io/pagecache/impl/SingleFilePageSwapperWithAdversarialFileChannelIT.java
similarity index 51%
rename from community/io/src/test/java/org/neo4j/io/pagecache/impl/SingleFilePageSwapperWithAdversarialFileDispatcherIT.java
rename to community/io/src/test/java/org/neo4j/io/pagecache/impl/SingleFilePageSwapperWithAdversarialFileChannelIT.java
index 22ca24ad4d39c..17f2fb52e16ae 100644
--- a/community/io/src/test/java/org/neo4j/io/pagecache/impl/SingleFilePageSwapperWithAdversarialFileDispatcherIT.java
+++ b/community/io/src/test/java/org/neo4j/io/pagecache/impl/SingleFilePageSwapperWithAdversarialFileChannelIT.java
@@ -19,27 +19,14 @@
*/
package org.neo4j.io.pagecache.impl;
-import org.junit.AfterClass;
-import org.junit.BeforeClass;
-import org.junit.runner.RunWith;
+import org.neo4j.adversaries.fs.AdversarialChannelDefaultFileSystemAbstraction;
+import org.neo4j.io.fs.FileSystemAbstraction;
-import org.neo4j.adversaries.fs.AdversarialFileChannel;
-import org.neo4j.test.bootclasspathrunner.BootClassPathRunner;
-import org.neo4j.unsafe.impl.internal.dragons.UnsafeUtilTest;
-
-@BootClassPathRunner.BootEntryOf( UnsafeUtilTest.class )
-@RunWith( BootClassPathRunner.class )
-public class SingleFilePageSwapperWithAdversarialFileDispatcherIT extends SingleFilePageSwapperWithRealFileSystemIT
+public class SingleFilePageSwapperWithAdversarialFileChannelIT extends SingleFilePageSwapperWithRealFileSystemIT
{
- @BeforeClass
- public static void enableAdversarialFileDispatcher()
- {
- AdversarialFileChannel.useAdversarialFileDispatcherHack = true;
- }
-
- @AfterClass
- public static void disableAdversarialFileDispatcher()
+ @Override
+ protected FileSystemAbstraction getFs()
{
- AdversarialFileChannel.useAdversarialFileDispatcherHack = false;
+ return new AdversarialChannelDefaultFileSystemAbstraction();
}
}
diff --git a/community/io/src/test/java/org/neo4j/io/pagecache/impl/muninn/MuninnPageCacheFixture.java b/community/io/src/test/java/org/neo4j/io/pagecache/impl/muninn/MuninnPageCacheFixture.java
index 4b5168e089f62..6b098d6acd372 100644
--- a/community/io/src/test/java/org/neo4j/io/pagecache/impl/muninn/MuninnPageCacheFixture.java
+++ b/community/io/src/test/java/org/neo4j/io/pagecache/impl/muninn/MuninnPageCacheFixture.java
@@ -26,7 +26,7 @@
import org.neo4j.io.pagecache.PageSwapperFactory;
import org.neo4j.io.pagecache.tracing.PageCacheTracer;
-class MuninnPageCacheFixture extends PageCacheTestSupport.Fixture
+public class MuninnPageCacheFixture extends PageCacheTestSupport.Fixture
{
CountDownLatch backgroundFlushLatch;
diff --git a/community/io/src/test/java/org/neo4j/io/pagecache/impl/muninn/MuninnPageCacheSlowTestWithAdversarialFileDispatcherIT.java b/community/io/src/test/java/org/neo4j/io/pagecache/impl/muninn/MuninnPageCacheSlowTestWithAdversarialChannel.java
similarity index 52%
rename from community/io/src/test/java/org/neo4j/io/pagecache/impl/muninn/MuninnPageCacheSlowTestWithAdversarialFileDispatcherIT.java
rename to community/io/src/test/java/org/neo4j/io/pagecache/impl/muninn/MuninnPageCacheSlowTestWithAdversarialChannel.java
index 15839e78c3751..9e1e3dd01374a 100644
--- a/community/io/src/test/java/org/neo4j/io/pagecache/impl/muninn/MuninnPageCacheSlowTestWithAdversarialFileDispatcherIT.java
+++ b/community/io/src/test/java/org/neo4j/io/pagecache/impl/muninn/MuninnPageCacheSlowTestWithAdversarialChannel.java
@@ -19,27 +19,17 @@
*/
package org.neo4j.io.pagecache.impl.muninn;
-import org.junit.AfterClass;
-import org.junit.BeforeClass;
-import org.junit.runner.RunWith;
+import org.neo4j.adversaries.fs.AdversarialChannelDefaultFileSystemAbstraction;
-import org.neo4j.adversaries.fs.AdversarialFileChannel;
-import org.neo4j.test.bootclasspathrunner.BootClassPathRunner;
-import org.neo4j.unsafe.impl.internal.dragons.UnsafeUtilTest;
-
-@BootClassPathRunner.BootEntryOf( UnsafeUtilTest.class )
-@RunWith( BootClassPathRunner.class )
-public class MuninnPageCacheSlowTestWithAdversarialFileDispatcherIT extends MuninnPageCacheSlowTestWithRealFileSystemIT
+public class MuninnPageCacheSlowTestWithAdversarialChannel extends MuninnPageCacheSlowTestWithRealFileSystemIT
{
- @BeforeClass
- public static void enableAdversarialFileDispatcher()
- {
- AdversarialFileChannel.useAdversarialFileDispatcherHack = true;
- }
- @AfterClass
- public static void disableAdversarialFileDispatcher()
+ @Override
+ protected Fixture createFixture()
{
- AdversarialFileChannel.useAdversarialFileDispatcherHack = false;
+ return super.createFixture()
+ .withFileSystemAbstraction( AdversarialChannelDefaultFileSystemAbstraction::new )
+ .withFileConstructor( pathname -> directory.file( pathname ) );
}
+
}
diff --git a/community/io/src/test/java/org/neo4j/io/pagecache/impl/muninn/MuninnPageCacheWithAdversarialFileDispatcherIT.java b/community/io/src/test/java/org/neo4j/io/pagecache/impl/muninn/MuninnPageCacheWithAdversarialFileDispatcherIT.java
deleted file mode 100644
index 6ddf7243c5b60..0000000000000
--- a/community/io/src/test/java/org/neo4j/io/pagecache/impl/muninn/MuninnPageCacheWithAdversarialFileDispatcherIT.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (c) 2002-2016 "Neo Technology,"
- * Network Engine for Objects in Lund AB [http://neotechnology.com]
- *
- * This file is part of Neo4j.
- *
- * Neo4j is free software: you can redistribute it and/or modify
- * it under the terms of the GNU 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-package org.neo4j.io.pagecache.impl.muninn;
-
-import org.junit.AfterClass;
-import org.junit.BeforeClass;
-import org.junit.runner.RunWith;
-
-import org.neo4j.adversaries.fs.AdversarialFileChannel;
-import org.neo4j.test.bootclasspathrunner.BootClassPathRunner;
-import org.neo4j.unsafe.impl.internal.dragons.UnsafeUtilTest;
-
-/**
- * Use a special runner that will put the AccessibleFileDispatcher and the DelegateFileDispatcher in the -Xbootclasspath
- *
- * We already have the test-jar from the 'unsafe' module on our classpath. This custom test runner will put that
- * classpath entry on the boot classpath. We refer to that classpath entry through the UnsafeUtilTest class, because
- * we are not allowed to refer to the AccessibleFileDispatcher and the DelegateFileDispatcher classes directly. If we
- * try to load them normally, we will be told that they are not allowed to refer to the sun.nio.ch.FileDispatcher
- * superclass.
- *
- * To implement the boot classpath hack, the BootClassPathRunner will run the test in a sub-process, and tunnel the
- * JUnit communication through RMI.
- */
-@BootClassPathRunner.BootEntryOf( UnsafeUtilTest.class )
-@RunWith( BootClassPathRunner.class )
-public class MuninnPageCacheWithAdversarialFileDispatcherIT extends MuninnPageCacheWithRealFileSystemIT
-{
- @BeforeClass
- public static void enableAdversarialFileDispatcher()
- {
- AdversarialFileChannel.useAdversarialFileDispatcherHack = true;
- }
-
- @AfterClass
- public static void disableAdversarialFileDispatcher()
- {
- AdversarialFileChannel.useAdversarialFileDispatcherHack = false;
- }
-}
diff --git a/community/io/src/test/java/org/neo4j/test/bootclasspathrunner/BootClassPathRunner.java b/community/io/src/test/java/org/neo4j/test/bootclasspathrunner/BootClassPathRunner.java
deleted file mode 100644
index a794e0a96ed1b..0000000000000
--- a/community/io/src/test/java/org/neo4j/test/bootclasspathrunner/BootClassPathRunner.java
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
- * Copyright (c) 2002-2016 "Neo Technology,"
- * Network Engine for Objects in Lund AB [http://neotechnology.com]
- *
- * This file is part of Neo4j.
- *
- * Neo4j is free software: you can redistribute it and/or modify
- * it under the terms of the GNU 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-package org.neo4j.test.bootclasspathrunner;
-
-import org.junit.runner.Description;
-import org.junit.runner.Runner;
-import org.junit.runner.notification.RunNotifier;
-import org.junit.runners.BlockJUnit4ClassRunner;
-import org.junit.runners.model.InitializationError;
-
-import java.io.File;
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-import java.net.URL;
-import java.rmi.registry.LocateRegistry;
-import java.rmi.registry.Registry;
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-import org.neo4j.io.proc.ProcessUtil;
-
-public class BootClassPathRunner extends Runner
-{
- private static final String RMI_RUN_NOTIFIER_NAME = "RunNotifier";
-
- @Target( ElementType.TYPE )
- @Retention( RetentionPolicy.RUNTIME )
- public @interface BootEntryOf
- {
- Class> value();
- }
-
- private final Class> testClass;
- private final String classpathEntryToBootWith;
-
- @SuppressWarnings( "unchecked" )
- public BootClassPathRunner( Class> testClass ) throws Exception
- {
- this.testClass = testClass;
- BootEntryOf bootEntryOf = testClass.getAnnotation( BootEntryOf.class );
- Class> bootEntryOfClass = bootEntryOf.value();
- URL location = bootEntryOfClass.getProtectionDomain().getCodeSource().getLocation();
- this.classpathEntryToBootWith = location.getPath();
- }
-
- @Override
- public Description getDescription()
- {
- try
- {
- Runner describingRunner = new BlockJUnit4ClassRunner( testClass );
- return describingRunner.getDescription();
- }
- catch ( InitializationError initializationError )
- {
- throw new RuntimeException( initializationError );
- }
- }
-
- @Override
- public void run( RunNotifier notifier )
- {
- StringBuilder classpath = buildClassPath();
-
- try ( RmiServer server = new RmiServer() )
- {
- int port = server.getPort();
- server.export( RMI_RUN_NOTIFIER_NAME, new DelegatingRemoteRunNotifier( notifier ) );
-
- List command = new ArrayList<>();
- command.add( ProcessUtil.getJavaExecutable().toString() );
- for ( String argument : ProcessUtil.getJavaExecutableArguments() )
- {
- if ( !argument.startsWith( "-agentlib" ) )
- {
- command.add( argument );
- }
- }
- command.add( "-ea" );
- command.add( "-Xbootclasspath/a:" + classpathEntryToBootWith );
- command.add( "-cp" );
- command.add( classpath.toString() );
- command.add( getClass().getName() );
- command.add( String.valueOf( port ) );
- command.add( testClass.getName() );
-
- ProcessBuilder pb = new ProcessBuilder();
- pb.command( command );
- pb.inheritIO();
- Process process = pb.start();
- process.waitFor();
- }
- catch ( Exception e )
- {
- throw new RuntimeException( e );
- }
- }
-
- private StringBuilder buildClassPath()
- {
- Set classpathEntries = new HashSet<>();
- classpathEntries.addAll( ProcessUtil.getClassPathList() );
- classpathEntries.remove( classpathEntryToBootWith );
- StringBuilder classpath = new StringBuilder();
- for ( String classpathEntry : classpathEntries )
- {
- classpath.append( classpathEntry );
- classpath.append( File.pathSeparator );
- }
- classpath.setLength( classpath.length() - 1 ); // Cut off the last pathSeparator
- return classpath;
- }
-
- public static void main( String[] args ) throws Exception
- {
- int rmiPort = Integer.parseInt( args[0] );
- String testClassName = args[1];
- Class> testClass = Class.forName( testClassName );
-
- Registry registry = LocateRegistry.getRegistry( rmiPort );
- RemoteRunNotifier remote = (RemoteRunNotifier) registry.lookup( RMI_RUN_NOTIFIER_NAME );
-
- Runner runner = new BlockJUnit4ClassRunner( testClass );
- runner.run( new DelegatingRunNotifier( remote ) );
- }
-}
diff --git a/community/io/src/test/java/org/neo4j/test/bootclasspathrunner/DelegatingRemoteRunNotifier.java b/community/io/src/test/java/org/neo4j/test/bootclasspathrunner/DelegatingRemoteRunNotifier.java
deleted file mode 100644
index e8586738a3175..0000000000000
--- a/community/io/src/test/java/org/neo4j/test/bootclasspathrunner/DelegatingRemoteRunNotifier.java
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * Copyright (c) 2002-2016 "Neo Technology,"
- * Network Engine for Objects in Lund AB [http://neotechnology.com]
- *
- * This file is part of Neo4j.
- *
- * Neo4j is free software: you can redistribute it and/or modify
- * it under the terms of the GNU 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-package org.neo4j.test.bootclasspathrunner;
-
-import org.junit.runner.Description;
-import org.junit.runner.Result;
-import org.junit.runner.notification.Failure;
-import org.junit.runner.notification.RunListener;
-import org.junit.runner.notification.RunNotifier;
-import org.junit.runner.notification.StoppedByUserException;
-
-class DelegatingRemoteRunNotifier implements RemoteRunNotifier
-{
- private final RunNotifier delegate;
-
- public DelegatingRemoteRunNotifier( RunNotifier delegate )
- {
- this.delegate = delegate;
- }
-
- @Override
- public void addListener( RunListener listener )
- {
- delegate.addListener( listener );
- }
-
- @Override
- public void fireTestRunFinished( Result result )
- {
- delegate.fireTestRunFinished( result );
- }
-
- @Override
- public void pleaseStop()
- {
- delegate.pleaseStop();
- }
-
- @Override
- public void fireTestIgnored( Description description )
- {
- delegate.fireTestIgnored( description );
- }
-
- @Override
- public void fireTestStarted( Description description ) throws StoppedByUserException
- {
- delegate.fireTestStarted( description );
- }
-
- @Override
- public void fireTestFinished( Description description )
- {
- delegate.fireTestFinished( description );
- }
-
- @Override
- public void fireTestAssumptionFailed( Failure failure )
- {
- delegate.fireTestAssumptionFailed( failure );
- }
-
- @Override
- public void addFirstListener( RunListener listener )
- {
- delegate.addFirstListener( listener );
- }
-
- @Override
- public void removeListener( RunListener listener )
- {
- delegate.removeListener( listener );
- }
-
- @Override
- public void fireTestRunStarted( Description description )
- {
- delegate.fireTestRunStarted( description );
- }
-
- @Override
- public void fireTestFailure( Failure failure )
- {
- delegate.fireTestFailure( failure );
- }
-}
diff --git a/community/io/src/test/java/org/neo4j/test/bootclasspathrunner/DelegatingRunNotifier.java b/community/io/src/test/java/org/neo4j/test/bootclasspathrunner/DelegatingRunNotifier.java
deleted file mode 100644
index 7e9919d83a170..0000000000000
--- a/community/io/src/test/java/org/neo4j/test/bootclasspathrunner/DelegatingRunNotifier.java
+++ /dev/null
@@ -1,171 +0,0 @@
-/*
- * Copyright (c) 2002-2016 "Neo Technology,"
- * Network Engine for Objects in Lund AB [http://neotechnology.com]
- *
- * This file is part of Neo4j.
- *
- * Neo4j is free software: you can redistribute it and/or modify
- * it under the terms of the GNU 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-package org.neo4j.test.bootclasspathrunner;
-
-import org.junit.runner.Description;
-import org.junit.runner.Result;
-import org.junit.runner.notification.Failure;
-import org.junit.runner.notification.RunListener;
-import org.junit.runner.notification.RunNotifier;
-import org.junit.runner.notification.StoppedByUserException;
-
-import java.rmi.RemoteException;
-
-class DelegatingRunNotifier extends RunNotifier
-{
- private final RemoteRunNotifier delegate;
-
- public DelegatingRunNotifier( RemoteRunNotifier delegate )
- {
- this.delegate = delegate;
- }
-
- public void addListener( RunListener listener )
- {
- try
- {
- delegate.addListener( listener );
- }
- catch ( RemoteException e )
- {
- throw new RuntimeException( e );
- }
- }
-
- public void fireTestFinished( Description description )
- {
- try
- {
- delegate.fireTestFinished( description );
- }
- catch ( RemoteException e )
- {
- throw new RuntimeException( e );
- }
- }
-
- public void fireTestIgnored( Description description )
- {
- try
- {
- delegate.fireTestIgnored( description );
- }
- catch ( RemoteException e )
- {
- throw new RuntimeException( e );
- }
- }
-
- public void fireTestAssumptionFailed( Failure failure )
- {
- try
- {
- delegate.fireTestAssumptionFailed( failure );
- }
- catch ( RemoteException e )
- {
- throw new RuntimeException( e );
- }
- }
-
- public void fireTestFailure( Failure failure )
- {
- try
- {
- delegate.fireTestFailure( failure );
- }
- catch ( RemoteException e )
- {
- throw new RuntimeException( e );
- }
- }
-
- public void addFirstListener( RunListener listener )
- {
- try
- {
- delegate.addFirstListener( listener );
- }
- catch ( RemoteException e )
- {
- throw new RuntimeException( e );
- }
- }
-
- public void fireTestRunFinished( Result result )
- {
- try
- {
- delegate.fireTestRunFinished( result );
- }
- catch ( RemoteException e )
- {
- throw new RuntimeException( e );
- }
- }
-
- public void fireTestRunStarted( Description description )
- {
- try
- {
- delegate.fireTestRunStarted( description );
- }
- catch ( RemoteException e )
- {
- throw new RuntimeException( e );
- }
- }
-
- public void fireTestStarted( Description description ) throws StoppedByUserException
- {
- try
- {
- delegate.fireTestStarted( description );
- }
- catch ( RemoteException e )
- {
- throw new RuntimeException( e );
- }
- }
-
- public void removeListener( RunListener listener )
- {
- try
- {
- delegate.removeListener( listener );
- }
- catch ( RemoteException e )
- {
- throw new RuntimeException( e );
- }
- }
-
- public void pleaseStop()
- {
- try
- {
- delegate.pleaseStop();
- }
- catch ( RemoteException e )
- {
- throw new RuntimeException( e );
- }
- }
-}
diff --git a/community/io/src/test/java/org/neo4j/test/bootclasspathrunner/RemoteRunNotifier.java b/community/io/src/test/java/org/neo4j/test/bootclasspathrunner/RemoteRunNotifier.java
deleted file mode 100644
index 968768013abab..0000000000000
--- a/community/io/src/test/java/org/neo4j/test/bootclasspathrunner/RemoteRunNotifier.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (c) 2002-2016 "Neo Technology,"
- * Network Engine for Objects in Lund AB [http://neotechnology.com]
- *
- * This file is part of Neo4j.
- *
- * Neo4j is free software: you can redistribute it and/or modify
- * it under the terms of the GNU 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-package org.neo4j.test.bootclasspathrunner;
-
-import org.junit.runner.Description;
-import org.junit.runner.Result;
-import org.junit.runner.notification.Failure;
-import org.junit.runner.notification.RunListener;
-import org.junit.runner.notification.StoppedByUserException;
-
-import java.rmi.Remote;
-import java.rmi.RemoteException;
-
-interface RemoteRunNotifier extends Remote
-{
- void addListener( RunListener listener ) throws RemoteException;
-
- void fireTestRunFinished( Result result ) throws RemoteException;
-
- void pleaseStop() throws RemoteException;
-
- void fireTestIgnored( Description description ) throws RemoteException;
-
- void fireTestStarted( Description description ) throws StoppedByUserException, RemoteException;
-
- void fireTestFinished( Description description ) throws RemoteException;
-
- void fireTestAssumptionFailed( Failure failure ) throws RemoteException;
-
- void addFirstListener( RunListener listener ) throws RemoteException;
-
- void removeListener( RunListener listener ) throws RemoteException;
-
- void fireTestRunStarted( Description description ) throws RemoteException;
-
- void fireTestFailure( Failure failure ) throws RemoteException;
-}
diff --git a/community/io/src/test/java/org/neo4j/test/bootclasspathrunner/RmiServer.java b/community/io/src/test/java/org/neo4j/test/bootclasspathrunner/RmiServer.java
deleted file mode 100644
index c6a9f29e26a5b..0000000000000
--- a/community/io/src/test/java/org/neo4j/test/bootclasspathrunner/RmiServer.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Copyright (c) 2002-2016 "Neo Technology,"
- * Network Engine for Objects in Lund AB [http://neotechnology.com]
- *
- * This file is part of Neo4j.
- *
- * Neo4j is free software: you can redistribute it and/or modify
- * it under the terms of the GNU 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-package org.neo4j.test.bootclasspathrunner;
-
-import java.rmi.Remote;
-import java.rmi.RemoteException;
-import java.rmi.registry.LocateRegistry;
-import java.rmi.registry.Registry;
-import java.rmi.server.UnicastRemoteObject;
-import java.util.ArrayList;
-import java.util.List;
-
-class RmiServer implements AutoCloseable
-{
- // The Registry is only initialised once per JVM, because otherwise RMI will complain
- private static Registry registry;
- private static int port = Registry.REGISTRY_PORT;
-
- private List boundNames = new ArrayList<>();
-
- public RmiServer()
- {
- createRegistry();
-
- }
-
- private static synchronized void createRegistry()
- {
- while ( registry == null )
- {
- try
- {
- registry = LocateRegistry.createRegistry( port );
- }
- catch ( RemoteException e )
- {
- port++;
- if ( port > Registry.REGISTRY_PORT + 4000 )
- {
- throw new RuntimeException( e );
- }
- }
- }
- }
-
- public int getPort()
- {
- return port;
- }
-
- public void export( String name, Remote remote )
- {
- try
- {
- Remote stub = UnicastRemoteObject.exportObject( remote, port );
- registry.rebind( name, stub );
- }
- catch ( RemoteException e )
- {
- throw new RuntimeException( e );
- }
- }
-
- @Override
- public void close() throws Exception
- {
- for ( String name : registry.list() )
- {
- registry.unbind( name );
- }
- }
-}
diff --git a/community/unsafe/src/test/java/sun/nio/ch/AccessibleFileDisptacher.java b/community/unsafe/src/test/java/sun/nio/ch/AccessibleFileDisptacher.java
deleted file mode 100644
index c7d71aeb11f18..0000000000000
--- a/community/unsafe/src/test/java/sun/nio/ch/AccessibleFileDisptacher.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (c) 2002-2016 "Neo Technology,"
- * Network Engine for Objects in Lund AB [http://neotechnology.com]
- *
- * This file is part of Neo4j.
- *
- * Neo4j is free software: you can redistribute it and/or modify
- * it under the terms of the GNU 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-package sun.nio.ch;
-
-import java.io.FileDescriptor;
-import java.io.IOException;
-
-public abstract class AccessibleFileDisptacher extends FileDispatcher
-{
- // FileDispatcher:
- public abstract int force(FileDescriptor fd, boolean metaData) throws IOException;
- public abstract int force(FileDescriptor fd, boolean metaData, boolean writable) throws IOException;
- public abstract int truncate(FileDescriptor fd, long size) throws IOException;
- public abstract long size(FileDescriptor fd) throws IOException;
- public abstract int lock(FileDescriptor fd, boolean blocking, long pos, long size, boolean shared) throws IOException;
- public abstract void release(FileDescriptor fd, long pos, long size) throws IOException;
- public abstract FileDescriptor duplicateForMapping(FileDescriptor fd) throws IOException;
-
- // NativeDispatcher:
- public abstract int read(FileDescriptor fd, long address, int len) throws IOException;
- public boolean needsPositionLock() { return super.needsPositionLock(); }
- public int pread(FileDescriptor fd, long address, int len, long position) throws IOException { return super.pread( fd, address, len, position ); }
- public abstract long readv(FileDescriptor fd, long address, int len) throws IOException;
- public abstract int write(FileDescriptor fd, long address, int len) throws IOException;
- public int pwrite(FileDescriptor fd, long address, int len, long position) throws IOException { return super.pwrite( fd, address, len, position ); }
- public abstract long writev(FileDescriptor fd, long address, int len) throws IOException;
- public abstract void close(FileDescriptor fd) throws IOException;
- public void preClose(FileDescriptor fd) throws IOException { }
-}
diff --git a/community/unsafe/src/test/java/sun/nio/ch/DelegateFileDispatcher.java b/community/unsafe/src/test/java/sun/nio/ch/DelegateFileDispatcher.java
deleted file mode 100644
index c1eb8f6bba19a..0000000000000
--- a/community/unsafe/src/test/java/sun/nio/ch/DelegateFileDispatcher.java
+++ /dev/null
@@ -1,228 +0,0 @@
-/*
- * Copyright (c) 2002-2016 "Neo Technology,"
- * Network Engine for Objects in Lund AB [http://neotechnology.com]
- *
- * This file is part of Neo4j.
- *
- * Neo4j is free software: you can redistribute it and/or modify
- * it under the terms of the GNU 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-package sun.nio.ch;
-
-import java.io.FileDescriptor;
-import java.io.IOException;
-import java.lang.invoke.MethodHandle;
-import java.lang.invoke.MethodType;
-import java.lang.reflect.Method;
-import java.nio.channels.SelectableChannel;
-
-import org.neo4j.unsafe.impl.internal.dragons.LookupBypass;
-
-public class DelegateFileDispatcher extends AccessibleFileDisptacher
-{
- private final FileDispatcher delegate;
-
- public DelegateFileDispatcher( Object delegate )
- {
- this.delegate = (FileDispatcher) delegate;
- }
-
- // Specific to all platforms other than Oracle JDK 7 on Linux, it seems
- public int force( FileDescriptor fd, boolean metaData ) throws IOException
- {
- try
- {
- return (int) forceHandle.invokeExact( delegate, fd, metaData );
- }
- catch ( Throwable throwable )
- {
- throw new LinkageError( "not linked: FileDispatcher.force(FileDescriptor, boolean)", throwable );
- }
- }
-
- // Specific to Oracle JDK 7 on Linux
- public int force( FileDescriptor fd, boolean metaData, boolean writable ) throws IOException
- {
- try
- {
- return (int) forceHandle.invokeExact( delegate, fd, metaData, writable );
- }
- catch ( Throwable throwable )
- {
- throw new LinkageError( "not linked: FileDispatcher.force(FileDescriptor, boolean, boolean)", throwable );
- }
- }
-
- private static final MethodHandle forceHandle = getForceHandle();
-
- private static MethodHandle getForceHandle()
- {
- LookupBypass lookup = new LookupBypass();
- MethodType arg2 = MethodType.methodType( int.class, FileDescriptor.class, boolean.class );
- MethodType arg3 = MethodType.methodType( int.class, FileDescriptor.class, boolean.class, boolean.class );
- MethodHandle handle = lookupFileDispatcherHandle( lookup, "force", arg2, false );
- if ( handle == null )
- {
- handle = lookupFileDispatcherHandle( lookup, "force", arg3, true );
- }
- return handle;
- }
-
- public long readv( FileDescriptor fd, long address, int len ) throws IOException
- {
- return delegate.readv( fd, address, len );
- }
-
- public int lock( FileDescriptor fd, boolean blocking, long pos, long size, boolean shared ) throws IOException
- {
- return delegate.lock( fd, blocking, pos, size, shared );
- }
-
- public FileDescriptor duplicateForMapping( FileDescriptor fd ) throws IOException
- {
- return delegate.duplicateForMapping( fd );
- }
-
- public int read( FileDescriptor fd, long address, int len ) throws IOException
- {
- return delegate.read( fd, address, len );
- }
-
- public int pwrite( FileDescriptor fd, long address, int len, long position ) throws IOException
- {
- return delegate.pwrite( fd, address, len, position );
- }
-
- public void preClose( FileDescriptor fd ) throws IOException
- {
- delegate.preClose( fd );
- }
-
- public int truncate( FileDescriptor fd, long size ) throws IOException
- {
- return delegate.truncate( fd, size );
- }
-
- public void release( FileDescriptor fd, long pos, long size ) throws IOException
- {
- delegate.release( fd, pos, size );
- }
-
- public boolean needsPositionLock()
- {
- return delegate.needsPositionLock();
- }
-
- public long size( FileDescriptor fd ) throws IOException
- {
- return delegate.size( fd );
- }
-
- public int pread( FileDescriptor fd, long address, int len, long position ) throws IOException
- {
- return delegate.pread( fd, address, len, position );
- }
-
- public long writev( FileDescriptor fd, long address, int len ) throws IOException
- {
- return delegate.writev( fd, address, len );
- }
-
- public int write( FileDescriptor fd, long address, int len ) throws IOException
- {
- return delegate.write( fd, address, len );
- }
-
- public void close( FileDescriptor fd ) throws IOException
- {
- delegate.close( fd );
- }
-
- // new method introduced in oracle 8u60 and 7u80
- boolean transferToDirectlyNeedsPositionLock()
- {
- if ( transferToDirectlyNeedsPositionLockHandle == null )
- {
- // whatever it should not be called...
- return false;
- }
-
- try
- {
- return (Boolean) transferToDirectlyNeedsPositionLockHandle.invokeExact( delegate );
- }
- catch ( Throwable throwable )
- {
- throw new LinkageError( "not linked: FileDispatcher.transferToDirectlyNeedsPositionLock()", throwable );
- }
- }
-
- private static final MethodHandle transferToDirectlyNeedsPositionLockHandle =
- getTransferToDirectlyNeedsPositionLockHandle();
-
- public static MethodHandle getTransferToDirectlyNeedsPositionLockHandle()
- {
- LookupBypass lookup = new LookupBypass();
- MethodType methodType = MethodType.methodType( boolean.class );
- return lookupFileDispatcherHandle( lookup, "transferToDirectlyNeedsPositionLock", methodType, false );
- }
-
- // new method introduced in oracle 8u60 and 7u80
- boolean canTransferToDirectly( SelectableChannel selectableChannel )
- {
- if ( canTransferToDirectlyHandle == null )
- {
- // whatever it should not be called...
- return false;
- }
-
- try
- {
- return (Boolean) canTransferToDirectlyHandle.invokeExact( delegate, selectableChannel );
- }
- catch ( Throwable throwable )
- {
- throw new LinkageError( "not linked: FileDispatcher.canTransferToDirectly(SelectableChannel)", throwable );
- }
- }
-
- private static final MethodHandle canTransferToDirectlyHandle = getCanTransferToDirectlyHandle();
-
- public static MethodHandle getCanTransferToDirectlyHandle()
- {
- LookupBypass lookup = new LookupBypass();
- MethodType methodType = MethodType.methodType( boolean.class, SelectableChannel.class );
- return lookupFileDispatcherHandle( lookup, "canTransferToDirectly", methodType, false );
- }
-
- // utility method
- private static MethodHandle lookupFileDispatcherHandle(
- LookupBypass lookup, String name, MethodType type, boolean throwOnError )
- {
- try
- {
- Class cls = FileDispatcher.class;
- Method method = cls.getDeclaredMethod( name, type.parameterArray() );
- method.setAccessible( true );
- return lookup.unreflect( method ); // We have to unreflect because we need to setAccessible( true )
- }
- catch ( Exception e )
- {
- if ( throwOnError )
- {
- throw new LinkageError( "No such FileDispatcher method: " + name + " of type " + type );
- }
- return null;
- }
- }
-}