Ver Fonte

[Swift 6] Add Swift 6 testing for CoreInternal (#14561)

Nick Cooke há 1 ano atrás
pai
commit
82c6c555fc

+ 10 - 0
.github/workflows/core_internal.yml

@@ -21,8 +21,13 @@ jobs:
         build-env:
           - os: macos-14
             xcode: Xcode_15.2
+            swift_version: 5.9
           - os: macos-15
             xcode: Xcode_16.2
+            swift_version: 5.9
+          - os: macos-15
+            xcode: Xcode_16.2
+            swift_version: 6.0
     runs-on: ${{ matrix.build-env.os }}
     steps:
     - uses: actions/checkout@v4
@@ -31,6 +36,8 @@ jobs:
       run: scripts/setup_bundler.sh
     - name: Xcode
       run: sudo xcode-select -s /Applications/${{ matrix.build-env.xcode }}.app/Contents/Developer
+    - name: Set Swift swift_version
+      run: sed -i "" "s/s.swift_version[[:space:]]*=[[:space:]]*'5.9'/s.swift_version = '${{ matrix.build-env.swift_version }}'/" FirebaseCoreInternal.podspec
     - name: Build and test
       run: scripts/third_party/travis/retry.sh scripts/pod_lib_lint.rb FirebaseCoreInternal.podspec --platforms=${{ matrix.target }}
 
@@ -99,6 +106,9 @@ jobs:
       run: scripts/setup_spm_tests.sh
     - name: Xcode
       run: sudo xcode-select -s /Applications/${{ matrix.xcode }}.app/Contents/Developer
+    - name: Install visionOS, if needed.
+      if: matrix.target == 'visionOS'
+      run: xcodebuild -downloadPlatform visionOS
     - name: FirebaseCoreInternalTests
       run: scripts/third_party/travis/retry.sh ./scripts/build.sh FirebaseCoreInternalTests ${{ matrix.target }} spm
 

+ 51 - 59
FirebaseCore/Internal/Tests/Integration/HeartbeatLoggingIntegrationTests.swift

@@ -16,9 +16,6 @@
 import XCTest
 
 class HeartbeatLoggingIntegrationTests: XCTestCase {
-  // 2021-11-01 @ 00:00:00 (EST)
-  let date = Date(timeIntervalSince1970: 1_635_739_200)
-
   override func setUpWithError() throws {
     try HeartbeatLoggingTestUtils.removeUnderlyingHeartbeatStorageContainers()
   }
@@ -52,7 +49,7 @@ class HeartbeatLoggingIntegrationTests: XCTestCase {
     )
   }
 
-  func testLogAndFlushAsync() throws {
+  @MainActor func testLogAndFlushAsync() throws {
     // Given
     let heartbeatController = HeartbeatController(id: #function)
     let expectedDate = HeartbeatsPayload.dateFormatter.string(from: Date())
@@ -123,8 +120,9 @@ class HeartbeatLoggingIntegrationTests: XCTestCase {
 
   func testMultipleControllersWithTheSameIDUseTheSameStorageInstance() throws {
     // Given
-    let heartbeatController1 = HeartbeatController(id: #function, dateProvider: { self.date })
-    let heartbeatController2 = HeartbeatController(id: #function, dateProvider: { self.date })
+    let date = Date(timeIntervalSince1970: 1_635_739_200) // 2021-11-01 @ 00:00:00 (EST)
+    let heartbeatController1 = HeartbeatController(id: #function, dateProvider: { date })
+    let heartbeatController2 = HeartbeatController(id: #function, dateProvider: { date })
     // When
     heartbeatController1.log("dummy_agent")
     // Then
@@ -146,92 +144,85 @@ class HeartbeatLoggingIntegrationTests: XCTestCase {
     assertHeartbeatControllerFlushesEmptyPayload(heartbeatController1)
   }
 
-  func testLogAndFlushConcurrencyStressTest() throws {
+  @MainActor func testLogAndFlushConcurrencyStressTest() throws {
     // Given
-    let heartbeatController = HeartbeatController(id: #function, dateProvider: { self.date })
+    let date = Date(timeIntervalSince1970: 1_635_739_200) // 2021-11-01 @ 00:00:00 (EST)
+    let heartbeatController = HeartbeatController(id: #function, dateProvider: { date })
 
     // When
     DispatchQueue.concurrentPerform(iterations: 100) { _ in
       heartbeatController.log("dummy_agent")
     }
 
-    var payloads: [HeartbeatsPayload] = []
+    let expectation = self.expectation(description: #function)
 
     DispatchQueue.concurrentPerform(iterations: 100) { _ in
       let payload = heartbeatController.flush()
-      payloads.append(payload)
-    }
-
-    // Then
-    let nonEmptyPayloads = payloads.filter { payload in
-      // Filter out non-empty payloads.
-      !payload.userAgentPayloads.isEmpty
-    }
-
-    XCTAssertEqual(nonEmptyPayloads.count, 1)
-
-    let payload = try XCTUnwrap(nonEmptyPayloads.first)
-    try HeartbeatLoggingTestUtils.assertEqualPayloadStrings(
-      payload.headerValue(),
-      """
-      {
-        "version": 2,
-        "heartbeats": [
+      if !payload.userAgentPayloads.isEmpty {
+        try! HeartbeatLoggingTestUtils.assertEqualPayloadStrings(
+          payload.headerValue(),
+          """
           {
-            "agent": "dummy_agent",
-            "dates": ["2021-11-01"]
+            "version": 2,
+            "heartbeats": [
+              {
+                "agent": "dummy_agent",
+                "dates": ["2021-11-01"]
+              }
+            ]
           }
-        ]
+          """
+        )
+        expectation.fulfill()
       }
-      """
-    )
+    }
+
+    // Then
+    wait(for: [expectation])
   }
 
-  func testLogAndFlushHeartbeatFromTodayConcurrencyStressTest() throws {
+  @MainActor func testLogAndFlushHeartbeatFromTodayConcurrencyStressTest() throws {
     // Given
-    let heartbeatController = HeartbeatController(id: #function, dateProvider: { self.date })
+    let date = Date(timeIntervalSince1970: 1_635_739_200) // 2021-11-01 @ 00:00:00 (EST)
+    let heartbeatController = HeartbeatController(id: #function, dateProvider: { date })
 
     // When
     DispatchQueue.concurrentPerform(iterations: 100) { _ in
       heartbeatController.log("dummy_agent")
     }
 
-    var payloads: [HeartbeatsPayload] = []
+    let expectation = self.expectation(description: #function)
 
     DispatchQueue.concurrentPerform(iterations: 100) { _ in
       let payload = heartbeatController.flushHeartbeatFromToday()
-      payloads.append(payload)
-    }
-
-    // Then
-    let nonEmptyPayloads = payloads.filter { payload in
-      // Filter out non-empty payloads.
-      !payload.userAgentPayloads.isEmpty
-    }
-
-    XCTAssertEqual(nonEmptyPayloads.count, 1)
-
-    let payload = try XCTUnwrap(nonEmptyPayloads.first)
-    try HeartbeatLoggingTestUtils.assertEqualPayloadStrings(
-      payload.headerValue(),
-      """
-      {
-        "version": 2,
-        "heartbeats": [
+      if !payload.userAgentPayloads.isEmpty {
+        try! HeartbeatLoggingTestUtils.assertEqualPayloadStrings(
+          payload.headerValue(),
+          """
           {
-            "agent": "dummy_agent",
-            "dates": ["2021-11-01"],
+            "version": 2,
+            "heartbeats": [
+              {
+                "agent": "dummy_agent",
+                "dates": ["2021-11-01"],
+              }
+            ]
           }
-        ]
+          """
+        )
+        expectation.fulfill()
       }
-      """
-    )
+    }
+
+    // Then
+    wait(for: [expectation])
 
     assertHeartbeatControllerFlushesEmptyPayload(heartbeatController)
   }
 
   func testLogRepeatedly_WithoutFlushing_LimitsOnWrite() throws {
     // Given
+    let date = Date(timeIntervalSince1970: 1_635_739_200) // 2021-11-01 @ 00:00:00 (EST)
     let testDate = AdjustableDate(date: date)
     let heartbeatController = HeartbeatController(id: #function, dateProvider: { testDate.date })
 
@@ -313,7 +304,8 @@ class HeartbeatLoggingIntegrationTests: XCTestCase {
 
   func testLogAndFlush_AfterUnderlyingStorageIsDeleted_CreatesNewStorage() throws {
     // Given
-    let heartbeatController = HeartbeatController(id: #function, dateProvider: { self.date })
+    let date = Date(timeIntervalSince1970: 1_635_739_200) // 2021-11-01 @ 00:00:00 (EST)
+    let heartbeatController = HeartbeatController(id: #function, dateProvider: { date })
     heartbeatController.log("dummy_agent")
     _ = XCTWaiter.wait(for: [expectation(description: "Wait for async log.")], timeout: 0.1)
 

+ 14 - 9
FirebaseCore/Internal/Tests/Unit/HeartbeatControllerTests.swift

@@ -16,9 +16,6 @@
 import XCTest
 
 class HeartbeatControllerTests: XCTestCase {
-  // 2021-11-01 @ 00:00:00 (EST)
-  let date = Date(timeIntervalSince1970: 1_635_739_200)
-
   func testFlush_WhenEmpty_ReturnsEmptyPayload() throws {
     // Given
     let controller = HeartbeatController(storage: HeartbeatStorageFake())
@@ -28,9 +25,10 @@ class HeartbeatControllerTests: XCTestCase {
 
   func testLogAndFlush() throws {
     // Given
+    let date = Date(timeIntervalSince1970: 1_635_739_200) // 2021-11-01 @ 00:00:00 (EST)
     let controller = HeartbeatController(
       storage: HeartbeatStorageFake(),
-      dateProvider: { self.date }
+      dateProvider: { date }
     )
 
     assertHeartbeatControllerFlushesEmptyPayload(controller)
@@ -58,11 +56,12 @@ class HeartbeatControllerTests: XCTestCase {
     assertHeartbeatControllerFlushesEmptyPayload(controller)
   }
 
-  func testLogAndFlushAsync() throws {
+  @MainActor func testLogAndFlushAsync() throws {
     // Given
+    let date = Date(timeIntervalSince1970: 1_635_739_200) // 2021-11-01 @ 00:00:00 (EST)
     let controller = HeartbeatController(
       storage: HeartbeatStorageFake(),
-      dateProvider: { self.date }
+      dateProvider: { date }
     )
     let expectation = expectation(description: #function)
 
@@ -99,6 +98,7 @@ class HeartbeatControllerTests: XCTestCase {
 
   func testLogAtEndOfTimePeriodAndAcceptAtStartOfNextOne() throws {
     // Given
+    let date = Date(timeIntervalSince1970: 1_635_739_200) // 2021-11-01 @ 00:00:00 (EST)
     let testDate = AdjustableDate(date: date)
 
     let controller = HeartbeatController(
@@ -148,9 +148,10 @@ class HeartbeatControllerTests: XCTestCase {
 
   func testDoNotLogMoreThanOnceInACalendarDay() throws {
     // Given
+    let date = Date(timeIntervalSince1970: 1_635_739_200) // 2021-11-01 @ 00:00:00 (EST)
     let controller = HeartbeatController(
       storage: HeartbeatStorageFake(),
-      dateProvider: { self.date }
+      dateProvider: { date }
     )
 
     // When
@@ -178,9 +179,10 @@ class HeartbeatControllerTests: XCTestCase {
 
   func testDoNotLogMoreThanOnceInACalendarDay_AfterFlushing() throws {
     // Given
+    let date = Date(timeIntervalSince1970: 1_635_739_200) // 2021-11-01 @ 00:00:00 (EST)
     let controller = HeartbeatController(
       storage: HeartbeatStorageFake(),
-      dateProvider: { self.date }
+      dateProvider: { date }
     )
 
     // When
@@ -308,6 +310,7 @@ class HeartbeatControllerTests: XCTestCase {
 
   func testLoggingDependsOnDateNotUserAgent() throws {
     // Given
+    let date = Date(timeIntervalSince1970: 1_635_739_200) // 2021-11-01 @ 00:00:00 (EST)
     let testDate = AdjustableDate(date: date)
     let heartbeatController = HeartbeatController(
       storage: HeartbeatStorageFake(),
@@ -355,6 +358,7 @@ class HeartbeatControllerTests: XCTestCase {
 
   func testFlushHeartbeatFromToday_WhenTodayHasAHeartbeat_ReturnsPayloadWithOnlyTodaysHeartbeat() throws {
     // Given
+    let date = Date(timeIntervalSince1970: 1_635_739_200) // 2021-11-01 @ 00:00:00 (EST)
     let yesterdaysDate = date.addingTimeInterval(-1 * 60 * 60 * 24)
     let todaysDate = date
     let tomorrowsDate = date.addingTimeInterval(60 * 60 * 24)
@@ -416,7 +420,8 @@ class HeartbeatControllerTests: XCTestCase {
 
   func testFlushHeartbeatFromToday_WhenTodayDoesNotHaveAHeartbeat_ReturnsEmptyPayload() throws {
     // Given
-    let heartbeatController = HeartbeatController(id: #function, dateProvider: { self.date })
+    let date = Date(timeIntervalSince1970: 1_635_739_200) // 2021-11-01 @ 00:00:00 (EST)
+    let heartbeatController = HeartbeatController(id: #function, dateProvider: { date })
     // When
     heartbeatController.flushHeartbeatFromToday()
     // Then

+ 11 - 10
FirebaseCore/Internal/Tests/Unit/HeartbeatStorageTests.swift

@@ -16,11 +16,12 @@
 import XCTest
 
 extension HeartbeatsBundle {
-  static let testHeartbeatBundle: Self = {
+  static func testHeartbeatBundle() -> HeartbeatsBundle {
     var heartbeatBundle = HeartbeatsBundle(capacity: 1)
-    heartbeatBundle.append(Heartbeat(agent: "dummy_agent", date: Date()))
+    let date = Date(timeIntervalSince1970: 1_635_739_200) // 2021-11-01 @ 00:00:00 (EST)
+    heartbeatBundle.append(Heartbeat(agent: "dummy_agent", date: date))
     return heartbeatBundle
-  }()
+  }
 }
 
 class HeartbeatStorageTests: XCTestCase {
@@ -108,7 +109,7 @@ class HeartbeatStorageTests: XCTestCase {
       // Assert that heartbeat storage is empty.
       XCTAssertNil(heartbeatsBundle)
       // Write new value.
-      return HeartbeatsBundle.testHeartbeatBundle
+      return HeartbeatsBundle.testHeartbeatBundle()
     }
 
     heartbeatStorage.readAndWriteAsync { heartbeatsBundle in
@@ -116,7 +117,7 @@ class HeartbeatStorageTests: XCTestCase {
       // Assert old value is read.
       XCTAssertEqual(
         heartbeatsBundle?.makeHeartbeatsPayload(),
-        HeartbeatsBundle.testHeartbeatBundle.makeHeartbeatsPayload()
+        HeartbeatsBundle.testHeartbeatBundle().makeHeartbeatsPayload()
       )
       // Write some new value.
       return heartbeatsBundle
@@ -158,7 +159,7 @@ class HeartbeatStorageTests: XCTestCase {
 
     heartbeatStorage.readAndWriteAsync { heartbeatsBundle in
       expectation.fulfill()
-      return HeartbeatsBundle.testHeartbeatBundle
+      return HeartbeatsBundle.testHeartbeatBundle()
     }
 
     // Then
@@ -166,10 +167,10 @@ class HeartbeatStorageTests: XCTestCase {
       expectation.fulfill()
       XCTAssertNotEqual(
         heartbeatsBundle?.makeHeartbeatsPayload(),
-        HeartbeatsBundle.testHeartbeatBundle.makeHeartbeatsPayload(),
+        HeartbeatsBundle.testHeartbeatBundle().makeHeartbeatsPayload(),
         "They should not be equal because the previous save failed."
       )
-      return HeartbeatsBundle.testHeartbeatBundle
+      return HeartbeatsBundle.testHeartbeatBundle()
     }
 
     wait(for: [expectation], timeout: 0.5)
@@ -220,7 +221,7 @@ class HeartbeatStorageTests: XCTestCase {
       // Assert that heartbeat storage is empty.
       XCTAssertNil(heartbeatsBundle)
       // Write new value.
-      return HeartbeatsBundle.testHeartbeatBundle
+      return HeartbeatsBundle.testHeartbeatBundle()
     } completion: { result in
       switch result {
       case .success: break
@@ -236,7 +237,7 @@ class HeartbeatStorageTests: XCTestCase {
         // Assert old value is read.
         XCTAssertEqual(
           heartbeatsBundle?.makeHeartbeatsPayload(),
-          HeartbeatsBundle.testHeartbeatBundle.makeHeartbeatsPayload()
+          HeartbeatsBundle.testHeartbeatBundle().makeHeartbeatsPayload()
         )
         // Write some new value.
         expectation2.fulfill()