FPRProtoUtilsTest.m 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531
  1. // Copyright 2020 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/FPRProtoUtils.h"
  18. #import "FirebasePerformance/Sources/Public/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 FPRProtoUtilsTest : FPRTestCase
  29. @end
  30. @implementation FPRProtoUtilsTest
  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 PerfMetricMessage creation is successful. */
  42. - (void)testPerfMetricMessageCreation {
  43. NSString *appID = @"RandomAppID";
  44. FPRMSGPerfMetric *perfMetric = FPRGetPerfMetricMessage(appID);
  45. XCTAssertEqualObjects(perfMetric.applicationInfo.googleAppId, appID);
  46. XCTAssertNotNil(perfMetric.applicationInfo);
  47. }
  48. /** Tests if the application information is populated when creating a FPRMSGPerfMetric message. */
  49. - (void)testApplicationInfoMessage {
  50. FPRMSGPerfMetric *event = FPRGetPerfMetricMessage(@"appid");
  51. FPRMSGApplicationInfo *appInfo = event.applicationInfo;
  52. XCTAssertEqual(appInfo.googleAppId, @"appid");
  53. XCTAssertNotNil(appInfo.iosAppInfo.sdkVersion);
  54. XCTAssertNotNil(appInfo.iosAppInfo.bundleShortVersion);
  55. XCTAssertTrue((appInfo.iosAppInfo.mccMnc.length == 0) || (appInfo.iosAppInfo.mccMnc.length == 6));
  56. XCTAssertTrue(appInfo.iosAppInfo.networkConnectionInfo.networkType !=
  57. FPRMSGNetworkConnectionInfo_NetworkType_None);
  58. if (appInfo.iosAppInfo.networkConnectionInfo.networkType ==
  59. FPRMSGNetworkConnectionInfo_NetworkType_Mobile) {
  60. XCTAssertTrue(appInfo.iosAppInfo.networkConnectionInfo.mobileSubtype !=
  61. FPRMSGNetworkConnectionInfo_MobileSubtype_UnknownMobileSubtype);
  62. }
  63. }
  64. /** Validates that ApplicationInfoMessage carries global attributes. */
  65. - (void)testApplicationInfoMessageWithAttributes {
  66. FIRPerformance *performance = [FIRPerformance sharedInstance];
  67. [performance setValue:@"bar" forAttribute:@"foo"];
  68. FPRMSGPerfMetric *event = FPRGetPerfMetricMessage(@"appid");
  69. FPRMSGApplicationInfo *appInfo = event.applicationInfo;
  70. XCTAssertNotNil(appInfo.customAttributes);
  71. XCTAssertEqual(appInfo.customAttributes.allKeys.count, 1);
  72. NSDictionary *attributes = appInfo.customAttributes;
  73. XCTAssertEqual(attributes[@"foo"], @"bar");
  74. [performance removeAttribute:@"foo"];
  75. }
  76. /** Tests if mccMnc validation is catching non numerals. */
  77. - (void)testMccMncOnlyHasNumbers {
  78. NSString *mccMnc = FPRValidatedMccMnc(@"123", @"MKV");
  79. XCTAssertNil(mccMnc);
  80. mccMnc = FPRValidatedMccMnc(@"ABC", @"123");
  81. XCTAssertNil(mccMnc);
  82. }
  83. /** Tests if mccMnc validation is working. */
  84. - (void)testMccMnc {
  85. NSString *mccMnc = FPRValidatedMccMnc(@"123", @"22");
  86. XCTAssertNotNil(mccMnc);
  87. mccMnc = FPRValidatedMccMnc(@"123", @"223");
  88. XCTAssertNotNil(mccMnc);
  89. }
  90. /** Tests if mccMnc validation catches improper lengths. */
  91. - (void)testMccMncLength {
  92. NSString *mccMnc = FPRValidatedMccMnc(@"12", @"22");
  93. XCTAssertNil(mccMnc);
  94. mccMnc = FPRValidatedMccMnc(@"123", @"2");
  95. XCTAssertNil(mccMnc);
  96. }
  97. /** Validates that a valid FIRTrace object to Proto conversion is successful. */
  98. - (void)testTraceMetricMessageCreation {
  99. FIRTrace *trace = [[FIRTrace alloc] initWithName:@"Random"];
  100. [trace start];
  101. [trace startStageNamed:@"1"];
  102. [trace startStageNamed:@"2"];
  103. [trace incrementMetric:@"c1" byInt:2];
  104. [trace setValue:@"bar" forAttribute:@"foo"];
  105. [trace stop];
  106. FPRMSGTraceMetric *traceMetric = FPRGetTraceMetric(trace);
  107. XCTAssertNotNil(traceMetric);
  108. XCTAssertEqualObjects(traceMetric.name, @"Random");
  109. XCTAssertEqual(traceMetric.subtracesArray.count, 2);
  110. XCTAssertEqual(traceMetric.counters.count, 1);
  111. XCTAssertEqualObjects(traceMetric.subtracesArray[0].name, @"1");
  112. XCTAssertEqualObjects(traceMetric.subtracesArray[1].name, @"2");
  113. XCTAssertNotNil(traceMetric.customAttributes);
  114. XCTAssertEqual(traceMetric.customAttributes.allKeys.count, 1);
  115. NSDictionary *attributes = traceMetric.customAttributes;
  116. XCTAssertEqual(attributes[@"foo"], @"bar");
  117. }
  118. /** Validates that a valid FIRTrace object to Proto conversion has required fields. */
  119. - (void)testTraceMetricMessageCreationHasRequiredFields {
  120. FIRTrace *trace = [[FIRTrace alloc] initWithName:@"Random"];
  121. [trace start];
  122. [trace incrementMetric:@"c1" byInt:2];
  123. [trace stop];
  124. FPRMSGTraceMetric *traceMetric = FPRGetTraceMetric(trace);
  125. XCTAssertNotNil(traceMetric);
  126. XCTAssertTrue(traceMetric.hasName);
  127. XCTAssertTrue(traceMetric.hasClientStartTimeUs);
  128. XCTAssertTrue(traceMetric.hasDurationUs);
  129. XCTAssertTrue(traceMetric.hasIsAuto);
  130. }
  131. /** Validates the session details inside trace metric. */
  132. - (void)testTraceMetricMessageHasSessionDetails {
  133. FIRTrace *trace = [[FIRTrace alloc] initWithName:@"Random"];
  134. [trace start];
  135. [trace incrementMetric:@"c1" byInt:2];
  136. FPRSessionDetails *session1 = [[FPRSessionDetails alloc] initWithSessionId:@"a"
  137. options:FPRSessionOptionsNone];
  138. FPRSessionDetails *session2 =
  139. [[FPRSessionDetails alloc] initWithSessionId:@"b" options:FPRSessionOptionsGauges];
  140. trace.activeSessions = [@[ session1, session2 ] mutableCopy];
  141. [trace stop];
  142. FPRMSGTraceMetric *traceMetric = FPRGetTraceMetric(trace);
  143. XCTAssertNotNil(traceMetric);
  144. XCTAssertNotNil(traceMetric.perfSessionsArray);
  145. XCTAssertTrue(traceMetric.perfSessionsArray.count >= 2);
  146. }
  147. /** Validates that an invalid FIRTrace object to Proto conversion is unsuccessful. */
  148. - (void)testTraceMetricMessageCreationForInvalidTrace {
  149. #pragma clang diagnostic push
  150. #pragma clang diagnostic ignored "-Wnonnull"
  151. XCTAssertNil(FPRGetTraceMetric(nil));
  152. #pragma clang diagnostic pop
  153. }
  154. /** Validates that the FPRNetworkTrace object to Proto conversion is successful. */
  155. - (void)testNetworkTraceMetricMessage {
  156. NSURL *URL = [NSURL URLWithString:@"https://abc.com"];
  157. NSURLRequest *URLRequest = [NSURLRequest requestWithURL:URL];
  158. FPRNetworkTrace *trace = [[FPRNetworkTrace alloc] initWithURLRequest:URLRequest];
  159. [trace start];
  160. [trace checkpointState:FPRNetworkTraceCheckpointStateInitiated];
  161. [trace checkpointState:FPRNetworkTraceCheckpointStateResponseReceived];
  162. NSDictionary<NSString *, NSString *> *headerFields = @{@"Content-Type" : @"text/json"};
  163. NSHTTPURLResponse *response = [[NSHTTPURLResponse alloc] initWithURL:URLRequest.URL
  164. statusCode:404
  165. HTTPVersion:@"HTTP/1.1"
  166. headerFields:headerFields];
  167. NSError *error = [NSError errorWithDomain:NSURLErrorDomain code:-200 userInfo:nil];
  168. [trace didReceiveData:[NSData data]];
  169. [trace didCompleteRequestWithResponse:response error:error];
  170. FPRMSGNetworkRequestMetric *networkMetric = FPRGetNetworkRequestMetric(trace);
  171. XCTAssertEqualObjects(networkMetric.URL, URL.absoluteString);
  172. XCTAssertEqual(networkMetric.HTTPMethod, FPRMSGNetworkRequestMetric_HttpMethod_Get);
  173. XCTAssertEqual(networkMetric.networkClientErrorReason,
  174. FPRMSGNetworkRequestMetric_NetworkClientErrorReason_GenericClientError);
  175. XCTAssertEqual(networkMetric.HTTPResponseCode, 404);
  176. XCTAssertEqualObjects(networkMetric.responseContentType, @"text/json");
  177. }
  178. /** Validates that the FPRNetworkTrace object to Proto conversion has required fields for a valid
  179. * response.
  180. */
  181. - (void)testNetworkTraceMetricMessageHasAllRequiredFields {
  182. NSURL *URL = [NSURL URLWithString:@"https://abc.com"];
  183. NSURLRequest *URLRequest = [NSURLRequest requestWithURL:URL];
  184. FPRNetworkTrace *trace = [[FPRNetworkTrace alloc] initWithURLRequest:URLRequest];
  185. [trace start];
  186. [trace checkpointState:FPRNetworkTraceCheckpointStateInitiated];
  187. [trace checkpointState:FPRNetworkTraceCheckpointStateResponseReceived];
  188. NSDictionary<NSString *, NSString *> *headerFields = @{@"Content-Type" : @"text/json"};
  189. NSHTTPURLResponse *response = [[NSHTTPURLResponse alloc] initWithURL:URLRequest.URL
  190. statusCode:404
  191. HTTPVersion:@"HTTP/1.1"
  192. headerFields:headerFields];
  193. NSError *error = [NSError errorWithDomain:NSURLErrorDomain code:-200 userInfo:nil];
  194. [trace didReceiveData:[NSData data]];
  195. [trace didCompleteRequestWithResponse:response error:error];
  196. FPRMSGNetworkRequestMetric *networkMetric = FPRGetNetworkRequestMetric(trace);
  197. XCTAssertTrue(networkMetric.hasURL);
  198. XCTAssertTrue(networkMetric.hasClientStartTimeUs);
  199. XCTAssertTrue(networkMetric.hasHTTPMethod);
  200. XCTAssertTrue(networkMetric.hasResponsePayloadBytes);
  201. XCTAssertTrue(networkMetric.hasNetworkClientErrorReason);
  202. XCTAssertTrue(networkMetric.hasHTTPResponseCode);
  203. XCTAssertTrue(networkMetric.hasResponseContentType);
  204. XCTAssertTrue(networkMetric.hasTimeToResponseCompletedUs);
  205. }
  206. /** Validates that an invalid FPRNetworkTrace object to Proto conversion is unsuccessful. */
  207. - (void)testNetworkTraceMetricMessageCreationForInvalidTrace {
  208. #pragma clang diagnostic push
  209. #pragma clang diagnostic ignored "-Wnonnull"
  210. XCTAssertNil(FPRGetNetworkRequestMetric(nil));
  211. #pragma clang diagnostic pop
  212. }
  213. /** Validates that application process state conversion to proto enum type is successful. */
  214. - (void)testApplicationProcessStateConversion {
  215. XCTAssertEqual(FPRMSGApplicationProcessState_Background,
  216. FPRApplicationProcessState(FPRTraceStateBackgroundOnly));
  217. XCTAssertEqual(FPRMSGApplicationProcessState_Foreground,
  218. FPRApplicationProcessState(FPRTraceStateForegroundOnly));
  219. XCTAssertEqual(FPRMSGApplicationProcessState_ForegroundBackground,
  220. FPRApplicationProcessState(FPRTraceStateBackgroundAndForeground));
  221. XCTAssertEqual(FPRMSGApplicationProcessState_ApplicationProcessStateUnknown,
  222. FPRApplicationProcessState(FPRTraceStateUnknown));
  223. // Try with some random value should say the application state is unknown.
  224. XCTAssertEqual(FPRMSGApplicationProcessState_ApplicationProcessStateUnknown,
  225. FPRApplicationProcessState(100));
  226. }
  227. /** Validates if network object creation works. */
  228. - (void)testNetworkInfoObjectCreation {
  229. XCTAssertNotNil(FPRNetworkInfo());
  230. }
  231. /** Validates if network events are dropped when there is not valid response code. */
  232. - (void)testDroppingNetworkEventsWithInvalidStatusCode {
  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. [trace didReceiveData:[NSData data]];
  240. [trace didCompleteRequestWithResponse:nil error:nil];
  241. XCTAssertNil(FPRGetNetworkRequestMetric(trace));
  242. }
  243. /** Validates the session details inside trace metric. */
  244. - (void)testNetworkRequestMetricMessageHasSessionDetails {
  245. NSURL *URL = [NSURL URLWithString:@"https://abc.com"];
  246. NSURLRequest *URLRequest = [NSURLRequest requestWithURL:URL];
  247. FPRNetworkTrace *trace = [[FPRNetworkTrace alloc] initWithURLRequest:URLRequest];
  248. [trace start];
  249. [trace checkpointState:FPRNetworkTraceCheckpointStateInitiated];
  250. [trace checkpointState:FPRNetworkTraceCheckpointStateResponseReceived];
  251. NSDictionary<NSString *, NSString *> *headerFields = @{@"Content-Type" : @"text/json"};
  252. NSHTTPURLResponse *response = [[NSHTTPURLResponse alloc] initWithURL:URLRequest.URL
  253. statusCode:404
  254. HTTPVersion:@"HTTP/1.1"
  255. headerFields:headerFields];
  256. NSError *error = [NSError errorWithDomain:NSURLErrorDomain code:-200 userInfo:nil];
  257. FPRSessionDetails *session1 = [[FPRSessionDetails alloc] initWithSessionId:@"a"
  258. options:FPRSessionOptionsNone];
  259. FPRSessionDetails *session2 =
  260. [[FPRSessionDetails alloc] initWithSessionId:@"b" options:FPRSessionOptionsGauges];
  261. trace.activeSessions = [@[ session1, session2 ] mutableCopy];
  262. [trace didReceiveData:[NSData data]];
  263. [trace didCompleteRequestWithResponse:response error:error];
  264. FPRMSGNetworkRequestMetric *networkMetric = FPRGetNetworkRequestMetric(trace);
  265. XCTAssertNotNil(networkMetric);
  266. XCTAssertNotNil(networkMetric.perfSessionsArray);
  267. XCTAssertTrue(networkMetric.perfSessionsArray.count >= 2);
  268. }
  269. /** Validates the gauge metric proto packaging works with proper conversions. */
  270. - (void)testMemoryMetricProtoConversion {
  271. NSMutableArray *gauges = [[NSMutableArray alloc] init];
  272. NSDate *date = [NSDate date];
  273. FPRMemoryGaugeData *memoryData = [[FPRMemoryGaugeData alloc] initWithCollectionTime:date
  274. heapUsed:5 * 1024
  275. heapAvailable:10 * 1024];
  276. [gauges addObject:memoryData];
  277. FPRMSGGaugeMetric *gaugeMetric = FPRGetGaugeMetric(gauges, @"abc");
  278. XCTAssertNotNil(gaugeMetric);
  279. XCTAssertEqual(gaugeMetric.cpuMetricReadingsArray_Count, 0);
  280. XCTAssertEqual(gaugeMetric.iosMemoryReadingsArray_Count, 1);
  281. FPRMSGIosMemoryReading *memoryReading = [gaugeMetric.iosMemoryReadingsArray firstObject];
  282. XCTAssertEqual(memoryReading.usedAppHeapMemoryKb, 5);
  283. XCTAssertEqual(memoryReading.freeAppHeapMemoryKb, 10);
  284. }
  285. /** Validates the gauge metric proto packaging works. */
  286. - (void)testGaugeMetricProtoPacking {
  287. NSMutableArray *gauges = [[NSMutableArray alloc] init];
  288. for (int i = 0; i < 5; i++) {
  289. NSDate *date = [NSDate date];
  290. FPRCPUGaugeData *cpuData = [[FPRCPUGaugeData alloc] initWithCollectionTime:date
  291. systemTime:100
  292. userTime:200];
  293. FPRMemoryGaugeData *memoryData = [[FPRMemoryGaugeData alloc] initWithCollectionTime:date
  294. heapUsed:100
  295. heapAvailable:200];
  296. [gauges addObject:cpuData];
  297. [gauges addObject:memoryData];
  298. }
  299. FPRMSGGaugeMetric *gaugeMetric = FPRGetGaugeMetric(gauges, @"abc");
  300. XCTAssertNotNil(gaugeMetric);
  301. XCTAssertEqual(gaugeMetric.cpuMetricReadingsArray_Count, 5);
  302. XCTAssertEqual(gaugeMetric.iosMemoryReadingsArray_Count, 5);
  303. }
  304. /** Validates the gauge metric proto packaging does not create an empty package. */
  305. - (void)testGaugeMetricProtoPackingWithEmptyData {
  306. NSMutableArray *gauges = [[NSMutableArray alloc] init];
  307. FPRMSGGaugeMetric *gaugeMetric1 = FPRGetGaugeMetric(gauges, @"abc");
  308. XCTAssertNil(gaugeMetric1);
  309. FPRMSGGaugeMetric *gaugeMetric2 = FPRGetGaugeMetric(gauges, @"");
  310. XCTAssertNil(gaugeMetric2);
  311. }
  312. /** Validates if the first session is a verbose session for a trace. */
  313. - (void)testOrderingOfSessionsForTrace {
  314. FIRTrace *trace = [[FIRTrace alloc] initWithName:@"Random"];
  315. [trace start];
  316. FPRSessionDetails *session1 = [[FPRSessionDetails alloc] initWithSessionId:@"a"
  317. options:FPRSessionOptionsNone];
  318. FPRSessionDetails *session2 =
  319. [[FPRSessionDetails alloc] initWithSessionId:@"b" options:FPRSessionOptionsGauges];
  320. trace.activeSessions = [@[ session1, session2 ] mutableCopy];
  321. [trace stop];
  322. FPRMSGTraceMetric *traceMetric = FPRGetTraceMetric(trace);
  323. XCTAssertNotNil(traceMetric);
  324. XCTAssertNotNil(traceMetric.perfSessionsArray);
  325. XCTAssertTrue(traceMetric.perfSessionsArray.count >= 2);
  326. FPRMSGPerfSession *perfSession = [traceMetric.perfSessionsArray firstObject];
  327. GPBEnumArray *firstSessionVerbosity = perfSession.sessionVerbosityArray;
  328. XCTAssertEqual([firstSessionVerbosity valueAtIndex:0],
  329. FPRMSGSessionVerbosity_GaugesAndSystemEvents);
  330. XCTAssertEqualObjects(perfSession.sessionId, @"b");
  331. }
  332. /** Validates the verbosity ordering when no sessions are verbose. */
  333. - (void)testOrderingOfNonVerboseSessionsForTrace {
  334. FIRTrace *trace = [[FIRTrace alloc] initWithName:@"Random"];
  335. [trace start];
  336. FPRSessionDetails *session1 = [[FPRSessionDetails alloc] initWithSessionId:@"a"
  337. options:FPRSessionOptionsNone];
  338. FPRSessionDetails *session2 = [[FPRSessionDetails alloc] initWithSessionId:@"b"
  339. options:FPRSessionOptionsNone];
  340. trace.activeSessions = [@[ session1, session2 ] mutableCopy];
  341. [trace stop];
  342. FPRMSGTraceMetric *traceMetric = FPRGetTraceMetric(trace);
  343. XCTAssertNotNil(traceMetric);
  344. XCTAssertNotNil(traceMetric.perfSessionsArray);
  345. XCTAssertTrue(traceMetric.perfSessionsArray.count >= 2);
  346. FPRMSGPerfSession *perfSession = [traceMetric.perfSessionsArray firstObject];
  347. XCTAssertEqualObjects(perfSession.sessionId, @"a");
  348. XCTAssertEqual(perfSession.sessionVerbosityArray_Count, 0);
  349. }
  350. /** Validates if a session is not verbose, do not populate the session verbosity array. */
  351. - (void)testVerbosityArrayEmptyWhenTheSessionIsNotVerbose {
  352. FIRTrace *trace = [[FIRTrace alloc] initWithName:@"Random"];
  353. [trace start];
  354. FPRSessionDetails *session1 = [[FPRSessionDetails alloc] initWithSessionId:@"a"
  355. options:FPRSessionOptionsNone];
  356. trace.activeSessions = [@[ session1 ] mutableCopy];
  357. [trace stop];
  358. FPRMSGTraceMetric *traceMetric = FPRGetTraceMetric(trace);
  359. XCTAssertNotNil(traceMetric);
  360. XCTAssertNotNil(traceMetric.perfSessionsArray);
  361. XCTAssertTrue(traceMetric.perfSessionsArray.count >= 1);
  362. FPRMSGPerfSession *perfSession = [traceMetric.perfSessionsArray firstObject];
  363. XCTAssertEqualObjects(perfSession.sessionId, @"a");
  364. XCTAssertEqual(perfSession.sessionVerbosityArray_Count, 0);
  365. }
  366. /** Validates if the first session is a verbose session for a network trace. */
  367. - (void)testOrderingOfSessionsForNetworkTrace {
  368. NSURL *URL = [NSURL URLWithString:@"https://abc.com"];
  369. NSURLRequest *URLRequest = [NSURLRequest requestWithURL:URL];
  370. FPRNetworkTrace *trace = [[FPRNetworkTrace alloc] initWithURLRequest:URLRequest];
  371. [trace start];
  372. [trace checkpointState:FPRNetworkTraceCheckpointStateInitiated];
  373. [trace checkpointState:FPRNetworkTraceCheckpointStateResponseReceived];
  374. NSDictionary<NSString *, NSString *> *headerFields = @{@"Content-Type" : @"text/json"};
  375. NSHTTPURLResponse *response = [[NSHTTPURLResponse alloc] initWithURL:URLRequest.URL
  376. statusCode:404
  377. HTTPVersion:@"HTTP/1.1"
  378. headerFields:headerFields];
  379. NSError *error = [NSError errorWithDomain:NSURLErrorDomain code:-200 userInfo:nil];
  380. FPRSessionDetails *session1 = [[FPRSessionDetails alloc] initWithSessionId:@"a"
  381. options:FPRSessionOptionsNone];
  382. FPRSessionDetails *session2 =
  383. [[FPRSessionDetails alloc] initWithSessionId:@"b" options:FPRSessionOptionsGauges];
  384. trace.activeSessions = [@[ session1, session2 ] mutableCopy];
  385. [trace didReceiveData:[NSData data]];
  386. [trace didCompleteRequestWithResponse:response error:error];
  387. FPRMSGNetworkRequestMetric *networkMetric = FPRGetNetworkRequestMetric(trace);
  388. XCTAssertNotNil(networkMetric);
  389. XCTAssertNotNil(networkMetric.perfSessionsArray);
  390. XCTAssertTrue(networkMetric.perfSessionsArray.count >= 2);
  391. FPRMSGPerfSession *perfSession = [networkMetric.perfSessionsArray firstObject];
  392. GPBEnumArray *firstSessionVerbosity = perfSession.sessionVerbosityArray;
  393. XCTAssertEqual([firstSessionVerbosity valueAtIndex:0],
  394. FPRMSGSessionVerbosity_GaugesAndSystemEvents);
  395. XCTAssertEqualObjects(perfSession.sessionId, @"b");
  396. }
  397. /** Validates the verbosity ordering when no sessions are verbose for a network trace. */
  398. - (void)testOrderingOfNonVerboseSessionsForNetworkTrace {
  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. FPRSessionDetails *session2 = [[FPRSessionDetails alloc] initWithSessionId:@"b"
  414. options:FPRSessionOptionsNone];
  415. trace.activeSessions = [@[ session1, session2 ] mutableCopy];
  416. [trace didReceiveData:[NSData data]];
  417. [trace didCompleteRequestWithResponse:response error:error];
  418. FPRMSGNetworkRequestMetric *networkMetric = FPRGetNetworkRequestMetric(trace);
  419. XCTAssertNotNil(networkMetric);
  420. XCTAssertNotNil(networkMetric.perfSessionsArray);
  421. XCTAssertTrue(networkMetric.perfSessionsArray.count >= 2);
  422. FPRMSGPerfSession *perfSession = [networkMetric.perfSessionsArray firstObject];
  423. XCTAssertEqualObjects(perfSession.sessionId, @"a");
  424. XCTAssertEqual(perfSession.sessionVerbosityArray_Count, 0);
  425. }
  426. /** Validates if a session is not verbose, do not populate the session verbosity array for network
  427. * trace.
  428. */
  429. - (void)testVerbosityArrayEmptyWhenTheSessionIsNotVerboseForNetworkTrace {
  430. NSURL *URL = [NSURL URLWithString:@"https://abc.com"];
  431. NSURLRequest *URLRequest = [NSURLRequest requestWithURL:URL];
  432. FPRNetworkTrace *trace = [[FPRNetworkTrace alloc] initWithURLRequest:URLRequest];
  433. [trace start];
  434. [trace checkpointState:FPRNetworkTraceCheckpointStateInitiated];
  435. [trace checkpointState:FPRNetworkTraceCheckpointStateResponseReceived];
  436. NSDictionary<NSString *, NSString *> *headerFields = @{@"Content-Type" : @"text/json"};
  437. NSHTTPURLResponse *response = [[NSHTTPURLResponse alloc] initWithURL:URLRequest.URL
  438. statusCode:404
  439. HTTPVersion:@"HTTP/1.1"
  440. headerFields:headerFields];
  441. NSError *error = [NSError errorWithDomain:NSURLErrorDomain code:-200 userInfo:nil];
  442. FPRSessionDetails *session1 = [[FPRSessionDetails alloc] initWithSessionId:@"a"
  443. options:FPRSessionOptionsNone];
  444. trace.activeSessions = [@[ session1 ] mutableCopy];
  445. [trace didReceiveData:[NSData data]];
  446. [trace didCompleteRequestWithResponse:response error:error];
  447. FPRMSGNetworkRequestMetric *networkMetric = FPRGetNetworkRequestMetric(trace);
  448. XCTAssertNotNil(networkMetric);
  449. XCTAssertNotNil(networkMetric.perfSessionsArray);
  450. XCTAssertTrue(networkMetric.perfSessionsArray.count >= 1);
  451. FPRMSGPerfSession *perfSession = [networkMetric.perfSessionsArray firstObject];
  452. XCTAssertEqualObjects(perfSession.sessionId, @"a");
  453. XCTAssertEqual(perfSession.sessionVerbosityArray_Count, 0);
  454. }
  455. @end