@@ -600,6 +600,136 @@ def make_sub_log(layer_id: str):
600600 ]
601601
602602
603+ async def test_install_progress_rounding_does_not_cause_misses (
604+ coresys : CoreSys , test_docker_interface : DockerInterface , ha_ws_client : AsyncMock
605+ ):
606+ """Test extremely close progress events do not create rounding issues."""
607+ coresys .core .set_state (CoreState .RUNNING )
608+ coresys .docker .docker .api .pull .return_value = [
609+ {
610+ "status" : "Pulling from home-assistant/odroid-n2-homeassistant" ,
611+ "id" : "2025.7.1" ,
612+ },
613+ {"status" : "Pulling fs layer" , "progressDetail" : {}, "id" : "1e214cd6d7d0" },
614+ {
615+ "status" : "Downloading" ,
616+ "progressDetail" : {"current" : 432700000 , "total" : 436480882 },
617+ "progress" : "[=================================================> ] 432.7MB/436.5MB" ,
618+ "id" : "1e214cd6d7d0" ,
619+ },
620+ {
621+ "status" : "Downloading" ,
622+ "progressDetail" : {"current" : 432800000 , "total" : 436480882 },
623+ "progress" : "[=================================================> ] 432.8MB/436.5MB" ,
624+ "id" : "1e214cd6d7d0" ,
625+ },
626+ {"status" : "Verifying Checksum" , "progressDetail" : {}, "id" : "1e214cd6d7d0" },
627+ {"status" : "Download complete" , "progressDetail" : {}, "id" : "1e214cd6d7d0" },
628+ {
629+ "status" : "Extracting" ,
630+ "progressDetail" : {"current" : 432700000 , "total" : 436480882 },
631+ "progress" : "[=================================================> ] 432.7MB/436.5MB" ,
632+ "id" : "1e214cd6d7d0" ,
633+ },
634+ {
635+ "status" : "Extracting" ,
636+ "progressDetail" : {"current" : 432800000 , "total" : 436480882 },
637+ "progress" : "[=================================================> ] 432.8MB/436.5MB" ,
638+ "id" : "1e214cd6d7d0" ,
639+ },
640+ {"status" : "Pull complete" , "progressDetail" : {}, "id" : "1e214cd6d7d0" },
641+ {
642+ "status" : "Digest: sha256:7d97da645f232f82a768d0a537e452536719d56d484d419836e53dbe3e4ec736"
643+ },
644+ {
645+ "status" : "Status: Downloaded newer image for ghcr.io/home-assistant/odroid-n2-homeassistant:2025.7.1"
646+ },
647+ ]
648+
649+ with (
650+ patch .object (
651+ type (coresys .supervisor ), "arch" , PropertyMock (return_value = "i386" )
652+ ),
653+ ):
654+ # Schedule job so we can listen for the end. Then we can assert against the WS mock
655+ event = asyncio .Event ()
656+ job , install_task = coresys .jobs .schedule_job (
657+ test_docker_interface .install ,
658+ JobSchedulerOptions (),
659+ AwesomeVersion ("1.2.3" ),
660+ "test" ,
661+ )
662+
663+ async def listen_for_job_end (reference : SupervisorJob ):
664+ if reference .uuid != job .uuid :
665+ return
666+ event .set ()
667+
668+ coresys .bus .register_event (BusEvent .SUPERVISOR_JOB_END , listen_for_job_end )
669+ await install_task
670+ await event .wait ()
671+
672+ events = [
673+ evt .args [0 ]["data" ]["data" ]
674+ for evt in ha_ws_client .async_send_command .call_args_list
675+ if "data" in evt .args [0 ]
676+ and evt .args [0 ]["data" ]["event" ] == WSEvent .JOB
677+ and evt .args [0 ]["data" ]["data" ]["reference" ] == "1e214cd6d7d0"
678+ and evt .args [0 ]["data" ]["data" ]["stage" ] in {"Downloading" , "Extracting" }
679+ ]
680+
681+ assert events == [
682+ {
683+ "name" : "Pulling container image layer" ,
684+ "stage" : "Downloading" ,
685+ "progress" : 49.6 ,
686+ "done" : False ,
687+ "extra" : {"current" : 432700000 , "total" : 436480882 },
688+ "reference" : "1e214cd6d7d0" ,
689+ "parent_id" : job .uuid ,
690+ "errors" : [],
691+ "uuid" : ANY ,
692+ "created" : ANY ,
693+ },
694+ {
695+ "name" : "Pulling container image layer" ,
696+ "stage" : "Downloading" ,
697+ "progress" : 49.6 ,
698+ "done" : False ,
699+ "extra" : {"current" : 432800000 , "total" : 436480882 },
700+ "reference" : "1e214cd6d7d0" ,
701+ "parent_id" : job .uuid ,
702+ "errors" : [],
703+ "uuid" : ANY ,
704+ "created" : ANY ,
705+ },
706+ {
707+ "name" : "Pulling container image layer" ,
708+ "stage" : "Extracting" ,
709+ "progress" : 99.6 ,
710+ "done" : False ,
711+ "extra" : {"current" : 432700000 , "total" : 436480882 },
712+ "reference" : "1e214cd6d7d0" ,
713+ "parent_id" : job .uuid ,
714+ "errors" : [],
715+ "uuid" : ANY ,
716+ "created" : ANY ,
717+ },
718+ {
719+ "name" : "Pulling container image layer" ,
720+ "stage" : "Extracting" ,
721+ "progress" : 99.6 ,
722+ "done" : False ,
723+ "extra" : {"current" : 432800000 , "total" : 436480882 },
724+ "reference" : "1e214cd6d7d0" ,
725+ "parent_id" : job .uuid ,
726+ "errors" : [],
727+ "uuid" : ANY ,
728+ "created" : ANY ,
729+ },
730+ ]
731+
732+
603733@pytest .mark .parametrize (
604734 ("error_log" , "exc_type" , "exc_msg" ),
605735 [
0 commit comments