2 * Copyright (c) 2016 Apple Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
21 * @APPLE_LICENSE_HEADER_END@
25 #import "SCTestUtils.h"
27 @interface SCTestUnitTest : SCTest
30 @implementation SCTestUnitTest
37 + (NSString *)commandDescription
39 return @"Runs the unit test for all commands";
44 NSMutableDictionary *testDictionary;
45 NSMutableArray *testsArray;
47 NSArray<NSString *> *testClasses;
51 testDictionary = [[NSMutableDictionary alloc] init];
52 [testDictionary setObject:@"SystemConfiguration Unit Tests" forKey:@"Name"];
53 [testDictionary setObject:@"These tests exercise 'configd' and the 'SystemConfiguration' framework" forKey:@"Description"];
55 testsArray = [[NSMutableArray alloc] init];
56 thisClass = NSStringFromClass([self class]);
57 testClasses = getTestClasses();
58 for (NSString *className in testClasses) {
60 NSMutableDictionary *subTest;
62 NSMutableArray *subTestArray;
64 if ([className isEqualToString:thisClass] ) {
68 testClass = NSClassFromString(className);
69 list = getUnitTestListForClass(testClass);
71 subTest = [[NSMutableDictionary alloc] init];
72 [subTest setObject:@NO forKey:@"RequiresTCPDUMP"];
73 [subTest setObject:@YES forKey:@"RequiresNetwork"];
74 [subTest setObject:@NO forKey:@"RequiresRoot"];
75 [subTest setObject:@NO forKey:@"RequiresPowermetrics"];
76 [subTest setObject:[testClass command] forKey:@"Name"];
77 [subTest setObject:[testClass commandDescription] forKey:@"Description"];
78 subTestArray = [[NSMutableArray alloc] init];
79 for (NSString *unitTest in list) {
80 NSDictionary *testDict = @{@"Command":@[@"/usr/local/bin/sctest",
84 @"Name":[unitTest stringByReplacingOccurrencesOfString:@"unitTest" withString:@""],
85 @"Description":@"Unit test"
87 [subTestArray addObject:testDict];
89 [subTest setObject:subTestArray forKey:@"SubTests"];
90 [testsArray addObject:subTest];
92 [testDictionary setObject:testsArray forKey:@"Tests"];
93 data = [NSJSONSerialization dataWithJSONObject:testDictionary
94 options:NSJSONWritingPrettyPrinted
96 jsonString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
97 //SCTestLog("%@", jsonString);
98 SCPrint(TRUE, stderr, CFSTR("%@"), jsonString);
103 NSArray<NSString *> *testClasses;
104 NSString *thisClass = NSStringFromClass([self class]);;
105 testClasses = getTestClasses();
106 BOOL errorOccured = NO;
108 if (self.options[kSCTestUnitTestListTests]) {
110 } else if (self.options[kSCTestUnitTestTestMethodList]) {
111 SCTestLog("List of unit tests:");
112 for (NSString *className in testClasses) {
116 if ([className isEqualToString:thisClass] ) {
120 testClass = NSClassFromString(className);
121 if (self.options[kSCTestUnitTestCommand] != nil) {
122 if (![self.options[kSCTestUnitTestCommand] isEqualToString:[testClass command]]) {
123 // Run unit test only for a specific command
128 SCTestLog("\n======= '%@' unit tests =======", [testClass command]);
129 list = getUnitTestListForClass(testClass);
130 for (NSString *unitTest in list) {
131 SCTestLog("%@", unitTest);
135 SCTestLog("\nEach of the unit tests can be run with the 'test_method' option\n");
136 } else if (self.options[kSCTestUnitTestTestMethod]) {
137 for (NSString *className in testClasses) {
141 if ([className isEqualToString:thisClass] ) {
145 testClass = NSClassFromString(className);
146 if (self.options[kSCTestUnitTestCommand] != nil) {
147 if (![self.options[kSCTestUnitTestCommand] isEqualToString:[testClass command]]) {
148 // Run unit test only for a specific command
153 list = getUnitTestListForClass(testClass);
154 for (NSString *unitTest in list) {
155 if ([unitTest isEqualToString:self.options[kSCTestUnitTestTestMethod]]) {
156 id obj = [(SCTest *)[testClass alloc] initWithOptions:self.options];
158 SCTestLog("Running unit test %@ ...", unitTest);
160 SEL methodSelector = NSSelectorFromString(unitTest);
161 Boolean retVal = false;
162 if ([obj respondsToSelector:methodSelector]) {
163 NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[obj methodSignatureForSelector:methodSelector]];
164 invocation.target = obj;
165 invocation.selector = methodSelector;
167 [invocation getReturnValue:&retVal];
181 // This command runs unit tests for all commands.
182 for (NSString *className in testClasses) {
186 if ([className isEqualToString:thisClass] ) {
190 testClass = NSClassFromString(className);
191 if (self.options[kSCTestUnitTestCommand] != nil) {
192 if (![self.options[kSCTestUnitTestCommand] isEqualToString:[testClass command]]) {
193 // Run unit test only for a specific command
198 obj = [(SCTest *)[testClass alloc] initWithOptions:self.options];
199 if ([obj respondsToSelector:@selector(unitTest)]) {
200 SCTestLog("\n*** Running unit test for \"%@\" command ***\n", [testClass command]);
201 BOOL passed = [obj unitTest];
210 [self cleanupAndExitWithErrorCode:errorOccured];
213 - (void)cleanupAndExitWithErrorCode:(int)error
215 [super cleanupAndExitWithErrorCode:error];