diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/store/format/Capability.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/store/format/Capability.java index 4af806f61b918..0cad47a4a2cde 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/store/format/Capability.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/store/format/Capability.java @@ -37,6 +37,11 @@ public enum Capability */ DENSE_NODES( CapabilityType.FORMAT, CapabilityType.STORE ), + /** + * Store has fixed reference encoding support support + */ + FIXED_REFERENCE( CapabilityType.FORMAT ), + /** * Store has version trailers in the end of cleanly shut down store */ diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/store/format/StoreVersion.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/store/format/StoreVersion.java index d95674fe9f6d4..bb60c2066fbd4 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/store/format/StoreVersion.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/store/format/StoreVersion.java @@ -32,7 +32,8 @@ public enum StoreVersion STANDARD_V2_3( "v0.A.6", true ), STANDARD_V3_0( "v0.A.7", true ), - HIGH_LIMIT_V3_0( "vE.H.0", false ); + HIGH_LIMIT_V3_0( "vE.H.0", false ), + HIGH_LIMIT_V3_1( "vE.H.1", false ); private static final StoreVersion[] ALL_STORE_VERSIONS = values(); diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/storemigration/participant/StoreMigrator.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/storemigration/participant/StoreMigrator.java index 6b33e91994e7b..6318c3b3b5ab5 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/storemigration/participant/StoreMigrator.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/storemigration/participant/StoreMigrator.java @@ -55,6 +55,7 @@ import org.neo4j.kernel.impl.store.StoreType; import org.neo4j.kernel.impl.store.TransactionId; import org.neo4j.kernel.impl.store.counts.CountsTracker; +import org.neo4j.kernel.impl.store.format.CapabilityType; import org.neo4j.kernel.impl.store.format.RecordFormats; import org.neo4j.kernel.impl.store.format.standard.MetaDataRecordFormat; import org.neo4j.kernel.impl.store.format.standard.NodeRecordFormat; @@ -169,7 +170,7 @@ public void migrate( File storeDir, File migrationDir, MigrationProgressMonitor. RecordFormats oldFormat = selectForVersion( versionToMigrateFrom ); RecordFormats newFormat = selectForVersion( versionToMigrateTo ); - if ( !oldFormat.equals( newFormat ) ) + if ( !oldFormat.hasSameCapabilities( newFormat, CapabilityType.FORMAT ) ) { // TODO if this store has relationship indexes then warn user about that they will be incorrect // after migration, because now we're rewriting the relationship ids. diff --git a/community/neo4j/src/test/java/synchronization/ConcurrentChangesOnEntitiesTest.java b/community/neo4j/src/test/java/synchronization/ConcurrentChangesOnEntitiesTest.java index 26be44a8e409c..c5bcb6a078ced 100644 --- a/community/neo4j/src/test/java/synchronization/ConcurrentChangesOnEntitiesTest.java +++ b/community/neo4j/src/test/java/synchronization/ConcurrentChangesOnEntitiesTest.java @@ -22,6 +22,7 @@ import org.junit.Before; import org.junit.Rule; import org.junit.Test; +import org.junit.rules.RuleChain; import java.io.IOException; import java.util.concurrent.CyclicBarrier; @@ -41,6 +42,7 @@ import org.neo4j.kernel.configuration.Config; import org.neo4j.logging.FormattedLogProvider; import org.neo4j.logging.LogProvider; +import org.neo4j.test.rule.SuppressOutput; import org.neo4j.test.rule.TestDirectory; import static org.junit.Assert.assertTrue; @@ -48,8 +50,13 @@ public class ConcurrentChangesOnEntitiesTest { + + private SuppressOutput suppressOutput = SuppressOutput.suppressAll(); + private TestDirectory testDirectory = TestDirectory.testDirectory(); + @Rule - public TestDirectory testDirectory = TestDirectory.testDirectory(); + public RuleChain ruleChain = RuleChain.outerRule( suppressOutput ).around( testDirectory ); + private final CyclicBarrier barrier = new CyclicBarrier( 2 ); private final AtomicReference ex = new AtomicReference<>(); private GraphDatabaseService db; diff --git a/community/neo4j/src/test/java/upgrade/StoreUpgraderTest.java b/community/neo4j/src/test/java/upgrade/StoreUpgraderTest.java index 4bb9da16becd5..838208d42ad2d 100644 --- a/community/neo4j/src/test/java/upgrade/StoreUpgraderTest.java +++ b/community/neo4j/src/test/java/upgrade/StoreUpgraderTest.java @@ -32,6 +32,9 @@ import java.util.Arrays; import java.util.Collection; import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; +import java.util.stream.Stream; import org.neo4j.consistency.checking.full.ConsistencyCheckIncompleteException; import org.neo4j.graphdb.GraphDatabaseService; @@ -85,6 +88,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.mockito.Matchers.any; import static org.mockito.Matchers.eq; import static org.mockito.Mockito.verify; @@ -139,7 +143,7 @@ public void prepareDb() throws IOException { dbDirectory = directory.directory( "db_" + version ); File prepareDirectory = directory.directory( "prepare_" + version ); - prepareSampleLegacyDatabase( version, fileSystem, dbDirectory, prepareDirectory ); + prepareSampleDatabase( version, fileSystem, dbDirectory, prepareDirectory ); } @Test @@ -150,7 +154,11 @@ public void shouldUpgradeAnOldFormatStore() throws IOException, ConsistencyCheck UpgradableDatabase upgradableDatabase = new UpgradableDatabase( fileSystem, new StoreVersionCheck( pageCache ), new LegacyStoreVersionCheck( fileSystem ), getRecordFormats() ); - assertEquals( !StandardV2_3.STORE_VERSION.equals( version ), + Set versionSet = versionSet( StandardV2_0.STORE_VERSION, + StandardV2_1.STORE_VERSION, + StandardV2_2.STORE_VERSION ); + + assertEquals( versionSet.contains( version ), allLegacyStoreFilesHaveVersion( fileSystem, dbDirectory, version ) ); // When @@ -194,7 +202,9 @@ public void shouldHaltUpgradeIfUpgradeConfigurationVetoesTheProcess() public void shouldLeaveAllFilesUntouchedIfWrongVersionNumberFound() throws IOException { - Assume.assumeFalse( StandardV2_3.STORE_VERSION.equals( version ) ); + Set applicableVersions = + versionSet( StandardV2_0.STORE_VERSION, StandardV2_1.STORE_VERSION, StandardV2_2.STORE_VERSION ); + assumeTrue( "Applicable only to specified version set.", applicableVersions.contains( version ) ); File comparisonDirectory = new File( "target/" + StoreUpgraderTest.class.getSimpleName() + "shouldLeaveAllFilesUntouchedIfWrongVersionNumberFound-comparison" ); @@ -221,11 +231,11 @@ public void shouldLeaveAllFilesUntouchedIfWrongVersionNumberFound() } @Test - public void shouldRefuseToUpgradeIfAnyOfTheStoresWeNotShutDownCleanly() + public void shouldRefuseToUpgradeIfAnyOfTheStoresWereNotShutDownCleanly() throws IOException { - File comparisonDirectory = new File( "target/" + StoreUpgraderTest.class.getSimpleName() - + "shouldRefuseToUpgradeIfAnyOfTheStoresWeNotShutDownCleanly-comparison" ); + File comparisonDirectory = new File( "target/" + StoreUpgraderTest.class.getSimpleName() + + "shouldRefuseToUpgradeIfAnyOfTheStoresWereNotShutDownCleanly-comparison" ); makeDbNotCleanlyShutdown( false ); fileSystem.deleteRecursively( comparisonDirectory ); fileSystem.copyRecursively( dbDirectory, comparisonDirectory ); @@ -251,8 +261,8 @@ public void shouldRefuseToUpgradeIfAnyOfTheStoresWeNotShutDownCleanly() public void shouldRefuseToUpgradeIfAllOfTheStoresWereNotShutDownCleanly() throws IOException { - File comparisonDirectory = new File( "target/" + StoreUpgraderTest.class.getSimpleName() - + "shouldRefuseToUpgradeIfAllOfTheStoresWeNotShutDownCleanly-comparison" ); + File comparisonDirectory = new File( "target/" + StoreUpgraderTest.class.getSimpleName() + + "shouldRefuseToUpgradeIfAllOfTheStoresWereNotShutDownCleanly-comparison" ); makeDbNotCleanlyShutdown( true ); fileSystem.deleteRecursively( comparisonDirectory ); fileSystem.copyRecursively( dbDirectory, comparisonDirectory ); @@ -390,6 +400,12 @@ public void upgraderShouldCleanupLegacyLeftoverAndMigrationDirs() throws Excepti assertThat( migrationHelperDirs(), is( emptyCollectionOf( File.class ) ) ); } + protected void prepareSampleDatabase( String version, FileSystemAbstraction fileSystem, File dbDirectory, + File databaseDirectory ) throws IOException + { + prepareSampleLegacyDatabase( version, fileSystem, dbDirectory, databaseDirectory ); + } + private static void assertCorrectStoreVersion( String expectedStoreVersion, StoreVersionCheck check, File storeDir ) { File neoStoreFile = new File( storeDir, MetaDataStore.DEFAULT_NAME ); @@ -449,11 +465,9 @@ private List migrationHelperDirs() private void makeDbNotCleanlyShutdown( boolean truncateAll ) throws IOException { - if ( StandardV2_3.STORE_VERSION.equals( version ) ) - { - removeCheckPointFromTxLog( fileSystem, dbDirectory ); - } - else + Set truncateVersions = versionSet( StandardV2_0.STORE_VERSION, StandardV2_1.STORE_VERSION, + StandardV2_2.STORE_VERSION ); + if (truncateVersions.contains( version )) { if ( truncateAll ) { @@ -466,6 +480,10 @@ private void makeDbNotCleanlyShutdown( boolean truncateAll ) throws IOException truncateFile( fileSystem, storeFile, "StringPropertyStore " + version ); } } + else + { + removeCheckPointFromTxLog( fileSystem, dbDirectory ); + } } private Config getTuningConfig() @@ -483,6 +501,11 @@ protected String getRecordFormatsName() return StandardV3_0.NAME; } + private Set versionSet(String... versions) + { + return Stream.of( versions ).collect( Collectors.toSet() ); + } + private void startStopDatabase() { GraphDatabaseService databaseService = new TestGraphDatabaseFactory().newEmbeddedDatabase( dbDirectory ); diff --git a/enterprise/kernel/src/main/java/org/neo4j/kernel/impl/store/format/highlimit/HighLimit.java b/enterprise/kernel/src/main/java/org/neo4j/kernel/impl/store/format/highlimit/HighLimit.java index b2c48157c5256..ea56046074472 100644 --- a/enterprise/kernel/src/main/java/org/neo4j/kernel/impl/store/format/highlimit/HighLimit.java +++ b/enterprise/kernel/src/main/java/org/neo4j/kernel/impl/store/format/highlimit/HighLimit.java @@ -24,6 +24,7 @@ import org.neo4j.kernel.impl.store.format.RecordFormat; import org.neo4j.kernel.impl.store.format.RecordFormats; import org.neo4j.kernel.impl.store.format.StoreVersion; +import org.neo4j.kernel.impl.store.format.highlimit.v30.HighLimitV3_0; import org.neo4j.kernel.impl.store.format.standard.LabelTokenRecordFormat; import org.neo4j.kernel.impl.store.format.standard.PropertyKeyTokenRecordFormat; import org.neo4j.kernel.impl.store.format.standard.RelationshipTypeTokenRecordFormat; @@ -48,13 +49,14 @@ public class HighLimit extends BaseRecordFormats */ static final int DEFAULT_MAXIMUM_BITS_PER_ID = 50; - public static final String STORE_VERSION = StoreVersion.HIGH_LIMIT_V3_0.versionString(); + public static final String STORE_VERSION = StoreVersion.HIGH_LIMIT_V3_1.versionString(); public static final RecordFormats RECORD_FORMATS = new HighLimit(); public static final String NAME = "high_limit"; public HighLimit() { - super( STORE_VERSION, 8, Capability.DENSE_NODES, Capability.SCHEMA, Capability.LUCENE_5 ); + super( STORE_VERSION, 8, Capability.DENSE_NODES, Capability.SCHEMA, Capability.LUCENE_5, + Capability.FIXED_REFERENCE ); } @Override diff --git a/enterprise/kernel/src/main/java/org/neo4j/kernel/impl/store/format/highlimit/v30/HighLimitV3_0.java b/enterprise/kernel/src/main/java/org/neo4j/kernel/impl/store/format/highlimit/v30/HighLimitV3_0.java index b943763b4c1d8..c24139a74dcff 100644 --- a/enterprise/kernel/src/main/java/org/neo4j/kernel/impl/store/format/highlimit/v30/HighLimitV3_0.java +++ b/enterprise/kernel/src/main/java/org/neo4j/kernel/impl/store/format/highlimit/v30/HighLimitV3_0.java @@ -55,7 +55,8 @@ public class HighLimitV3_0 extends BaseRecordFormats public HighLimitV3_0() { - super( STORE_VERSION, 7, Capability.DENSE_NODES, Capability.SCHEMA, Capability.LUCENE_5 ); + super( STORE_VERSION, 7, Capability.DENSE_NODES, Capability.SCHEMA, Capability.LUCENE_5, + Capability.FIXED_REFERENCE ); } @Override diff --git a/enterprise/kernel/src/main/java/org/neo4j/kernel/impl/store/format/highlimit/v30/HighLimitV3_0Factory.java b/enterprise/kernel/src/main/java/org/neo4j/kernel/impl/store/format/highlimit/v30/HighLimitV3_0Factory.java new file mode 100644 index 0000000000000..cbcfaee756bfb --- /dev/null +++ b/enterprise/kernel/src/main/java/org/neo4j/kernel/impl/store/format/highlimit/v30/HighLimitV3_0Factory.java @@ -0,0 +1,38 @@ +/* + * 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 Affero 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ +package org.neo4j.kernel.impl.store.format.highlimit.v30; + +import org.neo4j.helpers.Service; +import org.neo4j.kernel.impl.store.format.RecordFormats; + +@Service.Implementation( RecordFormats.Factory.class ) +public class HighLimitV3_0Factory extends RecordFormats.Factory +{ + public HighLimitV3_0Factory() + { + super( HighLimitV3_0.NAME ); + } + + @Override + public RecordFormats newInstance() + { + return HighLimitV3_0.RECORD_FORMATS; + } +} diff --git a/enterprise/kernel/src/main/resources/META-INF/services/org.neo4j.kernel.impl.store.format.RecordFormats$Factory b/enterprise/kernel/src/main/resources/META-INF/services/org.neo4j.kernel.impl.store.format.RecordFormats$Factory index 34e1474a78ff6..55c936755dd29 100644 --- a/enterprise/kernel/src/main/resources/META-INF/services/org.neo4j.kernel.impl.store.format.RecordFormats$Factory +++ b/enterprise/kernel/src/main/resources/META-INF/services/org.neo4j.kernel.impl.store.format.RecordFormats$Factory @@ -1 +1,2 @@ -org.neo4j.kernel.impl.store.format.highlimit.HighLimitFactory \ No newline at end of file +org.neo4j.kernel.impl.store.format.highlimit.HighLimitFactory +org.neo4j.kernel.impl.store.format.highlimit.v30.HighLimitV3_0Factory diff --git a/enterprise/kernel/src/test/java/org/neo4j/kernel/impl/store/format/RecordFormatSelectorTest.java b/enterprise/kernel/src/test/java/org/neo4j/kernel/impl/store/format/RecordFormatSelectorTest.java index 2b7d93da418e7..c170a9b697843 100644 --- a/enterprise/kernel/src/test/java/org/neo4j/kernel/impl/store/format/RecordFormatSelectorTest.java +++ b/enterprise/kernel/src/test/java/org/neo4j/kernel/impl/store/format/RecordFormatSelectorTest.java @@ -32,6 +32,7 @@ import org.neo4j.kernel.configuration.Config; import org.neo4j.kernel.impl.store.MetaDataStore; import org.neo4j.kernel.impl.store.format.highlimit.HighLimit; +import org.neo4j.kernel.impl.store.format.highlimit.v30.HighLimitV3_0; import org.neo4j.kernel.impl.store.format.standard.StandardV2_0; import org.neo4j.kernel.impl.store.format.standard.StandardV2_1; import org.neo4j.kernel.impl.store.format.standard.StandardV2_2; @@ -83,6 +84,7 @@ public void selectForVersionTest() assertSame( StandardV2_2.RECORD_FORMATS, selectForVersion( StandardV2_2.STORE_VERSION ) ); assertSame( StandardV2_3.RECORD_FORMATS, selectForVersion( StandardV2_3.STORE_VERSION ) ); assertSame( StandardV3_0.RECORD_FORMATS, selectForVersion( StandardV3_0.STORE_VERSION ) ); + assertSame( HighLimitV3_0.RECORD_FORMATS, selectForVersion( HighLimitV3_0.STORE_VERSION ) ); assertSame( HighLimit.RECORD_FORMATS, selectForVersion( HighLimit.STORE_VERSION ) ); } @@ -136,6 +138,7 @@ public void selectForStoreWithValidStore() throws IOException verifySelectForStore( pageCache, StandardV2_2.RECORD_FORMATS ); verifySelectForStore( pageCache, StandardV2_3.RECORD_FORMATS ); verifySelectForStore( pageCache, StandardV3_0.RECORD_FORMATS ); + verifySelectForStore( pageCache, HighLimitV3_0.RECORD_FORMATS ); verifySelectForStore( pageCache, HighLimit.RECORD_FORMATS ); } diff --git a/enterprise/kernel/src/test/java/org/neo4j/kernel/impl/store/format/highlimit/HighLimitStoreMigrationTest.java b/enterprise/kernel/src/test/java/org/neo4j/kernel/impl/store/format/highlimit/HighLimitStoreMigrationTest.java new file mode 100644 index 0000000000000..332adc68a1174 --- /dev/null +++ b/enterprise/kernel/src/test/java/org/neo4j/kernel/impl/store/format/highlimit/HighLimitStoreMigrationTest.java @@ -0,0 +1,101 @@ +/* + * 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 Affero 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ +package org.neo4j.kernel.impl.store.format.highlimit; + +import org.hamcrest.CoreMatchers; +import org.junit.Rule; +import org.junit.Test; + +import java.io.File; +import java.io.IOException; +import java.util.Set; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import org.neo4j.graphdb.mockfs.EphemeralFileSystemAbstraction; +import org.neo4j.io.fs.FileSystemAbstraction; +import org.neo4j.io.pagecache.PageCache; +import org.neo4j.kernel.api.index.SchemaIndexProvider; +import org.neo4j.kernel.configuration.Config; +import org.neo4j.kernel.impl.logging.NullLogService; +import org.neo4j.kernel.impl.store.MetaDataStore; +import org.neo4j.kernel.impl.store.format.CapabilityType; +import org.neo4j.kernel.impl.store.format.highlimit.v30.HighLimitV3_0; +import org.neo4j.kernel.impl.storemigration.monitoring.MigrationProgressMonitor; +import org.neo4j.kernel.impl.storemigration.participant.StoreMigrator; +import org.neo4j.test.rule.PageCacheRule; + +import static org.junit.Assert.assertThat; +import static org.mockito.Mockito.mock; +import static org.neo4j.kernel.impl.store.MetaDataStore.Position.STORE_VERSION; + +public class HighLimitStoreMigrationTest +{ + @Rule + public final PageCacheRule pageCacheRule = new PageCacheRule(); + private final FileSystemAbstraction fileSystem = new EphemeralFileSystemAbstraction(); + + @Test + public void haveSameFormatCapabilitiesAsHighLimit3_0() + { + HighLimit.RECORD_FORMATS.hasSameCapabilities( HighLimitV3_0.RECORD_FORMATS, CapabilityType.FORMAT ); + } + + @Test + public void doNotMigrateHighLimit3_0StoreFiles() throws IOException + { + PageCache pageCache = pageCacheRule.getPageCache( fileSystem ); + SchemaIndexProvider schemaIndexProvider = mock( SchemaIndexProvider.class ); + StoreMigrator migrator = new StoreMigrator( fileSystem, pageCache, Config.empty(), NullLogService.getInstance(), + schemaIndexProvider ); + + File storeDir = new File( "storeDir" ); + File migrationDir = new File( "migrationDir" ); + fileSystem.mkdir( migrationDir ); + + prepareNeoStoreFile( storeDir, HighLimitV3_0.STORE_VERSION, pageCache ); + + MigrationProgressMonitor.Section progressMonitor = mock( MigrationProgressMonitor.Section.class ); + migrator.migrate( storeDir, migrationDir, progressMonitor, HighLimitV3_0.STORE_VERSION, HighLimit.STORE_VERSION ); + + File[] migrationFiles = fileSystem.listFiles( migrationDir ); + Set fileNames = Stream.of( migrationFiles ).map( File::getName ).collect( Collectors.toSet() ); + assertThat( "Only specified files should be created after migration attempt from 3.0 to 3.1 using high limit " + + "format. Since formats are compatible and migration is not required.", fileNames, + CoreMatchers.hasItems( "lastxinformation", "lastxlogposition" ) ); + } + + private File prepareNeoStoreFile( File storeDir, String storeVersion, PageCache pageCache ) throws IOException + { + File neoStoreFile = createNeoStoreFile( storeDir ); + long value = MetaDataStore.versionStringToLong( storeVersion ); + MetaDataStore.setRecord( pageCache, neoStoreFile, STORE_VERSION, value ); + return neoStoreFile; + } + + private File createNeoStoreFile( File storeDir ) throws IOException + { + fileSystem.mkdir( storeDir ); + File neoStoreFile = new File( storeDir, MetaDataStore.DEFAULT_NAME ); + fileSystem.create( neoStoreFile ).close(); + return neoStoreFile; + } + +} diff --git a/enterprise/kernel/src/test/java/org/neo4j/kernel/impl/store/format/highlimit/v30/HighLimitV3_0RecordFormatTest.java b/enterprise/kernel/src/test/java/org/neo4j/kernel/impl/store/format/highlimit/v30/HighLimitV3_0RecordFormatTest.java new file mode 100644 index 0000000000000..af783c528c66d --- /dev/null +++ b/enterprise/kernel/src/test/java/org/neo4j/kernel/impl/store/format/highlimit/v30/HighLimitV3_0RecordFormatTest.java @@ -0,0 +1,30 @@ +/* + * 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 Affero 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ +package org.neo4j.kernel.impl.store.format.highlimit.v30; + +import org.neo4j.kernel.impl.store.format.RecordFormatTest; + +public class HighLimitV3_0RecordFormatTest extends RecordFormatTest +{ + public HighLimitV3_0RecordFormatTest() + { + super( HighLimitV3_0.RECORD_FORMATS, 50, 50 ); + } +} diff --git a/enterprise/neo4j-enterprise/src/test/java/org/neo4j/RecordFormatsGenerationTest.java b/enterprise/neo4j-enterprise/src/test/java/org/neo4j/RecordFormatsGenerationTest.java index 3cdd270dabb08..f335e3ac71e2e 100644 --- a/enterprise/neo4j-enterprise/src/test/java/org/neo4j/RecordFormatsGenerationTest.java +++ b/enterprise/neo4j-enterprise/src/test/java/org/neo4j/RecordFormatsGenerationTest.java @@ -28,6 +28,7 @@ import org.neo4j.kernel.impl.store.format.RecordFormats; import org.neo4j.kernel.impl.store.format.StoreVersion; import org.neo4j.kernel.impl.store.format.highlimit.HighLimit; +import org.neo4j.kernel.impl.store.format.highlimit.v30.HighLimitV3_0; import org.neo4j.kernel.impl.store.format.standard.StandardV2_0; import org.neo4j.kernel.impl.store.format.standard.StandardV2_1; import org.neo4j.kernel.impl.store.format.standard.StandardV2_2; @@ -48,6 +49,7 @@ public void correctGenerations() StandardV2_2.RECORD_FORMATS.generation(), StandardV2_3.RECORD_FORMATS.generation(), StandardV3_0.RECORD_FORMATS.generation(), + HighLimitV3_0.RECORD_FORMATS.generation(), HighLimit.RECORD_FORMATS.generation() ); diff --git a/enterprise/neo4j-enterprise/src/test/java/org/neo4j/upgrade/EnterpriseStoreUpgraderTest.java b/enterprise/neo4j-enterprise/src/test/java/org/neo4j/upgrade/EnterpriseStoreUpgraderTest.java new file mode 100644 index 0000000000000..5874ae8a9de8b --- /dev/null +++ b/enterprise/neo4j-enterprise/src/test/java/org/neo4j/upgrade/EnterpriseStoreUpgraderTest.java @@ -0,0 +1,88 @@ +/* + * 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 Affero 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ +package org.neo4j.upgrade; + +import org.junit.runners.Parameterized; +import upgrade.StoreUpgraderTest; + +import java.io.File; +import java.io.IOException; +import java.util.Collection; + +import org.neo4j.io.fs.FileSystemAbstraction; +import org.neo4j.kernel.impl.store.format.RecordFormats; +import org.neo4j.kernel.impl.store.format.highlimit.HighLimit; +import org.neo4j.kernel.impl.store.format.highlimit.v30.HighLimitV3_0; +import org.neo4j.test.Unzip; + +import static java.util.Collections.singletonList; + +public class EnterpriseStoreUpgraderTest extends StoreUpgraderTest +{ + public EnterpriseStoreUpgraderTest( String version ) + { + super( version ); + } + + @Parameterized.Parameters( name = "{0}" ) + public static Collection versions() + { + return singletonList( HighLimitV3_0.STORE_VERSION ); + } + + @Override + protected RecordFormats getRecordFormats() + { + return HighLimit.RECORD_FORMATS; + } + + @Override + protected String getRecordFormatsName() + { + return HighLimit.NAME; + } + + @Override + protected void prepareSampleDatabase( String version, FileSystemAbstraction fileSystem, File dbDirectory, + File databaseDirectory ) throws IOException + { + File resourceDirectory = findFormatStoreDirectoryForVersion( version, databaseDirectory ); + fileSystem.deleteRecursively( dbDirectory ); + fileSystem.mkdirs( dbDirectory ); + fileSystem.copyRecursively( resourceDirectory, dbDirectory ); + } + + private File findFormatStoreDirectoryForVersion( String version, File databaseDirectory ) throws IOException + { + if ( version.equals( HighLimitV3_0.STORE_VERSION ) ) + { + return highLimit3_0Store( databaseDirectory ); + } + else + { + throw new IllegalArgumentException( "Unknown enterprise store version." ); + } + } + + private File highLimit3_0Store( File databaseDirectory ) throws IOException + { + return Unzip.unzip( EnterpriseStoreUpgraderTest.class, "upgradeTest30HighLimitDb.zip", databaseDirectory ); + } +} diff --git a/enterprise/neo4j-enterprise/src/test/java/upgrade/RecordFormatsMigrationIT.java b/enterprise/neo4j-enterprise/src/test/java/org/neo4j/upgrade/RecordFormatsMigrationIT.java similarity index 86% rename from enterprise/neo4j-enterprise/src/test/java/upgrade/RecordFormatsMigrationIT.java rename to enterprise/neo4j-enterprise/src/test/java/org/neo4j/upgrade/RecordFormatsMigrationIT.java index d99a27baa9d5c..8c7a74ad5156f 100644 --- a/enterprise/neo4j-enterprise/src/test/java/upgrade/RecordFormatsMigrationIT.java +++ b/enterprise/neo4j-enterprise/src/test/java/org/neo4j/upgrade/RecordFormatsMigrationIT.java @@ -17,7 +17,7 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ -package upgrade; +package org.neo4j.upgrade; import org.junit.Rule; import org.junit.Test; @@ -41,6 +41,7 @@ import org.neo4j.kernel.impl.store.format.RecordFormatSelector; import org.neo4j.kernel.impl.store.format.RecordFormats; import org.neo4j.kernel.impl.store.format.highlimit.HighLimit; +import org.neo4j.kernel.impl.store.format.highlimit.v30.HighLimitV3_0; import org.neo4j.kernel.impl.store.format.standard.StandardV3_0; import org.neo4j.kernel.impl.storemigration.StoreUpgrader.UnexpectedUpgradingStoreFormatException; import org.neo4j.logging.NullLogProvider; @@ -65,20 +66,30 @@ public class RecordFormatsMigrationIT public final TestDirectory testDir = TestDirectory.testDirectory( fs ); @Test - public void migrateStandardToHighLimit() throws IOException + public void migrateLatestStandardToLatestHighLimit() throws IOException { executeAndStopDb( startStandardFormatDb(), this::createNode ); - assertStandardStore(); + assertLatestStandardStore(); executeAndStopDb( startHighLimitFormatDb(), this::assertNodeExists ); - assertHighLimitStore(); + assertLatestHighLimitStore(); + } + + @Test + public void migrateHighLimitV3_0ToLatestHighLimit() throws IOException + { + executeAndStopDb( startDb( HighLimitV3_0.NAME ), this::createNode ); + assertStoreFormat( HighLimitV3_0.RECORD_FORMATS ); + + executeAndStopDb( startHighLimitFormatDb(), this::assertNodeExists ); + assertLatestHighLimitStore(); } @Test public void migrateHighLimitToStandard() throws IOException { executeAndStopDb( startHighLimitFormatDb(), this::createNode ); - assertHighLimitStore(); + assertLatestHighLimitStore(); try { @@ -89,7 +100,7 @@ public void migrateHighLimitToStandard() throws IOException { assertThat( Exceptions.rootCause( e ), instanceOf( UnexpectedUpgradingStoreFormatException.class ) ); } - assertHighLimitStore(); + assertLatestHighLimitStore(); } private void createNode( GraphDatabaseService db ) @@ -129,12 +140,12 @@ private GraphDatabaseService startDb( String recordFormatName ) .newGraphDatabase(); } - private void assertStandardStore() throws IOException + private void assertLatestStandardStore() throws IOException { assertStoreFormat( StandardV3_0.RECORD_FORMATS ); } - private void assertHighLimitStore() throws IOException + private void assertLatestHighLimitStore() throws IOException { assertStoreFormat( HighLimit.RECORD_FORMATS ); } diff --git a/enterprise/neo4j-enterprise/src/test/java/upgrade/EnterpriseStoreUpgraderTest.java b/enterprise/neo4j-enterprise/src/test/java/org/neo4j/upgrade/StandardToEnterpriseStoreUpgraderTest.java similarity index 86% rename from enterprise/neo4j-enterprise/src/test/java/upgrade/EnterpriseStoreUpgraderTest.java rename to enterprise/neo4j-enterprise/src/test/java/org/neo4j/upgrade/StandardToEnterpriseStoreUpgraderTest.java index ba7f1e7e38f88..b957aef9ab6d7 100644 --- a/enterprise/neo4j-enterprise/src/test/java/upgrade/EnterpriseStoreUpgraderTest.java +++ b/enterprise/neo4j-enterprise/src/test/java/org/neo4j/upgrade/StandardToEnterpriseStoreUpgraderTest.java @@ -17,7 +17,9 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ -package upgrade; +package org.neo4j.upgrade; + +import upgrade.StoreUpgraderTest; import org.neo4j.kernel.impl.store.format.RecordFormats; import org.neo4j.kernel.impl.store.format.highlimit.HighLimit; @@ -25,9 +27,9 @@ /** * Runs the store upgrader tests from older versions, migrating to the current enterprise version. */ -public class EnterpriseStoreUpgraderTest extends StoreUpgraderTest +public class StandardToEnterpriseStoreUpgraderTest extends StoreUpgraderTest { - public EnterpriseStoreUpgraderTest( String version ) + public StandardToEnterpriseStoreUpgraderTest( String version ) { super( version ); } diff --git a/enterprise/neo4j-enterprise/src/test/java/upgrade/StoreMigratorFrom20IT.java b/enterprise/neo4j-enterprise/src/test/java/org/neo4j/upgrade/StoreMigratorFrom20IT.java similarity index 98% rename from enterprise/neo4j-enterprise/src/test/java/upgrade/StoreMigratorFrom20IT.java rename to enterprise/neo4j-enterprise/src/test/java/org/neo4j/upgrade/StoreMigratorFrom20IT.java index 8e15617d3ee41..3f1ecf07febe4 100644 --- a/enterprise/neo4j-enterprise/src/test/java/upgrade/StoreMigratorFrom20IT.java +++ b/enterprise/neo4j-enterprise/src/test/java/org/neo4j/upgrade/StoreMigratorFrom20IT.java @@ -17,7 +17,7 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ -package upgrade; +package org.neo4j.upgrade; import org.junit.After; import org.junit.Before; @@ -27,6 +27,8 @@ import org.junit.runners.Parameterized; import org.junit.runners.Parameterized.Parameter; import org.junit.runners.Parameterized.Parameters; +import upgrade.DatabaseContentVerifier; +import upgrade.ListAccumulatorMigrationProgressMonitor; import java.io.File; import java.io.IOException; @@ -76,7 +78,7 @@ import static org.neo4j.helpers.collection.MapUtil.stringMap; import static org.neo4j.kernel.impl.ha.ClusterManager.allSeesAllAsAvailable; import static org.neo4j.kernel.impl.storemigration.MigrationTestUtils.find20FormatStoreDirectory; -import static upgrade.StoreMigratorTestUtil.buildClusterWithMasterDirIn; +import static org.neo4j.upgrade.StoreMigratorTestUtil.buildClusterWithMasterDirIn; @RunWith( Parameterized.class ) public class StoreMigratorFrom20IT diff --git a/enterprise/neo4j-enterprise/src/test/java/upgrade/StoreMigratorFrom21IT.java b/enterprise/neo4j-enterprise/src/test/java/org/neo4j/upgrade/StoreMigratorFrom21IT.java similarity index 99% rename from enterprise/neo4j-enterprise/src/test/java/upgrade/StoreMigratorFrom21IT.java rename to enterprise/neo4j-enterprise/src/test/java/org/neo4j/upgrade/StoreMigratorFrom21IT.java index 6e5f90b092e2e..df092ef1f1a96 100644 --- a/enterprise/neo4j-enterprise/src/test/java/upgrade/StoreMigratorFrom21IT.java +++ b/enterprise/neo4j-enterprise/src/test/java/org/neo4j/upgrade/StoreMigratorFrom21IT.java @@ -17,7 +17,7 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ -package upgrade; +package org.neo4j.upgrade; import org.junit.Rule; import org.junit.Test; diff --git a/enterprise/neo4j-enterprise/src/test/java/upgrade/StoreMigratorTestUtil.java b/enterprise/neo4j-enterprise/src/test/java/org/neo4j/upgrade/StoreMigratorTestUtil.java similarity index 79% rename from enterprise/neo4j-enterprise/src/test/java/upgrade/StoreMigratorTestUtil.java rename to enterprise/neo4j-enterprise/src/test/java/org/neo4j/upgrade/StoreMigratorTestUtil.java index 2e915b399701c..7a52298b3c1d5 100644 --- a/enterprise/neo4j-enterprise/src/test/java/upgrade/StoreMigratorTestUtil.java +++ b/enterprise/neo4j-enterprise/src/test/java/org/neo4j/upgrade/StoreMigratorTestUtil.java @@ -17,7 +17,7 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ -package upgrade; +package org.neo4j.upgrade; import java.io.File; import java.io.IOException; @@ -34,7 +34,7 @@ public class StoreMigratorTestUtil { StoreMigratorTestUtil() { - // no istance allowed + // no instance allowed } public static ClusterManager.ManagedCluster buildClusterWithMasterDirIn( FileSystemAbstraction fs, @@ -45,15 +45,11 @@ public static ClusterManager.ManagedCluster buildClusterWithMasterDirIn( FileSys fs.deleteRecursively( haRootDir ); ClusterManager clusterManager = new ClusterManager.Builder( haRootDir ) - .withStoreDirInitializer( new ClusterManager.StoreDirInitializer() + .withStoreDirInitializer( ( serverId, storeDir ) -> { - @Override - public void initializeStoreDir( int serverId, File storeDir ) throws IOException + if ( serverId == 1 ) // Initialize dir only for master, others will copy store from it { - if ( serverId == 1 ) // Initialize dir only for master, others will copy store from it - { - FileUtils.copyRecursively( legacyStoreDir, storeDir ); - } + FileUtils.copyRecursively( legacyStoreDir, storeDir ); } } ) .withCluster( clusterOfSize( 3 ) ) diff --git a/enterprise/neo4j-enterprise/src/test/resources/org/neo4j/upgrade/upgradeTest30HighLimitDb.zip b/enterprise/neo4j-enterprise/src/test/resources/org/neo4j/upgrade/upgradeTest30HighLimitDb.zip new file mode 100644 index 0000000000000..154f10c3d05c7 Binary files /dev/null and b/enterprise/neo4j-enterprise/src/test/resources/org/neo4j/upgrade/upgradeTest30HighLimitDb.zip differ