Skip to content

Commit

Permalink
NativeLabelScanStoreStartupIT (part of lss compliance testing)
Browse files Browse the repository at this point in the history
  • Loading branch information
tinwelint committed Jan 22, 2017
1 parent 8726899 commit f5caecd
Show file tree
Hide file tree
Showing 3 changed files with 137 additions and 53 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,31 +19,23 @@
*/
package org.neo4j.graphdb;

import org.apache.commons.lang3.ArrayUtils;
import org.junit.Rule;
import org.junit.Test;

import java.io.File;
import java.io.IOException;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;

import org.neo4j.collection.primitive.PrimitiveLongCollections;
import org.neo4j.io.fs.FileUtils;
import org.neo4j.graphdb.factory.GraphDatabaseBuilder;
import org.neo4j.io.pagecache.IOLimiter;
import org.neo4j.kernel.NeoStoreDataSource;
import org.neo4j.kernel.api.impl.labelscan.LabelScanStoreTest;
import org.neo4j.kernel.api.labelscan.LabelScanStore;
import org.neo4j.kernel.api.labelscan.LabelScanWriter;
import org.neo4j.kernel.api.labelscan.NodeLabelUpdate;
import org.neo4j.kernel.impl.api.scan.LabelScanStoreProvider;
import org.neo4j.kernel.impl.core.ThreadToStatementContextBridge;
import org.neo4j.kernel.impl.transaction.state.DataSourceManager;
import org.neo4j.storageengine.api.schema.LabelScanReader;
import org.neo4j.test.rule.DatabaseRule;
import org.neo4j.test.rule.EmbeddedDatabaseRule;
import org.neo4j.test.rule.RandomRule;

import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
Expand All @@ -53,19 +45,28 @@ public abstract class LabelScanStoreStartupIT
private static final Label LABEL = Label.label( "testLabel" );

@Rule
public final DatabaseRule dbRule = new EmbeddedDatabaseRule( getClass() );
public final DatabaseRule dbRule = new EmbeddedDatabaseRule( getClass() )
{
@Override
protected void configure( GraphDatabaseBuilder builder )
{
addSpecificConfig( builder );
}
};
@Rule
public final RandomRule random = new RandomRule();

private int labelId;

protected abstract void addSpecificConfig( GraphDatabaseBuilder builder );

@Test
public void scanStoreStartWithoutExistentIndex() throws IOException
{
NeoStoreDataSource dataSource = getDataSource();
LabelScanStore labelScanStore = getLabelScanStore( dbRule );
LabelScanStore labelScanStore = getLabelScanStore();
labelScanStore.shutdown();

File labelScanStoreDirectory = getLabelScanStoreDirectory( dataSource );
FileUtils.deleteRecursively( labelScanStoreDirectory );
deleteLabelScanStoreFiles( dbRule.getStoreDirFile() );

labelScanStore.init();
labelScanStore.start();
Expand All @@ -76,16 +77,15 @@ public void scanStoreStartWithoutExistentIndex() throws IOException
@Test
public void scanStoreRecreateCorruptedIndexOnStartup() throws IOException
{
NeoStoreDataSource dataSource = getDataSource();
LabelScanStore labelScanStore = getLabelScanStore( dbRule );
LabelScanStore labelScanStore = getLabelScanStore();

Node node = createTestNode();
createTestNode();
long[] labels = readNodesForLabel( labelScanStore );
assertEquals( "Label scan store see 1 label for node", 1, labels.length );
labelScanStore.force( IOLimiter.unlimited() );
labelScanStore.shutdown();

corruptIndex( dataSource );
corruptLabelScanStoreFiles( dbRule.getStoreDirFile() );

labelScanStore.init();
labelScanStore.start();
Expand All @@ -94,6 +94,11 @@ public void scanStoreRecreateCorruptedIndexOnStartup() throws IOException
assertArrayEquals( "Store should rebuild corrupted index", labels, rebuildLabels );
}

private LabelScanStore getLabelScanStore()
{
return dbRule.getDependencyResolver().resolveDependency( LabelScanStore.class );
}

private long[] readNodesForLabel( LabelScanStore labelScanStore )
{
try ( LabelScanReader reader = labelScanStore.newReader() )
Expand All @@ -116,33 +121,14 @@ private Node createTestNode()
return node;
}

private void corruptIndex( NeoStoreDataSource dataSource ) throws IOException
protected void scrambleFile( File file ) throws IOException
{
File labelScanStoreDirectory = getLabelScanStoreDirectory( dataSource );
Files.walkFileTree( labelScanStoreDirectory.toPath(), new SimpleFileVisitor<Path>()
{
@Override
public FileVisitResult visitFile( Path file, BasicFileAttributes attrs ) throws IOException
{
Files.write( file, ArrayUtils.add(Files.readAllBytes( file ), (byte) 7 ));
return FileVisitResult.CONTINUE;
}
} );
LabelScanStoreTest.scrambleFile( random.random(), file );
}

private File getLabelScanStoreDirectory( NeoStoreDataSource dataSource )
{
return LabelScanStoreProvider.getStoreDirectory( dataSource.getStoreDir() );
}

private NeoStoreDataSource getDataSource()
{
DependencyResolver dependencyResolver = dbRule.getDependencyResolver();
DataSourceManager dataSourceManager = dependencyResolver.resolveDependency( DataSourceManager.class );
return dataSourceManager.getDataSource();
}
protected abstract void corruptLabelScanStoreFiles( File storeDirectory ) throws IOException;

protected abstract LabelScanStore getLabelScanStore( DatabaseRule dbRule );
protected abstract void deleteLabelScanStoreFiles( File storeDirectory ) throws IOException;

private void checkLabelScanStoreAccessible( LabelScanStore labelScanStore ) throws IOException
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/*
* Copyright (c) 2002-2017 "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.kernel.impl.index.labelscan;

import java.io.File;
import java.io.IOException;

import org.neo4j.graphdb.LabelScanStoreStartupIT;
import org.neo4j.graphdb.factory.GraphDatabaseBuilder;
import org.neo4j.kernel.impl.api.scan.NativeLabelScanStoreExtension;

import static org.junit.Assert.assertTrue;

import static org.neo4j.graphdb.factory.GraphDatabaseSettings.label_scan_store;

public class NativeLabelScanStoreStartupIT extends LabelScanStoreStartupIT
{
@Override
protected void addSpecificConfig( GraphDatabaseBuilder builder )
{
builder.setConfig( label_scan_store, NativeLabelScanStoreExtension.LABEL_SCAN_STORE_NAME );
}

@Override
protected void corruptLabelScanStoreFiles( File storeDirectory ) throws IOException
{
scrambleFile( storeFile( storeDirectory ) );
}

@Override
protected void deleteLabelScanStoreFiles( File storeDirectory ) throws IOException
{
assertTrue( storeFile( storeDirectory ).delete() );
}

private static File storeFile( File directory )
{
return new File( directory, NativeLabelScanStore.FILE_NAME );
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,21 +19,62 @@
*/
package org.neo4j.graphdb;

import org.neo4j.kernel.api.impl.labelscan.LuceneLabelScanStore;
import org.neo4j.kernel.api.labelscan.LabelScanStore;
import org.neo4j.test.rule.DatabaseRule;
import java.io.File;
import java.io.IOException;
import java.util.Collections;
import java.util.List;
import java.util.stream.Stream;

import static org.hamcrest.Matchers.instanceOf;
import static org.junit.Assert.assertThat;
import org.neo4j.graphdb.factory.GraphDatabaseBuilder;
import org.neo4j.kernel.api.impl.labelscan.LuceneLabelScanIndexBuilder;
import org.neo4j.kernel.api.impl.labelscan.LuceneLabelScanStoreExtension;

import static org.junit.Assert.assertTrue;

import static java.util.stream.Collectors.toList;

import static org.neo4j.graphdb.factory.GraphDatabaseSettings.label_scan_store;
import static org.neo4j.io.fs.FileUtils.deleteRecursively;

public class LuceneLabelScanStoreStartupIT extends LabelScanStoreStartupIT
{
@Override
protected LabelScanStore getLabelScanStore( DatabaseRule dbRule )
protected void addSpecificConfig( GraphDatabaseBuilder builder )
{
builder.setConfig( label_scan_store, LuceneLabelScanStoreExtension.LABEL_SCAN_STORE_NAME );
}

private List<File> labelScanStoreIndexDirectories( File storeDirectory )
{
File rootDir = new File( new File( new File( new File( storeDirectory, "schema" ), "label" ), "lucene" ),
LuceneLabelScanIndexBuilder.DEFAULT_INDEX_IDENTIFIER );

File[] partitionDirs = rootDir.listFiles( File::isDirectory );
return (partitionDirs == null) ? Collections.emptyList() : Stream.of( partitionDirs ).collect( toList() );
}

@Override
protected void corruptLabelScanStoreFiles( File storeDirectory ) throws IOException
{
List<File> partitionDirs = labelScanStoreIndexDirectories( storeDirectory );
for ( File partitionDir : partitionDirs )
{
for ( File file : partitionDir.listFiles() )
{
scrambleFile( file );
}
}
}

@Override
protected void deleteLabelScanStoreFiles( File storeDirectory ) throws IOException
{
DependencyResolver dependencyResolver = dbRule.getDependencyResolver();
LabelScanStore labelScanStore = dependencyResolver.resolveDependency( LabelScanStore.class );
assertThat( labelScanStore, instanceOf( LuceneLabelScanStore.class ) );
return labelScanStore;
List<File> partitionDirs = labelScanStoreIndexDirectories( storeDirectory );
for ( File dir : partitionDirs )
{
assertTrue( "We seem to want to delete the wrong directory here", dir.exists() );
assertTrue( "No index files to delete", dir.listFiles().length > 0 );
deleteRecursively( dir );
}
}
}

0 comments on commit f5caecd

Please sign in to comment.