Skip to content

Commit

Permalink
Simplify page cache adversarial tests, reorganise page cache harness …
Browse files Browse the repository at this point in the history
…tests

Remove BootClassPathRunner infrustructure of page cache adversarial tests since those where extremelly flaky under IBM JDK.
Switch those tests to inject and use adversarial file system or adversarial channel instead of custom file dispatcher.

Extract page cache harness into separate tests.
  • Loading branch information
MishaDemianenko committed Apr 14, 2016
1 parent b04ab8a commit 4d9a371
Show file tree
Hide file tree
Showing 21 changed files with 361 additions and 1,228 deletions.
Expand Up @@ -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. // Returning only the channel is ok, because the channel, when close()d will close its parent File.
FileChannel channel = new RandomAccessFile( fileName, mode ).getChannel(); FileChannel channel = new RandomAccessFile( fileName, mode ).getChannel();
return new StoreFileChannel( channel ); return getStoreFileChannel( channel );
} }


@Override @Override
Expand Down Expand Up @@ -194,4 +194,9 @@ public void truncate( File path, long size ) throws IOException
{ {
FileUtils.truncateFile( path, size ); FileUtils.truncateFile( path, size );
} }

protected StoreFileChannel getStoreFileChannel( FileChannel channel )
{
return new StoreFileChannel( channel );
}
} }
@@ -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 <http://www.gnu.org/licenses/>.
*/
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} <b>except</b> 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 );
}
}
Expand Up @@ -19,56 +19,28 @@
*/ */
package org.neo4j.adversaries.fs; package org.neo4j.adversaries.fs;


import sun.nio.ch.FileChannelImpl;

import java.io.IOException; import java.io.IOException;
import java.lang.reflect.Field;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.channels.FileLock; import java.nio.channels.FileLock;


import org.neo4j.adversaries.Adversary; import org.neo4j.adversaries.Adversary;
import org.neo4j.io.fs.StoreChannel; import org.neo4j.io.fs.StoreChannel;
import org.neo4j.io.fs.StoreFileChannel; import org.neo4j.io.fs.StoreFileChannel;
import org.neo4j.io.fs.StoreFileChannelUnwrapper;

import static org.neo4j.adversaries.fs.AdversarialFileDispatcherFactory.makeFileDispatcherAdversarial;


@SuppressWarnings( "unchecked" ) @SuppressWarnings( "unchecked" )
public class AdversarialFileChannel implements StoreChannel public class AdversarialFileChannel extends StoreFileChannel
{ {
public static volatile boolean useAdversarialFileDispatcherHack;

private final StoreChannel delegate; private final StoreChannel delegate;
private final Adversary adversary; 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 ); return new AdversarialFileChannel( channel, adversary );
} }


private AdversarialFileChannel( StoreChannel channel, Adversary adversary ) private AdversarialFileChannel( StoreFileChannel channel, Adversary adversary )
{ {
super( channel );
this.delegate = channel; this.delegate = channel;
this.adversary = adversary; this.adversary = adversary;
} }
Expand Down Expand Up @@ -130,17 +102,17 @@ public long write( ByteBuffer[] srcs, int offset, int length ) throws IOExceptio
} }


@Override @Override
public StoreChannel truncate( long size ) throws IOException public StoreFileChannel truncate( long size ) throws IOException
{ {
adversary.injectFailure( IOException.class ); adversary.injectFailure( IOException.class );
return delegate.truncate( size ); return (StoreFileChannel) delegate.truncate( size );
} }


@Override @Override
public StoreChannel position( long newPosition ) throws IOException public StoreFileChannel position( long newPosition ) throws IOException
{ {
adversary.injectFailure( IOException.class ); adversary.injectFailure( IOException.class );
return delegate.position( newPosition ); return (StoreFileChannel) delegate.position( newPosition );
} }


@Override @Override
Expand Down

This file was deleted.

Expand Up @@ -40,6 +40,7 @@
import org.neo4j.io.fs.DefaultFileSystemAbstraction; import org.neo4j.io.fs.DefaultFileSystemAbstraction;
import org.neo4j.io.fs.FileSystemAbstraction; import org.neo4j.io.fs.FileSystemAbstraction;
import org.neo4j.io.fs.StoreChannel; import org.neo4j.io.fs.StoreChannel;
import org.neo4j.io.fs.StoreFileChannel;


/** /**
* Used by the robustness suite to check for partial failures. * Used by the robustness suite to check for partial failures.
Expand All @@ -64,7 +65,7 @@ public AdversarialFileSystemAbstraction( Adversary adversary, FileSystemAbstract
public StoreChannel open( File fileName, String mode ) throws IOException public StoreChannel open( File fileName, String mode ) throws IOException
{ {
adversary.injectFailure( FileNotFoundException.class, IOException.class, SecurityException.class ); 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 public boolean renameFile( File from, File to ) throws IOException
Expand All @@ -82,7 +83,7 @@ public OutputStream openAsOutputStream( File fileName, boolean append ) throws I
public StoreChannel create( File fileName ) throws IOException public StoreChannel create( File fileName ) throws IOException
{ {
adversary.injectFailure( FileNotFoundException.class, IOException.class, SecurityException.class ); 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 ) public boolean mkdir( File fileName )
Expand Down

0 comments on commit 4d9a371

Please sign in to comment.