@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));
  }
  @Test
  public void testFile() throws Exception {
    byte[] data = FileServerTestUtil.createRandomData(1024);

    long lastModified = FileServerTestUtil.getFileSystemTime(System.currentTimeMillis() - Time.DAY);

    FileResponse fileResponse = new FileResponse(_path, data.length, lastModified, false);

    NoticeableFuture<FileResponse> noticeableFuture = _asyncBroker.post(_path);

    _fileResponseChannelHandler.channelRead(
        _channelHandlerContext, fileResponse, FileServerTestUtil.wrapFirstHalf(data));

    ChannelHandler channelHandler = _channelPipeline.first();

    Assert.assertTrue(channelHandler instanceof FileUploadChannelHandler);

    FileUploadChannelHandler fileUploadChannelHandler = (FileUploadChannelHandler) channelHandler;

    _channelPipeline.fireChannelRead(FileServerTestUtil.wrapSecondHalf(data));

    channelHandler = _channelPipeline.first();

    Assert.assertFalse(channelHandler instanceof FileUploadChannelHandler);
    Assert.assertSame(fileResponse, fileUploadChannelHandler.fileResponse);
    Assert.assertSame(fileResponse, noticeableFuture.get());

    Path localFile = fileResponse.getLocalFile();

    Assert.assertNotNull(localFile);

    FileTime fileTime = Files.getLastModifiedTime(localFile);

    Assert.assertEquals(lastModified, fileTime.toMillis());
    Assert.assertArrayEquals(data, Files.readAllBytes(localFile));

    Files.delete(localFile);
  }
  @Test
  public void testFileNotModifiedNoMatchKey() throws Exception {
    FileResponse fileResponse = new FileResponse(_path, FileResponse.FILE_NOT_MODIFIED, -1, false);

    try (CaptureHandler captureHandler =
        JDKLoggerTestUtil.configureJDKLogger(
            FileResponseChannelHandler.class.getName(), Level.SEVERE)) {

      _fileResponseChannelHandler.channelRead(_channelHandlerContext, fileResponse, null);

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

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

      LogRecord logRecord = logRecords.get(0);

      Assert.assertEquals(
          "Unable to place result "
              + fileResponse
              + " because no future exists with ID "
              + fileResponse.getPath(),
          logRecord.getMessage());
    }
  }
  @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());
    }
  }