diff --git a/packages/manager/.changeset/pr-10581-tests-1718308219716.md b/packages/manager/.changeset/pr-10581-tests-1718308219716.md new file mode 100644 index 00000000000..96c0f6d70db --- /dev/null +++ b/packages/manager/.changeset/pr-10581-tests-1718308219716.md @@ -0,0 +1,5 @@ +--- +"@linode/manager": Tests +--- + +Fix Linode/Firewall related E2E test flake ([#10581](https://github.com/linode/manager/pull/10581)) diff --git a/packages/manager/cypress/e2e/core/linodes/clone-linode.spec.ts b/packages/manager/cypress/e2e/core/linodes/clone-linode.spec.ts index 5a664581264..29273aab7f3 100644 --- a/packages/manager/cypress/e2e/core/linodes/clone-linode.spec.ts +++ b/packages/manager/cypress/e2e/core/linodes/clone-linode.spec.ts @@ -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(() => { @@ -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'); @@ -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 } ); }); }); diff --git a/packages/manager/cypress/e2e/core/linodes/linode-config.spec.ts b/packages/manager/cypress/e2e/core/linodes/linode-config.spec.ts index 38f4ceea087..e95ca4252d7 100644 --- a/packages/manager/cypress/e2e/core/linodes/linode-config.spec.ts +++ b/packages/manager/cypress/e2e/core/linodes/linode-config.spec.ts @@ -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' } + ), ]); }; diff --git a/packages/manager/cypress/e2e/core/linodes/rescue-linode.spec.ts b/packages/manager/cypress/e2e/core/linodes/rescue-linode.spec.ts index ee9a741e274..533eac2535f 100644 --- a/packages/manager/cypress/e2e/core/linodes/rescue-linode.spec.ts +++ b/packages/manager/cypress/e2e/core/linodes/rescue-linode.spec.ts @@ -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'); + }); }); /* diff --git a/packages/manager/cypress/e2e/core/linodes/resize-linode.spec.ts b/packages/manager/cypress/e2e/core/linodes/resize-linode.spec.ts index 8dc827d6296..0d003ddd864 100644 --- a/packages/manager/cypress/e2e/core/linodes/resize-linode.spec.ts +++ b/packages/manager/cypress/e2e/core/linodes/resize-linode.spec.ts @@ -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 }); @@ -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 }); @@ -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 @@ -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