@@ -598,3 +598,210 @@ def test_has_response_lock(self):
598598
599599 assert hasattr (communicator , "_response_lock" )
600600 assert isinstance (communicator ._response_lock , type (threading .Lock ()))
601+
602+
603+ class TestProtobufCommunicatorHandleSetTimeTravelSync :
604+ """Tests for _handle_set_time_travel_sync method."""
605+
606+ def test_returns_early_when_no_request (self , mocker ):
607+ """Should return early when set_time_travel_request is None."""
608+ communicator = ProtobufCommunicator ()
609+ mock_send = mocker .patch .object (communicator , "_send_message_sync" )
610+
611+ mock_cli_message = mocker .MagicMock ()
612+ mock_cli_message .set_time_travel_request = None
613+
614+ communicator ._handle_set_time_travel_sync (mock_cli_message )
615+
616+ mock_send .assert_not_called ()
617+
618+ def test_handles_successful_time_travel (self , mocker ):
619+ """Should send success response when time travel starts successfully."""
620+ from tusk .drift .core .v1 import MessageType
621+
622+ communicator = ProtobufCommunicator ()
623+ mock_send = mocker .patch .object (communicator , "_send_message_sync" )
624+
625+ mock_cli_message = mocker .MagicMock ()
626+ mock_request = mocker .MagicMock ()
627+ mock_request .timestamp_seconds = 1234567890
628+ mock_request .trace_id = "trace123"
629+ mock_request .timestamp_source = "manual"
630+ mock_cli_message .set_time_travel_request = mock_request
631+ mock_cli_message .request_id = "req123"
632+
633+ mock_start_time_travel = mocker .patch (
634+ "drift.instrumentation.datetime.instrumentation.start_time_travel" , return_value = True
635+ )
636+
637+ communicator ._handle_set_time_travel_sync (mock_cli_message )
638+
639+ mock_start_time_travel .assert_called_once_with (1234567890 , "trace123" )
640+ mock_send .assert_called_once ()
641+ sent_message = mock_send .call_args [0 ][0 ]
642+ assert sent_message .type == MessageType .SET_TIME_TRAVEL
643+ assert sent_message .request_id == "req123"
644+ assert sent_message .set_time_travel_response .success is True
645+
646+ def test_handles_time_travel_failure (self , mocker ):
647+ """Should send error response when time travel fails."""
648+ from tusk .drift .core .v1 import MessageType
649+
650+ communicator = ProtobufCommunicator ()
651+ mock_send = mocker .patch .object (communicator , "_send_message_sync" )
652+
653+ mock_cli_message = mocker .MagicMock ()
654+ mock_request = mocker .MagicMock ()
655+ mock_request .timestamp_seconds = 1234567890
656+ mock_request .trace_id = "trace123"
657+ mock_request .timestamp_source = "manual"
658+ mock_cli_message .set_time_travel_request = mock_request
659+ mock_cli_message .request_id = "req456"
660+
661+ mocker .patch ("drift.instrumentation.datetime.instrumentation.start_time_travel" , return_value = False )
662+
663+ communicator ._handle_set_time_travel_sync (mock_cli_message )
664+
665+ mock_send .assert_called_once ()
666+ sent_message = mock_send .call_args [0 ][0 ]
667+ assert sent_message .type == MessageType .SET_TIME_TRAVEL
668+ assert sent_message .set_time_travel_response .success is False
669+ assert "not available" in sent_message .set_time_travel_response .error
670+
671+ def test_handles_time_travel_exception (self , mocker ):
672+ """Should send error response when exception occurs during time travel."""
673+
674+ communicator = ProtobufCommunicator ()
675+ mock_send = mocker .patch .object (communicator , "_send_message_sync" )
676+
677+ mock_cli_message = mocker .MagicMock ()
678+ mock_request = mocker .MagicMock ()
679+ mock_request .timestamp_seconds = 1234567890
680+ mock_request .trace_id = "trace123"
681+ mock_request .timestamp_source = "manual"
682+ mock_cli_message .set_time_travel_request = mock_request
683+ mock_cli_message .request_id = "req789"
684+
685+ mocker .patch (
686+ "drift.instrumentation.datetime.instrumentation.start_time_travel" ,
687+ side_effect = Exception ("Time travel error" ),
688+ )
689+
690+ communicator ._handle_set_time_travel_sync (mock_cli_message )
691+
692+ mock_send .assert_called_once ()
693+ sent_message = mock_send .call_args [0 ][0 ]
694+ assert sent_message .set_time_travel_response .success is False
695+ assert "Time travel error" in sent_message .set_time_travel_response .error
696+
697+
698+ class TestProtobufCommunicatorHandleCoverageSnapshotSync :
699+ """Tests for _handle_coverage_snapshot_sync method."""
700+
701+ def test_returns_early_when_no_request (self , mocker ):
702+ """Should return early when coverage_snapshot_request is None."""
703+ communicator = ProtobufCommunicator ()
704+ mock_send = mocker .patch .object (communicator , "_send_message_sync" )
705+
706+ mock_cli_message = mocker .MagicMock ()
707+ mock_cli_message .coverage_snapshot_request = None
708+
709+ communicator ._handle_coverage_snapshot_sync (mock_cli_message )
710+
711+ mock_send .assert_not_called ()
712+
713+ def test_handles_successful_baseline_snapshot (self , mocker ):
714+ """Should send success response with coverage data for baseline snapshot."""
715+ from tusk .drift .core .v1 import MessageType
716+
717+ communicator = ProtobufCommunicator ()
718+ mock_send = mocker .patch .object (communicator , "_send_message_sync" )
719+
720+ mock_cli_message = mocker .MagicMock ()
721+ mock_request = mocker .MagicMock ()
722+ mock_request .baseline = True
723+ mock_cli_message .coverage_snapshot_request = mock_request
724+ mock_cli_message .request_id = "cov123"
725+
726+ mock_snapshot_result = {
727+ "/app/main.py" : {
728+ "lines" : {"1" : 1 , "2" : 0 , "3" : 1 },
729+ "totalBranches" : 2 ,
730+ "coveredBranches" : 1 ,
731+ "branches" : {"5" : {"total" : 2 , "covered" : 1 }},
732+ }
733+ }
734+ mock_take_snapshot = mocker .patch (
735+ "drift.core.coverage_server.take_coverage_snapshot" ,
736+ return_value = mock_snapshot_result ,
737+ )
738+
739+ communicator ._handle_coverage_snapshot_sync (mock_cli_message )
740+
741+ mock_take_snapshot .assert_called_once_with (True )
742+ mock_send .assert_called_once ()
743+ sent_message = mock_send .call_args [0 ][0 ]
744+ assert sent_message .type == MessageType .COVERAGE_SNAPSHOT
745+ assert sent_message .request_id == "cov123"
746+ assert sent_message .coverage_snapshot_response .success is True
747+ assert "/app/main.py" in sent_message .coverage_snapshot_response .coverage
748+
749+ def test_converts_coverage_data_to_protobuf_format (self , mocker ):
750+ """Should properly convert coverage data to protobuf FileCoverageData format."""
751+
752+ communicator = ProtobufCommunicator ()
753+ mock_send = mocker .patch .object (communicator , "_send_message_sync" )
754+
755+ mock_cli_message = mocker .MagicMock ()
756+ mock_request = mocker .MagicMock ()
757+ mock_request .baseline = False
758+ mock_cli_message .coverage_snapshot_request = mock_request
759+ mock_cli_message .request_id = "cov789"
760+
761+ mock_snapshot_result = {
762+ "/app/file1.py" : {
763+ "lines" : {"1" : 1 , "2" : 1 },
764+ "totalBranches" : 4 ,
765+ "coveredBranches" : 3 ,
766+ "branches" : {"5" : {"total" : 2 , "covered" : 1 }, "10" : {"total" : 2 , "covered" : 2 }},
767+ }
768+ }
769+ mocker .patch (
770+ "drift.core.coverage_server.take_coverage_snapshot" ,
771+ return_value = mock_snapshot_result ,
772+ )
773+
774+ communicator ._handle_coverage_snapshot_sync (mock_cli_message )
775+
776+ sent_message = mock_send .call_args [0 ][0 ]
777+ file_data = sent_message .coverage_snapshot_response .coverage ["/app/file1.py" ]
778+ assert file_data .lines == {"1" : 1 , "2" : 1 }
779+ assert file_data .total_branches == 4
780+ assert file_data .covered_branches == 3
781+ assert "5" in file_data .branches
782+ assert file_data .branches ["5" ].total == 2
783+ assert file_data .branches ["5" ].covered == 1
784+
785+ def test_handles_snapshot_exception (self , mocker ):
786+ """Should send error response when take_coverage_snapshot raises exception."""
787+
788+ communicator = ProtobufCommunicator ()
789+ mock_send = mocker .patch .object (communicator , "_send_message_sync" )
790+
791+ mock_cli_message = mocker .MagicMock ()
792+ mock_request = mocker .MagicMock ()
793+ mock_request .baseline = False
794+ mock_cli_message .coverage_snapshot_request = mock_request
795+ mock_cli_message .request_id = "cov999"
796+
797+ mocker .patch (
798+ "drift.core.coverage_server.take_coverage_snapshot" ,
799+ side_effect = RuntimeError ("Coverage not initialized" ),
800+ )
801+
802+ communicator ._handle_coverage_snapshot_sync (mock_cli_message )
803+
804+ mock_send .assert_called_once ()
805+ sent_message = mock_send .call_args [0 ][0 ]
806+ assert sent_message .coverage_snapshot_response .success is False
807+ assert "Coverage not initialized" in sent_message .coverage_snapshot_response .error
0 commit comments