experimaestro 1.11.1__py3-none-any.whl → 2.0.0rc0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of experimaestro might be problematic. Click here for more details.
- experimaestro/annotations.py +1 -1
- experimaestro/cli/__init__.py +10 -11
- experimaestro/cli/progress.py +269 -0
- experimaestro/core/identifier.py +11 -2
- experimaestro/core/objects/config.py +64 -94
- experimaestro/core/types.py +35 -57
- experimaestro/launcherfinder/registry.py +3 -3
- experimaestro/mkdocs/base.py +6 -8
- experimaestro/notifications.py +12 -3
- experimaestro/progress.py +406 -0
- experimaestro/settings.py +4 -2
- experimaestro/tests/launchers/common.py +2 -2
- experimaestro/tests/restart.py +1 -1
- experimaestro/tests/test_checkers.py +2 -2
- experimaestro/tests/test_dependencies.py +12 -12
- experimaestro/tests/test_experiment.py +3 -3
- experimaestro/tests/test_file_progress.py +425 -0
- experimaestro/tests/test_file_progress_integration.py +477 -0
- experimaestro/tests/test_generators.py +61 -0
- experimaestro/tests/test_identifier.py +90 -81
- experimaestro/tests/test_instance.py +9 -9
- experimaestro/tests/test_objects.py +9 -32
- experimaestro/tests/test_outputs.py +6 -6
- experimaestro/tests/test_param.py +14 -14
- experimaestro/tests/test_progress.py +4 -4
- experimaestro/tests/test_serializers.py +5 -5
- experimaestro/tests/test_tags.py +15 -15
- experimaestro/tests/test_tasks.py +40 -36
- experimaestro/tests/test_tokens.py +8 -6
- experimaestro/tests/test_types.py +10 -10
- experimaestro/tests/test_validation.py +19 -19
- experimaestro/tests/token_reschedule.py +1 -1
- {experimaestro-1.11.1.dist-info → experimaestro-2.0.0rc0.dist-info}/METADATA +1 -1
- {experimaestro-1.11.1.dist-info → experimaestro-2.0.0rc0.dist-info}/RECORD +37 -32
- {experimaestro-1.11.1.dist-info → experimaestro-2.0.0rc0.dist-info}/LICENSE +0 -0
- {experimaestro-1.11.1.dist-info → experimaestro-2.0.0rc0.dist-info}/WHEEL +0 -0
- {experimaestro-1.11.1.dist-info → experimaestro-2.0.0rc0.dist-info}/entry_points.txt +0 -0
|
@@ -0,0 +1,425 @@
|
|
|
1
|
+
"""Tests for the file-based progress tracking system"""
|
|
2
|
+
|
|
3
|
+
import json
|
|
4
|
+
import tempfile
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
from unittest.mock import patch
|
|
7
|
+
|
|
8
|
+
import pytest
|
|
9
|
+
|
|
10
|
+
from experimaestro.progress import (
|
|
11
|
+
ProgressEntry,
|
|
12
|
+
ProgressFileWriter,
|
|
13
|
+
ProgressFileReader,
|
|
14
|
+
FileBasedProgressReporter,
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class TestProgressEntry:
|
|
19
|
+
"""Test ProgressEntry dataclass"""
|
|
20
|
+
|
|
21
|
+
def test_to_dict(self):
|
|
22
|
+
entry = ProgressEntry(
|
|
23
|
+
timestamp=1234567890.0, level=1, progress=0.5, desc="Test description"
|
|
24
|
+
)
|
|
25
|
+
|
|
26
|
+
expected = {
|
|
27
|
+
"timestamp": 1234567890.0,
|
|
28
|
+
"level": 1,
|
|
29
|
+
"progress": 0.5,
|
|
30
|
+
"desc": "Test description",
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
assert entry.to_dict() == expected
|
|
34
|
+
|
|
35
|
+
def test_from_dict(self):
|
|
36
|
+
data = {
|
|
37
|
+
"timestamp": 1234567890.0,
|
|
38
|
+
"level": 1,
|
|
39
|
+
"progress": 0.5,
|
|
40
|
+
"desc": "Test description",
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
entry = ProgressEntry.from_dict(data)
|
|
44
|
+
|
|
45
|
+
assert entry.timestamp == 1234567890.0
|
|
46
|
+
assert entry.level == 1
|
|
47
|
+
assert entry.progress == 0.5
|
|
48
|
+
assert entry.desc == "Test description"
|
|
49
|
+
|
|
50
|
+
def test_from_dict_minimal(self):
|
|
51
|
+
data = {"timestamp": 1234567890.0, "level": 0, "progress": 1.0}
|
|
52
|
+
|
|
53
|
+
entry = ProgressEntry.from_dict(data)
|
|
54
|
+
|
|
55
|
+
assert entry.timestamp == 1234567890.0
|
|
56
|
+
assert entry.level == 0
|
|
57
|
+
assert entry.progress == 1.0
|
|
58
|
+
assert entry.desc is None
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
class TestProgressFileWriter:
|
|
62
|
+
"""Test ProgressFileWriter class"""
|
|
63
|
+
|
|
64
|
+
def test_init_creates_directory(self):
|
|
65
|
+
with tempfile.TemporaryDirectory() as tmpdir:
|
|
66
|
+
task_path = Path(tmpdir)
|
|
67
|
+
writer = ProgressFileWriter(task_path)
|
|
68
|
+
|
|
69
|
+
assert writer.progress_dir.exists()
|
|
70
|
+
assert writer.progress_dir == task_path / ".experimaestro"
|
|
71
|
+
|
|
72
|
+
def test_write_single_progress(self):
|
|
73
|
+
with tempfile.TemporaryDirectory() as tmpdir:
|
|
74
|
+
task_path = Path(tmpdir)
|
|
75
|
+
writer = ProgressFileWriter(task_path)
|
|
76
|
+
|
|
77
|
+
writer.write_progress(0, 0.5, "Test progress")
|
|
78
|
+
|
|
79
|
+
# Check file was created
|
|
80
|
+
progress_file = writer.progress_dir / "progress-0000.jsonl"
|
|
81
|
+
assert progress_file.exists()
|
|
82
|
+
|
|
83
|
+
# Check symlink was created
|
|
84
|
+
latest_link = writer.progress_dir / "progress-latest.jsonl"
|
|
85
|
+
assert latest_link.exists()
|
|
86
|
+
assert latest_link.is_symlink()
|
|
87
|
+
assert latest_link.resolve().name == progress_file.name
|
|
88
|
+
|
|
89
|
+
def test_write_multiple_progress(self):
|
|
90
|
+
with tempfile.TemporaryDirectory() as tmpdir:
|
|
91
|
+
task_path = Path(tmpdir)
|
|
92
|
+
writer = ProgressFileWriter(task_path)
|
|
93
|
+
|
|
94
|
+
# Write multiple progress entries
|
|
95
|
+
writer.write_progress(0, 0.1, "Step 1")
|
|
96
|
+
writer.write_progress(0, 0.5, "Step 2")
|
|
97
|
+
writer.write_progress(1, 0.3, "Substep")
|
|
98
|
+
writer.write_progress(0, 1.0, "Complete")
|
|
99
|
+
|
|
100
|
+
progress_file = writer.progress_dir / "progress-0000.jsonl"
|
|
101
|
+
assert progress_file.exists()
|
|
102
|
+
|
|
103
|
+
# Read and verify entries
|
|
104
|
+
lines = progress_file.read_text().strip().split("\n")
|
|
105
|
+
assert len(lines) == 4
|
|
106
|
+
|
|
107
|
+
# Check first entry
|
|
108
|
+
entry1 = json.loads(lines[0])
|
|
109
|
+
assert entry1["level"] == 0
|
|
110
|
+
assert entry1["progress"] == 0.1
|
|
111
|
+
assert entry1["desc"] == "Step 1"
|
|
112
|
+
|
|
113
|
+
def test_file_rotation(self):
|
|
114
|
+
with tempfile.TemporaryDirectory() as tmpdir:
|
|
115
|
+
task_path = Path(tmpdir)
|
|
116
|
+
# Set small max entries for testing rotation
|
|
117
|
+
writer = ProgressFileWriter(task_path, max_entries_per_file=2)
|
|
118
|
+
|
|
119
|
+
# Write 3 entries to trigger rotation
|
|
120
|
+
writer.write_progress(0, 0.1, "Entry 1")
|
|
121
|
+
writer.write_progress(0, 0.2, "Entry 2")
|
|
122
|
+
writer.write_progress(0, 0.3, "Entry 3") # Should trigger rotation
|
|
123
|
+
|
|
124
|
+
# Check both files exist
|
|
125
|
+
file1 = writer.progress_dir / "progress-0000.jsonl"
|
|
126
|
+
file2 = writer.progress_dir / "progress-0001.jsonl"
|
|
127
|
+
|
|
128
|
+
assert file1.exists()
|
|
129
|
+
assert file2.exists()
|
|
130
|
+
|
|
131
|
+
# Check file1 has 2 entries
|
|
132
|
+
lines1 = file1.read_text().strip().split("\n")
|
|
133
|
+
assert len(lines1) == 2
|
|
134
|
+
|
|
135
|
+
# Check file2 has 1 entry
|
|
136
|
+
lines2 = file2.read_text().strip().split("\n")
|
|
137
|
+
assert len(lines2) == 1
|
|
138
|
+
|
|
139
|
+
# Check symlink points to latest file
|
|
140
|
+
latest_link = writer.progress_dir / "progress-latest.jsonl"
|
|
141
|
+
assert latest_link.resolve().name == file2.name
|
|
142
|
+
|
|
143
|
+
def test_resume_from_existing_files(self):
|
|
144
|
+
with tempfile.TemporaryDirectory() as tmpdir:
|
|
145
|
+
task_path = Path(tmpdir)
|
|
146
|
+
|
|
147
|
+
# Create first writer and write some entries
|
|
148
|
+
writer1 = ProgressFileWriter(task_path, max_entries_per_file=2)
|
|
149
|
+
writer1.write_progress(0, 0.1, "Entry 1")
|
|
150
|
+
writer1.write_progress(0, 0.2, "Entry 2")
|
|
151
|
+
|
|
152
|
+
# Create second writer (simulating restart)
|
|
153
|
+
writer2 = ProgressFileWriter(task_path, max_entries_per_file=2)
|
|
154
|
+
|
|
155
|
+
# Should resume from existing state
|
|
156
|
+
assert writer2.current_file_index == 0
|
|
157
|
+
assert writer2.current_file_entries == 2
|
|
158
|
+
|
|
159
|
+
# Writing one more should trigger rotation
|
|
160
|
+
writer2.write_progress(0, 0.3, "Entry 3")
|
|
161
|
+
|
|
162
|
+
file2 = writer2.progress_dir / "progress-0001.jsonl"
|
|
163
|
+
assert file2.exists()
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
class TestProgressFileReader:
|
|
167
|
+
"""Test ProgressFileReader class"""
|
|
168
|
+
|
|
169
|
+
def test_read_entries_from_file(self):
|
|
170
|
+
with tempfile.TemporaryDirectory() as tmpdir:
|
|
171
|
+
task_path = Path(tmpdir)
|
|
172
|
+
|
|
173
|
+
# Write some test data
|
|
174
|
+
writer = ProgressFileWriter(task_path)
|
|
175
|
+
writer.write_progress(0, 0.5, "Test")
|
|
176
|
+
writer.write_progress(1, 0.3, "Nested")
|
|
177
|
+
|
|
178
|
+
# Read it back
|
|
179
|
+
reader = ProgressFileReader(task_path)
|
|
180
|
+
progress_file = reader.get_progress_files()[0]
|
|
181
|
+
entries = list(reader.read_entries(progress_file))
|
|
182
|
+
|
|
183
|
+
assert len(entries) == 2
|
|
184
|
+
assert entries[0].level == 0
|
|
185
|
+
assert entries[0].progress == 0.5
|
|
186
|
+
assert entries[0].desc == "Test"
|
|
187
|
+
assert entries[1].level == 1
|
|
188
|
+
assert entries[1].progress == 0.3
|
|
189
|
+
assert entries[1].desc == "Nested"
|
|
190
|
+
|
|
191
|
+
def test_read_all_entries(self):
|
|
192
|
+
with tempfile.TemporaryDirectory() as tmpdir:
|
|
193
|
+
task_path = Path(tmpdir)
|
|
194
|
+
|
|
195
|
+
# Write entries across multiple files
|
|
196
|
+
writer = ProgressFileWriter(task_path, max_entries_per_file=2)
|
|
197
|
+
writer.write_progress(0, 0.1, "Entry 1")
|
|
198
|
+
writer.write_progress(0, 0.2, "Entry 2")
|
|
199
|
+
writer.write_progress(0, 0.3, "Entry 3") # Triggers rotation
|
|
200
|
+
writer.write_progress(0, 0.4, "Entry 4")
|
|
201
|
+
|
|
202
|
+
# Read all entries
|
|
203
|
+
reader = ProgressFileReader(task_path)
|
|
204
|
+
entries = list(reader.read_all_entries())
|
|
205
|
+
|
|
206
|
+
assert len(entries) == 4
|
|
207
|
+
assert entries[0].desc == "Entry 1"
|
|
208
|
+
assert entries[1].desc == "Entry 2"
|
|
209
|
+
assert entries[2].desc == "Entry 3"
|
|
210
|
+
assert entries[3].desc == "Entry 4"
|
|
211
|
+
|
|
212
|
+
def test_read_latest_entries(self):
|
|
213
|
+
with tempfile.TemporaryDirectory() as tmpdir:
|
|
214
|
+
task_path = Path(tmpdir)
|
|
215
|
+
|
|
216
|
+
# Write many entries
|
|
217
|
+
writer = ProgressFileWriter(task_path, max_entries_per_file=3)
|
|
218
|
+
for i in range(10):
|
|
219
|
+
writer.write_progress(0, i / 10.0, f"Entry {i}")
|
|
220
|
+
|
|
221
|
+
# Read latest 5 entries
|
|
222
|
+
reader = ProgressFileReader(task_path)
|
|
223
|
+
latest = reader.read_latest_entries(5)
|
|
224
|
+
|
|
225
|
+
assert len(latest) == 5
|
|
226
|
+
# Should be entries 5-9 in chronological order
|
|
227
|
+
assert latest[0].desc == "Entry 5"
|
|
228
|
+
assert latest[4].desc == "Entry 9"
|
|
229
|
+
|
|
230
|
+
def test_get_current_progress(self):
|
|
231
|
+
with tempfile.TemporaryDirectory() as tmpdir:
|
|
232
|
+
task_path = Path(tmpdir)
|
|
233
|
+
|
|
234
|
+
# Write progress for multiple levels
|
|
235
|
+
writer = ProgressFileWriter(task_path)
|
|
236
|
+
writer.write_progress(0, 0.1, "Level 0 start")
|
|
237
|
+
writer.write_progress(1, 0.5, "Level 1 progress")
|
|
238
|
+
writer.write_progress(0, 0.5, "Level 0 update")
|
|
239
|
+
writer.write_progress(1, 1.0, "Level 1 complete")
|
|
240
|
+
writer.write_progress(0, 1.0, "Level 0 complete")
|
|
241
|
+
|
|
242
|
+
# Get current progress
|
|
243
|
+
reader = ProgressFileReader(task_path)
|
|
244
|
+
current = reader.get_current_progress()
|
|
245
|
+
|
|
246
|
+
assert len(current) == 2
|
|
247
|
+
assert current[0].progress == 1.0
|
|
248
|
+
assert current[0].desc == "Level 0 complete"
|
|
249
|
+
assert current[1].progress == 1.0
|
|
250
|
+
assert current[1].desc == "Level 1 complete"
|
|
251
|
+
|
|
252
|
+
def test_get_latest_file_via_symlink(self):
|
|
253
|
+
with tempfile.TemporaryDirectory() as tmpdir:
|
|
254
|
+
task_path = Path(tmpdir)
|
|
255
|
+
|
|
256
|
+
# Write some entries
|
|
257
|
+
writer = ProgressFileWriter(task_path, max_entries_per_file=2)
|
|
258
|
+
writer.write_progress(0, 0.1, "Entry 1")
|
|
259
|
+
writer.write_progress(0, 0.2, "Entry 2")
|
|
260
|
+
writer.write_progress(0, 0.3, "Entry 3") # Triggers rotation
|
|
261
|
+
|
|
262
|
+
# Get latest file
|
|
263
|
+
reader = ProgressFileReader(task_path)
|
|
264
|
+
latest_file = reader.get_latest_file()
|
|
265
|
+
|
|
266
|
+
expected_file = task_path / ".experimaestro" / "progress-0001.jsonl"
|
|
267
|
+
assert latest_file.name == expected_file.name
|
|
268
|
+
|
|
269
|
+
def test_no_progress_files(self):
|
|
270
|
+
with tempfile.TemporaryDirectory() as tmpdir:
|
|
271
|
+
task_path = Path(tmpdir)
|
|
272
|
+
|
|
273
|
+
reader = ProgressFileReader(task_path)
|
|
274
|
+
|
|
275
|
+
assert reader.get_progress_files() == []
|
|
276
|
+
assert reader.get_latest_file() is None
|
|
277
|
+
assert list(reader.read_all_entries()) == []
|
|
278
|
+
assert reader.read_latest_entries(10) == []
|
|
279
|
+
assert reader.get_current_progress() == {}
|
|
280
|
+
|
|
281
|
+
|
|
282
|
+
class TestFileBasedProgressReporter:
|
|
283
|
+
"""Test FileBasedProgressReporter class"""
|
|
284
|
+
|
|
285
|
+
def test_set_progress_writes_to_file(self):
|
|
286
|
+
with tempfile.TemporaryDirectory() as tmpdir:
|
|
287
|
+
task_path = Path(tmpdir)
|
|
288
|
+
|
|
289
|
+
reporter = FileBasedProgressReporter(task_path)
|
|
290
|
+
reporter.set_progress(0.5, 0, "Test progress")
|
|
291
|
+
|
|
292
|
+
# Verify file was written
|
|
293
|
+
progress_file = task_path / ".experimaestro" / "progress-0000.jsonl"
|
|
294
|
+
assert progress_file.exists()
|
|
295
|
+
|
|
296
|
+
# Read and verify content
|
|
297
|
+
reader = ProgressFileReader(task_path)
|
|
298
|
+
entries = list(reader.read_all_entries())
|
|
299
|
+
|
|
300
|
+
assert len(entries) == 1
|
|
301
|
+
assert entries[0].level == 0
|
|
302
|
+
assert entries[0].progress == 0.5
|
|
303
|
+
assert entries[0].desc == "Test progress"
|
|
304
|
+
|
|
305
|
+
def test_set_progress_threshold(self):
|
|
306
|
+
with tempfile.TemporaryDirectory() as tmpdir:
|
|
307
|
+
task_path = Path(tmpdir)
|
|
308
|
+
|
|
309
|
+
reporter = FileBasedProgressReporter(task_path)
|
|
310
|
+
|
|
311
|
+
# First progress
|
|
312
|
+
reporter.set_progress(0.5, 0, "Test")
|
|
313
|
+
|
|
314
|
+
# Small change (should not write)
|
|
315
|
+
reporter.set_progress(0.505, 0, "Test")
|
|
316
|
+
|
|
317
|
+
# Larger change (should write)
|
|
318
|
+
reporter.set_progress(0.6, 0, "Test")
|
|
319
|
+
|
|
320
|
+
# Read entries
|
|
321
|
+
reader = ProgressFileReader(task_path)
|
|
322
|
+
entries = list(reader.read_all_entries())
|
|
323
|
+
|
|
324
|
+
# Should only have 2 entries (first and third)
|
|
325
|
+
assert len(entries) == 2
|
|
326
|
+
assert entries[0].progress == 0.5
|
|
327
|
+
assert entries[1].progress == 0.6
|
|
328
|
+
|
|
329
|
+
def test_set_progress_description_change(self):
|
|
330
|
+
with tempfile.TemporaryDirectory() as tmpdir:
|
|
331
|
+
task_path = Path(tmpdir)
|
|
332
|
+
|
|
333
|
+
reporter = FileBasedProgressReporter(task_path)
|
|
334
|
+
|
|
335
|
+
# Same progress, different description
|
|
336
|
+
reporter.set_progress(0.5, 0, "Description 1")
|
|
337
|
+
reporter.set_progress(0.5, 0, "Description 2")
|
|
338
|
+
|
|
339
|
+
# Read entries
|
|
340
|
+
reader = ProgressFileReader(task_path)
|
|
341
|
+
entries = list(reader.read_all_entries())
|
|
342
|
+
|
|
343
|
+
# Should have both entries due to description change
|
|
344
|
+
assert len(entries) == 2
|
|
345
|
+
assert entries[0].desc == "Description 1"
|
|
346
|
+
assert entries[1].desc == "Description 2"
|
|
347
|
+
|
|
348
|
+
def test_eoj_writes_marker(self):
|
|
349
|
+
with tempfile.TemporaryDirectory() as tmpdir:
|
|
350
|
+
task_path = Path(tmpdir)
|
|
351
|
+
|
|
352
|
+
reporter = FileBasedProgressReporter(task_path)
|
|
353
|
+
reporter.set_progress(1.0, 0, "Complete")
|
|
354
|
+
reporter.eoj()
|
|
355
|
+
|
|
356
|
+
# Read entries
|
|
357
|
+
reader = ProgressFileReader(task_path)
|
|
358
|
+
entries = list(reader.read_all_entries())
|
|
359
|
+
|
|
360
|
+
assert len(entries) == 2
|
|
361
|
+
assert entries[0].level == 0
|
|
362
|
+
assert entries[0].progress == 1.0
|
|
363
|
+
assert entries[1].level == -1 # EOJ marker
|
|
364
|
+
assert entries[1].progress == 1.0
|
|
365
|
+
assert entries[1].desc == "EOJ"
|
|
366
|
+
|
|
367
|
+
def test_multiple_levels(self):
|
|
368
|
+
with tempfile.TemporaryDirectory() as tmpdir:
|
|
369
|
+
task_path = Path(tmpdir)
|
|
370
|
+
|
|
371
|
+
reporter = FileBasedProgressReporter(task_path)
|
|
372
|
+
|
|
373
|
+
# Progress at different levels
|
|
374
|
+
reporter.set_progress(0.1, 0, "Main task")
|
|
375
|
+
reporter.set_progress(0.5, 1, "Subtask")
|
|
376
|
+
reporter.set_progress(0.3, 2, "Sub-subtask")
|
|
377
|
+
reporter.set_progress(0.5, 0, "Main task update")
|
|
378
|
+
|
|
379
|
+
# Read current progress
|
|
380
|
+
reader = ProgressFileReader(task_path)
|
|
381
|
+
current = reader.get_current_progress()
|
|
382
|
+
|
|
383
|
+
assert len(current) == 3
|
|
384
|
+
assert current[0].progress == 0.5
|
|
385
|
+
assert current[0].desc == "Main task update"
|
|
386
|
+
assert current[1].progress == 0.5
|
|
387
|
+
assert current[1].desc == "Subtask"
|
|
388
|
+
assert current[2].progress == 0.3
|
|
389
|
+
assert current[2].desc == "Sub-subtask"
|
|
390
|
+
|
|
391
|
+
|
|
392
|
+
class TestIntegrationWithNotifications:
|
|
393
|
+
"""Test integration with existing notification system"""
|
|
394
|
+
|
|
395
|
+
@patch("experimaestro.taskglobals.Env.instance")
|
|
396
|
+
def test_progress_function_writes_to_file(self, mock_env):
|
|
397
|
+
"""Test that the progress() function writes to file system"""
|
|
398
|
+
with tempfile.TemporaryDirectory() as tmpdir:
|
|
399
|
+
task_path = Path(tmpdir)
|
|
400
|
+
|
|
401
|
+
# Mock the task environment
|
|
402
|
+
mock_env.return_value.taskpath = task_path
|
|
403
|
+
mock_env.return_value.slave = False
|
|
404
|
+
|
|
405
|
+
# Import and call progress function
|
|
406
|
+
from experimaestro.notifications import progress
|
|
407
|
+
|
|
408
|
+
progress(0.5, level=0, desc="Test progress")
|
|
409
|
+
|
|
410
|
+
# Verify file was written
|
|
411
|
+
progress_file = task_path / ".experimaestro" / "progress-0000.jsonl"
|
|
412
|
+
assert progress_file.exists()
|
|
413
|
+
|
|
414
|
+
# Read and verify
|
|
415
|
+
reader = ProgressFileReader(task_path)
|
|
416
|
+
entries = list(reader.read_all_entries())
|
|
417
|
+
|
|
418
|
+
assert len(entries) == 1
|
|
419
|
+
assert entries[0].level == 0
|
|
420
|
+
assert entries[0].progress == 0.5
|
|
421
|
+
assert entries[0].desc == "Test progress"
|
|
422
|
+
|
|
423
|
+
|
|
424
|
+
if __name__ == "__main__":
|
|
425
|
+
pytest.main([__file__])
|