HeartbeatsBundleTests.swift 10.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347
  1. // Copyright 2021 Google LLC
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. import XCTest
  15. @testable import FirebaseCoreInternal
  16. import HeartbeatLoggingTestUtils
  17. class HeartbeatsBundleTests: XCTestCase {
  18. // 2021-11-01 @ 00:00:00 (EST)
  19. let date = Date(timeIntervalSince1970: 1_635_739_200)
  20. func testInitializesWithDefaultCacheProvider() throws {
  21. // Given
  22. let heartbeatsBundle = HeartbeatsBundle(capacity: 0)
  23. // Then
  24. XCTAssertEqual(
  25. heartbeatsBundle.lastAddedHeartbeatDates,
  26. [
  27. .daily: .distantPast,
  28. ]
  29. )
  30. }
  31. func testAppendingHeartbeatUpdatesCache() throws {
  32. // Given
  33. var heartbeatsBundle = HeartbeatsBundle(capacity: 1)
  34. let heartbeat = Heartbeat(agent: "dummy_agent", date: date, timePeriods: [.daily])
  35. // When
  36. heartbeatsBundle.append(heartbeat)
  37. // Then
  38. let heartbeatsBundleString = heartbeatsBundle
  39. .makeHeartbeatsPayload()
  40. .headerValue()
  41. try HeartbeatLoggingTestUtils.assertEqualPayloadStrings(
  42. heartbeatsBundleString,
  43. """
  44. {
  45. "version": 2,
  46. "heartbeats": [
  47. {
  48. "agent": "dummy_agent",
  49. "dates": ["2021-11-01"]
  50. }
  51. ]
  52. }
  53. """
  54. )
  55. XCTAssertEqual(heartbeatsBundle.lastAddedHeartbeatDates, [.daily: heartbeat.date])
  56. }
  57. func testAppendingHeartbeat_WhenCapacityIsZero_DoesNothing() throws {
  58. // Given
  59. var heartbeatsBundle = HeartbeatsBundle(capacity: 0)
  60. let preAppendCacheSnapshot = heartbeatsBundle.lastAddedHeartbeatDates
  61. let heartbeat = Heartbeat(agent: "dummy_agent", date: date, timePeriods: [.daily])
  62. // When
  63. heartbeatsBundle.append(heartbeat)
  64. // Then
  65. let heartbeatsBundleString = heartbeatsBundle
  66. .makeHeartbeatsPayload()
  67. .headerValue()
  68. try HeartbeatLoggingTestUtils.assertEqualPayloadStrings(
  69. heartbeatsBundleString,
  70. """
  71. {
  72. "version": 2,
  73. "heartbeats": []
  74. }
  75. """
  76. )
  77. XCTAssertEqual(heartbeatsBundle.lastAddedHeartbeatDates, preAppendCacheSnapshot)
  78. }
  79. func testAppendingHeartbeat_AtMaxCapacity_RemovesOverwrittenFromCache() throws {
  80. // Given
  81. var heartbeatsBundle = HeartbeatsBundle(capacity: 1)
  82. let heartbeat1 = Heartbeat(agent: "dummy_agent_1", date: date, timePeriods: [.daily])
  83. heartbeatsBundle.append(heartbeat1)
  84. XCTAssertEqual(heartbeatsBundle.lastAddedHeartbeatDates, [.daily: heartbeat1.date])
  85. let heartbeat2 = Heartbeat(agent: "dummy_agent_2", date: date, timePeriods: [.daily])
  86. // When
  87. heartbeatsBundle.append(heartbeat2)
  88. // Then
  89. let heartbeatsBundleString = heartbeatsBundle
  90. .makeHeartbeatsPayload()
  91. .headerValue()
  92. try HeartbeatLoggingTestUtils.assertEqualPayloadStrings(
  93. heartbeatsBundleString,
  94. """
  95. {
  96. "version": 2,
  97. "heartbeats": [
  98. {
  99. "agent": "dummy_agent_2",
  100. "dates": ["2021-11-01"]
  101. }
  102. ]
  103. }
  104. """
  105. )
  106. XCTAssertEqual(heartbeatsBundle.lastAddedHeartbeatDates, [.daily: heartbeat2.date])
  107. }
  108. func testRemovingHeartbeatFromDateDoesNotUpdateCache() throws {
  109. // Given
  110. var heartbeatsBundle = HeartbeatsBundle(capacity: 1)
  111. let heartbeat = Heartbeat(agent: "agent", date: date, timePeriods: [.daily])
  112. heartbeatsBundle.append(heartbeat)
  113. // When
  114. heartbeatsBundle.removeHeartbeat(from: date)
  115. // Then
  116. XCTAssertEqual(
  117. heartbeatsBundle.lastAddedHeartbeatDates,
  118. [
  119. .daily: heartbeat.date,
  120. ]
  121. )
  122. }
  123. func testRemovingHeartbeatFromDate_WhenCapacityIsZero_DoesNothing() throws {
  124. // Given
  125. var heartbeatsBundle = HeartbeatsBundle(capacity: 0)
  126. let preRemoveCacheSnapshot = heartbeatsBundle.lastAddedHeartbeatDates
  127. // When
  128. let removedHeartbeat = heartbeatsBundle.removeHeartbeat(from: date)
  129. // Then
  130. XCTAssertNil(removedHeartbeat)
  131. let heartbeatsBundleString = heartbeatsBundle
  132. .makeHeartbeatsPayload()
  133. .headerValue()
  134. try HeartbeatLoggingTestUtils.assertEqualPayloadStrings(
  135. heartbeatsBundleString,
  136. """
  137. {
  138. "version": 2,
  139. "heartbeats": []
  140. }
  141. """
  142. )
  143. XCTAssertEqual(heartbeatsBundle.lastAddedHeartbeatDates, preRemoveCacheSnapshot)
  144. }
  145. func testRemovingHeartbeatFromDate_WhenHeartbeatFromDateInBundle_RemovesAndReturnsTheHeartbeat() throws {
  146. // Given
  147. var heartbeatsBundle = HeartbeatsBundle(capacity: 1)
  148. let heartbeat = Heartbeat(agent: "dummy_agent", date: date, timePeriods: [.daily])
  149. heartbeatsBundle.append(heartbeat)
  150. // When
  151. let removedHeartbeat = heartbeatsBundle.removeHeartbeat(from: date)
  152. // Then
  153. XCTAssertEqual(removedHeartbeat, heartbeat)
  154. let heartbeatsBundleString = heartbeatsBundle
  155. .makeHeartbeatsPayload()
  156. .headerValue()
  157. try HeartbeatLoggingTestUtils.assertEqualPayloadStrings(
  158. heartbeatsBundleString,
  159. """
  160. {
  161. "version": 2,
  162. "heartbeats": []
  163. }
  164. """
  165. )
  166. }
  167. func testRemovingHeartbeatFromDate_WhenHeartbeatFromDateNotInBundle_RemovesNothingAndReturnsNil() throws {
  168. // Given
  169. var heartbeatsBundle = HeartbeatsBundle(capacity: 1)
  170. let heartbeat = Heartbeat(agent: "dummy_agent", date: date, timePeriods: [.daily])
  171. heartbeatsBundle.append(heartbeat)
  172. // When
  173. let removedHeartbeat = heartbeatsBundle.removeHeartbeat(from: .distantPast)
  174. // Then
  175. XCTAssertNil(removedHeartbeat)
  176. let heartbeatsBundleString = heartbeatsBundle
  177. .makeHeartbeatsPayload()
  178. .headerValue()
  179. try HeartbeatLoggingTestUtils.assertEqualPayloadStrings(
  180. heartbeatsBundleString,
  181. """
  182. {
  183. "version": 2,
  184. "heartbeats": [
  185. {
  186. "agent": "dummy_agent",
  187. "dates": ["2021-11-01"]
  188. }
  189. ]
  190. }
  191. """
  192. )
  193. }
  194. func testRemovingHeartbeatFromDate_DoesNotAlterOrderingForRemainingHeartbeats() throws {
  195. // Given
  196. var heartbeatsBundle = HeartbeatsBundle(capacity: 3)
  197. let yesterdayDate = date.addingTimeInterval(-1 * 60 * 60 * 24)
  198. let heartbeat1 = Heartbeat(agent: "dummy_agent_1", date: .distantPast)
  199. let heartbeat2 = Heartbeat(agent: "dummy_agent_2", date: yesterdayDate)
  200. let heartbeat3 = Heartbeat(agent: "dummy_agent_3", date: date)
  201. heartbeatsBundle.append(heartbeat1) // [heartbeat1, __________, __________]
  202. heartbeatsBundle.append(heartbeat2) // [heartbeat1, heartbeat1, __________]
  203. heartbeatsBundle.append(heartbeat3) // [heartbeat1, heartbeat2, heartbeat3]
  204. // When
  205. heartbeatsBundle.removeHeartbeat(from: yesterdayDate) // [heartbeat1, heartbeat3, nil]
  206. // Then
  207. let heartbeat4 = Heartbeat(agent: "dummy_agent_4", date: date)
  208. let heartbeat5 = Heartbeat(agent: "dummy_agent_5", date: date)
  209. heartbeatsBundle.append(heartbeat4) // [heartbeat1, heartbeat3, heartbeat4]
  210. heartbeatsBundle.append(heartbeat5) // [heartbeat5, heartbeat3, heartbeat4]
  211. let heartbeatsBundleString = heartbeatsBundle
  212. .makeHeartbeatsPayload()
  213. .headerValue()
  214. try HeartbeatLoggingTestUtils.assertEqualPayloadStrings(
  215. heartbeatsBundleString,
  216. """
  217. {
  218. "version": 2,
  219. "heartbeats": [
  220. {
  221. "agent": "dummy_agent_3",
  222. "dates": ["2021-11-01"]
  223. },
  224. {
  225. "agent": "dummy_agent_4",
  226. "dates": ["2021-11-01"]
  227. },
  228. {
  229. "agent": "dummy_agent_5",
  230. "dates": ["2021-11-01"]
  231. }
  232. ]
  233. }
  234. """
  235. )
  236. }
  237. func testRemovingHeartbeatFromDate_WhenMultipleHeartbeatFromDateExist_RemovesAndReturnsTheLastHeartbeat() throws {
  238. // Given
  239. var heartbeatsBundle = HeartbeatsBundle(capacity: 3)
  240. let heartbeat1 = Heartbeat(agent: "dummy_agent_1", date: date)
  241. let heartbeat2 = Heartbeat(agent: "dummy_agent_2", date: date)
  242. let heartbeat3 = Heartbeat(agent: "dummy_agent_3", date: date)
  243. heartbeatsBundle.append(heartbeat1) // [heartbeat1, __________, __________]
  244. heartbeatsBundle.append(heartbeat2) // [heartbeat1, heartbeat2, __________]
  245. heartbeatsBundle.append(heartbeat3) // [heartbeat1, heartbeat2, heartbeat3]
  246. // When
  247. let removed = heartbeatsBundle
  248. .removeHeartbeat(from: date) // [heartbeat1, heartbeat2, __________]
  249. // Then
  250. XCTAssertEqual(removed, heartbeat3)
  251. let heartbeatsBundleString = heartbeatsBundle
  252. .makeHeartbeatsPayload()
  253. .headerValue()
  254. try HeartbeatLoggingTestUtils.assertEqualPayloadStrings(
  255. heartbeatsBundleString,
  256. """
  257. {
  258. "version": 2,
  259. "heartbeats": [
  260. {
  261. "agent": "dummy_agent_1",
  262. "dates": ["2021-11-01"]
  263. },
  264. {
  265. "agent": "dummy_agent_2",
  266. "dates": ["2021-11-01"]
  267. }
  268. ]
  269. }
  270. """
  271. )
  272. }
  273. func testMakePayload_WithMultipleUserAgents() throws {
  274. // Given
  275. var heartbeatsBundle = HeartbeatsBundle(capacity: 2)
  276. // When
  277. let heartbeat1 = Heartbeat(agent: "dummy_agent_1", date: date)
  278. heartbeatsBundle.append(heartbeat1)
  279. let heartbeat2 = Heartbeat(agent: "dummy_agent_2", date: date)
  280. heartbeatsBundle.append(heartbeat2)
  281. // Then
  282. let heartbeatsBundleString = heartbeatsBundle
  283. .makeHeartbeatsPayload()
  284. .headerValue()
  285. try HeartbeatLoggingTestUtils.assertEqualPayloadStrings(
  286. heartbeatsBundleString,
  287. """
  288. {
  289. "version": 2,
  290. "heartbeats": [
  291. {
  292. "agent": "dummy_agent_1",
  293. "dates": ["2021-11-01"]
  294. },
  295. {
  296. "agent": "dummy_agent_2",
  297. "dates": ["2021-11-01"]
  298. }
  299. ]
  300. }
  301. """
  302. )
  303. }
  304. }