| ... | ... | @@ -4,6 +4,7 @@ import * as Effect from "effect/Effect"; |
| 4 | 4 | import * as Layer from "effect/Layer"; |
| 5 | 5 | import * as Redacted from "effect/Redacted"; |
| 6 | 6 | import * as TestClock from "effect/testing/TestClock"; |
| 7 | import * as Tracer from "effect/Tracer"; |
| 7 | 8 | |
| 8 | 9 | import * as RelayConfiguration from "../Config.ts"; |
| 9 | 10 | import * as ManagedEndpointAllocations from "./ManagedEndpointAllocations.ts"; |
| ... | ... | @@ -574,6 +575,54 @@ describe("ManagedEndpointReaper", () => { |
| 574 | 575 | }).pipe(Effect.provide(state.layer)); |
| 575 | 576 | }); |
| 576 | 577 | |
| 578 | it.effect("records dry-run counters on the sweep span", () => { |
| 579 | const spans: Array<Tracer.NativeSpan> = []; |
| 580 | const tracer = Tracer.make({ |
| 581 | span: (options) => { |
| 582 | const span = new Tracer.NativeSpan(options); |
| 583 | spans.push(span); |
| 584 | return span; |
| 585 | }, |
| 586 | }); |
| 587 | const expired = [ |
| 588 | tunnel({ |
| 589 | id: "recoverable", |
| 590 | suffix: "aaaaaaaaaaaaaaaa", |
| 591 | status: "down", |
| 592 | timestamp: "2026-08-25T11:00:00.000Z", |
| 593 | }), |
| 594 | tunnel({ |
| 595 | id: "legacy", |
| 596 | suffix: "bbbbbbbbbbbbbbbb", |
| 597 | status: "down", |
| 598 | timestamp: "2026-08-25T11:00:00.000Z", |
| 599 | }), |
| 600 | ]; |
| 601 | const state = harness({ |
| 602 | cleanupMode: "dry-run", |
| 603 | tunnels: expired, |
| 604 | allocations: [ |
| 605 | allocation({ tunnelId: "recoverable", recoveryEnabled: true }), |
| 606 | allocation({ tunnelId: "legacy", recoveryEnabled: false }), |
| 607 | ], |
| 608 | }); |
| 609 | |
| 610 | return Effect.gen(function* () { |
| 611 | yield* TestClock.setTime(NOW_MILLIS); |
| 612 | const reaper = yield* ManagedEndpointReaper.ManagedEndpointReaper; |
| 613 | yield* reaper.sweep; |
| 614 | const sweepSpan = spans.find((span) => span.name === "relay.managed_endpoint_reaper.sweep"); |
| 615 | expect(Object.fromEntries(sweepSpan?.attributes ?? [])).toMatchObject({ |
| 616 | "relay.managed_endpoint_reaper.mode": "dry-run", |
| 617 | "relay.managed_endpoint_reaper.scanned": 2, |
| 618 | "relay.managed_endpoint_reaper.wouldDelete": 1, |
| 619 | "relay.managed_endpoint_reaper.skippedLegacy": 1, |
| 620 | "relay.managed_endpoint_reaper.deleted": 0, |
| 621 | }); |
| 622 | expect(state.deleted).toEqual([]); |
| 623 | }).pipe(Effect.provide(state.layer), Effect.withTracer(tracer)); |
| 624 | }); |
| 625 | |
| 577 | 626 | it.effect("does no Cloudflare work while cleanup is off", () => { |
| 578 | 627 | const state = harness({ |
| 579 | 628 | cleanupMode: "off", |