FPRNanoPbUtilsTest.m 24 KB

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