All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.opentelemetry.instrumentation.test.asserts.InMemoryExporterAssert.groovy Maven / Gradle / Ivy

/*
 * Copyright The OpenTelemetry Authors
 * SPDX-License-Identifier: Apache-2.0
 */

package io.opentelemetry.instrumentation.test.asserts

import groovy.transform.stc.ClosureParams
import groovy.transform.stc.SimpleType
import io.opentelemetry.api.trace.SpanKind
import io.opentelemetry.instrumentation.testing.util.TelemetryDataUtil
import io.opentelemetry.sdk.trace.data.SpanData
import org.codehaus.groovy.runtime.powerassert.PowerAssertionError
import org.spockframework.runtime.Condition
import org.spockframework.runtime.ConditionNotSatisfiedError
import org.spockframework.runtime.model.TextPosition

import java.util.function.Supplier

import static TraceAssert.assertTrace

class InMemoryExporterAssert {
  private final List> traces
  private final Supplier> spanSupplier

  private final Set assertedIndexes = new HashSet<>()

  private InMemoryExporterAssert(List> traces, Supplier> spanSupplier) {
    this.traces = traces
    this.spanSupplier = spanSupplier
  }

  static void assertTraces(Supplier> spanSupplier, int expectedSize,
                           @ClosureParams(value = SimpleType, options = ['io.opentelemetry.instrumentation.test.asserts.ListWriterAssert'])
                           @DelegatesTo(value = InMemoryExporterAssert, strategy = Closure.DELEGATE_FIRST) Closure spec,
                           boolean verifyScopeVersion) {
    try {
      def traces = TelemetryDataUtil.waitForTraces(spanSupplier, expectedSize)
      assert traces.size() == expectedSize
      if (verifyScopeVersion) {
        TelemetryDataUtil.assertScopeVersion(traces)
      }
      def asserter = new InMemoryExporterAssert(traces, spanSupplier)
      def clone = (Closure) spec.clone()
      clone.delegate = asserter
      clone.resolveStrategy = Closure.DELEGATE_FIRST
      clone(asserter)
      asserter.assertTracesAllVerified()
    } catch (PowerAssertionError e) {
      def stackLine = null
      for (int i = 0; i < e.stackTrace.length; i++) {
        def className = e.stackTrace[i].className
        def skip = className.startsWith("org.codehaus.groovy.") ||
          className.startsWith("io.opentelemetry.instrumentation.test.") ||
          className.startsWith("sun.reflect.") ||
          className.startsWith("groovy.lang.") ||
          className.startsWith("java.lang.")
        if (skip) {
          continue
        }
        stackLine = e.stackTrace[i]
        break
      }
      def condition = new Condition(null, "$stackLine", TextPosition.create(stackLine == null ? 0 : stackLine.lineNumber, 0), e.message, null, e)
      throw new ConditionNotSatisfiedError(condition, e)
    }
  }

  List> getTraces() {
    return traces
  }

  void trace(int index, int expectedSize,
             @ClosureParams(value = SimpleType, options = ['io.opentelemetry.instrumentation.test.asserts.TraceAssert'])
             @DelegatesTo(value = TraceAssert, strategy = Closure.DELEGATE_FIRST) Closure spec) {
    if (index >= traces.size()) {
      throw new ArrayIndexOutOfBoundsException(index)
    }
    assertedIndexes.add(index)
    assertTrace(spanSupplier, traces[index][0].traceId, expectedSize, spec)
  }

  static Comparator> orderByRootSpanName(String... names) {
    return TelemetryDataUtil.orderByRootSpanName(names)
  }

  static Comparator> orderByRootSpanKind(SpanKind... spanKinds) {
    return TelemetryDataUtil.orderByRootSpanKind(spanKinds)
  }

  void assertTracesAllVerified() {
    assert assertedIndexes.size() == traces.size()
  }

  void sortSpansByStartTime() {
    traces.each {
      it.sort { a, b ->
        return a.startEpochNanos <=> b.startEpochNanos
      }
    }
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy