Skip to content

Commit ed76d19

Browse files
committed
fix(recording): sanitize process recording filenames for Windows
Replace colons in ISO 8601 timestamps with hyphens when generating filenames for process recordings. This prevents OSErrors on Windows systems where colons are invalid characters in filenames. Includes a regression test to verify that generated filenames do not contain colons. Also changes the format to use a dash to separate the timestamp from the PID for consistency. Fixes #377
1 parent 84f9784 commit ed76d19

File tree

2 files changed

+25
-1
lines changed

2 files changed

+25
-1
lines changed

_appmap/recording.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ def save_at_exit():
117117
now = datetime.now(timezone.utc)
118118
iso_time = now.isoformat(timespec="seconds").replace("+00:00", "Z")
119119
process_id = os.getpid()
120-
appmap_name = f"{iso_time}_{process_id}"
120+
appmap_name = f"{iso_time}-{process_id}".replace(":","-")
121121
recorder_type = "process"
122122
metadata = {
123123
"name": appmap_name,

_appmap/test/test_recording.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,3 +226,27 @@ def test_process_recording(data_dir, shell, tmp_path):
226226
actual = json.loads(appmap_files[0].read_text())
227227
assert len(actual["events"]) > 0
228228
assert len(actual["classMap"]) > 0
229+
230+
231+
def test_process_recording_filename_is_sanitized(data_dir, shell, tmp_path):
232+
fixture = data_dir / "package1"
233+
tmp = tmp_path / "process"
234+
copytree(fixture, str(tmp / "package1"), dirs_exist_ok=True)
235+
copy(data_dir / "appmap.yml", str(tmp))
236+
copytree(data_dir / "flask" / "init", str(tmp / "init"), dirs_exist_ok=True)
237+
238+
ret = shell.run(
239+
"python",
240+
"-m",
241+
"package1.package2",
242+
env={"PYTHONPATH": "init", "APPMAP_RECORD_PROCESS": "true"},
243+
cwd=tmp,
244+
)
245+
assert ret.returncode == 0
246+
247+
appmap_dir = tmp / "tmp" / "appmap" / "process"
248+
appmap_files = list(appmap_dir.glob("*.appmap.json"))
249+
assert len(appmap_files) == 1, "this only fails when run from VS Code?"
250+
251+
filename = appmap_files[0].name
252+
assert ":" not in filename

0 commit comments

Comments
 (0)