Skip to content

Commit

Permalink
Update io module test to junit 5. Introduce common extensions.
Browse files Browse the repository at this point in the history
Rewrite all, except parametrized tests, in junit 5.
Introduce common test extensions.
Introduce Inject annotation to inject test resources from custom extensions.
  • Loading branch information
MishaDemianenko committed May 31, 2018
1 parent 63f0c76 commit cf0d91c
Show file tree
Hide file tree
Showing 61 changed files with 4,623 additions and 4,115 deletions.
@@ -0,0 +1,32 @@
/*
* Copyright (c) 2002-2018 "Neo4j,"
* Neo4j Sweden AB [http://neo4j.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.test.extension;

import java.lang.annotation.Retention;
import java.lang.annotation.Target;

import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.RetentionPolicy.RUNTIME;

@Target( FIELD )
@Retention( RUNTIME )
public @interface Inject
{
}
@@ -0,0 +1,105 @@
/*
* Copyright (c) 2002-2018 "Neo4j,"
* Neo4j Sweden AB [http://neo4j.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.test.extension;

import org.junit.jupiter.api.extension.AfterAllCallback;
import org.junit.jupiter.api.extension.ExtensionContext;
import org.junit.jupiter.api.extension.ExtensionContext.Namespace;
import org.junit.jupiter.api.extension.ExtensionContext.Store;
import org.junit.jupiter.api.extension.TestInstancePostProcessor;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.function.Function;

public abstract class StatefullFieldExtension<T> implements TestInstancePostProcessor, AfterAllCallback
{
protected abstract String getFieldKey();

protected abstract Class<T> getFieldType();

protected abstract T createField( ExtensionContext extensionContext );

protected abstract Namespace getNameSpace();

@Override
public void afterAll( ExtensionContext context )
{
removeStoredValue( context );
}

@Override
public void postProcessTestInstance( Object testInstance, ExtensionContext context ) throws Exception
{
Class<?> clazz = testInstance.getClass();
List<Field> declaredFields = getAllFields( clazz );
for ( Field declaredField : declaredFields )
{
if ( declaredField.isAnnotationPresent( Inject.class ) &&
getFieldType().equals( declaredField.getType() ) )
{
declaredField.setAccessible( true );
declaredField.set( testInstance, createFieldInstance( context ) );
}
}
}

T getStoredValue( ExtensionContext context )
{
return getLocalStore( context ).get( getFieldKey(), getFieldType() );
}

void removeStoredValue( ExtensionContext context )
{
getLocalStore( context ).remove( getFieldKey(), getFieldType() );
}

Store getStore( ExtensionContext extensionContext, Namespace namespace )
{
return extensionContext.getRoot().getStore( namespace );
}

private Store getLocalStore( ExtensionContext extensionContext )
{
return getStore( extensionContext, getNameSpace() );
}

private Object createFieldInstance( ExtensionContext extensionContext )
{
Store store = getLocalStore( extensionContext );
return store.getOrComputeIfAbsent( getFieldKey(), (Function<String,Object>) s -> createField( extensionContext ) );
}

private static List<Field> getAllFields( Class<?> baseClazz )
{
ArrayList<Field> fields = new ArrayList<>();
Class<?> clazz = baseClazz;
do
{
Collections.addAll( fields, clazz.getDeclaredFields() );
clazz = clazz.getSuperclass();
}
while ( clazz != null );
return fields;
}
}
@@ -0,0 +1,70 @@
/*
* Copyright (c) 2002-2018 "Neo4j,"
* Neo4j Sweden AB [http://neo4j.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.test.extension;

import org.junit.jupiter.api.extension.AfterEachCallback;
import org.junit.jupiter.api.extension.BeforeEachCallback;
import org.junit.jupiter.api.extension.ExtensionContext;
import org.junit.jupiter.api.extension.ExtensionContext.Namespace;

import org.neo4j.test.rule.SuppressOutput;

public class SuppressOutputExtension extends StatefullFieldExtension<SuppressOutput> implements BeforeEachCallback, AfterEachCallback
{
private static final String SUPPRESS_OUTPUT = "suppressOutput";
private static final Namespace SUPPRESS_OUTPUT_NAMESPACE = Namespace.create( SUPPRESS_OUTPUT );

@Override
protected String getFieldKey()
{
return SUPPRESS_OUTPUT;
}

@Override
protected Class<SuppressOutput> getFieldType()
{
return SuppressOutput.class;
}

@Override
protected SuppressOutput createField( ExtensionContext extensionContext )
{
return SuppressOutput.suppressAll();
}

@Override
protected Namespace getNameSpace()
{
return SUPPRESS_OUTPUT_NAMESPACE;
}

@Override
public void afterEach( ExtensionContext context )
{
getStoredValue( context ).releaseVoices( context.getExecutionException().isPresent() );
removeStoredValue( context );
}

@Override
public void beforeEach( ExtensionContext context )
{
getStoredValue( context ).captureVoices();
}
}
Expand Up @@ -153,7 +153,7 @@ void restore( boolean failure )

public <T> T call( Callable<T> callable ) throws Exception
{
voices = captureVoices();
captureVoices();
boolean failure = true;
try
{
Expand Down Expand Up @@ -210,7 +210,7 @@ public Statement apply( final Statement base, Description description )
@Override
public void evaluate() throws Throwable
{
voices = captureVoices();
captureVoices();
boolean failure = true;
try
{
Expand Down Expand Up @@ -273,7 +273,7 @@ public String toString()
abstract void restore( boolean failure ) throws IOException;
}

Voice[] captureVoices()
public void captureVoices()
{
Voice[] voices = new Voice[suppressibles.length];
boolean ok = false;
Expand All @@ -292,7 +292,12 @@ Voice[] captureVoices()
releaseVoices( voices, false );
}
}
return voices;
this.voices = voices;
}

public void releaseVoices( boolean failure )
{
releaseVoices( voices, failure );
}

void releaseVoices( Voice[] voices, boolean failure )
Expand Down
4 changes: 4 additions & 0 deletions community/io/pom.xml
Expand Up @@ -97,6 +97,10 @@ the relevant Commercial Agreement.
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-junit-jupiter</artifactId>
</dependency>
<dependency>
<groupId>org.neo4j</groupId>
<artifactId>neo4j-unsafe</artifactId>
Expand Down
Expand Up @@ -54,7 +54,7 @@ protected void throwOneOf( Class<? extends Throwable>... types )

public static void sneakyThrow( Throwable throwable )
{
AbstractAdversary._sneakyThrow( throwable );
_sneakyThrow( throwable );
}

// http://youtu.be/7qXXWHfJha4
Expand Down
Expand Up @@ -19,19 +19,19 @@
*/
package org.neo4j.adversaries.pagecache;

import org.junit.Test;
import org.junit.jupiter.api.Test;

import java.util.concurrent.atomic.AtomicBoolean;

import org.neo4j.io.pagecache.ByteArrayPageCursor;
import org.neo4j.test.rule.PageCacheRule;

import static org.junit.Assert.assertEquals;
import static org.junit.jupiter.api.Assertions.assertEquals;

public class AdversarialReadPageCursorTest
class AdversarialReadPageCursorTest
{
@Test
public void shouldNotMessUpUnrelatedSegmentOnReadBytes() throws Exception
void shouldNotMessUpUnrelatedSegmentOnReadBytes() throws Exception
{
// Given
byte[] buf = new byte[4];
Expand Down
Expand Up @@ -19,7 +19,6 @@
*/
package org.neo4j.graphdb.mockfs;

import java.io.IOException;
import java.util.zip.ZipOutputStream;

import org.neo4j.io.fs.FileSystemAbstraction;
Expand Down
Expand Up @@ -29,6 +29,7 @@
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Reader;
import java.io.UncheckedIOException;
import java.io.Writer;
import java.lang.ref.WeakReference;
import java.nio.ByteBuffer;
Expand All @@ -55,7 +56,6 @@
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function;
Expand Down Expand Up @@ -119,9 +119,7 @@ private void initCurrentWorkingDirectory()
}
catch ( IOException e )
{
System.err.println(
"WARNING: EphemeralFileSystemAbstraction could not initialise current working directory" );
e.printStackTrace();
throw new UncheckedIOException( "EphemeralFileSystemAbstraction could not initialise current working directory", e );
}
}

Expand Down Expand Up @@ -334,11 +332,8 @@ private File canonicalFile( File file )
}
catch ( IOException e )
{
System.err.println( "WARNING: EphemeralFileSystemAbstraction could not canonicalise file: " + file );
e.printStackTrace();
throw new UncheckedIOException( "EphemeralFileSystemAbstraction could not canonicalise file: " + file, e );
}
// Ugly fallback
return file.getAbsoluteFile();
}

@Override
Expand Down

0 comments on commit cf0d91c

Please sign in to comment.