예제 #1
0
  @Test
  public void shouldRespectCustomLogRotationThreshold() throws Exception {
    // GIVEN
    long maxSize = 1000;
    XaLogicalLog log =
        new XaLogicalLog(
            new File("log"),
            mock(XaResourceManager.class),
            new FixedSizeXaCommandFactory(),
            new VersionRespectingXaTransactionFactory(),
            new DefaultLogBufferFactory(),
            ephemeralFs.get(),
            new DevNullLoggingService(),
            NO_PRUNING,
            mock(TransactionStateFactory.class),
            maxSize);
    log.open();
    long initialLogVersion = log.getHighestLogVersion();

    // WHEN
    for (int i = 0; i < 10; i++) {
      int identifier = log.start(xid, -1, -1);
      log.writeStartEntry(identifier);
      log.writeCommand(new FixedSizeXaCommand(100), identifier);
      log.commitOnePhase(identifier, i + 1, forced);
      log.done(identifier);
    }

    // THEN
    assertEquals(initialLogVersion + 1, log.getHighestLogVersion());
  }
예제 #2
0
 private int logCount() {
   XaLogicalLog log = neoDataSource().getXaContainer().getLogicalLog();
   int count = 0;
   for (long i = log.getHighestLogVersion() - 1; i >= 0; i--) {
     if (fs.fileExists(log.getFileName(i))) {
       count++;
     } else {
       break;
     }
   }
   return count;
 }
예제 #3
0
  @Test
  public void shouldNotReadExcessivelyFromTheFileChannelWhenRotatingLogWithNoOpenTransactions()
      throws Exception {
    // given
    XaTransactionFactory xaTf = mock(XaTransactionFactory.class);
    when(xaTf.getAndSetNewVersion()).thenAnswer(new TxVersion(TxVersion.UPDATE_AND_GET));
    when(xaTf.getCurrentVersion()).thenAnswer(new TxVersion(TxVersion.GET));
    // spy on the file system abstraction so that we can spy on the file channel for the logical log
    FileSystemAbstraction fs = spy(ephemeralFs.get());
    File dir = TargetDirectory.forTest(fs, XaLogicalLogTest.class).directory("log", true);
    // -- when opening the logical log, spy on the file channel we return and count invocations to
    // channel.read(*)
    when(fs.open(new File(dir, "logical.log.1"), "rw"))
        .thenAnswer(
            new Answer<FileChannel>() {
              @Override
              public FileChannel answer(InvocationOnMock invocation) throws Throwable {
                FileChannel channel = (FileChannel) invocation.callRealMethod();
                return mock(
                    channel.getClass(),
                    withSettings()
                        .spiedInstance(channel)
                        .name("channel")
                        .defaultAnswer(CALLS_REAL_METHODS)
                        .invocationListeners(
                            new InvocationListener() {
                              @Override
                              public void reportInvocation(
                                  MethodInvocationReport methodInvocationReport) {
                                if (methodInvocationReport
                                    .getInvocation()
                                    .toString()
                                    .startsWith("channel.read(")) {
                                  reads++;
                                }
                              }
                            }));
              }
            });
    XaLogicalLog xaLogicalLog =
        new XaLogicalLog(
            new File(dir, "logical.log"),
            mock(XaResourceManager.class),
            mock(XaCommandFactory.class),
            xaTf,
            new DefaultLogBufferFactory(),
            fs,
            new SingleLoggingService(StringLogger.wrap(output.writer())),
            LogPruneStrategies.NO_PRUNING,
            mock(TransactionStateFactory.class),
            25 * 1024 * 1024);
    xaLogicalLog.open();
    // -- set the log up with 10 transactions (with no commands, just start and commit)
    for (int txId = 1; txId <= 10; txId++) {
      int identifier =
          xaLogicalLog.start(new XidImpl(XidImpl.getNewGlobalId(), RESOURCE_ID), -1, 0);
      xaLogicalLog.writeStartEntry(identifier);
      xaLogicalLog.commitOnePhase(identifier, txId, ForceMode.forced);
      xaLogicalLog.done(identifier);
    }

    // when
    xaLogicalLog.rotate();

    // then
    assertThat(
        "should not read excessively from the logical log file channel", reads, lessThan(10));
  }