mirror of
https://github.com/Akkudoktor-EOS/EOS.git
synced 2026-10-30 09:41:57 +00:00
fix(database): make delete_by_datetime(None, None) a true full wipe (#1476)
delete_by_datetime() with no bounds was documented as "delete all
records", but db_delete_records() assumed that
_db_ensure_loaded(start=None, end=None) loads every record into memory
before building the delete list. That is wrong: _db_ensure_loaded()
implements a NONE -> INITIAL -> FULL phase machine, and with both bounds
None in the NONE phase it loads only an *initial window* and leaves the
phase at INITIAL. Records outside that window never enter
_db_sorted_timestamps, so they are never marked for deletion and survive
in the physical store. Symptom: after a "wipe", db_count_records() still
returned N records (observed: 4 leftovers from a previous dense fixture).
A second delete_by_datetime() call happened to escalate INITIAL -> FULL
and deleted the rest, which is why the bug looked intermittent and why
stacked test runs accumulated rows.
Fix: in db_delete_records(), when both bounds are None, call
self._db_load_full() directly; otherwise keep the existing
_db_ensure_loaded(start, end) path. The delete list is then complete and
the "wipe" fixture actually wipes.
delete_by_datetime() remains a soft delete (rows are only added to
_db_deleted_timestamps; the physical DELETE happens on the next flush),
unchanged by this commit.
Besides this an additional fix was added:
* fix(tests): assert UTC-instant ordering in test_timestamps_remain_sorted
The test asserted `dts == sorted(dts)` on seq.records[].date_time, which
are tz-aware DateTime values in Europe/Berlin. Compaction buckets on a
UTC grid but records are materialized in local time, so across a DST
fall-back the local wall-clock sequence is non-monotonic even though the
UTC instants are ordered (e.g. 00:45 UTC -> 02:45 CEST, 01:00 UTC ->
02:00 CET). sorted() compares wall-clock fields, so it flags the pair at
the seam (index 1248 on 2026-10-25 for Europe/Berlin) as out of order.
The assertion is unsatisfiable for any 15-min grid spanning a fall-back
boundary when records are labelled in local time.
The actual invariant is "ascending by UTC instant", which is what
_db_sorted_timestamps guarantees and what the adjacent alignment tests
already assert via int(rec.date_time.timestamp()). Change the assertion
to compare integer UTC epochs:
epochs = [int(r.date_time.timestamp()) for r in seq.records if r.date_time]
assert epochs == sorted(epochs)
Note: this test was seasonally flaky. It only fails while a DST
transition lies inside the [now - 4 weeks, now] window used by
dense_energy_seq, which is why it newly started failing without any code
change. Upstream should ideally emit compacted records in UTC (or order
by UTC instant) so that wall-clock ordering is not silently assumed.
Signed-off-by: Bobby Noelte <b0661n0e17e@gmail.com>
This commit is contained in:
+22
-8
@@ -8,7 +8,7 @@
|
||||
"name": "Apache 2.0",
|
||||
"url": "https://www.apache.org/licenses/LICENSE-2.0.html"
|
||||
},
|
||||
"version": "v0.3.0.dev2610261491542381"
|
||||
"version": "v0.3.0.dev2610291327175670"
|
||||
},
|
||||
"paths": {
|
||||
"/v1/measurement/battery-capacity/{battery_id}": {
|
||||
@@ -1164,7 +1164,7 @@
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"anyOf": [
|
||||
"oneOf": [
|
||||
{
|
||||
"$ref": "#/components/schemas/PowerMeasurement"
|
||||
},
|
||||
@@ -1193,6 +1193,20 @@
|
||||
"$ref": "#/components/schemas/DDBCActuatorStatus"
|
||||
}
|
||||
],
|
||||
"discriminator": {
|
||||
"propertyName": "type",
|
||||
"mapping": {
|
||||
"PowerMeasurement": "#/components/schemas/PowerMeasurement",
|
||||
"EnergyMeasurement": "#/components/schemas/EnergyMeasurement",
|
||||
"PPBCPowerProfileStatus": "#/components/schemas/PPBCPowerProfileStatus",
|
||||
"OMBCStatus": "#/components/schemas/OMBCStatus",
|
||||
"FRBCActuatorStatus": "#/components/schemas/FRBCActuatorStatus",
|
||||
"FRBCEnergyStatus": "#/components/schemas/FRBCEnergyStatus",
|
||||
"FRBCStorageStatus": "#/components/schemas/FRBCStorageStatus",
|
||||
"FRBCTimerStatus": "#/components/schemas/FRBCTimerStatus",
|
||||
"DDBCActuatorStatus": "#/components/schemas/DDBCActuatorStatus"
|
||||
}
|
||||
},
|
||||
"description": "Resource Status.",
|
||||
"title": "Status"
|
||||
}
|
||||
@@ -10992,11 +11006,11 @@
|
||||
}
|
||||
],
|
||||
"title": "Device Measurement Entity Ids",
|
||||
"description": "Mapping of EOS measurement keys used by device (resource) simulations to Home Assistant entity IDs.",
|
||||
"description": "Mapping of EOS device measurement keys to Home Assistant entity IDs. Registered keys such as 'battery1-soc-factor' are accepted; legacy underscore spellings are resolved when they uniquely match a registered key.",
|
||||
"examples": [
|
||||
{
|
||||
"battery1_soc_factor": "sensor.battery1_soc_factor",
|
||||
"ev11_soc_factor": "sensor.ev11_soc_factor"
|
||||
"battery1-soc-factor": "sensor.battery1_soc_factor",
|
||||
"ev11-soc-factor": "sensor.ev11_soc_factor"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -11168,11 +11182,11 @@
|
||||
}
|
||||
],
|
||||
"title": "Device Measurement Entity Ids",
|
||||
"description": "Mapping of EOS measurement keys used by device (resource) simulations to Home Assistant entity IDs.",
|
||||
"description": "Mapping of EOS device measurement keys to Home Assistant entity IDs. Registered keys such as 'battery1-soc-factor' are accepted; legacy underscore spellings are resolved when they uniquely match a registered key.",
|
||||
"examples": [
|
||||
{
|
||||
"battery1_soc_factor": "sensor.battery1_soc_factor",
|
||||
"ev11_soc_factor": "sensor.ev11_soc_factor"
|
||||
"battery1-soc-factor": "sensor.battery1_soc_factor",
|
||||
"ev11-soc-factor": "sensor.ev11_soc_factor"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user