1import { describe, it } from "@effect/vitest"
2import { strictEqual } from "@effect/vitest/utils"
3import { Option } from "effect"
4import { Headers, HttpTraceContext } from "effect/http"
5
6const traceId = "80f198ee56343ba864fe8b2a57d3eff7"
7const spanId = "e457b5a2e4d86bd1"
8
9const assertSampled = (headers: Record<string, string>, sampled: boolean) => {
10 const span = Option.getOrThrow(HttpTraceContext.fromHeaders(Headers.fromInput(headers)))
11 strictEqual(span.traceId, traceId)
12 strictEqual(span.spanId, spanId)
13 strictEqual(span.sampled, sampled)
14}
15
16describe("HttpTraceContext", () => {
17 describe("fromHeaders", () => {
18 it("accepts single-header B3 debug sampling", () => {
19 assertSampled({ b3: `${traceId}-${spanId}-d` }, true)
20 })
21
22 it("accepts legacy X-B3-Sampled: true", () => {
23 assertSampled({ "X-B3-TraceId": traceId, "X-B3-SpanId": spanId, "X-B3-Sampled": "true" }, true)
24 })
25
26 it("lets X-B3-Flags debug override X-B3-Sampled: 0", () => {
27 assertSampled({
28 "X-B3-TraceId": traceId,
29 "X-B3-SpanId": spanId,
30 "X-B3-Sampled": "0",
31 "X-B3-Flags": "1"
32 }, true)
33 })
34
35 it("rejects an all-zero W3C trace-id", () => {
36 strictEqual(
37 Option.isNone(HttpTraceContext.fromHeaders(Headers.fromInput({
38 traceparent: `00-${"0".repeat(32)}-${spanId}-01`
39 }))),
40 true
41 )
42 })
43
44 it("rejects an all-zero W3C parent-id", () => {
45 strictEqual(
46 Option.isNone(HttpTraceContext.fromHeaders(Headers.fromInput({
47 traceparent: `00-${traceId}-${"0".repeat(16)}-01`
48 }))),
49 true
50 )
51 })
52 })
53})