FirebaseSessionsTests+DataCollection.swift 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. //
  2. // Copyright 2022 Google LLC
  3. //
  4. // Licensed under the Apache License, Version 2.0 (the "License");
  5. // you may not use this file except in compliance with the License.
  6. // You may obtain a copy of the License at
  7. //
  8. // http://www.apache.org/licenses/LICENSE-2.0
  9. //
  10. // Unless required by applicable law or agreed to in writing, software
  11. // distributed under the License is distributed on an "AS IS" BASIS,
  12. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. // See the License for the specific language governing permissions and
  14. // limitations under the License.
  15. import XCTest
  16. #if SWIFT_PACKAGE
  17. import FirebaseSessionsObjC
  18. #endif // SWIFT_PACKAGE
  19. @testable import FirebaseSessions
  20. final class FirebaseSessionsTestsBase_DataCollection: FirebaseSessionsTestsBase {
  21. // Ensure that for all subscribers, that the data collection state is correctly set.
  22. func assertEventDataCollectionCorrect(subscribedSDKs: [SessionsSubscriber]) {
  23. guard let loggedEvent = mockCoordinator.loggedEvent else {
  24. XCTFail(
  25. "Sessions had a successful result, but the mock Coordinator did not have a loggedEvent set"
  26. )
  27. return
  28. }
  29. let protoDataCollection = loggedEvent.proto.session_data.data_collection_status
  30. // Look through all possible subscribers, not just the ones subscribed in the test
  31. for subscriberSDK in allSubscribers {
  32. // Check if the subscriber was subscribed or not, because non-subscribers should
  33. // have their data collection state set to UNKNOWN
  34. let isSubscribed = subscribedSDKs.contains { subscriber in
  35. subscriber.sessionsSubscriberName == subscriberSDK.sessionsSubscriberName
  36. }
  37. switch subscriberSDK.sessionsSubscriberName {
  38. case .Crashlytics:
  39. assertEventDataCollectionProtoEqual(
  40. isDataCollectionEnabled: subscriberSDK.isDataCollectionEnabled,
  41. isSubscribed: isSubscribed,
  42. protoState: protoDataCollection.crashlytics
  43. )
  44. case .Performance:
  45. assertEventDataCollectionProtoEqual(
  46. isDataCollectionEnabled: subscriberSDK.isDataCollectionEnabled,
  47. isSubscribed: isSubscribed,
  48. protoState: protoDataCollection.performance
  49. )
  50. case .Unknown:
  51. XCTFail("Sessions subscribed to with 'Unknown' Subscriber Name")
  52. }
  53. }
  54. }
  55. func assertEventDataCollectionProtoEqual(isDataCollectionEnabled: Bool,
  56. isSubscribed: Bool,
  57. protoState: firebase_appquality_sessions_DataCollectionState) {
  58. if !isSubscribed {
  59. XCTAssertEqual(
  60. protoState,
  61. firebase_appquality_sessions_DataCollectionState_COLLECTION_SDK_NOT_INSTALLED
  62. )
  63. } else if isDataCollectionEnabled {
  64. XCTAssertEqual(
  65. protoState,
  66. firebase_appquality_sessions_DataCollectionState_COLLECTION_ENABLED
  67. )
  68. } else {
  69. XCTAssertEqual(
  70. protoState,
  71. firebase_appquality_sessions_DataCollectionState_COLLECTION_DISABLED
  72. )
  73. }
  74. }
  75. // MARK: - Test Data Collection
  76. func test_subscriberWithDataCollectionEnabled_logsSessionEvent() {
  77. runSessionsSDK(
  78. subscriberSDKs: [
  79. mockCrashlyticsSubscriber,
  80. ], preSessionsInit: { _ in
  81. // Nothing
  82. }, postSessionsInit: {
  83. sessions.register(subscriber: self.mockCrashlyticsSubscriber)
  84. // Sessions hasn't logged yet because no Subscriber SDKs have registered
  85. XCTAssertNil(self.mockCoordinator.loggedEvent)
  86. }, postLogEvent: { result, subscriberSDKs in
  87. // Make sure the SDK reported success, we logged an event and
  88. // Settings fetched new configs
  89. self.assertSuccess(result: result)
  90. self.assertEventDataCollectionCorrect(subscribedSDKs: subscriberSDKs)
  91. XCTAssertTrue(self.mockSettings.updateSettingsCalled)
  92. XCTAssertNotNil(self.mockCoordinator.loggedEvent)
  93. }
  94. )
  95. }
  96. func test_subscribersSomeDataCollectionDisabled_logsSessionEvent() {
  97. runSessionsSDK(
  98. subscriberSDKs: [
  99. mockCrashlyticsSubscriber,
  100. mockPerformanceSubscriber,
  101. ], preSessionsInit: { _ in
  102. // Same as above, but this time we've disabled data collection in
  103. // only one of the subscribers
  104. self.mockCrashlyticsSubscriber.isDataCollectionEnabled = false
  105. }, postSessionsInit: {
  106. // Register the subscribers
  107. sessions.register(subscriber: self.mockPerformanceSubscriber)
  108. sessions.register(subscriber: self.mockCrashlyticsSubscriber)
  109. }, postLogEvent: { result, subscriberSDKs in
  110. // Make sure the SDK reported success, we logged an event and
  111. // Settings fetched new configs
  112. self.assertSuccess(result: result)
  113. self.assertEventDataCollectionCorrect(subscribedSDKs: subscriberSDKs)
  114. XCTAssertTrue(self.mockSettings.updateSettingsCalled)
  115. XCTAssertNotNil(self.mockCoordinator.loggedEvent)
  116. }
  117. )
  118. }
  119. func test_subscribersAllDataCollectionDisabled_doesNotLogSessionEvent() {
  120. runSessionsSDK(
  121. subscriberSDKs: [
  122. mockCrashlyticsSubscriber,
  123. mockPerformanceSubscriber,
  124. ], preSessionsInit: { _ in
  125. // We've disabled data collection in all our Subscriber SDKs
  126. self.mockCrashlyticsSubscriber.isDataCollectionEnabled = false
  127. self.mockPerformanceSubscriber.isDataCollectionEnabled = false
  128. }, postSessionsInit: {
  129. // Register the subscribers
  130. sessions.register(subscriber: self.mockCrashlyticsSubscriber)
  131. sessions.register(subscriber: self.mockPerformanceSubscriber)
  132. }, postLogEvent: { result, subscriberSDKs in
  133. // Make sure we failed with the correct error
  134. self.assertFailure(result: result, expectedError: .DataCollectionError)
  135. // Make sure we didn't do any data collection
  136. XCTAssertFalse(self.mockSettings.updateSettingsCalled)
  137. XCTAssertNil(self.mockCoordinator.loggedEvent)
  138. }
  139. )
  140. }
  141. func test_defaultSamplingRate_isSetInProto() {
  142. runSessionsSDK(
  143. subscriberSDKs: [
  144. mockCrashlyticsSubscriber,
  145. ], preSessionsInit: { _ in
  146. // Nothing
  147. }, postSessionsInit: {
  148. sessions.register(subscriber: self.mockCrashlyticsSubscriber)
  149. // Nothing
  150. }, postLogEvent: { result, subscriberSDKs in
  151. // Make sure we set the sampling rate in the proto
  152. XCTAssertEqual(
  153. self.mockCoordinator.loggedEvent?.proto.session_data.data_collection_status
  154. .session_sampling_rate,
  155. 1.0
  156. )
  157. }
  158. )
  159. }
  160. }