Skip to content

Commit

Permalink
feat: add tests for undefined behavior
Browse files Browse the repository at this point in the history
  • Loading branch information
NiklasKoehneckeAA committed May 21, 2024
1 parent 733164f commit 875b1df
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 24 deletions.
9 changes: 2 additions & 7 deletions src/intelligence_layer/core/tracer/composite_tracer.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,7 @@ def span(
timestamp: Optional[datetime] = None,
) -> "CompositeSpan[Span]":
timestamp = timestamp or utc_now()
return CompositeSpan(
[tracer.span(name, timestamp) for tracer in self.tracers]
)
return CompositeSpan([tracer.span(name, timestamp) for tracer in self.tracers])

def task_span(
self,
Expand All @@ -56,10 +54,7 @@ def task_span(
) -> "CompositeTaskSpan":
timestamp = timestamp or utc_now()
return CompositeTaskSpan(
[
tracer.task_span(task_name, input, timestamp)
for tracer in self.tracers
]
[tracer.task_span(task_name, input, timestamp) for tracer in self.tracers]
)

def export_for_viewing(self) -> Sequence[ExportedSpan]:
Expand Down
8 changes: 8 additions & 0 deletions src/intelligence_layer/core/tracer/tracer.py
Original file line number Diff line number Diff line change
Expand Up @@ -212,8 +212,11 @@ def __init__(self, context: Optional[Context] = None):
trace_id = context.trace_id
self.context = Context(trace_id=trace_id, span_id=span_id)
self.status_code = SpanStatus.OK
self._closed = False

def __enter__(self) -> Self:
if self._closed:
raise ValueError("Spans cannot be opened once they have been close.")
return self

@abstractmethod
Expand All @@ -228,6 +231,8 @@ def log(
By default, the `Input` and `Output` of each :class:`Task` are logged automatically, but
you can log anything else that seems relevant to understanding the process of a given task.
Logging to closed spans is undefined behavior.
Args:
message: A description of the value you are logging, such as the step in the task this
is related to.
Expand All @@ -242,6 +247,8 @@ def end(self, timestamp: Optional[datetime] = None) -> None:
"""Marks the Span as done, with the end time of the span. The Span should be regarded
as complete, and no further logging should happen with it.
Ending a closed span in undefined behavior.
Args:
timestamp: Optional override of the timestamp, otherwise should be set to now.
"""
Expand Down Expand Up @@ -272,6 +279,7 @@ def __exit__(
self.log(error_value.message, error_value)
self.status_code = SpanStatus.ERROR
self.end()
self._closed = True


class TaskSpan(Span):
Expand Down
4 changes: 1 addition & 3 deletions tests/core/tracer/test_composite_tracer.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
from intelligence_layer.core import (
CompositeTracer,
FileTracer,
InMemorySpan,
InMemoryTracer,
Task,
)
Expand All @@ -18,4 +16,4 @@ def test_composite_tracer(test_task: Task[str, str]) -> None:
assert trace_1.attributes == trace_2.attributes
assert trace_1.status == trace_2.status
assert trace_1.context.trace_id != trace_2.context.trace_id
assert trace_1.context.span_id != trace_2.context.span_id
assert trace_1.context.span_id != trace_2.context.span_id
62 changes: 48 additions & 14 deletions tests/core/tracer/test_tracer.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
import pytest
from pytest import fixture
from pydantic import BaseModel
from pytest import fixture

from intelligence_layer.core import CompositeTracer
from intelligence_layer.core import FileTracer
from intelligence_layer.core import InMemoryTracer
from intelligence_layer.core import CompositeTracer, FileTracer, InMemoryTracer
from intelligence_layer.core.tracer.tracer import (
SpanStatus,
SpanType,
Expand All @@ -20,12 +18,10 @@ class DummyObject(BaseModel):


@fixture
def composite_tracer(
in_memory_tracer: InMemoryTracer,
file_tracer: FileTracer
):
def composite_tracer(in_memory_tracer: InMemoryTracer, file_tracer: FileTracer):
return CompositeTracer(in_memory_tracer, file_tracer)


tracer_fixtures = ["in_memory_tracer", "file_tracer", "composite_tracer"]


Expand Down Expand Up @@ -181,7 +177,7 @@ def test_tracer_exports_part_of_a_trace_correctly(
with tracer.span("name") as root_span:
child_span = root_span.span("name-2")
child_span.log("test_message", "test_body")

unified_format = child_span.export_for_viewing()

assert len(unified_format) == 2
Expand All @@ -193,6 +189,41 @@ def test_tracer_exports_part_of_a_trace_correctly(
assert span_1.context.trace_id != span_2.context.trace_id


@pytest.mark.skip("Not yet implemented")
@pytest.mark.parametrize(
"tracer_fixture",
tracer_fixtures,
)
def test_spans_cannot_be_closed_twice(
tracer_fixture: str,
request: pytest.FixtureRequest,
) -> None:
tracer: Tracer = request.getfixturevalue(tracer_fixture)

span = tracer.span("name")
span.end()
span.end()


@pytest.mark.parametrize(
"tracer_fixture",
tracer_fixtures,
)
def test_spans_cannot_be_used_as_context_twice(
tracer_fixture: str,
request: pytest.FixtureRequest,
) -> None:
tracer: Tracer = request.getfixturevalue(tracer_fixture)

span = tracer.span("name")
with span:
pass
with pytest.raises(Exception):
with span:
pass


@pytest.mark.skip("Not yet implemented")
@pytest.mark.parametrize(
"tracer_fixture",
tracer_fixtures,
Expand All @@ -203,15 +234,18 @@ def test_tracer_can_not_log_on_closed_span(
) -> None:
tracer: Tracer = request.getfixturevalue(tracer_fixture)

span = tracer.span("name")
span = tracer.span("name")
# ok
span.log("test_message", "test_body")
span.end()
# not ok
with pytest.raises(Exception):
span.log("test_message", "test_body")

span = tracer.span("name")
# ok
with span:
span.log("test_message", "test_body")
# not ok
with pytest.raises(Exception):
span.log("test_message", "test_body")




0 comments on commit 875b1df

Please sign in to comment.