Skip to content

Commit e74d357

Browse files
committed
Tests for fixing unique span timestamps
1 parent 16f222b commit e74d357

File tree

1 file changed

+86
-0
lines changed

1 file changed

+86
-0
lines changed

tests/test_logger_timestamps.py

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
from datetime import datetime, timedelta, timezone
2+
from unittest.mock import Mock, patch
3+
4+
from galileo.logger import GalileoLogger
5+
from tests.testutils.setup import setup_mock_logstreams_client, setup_mock_projects_client
6+
7+
8+
@patch("galileo.logger.logger.LogStreams")
9+
@patch("galileo.logger.logger.Projects")
10+
def test_rapid_span_creation_ensures_uniqueness(mock_projects_client: Mock, mock_logstreams_client: Mock):
11+
"""Tests that creating spans in a tight loop results in unique, monotonically increasing timestamps."""
12+
setup_mock_projects_client(mock_projects_client)
13+
setup_mock_logstreams_client(mock_logstreams_client)
14+
logger = GalileoLogger(project="test", log_stream="test")
15+
logger.start_trace(input="test")
16+
for _ in range(5):
17+
logger.add_llm_span(input="test", output="test", model="test")
18+
logger.conclude(output="test")
19+
20+
trace = logger.traces[0]
21+
timestamps = [span.created_at for span in trace.spans]
22+
assert len(timestamps) == len(set(timestamps)), "Timestamps should be unique"
23+
assert timestamps == sorted(timestamps), "Timestamps should be monotonically increasing"
24+
25+
26+
@patch("galileo.logger.logger.LogStreams")
27+
@patch("galileo.logger.logger.Projects")
28+
def test_user_provided_timestamps_are_respected(mock_projects_client: Mock, mock_logstreams_client: Mock):
29+
"""Tests that timestamps provided by the user are not modified."""
30+
setup_mock_projects_client(mock_projects_client)
31+
setup_mock_logstreams_client(mock_logstreams_client)
32+
logger = GalileoLogger(project="test", log_stream="test")
33+
logger.start_trace(input="test")
34+
35+
# Create timestamps in reverse order to test that the logger doesn't alter them
36+
now = datetime.now(timezone.utc)
37+
timestamps = [now - timedelta(seconds=i) for i in range(5)]
38+
39+
for ts in timestamps:
40+
logger.add_llm_span(input="test", output="test", model="test", created_at=ts)
41+
42+
logger.conclude(output="test")
43+
44+
trace = logger.traces[0]
45+
span_timestamps = [span.created_at for span in trace.spans]
46+
assert span_timestamps == timestamps, "User-provided timestamps should be respected"
47+
48+
49+
@patch("galileo.logger.logger.LogStreams")
50+
@patch("galileo.logger.logger.Projects")
51+
def test_mixed_default_and_user_timestamps(mock_projects_client: Mock, mock_logstreams_client: Mock):
52+
"""Tests that the internal state for default timestamp generation is not affected by user-provided timestamps."""
53+
setup_mock_projects_client(mock_projects_client)
54+
setup_mock_logstreams_client(mock_logstreams_client)
55+
logger = GalileoLogger(project="test", log_stream="test")
56+
logger.start_trace(input="test")
57+
58+
# 1. Add a default span
59+
logger.add_llm_span(input="test", output="test", model="test")
60+
61+
# 2. Add a user-provided span with a timestamp in the past
62+
past_timestamp = datetime.now(timezone.utc) - timedelta(seconds=10)
63+
logger.add_llm_span(input="test", output="test", model="test", created_at=past_timestamp)
64+
65+
# 3. Add a user-provided span with a timestamp in the future
66+
future_timestamp = datetime.now(timezone.utc) + timedelta(seconds=10)
67+
logger.add_llm_span(input="test", output="test", model="test", created_at=future_timestamp)
68+
69+
# 4. Add a final default span
70+
logger.add_llm_span(input="test", output="test", model="test")
71+
72+
logger.conclude(output="test")
73+
trace = logger.traces[0]
74+
75+
default_span1_ts = trace.spans[0].created_at
76+
past_user_span_ts = trace.spans[1].created_at
77+
future_user_span_ts = trace.spans[2].created_at
78+
default_span2_ts = trace.spans[3].created_at
79+
80+
assert past_user_span_ts == past_timestamp, "User-provided past timestamp should be respected"
81+
assert future_user_span_ts == future_timestamp, "User-provided future timestamp should be respected"
82+
assert default_span2_ts > default_span1_ts, "Second default timestamp should be greater than the first"
83+
assert default_span2_ts > past_user_span_ts, "Default timestamps are separate from past user-provided timestamps"
84+
assert default_span2_ts < future_user_span_ts, (
85+
"Default timestamps are separate from future user-provided timestamps"
86+
)

0 commit comments

Comments
 (0)