Summary:It handles mediator and is exposed via strategy to keep connection to test manager daemon alive.
Keeping strategy alive, didn't make much sense

Reviewed By: mmmulani

Differential Revision: D3041458

fb-gh-sync-id: 268cdcc5d79f79d145628a5556a1d0710110398d
shipit-source-id: 268cdcc5d79f79d145628a5556a1d0710110398d
This commit is contained in:
Marek Cirkos 2016-03-14 09:05:16 -07:00 коммит произвёл Facebook Github Bot 0
Родитель 4d0a616cd3
Коммит 2ddea9bdac
9 изменённых файлов: 135 добавлений и 40 удалений

Просмотреть файл

@ -162,6 +162,8 @@
AAF2D3571C33EA3100434516 /* FBSimulatorInteraction+Lifecycle.m in Sources */ = {isa = PBXBuildFile; fileRef = AAF2D3551C33EA3100434516 /* FBSimulatorInteraction+Lifecycle.m */; };
E7A30F0476B173B900000000 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DD70E2976B173B900000000 /* Cocoa.framework */; };
E7A30F04A6018C7A00000000 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DD70E29A6018C7A00000000 /* CoreGraphics.framework */; };
EE1277571C9329CC00DE52A1 /* FBTestManager.h in Headers */ = {isa = PBXBuildFile; fileRef = EE1277551C9329CC00DE52A1 /* FBTestManager.h */; settings = {ATTRIBUTES = (Public, ); }; };
EE1277581C9329CC00DE52A1 /* FBTestManager.m in Sources */ = {isa = PBXBuildFile; fileRef = EE1277561C9329CC00DE52A1 /* FBTestManager.m */; };
EE4F0D3A1C91B7DB00608E89 /* XCTestBootstrap.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EE4F0D301C91B7DA00608E89 /* XCTestBootstrap.framework */; };
EE4F0D701C91B82700608E89 /* FBApplicationDataPackage.h in Headers */ = {isa = PBXBuildFile; fileRef = EE4F0D4A1C91B82700608E89 /* FBApplicationDataPackage.h */; settings = {ATTRIBUTES = (Public, ); }; };
EE4F0D711C91B82700608E89 /* FBApplicationDataPackage.m in Sources */ = {isa = PBXBuildFile; fileRef = EE4F0D4B1C91B82700608E89 /* FBApplicationDataPackage.m */; };
@ -517,6 +519,8 @@
AAEA3AA81C90BB73004F8409 /* FBLogSearchTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBLogSearchTests.m; sourceTree = "<group>"; };
AAF2D3541C33EA3100434516 /* FBSimulatorInteraction+Lifecycle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "FBSimulatorInteraction+Lifecycle.h"; sourceTree = "<group>"; };
AAF2D3551C33EA3100434516 /* FBSimulatorInteraction+Lifecycle.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "FBSimulatorInteraction+Lifecycle.m"; sourceTree = "<group>"; };
EE1277551C9329CC00DE52A1 /* FBTestManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBTestManager.h; sourceTree = "<group>"; };
EE1277561C9329CC00DE52A1 /* FBTestManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBTestManager.m; sourceTree = "<group>"; };
EE4F0D301C91B7DA00608E89 /* XCTestBootstrap.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = XCTestBootstrap.framework; sourceTree = BUILT_PRODUCTS_DIR; };
EE4F0D391C91B7DB00608E89 /* XCTestBootstrapTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = XCTestBootstrapTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
EE4F0D4A1C91B82700608E89 /* FBApplicationDataPackage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBApplicationDataPackage.h; sourceTree = "<group>"; };
@ -1269,6 +1273,8 @@
EE4F0D661C91B82700608E89 /* TestManagerMediators */ = {
isa = PBXGroup;
children = (
EE1277551C9329CC00DE52A1 /* FBTestManager.h */,
EE1277561C9329CC00DE52A1 /* FBTestManager.m */,
EE4F0D671C91B82700608E89 /* FBTestManagerAPIMediator.h */,
EE4F0D681C91B82700608E89 /* FBTestManagerAPIMediator.m */,
);
@ -1559,6 +1565,7 @@
EE4F0D8B1C91B82700608E89 /* FBRunLoopSpinner.h in Headers */,
EE4F0D761C91B82700608E89 /* FBProductBundle+Private.h in Headers */,
EE4F0D8D1C91B82700608E89 /* NSError+XCTestBootstrap.h in Headers */,
EE1277571C9329CC00DE52A1 /* FBTestManager.h in Headers */,
EE4F0D751C91B82700608E89 /* FBFileManager.h in Headers */,
EE4F0D7B1C91B82700608E89 /* FBTestConfiguration.h in Headers */,
EE4F0D861C91B82700608E89 /* FBXCTestPreparationStrategy.h in Headers */,
@ -1931,6 +1938,7 @@
EE4F0D711C91B82700608E89 /* FBApplicationDataPackage.m in Sources */,
EE4F0D8E1C91B82700608E89 /* NSError+XCTestBootstrap.m in Sources */,
EE4F0D801C91B82700608E89 /* NSFileManager+FBFileManager.m in Sources */,
EE1277581C9329CC00DE52A1 /* FBTestManager.m in Sources */,
EE4F0D731C91B82700608E89 /* FBCodeSignCommand.m in Sources */,
EE4F0D831C91B82700608E89 /* FBDeviceTestPreparationStrategy.m in Sources */,
EE4F0D7C1C91B82700608E89 /* FBTestConfiguration.m in Sources */,

Просмотреть файл

@ -49,6 +49,16 @@
ReferencedContainer = "container:FBSimulatorControl.xcodeproj">
</BuildableReference>
</TestableReference>
<TestableReference
skipped = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "EE4F0D381C91B7DB00608E89"
BuildableName = "XCTestBootstrapTests.xctest"
BlueprintName = "XCTestBootstrapTests"
ReferencedContainer = "container:FBSimulatorControl.xcodeproj">
</BuildableReference>
</TestableReference>
</Testables>
<MacroExpansion>
<BuildableReference

Просмотреть файл

@ -2,6 +2,7 @@
#import <Foundation/Foundation.h>
@class FBTestManager;
@protocol FBXCTestPreparationStrategy;
@protocol FBDeviceOperator;
@ -25,8 +26,8 @@
@param attributes additional attributes used to start test runner
@param environment additional environment used to start test runner
@param error If there is an error, upon return contains an NSError object that describes the problem.
@return YES if the operation succeeds, otherwise NO.
@return testManager if the operation succeeds, otherwise nil.
*/
- (BOOL)startTestWithAttributes:(NSArray *)attributes environment:(NSDictionary *)environment error:(NSError **)error;
- (FBTestManager *)startTestManagerWithAttributes:(NSArray *)attributes environment:(NSDictionary *)environment error:(NSError **)error;
@end

Просмотреть файл

@ -6,15 +6,14 @@
#import "FBDeviceOperator.h"
#import "FBProductBundle.h"
#import "FBTestManagerAPIMediator.h"
#import "FBTestManager.h"
#import "FBTestRunnerConfiguration.h"
#import "FBXCTestPreparationStrategy.h"
#import "NSError+XCTestBootstrap.h"
@interface FBXCTestRunStrategy () <FBTestManagerDelegate>
@interface FBXCTestRunStrategy ()
@property (nonatomic, strong) id<FBDeviceOperator> deviceOperator;
@property (nonatomic, strong) id<FBXCTestPreparationStrategy> prepareStrategy;
@property (nonatomic, strong) FBTestManagerAPIMediator *mediator;
@end
@implementation FBXCTestRunStrategy
@ -27,14 +26,14 @@
return strategy;
}
- (BOOL)startTestWithAttributes:(NSArray *)attributes environment:(NSDictionary *)environment error:(NSError **)error
- (FBTestManager *)startTestManagerWithAttributes:(NSArray *)attributes environment:(NSDictionary *)environment error:(NSError **)error
{
NSAssert(self.deviceOperator, @"Device operator is needed to perform meaningful test");
NSAssert(self.prepareStrategy, @"Test preparation strategy is needed to perform meaningful test");
FBTestRunnerConfiguration *configuration = [self.prepareStrategy prepareTestWithDeviceOperator:self.deviceOperator error:error];
if (!configuration) {
return NO;
return nil;
}
NSMutableArray *mAttributes = (configuration.launchArguments ?: @[]).mutableCopy;
@ -51,7 +50,7 @@
arguments:mAttributes.copy
environment:mEnvironment.copy
error:error]) {
return NO;
return nil;
}
// Get XCTStubApps process Id
@ -60,31 +59,19 @@
if (error) {
*error = [NSError XCTestBootstrapErrorWithDescription:@"Failed to determine launched process PID"];
}
return NO;
return nil;
}
// Attach WDA
self.mediator =
[FBTestManagerAPIMediator mediatorWithDevice:self.deviceOperator.dvtDevice
testRunnerPID:testRunnerProcessID
sessionIdentifier:configuration.sessionIdentifier];
self.mediator.delegate = self;
[self.mediator connectTestRunnerWithTestManagerDaemon];
return YES;
}
#pragma mark - FBTestManagerDelegate
- (BOOL)testManagerMediator:(FBTestManagerAPIMediator *)mediator launchProcessWithPath:(NSString *)path bundleID:(NSString *)bundleID arguments:(NSArray *)arguments environmentVariables:(NSDictionary *)environment error:(NSError **)error
{
if (![self.deviceOperator installApplicationWithPath:path error:error]) {
return NO;
FBTestManager *testManager =
[FBTestManager testManagerWithOperator:self.deviceOperator
testRunnerPID:testRunnerProcessID
sessionIdentifier:configuration.sessionIdentifier
];
if (![testManager connectWithError:error]) {
return nil;
}
if (![self.deviceOperator launchApplicationWithBundleID:bundleID arguments:arguments environment:environment error:error]) {
return NO;
}
return YES;
return testManager;
}
@end

Просмотреть файл

@ -0,0 +1,37 @@
/**
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
#import <Foundation/Foundation.h>
@protocol FBDeviceOperator;
/**
This class manages connection with testmanager daemon
*/
@interface FBTestManager : NSObject
/**
Creates and returns a test manager with given paramenters
@param deviceOperator a device operator used to handle device
@param testRunnerPID a process id of test runner (XCTest bundle)
@param sessionIdentifier a session identifier of test that should be started
@return Prepared FBTestManager
*/
+ (instancetype)testManagerWithOperator:(id<FBDeviceOperator>)deviceOperator testRunnerPID:(pid_t)testRunnerPID sessionIdentifier:(NSUUID *)sessionIdentifier;
/**
Connects to test manager daemon
@param error If there is an error, upon return contains an NSError object that describes the problem.
@return YES if operation was successful, NO otherwise
*/
- (BOOL)connectWithError:(NSError **)error;
@end

Просмотреть файл

@ -0,0 +1,50 @@
/**
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
#import "FBTestManager.h"
#import "FBDeviceOperator.h"
#import "FBTestManagerAPIMediator.h"
@interface FBTestManager () <FBTestManagerMediatorDelegate>
@property (nonatomic, strong) FBTestManagerAPIMediator *mediator;
@property (nonatomic, strong) id<FBDeviceOperator> deviceOperator;
@end
@implementation FBTestManager
+ (instancetype)testManagerWithOperator:(id<FBDeviceOperator>)deviceOperator testRunnerPID:(pid_t)testRunnerPID sessionIdentifier:(NSUUID *)sessionIdentifier
{
FBTestManager *testManager = [self.class new];
testManager.mediator = [FBTestManagerAPIMediator mediatorWithDevice:deviceOperator.dvtDevice testRunnerPID:testRunnerPID sessionIdentifier:sessionIdentifier];
testManager.mediator.delegate = testManager;
testManager.deviceOperator = deviceOperator;
return testManager;
}
- (BOOL)connectWithError:(NSError *__autoreleasing *)error
{
[self.mediator connectTestRunnerWithTestManagerDaemon];
return YES;
}
#pragma mark - FBTestManagerMediatorDelegate
- (BOOL)testManagerMediator:(FBTestManagerAPIMediator *)mediator launchProcessWithPath:(NSString *)path bundleID:(NSString *)bundleID arguments:(NSArray *)arguments environmentVariables:(NSDictionary *)environment error:(NSError **)error
{
if (![self.deviceOperator installApplicationWithPath:path error:error]) {
return NO;
}
if (![self.deviceOperator launchApplicationWithBundleID:bundleID arguments:arguments environment:environment error:error]) {
return NO;
}
return YES;
}
@end

Просмотреть файл

@ -4,14 +4,14 @@
@class DVTAbstractiOSDevice;
@protocol FBTestManagerDelegate;
@protocol FBTestManagerMediatorDelegate;
/**
This is massively simplified reimplementations of Apple's _IDETestManagerAPIMediator class,
which is mediator (running on host) between test runner (app that executes XCTest bundle on device) and testmanagerd (running on device), that helps to launch tests.
*/
@interface FBTestManagerAPIMediator : NSObject
@property (nonatomic, weak) id<FBTestManagerDelegate> delegate;
@property (nonatomic, weak) id<FBTestManagerMediatorDelegate> delegate;
/**
Creates and returns a mediator with given paramenters
@ -31,7 +31,7 @@
@end
@protocol FBTestManagerDelegate <NSObject>
@protocol FBTestManagerMediatorDelegate <NSObject>
/**
Request to launch an application

Просмотреть файл

@ -1,3 +1,5 @@
// Copyright 2004-present Facebook. All Rights Reserved.
/**
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
@ -15,12 +17,12 @@
#import <XCTestBootstrap/FBFileManager.h>
#import <XCTestBootstrap/FBProductBundle.h>
#import <XCTestBootstrap/FBRunLoopSpinner.h>
#import <XCTestBootstrap/FBSimulatorTestPreparationStrategy.h>
#import <XCTestBootstrap/FBTestBundle.h>
#import <XCTestBootstrap/FBTestConfiguration.h>
#import <XCTestBootstrap/FBTestRunnerConfiguration.h>
#import <XCTestBootstrap/FBTestManager.h>
#import <XCTestBootstrap/FBTestManagerAPIMediator.h>
#import <XCTestBootstrap/FBSimulatorTestPreparationStrategy.h>
#import <XCTestBootstrap/FBTestRunnerConfiguration.h>
#import <XCTestBootstrap/FBXCTestRunStrategy.h>
#import <XCTestBootstrap/NSError+XCTestBootstrap.h>
#import <XCTestBootstrap/NSFileManager+FBFileManager.h>

Просмотреть файл

@ -18,14 +18,14 @@
{
id prepareTestMock = [OCMockObject niceMockForProtocol:@protocol(FBXCTestPreparationStrategy)];
FBXCTestRunStrategy *strategy = [FBXCTestRunStrategy strategyWithDeviceOperator:nil testPrepareStrategy:prepareTestMock];
XCTAssertThrows([strategy startTestWithAttributes:nil environment:nil error:nil]);
XCTAssertThrows([strategy startTestManagerWithAttributes:nil environment:nil error:nil]);
}
- (void)testTestRunWithRequiredAttributes
{
id prepareTestMock = [OCMockObject niceMockForProtocol:@protocol(FBXCTestPreparationStrategy)];
FBXCTestRunStrategy *strategy = [FBXCTestRunStrategy strategyWithDeviceOperator:[OCMockObject mockForProtocol:@protocol(FBDeviceOperator)] testPrepareStrategy:prepareTestMock];
XCTAssertNoThrow([strategy startTestWithAttributes:nil environment:nil error:nil]);
XCTAssertNoThrow([strategy startTestManagerWithAttributes:nil environment:nil error:nil]);
}
- (void)testCallToTestPreparationStep
@ -33,7 +33,7 @@
OCMockObject<FBXCTestPreparationStrategy> *prepareTestMock = [OCMockObject mockForProtocol:@protocol(FBXCTestPreparationStrategy)];
[[prepareTestMock expect] prepareTestWithDeviceOperator:[OCMArg any] error:[OCMArg anyObjectRef]];
FBXCTestRunStrategy *strategy = [FBXCTestRunStrategy strategyWithDeviceOperator:[OCMockObject mockForProtocol:@protocol(FBDeviceOperator)] testPrepareStrategy:prepareTestMock];
XCTAssertNoThrow([strategy startTestWithAttributes:nil environment:nil error:nil]);
XCTAssertNoThrow([strategy startTestManagerWithAttributes:nil environment:nil error:nil]);
[prepareTestMock verify];
}
@ -50,7 +50,7 @@
[[[prepareTestMock stub] andReturn:testConfigurationMock] prepareTestWithDeviceOperator:[OCMArg any] error:[OCMArg anyObjectRef]];
FBXCTestRunStrategy *strategy = [FBXCTestRunStrategy strategyWithDeviceOperator:deviceOperatorMock testPrepareStrategy:prepareTestMock];
XCTAssertTrue([strategy startTestWithAttributes:@[@4] environment:@{@"A" : @"B"} error:nil]);
XCTAssertTrue([strategy startTestManagerWithAttributes:@[@4] environment:@{@"A" : @"B"} error:nil]);
[deviceOperatorMock verify];
}
@ -59,7 +59,7 @@
OCMockObject<FBDeviceOperator> *deviceOperatorMock = [OCMockObject mockForProtocol:@protocol(FBDeviceOperator)];
id prepareTestMock = [OCMockObject niceMockForProtocol:@protocol(FBXCTestPreparationStrategy)];
FBXCTestRunStrategy *strategy = [FBXCTestRunStrategy strategyWithDeviceOperator:deviceOperatorMock testPrepareStrategy:prepareTestMock];
XCTAssertFalse([strategy startTestWithAttributes:nil environment:nil error:nil]);
XCTAssertFalse([strategy startTestManagerWithAttributes:nil environment:nil error:nil]);
[deviceOperatorMock verify];
}