| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414 |
- // Copyright 2020 Google LLC
- //
- // Licensed under the Apache License, Version 2.0 (the "License");
- // you may not use this file except in compliance with the License.
- // You may obtain a copy of the License at
- //
- // http://www.apache.org/licenses/LICENSE-2.0
- //
- // Unless required by applicable law or agreed to in writing, software
- // distributed under the License is distributed on an "AS IS" BASIS,
- // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- // See the License for the specific language governing permissions and
- // limitations under the License.
- #import <XCTest/XCTest.h>
- #import "FirebasePerformance/Sources/Configurations/FPRConfigurations+Private.h"
- #import "FirebasePerformance/Sources/Loggers/FPRGDTCCLogger.h"
- #import "FirebasePerformance/Sources/Loggers/FPRGDTCCLogger_Private.h"
- #import "FirebasePerformance/Sources/Loggers/FPRGDTLogSampler.h"
- #import "FirebasePerformance/Sources/Loggers/FPRGDTRateLimiter.h"
- #import "FirebasePerformance/Tests/Unit/Configurations/FPRFakeRemoteConfig.h"
- #import "FirebasePerformance/Tests/Unit/Configurations/FPRFakeRemoteConfigFlags.h"
- #import "FirebasePerformance/Tests/Unit/Fakes/FPRFakeConfigurations.h"
- #import "FirebasePerformance/Tests/Unit/FPRTestUtils.h"
- #import <GoogleDataTransport/GoogleDataTransport.h>
- #import "GoogleDataTransport/GDTCORLibrary/Private/GDTCORTransport_Private.h"
- #import "GoogleDataTransport/GDTCORTests/Common/Fakes/GDTCORTransportFake.h"
- #import "FirebasePerformance/ProtoSupport/PerfMetric.pbobjc.h"
- @interface FPRGDTCCLoggerTest : XCTestCase
- /** Clearcut logger used to dispatch events to Clearcut using Google Data Transport. */
- @property(nonatomic) FPRGDTCCLogger *logger;
- /** A fake for the GDTCORTransport for clearcut. */
- @property(nonatomic) GDTCORTransportFake *transportCCTFake;
- /** A fake for the GDTCORTransport for FLL. */
- @property(nonatomic) GDTCORTransportFake *transportFLLFake;
- /** The log source for the FPRGDTCCLogger to be used. */
- @property(nonatomic) NSInteger logSource;
- /** The target backend of the GDTCORTransport - Clearcut. */
- @property(nonatomic) NSInteger targetCCT;
- /** The target backend of the GDTCORTransport - FLL. */
- @property(nonatomic) NSInteger targetFL;
- @end
- @implementation FPRGDTCCLoggerTest
- - (void)setUp {
- [super setUp];
- self.logSource = 1;
- self.targetCCT = kGDTCORTargetCCT; // CCT
- self.targetFL = kGDTCORTargetFLL; // FLL
- self.logger = [[FPRGDTCCLogger alloc] initWithLogSource:self.logSource];
- self.logger.isSimulator = YES;
- // Set up for Fake logging.
- self.transportCCTFake =
- [[GDTCORTransportFake alloc] initWithMappingID:@(self.logSource).stringValue
- transformers:nil
- target:self.targetCCT];
- self.transportFLLFake =
- [[GDTCORTransportFake alloc] initWithMappingID:@(self.logSource).stringValue
- transformers:nil
- target:self.targetFL];
- self.logger.gdtcctTransport = self.transportCCTFake;
- self.logger.gdtfllTransport = self.transportFLLFake;
- }
- - (void)tearDown {
- [self.transportCCTFake reset];
- [self.transportFLLFake reset];
- [super tearDown];
- }
- /** Tests the designated initializer. */
- - (void)testInitWithLogSource {
- NSInteger randomLogSource = 1;
- FPRGDTCCLogger *logger = [[FPRGDTCCLogger alloc] initWithLogSource:randomLogSource];
- XCTAssertNotNil(logger);
- XCTAssertEqual(logger.logSource, randomLogSource);
- XCTAssertNotNil(logger.gdtcctTransport);
- }
- /** Tests the GDTCCLogger is generated with designated transformers. */
- - (void)testInitWithTransformers {
- NSInteger randomLogSource = 1;
- FPRGDTCCLogger *logger = [[FPRGDTCCLogger alloc] initWithLogSource:randomLogSource];
- XCTAssertNotNil(logger);
- XCTAssertNotNil(logger.gdtcctTransport);
- XCTAssertNotNil(logger.gdtfllTransport);
- // Clearcut logger tests
- XCTAssertEqual(logger.gdtcctTransport.transformers.count, 2);
- XCTAssertTrue(
- [logger.gdtcctTransport.transformers.firstObject isKindOfClass:[FPRGDTLogSampler class]]);
- XCTAssertTrue(
- [logger.gdtcctTransport.transformers.lastObject isKindOfClass:[FPRGDTRateLimiter class]]);
- // GDT logger tests
- XCTAssertEqual(logger.gdtfllTransport.transformers.count, 2);
- XCTAssertTrue(
- [logger.gdtfllTransport.transformers.firstObject isKindOfClass:[FPRGDTLogSampler class]]);
- XCTAssertTrue(
- [logger.gdtfllTransport.transformers.lastObject isKindOfClass:[FPRGDTRateLimiter class]]);
- }
- /** Validate all the required fields are set when logging an Event. */
- - (void)testValidateEventFieldsToBeLogged {
- // Log the event.
- FPRMSGPerfMetric *event = [FPRTestUtils createRandomPerfMetric:@"t1"];
- event.applicationInfo.appInstanceId = @"abc";
- [self.logger logEvent:event];
- // Note: Refer "dispatch_async issue" in "testLogMultipleEvents".
- dispatch_sync(self.logger.queue, ^{
- // Fetch the logged event.
- NSArray<GDTCOREvent *> *gdtCorEventArray = [self.transportCCTFake logEvents];
- GDTCOREvent *gdtCorEvent = gdtCorEventArray.firstObject;
- // Validate that only 1 event is logged.
- XCTAssertEqual(gdtCorEventArray.count, 1);
- // Validate that the corresponding GDTEvent to be logged is not nil.
- XCTAssertNotNil(gdtCorEvent.dataObject);
- // Validate that the mapping ID is correctly associated.
- XCTAssertEqual(gdtCorEvent.mappingID, @(self.logSource).stringValue);
- // Validate that the target is correctly associated.
- XCTAssertEqual(gdtCorEvent.target, self.targetCCT);
- // Validate that the QoS is set to GDTCOREventQoSFast in debug mode.
- XCTAssertEqual(gdtCorEvent.qosTier, GDTCOREventQoSFast);
- });
- }
- /** Validate that multiple events are logged correctly. */
- - (void)testLogMultipleEvents {
- // Log the events.
- int logCount = 3;
- for (int i = 1; i <= logCount; i++) {
- NSString *traceName = [NSString stringWithFormat:@"t%d", i];
- FPRMSGPerfMetric *event = [FPRTestUtils createRandomPerfMetric:traceName];
- event.applicationInfo.appInstanceId = @"abc";
- [self.logger logEvent:event];
- }
- // Note: "dispatch_async issue"
- //
- // There's a race condition between we checking the logEvents property on the "transportFake"
- // and writing to that property using the "logEvent" method from the "logger" class
- // because we are dispatching that event in a "dispatch_async" queue.
- //
- // To mitigate this we want that block to finish executing, so we call "dispatch_sync"
- // on the same "queue" and perform all the validations inside that block.
- //
- // This is because it will block the current thread until all queued blocks are done.
- dispatch_sync(self.logger.queue, ^{
- // Fetch the logged events.
- NSArray<GDTCOREvent *> *gdtCorEventArray = [self.transportCCTFake logEvents];
- // Validate that the count of logged events is what is expected.
- XCTAssertEqual(gdtCorEventArray.count, logCount);
- });
- }
- /** Validate events' QoS are set to GDTCOREventQoSFast when running in Simulator. */
- - (void)testEventsSimulatorQoS {
- self.logger.isSimulator = YES;
- // Log the event.
- FPRMSGPerfMetric *event = [FPRTestUtils createRandomPerfMetric:@"t1"];
- event.applicationInfo.appInstanceId = @"abc";
- [self.logger logEvent:event];
- // Note: Refer "dispatch_async issue" in "testLogMultipleEvents".
- dispatch_sync(self.logger.queue, ^{
- // Fetch the logged event.
- NSArray<GDTCOREvent *> *gdtCorEventArray = [self.transportCCTFake logEvents];
- GDTCOREvent *gdtCorEvent = gdtCorEventArray.firstObject;
- // Validate that the QoS is set to GDTCOREventQoSFast.
- XCTAssertEqual(gdtCorEvent.qosTier, GDTCOREventQoSFast);
- });
- }
- /** Validate events' QoS are set to GDTCOREventQosDefault in actual device. */
- - (void)testEventsRealDeviceQoS {
- self.logger.isSimulator = NO;
- // Log the event.
- FPRMSGPerfMetric *event = [FPRTestUtils createRandomPerfMetric:@"t1"];
- event.applicationInfo.appInstanceId = @"abc";
- [self.logger logEvent:event];
- // Note: Refer "dispatch_async issue" in "testLogMultipleEvents".
- dispatch_sync(self.logger.queue, ^{
- // Fetch the logged event.
- NSArray<GDTCOREvent *> *gdtCorEventArray = [self.transportCCTFake logEvents];
- GDTCOREvent *gdtCorEvent = gdtCorEventArray.firstObject;
- // Validate that the QoS is set to GDTCOREventQosDefault.
- XCTAssertEqual(gdtCorEvent.qosTier, GDTCOREventQosDefault);
- });
- }
- /** Validate if the events are dispatched to FLL if installation ID seed is smaller than
- * transport percentage. */
- - (void)testEventDispatchedToFllWithInstallationIdSeedSeedSmallerThanTransportPercentage {
- self.logger.isSimulator = NO;
- // Initialize the configurations
- FPRFakeConfigurations *fakeConfigurations =
- [[FPRFakeConfigurations alloc] initWithSources:FPRConfigurationSourceRemoteConfig];
- // Set fakes to the configurations
- FPRFakeRemoteConfig *fakeRemoteConfig = [[FPRFakeRemoteConfig alloc] init];
- FPRFakeRemoteConfigFlags *fakeConfigFlags =
- [[FPRFakeRemoteConfigFlags alloc] initWithRemoteConfig:(FIRRemoteConfig *)fakeRemoteConfig];
- fakeConfigFlags.userDefaults = [[NSUserDefaults alloc] init];
- fakeConfigurations.remoteConfigFlags = fakeConfigFlags;
- self.logger.configurations = fakeConfigurations;
- // Condition (1): when FLL transport percentage = 60% (greater than installation seed)
- fakeConfigurations.fllTransportPercentageValue = 60.00;
- // Log 2 random Perf events
- FPRMSGPerfMetric *event1 = [FPRTestUtils createRandomPerfMetric:@"t1"];
- event1.applicationInfo.appInstanceId = @"abc"; // Installation ID seed of "abc" is 54.0.
- FPRMSGPerfMetric *event2 = [FPRTestUtils createRandomPerfMetric:@"t2"];
- event2.applicationInfo.appInstanceId = @"abc"; // Installation ID seed of "abc" is 54.0.
- [self.logger logEvent:event1];
- [self.logger logEvent:event2];
- // Verify: that both events are logged to FLL
- dispatch_sync(self.logger.queue, ^{
- // Fetch the logged event
- NSArray<GDTCOREvent *> *gdtCorFllEventArray = [self.transportFLLFake logEvents];
- NSArray<GDTCOREvent *> *gdtCorCCTEventArray = [self.transportCCTFake logEvents];
- XCTAssertTrue(gdtCorFllEventArray.count == 2);
- XCTAssertTrue(gdtCorCCTEventArray.count == 0);
- });
- }
- /** Validate if the events are not dispatched to FLL if installation ID seed is greater than
- * transport percentage. */
- - (void)testEventDispatchedNotToFllWithInstallationIdGreaterThanTransportPercentage {
- self.logger.isSimulator = NO;
- // Initialize the configurations
- FPRFakeConfigurations *fakeConfigurations =
- [[FPRFakeConfigurations alloc] initWithSources:FPRConfigurationSourceRemoteConfig];
- // Set fakes to the configurations
- FPRFakeRemoteConfig *fakeRemoteConfig = [[FPRFakeRemoteConfig alloc] init];
- FPRFakeRemoteConfigFlags *fakeConfigFlags =
- [[FPRFakeRemoteConfigFlags alloc] initWithRemoteConfig:(FIRRemoteConfig *)fakeRemoteConfig];
- fakeConfigFlags.userDefaults = [[NSUserDefaults alloc] init];
- fakeConfigurations.remoteConfigFlags = fakeConfigFlags;
- self.logger.configurations = fakeConfigurations;
- // Condition (1): when FLL transport percentage = 50% (less that installation seed)
- fakeConfigurations.fllTransportPercentageValue = 50.00;
- // Log 2 random Perf events
- FPRMSGPerfMetric *event1 = [FPRTestUtils createRandomPerfMetric:@"t1"];
- event1.applicationInfo.appInstanceId = @"abc"; // Installation ID seed of "abc" is 54.0.
- FPRMSGPerfMetric *event2 = [FPRTestUtils createRandomPerfMetric:@"t2"];
- event2.applicationInfo.appInstanceId = @"abc"; // Installation ID seed of "abc" is 54.0.
- [self.logger logEvent:event1];
- [self.logger logEvent:event2];
- // Verify: that both events are logged to Clearcut
- dispatch_sync(self.logger.queue, ^{
- // Fetch the logged event
- NSArray<GDTCOREvent *> *gdtCorFllEventArray = [self.transportFLLFake logEvents];
- NSArray<GDTCOREvent *> *gdtCorCCTEventArray = [self.transportCCTFake logEvents];
- XCTAssertTrue(gdtCorFllEventArray.count == 0);
- XCTAssertTrue(gdtCorCCTEventArray.count == 2);
- });
- }
- /** Validate if the events are dispatched to FLL if installation ID seed equals to transport
- * percentage. */
- - (void)testEventDispatchedToFllWithInstallationIdSeedEqualsToTransportPercentage {
- self.logger.isSimulator = NO;
- // Initialize the configurations
- FPRFakeConfigurations *fakeConfigurations =
- [[FPRFakeConfigurations alloc] initWithSources:FPRConfigurationSourceRemoteConfig];
- // Set fakes to the configurations
- FPRFakeRemoteConfig *fakeRemoteConfig = [[FPRFakeRemoteConfig alloc] init];
- FPRFakeRemoteConfigFlags *fakeConfigFlags =
- [[FPRFakeRemoteConfigFlags alloc] initWithRemoteConfig:(FIRRemoteConfig *)fakeRemoteConfig];
- fakeConfigFlags.userDefaults = [[NSUserDefaults alloc] init];
- fakeConfigurations.remoteConfigFlags = fakeConfigFlags;
- self.logger.configurations = fakeConfigurations;
- // Condition (1): when FLL transport percentage = 54% (equal to installation seed)
- fakeConfigurations.fllTransportPercentageValue = 54.00;
- // Log 2 random Perf events
- FPRMSGPerfMetric *event1 = [FPRTestUtils createRandomPerfMetric:@"t1"];
- event1.applicationInfo.appInstanceId = @"abc"; // Installation ID seed of "abc" is 54.0.
- FPRMSGPerfMetric *event2 = [FPRTestUtils createRandomPerfMetric:@"t2"];
- event2.applicationInfo.appInstanceId = @"abc"; // Installation ID seed of "abc" is 54.0.
- [self.logger logEvent:event1];
- [self.logger logEvent:event2];
- // Verify: that both events are logged to FLL
- dispatch_sync(self.logger.queue, ^{
- // Fetch the logged event
- NSArray<GDTCOREvent *> *gdtCorFllEventArray = [self.transportFLLFake logEvents];
- NSArray<GDTCOREvent *> *gdtCorCCTEventArray = [self.transportCCTFake logEvents];
- XCTAssertTrue(gdtCorFllEventArray.count == 2);
- XCTAssertTrue(gdtCorCCTEventArray.count == 0);
- });
- }
- /** Validate if the events are dispatched to FLL if installation transport percentage is set to
- * maximum. */
- - (void)testEventDispatchedToFllWithMaxTransportPercentage {
- self.logger.isSimulator = NO;
- // Initialize the configurations
- FPRFakeConfigurations *fakeConfigurations =
- [[FPRFakeConfigurations alloc] initWithSources:FPRConfigurationSourceRemoteConfig];
- // Set fakes to the configurations
- FPRFakeRemoteConfig *fakeRemoteConfig = [[FPRFakeRemoteConfig alloc] init];
- FPRFakeRemoteConfigFlags *fakeConfigFlags =
- [[FPRFakeRemoteConfigFlags alloc] initWithRemoteConfig:(FIRRemoteConfig *)fakeRemoteConfig];
- fakeConfigFlags.userDefaults = [[NSUserDefaults alloc] init];
- fakeConfigurations.remoteConfigFlags = fakeConfigFlags;
- self.logger.configurations = fakeConfigurations;
- // Condition: when FLL transport percentage = 100% (maximum %age)
- fakeConfigurations.fllTransportPercentageValue = 100.00;
- // Log 2 random Perf events
- FPRMSGPerfMetric *event1 = [FPRTestUtils createRandomPerfMetric:@"t1"];
- event1.applicationInfo.appInstanceId = @"abc"; // Installation ID seed of "abc" is 54.0.
- FPRMSGPerfMetric *event2 = [FPRTestUtils createRandomPerfMetric:@"t2"];
- event2.applicationInfo.appInstanceId = @"abc"; // Installation ID seed of "abc" is 54.0.
- [self.logger logEvent:event1];
- [self.logger logEvent:event2];
- // Verify: that both events are logged to FLL
- dispatch_sync(self.logger.queue, ^{
- // Fetch the logged event
- NSArray<GDTCOREvent *> *gdtCorFllEventArray = [self.transportFLLFake logEvents];
- NSArray<GDTCOREvent *> *gdtCorCCTEventArray = [self.transportCCTFake logEvents];
- XCTAssertTrue(gdtCorFllEventArray.count == 2);
- XCTAssertTrue(gdtCorCCTEventArray.count == 0);
- });
- }
- /** Validate if the events are dispatched to FLL if installation transport percentage is set to
- * minimum. */
- - (void)testEventDispatchedNotToFllWithMinTransportPercentage {
- self.logger.isSimulator = NO;
- // Initialize the configurations
- FPRFakeConfigurations *fakeConfigurations =
- [[FPRFakeConfigurations alloc] initWithSources:FPRConfigurationSourceRemoteConfig];
- // Set fakes to the configurations
- FPRFakeRemoteConfig *fakeRemoteConfig = [[FPRFakeRemoteConfig alloc] init];
- FPRFakeRemoteConfigFlags *fakeConfigFlags =
- [[FPRFakeRemoteConfigFlags alloc] initWithRemoteConfig:(FIRRemoteConfig *)fakeRemoteConfig];
- fakeConfigFlags.userDefaults = [[NSUserDefaults alloc] init];
- fakeConfigurations.remoteConfigFlags = fakeConfigFlags;
- self.logger.configurations = fakeConfigurations;
- // Condition: when FLL transport percentage = 0% (minimum %age)
- fakeConfigurations.fllTransportPercentageValue = 0.00;
- // Log 2 random Perf events
- FPRMSGPerfMetric *event1 = [FPRTestUtils createRandomPerfMetric:@"t1"];
- event1.applicationInfo.appInstanceId = @"abc"; // Installation ID seed of "abc" is 54.0.
- FPRMSGPerfMetric *event2 = [FPRTestUtils createRandomPerfMetric:@"t2"];
- event2.applicationInfo.appInstanceId = @"abc"; // Installation ID seed of "abc" is 54.0.
- [self.logger logEvent:event1];
- [self.logger logEvent:event2];
- // Verify: that both events are logged to Clearcut
- dispatch_sync(self.logger.queue, ^{
- // Fetch the logged event
- NSArray<GDTCOREvent *> *gdtCorFllEventArray = [self.transportFLLFake logEvents];
- NSArray<GDTCOREvent *> *gdtCorCCTEventArray = [self.transportCCTFake logEvents];
- XCTAssertTrue(gdtCorFllEventArray.count == 0);
- XCTAssertTrue(gdtCorCCTEventArray.count == 2);
- });
- }
- @end
|