@AdviseWith(adviceClasses = NettyUtilAdvice.class)
  @Test
  public void testDispose() throws Exception {
    Path remoteFilePath = Paths.get("remoteFile");

    Path tempFilePath = FileServerTestUtil.createFileWithData(Paths.get("tempFile"));

    Map<Path, Path> pathMap = _nettyRepository.pathMap;

    FileServerTestUtil.createFileWithData(tempFilePath);

    try (CaptureHandler captureHandler =
        JDKLoggerTestUtil.configureJDKLogger(NettyRepository.class.getName(), Level.OFF)) {

      NoticeableFuture<Path> noticeableFuture =
          _nettyRepository.getFile(_embeddedChannel, remoteFilePath, null, false);

      FileResponse fileResponse =
          new FileResponse(remoteFilePath, System.currentTimeMillis(), 0, false);

      fileResponse.setLocalFile(tempFilePath);

      _asyncBroker.takeWithResult(remoteFilePath, fileResponse);

      Path localFilePath = noticeableFuture.get();

      Assert.assertNotNull(localFilePath);
      Assert.assertTrue(Files.notExists(tempFilePath));
      Assert.assertTrue(Files.exists(localFilePath));
      Assert.assertEquals(1, pathMap.size());
      Assert.assertSame(localFilePath, pathMap.get(remoteFilePath));

      _nettyRepository.dispose(false);

      Assert.assertTrue(Files.notExists(localFilePath));
      Assert.assertTrue(pathMap.isEmpty());
      Assert.assertTrue(Files.exists(_repositoryPath));

      _nettyRepository.dispose(true);

      Assert.assertTrue(Files.notExists(_repositoryPath));

      List<LogRecord> logRecords = captureHandler.getLogRecords();

      Assert.assertTrue(logRecords.isEmpty());
    }
  }
  @AdviseWith(adviceClasses = NettyUtilAdvice.class)
  @Test
  public void testGetFiles() throws Exception {
    Map<Path, Path> pathMap = new HashMap<>();

    Path remoteFilePath1 = Paths.get("remoteFile1");
    Path remoteFilePath2 = Paths.get("remoteFile2");
    Path localFilePath = FileServerTestUtil.registerForCleanUp(Paths.get("localFile1"));

    pathMap.put(remoteFilePath1, localFilePath);
    pathMap.put(remoteFilePath2, Paths.get("localFile2"));

    NoticeableFuture<Map<Path, Path>> noticeableFuture =
        _nettyRepository.getFiles(_embeddedChannel, pathMap, true);

    Path tempFilePath = FileServerTestUtil.createFileWithData(Paths.get("tempFile"));

    FileResponse fileResponse1 =
        new FileResponse(remoteFilePath1, Files.size(tempFilePath), -1, false);

    fileResponse1.setLocalFile(tempFilePath);

    Assert.assertTrue(_asyncBroker.takeWithResult(remoteFilePath1, fileResponse1));

    try (CaptureHandler captureHandler =
        JDKLoggerTestUtil.configureJDKLogger(NettyRepository.class.getName(), Level.WARNING)) {

      Assert.assertTrue(
          _asyncBroker.takeWithResult(
              remoteFilePath2,
              new FileResponse(remoteFilePath2, FileResponse.FILE_NOT_FOUND, -1, false)));

      List<LogRecord> logRecords = captureHandler.getLogRecords();

      Assert.assertEquals(1, logRecords.size());

      LogRecord logRecord = logRecords.get(0);

      Assert.assertEquals("Remote file remoteFile2 is not found", logRecord.getMessage());
    }

    Map<Path, Path> resultPathMap = noticeableFuture.get();

    Assert.assertEquals(1, resultPathMap.size());
    Assert.assertEquals(localFilePath, resultPathMap.get(remoteFilePath1));
  }
  @Before
  public void setUp() throws IOException {
    _channelPipeline = _embeddedChannel.pipeline();

    _repositoryPath = Paths.get("repository");

    FileHelperUtil.delete(_repositoryPath);

    FileServerTestUtil.registerForCleanUp(Files.createDirectory(_repositoryPath));

    _nettyRepository = new NettyRepository(_repositoryPath, Long.MAX_VALUE);

    _asyncBroker = _nettyRepository.getAsyncBroker();

    _channelPipeline.addLast(
        new FileResponseChannelHandler(_asyncBroker, _embeddedChannel.eventLoop()));
  }
 @After
 public void tearDown() {
   FileServerTestUtil.cleanUp();
 }
  @AdviseWith(adviceClasses = NettyUtilAdvice.class)
  @Test
  public void testGetFile() throws Exception {

    // With log, populate cache

    Path remoteFilePath = Paths.get("remoteFile");

    Path tempFilePath = FileServerTestUtil.createFileWithData(Paths.get("tempFile"));

    Map<Path, Path> pathMap = _nettyRepository.pathMap;

    try (CaptureHandler captureHandler =
        JDKLoggerTestUtil.configureJDKLogger(NettyRepository.class.getName(), Level.FINEST)) {

      NoticeableFuture<Path> noticeableFuture1 =
          _nettyRepository.getFile(_embeddedChannel, remoteFilePath, null, false);

      NoticeableFuture<Path> noticeableFuture2 =
          _nettyRepository.getFile(_embeddedChannel, remoteFilePath, null, false);

      Assert.assertNotSame(noticeableFuture1, noticeableFuture2);

      FileResponse fileResponse =
          new FileResponse(remoteFilePath, System.currentTimeMillis(), 0, false);

      fileResponse.setLocalFile(tempFilePath);

      _asyncBroker.takeWithResult(remoteFilePath, fileResponse);

      Path localFilePath = FileServerTestUtil.registerForCleanUp(noticeableFuture1.get());

      Assert.assertSame(localFilePath, noticeableFuture2.get());
      Assert.assertSame(localFilePath, fileResponse.getLocalFile());
      Assert.assertNotNull(localFilePath);
      Assert.assertTrue(Files.notExists(tempFilePath));
      Assert.assertTrue(Files.exists(localFilePath));
      Assert.assertEquals(1, pathMap.size());
      Assert.assertSame(localFilePath, pathMap.get(remoteFilePath));

      Files.delete(localFilePath);

      List<LogRecord> logRecords = captureHandler.getLogRecords();

      Assert.assertEquals(4, logRecords.size());

      LogRecord logRecord = logRecords.get(0);

      Assert.assertEquals("Fetching remote file " + remoteFilePath, logRecord.getMessage());

      logRecord = logRecords.get(1);

      Assert.assertEquals("Fetching remote file " + remoteFilePath, logRecord.getMessage());

      logRecord = logRecords.get(2);

      Assert.assertEquals(
          "Fetched remote file " + remoteFilePath + " to " + localFilePath, logRecord.getMessage());

      logRecord = logRecords.get(3);

      Assert.assertEquals(
          "Fetched remote file " + remoteFilePath + " to " + localFilePath, logRecord.getMessage());
    } finally {
      pathMap.clear();
    }

    // Without log, not populate cacge

    FileServerTestUtil.createFileWithData(tempFilePath);

    Path localFilePath1 =
        FileServerTestUtil.registerForCleanUp(_repositoryPath.resolve("localFile1"));
    Path localFilePath2 =
        FileServerTestUtil.registerForCleanUp(_repositoryPath.resolve("localFile2"));

    try (CaptureHandler captureHandler =
        JDKLoggerTestUtil.configureJDKLogger(NettyRepository.class.getName(), Level.OFF)) {

      NoticeableFuture<Path> noticeableFuture1 =
          _nettyRepository.getFile(_embeddedChannel, remoteFilePath, localFilePath1, false);

      NoticeableFuture<Path> noticeableFuture2 =
          _nettyRepository.getFile(_embeddedChannel, remoteFilePath, localFilePath2, false);

      Assert.assertNotSame(noticeableFuture1, noticeableFuture2);

      FileResponse fileResponse =
          new FileResponse(remoteFilePath, System.currentTimeMillis(), 0, false);

      fileResponse.setLocalFile(tempFilePath);

      _asyncBroker.takeWithResult(remoteFilePath, fileResponse);

      Assert.assertSame(localFilePath1, noticeableFuture1.get());
      Assert.assertSame(localFilePath2, noticeableFuture2.get());
      Assert.assertSame(localFilePath2, fileResponse.getLocalFile());
      Assert.assertTrue(Files.notExists(tempFilePath));
      Assert.assertTrue(Files.exists(localFilePath1));
      Assert.assertTrue(Files.exists(localFilePath2));
      Assert.assertTrue(pathMap.isEmpty());

      List<LogRecord> logRecords = captureHandler.getLogRecords();

      Assert.assertTrue(logRecords.isEmpty());
    }
  }