Skip to content

Commit

Permalink
E2E: Address review comments
Browse files Browse the repository at this point in the history
Signed-off-by: Mark Yen <mark.yen@suse.com>
  • Loading branch information
mook-as committed Jun 29, 2023
1 parent 755a85f commit b835a88
Show file tree
Hide file tree
Showing 6 changed files with 34 additions and 30 deletions.
2 changes: 1 addition & 1 deletion e2e/credentials-server.e2e.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,7 @@ describeWithCreds('Credentials server', () => {
test.describe.configure({ mode: 'serial' });

test.beforeAll(async() => {
await tool('rdctl', 'factory-reset');
await tool('rdctl', 'factory-reset', '--verbose');
createDefaultSettings({ kubernetes: { enabled: false } });
electronApp = await startRancherDesktop(__filename, { mock: false });
page = await electronApp.firstWindow();
Expand Down
3 changes: 1 addition & 2 deletions e2e/lockedFields.e2e.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,9 +97,8 @@ test.describe('Locked fields', () => {
page = await electronApp.firstWindow();
});

test.afterAll(() => teardown(electronApp, __filename));

test.afterAll(async() => {
await teardown(electronApp, __filename);
await tool('rdctl', 'factory-reset', '--verbose');
reopenLogs();
});
Expand Down
3 changes: 1 addition & 2 deletions e2e/preferences.e2e.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,8 @@ test.describe.serial('Main App Test', () => {
preferencesWindow = await electronApp.waitForEvent('window', page => /preferences/i.test(page.url()));
});

test.afterAll(() => teardown(electronApp, __filename));

test.afterAll(async() => {
await teardown(electronApp, __filename);
await tool('rdctl', 'factory-reset', '--verbose');
reopenLogs();
});
Expand Down
19 changes: 11 additions & 8 deletions e2e/utils/TestUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -163,27 +163,30 @@ export async function teardownApp(app: ElectronApplication) {
}
// Try to do platform-specific killing based on process groups
if (process.platform === 'darwin' || process.platform === 'linux') {
for (const signal of ['TERM', 'TERM', 'TERM', 'KILL']) {
let pids = '';
// Send SIGTERM to the process group, wait three seconds, then send
// SIGKILL and wait for one more second.
for (const [signal, timeout] of [['TERM', 3_000], ['KILL', 1_000]] as const) {
let pids: string[] = [];

try {
const args = ['-o', 'pid=', process.platform === 'darwin' ? '-g' : '--sid', `${ pid }`];
const { stdout } = await childProcess.spawnFile('ps', args, { stdio: ['ignore', 'pipe', 'inherit'] });

pids = (await childProcess.spawnFile('ps', args, { stdio: ['ignore', 'pipe', 'inherit'] })).stdout;
pids = stdout.trim().split(/\s+/);
} catch (ex) {
console.log(`Did not find processes in process group, ignoring.`);
console.log(`Did not find processes in process group ${ pid }, ignoring.`);
break;
}

try {
if (pids.trim()) {
console.log(`Manually killing group processes ${ pids.replace(/\r?\n/g, ' ').trim() }`);
await childProcess.spawnFile('kill', ['-s', signal].concat(...pids.split(/\s+/).filter(p => p)));
if (pids.length > 0) {
console.log(`Manually killing group processes ${ pids.join(' ') }`);
await childProcess.spawnFile('kill', ['-s', signal, ...pids]);
}
} catch (ex) {
console.log(`Failed to process group: ${ ex } (retrying)`);
}
await util.promisify(setTimeout)(1_000);
await util.promisify(setTimeout)(timeout);
}
}
}
Expand Down
26 changes: 11 additions & 15 deletions pkg/rancher-desktop/backend/mock.ts
Original file line number Diff line number Diff line change
Expand Up @@ -256,35 +256,31 @@ class MockContainerEngineClient implements ContainerEngineClient {
return Promise.resolve();
}

readFile(imageID: string, filePath: string): Promise<string>;
readFile(imageID: string, filePath: string, options: { encoding?: BufferEncoding | undefined; namespace?: string | undefined; }): Promise<string>;
readFile(imageID: string, filePath: string, options?: unknown): Promise<string> {
readFile(imageID: string, filePath: string, options?: { encoding?: BufferEncoding; namespace?: string; }): Promise<string> {
throw new Error('Method not implemented.');
}

copyFile(imageID: string, sourcePath: string, destinationDir: string): Promise<void>;
copyFile(imageID: string, sourcePath: string, destinationDir: string, options: { namespace?: string | undefined; }): Promise<void>;
copyFile(imageID: unknown, sourcePath: unknown, destinationDir: unknown, options?: unknown): Promise<void> {
copyFile(imageID: string, sourcePath: string, destinationDir: string, options?: { namespace?: string; }): Promise<void> {
throw new Error('Method not implemented.');
}

getTags(imageName: string, options?: ContainerBasicOptions | undefined): Promise<Set<string>> {
getTags(imageName: string, options?: ContainerBasicOptions): Promise<Set<string>> {
throw new Error('Method not implemented.');
}

run(imageID: string, options?: ContainerRunOptions | undefined): Promise<string> {
run(imageID: string, options?: ContainerRunOptions): Promise<string> {
throw new Error('Method not implemented.');
}

stop(container: string, options?: ContainerStopOptions | undefined): Promise<void> {
stop(container: string, options?: ContainerStopOptions): Promise<void> {
throw new Error('Method not implemented.');
}

composeUp(options: ContainerComposeOptions): Promise<void> {
throw new Error('Method not implemented.');
}

composeDown(options?: ContainerComposeOptions | undefined): Promise<void> {
composeDown(options?: ContainerComposeOptions): Promise<void> {
throw new Error('Method not implemented.');
}

Expand All @@ -296,11 +292,11 @@ class MockContainerEngineClient implements ContainerEngineClient {
throw new Error('Method not implemented.');
}

runClient(args: string[], stdio?: 'ignore' | undefined, options?: ContainerRunClientOptions | undefined): Promise<Record<string, never>>;
runClient(args: string[], stdio: Log, options?: ContainerRunClientOptions | undefined): Promise<Record<string, never>>;
runClient(args: string[], stdio: 'pipe', options?: ContainerRunClientOptions | undefined): Promise<{ stdout: string; stderr: string; }>;
runClient(args: string[], stdio: 'stream', options?: ContainerRunClientOptions | undefined): ReadableProcess;
runClient(args: unknown, stdio?: unknown, options?: unknown): import('./containerClient').ReadableProcess | Promise<Record<string, never>> | Promise<{ stdout: string; stderr: string; }> {
runClient(args: string[], stdio?: 'ignore', options?: ContainerRunClientOptions): Promise<Record<string, never>>;
runClient(args: string[], stdio: Log, options?: ContainerRunClientOptions): Promise<Record<string, never>>;
runClient(args: string[], stdio: 'pipe', options?: ContainerRunClientOptions): Promise<{ stdout: string; stderr: string; }>;
runClient(args: string[], stdio: 'stream', options?: ContainerRunClientOptions): ReadableProcess;
runClient(args: string[], stdio?: unknown, options?: ContainerRunClientOptions): unknown {
return Promise.resolve({ stdout: '', stderr: '' });
}
}
11 changes: 9 additions & 2 deletions pkg/rancher-desktop/utils/logging.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,12 @@ export class Log {

protected realStream: fs.WriteStream;

/**
* Reopen the logs; this is necessary after a factory reset because the files
* would have been deleted from under us (so reopening ensures any new logs
* are readable).
* @note This is only used during E2E tests where we do a factory reset.
*/
protected reopen(mode = 'w') {
if (process.env.RD_TEST === 'e2e') {
// If we're running E2E tests, we may need to create the log directory.
Expand Down Expand Up @@ -208,8 +214,9 @@ export function clearLoggingDirectory(): void {
export function reopenLogs() {
for (const log of logs.values()) {
log['reopen']('a');
// Trigger making the stream
((_: any) => {})(log.fdStream);
// Trigger making the stream (by passing it to `Array.of()` and ignoring the
// result).
Array.of(log.fdStream);
}
}

Expand Down

0 comments on commit b835a88

Please sign in to comment.