test_t3_performance.py
python
sha256:ca1d0e687bff8686b37126eb8e4fb6d38b40e189352a4920d66ae89c7274e340
Add T4 job cancellation retry and validation
Human
minor
⚠ breaking
41 days ago
| 1 | """Performance tier tests — T3 queue operations and dataset lookup under load.""" |
| 2 | |
| 3 | from __future__ import annotations |
| 4 | |
| 5 | import time |
| 6 | import unittest |
| 7 | |
| 8 | from scooling_lab_helpers import valid_payload |
| 9 | |
| 10 | from scooling_lab.dataset_review import ( |
| 11 | DatasetStore, |
| 12 | RejectionReasonCode, |
| 13 | default_dataset_shape, |
| 14 | ) |
| 15 | from scooling_lab.service import TrainingApiService |
| 16 | from scooling_lab.store import TrainingJobStore |
| 17 | |
| 18 | |
| 19 | class T3PerformanceTests(unittest.TestCase): |
| 20 | """Performance tests with generous wall-clock thresholds for CI robustness.""" |
| 21 | |
| 22 | def test_performance_t3_dataset_store_lookups_are_constant_time(self) -> None: |
| 23 | """10 000 is_approved checks complete under 1 second.""" |
| 24 | |
| 25 | ds_store = DatasetStore() |
| 26 | start = time.monotonic() |
| 27 | for _ in range(10_000): |
| 28 | ds_store.is_approved("fixture:synthetic-tiny-v1") |
| 29 | elapsed = time.monotonic() - start |
| 30 | self.assertLess( |
| 31 | elapsed, 1.0, msg=f"10 000 is_approved calls took {elapsed:.3f}s" |
| 32 | ) |
| 33 | |
| 34 | def test_performance_t3_queue_state_is_fast_under_large_backlog(self) -> None: |
| 35 | """queue_state call with 200 completed jobs finishes under 0.5 seconds.""" |
| 36 | |
| 37 | service = TrainingApiService(TrainingJobStore(queue_limit=256)) |
| 38 | for index in range(200): |
| 39 | service.create_training_job(valid_payload(f"perf-backlog-{index}")) |
| 40 | |
| 41 | start = time.monotonic() |
| 42 | for _ in range(500): |
| 43 | service.get_queue_state() |
| 44 | elapsed = time.monotonic() - start |
| 45 | self.assertLess( |
| 46 | elapsed, 0.5, msg=f"500 queue_state calls took {elapsed:.3f}s" |
| 47 | ) |
| 48 | |
| 49 | def test_performance_t3_bulk_dataset_register_review_is_bounded(self) -> None: |
| 50 | """Registering and reviewing 500 datasets completes under 3 seconds.""" |
| 51 | |
| 52 | ds_store = DatasetStore() |
| 53 | dataset_ids = [f"perf-ds-{i:05d}" for i in range(500)] |
| 54 | start = time.monotonic() |
| 55 | for did in dataset_ids: |
| 56 | ds_store.register(did) |
| 57 | ds_store.submit_for_review(did) |
| 58 | ds_store.approve(did) |
| 59 | elapsed = time.monotonic() - start |
| 60 | self.assertLess( |
| 61 | elapsed, 3.0, msg=f"500 register+review cycles took {elapsed:.3f}s" |
| 62 | ) |
| 63 | for did in dataset_ids: |
| 64 | self.assertTrue(ds_store.is_approved(did)) |
| 65 | |
| 66 | def test_performance_t3_rejected_dataset_lookup_is_bounded(self) -> None: |
| 67 | """1 000 is_approved calls on a rejected dataset finish under 0.2 seconds.""" |
| 68 | |
| 69 | ds_store = DatasetStore() |
| 70 | ds_store.register_shape( |
| 71 | "perf-rejected-ds", |
| 72 | default_dataset_shape(RejectionReasonCode.POLICY_VIOLATION), |
| 73 | ) |
| 74 | ds_store.submit_for_review("perf-rejected-ds") |
| 75 | ds_store.reject("perf-rejected-ds", RejectionReasonCode.POLICY_VIOLATION) |
| 76 | |
| 77 | start = time.monotonic() |
| 78 | for _ in range(1_000): |
| 79 | ds_store.is_approved("perf-rejected-ds") |
| 80 | elapsed = time.monotonic() - start |
| 81 | self.assertLess( |
| 82 | elapsed, 0.2, msg=f"1 000 rejected checks took {elapsed:.3f}s" |
| 83 | ) |
| 84 | |
| 85 | |
| 86 | if __name__ == "__main__": |
| 87 | unittest.main() |
File History
1 commit
sha256:ca1d0e687bff8686b37126eb8e4fb6d38b40e189352a4920d66ae89c7274e340
Add T4 job cancellation retry and validation
Human
minor
⚠
41 days ago