Skip to content

Commit

Permalink
test: Resolve Linode/Firewall E2E flake by using alternative security…
Browse files Browse the repository at this point in the history
… method (#10581)

* Work around Linode/Firewall flake by using alternative security method

* Added changeset: Fix Linode/Firewall related E2E test flake
  • Loading branch information
jdamore-linode authored Jun 17, 2024
1 parent 4ac62db commit ca19099
Show file tree
Hide file tree
Showing 5 changed files with 96 additions and 42 deletions.
5 changes: 5 additions & 0 deletions packages/manager/.changeset/pr-10581-tests-1718308219716.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@linode/manager": Tests
---

Fix Linode/Firewall related E2E test flake ([#10581](https://github.com/linode/manager/pull/10581))
16 changes: 12 additions & 4 deletions packages/manager/cypress/e2e/core/linodes/clone-linode.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ const getLinodeCloneUrl = (linode: Linode): string => {
return `/linodes/create?linodeID=${linode.id}${regionQuery}&type=Clone+Linode${typeQuery}`;
};

/* Timeout after 3 minutes while waiting for clone. */
const CLONE_TIMEOUT = 180_000;

authenticate();
describe('clone linode', () => {
before(() => {
Expand All @@ -48,15 +51,19 @@ describe('clone linode', () => {
const linodePayload = createLinodeRequestFactory.build({
label: randomLabel(),
region: linodeRegion.id,
// Specifying no image allows the Linode to provision and clone faster.
image: undefined,
booted: false,
type: 'g6-nanode-1',
});

const newLinodeLabel = `${linodePayload.label}-clone`;

cy.defer(() => createTestLinode(linodePayload)).then((linode: Linode) => {
// Use `vlan_no_internet` security method.
// This works around an issue where the Linode API responds with a 400
// when attempting to interact with it shortly after booting up when the
// Linode is attached to a Cloud Firewall.
cy.defer(() =>
createTestLinode(linodePayload, { securityMethod: 'vlan_no_internet' })
).then((linode: Linode) => {
const linodeRegion = getRegionById(linodePayload.region!);

interceptCloneLinode(linode.id).as('cloneLinode');
Expand Down Expand Up @@ -101,7 +108,8 @@ describe('clone linode', () => {

ui.toast.assertMessage(`Your Linode ${newLinodeLabel} is being created.`);
ui.toast.assertMessage(
`Linode ${linode.label} successfully cloned to ${newLinodeLabel}.`
`Linode ${linode.label} successfully cloned to ${newLinodeLabel}.`,
{ timeout: CLONE_TIMEOUT }
);
});
});
Expand Down
14 changes: 12 additions & 2 deletions packages/manager/cypress/e2e/core/linodes/linode-config.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -291,10 +291,20 @@ describe('Linode Config management', () => {
*/
it('Clones a config', () => {
// Create clone source and destination Linodes.
// Use `vlan_no_internet` security method.
// This works around an issue where the Linode API responds with a 400
// when attempting to interact with it shortly after booting up when the
// Linode is attached to a Cloud Firewall.
const createCloneTestLinodes = async () => {
return Promise.all([
createTestLinode({ booted: true }, { waitForBoot: true }),
createTestLinode({ booted: true }),
createTestLinode(
{ booted: true },
{ securityMethod: 'vlan_no_internet', waitForBoot: true }
),
createTestLinode(
{ booted: true },
{ securityMethod: 'vlan_no_internet' }
),
]);
};

Expand Down
68 changes: 37 additions & 31 deletions packages/manager/cypress/e2e/core/linodes/rescue-linode.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,44 +43,50 @@ describe('Rescue Linodes', () => {
region: chooseRegion().id,
});

cy.defer(() => createTestLinode(linodePayload), 'creating Linode').then(
(linode: Linode) => {
interceptGetLinodeDetails(linode.id).as('getLinode');
interceptRebootLinodeIntoRescueMode(linode.id).as(
'rebootLinodeRescueMode'
);
// Use `vlan_no_internet` security method.
// This works around an issue where the Linode API responds with a 400
// when attempting to interact with it shortly after booting up when the
// Linode is attached to a Cloud Firewall.
cy.defer(
() =>
createTestLinode(linodePayload, { securityMethod: 'vlan_no_internet' }),
'creating Linode'
).then((linode: Linode) => {
interceptGetLinodeDetails(linode.id).as('getLinode');
interceptRebootLinodeIntoRescueMode(linode.id).as(
'rebootLinodeRescueMode'
);

const rescueUrl = `/linodes/${linode.id}`;
cy.visitWithLogin(rescueUrl);
cy.wait('@getLinode');
const rescueUrl = `/linodes/${linode.id}`;
cy.visitWithLogin(rescueUrl);
cy.wait('@getLinode');

// Wait for Linode to boot.
cy.findByText('RUNNING').should('be.visible');
// Wait for Linode to boot.
cy.findByText('RUNNING').should('be.visible');

// Open rescue dialog using action menu..
ui.actionMenu
.findByTitle(`Action menu for Linode ${linode.label}`)
.should('be.visible')
.click();
// Open rescue dialog using action menu..
ui.actionMenu
.findByTitle(`Action menu for Linode ${linode.label}`)
.should('be.visible')
.click();

ui.actionMenuItem.findByTitle('Rescue').should('be.visible').click();
ui.actionMenuItem.findByTitle('Rescue').should('be.visible').click();

ui.dialog
.findByTitle(`Rescue Linode ${linode.label}`)
.should('be.visible')
.within(() => {
rebootInRescueMode();
});
ui.dialog
.findByTitle(`Rescue Linode ${linode.label}`)
.should('be.visible')
.within(() => {
rebootInRescueMode();
});

// Check intercepted response and make sure UI responded correctly.
cy.wait('@rebootLinodeRescueMode')
.its('response.statusCode')
.should('eq', 200);
// Check intercepted response and make sure UI responded correctly.
cy.wait('@rebootLinodeRescueMode')
.its('response.statusCode')
.should('eq', 200);

ui.toast.assertMessage('Linode rescue started.');
cy.findByText('REBOOTING').should('be.visible');
}
);
ui.toast.assertMessage('Linode rescue started.');
cy.findByText('REBOOTING').should('be.visible');
});
});

/*
Expand Down
35 changes: 30 additions & 5 deletions packages/manager/cypress/e2e/core/linodes/resize-linode.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,13 @@ describe('resize linode', () => {
it('resizes a linode by increasing size: warm migration', () => {
mockGetFeatureFlagClientstream().as('getClientStream');

cy.defer(() => createTestLinode({ booted: true })).then((linode) => {
// Use `vlan_no_internet` security method.
// This works around an issue where the Linode API responds with a 400
// when attempting to interact with it shortly after booting up when the
// Linode is attached to a Cloud Firewall.
cy.defer(() =>
createTestLinode({ booted: true }, { securityMethod: 'vlan_no_internet' })
).then((linode) => {
interceptLinodeResize(linode.id).as('linodeResize');
cy.visitWithLogin(`/linodes/${linode.id}?resize=true`);
cy.findByText('Shared CPU').click({ scrollBehavior: false });
Expand All @@ -35,7 +41,13 @@ describe('resize linode', () => {

it('resizes a linode by increasing size: cold migration', () => {
mockGetFeatureFlagClientstream().as('getClientStream');
cy.defer(() => createTestLinode({ booted: true })).then((linode) => {
// Use `vlan_no_internet` security method.
// This works around an issue where the Linode API responds with a 400
// when attempting to interact with it shortly after booting up when the
// Linode is attached to a Cloud Firewall.
cy.defer(() =>
createTestLinode({ booted: true }, { securityMethod: 'vlan_no_internet' })
).then((linode) => {
interceptLinodeResize(linode.id).as('linodeResize');
cy.visitWithLogin(`/linodes/${linode.id}?resize=true`);
cy.findByText('Shared CPU').click({ scrollBehavior: false });
Expand All @@ -56,7 +68,13 @@ describe('resize linode', () => {

it('resizes a linode by increasing size when offline: cold migration', () => {
mockGetFeatureFlagClientstream().as('getClientStream');
cy.defer(() => createTestLinode({ booted: true })).then((linode) => {
// Use `vlan_no_internet` security method.
// This works around an issue where the Linode API responds with a 400
// when attempting to interact with it shortly after booting up when the
// Linode is attached to a Cloud Firewall.
cy.defer(() =>
createTestLinode({ booted: true }, { securityMethod: 'vlan_no_internet' })
).then((linode) => {
cy.visitWithLogin(`/linodes/${linode.id}`);

// Turn off the linode to resize the disk
Expand Down Expand Up @@ -97,9 +115,16 @@ describe('resize linode', () => {
});
});

it.only('resizes a linode by decreasing size', () => {
it('resizes a linode by decreasing size', () => {
// Use `vlan_no_internet` security method.
// This works around an issue where the Linode API responds with a 400
// when attempting to interact with it shortly after booting up when the
// Linode is attached to a Cloud Firewall.
cy.defer(() =>
createTestLinode({ booted: true, type: 'g6-standard-2' })
createTestLinode(
{ booted: true, type: 'g6-standard-2' },
{ securityMethod: 'vlan_no_internet' }
)
).then((linode) => {
const diskName = 'Debian 11 Disk';
const size = '50000'; // 50 GB
Expand Down

0 comments on commit ca19099

Please sign in to comment.