Не подтверждена Коммит 621392c6 создал по автору Benjamin Pasero's avatar Benjamin Pasero Зафиксировано автором GitHub
Просмотр файлов

refactor: enhance process instance registration and termination logging (#245409)

владелец 8243aa99
......@@ -38,18 +38,28 @@ interface ICodeInstance {
const instances = new Set<ICodeInstance>();
function registerInstance(process: cp.ChildProcess, logger: Logger, type: string) {
function registerInstance(process: cp.ChildProcess, logger: Logger, type: 'electron' | 'server'): { safeToKill: Promise<void> } {
const instance = { kill: () => teardown(process, logger) };
instances.add(instance);
process.stdout?.on('data', data => logger.log(`[${type}] stdout: ${data}`));
process.stderr?.on('data', error => logger.log(`[${type}] stderr: ${error}`));
const safeToKill = new Promise<void>(resolve => {
process.stdout?.on('data', data => {
const output = data.toString();
if (output.indexOf('calling app.quit()') >= 0 && type === 'electron') {
setTimeout(() => resolve(), 500 /* give Electron some time to actually terminate fully */);
}
logger.log(`[${type}] stdout: ${output}`);
});
process.stderr?.on('data', error => logger.log(`[${type}] stderr: ${error}`));
});
process.once('exit', (code, signal) => {
logger.log(`[${type}] Process terminated (pid: ${process.pid}, code: ${code}, signal: ${signal})`);
instances.delete(instance);
});
return { safeToKill };
}
async function teardownAll(signal?: number) {
......@@ -85,15 +95,7 @@ export async function launch(options: LaunchOptions): Promise<Code> {
// Electron smoke tests (playwright)
else {
const { electronProcess, driver } = await measureAndLog(() => launchPlaywrightElectron(options), 'launch playwright (electron)', options.logger);
registerInstance(electronProcess, options.logger, 'electron');
const safeToKill = new Promise<void>(resolve => {
process.stdout?.on('data', data => {
if (data.toString().includes('Lifecycle#app.on(will-quit) - calling app.quit()')) {
setTimeout(() => resolve(), 500 /* give Electron some time to actually terminate fully */);
}
});
});
const { safeToKill } = registerInstance(electronProcess, options.logger, 'electron');
return new Code(driver, options.logger, electronProcess, safeToKill, options.quality);
}
......@@ -155,7 +157,10 @@ export class Code {
this.driver.close();
let safeToKill = false;
this.safeToKill?.then(() => safeToKill = true);
this.safeToKill?.then(() => {
this.logger.log('Smoke test exit(): safeToKill() called');
safeToKill = true;
});
// Await the exit of the application
(async () => {
......@@ -164,25 +169,26 @@ export class Code {
retries++;
if (safeToKill) {
this.logger.log('Smoke test exit() call did not terminate the process yet, but safeToKill is true, so we can kill it');
process.kill(pid);
this.logger.log('Smoke test exit(): call did not terminate the process yet, but safeToKill is true, so we can kill it');
this.kill(pid);
}
switch (retries) {
// after 10 seconds: forcefully kill
case 20: {
this.logger.log('Smoke test exit() call did not terminate process after 10s, forcefully exiting the application...');
process.kill(pid);
this.logger.log('Smoke test exit(): call did not terminate process after 10s, forcefully exiting the application...');
this.kill(pid);
break;
}
// after 20 seconds: give up
case 40: {
this.logger.log('Smoke test exit() call did not terminate process after 20s, giving up');
process.kill(pid);
this.logger.log('Smoke test exit(): call did not terminate process after 20s, giving up');
this.kill(pid);
done = true;
resolve();
break;
}
}
......@@ -190,9 +196,9 @@ export class Code {
process.kill(pid, 0); // throws an exception if the process doesn't exist anymore.
await this.wait(500);
} catch (error) {
this.logger.log('Smoke test exit() call terminated process successfully');
done = true;
this.logger.log('Smoke test exit(): call terminated process successfully');
done = true;
resolve();
}
}
......@@ -200,6 +206,15 @@ export class Code {
}), 'Code#exit()', this.logger);
}
private kill(pid: number): void {
try {
this.logger.log(`Smoke test exit(): Trying to SIGTERM process: ${pid}`);
process.kill(pid);
} catch (e) {
this.logger.log('Smoke test exit(): SIGTERM failed', e);
}
}
async getElement(selector: string): Promise<IElement | undefined> {
return (await this.driver.getElements(selector))?.[0];
}
......
Поддерживает Markdown
0% или .
You are about to add 0 people to the discussion. Proceed with caution.
Сначала завершите редактирование этого сообщения!
Пожалуйста, зарегистрируйтесь или чтобы прокомментировать