content: package org.libtorrent4j;
  
  import org.junit.Rule;
  import org.junit.rules.TemporaryFolder;
  import org.libtorrent4j.alerts.AddTorrentAlert;
  import org.libtorrent4j.alerts.Alert;
  import org.libtorrent4j.alerts.AlertType;
  import org.libtorrent4j.alerts.PieceFinishedAlert;
  import org.libtorrent4j.alerts.SaveResumeDataAlert;
  import org.libtorrent4j.alerts.TorrentFinishedAlert;
  import org.libtorrent4j.alerts.TorrentPausedAlert;
  import org.libtorrent4j.swig.torrent_flags_t;
  
  import java.io.File;
  import java.util.concurrent.CountDownLatch;
  
  import static org.junit.Assert.assertEquals;
  import static org.junit.Assert.assertNull;
  import static org.junit.Assert.assertTrue;
  
  /**
   * @author gubatron
   * @author aldenml
   */
  public final class StatusDurationTest {
  
      @Rule
      public TemporaryFolder folder = new TemporaryFolder();
  
      private long activeDuration = 0;
      private Entry resumeData;
  
      //@Test
      public void testDuration() throws Throwable {
  
          String torrentFilename = "AJC_and_The_Envelope_Pushers_Fallen_Star_FrostClick_FrostWire_MP3_January_16_2017.torrent";
          File torrentFile = folder.newFile(torrentFilename);
          byte[] data = Utils.resourceBytes(torrentFilename);
          Utils.writeByteArrayToFile(torrentFile, data, false);
  
          final SessionManager s = new SessionManager();
  
          final CountDownLatch signal1 = new CountDownLatch(1);
          final CountDownLatch signal2 = new CountDownLatch(1);
  
          s.addListener(new AlertListener() {
  
              private boolean paused = false;
  
              @Override
              public int[] types() {
                  return null;
              }
  
              @Override
              public void alert(Alert<?> alert) {
                  AlertType type = alert.type();
  
                  switch (type) {
                      case ADD_TORRENT:
                          ((AddTorrentAlert) alert).handle().resume();
                          break;
                      case PIECE_FINISHED:
                          int progress = (int) (((PieceFinishedAlert) alert).handle().status().progress() * 100);
                          // this number represents the current progress of
                          // the current status (downloading or checking)
                          log("progress: " + progress);
                          if (progress > 2 && !paused) {
                              paused = true;
                              ((PieceFinishedAlert) alert).handle().pause();
                          }
                          break;
                      case TORRENT_PAUSED:
                          log("Torrent paused");
                          TorrentHandle th = ((TorrentPausedAlert) alert).handle();
                          th.saveResumeData();
                          break;
                      case SAVE_RESUME_DATA:
                          resumeData = AddTorrentParams.writeResumeData(((SaveResumeDataAlert) alert).params());
                          TorrentHandle th2 = ((SaveResumeDataAlert) alert).handle();
                          TorrentStatus status2 = th2.status();
                          activeDuration = status2.activeDuration();
                          signal1.countDown();
                          break;
                      case TORRENT_FINISHED:
                          TorrentHandle th1 = ((TorrentFinishedAlert) alert).handle();
                          TorrentStatus status1 = th1.status();
                          activeDuration = status1.activeDuration();
                          signal2.countDown();
                          break;
  
                  }
              }
          });
  
          s.start();
  
          TorrentInfo ti = new TorrentInfo(torrentFile);
          s.download(ti, torrentFile.getParentFile());
  
          Utils.awaitMinutes(signal1, "too much time downloading the torrent 2%", 5);
          assertNull(s.lastAlertError());
  
          s.stop();
  
          log("activeDuration: " + activeDuration);
  
          //log(resumeData.toString());
          long savedActiveDuration = resumeData.dictionary().get("active_time").integer() * 1000;
          assertEquals(activeDuration, savedActiveDuration);
  
          File resumeFile = folder.newFile("resume.data");
          Utils.writeByteArrayToFile(resumeFile, resumeData.bencode(), false);
  
          Thread.sleep(10000);
  
          s.start();
  
          long timeMark = System.currentTimeMillis();
          s.download(ti, torrentFile.getParentFile(), resumeFile, null, null, new torrent_flags_t());
  
          Utils.awaitMinutes(signal2, "too much time downloading the torrent 100%", 5);
          assertNull(s.lastAlertError());
  
          log("activeDuration: " + activeDuration);
          long t1 = activeDuration - savedActiveDuration; // time active in the 98%
          long t2 = System.currentTimeMillis() - timeMark; // approximate time in the 98%
          assertTrue(t2 - t1 < 2000); // active time should not be affected by the sleep(10000)
      }
  
      private static void log(String msg) {
          // comment/uncomment for hand debugging
          System.out.println(msg);
      }
  }
  