Skip to content

Commit

Permalink
test: Attempt to fix DBaaS unit test flake (#11332)
Browse files Browse the repository at this point in the history
* fix test flakes

* fix test flakes

* add changeset

---------

Co-authored-by: Banks Nussman <banks@nussman.us>
  • Loading branch information
bnussman-akamai and bnussman authored Nov 26, 2024
1 parent afa6da9 commit 890e90e
Show file tree
Hide file tree
Showing 4 changed files with 153 additions and 154 deletions.
5 changes: 5 additions & 0 deletions packages/manager/.changeset/pr-11332-tests-1732639325137.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@linode/manager": Tests
---

Fix DBaaS unit test flake ([#11332](https://github.com/linode/manager/pull/11332))
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { waitFor } from '@testing-library/react';
import * as React from 'react';

import {
Expand All @@ -18,6 +17,7 @@ describe('Database Backups', () => {
const mockDatabase = databaseFactory.build({
platform: 'rdbms-legacy',
});

const backups = databaseBackupFactory.buildList(7);

server.use(
Expand All @@ -32,34 +32,19 @@ describe('Database Backups', () => {
})
);

const { findAllByText, getByText, queryByText } = renderWithTheme(
<DatabaseBackups />
);
const { findByText, getAllByRole } = renderWithTheme(<DatabaseBackups />);

// Wait for loading to disappear
await waitFor(() =>
expect(queryByText(/loading/i)).not.toBeInTheDocument()
);
for (const backup of backups) {
const expectedDate = formatDate(backup.created, { timezone: 'utc' });

await waitFor(
async () => {
const renderedBackups = await findAllByText((content) => {
return /\d{4}-\d{2}-\d{2}/.test(content);
});
expect(renderedBackups).toHaveLength(backups.length);
},
{ timeout: 5000 }
);
// eslint-disable-next-line no-await-in-loop
const backupItem = await findByText(expectedDate);

await waitFor(
() => {
backups.forEach((backup) => {
const formattedDate = formatDate(backup.created, { timezone: 'utc' });
expect(getByText(formattedDate)).toBeInTheDocument();
});
},
{ timeout: 5000 }
);
expect(backupItem).toBeVisible();
}

// Verify there is a table row for each backup (and a row for the table header)
expect(getAllByRole('row')).toHaveLength(backups.length + 1);
});

it('should render an empty state if there are no backups', async () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -128,132 +128,142 @@ export const DatabaseBackups = (props: Props) => {
setSelectedTime(null);
};

return isDefaultDatabase ? (
<Paper style={{ marginTop: 16 }}>
<Typography variant="h2">Summary</Typography>
<StyledTypography>
Databases are automatically backed-up with full daily backups for the
past 14 days, and binary logs recorded continuously. Full backups are
version-specific binary backups, which when combined with binary
logs allow for consistent recovery to a specific point in time (PITR).
</StyledTypography>
<Divider spacingBottom={25} spacingTop={25} />
<Typography variant="h2">Restore a Backup</Typography>
<StyledTypography>
{isDatabasesV2GA ? (
<span>
The newest full backup plus incremental is selected by default. Or,
select any date and time within the last 14 days you want to create
a fork from.
</span>
) : (
<span>
Select a date and time within the last 14 days you want to create a
fork from.
</span>
if (isDefaultDatabase) {
return (
<Paper style={{ marginTop: 16 }}>
<Typography variant="h2">Summary</Typography>
<StyledTypography>
Databases are automatically backed-up with full daily backups for the
past 14 days, and binary logs recorded continuously. Full backups are
version-specific binary backups, which when combined with binary
logs allow for consistent recovery to a specific point in time (PITR).
</StyledTypography>
<Divider spacingBottom={25} spacingTop={25} />
<Typography variant="h2">Restore a Backup</Typography>
<StyledTypography>
{isDatabasesV2GA ? (
<span>
The newest full backup plus incremental is selected by default.
Or, select any date and time within the last 14 days you want to
create a fork from.
</span>
) : (
<span>
Select a date and time within the last 14 days you want to create
a fork from.
</span>
)}
</StyledTypography>
{unableToRestoreCopy && (
<Notice spacingTop={16} text={unableToRestoreCopy} variant="info" />
)}
</StyledTypography>
{unableToRestoreCopy && (
<Notice spacingTop={16} text={unableToRestoreCopy} variant="info" />
)}
{isDatabasesV2GA && (
<RadioGroup
aria-label="type"
name="type"
onChange={handleOnVersionOptionChange}
value={versionOption}
>
<FormControlLabel
control={<Radio />}
data-qa-dbaas-radio="Newest"
disabled={disabled}
label="Newest full backup plus incremental"
value="newest"
/>
<FormControlLabel
control={<Radio />}
data-qa-dbaas-radio="DateTime"
disabled={disabled}
label="Specific date & time"
value="dateTime"
/>
</RadioGroup>
)}
<Grid container justifyContent="flex-start" mt={2}>
<Grid item lg={3} md={4} xs={12}>
<Typography variant="h3">Date</Typography>
<LocalizationProvider dateAdapter={AdapterLuxon}>
<StyledDateCalendar
shouldDisableDate={(date) =>
isDateOutsideBackup(date, oldestBackup?.startOf('day'))
}
disabled={disabled || versionOption === 'newest'}
onChange={handleDateChange}
value={selectedDate}
{isDatabasesV2GA && (
<RadioGroup
aria-label="type"
name="type"
onChange={handleOnVersionOptionChange}
value={versionOption}
>
<FormControlLabel
control={<Radio />}
data-qa-dbaas-radio="Newest"
disabled={disabled}
label="Newest full backup plus incremental"
value="newest"
/>
</LocalizationProvider>
<FormControlLabel
control={<Radio />}
data-qa-dbaas-radio="DateTime"
disabled={disabled}
label="Specific date & time"
value="dateTime"
/>
</RadioGroup>
)}
<Grid container justifyContent="flex-start" mt={2}>
<Grid item lg={3} md={4} xs={12}>
<Typography variant="h3">Date</Typography>
<LocalizationProvider dateAdapter={AdapterLuxon}>
<StyledDateCalendar
shouldDisableDate={(date) =>
isDateOutsideBackup(date, oldestBackup?.startOf('day'))
}
disabled={disabled || versionOption === 'newest'}
onChange={handleDateChange}
value={selectedDate}
/>
</LocalizationProvider>
</Grid>
<Grid item lg={3} md={4} xs={12}>
<Typography variant="h3">Time (UTC)</Typography>
<FormControl style={{ marginTop: 0 }}>
{/* TODO: Replace Time Select to the own custom date-time picker component when it's ready */}
<Autocomplete
getOptionDisabled={(option) =>
isTimeOutsideBackup(
option.value,
selectedDate!,
oldestBackup!
)
}
isOptionEqualToValue={(option, value) =>
option.value === value.value
}
renderOption={(props, option) => {
const { key, ...rest } = props;
return (
<li {...rest} key={key}>
{option.label}
</li>
);
}}
textFieldProps={{
dataAttrs: {
'data-qa-time-select': true,
},
}}
autoComplete={false}
className={classes.timeAutocomplete}
disabled={
disabled || !selectedDate || versionOption === 'newest'
}
label=""
onChange={(_, newTime) => setSelectedTime(newTime)}
options={TIME_OPTIONS}
placeholder="Choose a time"
value={selectedTime}
/>
</FormControl>
</Grid>
</Grid>
<Grid item lg={3} md={4} xs={12}>
<Typography variant="h3">Time (UTC)</Typography>
<FormControl style={{ marginTop: 0 }}>
{/* TODO: Replace Time Select to the own custom date-time picker component when it's ready */}
<Autocomplete
getOptionDisabled={(option) =>
isTimeOutsideBackup(option.value, selectedDate!, oldestBackup!)
}
isOptionEqualToValue={(option, value) =>
option.value === value.value
<Grid item xs={12}>
<Box display="flex" justifyContent="flex-end">
<Button
disabled={
versionOption === 'dateTime' && (!selectedDate || !selectedTime)
}
renderOption={(props, option) => {
const { key, ...rest } = props;
return (
<li {...rest} key={key}>
{option.label}
</li>
);
}}
textFieldProps={{
dataAttrs: {
'data-qa-time-select': true,
},
}}
autoComplete={false}
className={classes.timeAutocomplete}
disabled={disabled || !selectedDate || versionOption === 'newest'}
label=""
onChange={(_, newTime) => setSelectedTime(newTime)}
options={TIME_OPTIONS}
placeholder="Choose a time"
value={selectedTime}
/>
</FormControl>
buttonType="primary"
data-qa-settings-button="restore"
onClick={onRestoreDatabase}
>
Restore
</Button>
</Box>
</Grid>
</Grid>
<Grid item xs={12}>
<Box display="flex" justifyContent="flex-end">
<Button
disabled={
versionOption === 'dateTime' && (!selectedDate || !selectedTime)
}
buttonType="primary"
data-qa-settings-button="restore"
onClick={onRestoreDatabase}
>
Restore
</Button>
</Box>
</Grid>
{database ? (
<DatabaseBackupsDialog
database={database}
onClose={() => setIsRestoreDialogOpen(false)}
open={isRestoreDialogOpen}
selectedDate={selectedDate}
selectedTime={selectedTime?.value}
/>
) : null}
</Paper>
) : (
{database && (
<DatabaseBackupsDialog
database={database}
onClose={() => setIsRestoreDialogOpen(false)}
open={isRestoreDialogOpen}
selectedDate={selectedDate}
selectedTime={selectedTime?.value}
/>
)}
</Paper>
);
}

return (
<DatabaseBackupsLegacy
database={database}
databaseError={databaseError}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -395,16 +395,15 @@ describe('database resize', () => {
},
};

const { getByTestId } = renderWithTheme(
const { findByTestId } = renderWithTheme(
<DatabaseResize database={mockDatabase} />,
{ flags }
);
expect(getByTestId(loadingTestId)).toBeInTheDocument();
await waitForElementToBeRemoved(getByTestId(loadingTestId));
expect(getByTestId('database-nodes')).toBeDefined();
expect(getByTestId('database-node-1')).toBeDefined();
expect(getByTestId('database-node-2')).toBeDefined();
expect(getByTestId('database-node-3')).toBeDefined();

expect(await findByTestId('database-nodes')).toBeDefined();
expect(await findByTestId('database-node-1')).toBeDefined();
expect(await findByTestId('database-node-2')).toBeDefined();
expect(await findByTestId('database-node-3')).toBeDefined();
});

it('should disable lower node selections', async () => {
Expand Down

0 comments on commit 890e90e

Please sign in to comment.