reconcile jobqueue tests with NSTimer based retry

This commit is contained in:
Michael Kirk 2018-11-10 20:27:28 -06:00
parent 4971be5c26
commit 7cba367c0a
4 changed files with 50 additions and 17 deletions

View File

@ -202,10 +202,6 @@ public class MessageSenderOperation: OWSOperation, DurableOperation {
}
override public func retryInterval() -> TimeInterval {
guard !CurrentAppContext().isRunningTests else {
return 0
}
// Arbitrary backoff factor...
// With backOffFactor of 1.9
// try 1 delay: 0.00s

View File

@ -14,15 +14,14 @@ NS_ASSUME_NONNULL_BEGIN
success:(void (^)(void))successHandler
failure:(void (^)(NSError *error))failureHandler
{
if (self.sendMessageWasCalledBlock) {
self.sendMessageWasCalledBlock(message);
}
if (self.stubbedFailingError) {
failureHandler(self.stubbedFailingError);
} else {
successHandler();
}
if (self.sendMessageWasCalledBlock) {
self.sendMessageWasCalledBlock(message);
}
}
- (void)sendAttachment:(DataSource *)dataSource
@ -32,15 +31,14 @@ NS_ASSUME_NONNULL_BEGIN
success:(void (^)(void))successHandler
failure:(void (^)(NSError *error))failureHandler
{
if (self.sendAttachmentWasCalledBlock) {
self.sendAttachmentWasCalledBlock(outgoingMessage);
}
if (self.stubbedFailingError) {
failureHandler(self.stubbedFailingError);
} else {
successHandler();
}
if (self.sendAttachmentWasCalledBlock) {
self.sendAttachmentWasCalledBlock(outgoingMessage);
}
}
- (void)sendTemporaryAttachment:(DataSource *)dataSource
@ -49,15 +47,14 @@ NS_ASSUME_NONNULL_BEGIN
success:(void (^)(void))successHandler
failure:(void (^)(NSError *error))failureHandler
{
if (self.sendTemporaryAttachmentWasCalledBlock) {
self.sendTemporaryAttachmentWasCalledBlock(outgoingMessage);
}
if (self.stubbedFailingError) {
failureHandler(self.stubbedFailingError);
} else {
successHandler();
}
if (self.sendTemporaryAttachmentWasCalledBlock) {
self.sendTemporaryAttachmentWasCalledBlock(outgoingMessage);
}
}

View File

@ -26,6 +26,23 @@ public extension Error {
}
}
extension SSKJobRecordStatus: CustomStringConvertible {
public var description: String {
switch self {
case .ready:
return "ready"
case .unknown:
return "unknown"
case .running:
return "running"
case .permanentlyFailed:
return "permanentlyFailed"
case .obsolete:
return "obsolete"
}
}
}
public enum JobError: Error {
case assertionFailure(description: String)
case obsolete(description: String)
@ -251,7 +268,16 @@ public extension JobQueue {
return
}
self.runningOperations.first?.operation.runAnyQueuedRetry()
_ = self.runAnyQueuedRetry()
}
func runAnyQueuedRetry() -> DurableOperationType? {
guard let runningDurableOperation = self.runningOperations.first else {
return nil
}
runningDurableOperation.operation.runAnyQueuedRetry()
return runningDurableOperation
}
// MARK: DurableOperationDelegate

View File

@ -143,6 +143,16 @@ class MessageSenderJobQueueTest: SSKBaseTestSwift {
let retryCount: UInt = MessageSenderJobQueue.maxRetries
(1..<retryCount).forEach { _ in
let expectedResend = sentExpectation(message: message)
// Manually kick queue restart.
//
// OWSOperation uses an NSTimer backed retry mechanism, but NSTimer's are not fired
// during `self.wait(for:,timeout:` unless the timer was scheduled on the
// `RunLoop.main`.
//
// We could move the timer to fire on the main RunLoop (and have the selector dispatch
// back to a background queue), but the production code is simpler if we just manually
// kick every retry in the test case.
XCTAssertNotNil(jobQueue.runAnyQueuedRetry())
self.wait(for: [expectedResend], timeout: 0.1)
}
@ -155,6 +165,7 @@ class MessageSenderJobQueueTest: SSKBaseTestSwift {
// Verify final send fails permanently
let expectedFinalResend = sentExpectation(message: message)
XCTAssertNotNil(jobQueue.runAnyQueuedRetry())
self.wait(for: [expectedFinalResend], timeout: 0.1)
self.readWrite { transaction in
@ -163,6 +174,9 @@ class MessageSenderJobQueueTest: SSKBaseTestSwift {
XCTAssertEqual(retryCount + 1, jobRecord.failureCount)
XCTAssertEqual(.permanentlyFailed, jobRecord.status)
// No remaining retries
XCTAssertNil(jobQueue.runAnyQueuedRetry())
}
func test_permanentFailure() {