Merge pull request #1131 from Chlup/1126_fix_darksidetests

[#1126] Fix DarksideTests in state machine branch
This commit is contained in:
Michal Fousek 2023-05-26 10:46:51 +02:00 committed by GitHub
commit 0c3f01c201
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 175 additions and 261 deletions

View File

@ -36,7 +36,7 @@ actor CompactBlockProcessor {
private let metrics: SDKMetrics
private let rustBackend: ZcashRustBackendWelding
let service: LightWalletService
private let storage: CompactBlockRepository
let storage: CompactBlockRepository
private let transactionRepository: TransactionRepository
private let fileManager: ZcashFileManager

View File

@ -48,92 +48,6 @@ final class InternalStateConsistencyTests: ZcashTestCase {
try? FileManager.default.removeItem(at: coordinator.databases.dataDB)
}
// func testInternalStateIsConsistentWhenMigrating() async throws {
// sdkSynchronizerInternalSyncStatusHandler.subscribe(
// to: coordinator.synchronizer.stateStream,
// expectations: [.stopped: firstSyncExpectation]
// )
//
// let fullSyncLength = 10000
// try FakeChainBuilder.buildChain(darksideWallet: coordinator.service, branchID: branchID, chainName: chainName, length: fullSyncLength)
//
// sleep(1)
//
// // apply the height
// try coordinator.applyStaged(blockheight: 664150)
//
// sleep(1)
//
// try await coordinator.sync(
// completion: { _ in
// XCTFail("shouldn't have completed")
// },
// error: handleError
// )
//
// let coordinator = self.coordinator!
// DispatchQueue.global().asyncAfter(deadline: .now() + 1) {
// Task(priority: .userInitiated) {
// coordinator.synchronizer.stop()
// }
// }
//
// await fulfillment(of: [firstSyncExpectation], timeout: 2)
//
// let isSyncing = await coordinator.synchronizer.status.isSyncing
// let status = await coordinator.synchronizer.status
// XCTAssertFalse(isSyncing, "SDKSynchronizer shouldn't be syncing")
// XCTAssertEqual(status, .stopped)
//
// let internalSyncState = coordinator.synchronizer.internalSyncProgress
//
// let latestDownloadHeight = try await internalSyncState.latestDownloadedBlockHeight
// let latestScanHeight = try await coordinator.synchronizer.initializer.transactionRepository.lastScannedHeight()
// let dbHandle = TestDbHandle(originalDb: TestDbBuilder.prePopulatedDarksideCacheDb()!)
// try dbHandle.setUp()
//
// if latestDownloadHeight > latestScanHeight {
// try await coordinator.synchronizer.blockProcessor.migrateCacheDb(dbHandle.readWriteDb)
//
// let afterMigrationDownloadedHeight = try await internalSyncState.latestDownloadedBlockHeight
//
// XCTAssertNotEqual(latestDownloadHeight, afterMigrationDownloadedHeight)
// XCTAssertEqual(latestScanHeight, afterMigrationDownloadedHeight)
// } else {
// try await coordinator.synchronizer.blockProcessor.migrateCacheDb(dbHandle.readWriteDb)
//
// let afterMigrationDownloadedHeight = try await internalSyncState.latestDownloadedBlockHeight
//
// XCTAssertEqual(latestDownloadHeight, afterMigrationDownloadedHeight)
// XCTAssertEqual(latestScanHeight, afterMigrationDownloadedHeight)
// }
//
// XCTAssertFalse(FileManager.default.isReadableFile(atPath: dbHandle.readWriteDb.path))
//
// // clear to simulate a clean slate from the FsBlockDb
// try await coordinator.synchronizer.blockProcessor.storage.clear()
//
// // Now let's resume scanning and see how it goes.
// let secondSyncAttemptExpectation = XCTestExpectation(description: "second sync attempt")
//
// do {
// try await coordinator.sync(
// completion: { _ in
// XCTAssertTrue(true)
// secondSyncAttemptExpectation.fulfill()
// },
// error: { [weak self] error in
// secondSyncAttemptExpectation.fulfill()
// self?.handleError(error)
// }
// )
// } catch {
// handleError(error)
// }
//
// await fulfillment(of: [secondSyncAttemptExpectation], timeout: 10)
// }
func handleError(_ error: Error?) {
guard let testError = error else {
XCTFail("failed with nil error")

View File

@ -66,185 +66,185 @@ final class SynchronizerTests: ZcashTestCase {
reorgExpectation.fulfill()
}
// func testSynchronizerStops() async throws {
// /*
// 1. create fake chain
// */
// let fullSyncLength = 100_000
//
// try FakeChainBuilder.buildChain(darksideWallet: coordinator.service, branchID: branchID, chainName: chainName, length: fullSyncLength)
//
// try coordinator.applyStaged(blockheight: birthday + fullSyncLength)
//
// sleep(10)
//
// let syncStoppedExpectation = XCTestExpectation(description: "SynchronizerStopped Expectation")
// sdkSynchronizerInternalSyncStatusHandler.subscribe(
// to: coordinator.synchronizer.stateStream,
// expectations: [.stopped: syncStoppedExpectation]
// )
//
// /*
// sync to latest height
// */
// try await coordinator.sync(
// completion: { _ in
// XCTFail("Sync should have stopped")
// },
// error: self.handleError
// )
//
// try await Task.sleep(nanoseconds: 5_000_000_000)
// self.coordinator.synchronizer.stop()
//
// await fulfillment(of: [syncStoppedExpectation], timeout: 6)
//
// let status = await coordinator.synchronizer.status
// XCTAssertEqual(status, .stopped)
// let state = await coordinator.synchronizer.blockProcessor.state
// XCTAssertEqual(state, .stopped)
// }
func testSynchronizerStops() async throws {
/*
1. create fake chain
*/
let fullSyncLength = 100_000
try FakeChainBuilder.buildChain(darksideWallet: coordinator.service, branchID: branchID, chainName: chainName, length: fullSyncLength)
try coordinator.applyStaged(blockheight: birthday + fullSyncLength)
sleep(10)
let syncStoppedExpectation = XCTestExpectation(description: "SynchronizerStopped Expectation")
sdkSynchronizerInternalSyncStatusHandler.subscribe(
to: coordinator.synchronizer.stateStream,
expectations: [.stopped: syncStoppedExpectation]
)
/*
sync to latest height
*/
try await coordinator.sync(
completion: { _ in
XCTFail("Sync should have stopped")
},
error: self.handleError
)
try await Task.sleep(nanoseconds: 5_000_000_000)
self.coordinator.synchronizer.stop()
await fulfillment(of: [syncStoppedExpectation], timeout: 6)
let status = await coordinator.synchronizer.status
XCTAssertEqual(status, .stopped)
}
// MARK: Wipe tests
// func testWipeCalledWhichSyncDoesntRun() async throws {
// /*
// create fake chain
// */
// let fullSyncLength = 1000
//
// try FakeChainBuilder.buildChain(darksideWallet: coordinator.service, branchID: branchID, chainName: chainName, length: fullSyncLength)
//
// try coordinator.applyStaged(blockheight: birthday + fullSyncLength)
//
// sleep(2)
//
// let syncFinished = XCTestExpectation(description: "SynchronizerSyncFinished Expectation")
//
// /*
// sync to latest height
// */
// try await coordinator.sync(
// completion: { _ in
// syncFinished.fulfill()
// },
// error: handleError
// )
//
// await fulfillment(of: [syncFinished], timeout: 3)
//
// let wipeFinished = XCTestExpectation(description: "SynchronizerWipeFinished Expectation")
//
// /*
// Call wipe
// */
// coordinator.synchronizer.wipe()
// .sink(
// receiveCompletion: { completion in
// switch completion {
// case .finished:
// wipeFinished.fulfill()
//
// case .failure(let error):
// XCTFail("Wipe should finish successfully. \(error)")
// }
// },
// receiveValue: {
// XCTFail("No no value should be received from wipe.")
// }
// )
// .store(in: &cancellables)
//
// await fulfillment(of: [wipeFinished], timeout: 1)
//
// /*
// Check that wipe cleared everything that is expected
// */
// await checkThatWipeWorked()
// }
func testWipeCalledWhichSyncDoesntRun() async throws {
/*
create fake chain
*/
let fullSyncLength = 1000
// func testWipeCalledWhileSyncRuns() async throws {
// /*
// 1. create fake chain
// */
// let fullSyncLength = 50_000
//
// try FakeChainBuilder.buildChain(darksideWallet: coordinator.service, branchID: branchID, chainName: chainName, length: fullSyncLength)
//
// try coordinator.applyStaged(blockheight: birthday + fullSyncLength)
//
// sleep(5)
//
// /*
// Start sync
// */
// try await coordinator.sync(
// completion: { _ in
// XCTFail("Sync should have stopped")
// },
// error: self.handleError
// )
//
// try await Task.sleep(nanoseconds: 2_000_000_000)
//
// // Just to be sure that blockProcessor is still syncing and that this test does what it should.
// let blockProcessorState = await coordinator.synchronizer.blockProcessor.state
// XCTAssertEqual(blockProcessorState, .syncing)
//
// let wipeFinished = XCTestExpectation(description: "SynchronizerWipeFinished Expectation")
// /*
// Call wipe
// */
// coordinator.synchronizer.wipe()
// .sink(
// receiveCompletion: { completion in
// switch completion {
// case .finished:
// wipeFinished.fulfill()
//
// case .failure(let error):
// XCTFail("Wipe should finish successfully. \(error)")
// }
// },
// receiveValue: {
// XCTFail("No no value should be received from wipe.")
// }
// )
// .store(in: &cancellables)
//
// await fulfillment(of: [wipeFinished], timeout: 6)
//
// /*
// Check that wipe cleared everything that is expected
// */
// try await checkThatWipeWorked()
// }
try FakeChainBuilder.buildChain(darksideWallet: coordinator.service, branchID: branchID, chainName: chainName, length: fullSyncLength)
// private func checkThatWipeWorked() async throws {
// let storage = await self.coordinator.synchronizer.blockProcessor.storage as! FSCompactBlockRepository
// let fm = FileManager.default
// print(coordinator.synchronizer.initializer.dataDbURL.path)
//
// XCTAssertFalse(fm.fileExists(atPath: coordinator.synchronizer.initializer.dataDbURL.path), "Data DB should be deleted.")
// XCTAssertTrue(fm.fileExists(atPath: storage.blocksDirectory.path), "FS Cache directory should exist")
// XCTAssertEqual(try fm.contentsOfDirectory(atPath: storage.blocksDirectory.path), [], "FS Cache directory should be empty")
//
// let internalSyncProgress = coordinator.synchronizer.internalSyncProgress
//
// let latestDownloadedBlockHeight = try await internalSyncProgress.load(.latestDownloadedBlockHeight)
// let latestEnhancedHeight = try await internalSyncProgress.load(.latestEnhancedHeight)
// let latestUTXOFetchedHeight = try await internalSyncProgress.load(.latestUTXOFetchedHeight)
//
// XCTAssertEqual(latestDownloadedBlockHeight, 0, "internalSyncProgress latestDownloadedBlockHeight should be 0")
// XCTAssertEqual(latestEnhancedHeight, 0, "internalSyncProgress latestEnhancedHeight should be 0")
// XCTAssertEqual(latestUTXOFetchedHeight, 0, "internalSyncProgress latestUTXOFetchedHeight should be 0")
//
// let blockProcessorState = await coordinator.synchronizer.blockProcessor.state
// XCTAssertEqual(blockProcessorState, .stopped, "CompactBlockProcessor state should be stopped")
//
// let status = await coordinator.synchronizer.status
// XCTAssertEqual(status, .unprepared, "SDKSynchronizer state should be unprepared")
// }
try coordinator.applyStaged(blockheight: birthday + fullSyncLength)
sleep(2)
let syncFinished = XCTestExpectation(description: "SynchronizerSyncFinished Expectation")
/*
sync to latest height
*/
try await coordinator.sync(
completion: { _ in
syncFinished.fulfill()
},
error: handleError
)
await fulfillment(of: [syncFinished], timeout: 3)
let wipeFinished = XCTestExpectation(description: "SynchronizerWipeFinished Expectation")
/*
Call wipe
*/
coordinator.synchronizer.wipe()
.sink(
receiveCompletion: { completion in
switch completion {
case .finished:
wipeFinished.fulfill()
case .failure(let error):
XCTFail("Wipe should finish successfully. \(error)")
}
},
receiveValue: {
XCTFail("No no value should be received from wipe.")
}
)
.store(in: &cancellables)
await fulfillment(of: [wipeFinished], timeout: 1)
/*
Check that wipe cleared everything that is expected
*/
try await checkThatWipeWorked()
}
func testWipeCalledWhileSyncRuns() async throws {
/*
1. create fake chain
*/
let fullSyncLength = 50_000
try FakeChainBuilder.buildChain(darksideWallet: coordinator.service, branchID: branchID, chainName: chainName, length: fullSyncLength)
try coordinator.applyStaged(blockheight: birthday + fullSyncLength)
sleep(5)
/*
Start sync
*/
try await coordinator.sync(
completion: { _ in
XCTFail("Sync should have stopped")
},
error: self.handleError
)
try await Task.sleep(nanoseconds: 2_000_000_000)
// Just to be sure that blockProcessor is still syncing and that this test does what it should.
let synchronizerState = coordinator.synchronizer.latestState.syncStatus
switch synchronizerState {
case .syncing:
break
default:
XCTFail("Synchornizer should be in syncing state.")
}
let wipeFinished = XCTestExpectation(description: "SynchronizerWipeFinished Expectation")
/*
Call wipe
*/
coordinator.synchronizer.wipe()
.sink(
receiveCompletion: { completion in
switch completion {
case .finished:
wipeFinished.fulfill()
case .failure(let error):
XCTFail("Wipe should finish successfully. \(error)")
}
},
receiveValue: {
XCTFail("No no value should be received from wipe.")
}
)
.store(in: &cancellables)
await fulfillment(of: [wipeFinished], timeout: 6)
/*
Check that wipe cleared everything that is expected
*/
try await checkThatWipeWorked()
}
private func checkThatWipeWorked() async throws {
let storage = await self.coordinator.synchronizer.blockProcessor.storage as! FSCompactBlockRepository
let fm = FileManager.default
print(coordinator.synchronizer.initializer.dataDbURL.path)
XCTAssertFalse(fm.fileExists(atPath: coordinator.synchronizer.initializer.dataDbURL.path), "Data DB should be deleted.")
XCTAssertTrue(fm.fileExists(atPath: storage.blocksDirectory.path), "FS Cache directory should exist")
XCTAssertEqual(try fm.contentsOfDirectory(atPath: storage.blocksDirectory.path), [], "FS Cache directory should be empty")
let internalSyncProgress = coordinator.synchronizer.internalSyncProgress
let latestDownloadedBlockHeight = try await internalSyncProgress.load(.latestDownloadedBlockHeight)
let latestEnhancedHeight = try await internalSyncProgress.load(.latestEnhancedHeight)
let latestUTXOFetchedHeight = try await internalSyncProgress.load(.latestUTXOFetchedHeight)
XCTAssertEqual(latestDownloadedBlockHeight, 0, "internalSyncProgress latestDownloadedBlockHeight should be 0")
XCTAssertEqual(latestEnhancedHeight, 0, "internalSyncProgress latestEnhancedHeight should be 0")
XCTAssertEqual(latestUTXOFetchedHeight, 0, "internalSyncProgress latestUTXOFetchedHeight should be 0")
let status = await coordinator.synchronizer.status
XCTAssertEqual(status, .unprepared, "SDKSynchronizer state should be unprepared")
}
func handleError(_ error: Error?) async {
_ = try? await coordinator.stop()