Skip to content

Commit

Permalink
Merge 3498893 into e569a68
Browse files Browse the repository at this point in the history
  • Loading branch information
pmarkowsky committed Sep 22, 2021
2 parents e569a68 + 3498893 commit d572c92
Show file tree
Hide file tree
Showing 17 changed files with 1,180 additions and 0 deletions.
53 changes: 53 additions & 0 deletions Source/santametricservice/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
load("@build_bazel_rules_apple//apple:macos.bzl", "macos_command_line_application")
load("//:helper.bzl", "santa_unit_test")

package(default_visibility = ["//:santa_package_group"])

licenses(["notice"]) # Apache 2.0

objc_library(
name = "SNTMetricServiceLib",
srcs = [
"SNTMetricService.h",
"SNTMetricService.m",
"main.m",
],
deps = [
"//Source/common:SNTConfigurator",
"//Source/common:SNTLogging",
"//Source/common:SNTMetricSet",
"//Source/common:SNTXPCMetricServiceInterface",
"//Source/santametricservice/Formats:SNTMetricRawJSONFormat",
"//Source/santametricservice/Writers:SNTMetricFileWriter",
"@MOLCodesignChecker",
"@MOLXPCConnection",
],
)

santa_unit_test(
name = "SNTMetricServiceTest",
srcs = ["SNTMetricServiceTest.m"],
deps = [
":SNTMetricServiceLib",
"@OCMock",
],
)

test_suite(
name = "unit_tests",
tests = [
":SNTMetricServiceTest",
"//Source/santametricservice/Formats:SNTMetricRawJSONFormatTest",
"//Source/santametricservice/Writers:SNTMetricFileWriterTest",
],
)

macos_command_line_application(
name = "santametricservice",
bundle_id = "com.google.santa.metricservice",
infoplists = ["Info.plist"],
minimum_os_version = "10.15",
version = "//:version",
visibility = ["//:santa_package_group"],
deps = [":SNTMetricServiceLib"],
)
43 changes: 43 additions & 0 deletions Source/santametricservice/Formats/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
load("@build_bazel_rules_apple//apple:macos.bzl", "macos_command_line_application")
load("//:helper.bzl", "santa_unit_test")

package(default_visibility = ["//:santa_package_group"])

licenses(["notice"]) # Apache 2.0

objc_library(
name = "SNTMetricFormat",
hdrs = ["SNTMetricFormat.h"],
)

objc_library(
name = "SNTMetricRawJSONFormat",
srcs = [
"SNTMetricFormat.h",
"SNTMetricRawJSONFormat.h",
"SNTMetricRawJSONFormat.m",
],
deps = [
":SNTMetricFormat",
"//Source/common:SNTLogging",
],
)

santa_unit_test(
name = "SNTMetricRawJSONFormatTest",
srcs = [
"SNTMetricRawJSONFormatTest.m",
],
structured_resources = glob(["testdata/**"]),
deps = [
":SNTMetricRawJSONFormat",
"//Source/common:SNTMetricSet",
],
)

test_suite(
name = "format_tests",
tests = [
":SNTMetricRawJSONFormatTest",
],
)
19 changes: 19 additions & 0 deletions Source/santametricservice/Formats/SNTMetricFormat.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/// Copyright 2021 Google Inc. All rights reserved.
///
/// 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 <Foundation/Foundation.h>

@protocol SNTMetricFormat
- (NSArray<NSData *> *)convert:(NSDictionary *)metrics error:(NSError **)err;
@end
20 changes: 20 additions & 0 deletions Source/santametricservice/Formats/SNTMetricRawJSONFormat.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/// Copyright 2021 Google Inc. All rights reserved.
///
/// 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 <Foundation/Foundation.h>

#import "Source/santametricservice/Formats/SNTMetricFormat.h"

@interface SNTMetricRawJSONFormat : NSObject <SNTMetricFormat>
@end
102 changes: 102 additions & 0 deletions Source/santametricservice/Formats/SNTMetricRawJSONFormat.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
/// Copyright 2021 Google Inc. All rights reserved.
///
/// 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 "Source/common/SNTLogging.h"

#import "Source/santametricservice/Formats/SNTMetricRawJSONFormat.h"

@implementation SNTMetricRawJSONFormat {
NSDateFormatter *_dateFormatter;
}

- (instancetype)init {
self = [super init];
if (self) {
_dateFormatter = [[NSDateFormatter alloc] init];
[_dateFormatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"];
}
return self;
}

- (NSArray *)normalizeArray:(NSArray *)arr {
NSMutableArray *normalized = [NSMutableArray arrayWithArray:arr];

[normalized enumerateObjectsUsingBlock:^(id value, NSUInteger index, BOOL *stop) {
if ([value isKindOfClass:[NSDate class]]) {
normalized[index] = [self->_dateFormatter stringFromDate:(NSDate *)value];
} else if ([value isKindOfClass:[NSArray class]]) {
normalized[index] = [self normalizeArray:(NSArray *)value];
} else if ([value isKindOfClass:[NSDictionary class]]) {
normalized[index] = [self normalize:(NSDictionary *)value];
}
}];

return normalized;
}

/**
* Normalizes the metrics dictionary for exporting to JSON
**/
- (NSDictionary *)normalize:(NSDictionary *)metrics {
// Convert NSDate's to RFC3339 in strings as NSDate's cannot be serialized
// to JSON.
NSMutableDictionary *normalizedMetrics = [NSMutableDictionary dictionaryWithDictionary:metrics];

[metrics enumerateKeysAndObjectsUsingBlock:^(id key, id value, BOOL *stop) {
if ([value isKindOfClass:[NSDate class]]) {
normalizedMetrics[key] = [self->_dateFormatter stringFromDate:(NSDate *)value];
} else if ([value isKindOfClass:[NSDictionary class]]) {
normalizedMetrics[key] = [self normalize:(NSDictionary *)value];
} else if ([value isKindOfClass:[NSArray class]]) {
normalizedMetrics[key] = [self normalizeArray:(NSArray *)value];
}
}];

return (NSDictionary *)normalizedMetrics;
}

/*
* Convert normalies and converts the metrics dictionary to a single JSON
* object.
*
* @param metrics an NSDictionary exported by the SNTMetricSet
* @param error a pointer to an NSError to allow errors to bubble up.
*
* Returns an NSArray containing one entry of all metrics serialized to JSON or
* nil on error.
*/
- (NSArray<NSData *> *)convert:(NSDictionary *)metrics error:(NSError **)err {
NSDictionary *normalizedMetrics = [self normalize:metrics];

if (![NSJSONSerialization isValidJSONObject:normalizedMetrics]) {
if (err != nil) {
*err = [[NSError alloc]
initWithDomain:@"SNTMetricRawJSONFileWriter"
code:EINVAL
userInfo:@{
NSLocalizedDescriptionKey : @"unable to convert metrics to JSON: invalid metrics"
}];
}
return nil;
}

NSData *json = [NSJSONSerialization dataWithJSONObject:normalizedMetrics
options:NSJSONWritingPrettyPrinted
error:err];
if (json == nil || (err != nil && *err != nil)) {
return nil;
}

return @[ json ];
}
@end

0 comments on commit d572c92

Please sign in to comment.