Skip to content
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

test: E2E test case for the creation of the podman machine with user mode enabled #8528

Open
wants to merge 18 commits into
base: main
Choose a base branch
from

Conversation

danivilla9
Copy link
Contributor

What does this PR do?

This PR extends the E2E test suite by adding the test case of creating a rootfull/rootless Podman machine with user mode networking enabled

What issues does this PR fix or reference?

#4666

How to test this PR?

Run the e2e tests with yarn test:e2e

Copy link
Member

@ScrewTSW ScrewTSW left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, just a comment on timeout

tests/playwright/src/utility/operations.ts Outdated Show resolved Hide resolved
@danivilla9 danivilla9 force-pushed the 4666-e2e-create-podman-machine-windows branch from 37cec22 to d3bc498 Compare August 29, 2024 14:55
Copy link
Contributor

@cbr7 cbr7 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Left some comments.

@danivilla9 danivilla9 force-pushed the 4666-e2e-create-podman-machine-windows branch from d3bc498 to ea31515 Compare September 2, 2024 14:38
@danivilla9 danivilla9 marked this pull request as ready for review September 3, 2024 07:15
@danivilla9 danivilla9 requested review from benoitf and a team as code owners September 3, 2024 07:15
@danivilla9 danivilla9 requested review from cdrage, feloy and deboer-tim and removed request for a team September 3, 2024 07:15
await pdRunner.close();
});

test.describe.serial('Rootless Podman machine Verification', () => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a need for this file in testing the user mode machine?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, it's not needed. I updated it because it prompted an error when testing it on GH Actions. If you have a different version you can substitute it completely.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm still working on that file and it's not on containers main yet, just my branch where I'm testing it, so you don't have to update it in your PR.

async handleConnectionDialog(machineName: string, setAsDefault: boolean): Promise<void> {
const connectionDialog = this.page.getByRole('dialog', { name: 'Podman' });
const dialogMessage = connectionDialog.getByLabel('Dialog Message');
if ((await connectionDialog.isVisible()) && (await dialogMessage.isVisible())) {
Copy link
Contributor

@xbabalov xbabalov Sep 3, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was checking the regex of dialog message so I could be sure the connection dialog was regarding specifically the newly created machine, but if we don't want to check that we don't need to check the visibility of the dialog message if we know the dialog is already there.

} else {
console.log(`Podman machine [${machineVisibleName}] not present, skipping deletion.`);
}
}

export async function handleResetDefaultConnectionDialog(page: Page): Promise<void> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function is defined but never used

@danivilla9 danivilla9 requested a review from cbr7 September 4, 2024 06:54
Comment on lines 65 to 68
isRootful: boolean = true,
enableUserNet: boolean = false,
startNow: boolean = true,
setAsDefault: boolean = true,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please refactor this to use object descructuring, these are too many optional params not to be descructured.

Comment on lines 100 to 111
async isEnabled(checkbox: Locator): Promise<boolean> {
await playExpect(checkbox).toBeVisible();
const upperElement = checkbox.locator('..').locator('..');
const clickableCheckbox = upperElement.getByText('Enabled');
return await clickableCheckbox.isVisible();
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why do you not just check if the checkbox isChecked()?

Comment on lines +107 to +127
async switchCheckbox(checkbox: Locator): Promise<void> {
await playExpect(checkbox).toBeVisible();
const upperElement = checkbox.locator('..').locator('..');

const wasEnabled = await this.isEnabled(checkbox);
let checkText;
if (wasEnabled) {
checkText = 'Enabled';
} else {
checkText = 'Disabled';
}

const clickableCheckbox = upperElement.getByText(checkText);
await clickableCheckbox.click();
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above, the checkbox should be checkable for the isChecked() state.

Comment on lines +125 to +138
if (await connectionDialog.isVisible()) {
let handleButtonName = 'Yes';
if (!setAsDefault) {
handleButtonName = 'Ignore';
}
const handleButton = connectionDialog.getByRole('button', { name: handleButtonName });
await handleButton.click();
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not the right way to check this, the method isVisible() always returns immediately, it has no innate waiter, as such it can return false just as easily as true, simply because of system lag, this is very flaky behavior.

Comment on lines +92 to +101
await this.page.waitForTimeout(2_000); //wait for dialog to appear, in the needed cases
await this.handleConnectionDialog(setAsDefault);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not the best approach, you should be waiting until the element that you need is available, I would say that in this case you should use await playExpect(setAsDefault).toBeVisible() instead of waitForTimeout(), which could very well introduce flakyness.

By waiting on the specific element it also allows the implementation of handleConnectionDialog() method to be refactored, as pointed out below.

Comment on lines +73 to +91
if (isRootful !== (await this.isEnabled(this.rootPriviledgesCheckbox))) {
await this.switchCheckbox(this.rootPriviledgesCheckbox);
}

if (enableUserNet !== (await this.isEnabled(this.userModeNetworkingCheckbox))) {
await this.switchCheckbox(this.userModeNetworkingCheckbox);
}

if (startNow !== (await this.isEnabled(this.startNowCheckbox))) {
await this.switchCheckbox(this.startNowCheckbox);
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These can be refactor in order for the if statements to not be required, there should be some method named ensureCheckboxState() that accepts the checkbox locator and the desired state of the checkbox which checks the initial state and switches the state in case it does not match the desired state.

@@ -0,0 +1,134 @@
/**********************************************************************
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

File should be added to index.ts file to be exported.


test.afterAll(async () => {
await deletePodmanMachine(page, MACHINE_VISIBLE_NAME);
await pdRunner.close();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the close() method call should always be in a finally block, in order to ensure that it's executed even if some exception is thrown in the deletePodmanMachine() method.

Comment on lines 67 to 68
const connectionStatusLabel = await machineBox.resourceElementConnectionStatus.textContent();
playExpect(connectionStatusLabel === 'RUNNING').toBeTruthy();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
const connectionStatusLabel = await machineBox.resourceElementConnectionStatus.textContent();
playExpect(connectionStatusLabel === 'RUNNING').toBeTruthy();
await playExpect(await machineBox.resourceElementConnectionStatus).toContain('RUNNING');

pdRunner = new PodmanDesktopRunner();
page = await pdRunner.start();
pdRunner.setVideoAndTraceName('podman-machine-user-mode');
process.env.KEEP_TRACES_ON_PASS = 'true';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are we setting this env var here?

Comment on lines +65 to +53
const connectionStatusLabel = await machineBox.resourceElementConnectionStatus.textContent();
playExpect(connectionStatusLabel === 'RUNNING').toBeTruthy();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
const connectionStatusLabel = await machineBox.resourceElementConnectionStatus.textContent();
playExpect(connectionStatusLabel === 'RUNNING').toBeTruthy();
await playExpect(await machineBox.resourceElementConnectionStatus).toContain('RUNNING');

Comment on lines +81 to +73
const connectionStatusLabel = await machineBox.resourceElementConnectionStatus.textContent();
playExpect(connectionStatusLabel === 'RUNNING').toBeTruthy();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
const connectionStatusLabel = await machineBox.resourceElementConnectionStatus.textContent();
playExpect(connectionStatusLabel === 'RUNNING').toBeTruthy();
await playExpect(await machineBox.resourceElementConnectionStatus).toContain('RUNNING');

Comment on lines +215 to +221
export function checkForFailedTest(result: TaskResult, runner: PodmanDesktopRunner): void {
if (result.errors && result.errors.length > 0) runner.setTestPassed(false);
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is this method used for?

@@ -137,7 +137,7 @@ export async function deletePod(page: Page, name: string): Promise<void> {
async () => {
return !!(await pods.getPodRowByName(name));
},
{ timeout: 20000 },
{ timeout: 20_000 },
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are all these timeout refactorings required, what is the point of them?

Copy link
Contributor

@cbr7 cbr7 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Left some comments in the PR.

xbabalov and others added 18 commits September 5, 2024 12:10
Signed-off-by: Tamara Babalova <tbabalov@redhat.com>
Signed-off-by: Tamara Babalova <tbabalov@redhat.com>
Signed-off-by: Tamara Babalova <tbabalov@redhat.com>
Signed-off-by: Tamara Babalova <tbabalov@redhat.com>
Signed-off-by: Tamara Babalova <tbabalov@redhat.com>
Signed-off-by: Tamara Babalova <tbabalov@redhat.com>
Signed-off-by: Tamara Babalova <tbabalov@redhat.com>
Signed-off-by: Tamara Babalova <tbabalov@redhat.com>
Signed-off-by: xbabalov <t.babalova.17@gmail.com>
Signed-off-by: xbabalov <t.babalova.17@gmail.com>
Signed-off-by: Daniel Villanueva <davillan@redhat.com>
Signed-off-by: Daniel Villanueva <davillan@redhat.com>
Signed-off-by: Daniel Villanueva <davillan@redhat.com>
Signed-off-by: Daniel Villanueva <davillan@redhat.com>
Signed-off-by: Daniel Villanueva <davillan@redhat.com>
Signed-off-by: Daniel Villanueva <davillan@redhat.com>
Signed-off-by: Daniel Villanueva <davillan@redhat.com>
Signed-off-by: Daniel Villanueva <davillan@redhat.com>
@danivilla9 danivilla9 force-pushed the 4666-e2e-create-podman-machine-windows branch from d5717a1 to afd4492 Compare September 5, 2024 11:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants