Skip to content

Commit

Permalink
test: Resolve Cypress test flake for Linode config edit test (#9781)
Browse files Browse the repository at this point in the history
* Add util to poll each of a Linode's disks for a desired status

* Wait for Linode disks before attempting to edit config

* Added changeset: Improve Linode config edit test stability
  • Loading branch information
jdamore-linode authored Oct 16, 2023
1 parent 49f467d commit cdc51b6
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 6 deletions.
5 changes: 5 additions & 0 deletions packages/manager/.changeset/pr-9781-tests-1697144294347.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@linode/manager": Tests
---

Improve Linode config edit test stability ([#9781](https://github.com/linode/manager/pull/9781))
16 changes: 14 additions & 2 deletions packages/manager/cypress/support/util/linode-utils.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { createLinode, getLinodeConfigs } from '@linode/api-v4';
import { createLinode, Devices, getLinodeConfigs } from '@linode/api-v4';
import { createLinodeRequestFactory } from '@src/factories';
import { SimpleBackoffMethod } from 'support/util/backoff';
import { pollLinodeStatus } from 'support/util/polling';
import { pollLinodeStatus, pollLinodeDiskStatuses } from 'support/util/polling';
import { randomLabel } from 'support/util/random';
import { chooseRegion } from 'support/util/regions';

Expand Down Expand Up @@ -58,6 +58,18 @@ export const createLinodeAndGetConfig = async ({
})
));

// If we don't wait for the Linode to boot, we wait for the disks to be ready.
// Wait 7.5 seconds, then poll the Linode disks every 5 seconds until they are ready.
!waitForLinodeToBeRunning &&
(await pollLinodeDiskStatuses(
linode.id,
'ready',
new SimpleBackoffMethod(5000, {
initialDelay: 7500,
maxAttempts: 25,
})
));

// Throw if Linode has no config.
if (!configs[0] || !linode.id) {
throw new Error('Created Linode does not have any config');
Expand Down
43 changes: 39 additions & 4 deletions packages/manager/cypress/support/util/polling.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,20 @@
* @file Utilities for polling APIs and other resources.
*/

import {
import type {
Disk,
ImageStatus,
LinodeStatus,
VolumeStatus,
} from '@linode/api-v4';

import { pageSize } from 'support/constants/api';
import {
getImage,
getLinode,
getLinodeDisk,
VolumeStatus,
getVolume,
getLinodeDisks,
} from '@linode/api-v4';

import {
Expand All @@ -18,9 +24,12 @@ import {
FibonacciBackoffMethod,
attemptWithBackoff,
} from './backoff';
import { depaginate } from './paginate';

// / Describes a backoff configuration for a poll. This may be a partial BackoffOptions object,
// / an instance of a BackoffMethod implementation, or undefined.
/**
* Describes a backoff configuration for a poll. This may be a partial BackoffOptions object,
* an instance of a BackoffMethod implementation, or undefined.
*/
export type PollBackoffConfiguration =
| BackoffMethod
| Partial<BackoffOptions>
Expand Down Expand Up @@ -118,6 +127,32 @@ export const pollLinodeStatus = async (
return poll(getLinodeStatus, checkLinodeStatus, backoffOptions, label);
};

/**
* Polls the status of a Linode's disks until all of them are in the desired state.
*
* @param linodeId - ID of Linode containing the disks to poll.
* @param desiredStatus - Desired status of the disks that are being polled.
* @param backoffMethod - Backoff method implementation to manage re-attempts.
* @param label - Optional label to assign to poll for logging and troubleshooting.
*
* @returns A Promise that resolves to an array of disks or rejects on timeout.
*/
export const pollLinodeDiskStatuses = async (
linodeId: number,
desiredStatus: string,
backoffOptions: PollBackoffConfiguration = undefined,
label: string | undefined = undefined
) => {
const getDisks = async () =>
depaginate((page) =>
getLinodeDisks(linodeId, { page, page_size: pageSize })
);
const checkDisksStatus = (disks: Disk[]): boolean =>
disks.every((disk: Disk) => disk.status === desiredStatus);

return poll(getDisks, checkDisksStatus, backoffOptions, label);
};

/**
* Polls the size of a Linode disk until it is the given size.
*
Expand Down

0 comments on commit cdc51b6

Please sign in to comment.