Skip to content

Commit

Permalink
Make it easier to start "cross-test" helper apps in Darwin tests.
Browse files Browse the repository at this point in the history
We shouldn't require a testcase instance to start such an app, since it's
associated with the test suite, not a specific test.
  • Loading branch information
bzbarsky-apple committed Sep 5, 2024
1 parent 5fdee50 commit 763487d
Show file tree
Hide file tree
Showing 5 changed files with 62 additions and 35 deletions.
29 changes: 12 additions & 17 deletions src/darwin/Framework/CHIPTests/MTRCommissionableBrowserTests.m
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,6 @@
static const uint16_t kDiscoverDeviceTimeoutInSeconds = 10;
static const uint16_t kExpectedDiscoveredDevicesCount = 3;

static bool sHelperAppsStarted = false;

// Singleton controller we use.
static MTRDeviceController * sController = nil;

Expand Down Expand Up @@ -180,6 +178,18 @@ + (void)setUp
XCTAssertNotNil(controller);

sController = controller;

// Start the helper apps our tests use.
for (NSString * payload in @[
@"MT:Y.K90SO527JA0648G00",
@"MT:-24J0AFN00I40648G00",
]) {
__auto_type * appRunner = [[MTRTestServerAppRunner alloc] initCrossTestWithAppName:@"all-clusters"
arguments:@[]
payload:payload
testsuite:self];
XCTAssertNotNil(appRunner);
}
}

+ (void)tearDown
Expand All @@ -197,21 +207,6 @@ + (void)tearDown
- (void)setUp
{
[super setUp];

if (!sHelperAppsStarted) {
for (NSString * payload in @[
@"MT:Y.K90SO527JA0648G00",
@"MT:-24J0AFN00I40648G00",
]) {
__auto_type * appRunner = [[MTRTestServerAppRunner alloc] initCrossTestWithAppName:@"all-clusters"
arguments:@[]
payload:payload
testcase:self];
XCTAssertNotNil(appRunner);
}
sHelperAppsStarted = true;
}

[self setContinueAfterFailure:NO];
}

Expand Down
12 changes: 11 additions & 1 deletion src/darwin/Framework/CHIPTests/TestHelpers/MTRTestCase.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,11 @@ NS_ASSUME_NONNULL_BEGIN
*/
- (NSTask *)createTaskForPath:(NSString *)path;

/**
* Same thing, but not tied to a specific testcase instance.
*/
+ (NSTask *)createTaskForPath:(NSString *)path;

/**
* Run a task to completion and make sure it succeeds.
*/
Expand All @@ -52,14 +57,19 @@ NS_ASSUME_NONNULL_BEGIN
* Launch a cross-test task. The task will be automatically terminated when the testsuite
* tearDown happens.
*/
- (void)launchCrossTestTask:(NSTask *)task;
+ (void)launchCrossTestTask:(NSTask *)task;
#endif // HAVE_NSTASK

/**
* Get an absolute path from a path relative to the Matter SDK root.
*/
- (NSString *)absolutePathFor:(NSString *)matterRootRelativePath;

/**
* Same thing, but not tied to a specific testcase instance.
*/
+ (NSString *)absolutePathFor:(NSString *)matterRootRelativePath;

@end

NS_ASSUME_NONNULL_END
19 changes: 14 additions & 5 deletions src/darwin/Framework/CHIPTests/TestHelpers/MTRTestCase.mm
Original file line number Diff line number Diff line change
Expand Up @@ -85,13 +85,18 @@ - (void)tearDown
}

#if HAVE_NSTASK
- (NSTask *)createTaskForPath:(NSString *)path
+ (NSTask *)createTaskForPath:(NSString *)path
{
NSTask * task = [[NSTask alloc] init];
[task setLaunchPath:[self absolutePathFor:path]];
return task;
}

- (NSTask *)createTaskForPath:(NSString *)path
{
return [self.class createTaskForPath:path];
}

- (void)runTask:(NSTask *)task
{
NSError * launchError;
Expand All @@ -102,7 +107,7 @@ - (void)runTask:(NSTask *)task
XCTAssertEqual([task terminationStatus], 0);
}

- (void)doLaunchTask:(NSTask *)task
+ (void)doLaunchTask:(NSTask *)task
{
NSError * launchError;
[task launchAndReturnError:&launchError];
Expand All @@ -111,20 +116,20 @@ - (void)doLaunchTask:(NSTask *)task

- (void)launchTask:(NSTask *)task
{
[self doLaunchTask:task];
[self.class doLaunchTask:task];

[_runningTasks addObject:task];
}

- (void)launchCrossTestTask:(NSTask *)task
+ (void)launchCrossTestTask:(NSTask *)task
{
[self doLaunchTask:task];

[runningCrossTestTasks addObject:task];
}
#endif // HAVE_NSTASK

- (NSString *)absolutePathFor:(NSString *)matterRootRelativePath
+ (NSString *)absolutePathFor:(NSString *)matterRootRelativePath
{
// Start with the absolute path to our file, then remove the suffix that
// comes after the path to the Matter SDK root.
Expand All @@ -135,4 +140,8 @@ - (NSString *)absolutePathFor:(NSString *)matterRootRelativePath
return [NSString pathWithComponents:pathComponents];
}

- (NSString *)absolutePathFor:(NSString *)matterRootRelativePath
{
return [self.class absolutePathFor:matterRootRelativePath];
}
@end
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,10 @@ NS_ASSUME_NONNULL_BEGIN
/**
* Same thing, but initialize as a "cross test" helper, which is not killed at
* the end of the current test (but is killed at the end of the current suite).
*
* The passed-in testsuite must be a subclass of MTRTestCase.
*/
- (instancetype)initCrossTestWithAppName:(NSString *)name arguments:(NSArray<NSString *> *)arguments payload:(NSString *)payload testcase:(MTRTestCase *)testcase;
- (instancetype)initCrossTestWithAppName:(NSString *)name arguments:(NSArray<NSString *> *)arguments payload:(NSString *)payload testsuite:(Class)testsuite;

/**
* Get the unique index that will be used for the next initialization. This
Expand Down
33 changes: 22 additions & 11 deletions src/darwin/Framework/CHIPTests/TestHelpers/MTRTestServerAppRunner.m
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ @implementation MTRTestServerAppRunner {
#endif
}

- (instancetype)initInternalWithAppName:(NSString *)name arguments:(NSArray<NSString *> *)arguments payload:(NSString *)payload testcase:(MTRTestCase *)testcase isCrossTest:(BOOL)isCrossTest
- (instancetype)initInternalWithAppName:(NSString *)name arguments:(NSArray<NSString *> *)arguments payload:(NSString *)payload
{
#if !HAVE_NSTASK
XCTFail("Unable to start server app when we do not have NSTask");
Expand All @@ -61,7 +61,7 @@ - (instancetype)initInternalWithAppName:(NSString *)name arguments:(NSArray<NSSt
NSNumber * passcode = parsedPayload.setupPasscode;

__auto_type * executable = [NSString stringWithFormat:@"out/debug/%@-app/chip-%@-app", name, name];
_appTask = [testcase createTaskForPath:executable];
_appTask = [MTRTestCase createTaskForPath:executable];

__auto_type * forcedArguments = @[
// Make sure we only advertise on the local interface.
Expand Down Expand Up @@ -92,12 +92,6 @@ - (instancetype)initInternalWithAppName:(NSString *)name arguments:(NSArray<NSSt
_appTask.standardOutput = [NSFileHandle fileHandleForWritingAtPath:outFile];
_appTask.standardError = [NSFileHandle fileHandleForWritingAtPath:errorFile];

if (isCrossTest) {
[testcase launchCrossTestTask:_appTask];
} else {
[testcase launchTask:_appTask];
}

NSLog(@"Started chip-%@-app (%@) with arguments %@ stdout=%@ and stderr=%@", name, _appTask, allArguments, outFile, errorFile);

return self;
Expand All @@ -106,12 +100,29 @@ - (instancetype)initInternalWithAppName:(NSString *)name arguments:(NSArray<NSSt

- (instancetype)initWithAppName:(NSString *)name arguments:(NSArray<NSString *> *)arguments payload:(NSString *)payload testcase:(MTRTestCase *)testcase
{
return [self initInternalWithAppName:name arguments:arguments payload:payload testcase:testcase isCrossTest:NO];
if (!(self = [self initInternalWithAppName:name arguments:arguments payload:payload])) {
return nil;
}

[testcase launchTask:_appTask];

return self;
}

- (instancetype)initCrossTestWithAppName:(NSString *)name arguments:(NSArray<NSString *> *)arguments payload:(NSString *)payload testcase:(MTRTestCase *)testcase
- (instancetype)initCrossTestWithAppName:(NSString *)name arguments:(NSArray<NSString *> *)arguments payload:(NSString *)payload testsuite:(Class)testsuite
{
return [self initInternalWithAppName:name arguments:arguments payload:payload testcase:testcase isCrossTest:YES];
if (![testsuite isSubclassOfClass:MTRTestCase.class]) {
NSLog(@"%@ is not a subclass of MTRTestCase", testsuite);
return nil;
}

if (!(self = [self initInternalWithAppName:name arguments:arguments payload:payload])) {
return nil;
}

[MTRTestCase launchCrossTestTask:_appTask];

return self;
}

+ (unsigned)nextUniqueIndex
Expand Down

0 comments on commit 763487d

Please sign in to comment.