use of org.neo4j.io.fs.FileSystemAbstraction in project neo4j by neo4j.
the class MuninnPageCacheTest method mustUnblockPageFaultersWhenEvictionGetsException.
@Test(timeout = SEMI_LONG_TIMEOUT_MILLIS)
public void mustUnblockPageFaultersWhenEvictionGetsException() throws Exception {
writeInitialDataTo(file("a"));
FileSystemAbstraction fs = new DelegatingFileSystemAbstraction(this.fs) {
@Override
public StoreChannel open(File fileName, String mode) throws IOException {
return new DelegatingStoreChannel(super.open(fileName, mode)) {
@Override
public void writeAll(ByteBuffer src, long position) throws IOException {
throw new IOException("uh-oh...");
}
};
}
};
MuninnPageCache pageCache = createPageCache(fs, 2, 8, PageCacheTracer.NULL, DefaultPageCursorTracerSupplier.INSTANCE);
final PagedFile pagedFile = pageCache.map(file("a"), 8);
// all writes.
try (PageCursor cursor = pagedFile.io(0, PF_SHARED_WRITE_LOCK)) {
for (int i = 0; i < 1000; i++) {
assertTrue(cursor.next());
}
fail("Expected an exception at this point");
} catch (IOException ignore) {
// Good.
}
}
use of org.neo4j.io.fs.FileSystemAbstraction 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();
}
use of org.neo4j.io.fs.FileSystemAbstraction in project neo4j by neo4j.
the class PhysicalLogFileTest method shouldCloseChannelInFailedAttemptToReadHeaderAfterOpen.
@Test
public void shouldCloseChannelInFailedAttemptToReadHeaderAfterOpen() throws Exception {
// GIVEN a file which returns 1/2 log header size worth of bytes
File directory = new File("/dir");
FileSystemAbstraction fs = mock(FileSystemAbstraction.class);
PhysicalLogFiles logFiles = new PhysicalLogFiles(directory, fs);
int logVersion = 0;
File logFile = logFiles.getLogFileForVersion(logVersion);
StoreChannel channel = mock(StoreChannel.class);
when(channel.read(any(ByteBuffer.class))).thenReturn(LogHeader.LOG_HEADER_SIZE / 2);
when(fs.fileExists(logFile)).thenReturn(true);
when(fs.open(eq(logFile), anyString())).thenReturn(channel);
// WHEN
try {
PhysicalLogFile.openForVersion(logFiles, fs, logVersion, false);
fail("Should have failed");
} catch (IncompleteLogHeaderException e) {
// THEN good
verify(channel).close();
}
}
use of org.neo4j.io.fs.FileSystemAbstraction in project neo4j by neo4j.
the class PhysicalLogFileTest method shouldSuppressFailueToCloseChannelInFailedAttemptToReadHeaderAfterOpen.
@Test
public void shouldSuppressFailueToCloseChannelInFailedAttemptToReadHeaderAfterOpen() throws Exception {
// GIVEN a file which returns 1/2 log header size worth of bytes
File directory = new File("/dir");
FileSystemAbstraction fs = mock(FileSystemAbstraction.class);
PhysicalLogFiles logFiles = new PhysicalLogFiles(directory, fs);
int logVersion = 0;
File logFile = logFiles.getLogFileForVersion(logVersion);
StoreChannel channel = mock(StoreChannel.class);
when(channel.read(any(ByteBuffer.class))).thenReturn(LogHeader.LOG_HEADER_SIZE / 2);
when(fs.fileExists(logFile)).thenReturn(true);
when(fs.open(eq(logFile), anyString())).thenReturn(channel);
doThrow(IOException.class).when(channel).close();
// WHEN
try {
PhysicalLogFile.openForVersion(logFiles, fs, logVersion, false);
fail("Should have failed");
} catch (IncompleteLogHeaderException e) {
// THEN good
verify(channel).close();
assertEquals(1, e.getSuppressed().length);
assertTrue(e.getSuppressed()[0] instanceof IOException);
}
}
use of org.neo4j.io.fs.FileSystemAbstraction in project neo4j by neo4j.
the class EditionModule method setupSecurityModule.
protected static void setupSecurityModule(PlatformModule platformModule, Log log, Procedures procedures, String key) {
for (SecurityModule candidate : Service.load(SecurityModule.class)) {
if (candidate.matches(key)) {
try {
candidate.setup(new SecurityModule.Dependencies() {
@Override
public LogService logService() {
return platformModule.logging;
}
@Override
public Config config() {
return platformModule.config;
}
@Override
public Procedures procedures() {
return procedures;
}
@Override
public JobScheduler scheduler() {
return platformModule.jobScheduler;
}
@Override
public FileSystemAbstraction fileSystem() {
return platformModule.fileSystem;
}
@Override
public LifeSupport lifeSupport() {
return platformModule.life;
}
@Override
public DependencySatisfier dependencySatisfier() {
return platformModule.dependencies;
}
});
return;
} catch (Exception e) {
String errorMessage = "Failed to load security module.";
log.error(errorMessage);
throw new RuntimeException(errorMessage, e);
}
}
}
String errorMessage = "Failed to load security module with key '" + key + "'.";
log.error(errorMessage);
throw new IllegalArgumentException(errorMessage);
}
Aggregations