Skip to content

fix: Run and debug fail for iOS in Sidekick #3643

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
May 30, 2018
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 1 addition & 6 deletions lib/definitions/debug.d.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/**
* Describes information for starting debug process.
*/
interface IDebugData extends Mobile.IDeviceIdentifier {
interface IDebugData extends Mobile.IDeviceIdentifier, IProjectDir {
/**
* Application identifier of the app that it will be debugged.
*/
Expand All @@ -16,11 +16,6 @@ interface IDebugData extends Mobile.IDeviceIdentifier {
* The name of the application, for example `MyProject`.
*/
projectName?: string;

/**
* Path to project.
*/
projectDir?: string;
}

/**
Expand Down
10 changes: 6 additions & 4 deletions lib/definitions/ios-debugger-port-service.d.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
interface IIOSDebuggerPortInputData {
interface IIOSDebuggerPortInputData extends IProjectDir {
deviceId: string;
appId: string;
}
Expand All @@ -21,8 +21,10 @@ interface IIOSDebuggerPortService {
/**
* Attaches on DEBUGGER_PORT_FOUND event and STARTING_IOS_APPLICATION events
* In case when DEBUGGER_PORT_FOUND event is emitted, stores the port and clears the timeout if such.
* In case when STARTING_IOS_APPLICATION event is emiited, sets the port to null and add timeout for 5000 miliseconds which checks if port is null and prints a warning.
* @param {Mobile.IDevice} device - Describes the device which logs should be parsed.
* In case when STARTING_IOS_APPLICATION event is emitted, sets the port to null and add timeout for 5000 miliseconds which checks if port is null and prints a warning.
* @param {Mobile.IDevice} device - Describes the device which logs should be parsed.
* @param {IProjectDir} data - Object that has a projectDir property.
* @returns {void}
*/
attachToDebuggerPortFoundEvent(device: Mobile.IDevice): void;
attachToDebuggerPortFoundEvent(device: Mobile.IDevice, data: IProjectDir): void;
}
2 changes: 1 addition & 1 deletion lib/definitions/ios-log-parser-service.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@ interface IIOSLogParserService extends NodeJS.EventEmitter {
* Starts looking for debugger port. Attaches on device logs and processes them. In case when port is found, DEBUGGER_PORT_FOUND event is emitted.
* @param {Mobile.IDevice} device - Describes the device which logs will be processed.
*/
startParsingLog(device: Mobile.IDevice): void;
startParsingLog(device: Mobile.IDevice, data: IProjectName): void;
}
6 changes: 2 additions & 4 deletions lib/definitions/project.d.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
interface IProjectName {
projectName: string;
}

interface IProjectSettingsBase extends IProjectName {
/**
* Name of the newly created application.
*/
projectName: string;
}

interface IProjectSettingsBase extends IProjectName {
/**
* Defines whether the `npm install` command should be executed with `--ignore-scripts` option.
* When it is passed, all scripts (postinstall for example) will not be executed.
Expand Down
6 changes: 3 additions & 3 deletions lib/services/ios-debug-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ export class IOSDebugService extends DebugServiceBase implements IPlatformDebugS

private async emulatorStart(debugData: IDebugData, debugOptions: IDebugOptions): Promise<string> {
const device = await this.$devicesService.getDevice(debugData.deviceIdentifier);
this.$iOSDebuggerPortService.attachToDebuggerPortFoundEvent(device);
this.$iOSDebuggerPortService.attachToDebuggerPortFoundEvent(device, debugData);
const result = await this.wireDebuggerClient(debugData, debugOptions);

const attachRequestMessage = this.$iOSNotification.getAttachRequest(debugData.applicationIdentifier, debugData.deviceIdentifier);
Expand Down Expand Up @@ -192,7 +192,7 @@ export class IOSDebugService extends DebugServiceBase implements IPlatformDebugS
}

private async deviceStartCore(device: Mobile.IiOSDevice, debugData: IDebugData, debugOptions: IDebugOptions): Promise<string> {
this.$iOSDebuggerPortService.attachToDebuggerPortFoundEvent(device);
this.$iOSDebuggerPortService.attachToDebuggerPortFoundEvent(device, debugData);
await this.$iOSSocketRequestExecutor.executeAttachRequest(device, AWAIT_NOTIFICATION_TIMEOUT_SECONDS, debugData.applicationIdentifier);
return this.wireDebuggerClient(debugData, debugOptions, device);
}
Expand Down Expand Up @@ -231,7 +231,7 @@ export class IOSDebugService extends DebugServiceBase implements IPlatformDebugS

private getSocketFactory(debugData: IDebugData, device?: Mobile.IiOSDevice): () => Promise<net.Socket> {
const factory = async () => {
const port = await this.$iOSDebuggerPortService.getPort({ deviceId: debugData.deviceIdentifier, appId: debugData.applicationIdentifier });
const port = await this.$iOSDebuggerPortService.getPort({ projectDir: debugData.projectDir, deviceId: debugData.deviceIdentifier, appId: debugData.applicationIdentifier });
if (!port) {
this.$errors.fail("NativeScript debugger was not able to get inspector socket port.");
}
Expand Down
18 changes: 10 additions & 8 deletions lib/services/ios-debugger-port-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,12 @@ export class IOSDebuggerPortService implements IIOSDebuggerPortService {
constructor(private $iOSLogParserService: IIOSLogParserService,
private $iOSProjectService: IPlatformProjectService,
private $iOSNotification: IiOSNotification,
private $logger: ILogger,
private $projectData: IProjectData) { }
private $projectDataService: IProjectDataService,
private $logger: ILogger) { }

public getPort(data: IIOSDebuggerPortInputData): Promise<number> {
return new Promise((resolve, reject) => {
if (!this.canStartLookingForDebuggerPort()) {
if (!this.canStartLookingForDebuggerPort(data)) {
resolve(IOSDebuggerPortService.DEFAULT_PORT);
return;
}
Expand All @@ -36,19 +36,21 @@ export class IOSDebuggerPortService implements IIOSDebuggerPortService {
});
}

public attachToDebuggerPortFoundEvent(device: Mobile.IDevice): void {
if (!this.canStartLookingForDebuggerPort()) {
public attachToDebuggerPortFoundEvent(device: Mobile.IDevice, data: IProjectDir): void {
const projectData = this.$projectDataService.getProjectData(data && data.projectDir);
if (!this.canStartLookingForDebuggerPort(projectData)) {
return;
}

this.attachToDebuggerPortFoundEventCore();
this.attachToAttachRequestEvent(device);

this.$iOSLogParserService.startParsingLog(device);
this.$iOSLogParserService.startParsingLog(device, projectData);
}

private canStartLookingForDebuggerPort(): boolean {
const frameworkVersion = this.$iOSProjectService.getFrameworkVersion(this.$projectData);
private canStartLookingForDebuggerPort(data: IProjectDir): boolean {
const projectData = this.$projectDataService.getProjectData(data && data.projectDir);
const frameworkVersion = this.$iOSProjectService.getFrameworkVersion(projectData);
return semver.gt(frameworkVersion, IOSDebuggerPortService.MIN_REQUIRED_FRAMEWORK_VERSION);
}

Expand Down
7 changes: 3 additions & 4 deletions lib/services/ios-log-parser-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,12 @@ export class IOSLogParserService extends EventEmitter implements IIOSLogParserSe
constructor(private $deviceLogProvider: Mobile.IDeviceLogProvider,
private $iosDeviceOperations: IIOSDeviceOperations,
private $iOSSimulatorLogProvider: Mobile.IiOSSimulatorLogProvider,
private $logger: ILogger,
private $projectData: IProjectData) {
private $logger: ILogger) {
super();
}

public startParsingLog(device: Mobile.IDevice): void {
this.$deviceLogProvider.setProjectNameForDevice(device.deviceInfo.identifier, this.$projectData.projectName);
public startParsingLog(device: Mobile.IDevice, data: IProjectName): void {
this.$deviceLogProvider.setProjectNameForDevice(device.deviceInfo.identifier, data.projectName);

if (!this.startedDeviceLogInstances[device.deviceInfo.identifier]) {
this.startParsingLogCore(device);
Expand Down
1 change: 1 addition & 0 deletions lib/services/livesync/android-device-livesync-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ export class AndroidDeviceLiveSyncService extends DeviceLiveSyncServiceBase impl
private port: number;

constructor(_device: Mobile.IDevice,
data: IProjectDir,
private $mobileHelper: Mobile.IMobileHelper,
private $devicePathProvider: IDevicePathProvider,
private $injector: IInjector,
Expand Down
4 changes: 2 additions & 2 deletions lib/services/livesync/android-livesync-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ export class AndroidLiveSyncService extends PlatformLiveSyncServiceBase implemen
super($fs, $logger, $platformsData, $projectFilesManager, $devicePathProvider, $projectFilesProvider);
}

protected _getDeviceLiveSyncService(device: Mobile.IDevice): INativeScriptDeviceLiveSyncService {
const service = this.$injector.resolve<INativeScriptDeviceLiveSyncService>(AndroidDeviceLiveSyncService, { _device: device });
protected _getDeviceLiveSyncService(device: Mobile.IDevice, data: IProjectDir): INativeScriptDeviceLiveSyncService {
const service = this.$injector.resolve<INativeScriptDeviceLiveSyncService>(AndroidDeviceLiveSyncService, { _device: device, data });
return service;
}
}
Expand Down
15 changes: 8 additions & 7 deletions lib/services/livesync/ios-device-livesync-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ export class IOSDeviceLiveSyncService extends DeviceLiveSyncServiceBase implemen
private device: Mobile.IiOSDevice;

constructor(_device: Mobile.IiOSDevice,
data: IProjectDir,
private $iOSSocketRequestExecutor: IiOSSocketRequestExecutor,
private $iOSNotification: IiOSNotification,
private $iOSEmulatorServices: Mobile.IiOSSimulatorService,
Expand All @@ -19,25 +20,25 @@ export class IOSDeviceLiveSyncService extends DeviceLiveSyncServiceBase implemen
private $processService: IProcessService,
protected $platformsData: IPlatformsData) {
super($platformsData);
this.$iOSDebuggerPortService.attachToDebuggerPortFoundEvent(_device);
this.$iOSDebuggerPortService.attachToDebuggerPortFoundEvent(_device, data);
this.device = _device;
}

private async setupSocketIfNeeded(appId: string): Promise<boolean> {
private async setupSocketIfNeeded(projectData: IProjectData): Promise<boolean> {
if (this.socket) {
return true;
}

if (this.device.isEmulator) {
await this.$iOSEmulatorServices.postDarwinNotification(this.$iOSNotification.getAttachRequest(appId, this.device.deviceInfo.identifier), this.device.deviceInfo.identifier);
const port = await this.$iOSDebuggerPortService.getPort({ deviceId: this.device.deviceInfo.identifier, appId });
await this.$iOSEmulatorServices.postDarwinNotification(this.$iOSNotification.getAttachRequest(projectData.projectId, this.device.deviceInfo.identifier), this.device.deviceInfo.identifier);
const port = await this.$iOSDebuggerPortService.getPort({ projectDir: projectData.projectDir, deviceId: this.device.deviceInfo.identifier, appId: projectData.projectId });
this.socket = await this.$iOSEmulatorServices.connectToPort({ port });
if (!this.socket) {
return false;
}
} else {
await this.$iOSSocketRequestExecutor.executeAttachRequest(this.device, constants.AWAIT_NOTIFICATION_TIMEOUT_SECONDS, appId);
const port = await this.$iOSDebuggerPortService.getPort({ deviceId: this.device.deviceInfo.identifier, appId });
await this.$iOSSocketRequestExecutor.executeAttachRequest(this.device, constants.AWAIT_NOTIFICATION_TIMEOUT_SECONDS, projectData.projectId);
const port = await this.$iOSDebuggerPortService.getPort({ projectDir: projectData.projectDir, deviceId: this.device.deviceInfo.identifier, appId: projectData.projectId });
this.socket = await this.device.connectToPort(port);
}

Expand Down Expand Up @@ -70,7 +71,7 @@ export class IOSDeviceLiveSyncService extends DeviceLiveSyncServiceBase implemen
return;
}

if (await this.setupSocketIfNeeded(projectData.projectId)) {
if (await this.setupSocketIfNeeded(projectData)) {
await this.liveEdit(scriptFiles);
await this.reloadPage(deviceAppData, otherFiles);
} else {
Expand Down
6 changes: 3 additions & 3 deletions lib/services/livesync/ios-livesync-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ export class IOSLiveSyncService extends PlatformLiveSyncServiceBase implements I
return super.fullSync(syncInfo);
}

this.$iOSDebuggerPortService.attachToDebuggerPortFoundEvent(device);
this.$iOSDebuggerPortService.attachToDebuggerPortFoundEvent(device, syncInfo.projectData);

const projectData = syncInfo.projectData;
const platformData = this.$platformsData.getPlatformData(device.deviceInfo.platform, projectData);
Expand Down Expand Up @@ -70,8 +70,8 @@ export class IOSLiveSyncService extends PlatformLiveSyncServiceBase implements I
}
}

protected _getDeviceLiveSyncService(device: Mobile.IDevice): INativeScriptDeviceLiveSyncService {
const service = this.$injector.resolve<INativeScriptDeviceLiveSyncService>(IOSDeviceLiveSyncService, { _device: device });
protected _getDeviceLiveSyncService(device: Mobile.IDevice, data: IProjectDir): INativeScriptDeviceLiveSyncService {
const service = this.$injector.resolve<INativeScriptDeviceLiveSyncService>(IOSDeviceLiveSyncService, { _device: device, data });
return service;
}
}
Expand Down
14 changes: 7 additions & 7 deletions lib/services/livesync/platform-livesync-service-base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,20 +12,20 @@ export abstract class PlatformLiveSyncServiceBase {
private $devicePathProvider: IDevicePathProvider,
private $projectFilesProvider: IProjectFilesProvider) { }

public getDeviceLiveSyncService(device: Mobile.IDevice, applicationIdentifier: string): INativeScriptDeviceLiveSyncService {
const key = device.deviceInfo.identifier + applicationIdentifier;
public getDeviceLiveSyncService(device: Mobile.IDevice, projectData: IProjectData): INativeScriptDeviceLiveSyncService {
const key = device.deviceInfo.identifier + projectData.projectId;
if (!this._deviceLiveSyncServicesCache[key]) {
this._deviceLiveSyncServicesCache[key] = this._getDeviceLiveSyncService(device);
this._deviceLiveSyncServicesCache[key] = this._getDeviceLiveSyncService(device, projectData);
}

return this._deviceLiveSyncServicesCache[key];
}

protected abstract _getDeviceLiveSyncService(device: Mobile.IDevice): INativeScriptDeviceLiveSyncService;
protected abstract _getDeviceLiveSyncService(device: Mobile.IDevice, data: IProjectDir): INativeScriptDeviceLiveSyncService;

public async refreshApplication(projectData: IProjectData, liveSyncInfo: ILiveSyncResultInfo): Promise<void> {
if (liveSyncInfo.isFullSync || liveSyncInfo.modifiedFilesData.length) {
const deviceLiveSyncService = this.getDeviceLiveSyncService(liveSyncInfo.deviceAppData.device, projectData.projectId);
const deviceLiveSyncService = this.getDeviceLiveSyncService(liveSyncInfo.deviceAppData.device, projectData);
this.$logger.info("Refreshing application...");
await deviceLiveSyncService.refreshApplication(projectData, liveSyncInfo);
}
Expand All @@ -34,7 +34,7 @@ export abstract class PlatformLiveSyncServiceBase {
public async fullSync(syncInfo: IFullSyncInfo): Promise<ILiveSyncResultInfo> {
const projectData = syncInfo.projectData;
const device = syncInfo.device;
const deviceLiveSyncService = this.getDeviceLiveSyncService(device, syncInfo.projectData.projectId);
const deviceLiveSyncService = this.getDeviceLiveSyncService(device, syncInfo.projectData);
const platformData = this.$platformsData.getPlatformData(device.deviceInfo.platform, projectData);
const deviceAppData = await this.getAppData(syncInfo);

Expand Down Expand Up @@ -93,7 +93,7 @@ export abstract class PlatformLiveSyncServiceBase {
const localToDevicePaths = await this.$projectFilesManager.createLocalToDevicePaths(deviceAppData, projectFilesPath, mappedFiles, []);
modifiedLocalToDevicePaths.push(...localToDevicePaths);

const deviceLiveSyncService = this.getDeviceLiveSyncService(device, projectData.projectId);
const deviceLiveSyncService = this.getDeviceLiveSyncService(device, projectData);
await deviceLiveSyncService.removeFiles(deviceAppData, localToDevicePaths);
}

Expand Down
20 changes: 13 additions & 7 deletions test/services/ios-debugger-port-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,11 @@ function createTestInjector() {
injector.register("processService", {
attachToProcessExitSignals: () => ({})
});
injector.register("projectData", {
projectName: "test",
projectId: appId
injector.register("projectDataService", {
getProjectData: (projectDir: string) => ({
projectName: "test",
projectId: appId
})
});
injector.register("iOSNotification", DeviceApplicationManagerMock);

Expand Down Expand Up @@ -140,31 +142,35 @@ describe("iOSDebuggerPortService", () => {
}
];

const mockProjectDirObj = {
projectDir: "/Users/username/projectdir"
};

_.each(testCases, testCase => {
it(testCase.name, async () => {
iOSDebuggerPortService.attachToDebuggerPortFoundEvent(device);
iOSDebuggerPortService.attachToDebuggerPortFoundEvent(device, mockProjectDirObj);
if (testCase.emitStartingIOSApplicationEvent) {
emitStartingIOSApplicationEvent();
}
if (testCase.emittedPort) {
emitDeviceLog(getDebuggerPortMessage(testCase.emittedPort));
}

const promise = iOSDebuggerPortService.getPort({ deviceId: deviceId, appId: appId });
const promise = iOSDebuggerPortService.getPort({ deviceId: deviceId, appId: appId, projectDir: mockProjectDirObj.projectDir });
clock.tick(10000);
const port = await promise;
assert.deepEqual(port, testCase.emittedPort);
});
it(`${testCase.name} for multiline debugger port message.`, async () => {
iOSDebuggerPortService.attachToDebuggerPortFoundEvent(device);
iOSDebuggerPortService.attachToDebuggerPortFoundEvent(device, mockProjectDirObj);
if (testCase.emitStartingIOSApplicationEvent) {
emitStartingIOSApplicationEvent();
}
if (testCase.emittedPort) {
emitDeviceLog(getMultilineDebuggerPortMessage(testCase.emittedPort));
}

const promise = iOSDebuggerPortService.getPort({ deviceId: deviceId, appId: appId });
const promise = iOSDebuggerPortService.getPort({ deviceId: deviceId, appId: appId, projectDir: mockProjectDirObj.projectDir });
clock.tick(10000);
const port = await promise;
assert.deepEqual(port, testCase.emittedPort);
Expand Down
20 changes: 13 additions & 7 deletions test/services/ios-log-parser-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,11 @@ function createTestInjector() {
injector.register("processService", {
attachToProcessExitSignals: () => ({})
});
injector.register("projectData", {
projectName: "test",
projectId: appId
injector.register("projectDataService", {
getProjectData: (projectDir: string) => ({
projectName: "test",
projectId: appId
})
});

return injector;
Expand Down Expand Up @@ -77,12 +79,16 @@ describe("iOSLogParserService", () => {
});
}

const mockProjectNameObj: IProjectName = {
projectName: "projectName"
};

describe("startLookingForDebuggerPort", () => {
it(`should emit ${DEBUGGER_PORT_FOUND_EVENT_NAME} event`, async () => {
const emittedMessagesCount = 1;
const promise = attachOnDebuggerFoundEvent(emittedMessagesCount);

iOSLogParserService.startParsingLog(device);
iOSLogParserService.startParsingLog(device, mockProjectNameObj);
emitDeviceLog("test message");
emitDeviceLog(getDebuggerPortMessage(18181));

Expand All @@ -95,7 +101,7 @@ describe("iOSLogParserService", () => {
const emittedMessagesCount = 5;
const promise = attachOnDebuggerFoundEvent(emittedMessagesCount);

iOSLogParserService.startParsingLog(device);
iOSLogParserService.startParsingLog(device, mockProjectNameObj);
emitDeviceLog(getDebuggerPortMessage(18181));
emitDeviceLog(getDebuggerPortMessage(18181));
emitDeviceLog(getDebuggerPortMessage(18181));
Expand All @@ -115,7 +121,7 @@ describe("iOSLogParserService", () => {
const emittedMessagesCount = 5;
const promise = attachOnDebuggerFoundEvent(emittedMessagesCount);

iOSLogParserService.startParsingLog(device);
iOSLogParserService.startParsingLog(device, mockProjectNameObj);
emitDeviceLog(getDebuggerPortMessage(45898));
emitDeviceLog(getDebuggerPortMessage(1809));
emitDeviceLog(getDebuggerPortMessage(65072));
Expand All @@ -136,7 +142,7 @@ describe("iOSLogParserService", () => {

iOSLogParserService.on(DEBUGGER_PORT_FOUND_EVENT_NAME, (data: IIOSDebuggerPortData) => isDebuggedPortFound = true);

iOSLogParserService.startParsingLog(device);
iOSLogParserService.startParsingLog(device, mockProjectNameObj);
emitDeviceLog("some test message");
emitDeviceLog("another test message");

Expand Down