content: package com.acgist.snail.net.torrent.peer;
  
  import java.util.ArrayList;
  import java.util.List;
  import java.util.concurrent.atomic.AtomicLong;
  
  import org.junit.jupiter.api.Test;
  
  import com.acgist.snail.config.DownloadConfig;
  import com.acgist.snail.context.entity.TaskEntity;
  import com.acgist.snail.context.session.StatisticsSession;
  import com.acgist.snail.context.session.TaskSession;
  import com.acgist.snail.context.wrapper.DescriptionWrapper;
  import com.acgist.snail.net.DownloadException;
  import com.acgist.snail.net.torrent.TorrentContext;
  import com.acgist.snail.net.torrent.TorrentFile;
  import com.acgist.snail.net.torrent.TorrentServer;
  import com.acgist.snail.protocol.Protocol.Type;
  import com.acgist.snail.utils.Performance;
  import com.acgist.snail.utils.ThreadUtils;
  
  class PeerServerTest extends Performance {
      
      @Test
      void testServer() throws DownloadException {
          final var path = "D:/tmp/snail/902FFAA29EE632C8DC966ED9AB573409BA9A518E.torrent";
          final var torrentSession = TorrentContext.getInstance().newTorrentSession(path);
          DownloadConfig.setBuffer(40 * 1024);
          final List<String> list = new ArrayList<>();
          final AtomicLong size = new AtomicLong();
          torrentSession.torrent().getInfo().files().stream()
              .filter(TorrentFile::notPaddingFile)
              .forEach(file -> {
                  if(file.path().contains("Scans/Vol.1")) {
                      list.add(file.path());
                  }
                  size.addAndGet(file.getLength());
              });
          final var entity = new TaskEntity();
          entity.setFile("D:/tmp/snail/server");
          entity.setType(Type.TORRENT);
          entity.setSize(size.get());
          entity.setDescription(DescriptionWrapper.newEncoder(list).serialize());
          torrentSession.upload(TaskSession.newInstance(entity));
          torrentSession.verify();
          PeerServer.getInstance();
          TorrentServer.getInstance();
          ThreadUtils.sleep(100000);
      }
  
      @Test
      void testClient() throws DownloadException {
          final var path = "D:/tmp/snail/902FFAA29EE632C8DC966ED9AB573409BA9A518E.torrent";
          final var torrentSession = TorrentContext.getInstance().newTorrentSession(path);
          DownloadConfig.setBuffer(40 * 1024);
          final List<String> list = new ArrayList<>();
          // 选择下载文件
          torrentSession.torrent().getInfo().files().stream()
              .filter(TorrentFile::notPaddingFile)
              .forEach(file -> {
                  if(file.path().contains("Scans/Vol.1")) {
                      list.add(file.path());
                  }
              });
          final var entity = new TaskEntity();
          entity.setFile("D:/tmp/snail/client");
          entity.setType(Type.TORRENT);
          entity.setDescription(DescriptionWrapper.newEncoder(list).serialize());
          // 禁止自动加载Peer
          torrentSession.upload(TaskSession.newInstance(entity)).download(false);
          torrentSession.verify();
          final String host = "127.0.0.1";
          final Integer port = 18888;
          final var statisticsSession = new StatisticsSession(); // 统计
          final var peerSession = PeerSession.newInstance(statisticsSession, host, port);
          // UTP支持：需要启动服务端后修改端口配置
  //      peerSession.flags(PeerConfig.PEX_UTP);
          final var launcher = PeerDownloader.newInstance(peerSession, torrentSession);
          launcher.handshake();
          new Thread(() -> {
              while(true) {
                  LOGGER.debug("下载速度：{}", statisticsSession.getDownloadSpeed());
                  ThreadUtils.sleep(1000);
                  torrentSession.torrentStreamGroup().flush();
              }
          }).start();
          ThreadUtils.sleep(100000);
      }
  
  }
  