From 521b6157c39b7335351ec48e2aafe6986e45d24f Mon Sep 17 00:00:00 2001 From: mbruin-NR <118208503+mbruin-NR@users.noreply.github.com> Date: Fri, 31 Jan 2025 16:06:58 -0500 Subject: [PATCH] NR-352010 Changed NRMASAM to add the persisted attributes individually so that they get re-persisted (#342) * NR-352010 Changed NRMASAM to add the persisted attributes individually so that they get re-persisted * added unit test for persisted attributes * Added the logger to help debug this test that fails on GH * There is a chance that old test attributes are still present * Moving things around * trying to remove the last tests attributes even more * Removed the logging --- Agent/Analytics/NRMASAM.mm | 25 +++--- .../Analytics-Tests/NRMASAMTest.mm | 76 ++++++++++++++++++- 2 files changed, 88 insertions(+), 13 deletions(-) diff --git a/Agent/Analytics/NRMASAM.mm b/Agent/Analytics/NRMASAM.mm index 800c0101..801c2337 100644 --- a/Agent/Analytics/NRMASAM.mm +++ b/Agent/Analytics/NRMASAM.mm @@ -30,30 +30,31 @@ @implementation NRMASAM { - (id)initWithAttributeValidator:(__nullable id)validator { self = [super init]; if (self) { + attributeValidator = validator; + _attributePersistentStore = [[PersistentEventStore alloc] initWithFilename:[NRMASAM attributeFilePath] andMinimumDelay:.025]; _privateAttributePersistentStore = [[PersistentEventStore alloc] initWithFilename:[NRMASAM privateAttributeFilePath] andMinimumDelay:.025]; // Load public attributes from file. NSDictionary *lastSessionAttributes = [PersistentEventStore getLastSessionEventsFromFilename:[NRMASAM attributeFilePath]]; + attributeDict = [[NSMutableDictionary alloc] init]; if (lastSessionAttributes != nil) { - attributeDict = [lastSessionAttributes mutableCopy]; - } - if (!attributeDict) { - attributeDict = [[NSMutableDictionary alloc] init]; + for(NSString* key in [lastSessionAttributes allKeys]) { + [self setAttribute:key value:[lastSessionAttributes valueForKey:key]]; + } } // Load private attributes from file. NSDictionary *lastSessionPrivateAttributes = [PersistentEventStore getLastSessionEventsFromFilename:[NRMASAM privateAttributeFilePath]]; - + privateAttributeDict = [[NSMutableDictionary alloc] init]; + if (lastSessionPrivateAttributes != nil) { - privateAttributeDict = [lastSessionPrivateAttributes mutableCopy]; - } - if (!privateAttributeDict) { - privateAttributeDict = [[NSMutableDictionary alloc] init]; + for(NSString* key in [lastSessionPrivateAttributes allKeys]) { + [self setNRSessionAttribute:key value:[lastSessionPrivateAttributes valueForKey:key]]; + } } - - attributeValidator = validator; + } return self; } @@ -221,7 +222,7 @@ - (NSString*) sessionAttributeJSONString { + (NSString*) getLastSessionsAttributes { NSError *error; NSString *lastSessionAttributesJsonString = nil; - NSDictionary *lastSessionAttributes = [PersistentEventStore getLastSessionEventsFromFilename:[self attributeFilePath]]; + NSDictionary *lastSessionAttributes = [PersistentEventStore getLastSessionEventsFromFilename:[NRMASAM attributeFilePath]]; NSDictionary *lastSessionPrivateAttributes = [PersistentEventStore getLastSessionEventsFromFilename:[NRMASAM privateAttributeFilePath]]; NSMutableDictionary *mergedDictionary = [NSMutableDictionary dictionary]; diff --git a/Tests/Unit-Tests/NewRelicAgentTests/Analytics-Tests/NRMASAMTest.mm b/Tests/Unit-Tests/NewRelicAgentTests/Analytics-Tests/NRMASAMTest.mm index fd5707b2..437e7707 100644 --- a/Tests/Unit-Tests/NewRelicAgentTests/Analytics-Tests/NRMASAMTest.mm +++ b/Tests/Unit-Tests/NewRelicAgentTests/Analytics-Tests/NRMASAMTest.mm @@ -24,8 +24,21 @@ @implementation NRMASAMTest - (void)setUp { [super setUp]; + NSFileManager *fileManager = [NSFileManager defaultManager]; + if([fileManager fileExistsAtPath:[NSString stringWithFormat:@"%@/%@",[NewRelicInternalUtils getStorePath],kNRMA_Attrib_file]]) { + [fileManager removeItemAtPath:[NSString stringWithFormat:@"%@/%@",[NewRelicInternalUtils getStorePath],kNRMA_Attrib_file] error:nil]; + } + if([fileManager fileExistsAtPath:[NSString stringWithFormat:@"%@/%@",[NewRelicInternalUtils getStorePath],kNRMA_Attrib_file_private]]) { + [fileManager removeItemAtPath:[NSString stringWithFormat:@"%@/%@",[NewRelicInternalUtils getStorePath],kNRMA_Attrib_file_private] error:nil]; + } + + // [NRLogger setLogLevels:NRLogLevelDebug]; manager = [self samTest]; +} + +- (void) tearDown { + [super tearDown]; [manager removeAllSessionAttributes]; } @@ -129,6 +142,7 @@ - (void) testIncrementSessionAttribute { error:nil]; XCTAssertTrue([decode[attribute] isEqual:@(2)]); } + - (void) testIncrementSessionAttributeDiffTypes { NSString* attribute = @"incrementableAttribute"; float initialValue = 1.2; @@ -266,8 +280,68 @@ - (void) testClearLastSessionsAnalytics { } +- (void)waitForAttributesToPersist:(NSArray *)expectedAttributes timeout:(NSTimeInterval)timeout { + NSDate *timeoutDate = [NSDate dateWithTimeIntervalSinceNow:timeout]; + while ([timeoutDate timeIntervalSinceNow] > 0) { + NSString *attributes = [NRMASAM getLastSessionsAttributes]; + NSDictionary *decode = [NSJSONSerialization JSONObjectWithData:[attributes dataUsingEncoding:NSUTF8StringEncoding] options:0 error:nil]; + + BOOL allAttributesPersisted = YES; + for (NSString *attribute in expectedAttributes) { + if (![decode objectForKey:attribute]) { + allAttributesPersisted = NO; + break; + } + } + + if (allAttributesPersisted) { + return; + } + + // Wait a short period before retrying + [NSThread sleepForTimeInterval:0.1]; + } + XCTFail(@"Failed to persist expected attributes."); +} + +- (void)testPersistedSessionAnalytics { + + NSString *attribute = @"blarg"; + NSString *attribute2 = @"blarg2"; + NSString *attribute3 = @"privateBlarg3"; + NSString *attribute4 = @"Blarg4"; + NSString *attribute5 = @"privateBlarg5"; + + // Set attributes + XCTAssertTrue([manager setSessionAttribute:attribute value:@"blurg"], @"Failed to successfully set session attribute"); + XCTAssertTrue([manager setSessionAttribute:attribute2 value:@"blurg2"], @"Failed to successfully set session attribute"); + XCTAssertTrue([manager setNRSessionAttribute:attribute3 value:@"blurg2"], @"Failed to successfully set private session attribute"); + + NSString *attributes = [manager sessionAttributeJSONString]; + NSDictionary *decode = [NSJSONSerialization JSONObjectWithData:[attributes dataUsingEncoding:NSUTF8StringEncoding] options:0 error:nil]; + + XCTAssertEqual(decode.count, 3); + + manager = nil; + // Wait for persistence + [self waitForAttributesToPersist:@[attribute, attribute2, attribute3] timeout:10]; + + manager = [self samTest]; + + XCTAssertTrue([manager setSessionAttribute:attribute4 value:@"blurg"], @"Failed to successfully set session attribute"); + XCTAssertTrue([manager setNRSessionAttribute:attribute5 value:@"blurg2"], @"Failed to successfully set private session attribute"); + + attributes = [manager sessionAttributeJSONString]; + decode = [NSJSONSerialization JSONObjectWithData:[attributes dataUsingEncoding:NSUTF8StringEncoding] options:0 error:nil]; + + XCTAssertTrue([[decode allKeys] containsObject:attribute], @"Should have persisted and new attribute 1."); + XCTAssertTrue([[decode allKeys] containsObject:attribute2], @"Should have persisted and new attribute 2."); + XCTAssertTrue([[decode allKeys] containsObject:attribute3], @"Should have persisted and new private attribute 3."); + XCTAssertTrue([[decode allKeys] containsObject:attribute4], @"Should have persisted and new attribute 4."); + XCTAssertTrue([[decode allKeys] containsObject:attribute5], @"Should have persisted and new private attribute 5."); +} + - (void) testClearPersistedSessionAnalytics { - NRMASAM *manager = [self samTest]; NSString *attribute = @"blarg"; NSString *attribute2 = @"blarg2";