Skip to content

Commit 890e90e

Browse files
test: Attempt to fix DBaaS unit test flake (#11332)
* fix test flakes * fix test flakes * add changeset --------- Co-authored-by: Banks Nussman <banks@nussman.us>
1 parent afa6da9 commit 890e90e

File tree

4 files changed

+153
-154
lines changed

4 files changed

+153
-154
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@linode/manager": Tests
3+
---
4+
5+
Fix DBaaS unit test flake ([#11332](https://github.com/linode/manager/pull/11332))

packages/manager/src/features/Databases/DatabaseDetail/DatabaseBackups/DatabaseBackups.test.tsx

Lines changed: 11 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import { waitFor } from '@testing-library/react';
21
import * as React from 'react';
32

43
import {
@@ -18,6 +17,7 @@ describe('Database Backups', () => {
1817
const mockDatabase = databaseFactory.build({
1918
platform: 'rdbms-legacy',
2019
});
20+
2121
const backups = databaseBackupFactory.buildList(7);
2222

2323
server.use(
@@ -32,34 +32,19 @@ describe('Database Backups', () => {
3232
})
3333
);
3434

35-
const { findAllByText, getByText, queryByText } = renderWithTheme(
36-
<DatabaseBackups />
37-
);
35+
const { findByText, getAllByRole } = renderWithTheme(<DatabaseBackups />);
3836

39-
// Wait for loading to disappear
40-
await waitFor(() =>
41-
expect(queryByText(/loading/i)).not.toBeInTheDocument()
42-
);
37+
for (const backup of backups) {
38+
const expectedDate = formatDate(backup.created, { timezone: 'utc' });
4339

44-
await waitFor(
45-
async () => {
46-
const renderedBackups = await findAllByText((content) => {
47-
return /\d{4}-\d{2}-\d{2}/.test(content);
48-
});
49-
expect(renderedBackups).toHaveLength(backups.length);
50-
},
51-
{ timeout: 5000 }
52-
);
40+
// eslint-disable-next-line no-await-in-loop
41+
const backupItem = await findByText(expectedDate);
5342

54-
await waitFor(
55-
() => {
56-
backups.forEach((backup) => {
57-
const formattedDate = formatDate(backup.created, { timezone: 'utc' });
58-
expect(getByText(formattedDate)).toBeInTheDocument();
59-
});
60-
},
61-
{ timeout: 5000 }
62-
);
43+
expect(backupItem).toBeVisible();
44+
}
45+
46+
// Verify there is a table row for each backup (and a row for the table header)
47+
expect(getAllByRole('row')).toHaveLength(backups.length + 1);
6348
});
6449

6550
it('should render an empty state if there are no backups', async () => {

packages/manager/src/features/Databases/DatabaseDetail/DatabaseBackups/DatabaseBackups.tsx

Lines changed: 131 additions & 121 deletions
Original file line numberDiff line numberDiff line change
@@ -128,132 +128,142 @@ export const DatabaseBackups = (props: Props) => {
128128
setSelectedTime(null);
129129
};
130130

131-
return isDefaultDatabase ? (
132-
<Paper style={{ marginTop: 16 }}>
133-
<Typography variant="h2">Summary</Typography>
134-
<StyledTypography>
135-
Databases are automatically backed-up with full daily backups for the
136-
past 14 days, and binary logs recorded continuously. Full backups are
137-
version-specific binary backups, which when combined with binary
138-
logs allow for consistent recovery to a specific point in time (PITR).
139-
</StyledTypography>
140-
<Divider spacingBottom={25} spacingTop={25} />
141-
<Typography variant="h2">Restore a Backup</Typography>
142-
<StyledTypography>
143-
{isDatabasesV2GA ? (
144-
<span>
145-
The newest full backup plus incremental is selected by default. Or,
146-
select any date and time within the last 14 days you want to create
147-
a fork from.
148-
</span>
149-
) : (
150-
<span>
151-
Select a date and time within the last 14 days you want to create a
152-
fork from.
153-
</span>
131+
if (isDefaultDatabase) {
132+
return (
133+
<Paper style={{ marginTop: 16 }}>
134+
<Typography variant="h2">Summary</Typography>
135+
<StyledTypography>
136+
Databases are automatically backed-up with full daily backups for the
137+
past 14 days, and binary logs recorded continuously. Full backups are
138+
version-specific binary backups, which when combined with binary
139+
logs allow for consistent recovery to a specific point in time (PITR).
140+
</StyledTypography>
141+
<Divider spacingBottom={25} spacingTop={25} />
142+
<Typography variant="h2">Restore a Backup</Typography>
143+
<StyledTypography>
144+
{isDatabasesV2GA ? (
145+
<span>
146+
The newest full backup plus incremental is selected by default.
147+
Or, select any date and time within the last 14 days you want to
148+
create a fork from.
149+
</span>
150+
) : (
151+
<span>
152+
Select a date and time within the last 14 days you want to create
153+
a fork from.
154+
</span>
155+
)}
156+
</StyledTypography>
157+
{unableToRestoreCopy && (
158+
<Notice spacingTop={16} text={unableToRestoreCopy} variant="info" />
154159
)}
155-
</StyledTypography>
156-
{unableToRestoreCopy && (
157-
<Notice spacingTop={16} text={unableToRestoreCopy} variant="info" />
158-
)}
159-
{isDatabasesV2GA && (
160-
<RadioGroup
161-
aria-label="type"
162-
name="type"
163-
onChange={handleOnVersionOptionChange}
164-
value={versionOption}
165-
>
166-
<FormControlLabel
167-
control={<Radio />}
168-
data-qa-dbaas-radio="Newest"
169-
disabled={disabled}
170-
label="Newest full backup plus incremental"
171-
value="newest"
172-
/>
173-
<FormControlLabel
174-
control={<Radio />}
175-
data-qa-dbaas-radio="DateTime"
176-
disabled={disabled}
177-
label="Specific date & time"
178-
value="dateTime"
179-
/>
180-
</RadioGroup>
181-
)}
182-
<Grid container justifyContent="flex-start" mt={2}>
183-
<Grid item lg={3} md={4} xs={12}>
184-
<Typography variant="h3">Date</Typography>
185-
<LocalizationProvider dateAdapter={AdapterLuxon}>
186-
<StyledDateCalendar
187-
shouldDisableDate={(date) =>
188-
isDateOutsideBackup(date, oldestBackup?.startOf('day'))
189-
}
190-
disabled={disabled || versionOption === 'newest'}
191-
onChange={handleDateChange}
192-
value={selectedDate}
160+
{isDatabasesV2GA && (
161+
<RadioGroup
162+
aria-label="type"
163+
name="type"
164+
onChange={handleOnVersionOptionChange}
165+
value={versionOption}
166+
>
167+
<FormControlLabel
168+
control={<Radio />}
169+
data-qa-dbaas-radio="Newest"
170+
disabled={disabled}
171+
label="Newest full backup plus incremental"
172+
value="newest"
193173
/>
194-
</LocalizationProvider>
174+
<FormControlLabel
175+
control={<Radio />}
176+
data-qa-dbaas-radio="DateTime"
177+
disabled={disabled}
178+
label="Specific date & time"
179+
value="dateTime"
180+
/>
181+
</RadioGroup>
182+
)}
183+
<Grid container justifyContent="flex-start" mt={2}>
184+
<Grid item lg={3} md={4} xs={12}>
185+
<Typography variant="h3">Date</Typography>
186+
<LocalizationProvider dateAdapter={AdapterLuxon}>
187+
<StyledDateCalendar
188+
shouldDisableDate={(date) =>
189+
isDateOutsideBackup(date, oldestBackup?.startOf('day'))
190+
}
191+
disabled={disabled || versionOption === 'newest'}
192+
onChange={handleDateChange}
193+
value={selectedDate}
194+
/>
195+
</LocalizationProvider>
196+
</Grid>
197+
<Grid item lg={3} md={4} xs={12}>
198+
<Typography variant="h3">Time (UTC)</Typography>
199+
<FormControl style={{ marginTop: 0 }}>
200+
{/* TODO: Replace Time Select to the own custom date-time picker component when it's ready */}
201+
<Autocomplete
202+
getOptionDisabled={(option) =>
203+
isTimeOutsideBackup(
204+
option.value,
205+
selectedDate!,
206+
oldestBackup!
207+
)
208+
}
209+
isOptionEqualToValue={(option, value) =>
210+
option.value === value.value
211+
}
212+
renderOption={(props, option) => {
213+
const { key, ...rest } = props;
214+
return (
215+
<li {...rest} key={key}>
216+
{option.label}
217+
</li>
218+
);
219+
}}
220+
textFieldProps={{
221+
dataAttrs: {
222+
'data-qa-time-select': true,
223+
},
224+
}}
225+
autoComplete={false}
226+
className={classes.timeAutocomplete}
227+
disabled={
228+
disabled || !selectedDate || versionOption === 'newest'
229+
}
230+
label=""
231+
onChange={(_, newTime) => setSelectedTime(newTime)}
232+
options={TIME_OPTIONS}
233+
placeholder="Choose a time"
234+
value={selectedTime}
235+
/>
236+
</FormControl>
237+
</Grid>
195238
</Grid>
196-
<Grid item lg={3} md={4} xs={12}>
197-
<Typography variant="h3">Time (UTC)</Typography>
198-
<FormControl style={{ marginTop: 0 }}>
199-
{/* TODO: Replace Time Select to the own custom date-time picker component when it's ready */}
200-
<Autocomplete
201-
getOptionDisabled={(option) =>
202-
isTimeOutsideBackup(option.value, selectedDate!, oldestBackup!)
203-
}
204-
isOptionEqualToValue={(option, value) =>
205-
option.value === value.value
239+
<Grid item xs={12}>
240+
<Box display="flex" justifyContent="flex-end">
241+
<Button
242+
disabled={
243+
versionOption === 'dateTime' && (!selectedDate || !selectedTime)
206244
}
207-
renderOption={(props, option) => {
208-
const { key, ...rest } = props;
209-
return (
210-
<li {...rest} key={key}>
211-
{option.label}
212-
</li>
213-
);
214-
}}
215-
textFieldProps={{
216-
dataAttrs: {
217-
'data-qa-time-select': true,
218-
},
219-
}}
220-
autoComplete={false}
221-
className={classes.timeAutocomplete}
222-
disabled={disabled || !selectedDate || versionOption === 'newest'}
223-
label=""
224-
onChange={(_, newTime) => setSelectedTime(newTime)}
225-
options={TIME_OPTIONS}
226-
placeholder="Choose a time"
227-
value={selectedTime}
228-
/>
229-
</FormControl>
245+
buttonType="primary"
246+
data-qa-settings-button="restore"
247+
onClick={onRestoreDatabase}
248+
>
249+
Restore
250+
</Button>
251+
</Box>
230252
</Grid>
231-
</Grid>
232-
<Grid item xs={12}>
233-
<Box display="flex" justifyContent="flex-end">
234-
<Button
235-
disabled={
236-
versionOption === 'dateTime' && (!selectedDate || !selectedTime)
237-
}
238-
buttonType="primary"
239-
data-qa-settings-button="restore"
240-
onClick={onRestoreDatabase}
241-
>
242-
Restore
243-
</Button>
244-
</Box>
245-
</Grid>
246-
{database ? (
247-
<DatabaseBackupsDialog
248-
database={database}
249-
onClose={() => setIsRestoreDialogOpen(false)}
250-
open={isRestoreDialogOpen}
251-
selectedDate={selectedDate}
252-
selectedTime={selectedTime?.value}
253-
/>
254-
) : null}
255-
</Paper>
256-
) : (
253+
{database && (
254+
<DatabaseBackupsDialog
255+
database={database}
256+
onClose={() => setIsRestoreDialogOpen(false)}
257+
open={isRestoreDialogOpen}
258+
selectedDate={selectedDate}
259+
selectedTime={selectedTime?.value}
260+
/>
261+
)}
262+
</Paper>
263+
);
264+
}
265+
266+
return (
257267
<DatabaseBackupsLegacy
258268
database={database}
259269
databaseError={databaseError}

packages/manager/src/features/Databases/DatabaseDetail/DatabaseResize/DatabaseResize.test.tsx

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -395,16 +395,15 @@ describe('database resize', () => {
395395
},
396396
};
397397

398-
const { getByTestId } = renderWithTheme(
398+
const { findByTestId } = renderWithTheme(
399399
<DatabaseResize database={mockDatabase} />,
400400
{ flags }
401401
);
402-
expect(getByTestId(loadingTestId)).toBeInTheDocument();
403-
await waitForElementToBeRemoved(getByTestId(loadingTestId));
404-
expect(getByTestId('database-nodes')).toBeDefined();
405-
expect(getByTestId('database-node-1')).toBeDefined();
406-
expect(getByTestId('database-node-2')).toBeDefined();
407-
expect(getByTestId('database-node-3')).toBeDefined();
402+
403+
expect(await findByTestId('database-nodes')).toBeDefined();
404+
expect(await findByTestId('database-node-1')).toBeDefined();
405+
expect(await findByTestId('database-node-2')).toBeDefined();
406+
expect(await findByTestId('database-node-3')).toBeDefined();
408407
});
409408

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

0 commit comments

Comments
 (0)