Files
cowork-local/tests/unit/test_task_scheduler_clock_wiring.py
T
f9f6bc01fd
CI / test (push) Canceled after 0s
Feature/delta team/epic r04 (#7)
## Summary

epic r04 - begin refactor

## Change Type

- [x] Cowork feature
- [ ] Bug fix
- [ ] Core AI contribution
- [ ] Test / hardening
- [ ] Performance
- [ ] Documentation

## Related Work

Cowork Task:

Core Repo: http://34.143.229.138/gitea-admin/fsg-ai-core-assets

Core AI Issue:

Core Task:

Related PR:

## Scope

What is intentionally included?

What is intentionally NOT included?

## Validation

- [ ] Unit tests
- [ ] Integration tests
- [ ] Manual verification
- [ ] Regression check

Commands / evidence:

## Security Impact

Permission / credential / network / customer data impact:

## Compatibility

- [ ] No breaking change
- [ ] Breaking change documented

## Reviewer Notes

Anything Cowork reviewers should pay attention to.

---------

Co-authored-by: Anh Tran Nguyen Minh <anhtnm1@fpt.com>
Co-authored-by: Huong Le Thi Thien <huongltt35@fpt.com>
Co-authored-by: Nam Pham Dinh Thanh <nampdt@fpt.com>
Co-authored-by: Vu Dam Tuan <vudt15@fpt.com>
Co-authored-by: Hiep Ha Van <hiephv3@fpt.com>
Co-authored-by: Lam Hoang Van <lamhv7@fpt.com>
Reviewed-on: #7
Co-authored-by: Duy Le Huu <duylh19@fpt.com>
2026-08-31 05:15:13 +00:00

67 lines
2.2 KiB
Python

"""EPIC R07-T03: TaskScheduler <-> clock wiring, entirely through
tests/fakes/fake_clock.py::FakeClock — no real QTimer, no Qt event loop.
Scope note: this only exercises the clock injection seam (start arms+starts
the clock with `tick`, stop stops it), not the full dispatch/execution
pipeline (`_start` -> `AgentWorker` -> `execute_task`), which needs a real
``ctx``/provider and is exactly the kind of Qt-adjacent, thread-heavy path
better left to an offscreen integration test if/when R08 touches this file
again — recorded here rather than silently left untested.
"""
from __future__ import annotations
from cowork_local.core.task_scheduler import TICK_MS, TaskScheduler
from tests.fakes import FakeClock
def test_start_arms_and_starts_the_injected_clock(tmp_path):
clock = FakeClock()
scheduler = TaskScheduler(ctx=None, tasks_dir=tmp_path, clock=clock)
ticks = []
# Instance-attribute override, set BEFORE start(): TaskScheduler.start()
# reads `self.tick`, which Python resolves to this override rather than
# the class method, so we can count calls without a real due task/ctx.
scheduler.tick = lambda: ticks.append(1)
scheduler.start()
assert clock.running is True
assert clock.interval_ms == TICK_MS
assert ticks == [1] # the catch-up tick() call at startup
def test_clock_fire_drives_another_tick(tmp_path):
clock = FakeClock()
scheduler = TaskScheduler(ctx=None, tasks_dir=tmp_path, clock=clock)
ticks = []
scheduler.tick = lambda: ticks.append(1)
scheduler.start()
clock.fire()
assert ticks == [1, 1]
def test_stop_stops_the_clock(tmp_path):
clock = FakeClock()
scheduler = TaskScheduler(ctx=None, tasks_dir=tmp_path, clock=clock)
scheduler.tick = lambda: None
scheduler.start()
scheduler.stop()
assert clock.running is False
def test_fire_after_stop_does_not_call_tick(tmp_path):
clock = FakeClock()
scheduler = TaskScheduler(ctx=None, tasks_dir=tmp_path, clock=clock)
ticks = []
scheduler.tick = lambda: ticks.append(1)
scheduler.start()
scheduler.stop()
clock.fire()
assert ticks == [1] # only the startup catch-up tick, nothing after stop