Skip to content

Commit

Permalink
Convert memoryUsage and memoryUsageString to `CSSystemInfoProvide…
Browse files Browse the repository at this point in the history
…r` and add tests
  • Loading branch information
thecatalinstan committed Jun 18, 2021
1 parent 898069b commit 3a93c27
Show file tree
Hide file tree
Showing 11 changed files with 207 additions and 29 deletions.
4 changes: 4 additions & 0 deletions CSSystemInfoHelper.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
AD143BA4267C80760094D246 /* CSSystemInfoHelper+Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = AD143BA3267C80760094D246 /* CSSystemInfoHelper+Internal.h */; };
AD143BA7267C87450094D246 /* CSSystemInfoProviderMock.m in Sources */ = {isa = PBXBuildFile; fileRef = AD143BA6267C87450094D246 /* CSSystemInfoProviderMock.m */; };
AD352510267CB84700A3A929 /* CSSystemInfoHelperDeprecatedTests.m in Sources */ = {isa = PBXBuildFile; fileRef = AD35250F267CB84700A3A929 /* CSSystemInfoHelperDeprecatedTests.m */; };
AD352512267CCE0900A3A929 /* Errors.m in Sources */ = {isa = PBXBuildFile; fileRef = AD352511267CCE0900A3A929 /* Errors.m */; };
AD3BFDF0267AA56600FF8076 /* CSSystemInfoHelper.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AD3BFDE6267AA56600FF8076 /* CSSystemInfoHelper.framework */; };
AD3BFDF5267AA56600FF8076 /* CSSystemInfoHelperTests.m in Sources */ = {isa = PBXBuildFile; fileRef = AD3BFDF4267AA56600FF8076 /* CSSystemInfoHelperTests.m */; };
AD3BFE07267AA5BD00FF8076 /* CSSystemInfoHelper.h in Headers */ = {isa = PBXBuildFile; fileRef = AD3BFE03267AA5BD00FF8076 /* CSSystemInfoHelper.h */; settings = {ATTRIBUTES = (Public, ); }; };
Expand All @@ -38,6 +39,7 @@
AD143BA5267C87450094D246 /* CSSystemInfoProviderMock.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CSSystemInfoProviderMock.h; sourceTree = "<group>"; };
AD143BA6267C87450094D246 /* CSSystemInfoProviderMock.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CSSystemInfoProviderMock.m; sourceTree = "<group>"; };
AD35250F267CB84700A3A929 /* CSSystemInfoHelperDeprecatedTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CSSystemInfoHelperDeprecatedTests.m; sourceTree = "<group>"; };
AD352511267CCE0900A3A929 /* Errors.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = Errors.m; sourceTree = "<group>"; };
AD3BFDE6267AA56600FF8076 /* CSSystemInfoHelper.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = CSSystemInfoHelper.framework; sourceTree = BUILT_PRODUCTS_DIR; };
AD3BFDEF267AA56600FF8076 /* CSSystemInfoHelperTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = CSSystemInfoHelperTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
AD3BFDF4267AA56600FF8076 /* CSSystemInfoHelperTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CSSystemInfoHelperTests.m; sourceTree = "<group>"; };
Expand Down Expand Up @@ -145,6 +147,7 @@
AD143B9F267C7D350094D246 /* CSSystemInfoProvider.h */,
AD143BA0267C7D350094D246 /* CSSystemInfoProvider.m */,
ADB06B28267B608800D4F0E3 /* Errors.h */,
AD352511267CCE0900A3A929 /* Errors.m */,
);
path = Sources;
sourceTree = "<group>";
Expand Down Expand Up @@ -261,6 +264,7 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
AD352512267CCE0900A3A929 /* Errors.m in Sources */,
ADB06B25267B5A2400D4F0E3 /* CSNetworkInterface.m in Sources */,
AD143BA2267C7D350094D246 /* CSSystemInfoProvider.m in Sources */,
AD3BFE08267AA5BD00FF8076 /* CSSystemInfoHelper.m in Sources */,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ FOUNDATION_EXPORT NSString * const CSSystemInfoHelperIPAddressNone DEPRECATED_AT
/// @name UUID of the current device

/// Get the UUID of the current device
/// @note This API is only available on macOS
@property (nonatomic, readonly, strong) NSString * platformUUID API_UNAVAILABLE(ios, tvos, watchos);

- (instancetype)init NS_UNAVAILABLE;
Expand Down
2 changes: 2 additions & 0 deletions CSSystemInfoHelper/Sources/CSSystemInfoHelper+Internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ FOUNDATION_EXPORT NSString * const CSSystemInfoHelperDefaultInterface DEPRECATED

- (instancetype)initWithSystemInfoProvider:(id<CSSystemInfoProviderProtocol> _Nullable)systemInfoProvider NS_DESIGNATED_INITIALIZER;

- (NSString *)formatByteCount:(long long)byteCount;

@end

NS_ASSUME_NONNULL_END
27 changes: 15 additions & 12 deletions CSSystemInfoHelper/Sources/CSSystemInfoHelper.m
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
#import <CSSystemInfoHelper/CSSystemInfoHelper.h>
#import "CSSystemInfoHelper+Internal.h"

#import <mach/mach.h>
#import <sys/utsname.h>

#import "CSNetworkInterface+Internal.h"
Expand Down Expand Up @@ -53,14 +52,12 @@ - (instancetype)initWithSystemInfoProvider:(id<CSSystemInfoProviderProtocol>)sys
}

- (NSArray<CSNetworkInterface *> *)networkInterfaces {
NSArray<CSNetworkInterface *> *networkInterfaces;

NSError *error;
NSArray<CSNetworkInterface *> *networkInterfaces;
if (!(networkInterfaces = [self.systemInfoProvider queryNetworkInterfaces:&error])) {
NSLog(@"Error loading network interfaces: %@. %@.", error.localizedDescription, error.localizedFailureReason);
return nil;
}

return networkInterfaces;
}

Expand Down Expand Up @@ -108,18 +105,17 @@ - (NSString *)systemVersionString {
}

- (vm_size_t)memoryUsage {
//task_vm_info
struct task_basic_info info;
mach_msg_type_number_t size = sizeof(info);
kern_return_t kerr = task_info(mach_task_self(), TASK_BASIC_INFO, (task_info_t)&info, &size);
if(kerr != KERN_SUCCESS) {
@throw [NSException exceptionWithName:NSGenericException reason:[NSString stringWithUTF8String:mach_error_string(kerr)] userInfo:nil];
NSError *error;
vm_size_t memoryUsage = 0;
if (!([self.systemInfoProvider getResidentSize:&memoryUsage error:&error])) {
NSLog(@"Error getting resident size: %@. %@.", error.localizedDescription, error.localizedFailureReason);
return 0;
}
return info.resident_size;
return memoryUsage;
}

- (NSString *)memoryUsageString {
return [NSByteCountFormatter stringFromByteCount:self.memoryUsage countStyle:NSByteCountFormatterCountStyleMemory];
return [self formatByteCount:self.memoryUsage];
}

#if TARGET_OS_OSX
Expand Down Expand Up @@ -177,4 +173,11 @@ - (NSString *)IPAddress {

#pragma clang diagnostic pop

#pragma mark - Private Helpers

- (NSString *)formatByteCount:(long long)byteCount {
return [NSByteCountFormatter stringFromByteCount:byteCount countStyle:NSByteCountFormatterCountStyleMemory];
}


@end
2 changes: 2 additions & 0 deletions CSSystemInfoHelper/Sources/CSSystemInfoProvider.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ NS_ASSUME_NONNULL_BEGIN

- (nullable NSArray<CSNetworkInterface *> *)queryNetworkInterfaces:(NSError *__autoreleasing *)error NS_WARN_UNUSED_RESULT;

- (BOOL)getResidentSize:(vm_size_t *)residentSize error:(NSError *__autoreleasing *)error NS_WARN_UNUSED_RESULT;

@end

@interface CSSystemInfoProvider : NSObject<CSSystemInfoProviderProtocol>
Expand Down
18 changes: 18 additions & 0 deletions CSSystemInfoHelper/Sources/CSSystemInfoProvider.m
Original file line number Diff line number Diff line change
Expand Up @@ -83,4 +83,22 @@ - (CSNetworkInterface *)interfaceAddressWithAddr:(struct ifaddrs *)addr error:(N
return result;
}

- (BOOL)getResidentSize:(vm_size_t *)residentSize error:(NSError *__autoreleasing _Nullable *)error {
struct task_basic_info info = {0};

kern_return_t ret;
if (KERN_SUCCESS != (ret = task_info(mach_task_self(), TASK_BASIC_INFO, (task_info_t)&info, TASK_BASIC_INFO_COUNT))) {
if (error) {
*error = CSMachError(ret, nil, nil);
}
return NO;
}

if (residentSize) {
*residentSize = info.resident_size;
}

return YES;
}

@end
10 changes: 10 additions & 0 deletions CSSystemInfoHelper/Sources/Errors.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,14 @@
// Created by Cătălin Stan on 17/06/2021.
//

#import <errno.h>
#import <Foundation/Foundation.h>
#import <mach/mach.h>

NS_ASSUME_NONNULL_BEGIN

FOUNDATION_EXPORT NSErrorDomain const CSMachErrorDomain;

NS_INLINE NSError *
NSErrorMake(NSErrorDomain domain,
NSInteger code,
Expand All @@ -29,5 +33,11 @@ NSPosixError(int errnum, NSString *_Nullable reason, NSDictionary<NSErrorUserInf
return NSErrorMake(NSPOSIXErrorDomain, (NSInteger)errnum, @(strerror(errnum)), reason, userInfo);
}

NS_INLINE NSError *
CSMachError(kern_return_t ret, NSString *_Nullable reason, NSDictionary<NSErrorUserInfoKey, id> *_Nullable userInfo) {
return NSErrorMake(CSMachErrorDomain, (NSInteger)ret, @(mach_error_string(ret)), reason, userInfo);
}


NS_ASSUME_NONNULL_END

10 changes: 10 additions & 0 deletions CSSystemInfoHelper/Sources/Errors.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
//
// Errors.m
// CSSystemInfoHelper
//
// Created by Cătălin Stan on 18/06/2021.
//

#import "Errors.h"

NSErrorDomain const CSMachErrorDomain = @"CSMachErrorDomain";
117 changes: 104 additions & 13 deletions CSSystemInfoHelperTests/CSSystemInfoHelperTests.m
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ - (void)test_networkInterfaces_withFailingSystemInfoProvider_ShouldBeNil {
XCTAssertNil(helper.networkInterfaces);
}

- (void)test_networkInterfaces_withSucceedingSystemInfoProvider_ShouldBeIdenticalToProvidedInterfaces {
- (void)test_networkInterfaces_withSucceedingSystemInfoProvider_ShouldReturnProvidedInterfaces {
NSArray<CSNetworkInterface *> *expectedInterfaces = [NSArray array];
CSSystemInfoProviderMock *provider = [CSSystemInfoProviderMock succeedingProviderWithNetworkInterfaces:expectedInterfaces];
CSSystemInfoHelper *helper = [[CSSystemInfoHelper alloc] initWithSystemInfoProvider:provider];
Expand Down Expand Up @@ -97,31 +97,122 @@ - (void)test_SystemVersionString_ShouldNotBeEmpty {
XCTAssertGreaterThan(helper.systemVersionString.length, 0);
}

- (void)test_MemoryUsage_DoesNotThrow {
CSSystemInfoHelper *helper = [[CSSystemInfoHelper alloc] initWithSystemInfoProvider:nil];
XCTAssertNoThrow(helper.memoryUsage);
- (void)test_memoryUsage_withFailingSystemInfoProvider_ShouldBeZero {
CSSystemInfoProviderMock *provider = [CSSystemInfoProviderMock failingProviderWithError:nil];
CSSystemInfoHelper *helper = [[CSSystemInfoHelper alloc] initWithSystemInfoProvider:provider];

XCTAssertEqual(helper.memoryUsage, 0);
}

- (void)test_MemoryUsage_IsGreaterThan0 {
CSSystemInfoHelper *helper = [[CSSystemInfoHelper alloc] initWithSystemInfoProvider:nil];
XCTAssertGreaterThan(helper.memoryUsage, 0);
- (void)test_memoryUsage_withFailingSystemInfoProviderThatReturnsValue_ShouldBeZero {
vm_size_t residentSize = arc4random();
CSSystemInfoProviderMock *provider = [CSSystemInfoProviderMock failingProviderWithResidentSize:&residentSize error:nil];
CSSystemInfoHelper *helper = [[CSSystemInfoHelper alloc] initWithSystemInfoProvider:provider];

XCTAssertEqual(helper.memoryUsage, 0);
}

- (void)test_MemoryUsageString_DoesNotThrow {
CSSystemInfoHelper *helper = [[CSSystemInfoHelper alloc] initWithSystemInfoProvider:nil];
- (void)test_memoryUsage_withSucceedingSystemInfoProvider_ShouldReturnProvidedValue {
vm_size_t residentSize = arc4random();
CSSystemInfoProviderMock *provider = [CSSystemInfoProviderMock succeedingProviderWithResidentSize:&residentSize];
CSSystemInfoHelper *helper = [[CSSystemInfoHelper alloc] initWithSystemInfoProvider:provider];

XCTAssertEqual(helper.memoryUsage, residentSize);
}

- (void)test_MemoryUsageString_withFailingSystemInfoProvider_DoesNotThrow {
CSSystemInfoProviderMock *provider = [CSSystemInfoProviderMock failingProviderWithError:nil];
CSSystemInfoHelper *helper = [[CSSystemInfoHelper alloc] initWithSystemInfoProvider:provider];

XCTAssertNoThrow(helper.memoryUsageString);
}

- (void)test_MemoryUsageString_ShouldNotBeNil {
CSSystemInfoHelper *helper = [[CSSystemInfoHelper alloc] initWithSystemInfoProvider:nil];
- (void)test_MemoryUsageString_withFailingSystemInfoProvider_ShouldNotBeNil {
CSSystemInfoProviderMock *provider = [CSSystemInfoProviderMock failingProviderWithError:nil];
CSSystemInfoHelper *helper = [[CSSystemInfoHelper alloc] initWithSystemInfoProvider:provider];

XCTAssertNotNil(helper.memoryUsageString);
}

- (void)test_MemoryUsageString_ShouldNotBeEmpty {
CSSystemInfoHelper *helper = [[CSSystemInfoHelper alloc] initWithSystemInfoProvider:nil];
- (void)test_MemoryUsageString_withFailingSystemInfoProvider_ShouldNotBeEmpty {
CSSystemInfoProviderMock *provider = [CSSystemInfoProviderMock failingProviderWithError:nil];
CSSystemInfoHelper *helper = [[CSSystemInfoHelper alloc] initWithSystemInfoProvider:provider];

XCTAssertGreaterThan(helper.memoryUsageString.length, 0);
}

- (void)test_MemoryUsageString_withFailingSystemInfoProvider_ShouldEvnaluateTo0 {
CSSystemInfoProviderMock *provider = [CSSystemInfoProviderMock failingProviderWithError:nil];
CSSystemInfoHelper *helper = [[CSSystemInfoHelper alloc] initWithSystemInfoProvider:provider];

XCTAssertEqual(helper.memoryUsageString.integerValue, 0);
}

- (void)test_MemoryUsageString_withFailingSystemInfoProviderThatReturnsValue_DoesNotThrow {
vm_size_t residentSize = arc4random();
CSSystemInfoProviderMock *provider = [CSSystemInfoProviderMock failingProviderWithResidentSize:&residentSize error:nil];
CSSystemInfoHelper *helper = [[CSSystemInfoHelper alloc] initWithSystemInfoProvider:provider];

XCTAssertNoThrow(helper.memoryUsageString);
}

- (void)test_MemoryUsageString_withFailingSystemInfoProviderThatReturnsValue_ShouldNotBeNil {
vm_size_t residentSize = arc4random();
CSSystemInfoProviderMock *provider = [CSSystemInfoProviderMock failingProviderWithResidentSize:&residentSize error:nil];
CSSystemInfoHelper *helper = [[CSSystemInfoHelper alloc] initWithSystemInfoProvider:provider];

XCTAssertNotNil(helper.memoryUsageString);
}

- (void)test_MemoryUsageString_withFailingSystemInfoProviderThatReturnsValue_ShouldNotBeEmpty {
vm_size_t residentSize = arc4random();
CSSystemInfoProviderMock *provider = [CSSystemInfoProviderMock failingProviderWithResidentSize:&residentSize error:nil];
CSSystemInfoHelper *helper = [[CSSystemInfoHelper alloc] initWithSystemInfoProvider:provider];

XCTAssertGreaterThan(helper.memoryUsageString.length, 0);
}

- (void)test_MemoryUsageString_withFailingSystemInfoProviderThatReturnsValue_ShouldEvnaluateTo0 {
vm_size_t residentSize = arc4random();
CSSystemInfoProviderMock *provider = [CSSystemInfoProviderMock failingProviderWithResidentSize:&residentSize error:nil];
CSSystemInfoHelper *helper = [[CSSystemInfoHelper alloc] initWithSystemInfoProvider:provider];

XCTAssertEqual(helper.memoryUsageString.integerValue, 0);
}

- (void)test_MemoryUsageString_withSucceedingSystemInfoProvider_DoesNotThrow {
vm_size_t residentSize = arc4random();
CSSystemInfoProviderMock *provider = [CSSystemInfoProviderMock succeedingProviderWithResidentSize:&residentSize];
CSSystemInfoHelper *helper = [[CSSystemInfoHelper alloc] initWithSystemInfoProvider:provider];

XCTAssertNoThrow(helper.memoryUsageString);
}

- (void)test_MemoryUsageString_withSucceedingSystemInfoProvider_ShouldNotBeNil {
vm_size_t residentSize = arc4random();
CSSystemInfoProviderMock *provider = [CSSystemInfoProviderMock succeedingProviderWithResidentSize:&residentSize];
CSSystemInfoHelper *helper = [[CSSystemInfoHelper alloc] initWithSystemInfoProvider:provider];

XCTAssertNotNil(helper.memoryUsageString);
}

- (void)test_MemoryUsageString_withSucceedingSystemInfoProvider_ShouldNotBeEmpty {
vm_size_t residentSize = arc4random();
CSSystemInfoProviderMock *provider = [CSSystemInfoProviderMock succeedingProviderWithResidentSize:&residentSize];
CSSystemInfoHelper *helper = [[CSSystemInfoHelper alloc] initWithSystemInfoProvider:provider];

XCTAssertGreaterThan(helper.memoryUsageString.length, 0);
}

- (void)test_MemoryUsageString_withSucceedingSystemInfoProvider_ShouldReturnFormattedProvidedValue {
vm_size_t residentSize = arc4random();
CSSystemInfoProviderMock *provider = [CSSystemInfoProviderMock succeedingProviderWithResidentSize:&residentSize];
CSSystemInfoHelper *helper = [[CSSystemInfoHelper alloc] initWithSystemInfoProvider:provider];
NSString *expectedString = [helper formatByteCount:residentSize];

XCTAssertEqualObjects(helper.memoryUsageString, expectedString);
}

#if TARGET_OS_OSX
- (void)test_PlatformUUID_DoesNotThrow {
CSSystemInfoHelper *helper = [[CSSystemInfoHelper alloc] initWithSystemInfoProvider:nil];
Expand Down
7 changes: 5 additions & 2 deletions CSSystemInfoHelperTests/CSSystemInfoProviderMock.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//
// MyClass.h
//
// CSSystemInfoProviderMock.h
// CSSystemInfoHelper
//
// Created by Cătălin Stan on 18/06/2021.
//
Expand All @@ -13,7 +13,10 @@ NS_ASSUME_NONNULL_BEGIN
@interface CSSystemInfoProviderMock : NSObject <CSSystemInfoProviderProtocol>

+ (instancetype)failingProviderWithError:(NSError *_Nullable)error;
+ (instancetype)failingProviderWithResidentSize:(vm_size_t * _Nullable)residentSize error:(NSError *_Nullable)error;

+ (instancetype)succeedingProviderWithNetworkInterfaces:(NSArray<CSNetworkInterface *> *)networkInterfaces;
+ (instancetype)succeedingProviderWithResidentSize:(vm_size_t *)residentSize;

@end

Expand Down
Loading

0 comments on commit 3a93c27

Please sign in to comment.