ZcashLightClientKit/ZcashLightClientKitTests/BlockStreamingTest.swift

233 lines
7.8 KiB
Swift

//
// BlockStreamingTest.swift
// ZcashLightClientKit-Unit-Tests
//
// Created by Francisco Gindre on 5/25/21.
//
import XCTest
@testable import ZcashLightClientKit
// swiftlint:disable print_function_usage
class BlockStreamingTest: XCTestCase {
var queue: OperationQueue = {
let queue = OperationQueue()
queue.maxConcurrentOperationCount = 1
return queue
}()
override func setUpWithError() throws {
try super.setUpWithError()
logger = SampleLogger(logLevel: .debug)
}
override func tearDownWithError() throws {
try super.tearDownWithError()
try? FileManager.default.removeItem(at: __dataDbURL())
}
func testStreamOperation() throws {
let expectation = XCTestExpectation(description: "blockstream expectation")
let service = LightWalletGRPCService(
host: LightWalletEndpointBuilder.eccTestnet.host,
port: 9067,
secure: true,
singleCallTimeout: 1000,
streamingCallTimeout: 100000
)
let latestHeight = try service.latestBlockHeight()
let startHeight = latestHeight - 100_000
var blocks: [ZcashCompactBlock] = []
service.blockStream(startHeight: startHeight, endHeight: latestHeight) { result in
expectation.fulfill()
switch result {
case .success(let status):
XCTAssertEqual(GRPCResult.success, status)
case .failure(let error):
XCTFail("failed with error: \(error)")
}
} handler: { compactBlock in
print("received block \(compactBlock.height)")
blocks.append(compactBlock)
} progress: { progressReport in
print("progressHeight: \(progressReport.progressHeight)")
print("startHeight: \(progressReport.startHeight)")
print("targetHeight: \(progressReport.targetHeight)")
}
wait(for: [expectation], timeout: 1000)
}
func testStreamOperationCancellation() throws {
let expectation = XCTestExpectation(description: "blockstream expectation")
let service = LightWalletGRPCService(
host: LightWalletEndpointBuilder.eccTestnet.host,
port: 9067,
secure: true,
singleCallTimeout: 10000,
streamingCallTimeout: 10000
)
let storage = try TestDbBuilder.inMemoryCompactBlockStorage()
let startHeight = try service.latestBlockHeight() - 100_000
let operation = CompactBlockStreamDownloadOperation(
service: service,
storage: storage,
startHeight: startHeight,
progressDelegate: self
)
operation.completionHandler = { _, cancelled in
XCTAssert(cancelled)
expectation.fulfill()
}
operation.errorHandler = { error in
XCTFail("failed with error: \(error)")
expectation.fulfill()
}
queue.addOperation(operation)
DispatchQueue.main.asyncAfter(deadline: .now() + 3, execute: {
self.queue.cancelAllOperations()
})
wait(for: [expectation], timeout: 1000)
}
func testStreamOperationTimeout() throws {
let expectation = XCTestExpectation(description: "blockstream expectation")
let errorExpectation = XCTestExpectation(description: "blockstream error expectation")
let service = LightWalletGRPCService(
host: LightWalletEndpointBuilder.eccTestnet.host,
port: 9067,
secure: true,
singleCallTimeout: 1000,
streamingCallTimeout: 3000
)
let storage = try TestDbBuilder.inMemoryCompactBlockStorage()
let startHeight = try service.latestBlockHeight() - 100_000
let operation = CompactBlockStreamDownloadOperation(
service: service,
storage: storage,
startHeight: startHeight,
progressDelegate: self
)
operation.completionHandler = { finished, _ in
XCTAssert(finished)
expectation.fulfill()
}
operation.errorHandler = { error in
if let lwdError = error as? LightWalletServiceError {
switch lwdError {
case .timeOut:
XCTAssert(true)
default:
XCTFail("LWD Service erro found, but should have been a timeLimit reached Error")
}
} else {
XCTFail("Error should have been a timeLimit reached Error")
}
errorExpectation.fulfill()
}
queue.addOperation(operation)
let date = Date()
wait(for: [errorExpectation], timeout: 4)
let now = Date()
let elapsed = now.distance(to: date)
print("took \(elapsed) seconds")
}
func testBatchOperation() throws {
let expectation = XCTestExpectation(description: "blockbatch expectation")
let service = LightWalletGRPCService(
host: LightWalletEndpointBuilder.eccTestnet.host,
port: 9067,
secure: true,
singleCallTimeout: 300000,
streamingCallTimeout: 10000
)
let storage = try TestDbBuilder.diskCompactBlockStorage(at: __dataDbURL() )
let targetHeight = try service.latestBlockHeight()
let startHeight = targetHeight - 10_000
let operation = CompactBlockBatchDownloadOperation(
service: service,
storage: storage,
startHeight: startHeight,
targetHeight: targetHeight,
progressDelegate: self
)
operation.completionHandler = { _, cancelled in
if cancelled {
XCTFail("operation cancelled")
}
expectation.fulfill()
}
operation.errorHandler = { error in
XCTFail("failed with error: \(error)")
expectation.fulfill()
}
queue.addOperation(operation)
wait(for: [expectation], timeout: 120)
}
func testBatchOperationCancellation() throws {
let expectation = XCTestExpectation(description: "blockbatch expectation")
let service = LightWalletGRPCService(
host: LightWalletEndpointBuilder.eccTestnet.host,
port: 9067,
secure: true,
singleCallTimeout: 300000,
streamingCallTimeout: 10000
)
let storage = try TestDbBuilder.diskCompactBlockStorage(at: __dataDbURL() )
let targetHeight = try service.latestBlockHeight()
let startHeight = targetHeight - 100_000
let operation = CompactBlockBatchDownloadOperation(
service: service,
storage: storage,
startHeight: startHeight,
targetHeight: targetHeight,
progressDelegate: self
)
operation.completionHandler = { _, cancelled in
XCTAssert(cancelled)
expectation.fulfill()
}
operation.errorHandler = { error in
XCTFail("failed with error: \(error)")
expectation.fulfill()
}
queue.addOperation(operation)
DispatchQueue.main.asyncAfter(deadline: .now() + 3, execute: {
self.queue.cancelAllOperations()
})
wait(for: [expectation], timeout: 1000)
}
}
extension BlockStreamingTest: CompactBlockProgressDelegate {
func progressUpdated(_ progress: CompactBlockProgress) {
print("progressHeight: \(String(describing: progress.progressHeight))")
print("startHeight: \(progress.progress)")
print("targetHeight: \(String(describing: progress.targetHeight))")
}
}