fun testEndUnfinishedSpans_HandlesDeepHierarchy()

in agents/agents-features/agents-features-opentelemetry/src/jvmTest/kotlin/ai/koog/agents/features/opentelemetry/feature/OpenTelemetryFeatureTest.kt [165:228]


    fun testEndUnfinishedSpans_HandlesDeepHierarchy() {
        val spanCollector = SpanCollector()
        val tracer = MockTracer()
        val openTelemetry = OpenTelemetry.Feature

        // Create a deep hierarchy: root -> level1 -> level2 -> level3
        val rootSpan = GenAIAgentSpanBuilder(
            spanType = SpanType.CREATE_AGENT,
            parentSpan = null,
            id = "root",
            name = "root-name",
            kind = SpanKind.INTERNAL,
        ).buildAndStart(tracer)
        val rootPath = AgentExecutionInfo(null, "root")
        spanCollector.collectSpan(rootSpan, rootPath)

        val level1Span = GenAIAgentSpanBuilder(
            spanType = SpanType.INVOKE_AGENT,
            parentSpan = rootSpan,
            id = "level1",
            name = "level1-name",
            kind = SpanKind.INTERNAL,
        ).buildAndStart(tracer)
        val level1Path = AgentExecutionInfo(rootPath, "level1")
        spanCollector.collectSpan(level1Span, level1Path)

        val level2Span = GenAIAgentSpanBuilder(
            spanType = SpanType.NODE,
            parentSpan = level1Span,
            id = "level2",
            name = "level2-name",
            kind = SpanKind.INTERNAL,
        ).buildAndStart(tracer)
        val level2Path = AgentExecutionInfo(level1Path, "level2")
        spanCollector.collectSpan(level2Span, level2Path)

        val level3Span = GenAIAgentSpanBuilder(
            spanType = SpanType.EXECUTE_TOOL,
            parentSpan = level2Span,
            id = "level3",
            name = "level3-name",
            kind = SpanKind.INTERNAL,
        ).buildAndStart(tracer)
        val level3Path = AgentExecutionInfo(level2Path, "level3")
        spanCollector.collectSpan(level3Span, level3Path)

        assertEquals(4, spanCollector.activeSpansCount)

        // End all spans - should handle hierarchy correctly (leaf to root)
        openTelemetry.endUnfinishedSpans(spanCollector, verbose = false)

        // Verify all spans are ended
        assertEquals(0, spanCollector.activeSpansCount)

        val mockRootSpan = rootSpan.span as MockSpan
        val mockLevel1Span = level1Span.span as MockSpan
        val mockLevel2Span = level2Span.span as MockSpan
        val mockLevel3Span = level3Span.span as MockSpan

        assertTrue(mockRootSpan.isEnded)
        assertTrue(mockLevel1Span.isEnded)
        assertTrue(mockLevel2Span.isEnded)
        assertTrue(mockLevel3Span.isEnded)
    }