OpenPay (1 crate, ~2940 LOC, 40 tests)
op-statements Statement generation + reconciliation + fee accounting.
Render targets: PDF (template), CSV, JSON, 94-char
NACHA fixed-width. ISO 20022 camt.053 with full
BkToCstmrStmt envelope (GrpHdr/Stmt/Bal/Ntry). BAI2
with 01/02/03/16/49/98/99 records. MT940/MT942
SWIFT with :20:/:25:/:28C:/:60F:/:61:/:86:/:62F:
+ :90C:/:90D: counters. FeeBucket (interchange/scheme/
acquirer/fx/settlement-network/bnpl) + FeeSchedule
with bps + flat rules. Cadence (daily/weekly/monthly/
custom). Two-tier Reconciler (external_id → window
heuristic).
Smart Byte (1 crate, 3032 LOC, 39 tests)
smart-byte-activitypub ActivityPub W3C Rec (2018). AS2 vocab + Public
addressing; Actor (Person/Application/Group/
Organization/Service) with publicKey + shared-inbox;
Object (Note/Article/Image/Video/Tombstone) with
Mastodon extensions (sensitive, CW summary,
conversation, blurhash); 12 Activity types
(Create/Update/Delete/Follow/Accept/Reject/Announce/
Like/Undo/Move/Block/Flag) with side-effect rules;
OrderedCollection + Page; Webfinger (RFC 7033);
HTTP Signatures (cavage draft-12 + RFC 9421);
SHA-256 Digest; Ed25519 sign/verify.
EOC (1 crate, 2759 LOC, 20 tests)
eoc-observability OpenTelemetry-compatible tracing + metrics + logs.
W3C tracecontext + baggage. Span / SpanKind / Status.
Samplers: AlwaysOn/Off/RatioBased/ParentBased. Sync
BatchSpanProcessor + Exporter trait. Counter / Gauge /
Histogram. Prometheus text exposition (HELP/TYPE/
_bucket/_sum/_count/+Inf). StatsD / DogStatsD lines.
GenAI semconv (gen_ai.{operation,system,request.*,
response.*,usage.*}) + EOC extensions (eoc.joules.*,
eoc.co2e_grams, eoc.cost.usd). USD + gCO2e attribution
with PUE. LangSmith + LangFuse export adapters.
Co-Authored-By: Claude Opus 4.7 <[email protected]>
94 lines
2.4 KiB
Rust
94 lines
2.4 KiB
Rust
//! Ratio sampler determinism + parent-based fallback.
|
|
|
|
use eoc_observability::{
|
|
AlwaysOffSampler, AlwaysOnSampler, ParentBased, Sampler, SamplingDecision, SpanContext,
|
|
SpanId, TraceFlags, TraceIdRatioBased, TraceId,
|
|
};
|
|
|
|
#[test]
|
|
fn ratio_zero_drops_all() {
|
|
let s = TraceIdRatioBased::new(0.0);
|
|
let tid = TraceId([0xff; 16]);
|
|
assert_eq!(
|
|
s.should_sample(None, &tid, "op"),
|
|
SamplingDecision::Drop
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn ratio_one_keeps_all() {
|
|
let s = TraceIdRatioBased::new(1.0);
|
|
let tid = TraceId([0; 16]);
|
|
assert_eq!(
|
|
s.should_sample(None, &tid, "op"),
|
|
SamplingDecision::RecordAndSample
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn ratio_half_splits_on_high_bit() {
|
|
let s = TraceIdRatioBased::new(0.5);
|
|
// Threshold = u64::MAX / 2 (approximately). A trace_id whose high
|
|
// 8 bytes start with 0x00 must pass; one starting with 0xff must drop.
|
|
let low = TraceId([0x00; 16]);
|
|
let high = {
|
|
let mut b = [0u8; 16];
|
|
b[0] = 0xff;
|
|
TraceId(b)
|
|
};
|
|
assert_eq!(
|
|
s.should_sample(None, &low, "op"),
|
|
SamplingDecision::RecordAndSample
|
|
);
|
|
assert_eq!(
|
|
s.should_sample(None, &high, "op"),
|
|
SamplingDecision::Drop
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn ratio_is_clamped() {
|
|
let s = TraceIdRatioBased::new(-0.5);
|
|
assert_eq!(s.ratio(), 0.0);
|
|
let s = TraceIdRatioBased::new(2.0);
|
|
assert_eq!(s.ratio(), 1.0);
|
|
}
|
|
|
|
#[test]
|
|
fn parent_based_follows_sampled_parent() {
|
|
let pb = ParentBased::new(Box::new(AlwaysOffSampler));
|
|
let parent = SpanContext::new(
|
|
TraceId([1; 16]),
|
|
SpanId([2; 8]),
|
|
TraceFlags::SAMPLED,
|
|
);
|
|
assert_eq!(
|
|
pb.should_sample(Some(&parent), &parent.trace_id, "op"),
|
|
SamplingDecision::RecordAndSample
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn parent_based_follows_unsampled_parent() {
|
|
let pb = ParentBased::new(Box::new(AlwaysOnSampler));
|
|
let parent = SpanContext::new(
|
|
TraceId([1; 16]),
|
|
SpanId([2; 8]),
|
|
TraceFlags::default(), // not sampled
|
|
);
|
|
assert_eq!(
|
|
pb.should_sample(Some(&parent), &parent.trace_id, "op"),
|
|
SamplingDecision::Drop
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn parent_based_defers_to_root_when_no_parent() {
|
|
let pb = ParentBased::new(Box::new(AlwaysOnSampler));
|
|
let tid = TraceId([0; 16]);
|
|
// Even invalid trace_id with no parent should defer to root.
|
|
assert_eq!(
|
|
pb.should_sample(None, &tid, "op"),
|
|
SamplingDecision::RecordAndSample
|
|
);
|
|
}
|