/** * Copyright (c) 2002-2012 "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 <http://www.gnu.org/licenses/>. */ package slavetest; import java.io.File; import java.io.FileFilter; import org.apache.commons.io.FileUtils; import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.Ignore; import org.junit.Test; import org.neo4j.graphdb.Node; import org.neo4j.graphdb.Transaction; import org.neo4j.graphdb.factory.HighlyAvailableGraphDatabaseFactory; import org.neo4j.kernel.ha.HaSettings; import org.neo4j.kernel.ha.HighlyAvailableGraphDatabase; import org.neo4j.kernel.ha.SlaveStoreWriter; import org.neo4j.kernel.impl.util.StringLogger; import org.neo4j.test.TargetDirectory; /** * Check sandboxed copy of stores. The before and after methods * as they are form a complete test, so a test method with an empty * body would still perform a valid test. */ @Ignore public class TestStoreCopy { private static final FileFilter DISREGARD_ACTIVE_LOG_FILES = new FileFilter() { @Override public boolean accept( File file ) { // Skip log files and tx files from temporary database return !("active_tx_log tm_tx_log.1 tm_tx_log.2").contains( file.getName() ); } }; private HighlyAvailableGraphDatabase master; private HighlyAvailableGraphDatabase slave; private File slaveDir; private File sandboxed; private long nodeId; /** * Starts a master, creates a node and sets a property, starts the slave and * checks successful copy of the store. * * @throws Exception */ @Before public void setupMachinesAndSanityCheck() throws Exception { slaveDir = TargetDirectory.forTest( TestStoreCopy.class ).directory( "slave-sandboxed", true ); sandboxed = new File( slaveDir, SlaveStoreWriter.COPY_FROM_MASTER_TEMP ); master = (HighlyAvailableGraphDatabase) new HighlyAvailableGraphDatabaseFactory(). newHighlyAvailableDatabaseBuilder( TargetDirectory.forTest( TestStoreCopy.class ).directory( "master-sandboxed", true ).getAbsolutePath() ). setConfig( HaSettings.server_id, "1" ). setConfig( HaSettings.cluster_server, "localhost" ). newGraphDatabase(); Transaction masterTx = master.beginTx(); Node n = master.createNode(); n.setProperty( "foo", "bar" ); nodeId = n.getId(); masterTx.success(); masterTx.finish(); startSlave(); // Need to execute tx so we know the database has started Transaction tx = slave.beginTx(); tx.success(); tx.finish(); // Simple sanity check Assert.assertEquals( "bar", slave.getNodeById( nodeId ).getProperty( "foo" ) ); } private void startSlave() { slave = (HighlyAvailableGraphDatabase) new HighlyAvailableGraphDatabaseFactory(). newHighlyAvailableDatabaseBuilder( slaveDir.getAbsolutePath() ). setConfig( HaSettings.server_id, "2" ). setConfig( HaSettings.ha_server, ":6362" ). setConfig( HaSettings.cluster_server, ":5002" ). setConfig( HaSettings.cluster_discovery_enabled, "false" ). setConfig( HaSettings.initial_hosts, "localhost:5001" ). newGraphDatabase(); } /** * This is the sandboxed copy test, so we naturally want to always make sure * that the sandbox directory after every startup is there and holds only * messages.log * <p/> * Also, shutdown the instances. * * @throws Exception */ @After public void shutdownAndCheckSandbox() throws Exception { slave.shutdown(); master.shutdown(); /* * Make sure: * - The sandbox directory exists * - It only has one file in it * - It is the messages.log file */ Assert.assertTrue( sandboxed.exists() ); Assert.assertTrue( sandboxed.isDirectory() ); Assert.assertEquals( 1, sandboxed.listFiles( DISREGARD_ACTIVE_LOG_FILES ).length ); Assert.assertEquals( StringLogger.DEFAULT_NAME, sandboxed.listFiles( DISREGARD_ACTIVE_LOG_FILES )[0].getName() ); } /** * Checks that leftovers in the sandbox directory are discarded on store * copy. * * @throws Exception */ @Test public void sandboxIsOverwritten() throws Exception { slave.shutdown(); Transaction secondMasterTx = master.beginTx(); Node n = master.getNodeById( nodeId ); n.setProperty( "foo2", "bar2" ); secondMasterTx.success(); secondMasterTx.finish(); File sandboxed = new File( slaveDir, SlaveStoreWriter.COPY_FROM_MASTER_TEMP ); FileUtils.moveToDirectory( new File( slaveDir, "neostore" ), sandboxed, false ); FileUtils.moveToDirectory( new File( slaveDir, "neostore.propertystore.db" ), sandboxed, false ); Assert.assertEquals( "Found these files:" + filesAsString( sandboxed ), 3, sandboxed.listFiles( DISREGARD_ACTIVE_LOG_FILES ).length ); startSlave(); // Need to execute tx so we know the database has started Transaction tx = slave.beginTx(); tx.success(); tx.finish(); Assert.assertEquals( "bar", slave.getNodeById( nodeId ).getProperty( "foo" ) ); Assert.assertEquals( "bar2", slave.getNodeById( nodeId ).getProperty( "foo2" ) ); } private String filesAsString( File directory ) { StringBuilder builder = new StringBuilder(); for ( File file : directory.listFiles( DISREGARD_ACTIVE_LOG_FILES ) ) builder.append( "\n" ).append( file.isDirectory() ? "/" : "" ).append( file.getName() ); return builder.toString(); } }