238 lines
8.2 KiB
Swift
238 lines
8.2 KiB
Swift
//
|
|
// TorrentClientTests.swift
|
|
// BitTorrentTests
|
|
//
|
|
// Created by Ben Davis on 13/08/2017.
|
|
// Copyright © 2017 Ben Davis. All rights reserved.
|
|
//
|
|
|
|
import XCTest
|
|
@testable import BitTorrent
|
|
|
|
class TorrentClientTests: XCTestCase {
|
|
|
|
let pathRoot = NSSearchPathForDirectoriesInDomains(.documentDirectory,
|
|
.userDomainMask, true)[0] as String
|
|
let metaInfo: TorrentMetaInfo = {
|
|
let path = Bundle(for: TorrentProgressManagerTests.self).path(forResource: "TestText",
|
|
ofType: "torrent")
|
|
let data = try! Data(contentsOf: URL(fileURLWithPath: path!))
|
|
return TorrentMetaInfo(data: data)!
|
|
}()
|
|
|
|
let finalData: Data = {
|
|
let path = Bundle(for: TorrentProgressManagerTests.self).path(forResource: "text", ofType: "txt")
|
|
return try! Data(contentsOf: URL(fileURLWithPath: path!))
|
|
}()
|
|
|
|
var torrentServer: TorrentServerStub!
|
|
var progressManager: TorrentProgressManagerStub!
|
|
var peerManager: TorrentPeerManagerStub!
|
|
var trackerManager: TorrentTrackerManagerStub!
|
|
var sut: TorrentClient!
|
|
|
|
override func setUp() {
|
|
super.setUp()
|
|
try! TorrentFileManager.prepareRootDirectory(pathRoot + "/text/", forTorrentMetaInfo: metaInfo)
|
|
|
|
torrentServer = TorrentServerStub(metaInfo: metaInfo)
|
|
progressManager = TorrentProgressManagerStub(metaInfo: metaInfo)
|
|
peerManager = TorrentPeerManagerStub(metaInfo: metaInfo)
|
|
trackerManager = TorrentTrackerManagerStub(metaInfo: metaInfo)
|
|
|
|
sut = TorrentClient(metaInfo: metaInfo,
|
|
torrentServer: torrentServer,
|
|
progressManager: progressManager,
|
|
peerManager: peerManager,
|
|
trackerManager: trackerManager)
|
|
}
|
|
|
|
func test_dependanciesCreated() {
|
|
let sut = TorrentClient(metaInfo: metaInfo, rootDirectory: pathRoot)
|
|
|
|
XCTAssertEqual(sut.metaInfo.infoHash, metaInfo.infoHash)
|
|
XCTAssert(sut.torrentServer.delegate === sut)
|
|
XCTAssert(sut.trackerManager.delegate === sut)
|
|
XCTAssert(sut.peerManager.delegate === sut)
|
|
}
|
|
|
|
func test_torrentServerStartsListeningOnTorrentStart() {
|
|
sut.start()
|
|
XCTAssert(torrentServer.startListeningCalled)
|
|
}
|
|
|
|
func test_trackerAnnounceOnTorrentStart() {
|
|
sut.start()
|
|
XCTAssert(trackerManager.startCalled)
|
|
}
|
|
|
|
func test_status() {
|
|
|
|
XCTAssertEqual(sut.status, .stopped)
|
|
|
|
sut.start()
|
|
XCTAssertEqual(sut.status, .started)
|
|
|
|
progressManager.testProgress.setCurrentlyDownloading(piece: 0)
|
|
progressManager.testProgress.finishedDownloading(piece: 0)
|
|
sut.torrentPeerManager(peerManager, downloadedPieceAtIndex: 0, piece: finalData)
|
|
XCTAssertEqual(sut.status, .completed)
|
|
}
|
|
|
|
func test_whenTorrentAlreadyDownloaded_statusIsCompletedOnStart() {
|
|
progressManager.testProgress.setCurrentlyDownloading(piece: 0)
|
|
progressManager.testProgress.finishedDownloading(piece: 0)
|
|
sut.start()
|
|
XCTAssertEqual(sut.status, .completed)
|
|
}
|
|
|
|
func test_newPeersFromTrackerAreGivenToPeersManager() {
|
|
|
|
// Given
|
|
let peers = [TorrentPeerInfo(ip: "127.0.0.1", port: 123, peerId: nil)]
|
|
|
|
// When
|
|
sut.torrentTrackerManager(trackerManager, gotNewPeers: peers)
|
|
|
|
// Then
|
|
XCTAssert(peerManager.addPeersCalled)
|
|
if let addPeersParameter = peerManager.addPeersParameter {
|
|
XCTAssertEqual(addPeersParameter, peers)
|
|
}
|
|
}
|
|
|
|
func test_announceInfoComesFromProgress() {
|
|
|
|
// Given
|
|
let pieceLength = metaInfo.info.pieceLength
|
|
|
|
var progress = TorrentProgress(size: 5)
|
|
|
|
progress.setCurrentlyDownloading(piece: 0)
|
|
progress.finishedDownloading(piece: 0)
|
|
|
|
progress.setCurrentlyDownloading(piece: 1)
|
|
progress.finishedDownloading(piece: 1)
|
|
|
|
progressManager.testProgress = progress
|
|
|
|
// When
|
|
let result = sut.torrentTrackerManagerAnnonuceInfo(trackerManager)
|
|
|
|
// Then
|
|
XCTAssertEqual(result.numberOfBytesDownloaded, pieceLength*2)
|
|
XCTAssertEqual(result.numberOfBytesRemaining, pieceLength*3)
|
|
XCTAssertEqual(result.numberOfBytesUploaded, 0)
|
|
}
|
|
|
|
func test_bitFieldForHandshakeComesFromProgress() {
|
|
|
|
// Given
|
|
var progress = TorrentProgress(size: 5)
|
|
|
|
progress.setCurrentlyDownloading(piece: 0)
|
|
progress.finishedDownloading(piece: 0)
|
|
|
|
progress.setCurrentlyDownloading(piece: 1)
|
|
progress.finishedDownloading(piece: 1)
|
|
|
|
progressManager.testProgress = progress
|
|
|
|
// When
|
|
let result = sut.torrentPeerManagerCurrentBitfieldForHandshake(peerManager)
|
|
|
|
// Then
|
|
XCTAssertEqual(result, progress.bitField)
|
|
}
|
|
|
|
func test_progressNotifiedOnDownloadedPiece() {
|
|
|
|
sut.torrentPeerManager(peerManager, downloadedPieceAtIndex: 123, piece: finalData)
|
|
|
|
XCTAssert(progressManager.setDownloadedPieceCalled)
|
|
if let setDownloadedPieceParameters = progressManager.setDownloadedPieceParameters {
|
|
XCTAssertEqual(setDownloadedPieceParameters.piece, finalData)
|
|
XCTAssertEqual(setDownloadedPieceParameters.pieceIndex, 123)
|
|
}
|
|
}
|
|
|
|
func test_progressNotifiedOnLostPiece() {
|
|
|
|
sut.torrentPeerManager(peerManager, failedToGetPieceAtIndex: 123)
|
|
|
|
XCTAssert(progressManager.setLostPieceCalled)
|
|
XCTAssertEqual(progressManager.setLostPieceIndex, 123)
|
|
}
|
|
|
|
func test_nextPieceAvailableComesFromProgress() {
|
|
|
|
var bitField = BitField(size: 5)
|
|
bitField.set(at: 3)
|
|
|
|
let expected = TorrentPieceRequest(pieceIndex: 1, size: 2, checksum: Data(bytes: [2]))
|
|
progressManager.getNextPieceToDownloadResult = expected
|
|
|
|
guard let result = sut.torrentPeerManager(peerManager, nextPieceFromAvailable: bitField) else {
|
|
XCTFail()
|
|
return
|
|
}
|
|
|
|
XCTAssert(progressManager.getNextPieceToDownloadCalled)
|
|
XCTAssertEqual(progressManager.getNextPieceToDownloadParameter!, bitField)
|
|
XCTAssertEqual(result.pieceIndex, expected.pieceIndex)
|
|
XCTAssertEqual(result.size, expected.size)
|
|
XCTAssertEqual(result.checksum, expected.checksum)
|
|
}
|
|
|
|
func test_pieceForUploadComesFromFileManager() {
|
|
|
|
progressManager.fileHandle.seek(toFileOffset: 0)
|
|
progressManager.fileHandle.write(finalData)
|
|
let result = sut.torrentPeerManager(peerManager, peerRequiresPieceAtIndex: 0)
|
|
XCTAssertEqual(result, finalData)
|
|
}
|
|
|
|
func test_peersConnectingFromServerAreAddedToPeerManager() {
|
|
|
|
// Given
|
|
let peer = createFakePeer()
|
|
|
|
// When
|
|
sut.torrentServer(torrentServer, connectedToPeer: peer)
|
|
|
|
// Then
|
|
XCTAssert(peerManager.addPeerCalled)
|
|
if let addPeerParameter = peerManager.addPeerParameter {
|
|
XCTAssert(addPeerParameter === peer)
|
|
}
|
|
}
|
|
|
|
func createFakePeer() -> TorrentPeer {
|
|
let peerInfo = TorrentPeerInfo(ip: "127.0.0.1", port: 123, peerId: nil)
|
|
let communicator = TorrentPeerCommunicatorStub(peerInfo: peerInfo, infoHash: metaInfo.infoHash)
|
|
return TorrentPeerFake(peerInfo: peerInfo,
|
|
bitFieldSize: metaInfo.info.pieces.count,
|
|
communicator: communicator)
|
|
}
|
|
|
|
func test_currentProgressForTorrentServer() {
|
|
|
|
// Given
|
|
var progress = TorrentProgress(size: 5)
|
|
|
|
progress.setCurrentlyDownloading(piece: 0)
|
|
progress.finishedDownloading(piece: 0)
|
|
|
|
progress.setCurrentlyDownloading(piece: 1)
|
|
progress.finishedDownloading(piece: 1)
|
|
|
|
progressManager.testProgress = progress
|
|
|
|
// When
|
|
let result = sut.currentProgress(for: torrentServer)
|
|
|
|
// Then
|
|
XCTAssertEqual(result, progress.bitField)
|
|
}
|
|
}
|