Why: a crash after a tool was about to run left the call unpaired, and workspace writes could not be rewound. Evidence: GOWORK=off go test ./runtime/ ./runtime/llm/ ./runtime/checkpoint/ ./runtime/telemetry/ ./runtime/tools/ ./runtime/session/ ./adapters/native/ Impact: pending calls rerun only when both the stored and current replay declarations are safe; otherwise the result is an error. Empty fallback lists and a nil checkpoint log keep the previous behavior. Refs: feature/durable-rewind Co-authored-by: Cursor <cursoragent@cursor.com>
43 lines
1.2 KiB
Go
43 lines
1.2 KiB
Go
package tools
|
|
|
|
import (
|
|
"context"
|
|
"os"
|
|
"path/filepath"
|
|
"testing"
|
|
|
|
"agent-native/runtime/checkpoint"
|
|
)
|
|
|
|
func TestWriteAndEditRecordCheckpoints(t *testing.T) {
|
|
root := t.TempDir()
|
|
log, err := checkpoint.Open(filepath.Join(t.TempDir(), "cp.jsonl"))
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
reg := WorkspaceToolsCheckpointed(root, nil, log, func() string { return "m1" })
|
|
if reg.Execute(context.Background(), "write_file", []byte(`{"path":"a.txt","content":"one"}`)).IsError {
|
|
t.Fatal("write")
|
|
}
|
|
if reg.Execute(context.Background(), "edit_file", []byte(`{"path":"a.txt","old":"one","new":"two"}`)).IsError {
|
|
t.Fatal("edit")
|
|
}
|
|
if err := os.WriteFile(filepath.Join(root, "shell.txt"), []byte("nope"), 0o644); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
got, err := log.Rewind("m1", []string{"m1"})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if len(got.Restored) != 1 || got.Restored[0] != "a.txt" {
|
|
t.Fatalf("restored %#v skipped %#v", got.Restored, got.Skipped)
|
|
}
|
|
if _, err := os.Stat(filepath.Join(root, "a.txt")); !os.IsNotExist(err) {
|
|
t.Fatal("created file was kept")
|
|
}
|
|
side, err := os.ReadFile(filepath.Join(root, "shell.txt"))
|
|
if err != nil || string(side) != "nope" {
|
|
t.Fatalf("shell file %q %v", side, err)
|
|
}
|
|
}
|