b233f75ab7
F1: prune retry-state by elapsed window since lastRestart instead of "not seen this tick", so a container flapping through "starting" keeps its cooldown/max-retries accounting (storm guard no longer defeated). Recovered containers quiet for > window are still cleaned up. F2: list running containers only (All:false) so stopped-unhealthy containers are never revived. F3: each ContainerRestart gets its own context (stop-timeout + buffer), separate from the per-endpoint list context, so a slow/hung restart cannot starve the others or exhaust a single shared deadline. F4: start() is idempotent (no-op when a job is already scheduled); Reload still stops first so it always reschedules. F5: frontend parseBool mirrors Go strconv.ParseBool (case-insensitive 1/t/true; present-but-invalid counts as present & false). F6: tests TestPruneRetries and TestRetryStateSurvivesStartingTick lock in the F1 behavior; added AutoHealRow parse cases. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
61 lines
1.8 KiB
TypeScript
61 lines
1.8 KiB
TypeScript
import { render, screen } from '@testing-library/react';
|
|
|
|
import { AutoHealRow } from './AutoHealRow';
|
|
|
|
function renderRow(labels?: Record<string, string>) {
|
|
return render(
|
|
<table>
|
|
<tbody>
|
|
<AutoHealRow labels={labels} />
|
|
</tbody>
|
|
</table>
|
|
);
|
|
}
|
|
|
|
describe('AutoHealRow', () => {
|
|
it('shows enabled when the primary label is true', () => {
|
|
renderRow({ 'io.portainer.autoheal.enable': 'true' });
|
|
expect(screen.getByText('Enabled')).toBeInTheDocument();
|
|
});
|
|
|
|
it('shows enabled via the community alias', () => {
|
|
renderRow({ autoheal: 'true' });
|
|
expect(screen.getByText('Enabled')).toBeInTheDocument();
|
|
});
|
|
|
|
it.each(['TRUE', 'True', 'T', 't', '1'])(
|
|
'parses the truthy value %s like strconv.ParseBool',
|
|
(value) => {
|
|
renderRow({ 'io.portainer.autoheal.enable': value });
|
|
expect(screen.getByText('Enabled')).toBeInTheDocument();
|
|
}
|
|
);
|
|
|
|
it('treats a present-but-invalid value as opted out', () => {
|
|
renderRow({ 'io.portainer.autoheal.enable': 'yepp' });
|
|
expect(screen.getByText('Disabled (opted out)')).toBeInTheDocument();
|
|
});
|
|
|
|
it('shows opted out when the label is false', () => {
|
|
renderRow({ 'io.portainer.autoheal.enable': 'false' });
|
|
expect(screen.getByText('Disabled (opted out)')).toBeInTheDocument();
|
|
});
|
|
|
|
it('shows the global-scope fallback when no label is set', () => {
|
|
renderRow({});
|
|
expect(
|
|
screen.getByText('Not labeled (follows global scope)')
|
|
).toBeInTheDocument();
|
|
});
|
|
|
|
it('renders stop timeout and retries when present', () => {
|
|
renderRow({
|
|
'io.portainer.autoheal.enable': 'true',
|
|
'io.portainer.autoheal.stop-timeout': '20',
|
|
'io.portainer.autoheal.retries': '5',
|
|
});
|
|
expect(screen.getByText('Stop timeout: 20s')).toBeInTheDocument();
|
|
expect(screen.getByText('Max retries: 5')).toBeInTheDocument();
|
|
});
|
|
});
|