mirror of
https://github.com/garethgeorge/backrest.git
synced 2026-07-12 04:57:04 +00:00
fix: more summary dashboard bug fixes
This commit is contained in:
@@ -282,10 +282,12 @@ func (a *summaryAcc) finalize(id string, now time.Time, allowedStaleness time.Du
|
||||
}
|
||||
|
||||
// A day is overdue when, at its close (clamped to now for today), the newest
|
||||
// OK backup is older than the allowed staleness. Days before the first OK
|
||||
// backup ever are exempt: the scheduler anchors to the first real run. A day
|
||||
// where a late backup finally lands renders as backed-up, so checking only the
|
||||
// day's close loses nothing visible.
|
||||
// OK backup is older than the allowed staleness AND the day had no OK backup
|
||||
// of its own. Days before the first OK backup ever are exempt: the scheduler
|
||||
// anchors to the first real run. Requiring the day itself to be empty keeps
|
||||
// sub-daily schedules honest: an hourly plan whose last run was at noon still
|
||||
// backed the day up even though midnight is well past the allowed gap, so the
|
||||
// day must render as backed-up, not overdue.
|
||||
if allowedStaleness > 0 {
|
||||
checkpoint := day.AddDate(0, 0, 1)
|
||||
if checkpoint.After(now) {
|
||||
@@ -295,7 +297,11 @@ func (a *summaryAcc) finalize(id string, now time.Time, allowedStaleness time.Du
|
||||
lastOkBackup = okBackupDates[nextOkBackup]
|
||||
nextOkBackup++
|
||||
}
|
||||
bucket.Overdue = !lastOkBackup.IsZero() && checkpoint.Sub(lastOkBackup) > allowedStaleness
|
||||
// lastOkBackup <= checkpoint <= day+1, so lastOkBackup.Before(day) is
|
||||
// exactly "the newest OK backup landed on an earlier day" — this day had none.
|
||||
bucket.Overdue = !lastOkBackup.IsZero() &&
|
||||
lastOkBackup.Before(day) &&
|
||||
checkpoint.Sub(lastOkBackup) > allowedStaleness
|
||||
}
|
||||
|
||||
history = append(history, bucket)
|
||||
|
||||
@@ -69,6 +69,22 @@ func TestSummaryOverdueFlags(t *testing.T) {
|
||||
// day closes more than 48h past it.
|
||||
expected: []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9},
|
||||
},
|
||||
{
|
||||
name: "sub-daily schedule with a backup each day is never overdue",
|
||||
okBackupDates: []time.Time{at(0, 2), at(1, 2), at(2, 2), at(3, 2), at(4, 2), at(5, 2), at(6, 2), at(7, 2), at(8, 2), at(9, 2)},
|
||||
allowedGap: 75 * time.Minute, // hourly cadence * 1.25 grace
|
||||
// Every day has an OK backup at 02:00. Its close (midnight) is ~22h past
|
||||
// that, far beyond the gap, but a day that backed up is never overdue.
|
||||
expected: nil,
|
||||
},
|
||||
{
|
||||
name: "sub-daily schedule flags a fully missed day",
|
||||
okBackupDates: []time.Time{at(0, 2), at(1, 2), at(3, 2), at(4, 2), at(5, 2), at(6, 2), at(7, 2), at(8, 2), at(9, 2)}, // day2 missing
|
||||
allowedGap: 75 * time.Minute,
|
||||
// Day 2 has no OK backup of its own and closes far past the allowed gap;
|
||||
// day 3 recovers with its own backup and stays backed-up.
|
||||
expected: []int{2},
|
||||
},
|
||||
{
|
||||
name: "gap exactly at allowed staleness is not overdue",
|
||||
okBackupDates: []time.Time{at(0, 0), at(2, 0), at(4, 0), at(6, 0), at(8, 0)},
|
||||
|
||||
@@ -32,6 +32,7 @@ import { toaster } from "../../components/ui/toaster";
|
||||
|
||||
import {
|
||||
BackupProgressEntry,
|
||||
BackupProgressEntrySchema,
|
||||
ResticSnapshot,
|
||||
SnapshotSummary,
|
||||
} from "../../../gen/ts/v1/restic_pb";
|
||||
@@ -58,7 +59,7 @@ import {
|
||||
import { OperationIcon } from "./OperationIcon";
|
||||
import { LogView } from "../../components/common/LogView";
|
||||
|
||||
import { create } from "@bufbuild/protobuf";
|
||||
import { create, toJsonString } from "@bufbuild/protobuf";
|
||||
import { useReposByGuid } from "../../app/provider";
|
||||
import { OperationListView } from "./OperationListView";
|
||||
import * as m from "../../paraglide/messages";
|
||||
@@ -737,7 +738,14 @@ const BackupOperationStatus = ({
|
||||
);
|
||||
} else {
|
||||
console.error("GOT UNEXPECTED STATUS: ", status);
|
||||
return <>{m.op_row_unexpected_status() + JSON.stringify(status)}</>;
|
||||
// Serialize via the proto helper: BackupProgressEntry carries int64 fields that
|
||||
// become BigInt, which raw JSON.stringify cannot serialize (it throws).
|
||||
return (
|
||||
<>
|
||||
{m.op_row_unexpected_status() +
|
||||
toJsonString(BackupProgressEntrySchema, status)}
|
||||
</>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user