Skip to content

Commit

Permalink
fix: add post migration to trigger sync resources - WPB-14794 (#2240)
Browse files Browse the repository at this point in the history
Co-authored-by: François Benaiteau <netbe@users.noreply.github.com>
  • Loading branch information
github-actions[bot] and netbe authored Dec 4, 2024
1 parent a2bf418 commit 7a7574d
Show file tree
Hide file tree
Showing 20 changed files with 640 additions and 36 deletions.
4 changes: 4 additions & 0 deletions wire-ios-data-model/Resources/Databases Changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ As it is hard to spot changes from version to version of database models (.xcdat

## zmessaging

### 2.120.0

PostAction to fix issue with federation migration. It triggers a resyncResources to make sure users and conversations get the domain.

### 2.119.0

* removed phoneNumber from User entity
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@
<plist version="1.0">
<dict>
<key>_XCCurrentVersionName</key>
<string>zmessaging2.119.0.xcdatamodel</string>
<string>zmessaging2.120.0.xcdatamodel</string>
</dict>
</plist>

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions wire-ios-data-model/Source/MLS/SyncStatusProtocol.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import Foundation
public protocol SyncStatusProtocol {

func performQuickSync() async
func resyncResources()
func forceSlowSync()

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
//
// Wire
// Copyright (C) 2024 Wire Swiss GmbH
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see http://www.gnu.org/licenses/.
//

import Foundation

final class ForceSyncResourcesPostAction: CoreDataMigrationAction {

override func execute(in context: NSManagedObjectContext) {
do {
try context.setMigrationNeedsSyncResources()
} catch {
WireLogger.localStorage.error(
"Failed to trigger syncResources for federation migration issue: \(error.localizedDescription)",
attributes: .safePublic
)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ enum CoreDataMessagingMigrationVersion: String, CoreDataMigrationVersion {
// MARK: -

// Note: add new versions here in first position!
case v120 = "zmessaging2.120.0"
case v119 = "zmessaging2.119.0"
case v118 = "zmessaging2.118.0"
case v117 = "zmessaging2.117.0"
Expand Down Expand Up @@ -72,8 +73,10 @@ enum CoreDataMessagingMigrationVersion: String, CoreDataMigrationVersion {

var nextVersion: Self? {
switch self {
case .v119:
case .v120:
nil
case .v119:
.v120
case .v116, .v117, .v118:
.v119
case .v115,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,9 @@ enum CoreDataMigrationActionFactory {
static func createPostMigrationAction(for destinationVersion: CoreDataMessagingMigrationVersion)
-> CoreDataMigrationAction? {
switch destinationVersion {
case .v120:
ForceSyncResourcesPostAction()

case .v119:
FixDuplicateOneOnOneConversationsAction()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,15 @@ public extension NSManagedObjectContext {
}

/// checks if we need a slowSync after migrations
/// - Note: this cleans up after reading the value
func readAndResetSlowSyncFlag() -> Bool {
func readMigrationNeedsSlowSyncFlag() -> Bool {
let value = (persistentStoreMetadata(forKey: migrationsNeedToSlowSyncKey) as? Int) ?? 0
setPersistentStoreMetadata(Int?.none, key: migrationsNeedToSlowSyncKey)
return value == 1
}

/// Reset migration needs slow sync flag
func resetMigrationNeedsSlowSyncFlagIfNeeded() {
if readMigrationNeedsSlowSyncFlag() {
setPersistentStoreMetadata(Int?.none, key: migrationsNeedToSlowSyncKey)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
//
// Wire
// Copyright (C) 2024 Wire Swiss GmbH
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see http://www.gnu.org/licenses/.
//

import Foundation

// This contains some methods to pass the information through the persistence store metadata
// that we need a sync resources after
public extension NSManagedObjectContext {

private var migrationsNeedToSyncResourcesKey: String {
"migrationsNeedToSyncResources"
}

internal enum migrationsNeedToSyncResourcesError: Error {
case couldNotPersistMetadata
}

/// use to trigger sync resources after some CoreData migrations
func setMigrationNeedsSyncResources() throws {
setPersistentStoreMetadata(1, key: migrationsNeedToSyncResourcesKey)
if !makeMetadataPersistent() {
throw MigrationNeedsSlowSyncError.couldNotPersistMetadata
}
}

/// checks if we need a syncResources after migrations
func readMigrationNeedsSyncResourcesFlag() -> Bool {
let value = (persistentStoreMetadata(forKey: migrationsNeedToSyncResourcesKey) as? Int) ?? 0
return value == 1
}

/// Reset migration needs syncResources flag
func resetMigrationNeedsSyncResoucesFlagIfNeeded() {
if readMigrationNeedsSyncResourcesFlag() {
setPersistentStoreMetadata(Int?.none, key: migrationsNeedToSyncResourcesKey)
}
}
}
9 changes: 9 additions & 0 deletions wire-ios-data-model/Tests/MLS/MockSyncStatus.swift
Original file line number Diff line number Diff line change
Expand Up @@ -38,4 +38,13 @@ class MockSyncStatus: SyncStatusProtocol {
await mock()
}

var mockResyncResources: (() -> Void)?
func resyncResources() {
guard let mock = mockResyncResources else {
fatalError("no mock for `resyncResources`")
}

mock()
}

}
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,28 @@ final class CoreDataMigrationActionFactoryTests: XCTestCase {

// add version with actions here - aka custom migration
let excludedVersions: [CoreDataMessagingMigrationVersion] = [
.v120,
.v119,
.v116,
.v114,
.v111,
.v107
]

// MARK: - Version 120

func test_createPostMigrationAction_ReturnsPostActionForVersion120() {
let action = CoreDataMigrationActionFactory.createPostMigrationAction(for: .v120)

XCTAssertNotNil(action)
}

func test_createPostMigrationAction_ReturnsNoPreActionForVersion120() {
let action = CoreDataMigrationActionFactory.createPreMigrationAction(for: .v120)

XCTAssertNil(action)
}

// MARK: - Version 119

func test_ItReturnsPreActionForVersion119() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -151,9 +151,7 @@ final class DatabaseMigrationTests_ConversationUniqueness: XCTestCase {
conversations = try fetchConversations(with: conversationId, domain: domain, in: context)
XCTAssertEqual(conversations.count, 1)

XCTAssertTrue(context.readAndResetSlowSyncFlag())
// the flag has been consumed
XCTAssertFalse(context.readAndResetSlowSyncFlag())
XCTAssertTrue(context.readMigrationNeedsSlowSyncFlag())
}
},
for: self
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
//
// Wire
// Copyright (C) 2024 Wire Swiss GmbH
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see http://www.gnu.org/licenses/.
//

import Foundation
import XCTest
@testable import WireDataModel

final class DatabaseMigrationTests_ForceSyncResources: XCTestCase {

private let bundle = Bundle(for: ZMManagedObject.self)
private let teamId = UUID()
private let tmpStoreURL =
URL(fileURLWithPath: "\(NSTemporaryDirectory())DatabaseMigrationTests_ForceSyncResources/")
private let helper = DatabaseMigrationHelper()

override func setUpWithError() throws {
try super.setUpWithError()
try FileManager.default.createDirectory(at: tmpStoreURL, withIntermediateDirectories: true)
}

override func tearDownWithError() throws {
try? FileManager.default.removeItem(at: tmpStoreURL)
try super.tearDownWithError()
}

func testThatItPerformsMigrationFrom119Version_ToCurrentModelVersion() throws {
let initialVersion = "2.119.0"

try helper.migrateStoreToCurrentVersion(
sourceVersion: initialVersion,
preMigrationAction: { _ in
// nothing
},
postMigrationAction: { context in
try context.performAndWait {
// verify
XCTAssertTrue(context.readMigrationNeedsSyncResourcesFlag())
}
},
for: self
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -64,10 +64,7 @@ final class DatabaseMigrationTests_TeamUniqueness: XCTestCase {
teams = try fetchTeams(with: teamId, in: context)
XCTAssertEqual(teams.count, 1)

XCTAssertTrue(context.readAndResetSlowSyncFlag())
// the flag has been consumed
XCTAssertFalse(context.readAndResetSlowSyncFlag())

XCTAssertTrue(context.readMigrationNeedsSlowSyncFlag())
}
},
for: self
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -126,9 +126,7 @@ final class DatabaseMigrationTests_UserUniqueness: XCTestCase {
clients = try fetchUsers(with: userId, domain: domain, in: context)
XCTAssertEqual(clients.count, 1)

XCTAssertTrue(context.readAndResetSlowSyncFlag())
// the flag has been consumed
XCTAssertFalse(context.readAndResetSlowSyncFlag())
XCTAssertTrue(context.readMigrationNeedsSlowSyncFlag())
}
},
for: self
Expand Down
Loading

0 comments on commit 7a7574d

Please sign in to comment.