Tell a finished update by its build identifier #66
Loading…
Reference in a new issue
No description provided.
Delete branch "feat/build-id-confirms-update"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Section 11: "a new build identifier in
SYS_ANNOUNCEafter it is what says an update took". The session watched the firmware version instead, which is a hand-written0x0001on every node and does not move when a node is reflashed, so every successful update looked like nothing had happened.A session now takes the build the node was last heard announcing, and judges the one it comes back on against it. An announce heard during the session — the node answering a descriptor query on the image it still runs — replaces the caller's word, since it is the node's own.
Three outcomes where there was one:
UPDATED— back on a build it did not go in on.UNCHANGED— back on the one it went in on. No node reports a rollback, and this is what one looks like; so does being sent the image it was already running. It is not a failed fetch, so it never contradicts thefetch_failedattribute, which covers the failures a node is left running to report.RETURNED— back, with nothing to judge it against.Versions are still not comparable, and this does not try:
version_is_newerstays as it is. This makes "did it take" answerable; "is it behind" still is not.Nothing needed adding on the entity side.
firmware_labelalready puts both the version and the build on the device and ininstalled_version, andOtaStorealready ends a transfer on the pair changing.Tested: a node back on a new build, back on the same one, and back with an unchanged version across a real update — the case that was broken. CCS-UHA-16.
Judgement matches spec section 11 and the codec. Three things.
tests/test_updater_session.py:464—test_a_version_that_never_moved_is_still_an_update_that_tookis the sameFakeNodeand the sameruncall as the test directly above it; only the assertion differs. Nothing in it varies the firmware version, so it cannot fail for the reason its docstring gives. Mutating_judgedto always returnUPDATEDleaves both passing. Moveassert result.firmware == 1into the test above and drop this one.updater/session.py:554— the new module-level_judgedshares its name withUpdateSession._judgedat line 416, which judges aBULK_ENDresult. Two unrelated things under one name in one file. Rename the new one, e.g._what_the_build_says.updater/session.py:575— theUNCHANGEDwarning and the_LOGGER.infoat line 583 both fire on the same return, and the info line already carries the outcome. Drop one.Not a defect, but worth knowing:
tests/test_firmware_updates.py:466passes unchanged againstfeat/firmware-updates. It pinsfirmware_label, not anything in this diff.@ -430,0 +461,4 @@assert result.build == NEW_BUILDasync def test_a_version_that_never_moved_is_still_an_update_that_took() -> None:Same
FakeNodeand sameruncall astest_a_node_back_on_a_new_build_is_a_node_that_updatedabove; only the assertion differs. Nothing here varies the firmware version, so it cannot fail for the reason the docstring gives — mutating_judgedto always returnUPDATEDleaves both passing. Foldassert result.firmware == 1into the test above and delete this one.@ -527,6 +551,52 @@ class UpdateSession:return self._transferdef _judged(Name collides with
UpdateSession._judgedat line 416, which judges aBULK_ENDtransfer result. Rename, e.g._what_the_build_says.@ -530,0 +572,4 @@elif build == before:outcome = Outcome.UNCHANGEDdetail = f"the node came back on build {shown}, the one it went in on"_LOGGER.warning(This warning and the
_LOGGER.infobelow fire together on everyUNCHANGEDreturn, and the info line already names the outcome. Drop one.All three taken in
a34a531. Nothing further.test_a_node_announcing_before_it_writes_says_what_it_went_in_onnow bites: with both_watchand_returnedmutated to readfirmwareinstead ofbuild, it fails along with the other three build tests.