HeartbeatsBundleTests.swift 9.9 KB

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