Search in sources :

Example 1 with AdversarialFileSystemAbstraction

use of org.neo4j.adversaries.fs.AdversarialFileSystemAbstraction in project neo4j by neo4j.

the class SingleFilePageSwapperTest method mustHandleMischiefInPositionedRead.

@Test
public void mustHandleMischiefInPositionedRead() throws Exception {
    int bytesTotal = 512;
    byte[] data = new byte[bytesTotal];
    ThreadLocalRandom.current().nextBytes(data);
    PageSwapperFactory factory = createSwapperFactory();
    factory.setFileSystemAbstraction(getFs());
    File file = getFile();
    PageSwapper swapper = createSwapper(factory, file, bytesTotal, NO_CALLBACK, true);
    try {
        swapper.write(0, new ByteBufferPage(wrap(data)));
    } finally {
        swapper.close();
    }
    RandomAdversary adversary = new RandomAdversary(0.5, 0.0, 0.0);
    factory.setFileSystemAbstraction(new AdversarialFileSystemAbstraction(adversary, getFs()));
    swapper = createSwapper(factory, file, bytesTotal, NO_CALLBACK, false);
    ByteBufferPage page = createPage(bytesTotal);
    try {
        for (int i = 0; i < 10_000; i++) {
            clear(page);
            assertThat(swapper.read(0, page), is((long) bytesTotal));
            assertThat(array(page.buffer), is(data));
        }
    } finally {
        swapper.close();
    }
}
Also used : PageSwapperFactory(org.neo4j.io.pagecache.PageSwapperFactory) PageSwapper(org.neo4j.io.pagecache.PageSwapper) File(java.io.File) AdversarialFileSystemAbstraction(org.neo4j.adversaries.fs.AdversarialFileSystemAbstraction) RandomAdversary(org.neo4j.adversaries.RandomAdversary) PageSwapperTest(org.neo4j.io.pagecache.PageSwapperTest) Test(org.junit.Test)

Example 2 with AdversarialFileSystemAbstraction

use of org.neo4j.adversaries.fs.AdversarialFileSystemAbstraction in project neo4j by neo4j.

the class SingleFilePageSwapperTest method mustHandleMischiefInPositionedWrite.

@Test
public void mustHandleMischiefInPositionedWrite() throws Exception {
    int bytesTotal = 512;
    byte[] data = new byte[bytesTotal];
    ThreadLocalRandom.current().nextBytes(data);
    ByteBufferPage zeroPage = createPage(bytesTotal);
    clear(zeroPage);
    File file = getFile();
    PageSwapperFactory factory = createSwapperFactory();
    RandomAdversary adversary = new RandomAdversary(0.5, 0.0, 0.0);
    factory.setFileSystemAbstraction(new AdversarialFileSystemAbstraction(adversary, getFs()));
    PageSwapper swapper = createSwapper(factory, file, bytesTotal, NO_CALLBACK, true);
    ByteBufferPage page = createPage(bytesTotal);
    try {
        for (int i = 0; i < 10_000; i++) {
            adversary.setProbabilityFactor(0);
            swapper.write(0, zeroPage);
            page.putBytes(data, 0, 0, data.length);
            adversary.setProbabilityFactor(1);
            assertThat(swapper.write(0, page), is((long) bytesTotal));
            clear(page);
            adversary.setProbabilityFactor(0);
            swapper.read(0, page);
            assertThat(array(page.buffer), is(data));
        }
    } finally {
        swapper.close();
    }
}
Also used : PageSwapperFactory(org.neo4j.io.pagecache.PageSwapperFactory) PageSwapper(org.neo4j.io.pagecache.PageSwapper) File(java.io.File) AdversarialFileSystemAbstraction(org.neo4j.adversaries.fs.AdversarialFileSystemAbstraction) RandomAdversary(org.neo4j.adversaries.RandomAdversary) PageSwapperTest(org.neo4j.io.pagecache.PageSwapperTest) Test(org.junit.Test)

Example 3 with AdversarialFileSystemAbstraction

use of org.neo4j.adversaries.fs.AdversarialFileSystemAbstraction in project neo4j by neo4j.

the class SingleFilePageSwapperTest method mustHandleMischiefInPositionedVectoredRead.

@Test
public void mustHandleMischiefInPositionedVectoredRead() throws Exception {
    int bytesTotal = 512;
    int bytesPerPage = 32;
    int pageCount = bytesTotal / bytesPerPage;
    byte[] data = new byte[bytesTotal];
    ThreadLocalRandom.current().nextBytes(data);
    PageSwapperFactory factory = createSwapperFactory();
    factory.setFileSystemAbstraction(getFs());
    File file = getFile();
    PageSwapper swapper = createSwapper(factory, file, bytesTotal, NO_CALLBACK, true);
    try {
        swapper.write(0, new ByteBufferPage(wrap(data)));
    } finally {
        swapper.close();
    }
    RandomAdversary adversary = new RandomAdversary(0.5, 0.0, 0.0);
    factory.setFileSystemAbstraction(new AdversarialFileSystemAbstraction(adversary, getFs()));
    swapper = createSwapper(factory, file, bytesPerPage, NO_CALLBACK, false);
    ByteBufferPage[] pages = new ByteBufferPage[pageCount];
    for (int i = 0; i < pageCount; i++) {
        pages[i] = createPage(bytesPerPage);
    }
    byte[] temp = new byte[bytesPerPage];
    try {
        for (int i = 0; i < 10_000; i++) {
            for (ByteBufferPage page : pages) {
                clear(page);
            }
            assertThat(swapper.read(0, pages, 0, pages.length), is((long) bytesTotal));
            for (int j = 0; j < pageCount; j++) {
                System.arraycopy(data, j * bytesPerPage, temp, 0, bytesPerPage);
                assertThat(array(pages[j].buffer), is(temp));
            }
        }
    } finally {
        swapper.close();
    }
}
Also used : PageSwapperFactory(org.neo4j.io.pagecache.PageSwapperFactory) PageSwapper(org.neo4j.io.pagecache.PageSwapper) File(java.io.File) AdversarialFileSystemAbstraction(org.neo4j.adversaries.fs.AdversarialFileSystemAbstraction) RandomAdversary(org.neo4j.adversaries.RandomAdversary) PageSwapperTest(org.neo4j.io.pagecache.PageSwapperTest) Test(org.junit.Test)

Example 4 with AdversarialFileSystemAbstraction

use of org.neo4j.adversaries.fs.AdversarialFileSystemAbstraction in project neo4j by neo4j.

the class BatchingTransactionAppenderConcurrencyTest method shouldHaveAllConcurrentAppendersSeePanic.

/*
     * There was an issue where if multiple concurrent appending threads did append and they moved on
     * to await a force, where the force would fail and the one doing the force would raise a panic...
     * the other threads may not notice the panic and move on to mark those transactions as committed
     * and notice the panic later (which would be too late).
     */
@Test
public void shouldHaveAllConcurrentAppendersSeePanic() throws Throwable {
    // GIVEN
    Adversary adversary = new ClassGuardedAdversary(new CountingAdversary(1, true), failMethod(BatchingTransactionAppender.class, "force"));
    EphemeralFileSystemAbstraction efs = new EphemeralFileSystemAbstraction();
    File directory = new File("dir").getCanonicalFile();
    efs.mkdirs(directory);
    FileSystemAbstraction fs = new AdversarialFileSystemAbstraction(adversary, efs);
    life.add(new FileSystemLifecycleAdapter(fs));
    DatabaseHealth databaseHealth = new DatabaseHealth(mock(DatabasePanicEventGenerator.class), NullLog.getInstance());
    PhysicalLogFiles logFiles = new PhysicalLogFiles(directory, fs);
    LogFile logFile = life.add(new PhysicalLogFile(fs, logFiles, kibiBytes(10), transactionIdStore::getLastCommittedTransactionId, new DeadSimpleLogVersionRepository(0), new PhysicalLogFile.Monitor.Adapter(), logHeaderCache));
    final BatchingTransactionAppender appender = life.add(new BatchingTransactionAppender(logFile, logRotation, transactionMetadataCache, transactionIdStore, legacyIndexTransactionOrdering, databaseHealth));
    life.start();
    // WHEN
    int numberOfAppenders = 10;
    final CountDownLatch trap = new CountDownLatch(numberOfAppenders);
    final LogAppendEvent beforeForceTrappingEvent = new LogAppendEvent.Empty() {

        @Override
        public LogForceWaitEvent beginLogForceWait() {
            trap.countDown();
            awaitLatch(trap);
            return super.beginLogForceWait();
        }
    };
    Race race = new Race();
    for (int i = 0; i < numberOfAppenders; i++) {
        race.addContestant(() -> {
            try {
                // Append to the log, the LogAppenderEvent will have all of the appending threads
                // do wait for all of the other threads to start the force thing
                appender.append(tx(), beforeForceTrappingEvent);
                fail("No transaction should be considered appended");
            } catch (IOException e) {
            // Good, we know that this test uses an adversarial file system which will throw
            // an exception in BatchingTransactionAppender#force, and since all these transactions
            // will append and be forced in the same batch, where the force will fail then
            // all these transactions should fail. If there's any transaction not failing then
            // it just didn't notice the panic, which would be potentially hazardous.
            }
        });
    }
    // THEN perform the race. The relevant assertions are made inside the contestants.
    race.go();
}
Also used : FileSystemLifecycleAdapter(org.neo4j.io.fs.FileSystemLifecycleAdapter) DatabaseHealth(org.neo4j.kernel.internal.DatabaseHealth) CountingAdversary(org.neo4j.adversaries.CountingAdversary) AdversarialFileSystemAbstraction(org.neo4j.adversaries.fs.AdversarialFileSystemAbstraction) EphemeralFileSystemAbstraction(org.neo4j.graphdb.mockfs.EphemeralFileSystemAbstraction) FileSystemAbstraction(org.neo4j.io.fs.FileSystemAbstraction) ClassGuardedAdversary(org.neo4j.adversaries.ClassGuardedAdversary) EphemeralFileSystemAbstraction(org.neo4j.graphdb.mockfs.EphemeralFileSystemAbstraction) DatabasePanicEventGenerator(org.neo4j.kernel.impl.core.DatabasePanicEventGenerator) FileSystemLifecycleAdapter(org.neo4j.io.fs.FileSystemLifecycleAdapter) IOException(java.io.IOException) CountDownLatch(java.util.concurrent.CountDownLatch) LogAppendEvent(org.neo4j.kernel.impl.transaction.tracing.LogAppendEvent) DeadSimpleLogVersionRepository(org.neo4j.kernel.impl.transaction.DeadSimpleLogVersionRepository) Race(org.neo4j.test.Race) File(java.io.File) AdversarialFileSystemAbstraction(org.neo4j.adversaries.fs.AdversarialFileSystemAbstraction) Adversary(org.neo4j.adversaries.Adversary) CountingAdversary(org.neo4j.adversaries.CountingAdversary) ClassGuardedAdversary(org.neo4j.adversaries.ClassGuardedAdversary) Test(org.junit.Test)

Example 5 with AdversarialFileSystemAbstraction

use of org.neo4j.adversaries.fs.AdversarialFileSystemAbstraction in project neo4j by neo4j.

the class PartialTransactionFailureIT method concurrentlyCommittingTransactionsMustNotRotateOutLoggedCommandsOfFailingTransaction.

@Test
public void concurrentlyCommittingTransactionsMustNotRotateOutLoggedCommandsOfFailingTransaction() throws Exception {
    final ClassGuardedAdversary adversary = new ClassGuardedAdversary(new CountingAdversary(1, false), Command.RelationshipCommand.class);
    adversary.disable();
    File storeDir = dir.graphDbDir();
    final Map<String, String> params = stringMap(GraphDatabaseSettings.pagecache_memory.name(), "8m");
    final EmbeddedGraphDatabase db = new TestEmbeddedGraphDatabase(storeDir, params) {

        @Override
        protected void create(File storeDir, Map<String, String> params, GraphDatabaseFacadeFactory.Dependencies dependencies) {
            new GraphDatabaseFacadeFactory(DatabaseInfo.COMMUNITY, CommunityEditionModule::new) {

                @Override
                protected PlatformModule createPlatform(File storeDir, Config config, Dependencies dependencies, GraphDatabaseFacade graphDatabaseFacade) {
                    return new PlatformModule(storeDir, config, databaseInfo, dependencies, graphDatabaseFacade) {

                        @Override
                        protected FileSystemAbstraction createFileSystemAbstraction() {
                            return new AdversarialFileSystemAbstraction(adversary);
                        }
                    };
                }
            }.initFacade(storeDir, params, dependencies, this);
        }
    };
    Node a, b, c, d;
    try (Transaction tx = db.beginTx()) {
        a = db.createNode();
        b = db.createNode();
        c = db.createNode();
        d = db.createNode();
        tx.success();
    }
    adversary.enable();
    CountDownLatch latch = new CountDownLatch(1);
    Thread t1 = new Thread(createRelationship(db, a, b, latch), "T1");
    Thread t2 = new Thread(createRelationship(db, c, d, latch), "T2");
    t1.start();
    t2.start();
    // Wait for both threads to get going
    t1.join(10);
    t2.join(10);
    latch.countDown();
    // Wait for the transactions to finish
    t1.join(25000);
    t2.join(25000);
    db.shutdown();
    // We should observe the store in a consistent state
    EmbeddedGraphDatabase db2 = new TestEmbeddedGraphDatabase(storeDir, params);
    try (Transaction tx = db2.beginTx()) {
        Node x = db2.getNodeById(a.getId());
        Node y = db2.getNodeById(b.getId());
        Node z = db2.getNodeById(c.getId());
        Node w = db2.getNodeById(d.getId());
        Iterator<Relationship> itrRelX = x.getRelationships().iterator();
        Iterator<Relationship> itrRelY = y.getRelationships().iterator();
        Iterator<Relationship> itrRelZ = z.getRelationships().iterator();
        Iterator<Relationship> itrRelW = w.getRelationships().iterator();
        if (itrRelX.hasNext() != itrRelY.hasNext()) {
            fail("Node x and y have inconsistent relationship counts");
        } else if (itrRelX.hasNext()) {
            Relationship rel = itrRelX.next();
            assertEquals(rel, itrRelY.next());
            assertFalse(itrRelX.hasNext());
            assertFalse(itrRelY.hasNext());
        }
        if (itrRelZ.hasNext() != itrRelW.hasNext()) {
            fail("Node z and w have inconsistent relationship counts");
        } else if (itrRelZ.hasNext()) {
            Relationship rel = itrRelZ.next();
            assertEquals(rel, itrRelW.next());
            assertFalse(itrRelZ.hasNext());
            assertFalse(itrRelW.hasNext());
        }
    } finally {
        db2.shutdown();
    }
}
Also used : EmbeddedGraphDatabase(org.neo4j.kernel.internal.EmbeddedGraphDatabase) CountingAdversary(org.neo4j.adversaries.CountingAdversary) AdversarialFileSystemAbstraction(org.neo4j.adversaries.fs.AdversarialFileSystemAbstraction) FileSystemAbstraction(org.neo4j.io.fs.FileSystemAbstraction) ClassGuardedAdversary(org.neo4j.adversaries.ClassGuardedAdversary) Config(org.neo4j.kernel.configuration.Config) Node(org.neo4j.graphdb.Node) PlatformModule(org.neo4j.kernel.impl.factory.PlatformModule) CountDownLatch(java.util.concurrent.CountDownLatch) Transaction(org.neo4j.graphdb.Transaction) Command(org.neo4j.kernel.impl.transaction.command.Command) GraphDatabaseFacadeFactory(org.neo4j.kernel.impl.factory.GraphDatabaseFacadeFactory) Relationship(org.neo4j.graphdb.Relationship) GraphDatabaseFacade(org.neo4j.kernel.impl.factory.GraphDatabaseFacade) File(java.io.File) Map(java.util.Map) MapUtil.stringMap(org.neo4j.helpers.collection.MapUtil.stringMap) AdversarialFileSystemAbstraction(org.neo4j.adversaries.fs.AdversarialFileSystemAbstraction) Test(org.junit.Test)

Aggregations

AdversarialFileSystemAbstraction (org.neo4j.adversaries.fs.AdversarialFileSystemAbstraction)15 Test (org.junit.Test)14 File (java.io.File)12 RandomAdversary (org.neo4j.adversaries.RandomAdversary)8 CountingAdversary (org.neo4j.adversaries.CountingAdversary)7 EphemeralFileSystemAbstraction (org.neo4j.graphdb.mockfs.EphemeralFileSystemAbstraction)7 IOException (java.io.IOException)6 MethodGuardedAdversary (org.neo4j.adversaries.MethodGuardedAdversary)5 EndOfStreamException (org.neo4j.causalclustering.messaging.EndOfStreamException)5 FileSystemAbstraction (org.neo4j.io.fs.FileSystemAbstraction)5 PageSwapperFactory (org.neo4j.io.pagecache.PageSwapperFactory)5 SelectiveFileSystemAbstraction (org.neo4j.graphdb.mockfs.SelectiveFileSystemAbstraction)4 PageSwapper (org.neo4j.io.pagecache.PageSwapper)4 PageSwapperTest (org.neo4j.io.pagecache.PageSwapperTest)4 CountDownLatch (java.util.concurrent.CountDownLatch)2 Adversary (org.neo4j.adversaries.Adversary)2 ClassGuardedAdversary (org.neo4j.adversaries.ClassGuardedAdversary)2 HashMap (java.util.HashMap)1 Map (java.util.Map)1 ExecutorService (java.util.concurrent.ExecutorService)1