@@ -2,6 +2,7 @@ package runtime
22
33import (
44 "context"
5+ "errors"
56 "os"
67 "path/filepath"
78 "strings"
@@ -776,6 +777,76 @@ func TestCheckpointDiffRejectsMissingStateAndReturnsEmptyWhenNoPreviousSnapshot(
776777 }
777778}
778779
780+ func TestCreateEndOfTurnCheckpoint_SetsLastCheckpointID (t * testing.T ) {
781+ fixture := newRuntimeCheckpointFixture (t )
782+ fixture .captureFile (t , "tracked.go" , []byte ("package main\n " ))
783+
784+ state := newRunState ("run-eot-id" , fixture .session )
785+ fixture .service .createEndOfTurnCheckpoint (context .Background (), & state , true )
786+
787+ if state .lastEndOfTurnCheckpointID == "" {
788+ t .Fatal ("expected lastEndOfTurnCheckpointID to be set after end-of-turn checkpoint creation" )
789+ }
790+
791+ records , err := fixture .checkpointStore .ListCheckpoints (context .Background (), fixture .session .ID , checkpoint.ListCheckpointOpts {})
792+ if err != nil {
793+ t .Fatalf ("ListCheckpoints() error = %v" , err )
794+ }
795+ if len (records ) != 1 {
796+ t .Fatalf ("records = %#v, want 1" , records )
797+ }
798+ wantRef := checkpoint .PerEditCheckpointIDFromRef (records [0 ].CodeCheckpointRef )
799+ if state .lastEndOfTurnCheckpointID != wantRef {
800+ t .Fatalf ("lastEndOfTurnCheckpointID = %q, want %q" , state .lastEndOfTurnCheckpointID , wantRef )
801+ }
802+ }
803+
804+ func TestFindPreviousEndOfTurnCheckpoint (t * testing.T ) {
805+ spy := & checkpointStoreSpy {
806+ listRecords : []agentsession.CheckpointRecord {
807+ {CheckpointID : "cp-skip-current" , SessionID : "session-1" , Reason : agentsession .CheckpointReasonEndOfTurn , CodeCheckpointRef : checkpoint .RefForPerEditCheckpoint ("cp-skip-current" ), RunID : "current-run" , Status : agentsession .CheckpointStatusAvailable },
808+ {CheckpointID : "cp-skip-reason" , SessionID : "session-1" , Reason : agentsession .CheckpointReasonCompact , CodeCheckpointRef : checkpoint .RefForPerEditCheckpoint ("cp-skip-reason" ), RunID : "old-run" , Status : agentsession .CheckpointStatusAvailable },
809+ {CheckpointID : "cp-valid" , SessionID : "session-1" , Reason : agentsession .CheckpointReasonEndOfTurn , CodeCheckpointRef : checkpoint .RefForPerEditCheckpoint ("cp-valid" ), RunID : "old-run" , Status : agentsession .CheckpointStatusAvailable },
810+ },
811+ }
812+ service := & Service {checkpointStore : spy }
813+
814+ got := service .findPreviousEndOfTurnCheckpoint (context .Background (), "session-1" , "current-run" )
815+ if got != "cp-valid" {
816+ t .Fatalf ("findPreviousEndOfTurnCheckpoint() = %q, want cp-valid" , got )
817+ }
818+ if spy .listSessionID != "session-1" || ! spy .listOpts .RestorableOnly || spy .listOpts .Limit != 50 {
819+ t .Fatalf ("list opts = %#v, want session-1 restorableOnly=true limit=50" , spy .listOpts )
820+ }
821+ }
822+
823+ func TestFindPreviousEndOfTurnCheckpoint_NoStore (t * testing.T ) {
824+ service := & Service {}
825+ if got := service .findPreviousEndOfTurnCheckpoint (context .Background (), "session-1" , "run-1" ); got != "" {
826+ t .Fatalf ("expected empty, got %q" , got )
827+ }
828+ }
829+
830+ func TestFindPreviousEndOfTurnCheckpoint_ListError (t * testing.T ) {
831+ spy := & checkpointStoreSpy {listErr : errors .New ("db down" )}
832+ service := & Service {checkpointStore : spy }
833+ if got := service .findPreviousEndOfTurnCheckpoint (context .Background (), "session-1" , "run-1" ); got != "" {
834+ t .Fatalf ("expected empty on list error, got %q" , got )
835+ }
836+ }
837+
838+ func TestFindPreviousEndOfTurnCheckpoint_SkipsNonPerEditRef (t * testing.T ) {
839+ spy := & checkpointStoreSpy {
840+ listRecords : []agentsession.CheckpointRecord {
841+ {CheckpointID : "cp-no-ref" , SessionID : "session-1" , Reason : agentsession .CheckpointReasonEndOfTurn , CodeCheckpointRef : "" , RunID : "old-run" , Status : agentsession .CheckpointStatusAvailable },
842+ },
843+ }
844+ service := & Service {checkpointStore : spy }
845+ if got := service .findPreviousEndOfTurnCheckpoint (context .Background (), "session-1" , "current-run" ); got != "" {
846+ t .Fatalf ("expected empty when no per-edit ref available, got %q" , got )
847+ }
848+ }
849+
779850func mustReadRuntimeFile (t * testing.T , path string ) []byte {
780851 t .Helper ()
781852 data , err := os .ReadFile (path )
0 commit comments