import importlib.util import sys from pathlib import Path import pytest import torch from slime.utils.trace_utils import build_sglang_meta_trace_attrs, trace_span from slime.utils.types import Sample def _load_trace_timeline_viewer_module(): module_path = Path(__file__).resolve().parents[2] / "tools" / "trace_timeline_viewer.py" module_name = "test_trace_timeline_viewer_module" sys.modules.pop(module_name, None) spec = importlib.util.spec_from_file_location(module_name, module_path) module = importlib.util.module_from_spec(spec) assert spec is not None assert spec.loader is not None sys.modules[module_name] = module spec.loader.exec_module(module) return module @pytest.mark.unit def test_build_sglang_meta_trace_attrs_keeps_standard_and_pd_fields(): meta = { "prompt_tokens": 12, "completion_tokens": 7, "cached_tokens": 3, "pd_prefill_forward_duration": 0.125, "pd_decode_transfer_duration": None, "finish_reason": {"type": "stop"}, "unused_field": "ignored", } assert build_sglang_meta_trace_attrs(meta) == { "prompt_tokens": 12, "completion_tokens": 7, "cached_tokens": 3, "pd_prefill_forward_duration": 0.125, "finish_reason": "stop", } @pytest.mark.unit def test_trace_timeline_viewer_omits_virtual_pd_lanes_without_pd_attrs(tmp_path: Path): viewer = _load_trace_timeline_viewer_module() sample = Sample(index=0, prompt="hello") with trace_span(sample, "sglang_generate", attrs={"max_new_tokens": 8}) as span: span.update( build_sglang_meta_trace_attrs( { "prompt_tokens": 4, "completion_tokens": 2, "cached_tokens": 1, "finish_reason": {"type": "stop"}, } ) ) pt_path = tmp_path / "rollout.pt" torch.save({"samples": [sample]}, pt_path) cache = viewer._build_cache_data(pt_path) assert cache["sample_count"] == 1 row = cache["rows"][0] assert row["lane_count"] == 1 assert row["item_count"] == 1 assert row["closed_span_count"] == 1 item = row["items"][0] assert item["name"] == "sglang_generate" assert item["attrs"]["end_attrs"] == { "prompt_tokens": 4, "completion_tokens": 2, "cached_tokens": 1, "finish_reason": "stop", } assert "[P]" not in item["name"] assert "[D]" not in item["name"]