From 6f7f1b3b086f791051a70a4d2ce0359951e84806 Mon Sep 17 00:00:00 2001 From: Matthew Chen Date: Mon, 29 Jan 2018 10:11:19 -0500 Subject: [PATCH] Improve pre-migration testing tools. --- Signal/src/AppDelegate.m | 20 ++++----- .../ViewControllers/DebugUI/DebugUIMessages.m | 42 ++++++++++++++----- .../src/Storage/TSStorageManager.m | 4 ++ SignalServiceKit/src/Util/OWSFileSystem.h | 2 + SignalServiceKit/src/Util/OWSFileSystem.m | 14 +++++++ 5 files changed, 61 insertions(+), 21 deletions(-) diff --git a/Signal/src/AppDelegate.m b/Signal/src/AppDelegate.m index fd644f29c..01a727334 100644 --- a/Signal/src/AppDelegate.m +++ b/Signal/src/AppDelegate.m @@ -785,16 +785,16 @@ static NSString *const kURLHostVerifyPrefix = @"verify"; self.isEnvironmentSetup = YES; -#ifdef DEBUG - // A bug in orphan cleanup could be disastrous so let's only - // run it in DEBUG builds for a few releases. - // - // TODO: Release to production once we have analytics. - // TODO: Orphan cleanup is somewhat expensive - not least in doing a bunch - // of disk access. We might want to only run it "once per version" - // or something like that in production. - [OWSOrphanedDataCleaner auditAndCleanupAsync:nil]; -#endif + //#ifdef DEBUG + // // A bug in orphan cleanup could be disastrous so let's only + // // run it in DEBUG builds for a few releases. + // // + // // TODO: Release to production once we have analytics. + // // TODO: Orphan cleanup is somewhat expensive - not least in doing a bunch + // // of disk access. We might want to only run it "once per version" + // // or something like that in production. + // [OWSOrphanedDataCleaner auditAndCleanupAsync:nil]; + //#endif [OWSProfileManager.sharedManager fetchLocalUsersProfile]; [[OWSReadReceiptManager sharedManager] prepareCachedValues]; diff --git a/Signal/src/ViewControllers/DebugUI/DebugUIMessages.m b/Signal/src/ViewControllers/DebugUI/DebugUIMessages.m index 9f3ba3cd3..4c7692cf6 100644 --- a/Signal/src/ViewControllers/DebugUI/DebugUIMessages.m +++ b/Signal/src/ViewControllers/DebugUI/DebugUIMessages.m @@ -128,6 +128,10 @@ NS_ASSUME_NONNULL_BEGIN actionBlock:^{ [DebugUIMessages sendFakeMessages:100 * 1000 thread:thread]; }], + [OWSTableItem itemWithTitle:@"Create 100k fake text messages" + actionBlock:^{ + [DebugUIMessages sendFakeMessages:100 * 1000 thread:thread isTextOnly:YES]; + }], [OWSTableItem itemWithTitle:@"Create 1 fake unread messages" actionBlock:^{ [DebugUIMessages createFakeUnreadMessages:1 thread:thread]; @@ -983,27 +987,42 @@ NS_ASSUME_NONNULL_BEGIN + (void)sendFakeMessages:(NSUInteger)counter thread:(TSThread *)thread { - NSUInteger remainder = counter; - while (remainder > 0) { - NSUInteger batchSize = MIN((NSUInteger)2500, remainder); - [TSStorageManager.dbReadWriteConnection - readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { - [self sendFakeMessages:counter thread:thread transaction:transaction]; - }]; - remainder -= batchSize; - DDLogInfo(@"%@ sendFakeMessages %zd / %zd", self.logTag, counter - remainder, counter); + [self sendFakeMessages:counter thread:thread isTextOnly:NO]; +} + ++ (void)sendFakeMessages:(NSUInteger)counter thread:(TSThread *)thread isTextOnly:(BOOL)isTextOnly +{ + const NSUInteger kMaxBatchSize = 2500; + if (counter < kMaxBatchSize) { + [TSStorageManager.dbReadWriteConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { + [self sendFakeMessages:counter thread:thread isTextOnly:isTextOnly transaction:transaction]; + }]; + } else { + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ + NSUInteger remainder = counter; + while (remainder > 0) { + NSUInteger batchSize = MIN(kMaxBatchSize, remainder); + [TSStorageManager.dbReadWriteConnection + readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { + [self sendFakeMessages:batchSize thread:thread isTextOnly:isTextOnly transaction:transaction]; + }]; + remainder -= batchSize; + DDLogInfo(@"%@ sendFakeMessages %zd / %zd", self.logTag, counter - remainder, counter); + } + }); } } + (void)sendFakeMessages:(NSUInteger)counter thread:(TSThread *)thread + isTextOnly:(BOOL)isTextOnly transaction:(YapDatabaseReadWriteTransaction *)transaction { DDLogInfo(@"%@ sendFakeMessages: %zd", self.logTag, counter); for (NSUInteger i = 0; i < counter; i++) { NSString *randomText = [self randomText]; - switch (arc4random_uniform(4)) { + switch (arc4random_uniform(isTextOnly ? 2 : 4)) { case 0: { TSIncomingMessage *message = [[TSIncomingMessage alloc] initWithTimestamp:[NSDate ows_millisecondTimeStamp] @@ -1038,6 +1057,7 @@ NS_ASSUME_NONNULL_BEGIN relay:@"" sourceFilename:@"test.mp3" attachmentType:TSAttachmentTypeDefault]; + pointer.state = TSAttachmentPointerStateFailed; [pointer saveWithTransaction:transaction]; TSIncomingMessage *message = [[TSIncomingMessage alloc] initWithTimestamp:[NSDate ows_millisecondTimeStamp] @@ -1280,7 +1300,7 @@ NS_ASSUME_NONNULL_BEGIN }, ^(YapDatabaseReadWriteTransaction *transaction) { NSUInteger messageCount = (NSUInteger)(1 + arc4random_uniform(4)); - [self sendFakeMessages:messageCount thread:thread transaction:transaction]; + [self sendFakeMessages:messageCount thread:thread isTextOnly:NO transaction:transaction]; }, ^(YapDatabaseReadWriteTransaction *transaction) { NSUInteger messageCount = (NSUInteger)(1 + arc4random_uniform(4)); diff --git a/SignalServiceKit/src/Storage/TSStorageManager.m b/SignalServiceKit/src/Storage/TSStorageManager.m index f77ebec86..23b1c3295 100644 --- a/SignalServiceKit/src/Storage/TSStorageManager.m +++ b/SignalServiceKit/src/Storage/TSStorageManager.m @@ -141,6 +141,10 @@ void runAsyncRegistrationsForStorage(OWSStorage *storage) + (void)protectFiles { + DDLogInfo(@"%@ Database file size: %@", self.logTag, [OWSFileSystem fileSizeOfPath:self.legacyDatabaseFilePath]); + DDLogInfo(@"%@ \t SHM file size: %@", self.logTag, [OWSFileSystem fileSizeOfPath:self.legacyDatabaseFilePath_SHM]); + DDLogInfo(@"%@ \t WAL file size: %@", self.logTag, [OWSFileSystem fileSizeOfPath:self.legacyDatabaseFilePath_WAL]); + // The old database location was in the Document directory, // so protect the database files individually. [OWSFileSystem protectFileOrFolderAtPath:self.legacyDatabaseFilePath]; diff --git a/SignalServiceKit/src/Util/OWSFileSystem.h b/SignalServiceKit/src/Util/OWSFileSystem.h index cf6f091ce..d81d94fb3 100644 --- a/SignalServiceKit/src/Util/OWSFileSystem.h +++ b/SignalServiceKit/src/Util/OWSFileSystem.h @@ -35,6 +35,8 @@ NS_ASSUME_NONNULL_BEGIN // Returns nil on failure. + (nullable NSString *)writeDataToTemporaryFile:(NSData *)data fileExtension:(NSString *_Nullable)fileExtension; ++ (nullable NSNumber *)fileSizeOfPath:(NSString *)filePath; + @end NS_ASSUME_NONNULL_END diff --git a/SignalServiceKit/src/Util/OWSFileSystem.m b/SignalServiceKit/src/Util/OWSFileSystem.m index bd089cca6..a95ae4395 100644 --- a/SignalServiceKit/src/Util/OWSFileSystem.m +++ b/SignalServiceKit/src/Util/OWSFileSystem.m @@ -200,6 +200,20 @@ NS_ASSUME_NONNULL_BEGIN return tempFilePath; } ++ (nullable NSNumber *)fileSizeOfPath:(NSString *)filePath +{ + NSFileManager *fileManager = [NSFileManager defaultManager]; + NSError *_Nullable error; + unsigned long long fileSize = + [[fileManager attributesOfItemAtPath:filePath error:&error][NSFileSize] unsignedLongLongValue]; + if (error) { + DDLogError(@"%@ Couldn't fetch file size[%@]: %@", self.logTag, filePath, error); + return nil; + } else { + return @(fileSize); + } +} + @end NS_ASSUME_NONNULL_END