FPRNanoPbUtilsTest.m 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494
  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/XCTest.h>
  15. #import "FirebasePerformance/Sources/FIRPerformance+Internal.h"
  16. #import "FirebasePerformance/Sources/FPRDataUtils.h"
  17. #import "FirebasePerformance/Sources/FPRNanoPbUtils.h"
  18. #import "FirebasePerformance/Sources/Public/FirebasePerformance/FIRPerformance.h"
  19. #import "FirebasePerformance/Sources/Common/FPRConstants.h"
  20. #import "FirebasePerformance/Sources/Instrumentation/FPRNetworkTrace+Private.h"
  21. #import "FirebasePerformance/Sources/Instrumentation/FPRNetworkTrace.h"
  22. #import "FirebasePerformance/Sources/Timer/FIRTrace+Internal.h"
  23. #import "FirebasePerformance/Sources/Timer/FIRTrace+Private.h"
  24. #import "FirebasePerformance/Sources/Gauges/CPU/FPRCPUGaugeData.h"
  25. #import "FirebasePerformance/Sources/Gauges/Memory/FPRMemoryGaugeData.h"
  26. #import "FirebasePerformance/Tests/Unit/FPRTestCase.h"
  27. #import <OCMock/OCMock.h>
  28. @interface FPRNanoPbUtilsTest : FPRTestCase
  29. @end
  30. @implementation FPRNanoPbUtilsTest
  31. - (void)setUp {
  32. [super setUp];
  33. FIRPerformance *performance = [FIRPerformance sharedInstance];
  34. [performance setDataCollectionEnabled:YES];
  35. }
  36. - (void)tearDown {
  37. [super tearDown];
  38. FIRPerformance *performance = [FIRPerformance sharedInstance];
  39. [performance setDataCollectionEnabled:NO];
  40. }
  41. /** Validates that a firebase_perf_v1_PerfMetric creation is successful. */
  42. - (void)testPerfMetricMessageCreation {
  43. NSString *appID = @"RandomAppID";
  44. firebase_perf_v1_PerfMetric perfMetric = FPRGetPerfMetricMessage(appID);
  45. XCTAssertEqualObjects(FPRDecodeString(perfMetric.application_info.google_app_id), appID);
  46. }
  47. /** Tests if the application information is populated when creating a firebase_perf_v1_PerfMetric.
  48. */
  49. - (void)testApplicationInfoMessage {
  50. firebase_perf_v1_PerfMetric event = FPRGetPerfMetricMessage(@"appid");
  51. firebase_perf_v1_ApplicationInfo appInfo = event.application_info;
  52. XCTAssertEqualObjects(FPRDecodeString(appInfo.google_app_id), @"appid");
  53. XCTAssertTrue(appInfo.ios_app_info.sdk_version != NULL);
  54. XCTAssertTrue(appInfo.has_ios_app_info);
  55. XCTAssertTrue(appInfo.ios_app_info.bundle_short_version != NULL);
  56. XCTAssertTrue(appInfo.ios_app_info.mcc_mnc == NULL || appInfo.ios_app_info.mcc_mnc->size == 6);
  57. XCTAssertTrue(appInfo.ios_app_info.has_network_connection_info);
  58. XCTAssertTrue(appInfo.ios_app_info.network_connection_info.has_network_type);
  59. XCTAssertTrue(appInfo.ios_app_info.network_connection_info.network_type !=
  60. firebase_perf_v1_NetworkConnectionInfo_NetworkType_NONE);
  61. if (appInfo.ios_app_info.network_connection_info.network_type ==
  62. firebase_perf_v1_NetworkConnectionInfo_NetworkType_MOBILE) {
  63. XCTAssertTrue(appInfo.ios_app_info.network_connection_info.mobile_subtype !=
  64. firebase_perf_v1_NetworkConnectionInfo_MobileSubtype_UNKNOWN_MOBILE_SUBTYPE);
  65. }
  66. }
  67. /** Validates that ApplicationInfoMessage carries global attributes. */
  68. - (void)testApplicationInfoMessageWithAttributes {
  69. FIRPerformance *performance = [FIRPerformance sharedInstance];
  70. [performance setValue:@"bar1" forAttribute:@"foo1"];
  71. [performance setValue:@"bar2" forAttribute:@"foo2"];
  72. firebase_perf_v1_PerfMetric event = FPRGetPerfMetricMessage(@"appid");
  73. firebase_perf_v1_ApplicationInfo appInfo = event.application_info;
  74. XCTAssertEqual(appInfo.custom_attributes_count, 2);
  75. NSDictionary *attributes = FPRDecodeStringToStringMap(
  76. (StringToStringMap *)appInfo.custom_attributes, appInfo.custom_attributes_count);
  77. XCTAssertEqualObjects(attributes[@"foo1"], @"bar1");
  78. XCTAssertEqualObjects(attributes[@"foo2"], @"bar2");
  79. [performance removeAttribute:@"foo1"];
  80. [performance removeAttribute:@"foo2"];
  81. }
  82. /** Tests if mccMnc validation is catching non numerals. */
  83. - (void)testMccMncOnlyHasNumbers {
  84. NSString *mccMnc = FPRValidatedMccMnc(@"123", @"MKV");
  85. XCTAssertNil(mccMnc);
  86. mccMnc = FPRValidatedMccMnc(@"ABC", @"123");
  87. XCTAssertNil(mccMnc);
  88. }
  89. /** Tests if mccMnc validation is working. */
  90. - (void)testMccMnc {
  91. NSString *mccMnc = FPRValidatedMccMnc(@"123", @"22");
  92. XCTAssertNotNil(mccMnc);
  93. mccMnc = FPRValidatedMccMnc(@"123", @"223");
  94. XCTAssertNotNil(mccMnc);
  95. }
  96. /** Tests if mccMnc validation catches improper lengths. */
  97. - (void)testMccMncLength {
  98. NSString *mccMnc = FPRValidatedMccMnc(@"12", @"22");
  99. XCTAssertNil(mccMnc);
  100. mccMnc = FPRValidatedMccMnc(@"123", @"2");
  101. XCTAssertNil(mccMnc);
  102. }
  103. /** Validates that a valid FIRTrace object to firebase_perf_v1_TraceMetric conversion is successful.
  104. */
  105. - (void)testTraceMetricMessageCreation {
  106. FIRTrace *trace = [[FIRTrace alloc] initWithName:@"Random"];
  107. [trace start];
  108. [trace startStageNamed:@"1"];
  109. [trace startStageNamed:@"2"];
  110. [trace incrementMetric:@"c1" byInt:2];
  111. [trace setValue:@"bar" forAttribute:@"foo"];
  112. [trace stop];
  113. firebase_perf_v1_TraceMetric traceMetric = FPRGetTraceMetric(trace);
  114. XCTAssertEqualObjects(FPRDecodeString(traceMetric.name), @"Random");
  115. XCTAssertEqual(traceMetric.subtraces_count, 2);
  116. XCTAssertEqual(traceMetric.counters_count, 1);
  117. NSDictionary *counters = FPRDecodeStringToNumberMap((StringToNumberMap *)traceMetric.counters,
  118. traceMetric.counters_count);
  119. XCTAssertEqual([counters[@"c1"] intValue], 2);
  120. XCTAssertEqualObjects(FPRDecodeString(traceMetric.subtraces[0].name), @"1");
  121. XCTAssertEqualObjects(FPRDecodeString(traceMetric.subtraces[1].name), @"2");
  122. XCTAssertTrue(traceMetric.custom_attributes != NULL);
  123. XCTAssertEqual(traceMetric.custom_attributes_count, 1);
  124. NSDictionary *attributes = FPRDecodeStringToStringMap(
  125. (StringToStringMap *)traceMetric.custom_attributes, traceMetric.custom_attributes_count);
  126. XCTAssertEqualObjects(attributes[@"foo"], @"bar");
  127. }
  128. /** Validates that a valid FIRTrace object to firebase_perf_v1_TraceMetric conversion has required
  129. * fields. */
  130. - (void)testTraceMetricMessageCreationHasRequiredFields {
  131. FIRTrace *trace = [[FIRTrace alloc] initWithName:@"Random"];
  132. [trace start];
  133. [trace incrementMetric:@"c1" byInt:2];
  134. [trace stop];
  135. firebase_perf_v1_TraceMetric traceMetric = FPRGetTraceMetric(trace);
  136. XCTAssertTrue(traceMetric.name != NULL);
  137. XCTAssertTrue(traceMetric.has_client_start_time_us);
  138. XCTAssertTrue(traceMetric.has_duration_us);
  139. XCTAssertTrue(traceMetric.has_is_auto);
  140. }
  141. /** Validates the session details inside trace metric. */
  142. - (void)testTraceMetricMessageHasSessionDetails {
  143. FIRTrace *trace = [[FIRTrace alloc] initWithName:@"Random"];
  144. [trace start];
  145. [trace incrementMetric:@"c1" byInt:2];
  146. FPRSessionDetails *session1 = [[FPRSessionDetails alloc] initWithSessionId:@"a"
  147. options:FPRSessionOptionsNone];
  148. FPRSessionDetails *session2 =
  149. [[FPRSessionDetails alloc] initWithSessionId:@"b" options:FPRSessionOptionsGauges];
  150. trace.activeSessions = [@[ session1, session2 ] mutableCopy];
  151. [trace stop];
  152. firebase_perf_v1_TraceMetric traceMetric = FPRGetTraceMetric(trace);
  153. XCTAssertTrue(traceMetric.perf_sessions != NULL);
  154. XCTAssertTrue(traceMetric.perf_sessions_count >= 2);
  155. }
  156. /** Validates that the FPRNetworkTrace object to firebase_perf_v1_NetworkRequestMetric conversion is
  157. * successful. */
  158. - (void)testNetworkTraceMetricMessage {
  159. NSURL *URL = [NSURL URLWithString:@"https://abc.com"];
  160. NSURLRequest *URLRequest = [NSURLRequest requestWithURL:URL];
  161. FPRNetworkTrace *trace = [[FPRNetworkTrace alloc] initWithURLRequest:URLRequest];
  162. [trace start];
  163. [trace checkpointState:FPRNetworkTraceCheckpointStateInitiated];
  164. [trace checkpointState:FPRNetworkTraceCheckpointStateResponseReceived];
  165. NSDictionary<NSString *, NSString *> *headerFields = @{@"Content-Type" : @"text/json"};
  166. NSHTTPURLResponse *response = [[NSHTTPURLResponse alloc] initWithURL:URLRequest.URL
  167. statusCode:404
  168. HTTPVersion:@"HTTP/1.1"
  169. headerFields:headerFields];
  170. NSError *error = [NSError errorWithDomain:NSURLErrorDomain code:-200 userInfo:nil];
  171. [trace didReceiveData:[NSData data]];
  172. [trace didCompleteRequestWithResponse:response error:error];
  173. firebase_perf_v1_NetworkRequestMetric networkMetric = FPRGetNetworkRequestMetric(trace);
  174. XCTAssertEqualObjects(FPRDecodeString(networkMetric.url), URL.absoluteString);
  175. XCTAssertEqual(networkMetric.http_method, firebase_perf_v1_NetworkRequestMetric_HttpMethod_GET);
  176. XCTAssertEqual(
  177. networkMetric.network_client_error_reason,
  178. firebase_perf_v1_NetworkRequestMetric_NetworkClientErrorReason_GENERIC_CLIENT_ERROR);
  179. XCTAssertEqual(networkMetric.http_response_code, 404);
  180. XCTAssertEqualObjects(FPRDecodeString(networkMetric.response_content_type), @"text/json");
  181. }
  182. /** Validates that the FPRNetworkTrace object to Proto conversion has required fields for a valid
  183. * response.
  184. */
  185. - (void)testNetworkTraceMetricMessageHasAllRequiredFields {
  186. NSURL *URL = [NSURL URLWithString:@"https://abc.com"];
  187. NSURLRequest *URLRequest = [NSURLRequest requestWithURL:URL];
  188. FPRNetworkTrace *trace = [[FPRNetworkTrace alloc] initWithURLRequest:URLRequest];
  189. [trace start];
  190. [trace checkpointState:FPRNetworkTraceCheckpointStateInitiated];
  191. [trace checkpointState:FPRNetworkTraceCheckpointStateResponseReceived];
  192. NSDictionary<NSString *, NSString *> *headerFields = @{@"Content-Type" : @"text/json"};
  193. NSHTTPURLResponse *response = [[NSHTTPURLResponse alloc] initWithURL:URLRequest.URL
  194. statusCode:404
  195. HTTPVersion:@"HTTP/1.1"
  196. headerFields:headerFields];
  197. NSError *error = [NSError errorWithDomain:NSURLErrorDomain code:-200 userInfo:nil];
  198. [trace didReceiveData:[NSData data]];
  199. [trace didCompleteRequestWithResponse:response error:error];
  200. firebase_perf_v1_NetworkRequestMetric networkMetric = FPRGetNetworkRequestMetric(trace);
  201. XCTAssertTrue(networkMetric.url != NULL);
  202. XCTAssertTrue(networkMetric.has_client_start_time_us);
  203. XCTAssertTrue(networkMetric.has_http_method);
  204. XCTAssertTrue(networkMetric.has_response_payload_bytes);
  205. XCTAssertTrue(networkMetric.has_network_client_error_reason);
  206. XCTAssertTrue(networkMetric.has_http_response_code);
  207. XCTAssertTrue(networkMetric.response_content_type != NULL);
  208. XCTAssertTrue(networkMetric.has_time_to_response_completed_us);
  209. }
  210. /** Validates that application process state conversion to firebase_perf_v1_ApplicationProcessState
  211. * enum type is successful. */
  212. - (void)testApplicationProcessStateConversion {
  213. XCTAssertEqual(firebase_perf_v1_ApplicationProcessState_BACKGROUND,
  214. FPRApplicationProcessState(FPRTraceStateBackgroundOnly));
  215. XCTAssertEqual(firebase_perf_v1_ApplicationProcessState_FOREGROUND,
  216. FPRApplicationProcessState(FPRTraceStateForegroundOnly));
  217. XCTAssertEqual(firebase_perf_v1_ApplicationProcessState_FOREGROUND_BACKGROUND,
  218. FPRApplicationProcessState(FPRTraceStateBackgroundAndForeground));
  219. XCTAssertEqual(firebase_perf_v1_ApplicationProcessState_APPLICATION_PROCESS_STATE_UNKNOWN,
  220. FPRApplicationProcessState(FPRTraceStateUnknown));
  221. // Try with some random value should say the application state is unknown.
  222. XCTAssertEqual(firebase_perf_v1_ApplicationProcessState_APPLICATION_PROCESS_STATE_UNKNOWN,
  223. FPRApplicationProcessState(100));
  224. }
  225. #ifdef TARGET_HAS_MOBILE_CONNECTIVITY
  226. /** Validates if network object creation works. */
  227. - (void)testNetworkInfoObjectCreation {
  228. XCTAssertNotNil(FPRNetworkInfo());
  229. }
  230. #endif
  231. /** Validates the session details inside trace metric. */
  232. - (void)testNetworkRequestMetricMessageHasSessionDetails {
  233. NSURL *URL = [NSURL URLWithString:@"https://abc.com"];
  234. NSURLRequest *URLRequest = [NSURLRequest requestWithURL:URL];
  235. FPRNetworkTrace *trace = [[FPRNetworkTrace alloc] initWithURLRequest:URLRequest];
  236. [trace start];
  237. [trace checkpointState:FPRNetworkTraceCheckpointStateInitiated];
  238. [trace checkpointState:FPRNetworkTraceCheckpointStateResponseReceived];
  239. NSDictionary<NSString *, NSString *> *headerFields = @{@"Content-Type" : @"text/json"};
  240. NSHTTPURLResponse *response = [[NSHTTPURLResponse alloc] initWithURL:URLRequest.URL
  241. statusCode:404
  242. HTTPVersion:@"HTTP/1.1"
  243. headerFields:headerFields];
  244. NSError *error = [NSError errorWithDomain:NSURLErrorDomain code:-200 userInfo:nil];
  245. FPRSessionDetails *session1 = [[FPRSessionDetails alloc] initWithSessionId:@"a"
  246. options:FPRSessionOptionsNone];
  247. FPRSessionDetails *session2 =
  248. [[FPRSessionDetails alloc] initWithSessionId:@"b" options:FPRSessionOptionsGauges];
  249. trace.activeSessions = [@[ session1, session2 ] mutableCopy];
  250. [trace didReceiveData:[NSData data]];
  251. [trace didCompleteRequestWithResponse:response error:error];
  252. firebase_perf_v1_NetworkRequestMetric networkMetric = FPRGetNetworkRequestMetric(trace);
  253. XCTAssertTrue(networkMetric.perf_sessions != NULL);
  254. XCTAssertTrue(networkMetric.perf_sessions_count >= 2);
  255. }
  256. /** Validates the gauge metric proto packaging works with proper conversions. */
  257. - (void)testMemoryMetricProtoConversion {
  258. NSMutableArray *gauges = [[NSMutableArray alloc] init];
  259. NSDate *date = [NSDate date];
  260. FPRMemoryGaugeData *memoryData = [[FPRMemoryGaugeData alloc] initWithCollectionTime:date
  261. heapUsed:5 * 1024
  262. heapAvailable:10 * 1024];
  263. [gauges addObject:memoryData];
  264. firebase_perf_v1_GaugeMetric gaugeMetric = FPRGetGaugeMetric(gauges, @"abc");
  265. XCTAssertEqual(gaugeMetric.cpu_metric_readings_count, 0);
  266. XCTAssertEqual(gaugeMetric.ios_memory_readings_count, 1);
  267. XCTAssertEqual(gaugeMetric.ios_memory_readings[0].used_app_heap_memory_kb, 5);
  268. XCTAssertEqual(gaugeMetric.ios_memory_readings[0].free_app_heap_memory_kb, 10);
  269. }
  270. /** Validates the gauge metric proto packaging works. */
  271. - (void)testGaugeMetricProtoPacking {
  272. NSMutableArray *gauges = [[NSMutableArray alloc] init];
  273. for (int i = 0; i < 5; i++) {
  274. NSDate *date = [NSDate date];
  275. FPRCPUGaugeData *cpuData = [[FPRCPUGaugeData alloc] initWithCollectionTime:date
  276. systemTime:100
  277. userTime:200];
  278. FPRMemoryGaugeData *memoryData = [[FPRMemoryGaugeData alloc] initWithCollectionTime:date
  279. heapUsed:100
  280. heapAvailable:200];
  281. [gauges addObject:cpuData];
  282. [gauges addObject:memoryData];
  283. }
  284. firebase_perf_v1_GaugeMetric gaugeMetric = FPRGetGaugeMetric(gauges, @"abc");
  285. XCTAssertEqual(gaugeMetric.cpu_metric_readings_count, 5);
  286. XCTAssertEqual(gaugeMetric.ios_memory_readings_count, 5);
  287. }
  288. /** Validates if the first session is a verbose session for a trace. */
  289. - (void)testOrderingOfSessionsForTrace {
  290. FIRTrace *trace = [[FIRTrace alloc] initWithName:@"Random"];
  291. [trace start];
  292. FPRSessionDetails *session1 = [[FPRSessionDetails alloc] initWithSessionId:@"a"
  293. options:FPRSessionOptionsNone];
  294. FPRSessionDetails *session2 =
  295. [[FPRSessionDetails alloc] initWithSessionId:@"b" options:FPRSessionOptionsGauges];
  296. trace.activeSessions = [@[ session1, session2 ] mutableCopy];
  297. [trace stop];
  298. firebase_perf_v1_TraceMetric traceMetric = FPRGetTraceMetric(trace);
  299. XCTAssertTrue(traceMetric.perf_sessions != NULL);
  300. XCTAssertTrue(traceMetric.perf_sessions_count >= 2);
  301. firebase_perf_v1_PerfSession perfSession = traceMetric.perf_sessions[0];
  302. XCTAssertEqual(perfSession.session_verbosity[0],
  303. firebase_perf_v1_SessionVerbosity_GAUGES_AND_SYSTEM_EVENTS);
  304. XCTAssertEqualObjects(FPRDecodeString(perfSession.session_id), @"b");
  305. }
  306. /** Validates the verbosity ordering when no sessions are verbose. */
  307. - (void)testOrderingOfNonVerboseSessionsForTrace {
  308. FIRTrace *trace = [[FIRTrace alloc] initWithName:@"Random"];
  309. [trace start];
  310. FPRSessionDetails *session1 = [[FPRSessionDetails alloc] initWithSessionId:@"a"
  311. options:FPRSessionOptionsNone];
  312. FPRSessionDetails *session2 = [[FPRSessionDetails alloc] initWithSessionId:@"b"
  313. options:FPRSessionOptionsNone];
  314. trace.activeSessions = [@[ session1, session2 ] mutableCopy];
  315. [trace stop];
  316. firebase_perf_v1_TraceMetric traceMetric = FPRGetTraceMetric(trace);
  317. XCTAssertTrue(traceMetric.perf_sessions != NULL);
  318. XCTAssertTrue(traceMetric.perf_sessions_count >= 2);
  319. firebase_perf_v1_PerfSession perfSession = traceMetric.perf_sessions[0];
  320. XCTAssertEqualObjects(FPRDecodeString(perfSession.session_id), @"a");
  321. XCTAssertEqual(perfSession.session_verbosity_count, 0);
  322. }
  323. /** Validates if a session is not verbose, do not populate the session verbosity array. */
  324. - (void)testVerbosityArrayEmptyWhenTheSessionIsNotVerbose {
  325. FIRTrace *trace = [[FIRTrace alloc] initWithName:@"Random"];
  326. [trace start];
  327. FPRSessionDetails *session1 = [[FPRSessionDetails alloc] initWithSessionId:@"a"
  328. options:FPRSessionOptionsNone];
  329. trace.activeSessions = [@[ session1 ] mutableCopy];
  330. [trace stop];
  331. firebase_perf_v1_TraceMetric traceMetric = FPRGetTraceMetric(trace);
  332. XCTAssertTrue(traceMetric.perf_sessions != NULL);
  333. XCTAssertTrue(traceMetric.perf_sessions_count >= 1);
  334. firebase_perf_v1_PerfSession perfSession = traceMetric.perf_sessions[0];
  335. XCTAssertEqualObjects(FPRDecodeString(perfSession.session_id), @"a");
  336. XCTAssertEqual(perfSession.session_verbosity_count, 0);
  337. }
  338. /** Validates if the first session is a verbose session for a network trace. */
  339. - (void)testOrderingOfSessionsForNetworkTrace {
  340. NSURL *URL = [NSURL URLWithString:@"https://abc.com"];
  341. NSURLRequest *URLRequest = [NSURLRequest requestWithURL:URL];
  342. FPRNetworkTrace *trace = [[FPRNetworkTrace alloc] initWithURLRequest:URLRequest];
  343. [trace start];
  344. [trace checkpointState:FPRNetworkTraceCheckpointStateInitiated];
  345. [trace checkpointState:FPRNetworkTraceCheckpointStateResponseReceived];
  346. NSDictionary<NSString *, NSString *> *headerFields = @{@"Content-Type" : @"text/json"};
  347. NSHTTPURLResponse *response = [[NSHTTPURLResponse alloc] initWithURL:URLRequest.URL
  348. statusCode:404
  349. HTTPVersion:@"HTTP/1.1"
  350. headerFields:headerFields];
  351. NSError *error = [NSError errorWithDomain:NSURLErrorDomain code:-200 userInfo:nil];
  352. FPRSessionDetails *session1 = [[FPRSessionDetails alloc] initWithSessionId:@"a"
  353. options:FPRSessionOptionsNone];
  354. FPRSessionDetails *session2 =
  355. [[FPRSessionDetails alloc] initWithSessionId:@"b" options:FPRSessionOptionsGauges];
  356. trace.activeSessions = [@[ session1, session2 ] mutableCopy];
  357. [trace didReceiveData:[NSData data]];
  358. [trace didCompleteRequestWithResponse:response error:error];
  359. firebase_perf_v1_NetworkRequestMetric networkMetric = FPRGetNetworkRequestMetric(trace);
  360. XCTAssertTrue(networkMetric.perf_sessions != NULL);
  361. XCTAssertTrue(networkMetric.perf_sessions_count >= 2);
  362. firebase_perf_v1_PerfSession perfSession = networkMetric.perf_sessions[0];
  363. XCTAssertEqual(perfSession.session_verbosity[0],
  364. firebase_perf_v1_SessionVerbosity_GAUGES_AND_SYSTEM_EVENTS);
  365. XCTAssertEqualObjects(FPRDecodeString(perfSession.session_id), @"b");
  366. }
  367. /** Validates the verbosity ordering when no sessions are verbose for a network trace. */
  368. - (void)testOrderingOfNonVerboseSessionsForNetworkTrace {
  369. NSURL *URL = [NSURL URLWithString:@"https://abc.com"];
  370. NSURLRequest *URLRequest = [NSURLRequest requestWithURL:URL];
  371. FPRNetworkTrace *trace = [[FPRNetworkTrace alloc] initWithURLRequest:URLRequest];
  372. [trace start];
  373. [trace checkpointState:FPRNetworkTraceCheckpointStateInitiated];
  374. [trace checkpointState:FPRNetworkTraceCheckpointStateResponseReceived];
  375. NSDictionary<NSString *, NSString *> *headerFields = @{@"Content-Type" : @"text/json"};
  376. NSHTTPURLResponse *response = [[NSHTTPURLResponse alloc] initWithURL:URLRequest.URL
  377. statusCode:404
  378. HTTPVersion:@"HTTP/1.1"
  379. headerFields:headerFields];
  380. NSError *error = [NSError errorWithDomain:NSURLErrorDomain code:-200 userInfo:nil];
  381. FPRSessionDetails *session1 = [[FPRSessionDetails alloc] initWithSessionId:@"a"
  382. options:FPRSessionOptionsNone];
  383. FPRSessionDetails *session2 = [[FPRSessionDetails alloc] initWithSessionId:@"b"
  384. options:FPRSessionOptionsNone];
  385. trace.activeSessions = [@[ session1, session2 ] mutableCopy];
  386. [trace didReceiveData:[NSData data]];
  387. [trace didCompleteRequestWithResponse:response error:error];
  388. firebase_perf_v1_NetworkRequestMetric networkMetric = FPRGetNetworkRequestMetric(trace);
  389. XCTAssertTrue(networkMetric.perf_sessions != NULL);
  390. XCTAssertTrue(networkMetric.perf_sessions_count >= 2);
  391. firebase_perf_v1_PerfSession perfSession = networkMetric.perf_sessions[0];
  392. XCTAssertEqualObjects(FPRDecodeString(perfSession.session_id), @"a");
  393. XCTAssertEqual(perfSession.session_verbosity_count, 0);
  394. }
  395. /** Validates if a session is not verbose, do not populate the session verbosity array for network
  396. * trace.
  397. */
  398. - (void)testVerbosityArrayEmptyWhenTheSessionIsNotVerboseForNetworkTrace {
  399. NSURL *URL = [NSURL URLWithString:@"https://abc.com"];
  400. NSURLRequest *URLRequest = [NSURLRequest requestWithURL:URL];
  401. FPRNetworkTrace *trace = [[FPRNetworkTrace alloc] initWithURLRequest:URLRequest];
  402. [trace start];
  403. [trace checkpointState:FPRNetworkTraceCheckpointStateInitiated];
  404. [trace checkpointState:FPRNetworkTraceCheckpointStateResponseReceived];
  405. NSDictionary<NSString *, NSString *> *headerFields = @{@"Content-Type" : @"text/json"};
  406. NSHTTPURLResponse *response = [[NSHTTPURLResponse alloc] initWithURL:URLRequest.URL
  407. statusCode:404
  408. HTTPVersion:@"HTTP/1.1"
  409. headerFields:headerFields];
  410. NSError *error = [NSError errorWithDomain:NSURLErrorDomain code:-200 userInfo:nil];
  411. FPRSessionDetails *session1 = [[FPRSessionDetails alloc] initWithSessionId:@"a"
  412. options:FPRSessionOptionsNone];
  413. trace.activeSessions = [@[ session1 ] mutableCopy];
  414. [trace didReceiveData:[NSData data]];
  415. [trace didCompleteRequestWithResponse:response error:error];
  416. firebase_perf_v1_NetworkRequestMetric networkMetric = FPRGetNetworkRequestMetric(trace);
  417. XCTAssertTrue(networkMetric.perf_sessions != NULL);
  418. XCTAssertTrue(networkMetric.perf_sessions_count >= 1);
  419. firebase_perf_v1_PerfSession perfSession = networkMetric.perf_sessions[0];
  420. XCTAssertEqualObjects(FPRDecodeString(perfSession.session_id), @"a");
  421. XCTAssertEqual(perfSession.session_verbosity_count, 0);
  422. }
  423. @end