mirror of
https://github.com/Studio-Saelix/sencho.git
synced 2026-09-04 14:45:41 +00:00
fix: keep fleet prune estimate bytes after a target timeout (#1783)
* fix: keep fleet prune estimate bytes after a target timeout Accumulate successful per-target reclaimable bytes on both the local serial loop and the remote fan-out, mark partial nodes, and surface that state in the Fleet prune card instead of zeroing the whole node. * test: clarify zero-byte partial estimate card case Rename the FleetPruneCard assertion so it matches fold semantics: partial with zero bytes means a successful zero-byte target plus a failure, not an all-failed node. * fix: keep fleet prune estimate resilient on init and partial errors Guard DockerController init so a deleted-node race cannot 500 the whole fleet estimate, surface partial-node failure text in the card row title, and pin the generic-rejection partial path with a fast route test. * test: destroy reverse-route connect-ack sockets on teardown Unguarded accepted sockets could emit a late ECONNRESET after assertions passed, failing the Backend Vitest job with zero assertion failures.
This commit is contained in:
@@ -0,0 +1,58 @@
|
||||
import { describe, it, expect } from 'vitest';
|
||||
import { foldNodeEstimate } from '../helpers/fleetEstimate';
|
||||
|
||||
const node = { nodeId: 1, nodeName: 'local' };
|
||||
|
||||
describe('foldNodeEstimate', () => {
|
||||
it('returns the sum when every target succeeds', () => {
|
||||
expect(foldNodeEstimate(node, [
|
||||
{ bytes: 500 },
|
||||
{ bytes: 100 },
|
||||
])).toEqual({
|
||||
nodeId: 1,
|
||||
nodeName: 'local',
|
||||
reclaimableBytes: 600,
|
||||
reachable: true,
|
||||
});
|
||||
});
|
||||
|
||||
it('keeps successful bytes and marks partial when some targets fail', () => {
|
||||
expect(foldNodeEstimate(node, [
|
||||
{ bytes: 500 },
|
||||
{ bytes: 0, error: 'Docker daemon is busy. Please try again in a moment.' },
|
||||
{ bytes: 100 },
|
||||
])).toEqual({
|
||||
nodeId: 1,
|
||||
nodeName: 'local',
|
||||
reclaimableBytes: 600,
|
||||
reachable: true,
|
||||
partial: true,
|
||||
error: 'Docker daemon is busy. Please try again in a moment.',
|
||||
});
|
||||
});
|
||||
|
||||
it('marks the node unreachable when every target fails', () => {
|
||||
expect(foldNodeEstimate(node, [
|
||||
{ bytes: 0, error: 'first failure' },
|
||||
{ bytes: 0, error: 'second failure' },
|
||||
])).toEqual({
|
||||
nodeId: 1,
|
||||
nodeName: 'local',
|
||||
reclaimableBytes: 0,
|
||||
reachable: false,
|
||||
error: 'first failure',
|
||||
});
|
||||
});
|
||||
|
||||
it('surfaces the single-target failure message without partial', () => {
|
||||
expect(foldNodeEstimate(node, [
|
||||
{ bytes: 0, error: 'Docker daemon is busy. Please try again in a moment.' },
|
||||
])).toEqual({
|
||||
nodeId: 1,
|
||||
nodeName: 'local',
|
||||
reclaimableBytes: 0,
|
||||
reachable: false,
|
||||
error: 'Docker daemon is busy. Please try again in a moment.',
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user