mirror of
https://github.com/XRPLF/rippled.git
synced 2026-09-26 23:19:07 +00:00
Merge branch 'pratik/otel-phase9-metric-gap-fill' into pratik/otel-phase10-workload-validation
This commit is contained in:
@@ -132,7 +132,7 @@ private:
|
||||
* would otherwise never be sent and would never exist downstream. Absent and
|
||||
* zero must not look the same to an operator.
|
||||
*/
|
||||
TEST(StatsDCollector, UntouchedGaugePublishesInitialZero)
|
||||
TEST(StatsDCollector, untouched_gauge_publishes_initial_zero)
|
||||
{
|
||||
LoopbackStatsDServer server;
|
||||
auto const address = ip::Endpoint::fromString("127.0.0.1:" + std::to_string(server.port()));
|
||||
@@ -159,7 +159,7 @@ TEST(StatsDCollector, UntouchedGaugePublishesInitialZero)
|
||||
* comes along as a positive control. One flush tick serves both metrics, so a
|
||||
* counter line would have to travel beside the gauge's.
|
||||
*/
|
||||
TEST(StatsDCollector, UntouchedCounterPublishesNothing)
|
||||
TEST(StatsDCollector, untouched_counter_publishes_nothing)
|
||||
{
|
||||
LoopbackStatsDServer server;
|
||||
auto const address = ip::Endpoint::fromString("127.0.0.1:" + std::to_string(server.port()));
|
||||
|
||||
@@ -64,7 +64,7 @@ public:
|
||||
// The unit code is a contract with the collector's Prometheus exporter: it
|
||||
// derives the exported name suffix from this string. Assert the exact codes,
|
||||
// not merely that they differ.
|
||||
TEST(InsightUnit, otelCodeIsTheUcumCodeForEachUnit)
|
||||
TEST(InsightUnit, otel_code_is_the_ucum_code_for_each_unit)
|
||||
{
|
||||
EXPECT_STREQ(otelUnitCode(Unit::Millis), "ms");
|
||||
EXPECT_STREQ(otelUnitCode(Unit::Bytes), "By");
|
||||
@@ -72,13 +72,13 @@ TEST(InsightUnit, otelCodeIsTheUcumCodeForEachUnit)
|
||||
|
||||
// The description is what an operator reads in the metric catalogue, so a
|
||||
// byte-valued instrument must not describe itself as a duration.
|
||||
TEST(InsightUnit, descriptionMatchesWhatTheUnitActuallyMeasures)
|
||||
TEST(InsightUnit, description_matches_what_the_unit_actually_measures)
|
||||
{
|
||||
EXPECT_STREQ(otelUnitDescription(Unit::Millis), "Duration in ms");
|
||||
EXPECT_STREQ(otelUnitDescription(Unit::Bytes), "Size in bytes");
|
||||
}
|
||||
|
||||
TEST(InsightUnit, defaultEventUnitIsMillisForBackwardCompatibility)
|
||||
TEST(InsightUnit, default_event_unit_is_millis_for_backward_compatibility)
|
||||
{
|
||||
// Every pre-existing makeEvent(name) call site records a duration, so the
|
||||
// one-argument overload must keep meaning milliseconds.
|
||||
@@ -88,7 +88,7 @@ TEST(InsightUnit, defaultEventUnitIsMillisForBackwardCompatibility)
|
||||
EXPECT_EQ(event.impl()->unit(), Unit::Millis);
|
||||
}
|
||||
|
||||
TEST(InsightUnit, makeEventCarriesTheRequestedUnitToTheImpl)
|
||||
TEST(InsightUnit, make_event_carries_the_requested_unit_to_the_impl)
|
||||
{
|
||||
auto const collector = NullCollector::make();
|
||||
auto const event = collector->makeEvent("size", Unit::Bytes);
|
||||
@@ -96,7 +96,7 @@ TEST(InsightUnit, makeEventCarriesTheRequestedUnitToTheImpl)
|
||||
EXPECT_EQ(event.impl()->unit(), Unit::Bytes);
|
||||
}
|
||||
|
||||
TEST(InsightUnit, prefixedMakeEventCarriesTheUnit)
|
||||
TEST(InsightUnit, prefixed_make_event_carries_the_unit)
|
||||
{
|
||||
auto const collector = NullCollector::make();
|
||||
auto const event = collector->makeEvent("rpc", "size", Unit::Bytes);
|
||||
@@ -104,7 +104,7 @@ TEST(InsightUnit, prefixedMakeEventCarriesTheUnit)
|
||||
EXPECT_EQ(event.impl()->unit(), Unit::Bytes);
|
||||
}
|
||||
|
||||
TEST(InsightUnit, groupWrapperForwardsTheUnitAlongWithThePrefix)
|
||||
TEST(InsightUnit, group_wrapper_forwards_the_unit_along_with_the_prefix)
|
||||
{
|
||||
// ServerHandler creates its events through a Group, not through the
|
||||
// collector directly. If the group's makeEvent override forwards only the
|
||||
@@ -117,7 +117,7 @@ TEST(InsightUnit, groupWrapperForwardsTheUnitAlongWithThePrefix)
|
||||
EXPECT_EQ(event.impl()->unit(), Unit::Bytes);
|
||||
}
|
||||
|
||||
TEST(InsightUnit, groupWrapperStillDefaultsToMillis)
|
||||
TEST(InsightUnit, group_wrapper_still_defaults_to_millis)
|
||||
{
|
||||
auto const collector = NullCollector::make();
|
||||
auto const groups = makeGroups(collector);
|
||||
@@ -126,7 +126,7 @@ TEST(InsightUnit, groupWrapperStillDefaultsToMillis)
|
||||
EXPECT_EQ(event.impl()->unit(), Unit::Millis);
|
||||
}
|
||||
|
||||
TEST(InsightUnit, rawIntegralNotifyPreservesTheValueExactly)
|
||||
TEST(InsightUnit, raw_integral_notify_preserves_the_value_exactly)
|
||||
{
|
||||
// The byte path must not be rounded or scaled on its way through the
|
||||
// duration-typed storage field.
|
||||
@@ -143,7 +143,7 @@ TEST(InsightUnit, rawIntegralNotifyPreservesTheValueExactly)
|
||||
EXPECT_EQ(impl->samples[2].count(), 1'048'577);
|
||||
}
|
||||
|
||||
TEST(InsightUnit, durationNotifyStillRoundsUpToWholeMilliseconds)
|
||||
TEST(InsightUnit, duration_notify_still_rounds_up_to_whole_milliseconds)
|
||||
{
|
||||
// Pre-existing behaviour, asserted so the new overload cannot quietly
|
||||
// change it: Event applies ceil to whole milliseconds, which is why
|
||||
@@ -161,7 +161,7 @@ TEST(InsightUnit, durationNotifyStillRoundsUpToWholeMilliseconds)
|
||||
EXPECT_EQ(impl->samples[2].count(), 7);
|
||||
}
|
||||
|
||||
TEST(InsightUnit, notifyOnANullEventIsSafeForBothOverloads)
|
||||
TEST(InsightUnit, notify_on_a_null_event_is_safe_for_both_overloads)
|
||||
{
|
||||
// A default-constructed Event has no impl. Both overloads must be no-ops
|
||||
// rather than dereferencing null.
|
||||
|
||||
@@ -40,7 +40,7 @@ namespace telemetry = xrpl::telemetry;
|
||||
* the same in both configurations, which is what lets a caller report these
|
||||
* accessors without knowing which build it is in.
|
||||
*/
|
||||
TEST(AcquireStatsTest, StartsAtZero)
|
||||
TEST(AcquireStatsTest, starts_at_zero)
|
||||
{
|
||||
// Braces matter: without telemetry the counters hold no state, so the type
|
||||
// is trivially default constructible and MSVC rejects a const instance left
|
||||
@@ -62,7 +62,7 @@ TEST(AcquireStatsTest, StartsAtZero)
|
||||
* divergence that identifies the stall, so each step asserts both the counter
|
||||
* that should have moved and the ones that must not have.
|
||||
*/
|
||||
TEST(AcquireStatsTest, CountersAdvanceIndependently)
|
||||
TEST(AcquireStatsTest, counters_advance_independently)
|
||||
{
|
||||
AcquireStats stats;
|
||||
|
||||
@@ -142,7 +142,7 @@ TEST(AcquireStatsTest, CountersAdvanceIndependently)
|
||||
* that had built nothing yet, and the cheap one must leave the partial-work
|
||||
* counter untouched.
|
||||
*/
|
||||
TEST(AcquireStatsTest, AbortDistinguishesPartialWork)
|
||||
TEST(AcquireStatsTest, abort_distinguishes_partial_work)
|
||||
{
|
||||
AcquireStats stats;
|
||||
|
||||
@@ -180,7 +180,7 @@ TEST(AcquireStatsTest, AbortDistinguishesPartialWork)
|
||||
* discarding partial work. Timeouts staying at exactly zero is what proves the
|
||||
* give-up path cannot fire, so that assertion is the point of the test.
|
||||
*/
|
||||
TEST(AcquireStatsTest, StalledShapeIsDistinguishable)
|
||||
TEST(AcquireStatsTest, stalled_shape_is_distinguishable)
|
||||
{
|
||||
AcquireStats stalled;
|
||||
for (int i = 0; i < 1000; ++i)
|
||||
@@ -221,7 +221,7 @@ TEST(AcquireStatsTest, StalledShapeIsDistinguishable)
|
||||
* completions dominate. The same seven counters, read the opposite way, which
|
||||
* is what makes the stalled reading above meaningful.
|
||||
*/
|
||||
TEST(AcquireStatsTest, HealthyShapeIsDistinguishable)
|
||||
TEST(AcquireStatsTest, healthy_shape_is_distinguishable)
|
||||
{
|
||||
AcquireStats healthy;
|
||||
for (int i = 0; i < 10; ++i)
|
||||
@@ -262,7 +262,7 @@ TEST(AcquireStatsTest, HealthyShapeIsDistinguishable)
|
||||
* from the loop bounds would make the assertion agree with the loop by
|
||||
* construction and pass even if every increment were lost.
|
||||
*/
|
||||
TEST(AcquireStatsTest, ConcurrentRecordingLosesNothing)
|
||||
TEST(AcquireStatsTest, concurrent_recording_loses_nothing)
|
||||
{
|
||||
AcquireStats stats;
|
||||
constexpr int kThreads = 4;
|
||||
|
||||
@@ -33,7 +33,7 @@ class HistogramBucketsTest : public ::testing::TestWithParam<std::span<double co
|
||||
{
|
||||
};
|
||||
|
||||
TEST_P(HistogramBucketsTest, isStrictlyAscending)
|
||||
TEST_P(HistogramBucketsTest, is_strictly_ascending)
|
||||
{
|
||||
auto const ladder = GetParam();
|
||||
ASSERT_FALSE(ladder.empty());
|
||||
@@ -41,7 +41,7 @@ TEST_P(HistogramBucketsTest, isStrictlyAscending)
|
||||
EXPECT_LT(ladder[i - 1], ladder[i]) << "edge index " << i << " does not ascend";
|
||||
}
|
||||
|
||||
TEST_P(HistogramBucketsTest, isNonNegativeAndFinite)
|
||||
TEST_P(HistogramBucketsTest, is_non_negative_and_finite)
|
||||
{
|
||||
for (double const edge : GetParam())
|
||||
{
|
||||
@@ -50,7 +50,7 @@ TEST_P(HistogramBucketsTest, isNonNegativeAndFinite)
|
||||
}
|
||||
}
|
||||
|
||||
TEST_P(HistogramBucketsTest, passesTheCompileTimeValidator)
|
||||
TEST_P(HistogramBucketsTest, passes_the_compile_time_validator)
|
||||
{
|
||||
EXPECT_TRUE(isAscendingNonNegative(GetParam()));
|
||||
}
|
||||
@@ -65,7 +65,7 @@ INSTANTIATE_TEST_SUITE_P(
|
||||
std::span<double const>{kObjectCountBuckets},
|
||||
std::span<double const>{kChargeBuckets}));
|
||||
|
||||
TEST(HistogramBucketsRange, microsecondFloorLandsBelowTheMeasuredMass)
|
||||
TEST(HistogramBucketsRange, microsecond_floor_lands_below_the_measured_mass)
|
||||
{
|
||||
// Measured: 99.3% of job_queued_us samples sat below the old 100 us floor,
|
||||
// so p75/p95/p99 all interpolated inside bucket 0 and returned
|
||||
@@ -79,14 +79,14 @@ TEST(HistogramBucketsRange, microsecondFloorLandsBelowTheMeasuredMass)
|
||||
EXPECT_GE(belowHundred, 5) << "too little resolution below 100 us";
|
||||
}
|
||||
|
||||
TEST(HistogramBucketsRange, microsecondCeilingStillReachesOneMinute)
|
||||
TEST(HistogramBucketsRange, microsecond_ceiling_still_reaches_one_minute)
|
||||
{
|
||||
// Job waits and RPC latencies routinely exceed the SDK default ceiling of
|
||||
// 10,000; multi-second stalls must stay measurable rather than censored.
|
||||
EXPECT_EQ(kMicrosecondBuckets.back(), 60'000'000.0);
|
||||
}
|
||||
|
||||
TEST(HistogramBucketsRange, objectCountLadderCannotSaturate)
|
||||
TEST(HistogramBucketsRange, object_count_ladder_cannot_saturate)
|
||||
{
|
||||
// GetObject counts run 1..kHardMaxReplyNodes, so the top edge IS the hard
|
||||
// cap and censoring is impossible by construction.
|
||||
@@ -94,7 +94,7 @@ TEST(HistogramBucketsRange, objectCountLadderCannotSaturate)
|
||||
EXPECT_EQ(kObjectCountBuckets.back(), 12'288.0);
|
||||
}
|
||||
|
||||
TEST(HistogramBucketsRange, chargeLadderBracketsTheResourceThresholds)
|
||||
TEST(HistogramBucketsRange, charge_ladder_brackets_the_resource_thresholds)
|
||||
{
|
||||
// The two edges that decide a peer's fate must be present so a dashboard
|
||||
// can show how close charges run to each: warning at 5000, drop at 25000.
|
||||
@@ -109,7 +109,7 @@ TEST(HistogramBucketsRange, chargeLadderBracketsTheResourceThresholds)
|
||||
|
||||
// The validator must also REJECT. A predicate that only ever returns true
|
||||
// would let every ladder above pass while proving nothing.
|
||||
TEST(HistogramBucketsValidator, rejectsEmptyDescendingDuplicateAndNegative)
|
||||
TEST(HistogramBucketsValidator, rejects_empty_descending_duplicate_and_negative)
|
||||
{
|
||||
EXPECT_FALSE(isAscendingNonNegative(std::span<double const>{}));
|
||||
|
||||
@@ -123,7 +123,7 @@ TEST(HistogramBucketsValidator, rejectsEmptyDescendingDuplicateAndNegative)
|
||||
EXPECT_FALSE(isAscendingNonNegative(negative));
|
||||
}
|
||||
|
||||
TEST(HistogramBucketsValidator, acceptsASingleEdgeAndALeadingZero)
|
||||
TEST(HistogramBucketsValidator, accepts_a_single_edge_and_a_leading_zero)
|
||||
{
|
||||
constexpr std::array single{1.0};
|
||||
EXPECT_TRUE(isAscendingNonNegative(single));
|
||||
@@ -134,7 +134,7 @@ TEST(HistogramBucketsValidator, acceptsASingleEdgeAndALeadingZero)
|
||||
EXPECT_TRUE(isAscendingNonNegative(leadingZero));
|
||||
}
|
||||
|
||||
TEST(HistogramBucketsRange, millisecondFloorIsOneAndCeilingCoversTheSlowestJob)
|
||||
TEST(HistogramBucketsRange, millisecond_floor_is_one_and_ceiling_covers_the_slowest_job)
|
||||
{
|
||||
// beast::insight::Event rounds durations up to whole milliseconds, so 1
|
||||
// is the smallest edge that can ever collect a sample.
|
||||
@@ -146,7 +146,7 @@ TEST(HistogramBucketsRange, millisecondFloorIsOneAndCeilingCoversTheSlowestJob)
|
||||
EXPECT_GE(kMillisecondBuckets.back(), 120'000.0);
|
||||
}
|
||||
|
||||
TEST(HistogramBucketsRange, millisecondLadderClearsTheMeasuredCensoringPoint)
|
||||
TEST(HistogramBucketsRange, millisecond_ladder_clears_the_measured_censoring_point)
|
||||
{
|
||||
// rpc_size had 24.9% of samples above the old 5000 ceiling and
|
||||
// jobq_updatepaths had 100%. A ceiling at or below 5000 reintroduces the
|
||||
@@ -154,7 +154,7 @@ TEST(HistogramBucketsRange, millisecondLadderClearsTheMeasuredCensoringPoint)
|
||||
EXPECT_GT(kMillisecondBuckets.back(), 5'000.0);
|
||||
}
|
||||
|
||||
TEST(HistogramBucketsRange, millisecondLadderContainsEveryRepresentableCollectorEdge)
|
||||
TEST(HistogramBucketsRange, millisecond_ladder_contains_every_representable_collector_edge)
|
||||
{
|
||||
// Agreement with the collector's spanmetrics ladder over the shared
|
||||
// range is the invariant; edges above its 30 s top are allowed because
|
||||
@@ -186,7 +186,7 @@ TEST(HistogramBucketsRange, millisecondLadderContainsEveryRepresentableCollector
|
||||
}
|
||||
}
|
||||
|
||||
TEST(HistogramBucketsRange, millisecondLadderResolvesTheOneToFiveSecondBand)
|
||||
TEST(HistogramBucketsRange, millisecond_ladder_resolves_the_one_to_five_second_band)
|
||||
{
|
||||
// Without these the 1 s to 5 s span was one four-second-wide bucket, so
|
||||
// any quantile landing inside it was interpolated across four seconds.
|
||||
@@ -197,7 +197,7 @@ TEST(HistogramBucketsRange, millisecondLadderResolvesTheOneToFiveSecondBand)
|
||||
}
|
||||
}
|
||||
|
||||
TEST(HistogramBucketsRange, byteLadderBracketsTheMeasuredResponseDistribution)
|
||||
TEST(HistogramBucketsRange, byte_ladder_brackets_the_measured_response_distribution)
|
||||
{
|
||||
// Measured: mean 2131 B, half under 1 kB, three quarters under 5 kB, and
|
||||
// the tail above 5 kB has a mean of at most 7538 B -- which puts p99
|
||||
@@ -212,7 +212,7 @@ TEST(HistogramBucketsRange, byteLadderBracketsTheMeasuredResponseDistribution)
|
||||
EXPECT_GE(withinWorkingRange, 6) << "too little resolution between 512 B and 64 kB";
|
||||
}
|
||||
|
||||
TEST(HistogramBucketsRange, byteAndMillisecondLaddersAreDistinct)
|
||||
TEST(HistogramBucketsRange, byte_and_millisecond_ladders_are_distinct)
|
||||
{
|
||||
// A single shared ladder is what put a byte count on a latency scale and
|
||||
// censored a quarter of its samples.
|
||||
@@ -220,14 +220,14 @@ TEST(HistogramBucketsRange, byteAndMillisecondLaddersAreDistinct)
|
||||
EXPECT_GT(kByteBuckets.back(), kMillisecondBuckets.back());
|
||||
}
|
||||
|
||||
TEST(HistogramBucketsConvert, toVectorPreservesOrderAndSize)
|
||||
TEST(HistogramBucketsConvert, to_vector_preserves_order_and_size)
|
||||
{
|
||||
auto const converted = toVector(kByteBuckets);
|
||||
ASSERT_EQ(converted.size(), kByteBuckets.size());
|
||||
EXPECT_TRUE(std::ranges::equal(converted, kByteBuckets));
|
||||
}
|
||||
|
||||
TEST(HistogramBucketsConvert, toVectorHandlesAnEmptyLadder)
|
||||
TEST(HistogramBucketsConvert, to_vector_handles_an_empty_ladder)
|
||||
{
|
||||
EXPECT_TRUE(toVector(std::span<double const>{}).empty());
|
||||
}
|
||||
|
||||
@@ -92,7 +92,7 @@ inline constexpr int kMinBatchItemBytes = 3;
|
||||
|
||||
} // namespace
|
||||
|
||||
TEST(RpcMetricNames, namesAreTheExactExportedSeriesNames)
|
||||
TEST(RpcMetricNames, names_are_the_exact_exported_series_names)
|
||||
{
|
||||
// These strings ARE the Prometheus series. Changing one is a
|
||||
// dashboard-breaking change, so it has to be a deliberate edit here too.
|
||||
@@ -100,7 +100,7 @@ TEST(RpcMetricNames, namesAreTheExactExportedSeriesNames)
|
||||
EXPECT_EQ(std::string_view{kPathfindDiscoveredPaths}, "pathfind_discovered_paths");
|
||||
}
|
||||
|
||||
TEST(RpcMetricNames, descriptionsAreTheExactExportedHelpText)
|
||||
TEST(RpcMetricNames, descriptions_are_the_exact_exported_help_text)
|
||||
{
|
||||
// The description becomes the Prometheus `# HELP` line, so it is part of
|
||||
// the exported surface, not a code comment.
|
||||
@@ -110,7 +110,7 @@ TEST(RpcMetricNames, descriptionsAreTheExactExportedHelpText)
|
||||
"Payment paths produced per pathfinding pass, across all source assets");
|
||||
}
|
||||
|
||||
TEST(RpcMetricNames, namesAreLowerSnakeCase)
|
||||
TEST(RpcMetricNames, names_are_lower_snake_case)
|
||||
{
|
||||
for (std::string_view const name :
|
||||
{std::string_view{kRpcBatchSize}, std::string_view{kPathfindDiscoveredPaths}})
|
||||
@@ -129,7 +129,7 @@ TEST(RpcMetricNames, namesAreLowerSnakeCase)
|
||||
}
|
||||
}
|
||||
|
||||
TEST(RpcMetricNames, namesEndInTheCountedNounAndNotAUnitOrCounterSuffix)
|
||||
TEST(RpcMetricNames, names_end_in_the_counted_noun_and_not_a_unit_or_counter_suffix)
|
||||
{
|
||||
// Both instruments count things. `_total` is the Prometheus counter suffix
|
||||
// and `_count`/`_sum`/`_bucket` are the ones the exporter appends to a
|
||||
@@ -151,7 +151,7 @@ TEST(RpcMetricNames, namesEndInTheCountedNounAndNotAUnitOrCounterSuffix)
|
||||
}
|
||||
}
|
||||
|
||||
TEST(RpcMetricBucketFit, objectCountLadderSeparatesTheSmallestCounts)
|
||||
TEST(RpcMetricBucketFit, object_count_ladder_separates_the_smallest_counts)
|
||||
{
|
||||
using buckets::kObjectCountBuckets;
|
||||
|
||||
@@ -177,7 +177,7 @@ TEST(RpcMetricBucketFit, objectCountLadderSeparatesTheSmallestCounts)
|
||||
EXPECT_EQ(bucketIndex(ladder, 16.0), 4u);
|
||||
}
|
||||
|
||||
TEST(RpcMetricBucketFit, theSdkDefaultLadderWouldCollapseEverySmallBatch)
|
||||
TEST(RpcMetricBucketFit, the_sdk_default_ladder_would_collapse_every_small_batch)
|
||||
{
|
||||
// This is why both instruments get an explicit-bucket view. On the SDK
|
||||
// default ladder every batch from 1 to 5 sub-requests lands in one bucket,
|
||||
@@ -197,7 +197,7 @@ TEST(RpcMetricBucketFit, theSdkDefaultLadderWouldCollapseEverySmallBatch)
|
||||
EXPECT_EQ(bucketIndex(chosen, 5.0), 3u);
|
||||
}
|
||||
|
||||
TEST(RpcMetricBucketFit, aMaximumSizedBatchStillOverflowsTheLadderCeiling)
|
||||
TEST(RpcMetricBucketFit, a_maximum_sized_batch_still_overflows_the_ladder_ceiling)
|
||||
{
|
||||
// The documented limitation of rpc_batch_size, as an executable fact.
|
||||
// Nothing caps the sub-request count except the request-size limit, so the
|
||||
@@ -218,7 +218,7 @@ TEST(RpcMetricBucketFit, aMaximumSizedBatchStillOverflowsTheLadderCeiling)
|
||||
|
||||
// The placement helper must also disagree with the ladder when it should. A
|
||||
// helper that always returned 0 would let every index assertion above pass.
|
||||
TEST(RpcMetricBucketFit, bucketIndexPlacesAboveAndBelowEveryEdge)
|
||||
TEST(RpcMetricBucketFit, bucket_index_places_above_and_below_every_edge)
|
||||
{
|
||||
constexpr std::array probe{10.0, 20.0};
|
||||
std::span<double const> const ladder{probe};
|
||||
|
||||
@@ -368,7 +368,7 @@ protected:
|
||||
};
|
||||
|
||||
// freshRoot() must ignore the ambient active span and start a brand-new trace.
|
||||
TEST_F(SpanGuardScopeTest, spanGuard_freshRoot_is_true_root_ignoring_ambient)
|
||||
TEST_F(SpanGuardScopeTest, span_guard_fresh_root_is_true_root_ignoring_ambient)
|
||||
{
|
||||
{
|
||||
// Ambient span becomes the active span on this thread.
|
||||
@@ -398,7 +398,7 @@ TEST_F(SpanGuardScopeTest, spanGuard_freshRoot_is_true_root_ignoring_ambient)
|
||||
|
||||
// A ScopedSpanGuard is the ambient active span on its thread the moment it is
|
||||
// constructed: a child created while it is alive parents to its span.
|
||||
TEST_F(SpanGuardScopeTest, scopedGuard_is_ambient_on_construct)
|
||||
TEST_F(SpanGuardScopeTest, scoped_guard_is_ambient_on_construct)
|
||||
{
|
||||
opentelemetry::trace::SpanId activeId;
|
||||
{
|
||||
@@ -435,7 +435,7 @@ TEST_F(SpanGuardScopeTest, scopedGuard_is_ambient_on_construct)
|
||||
// operator SpanGuard() && pops the Scope eagerly on the origin thread, so the
|
||||
// span is no longer ambient here and the resulting thread-free guard can be
|
||||
// ended on a worker thread without corrupting this thread's context stack.
|
||||
TEST_F(SpanGuardScopeTest, scopedGuard_conversion_pops_scope_on_this_thread)
|
||||
TEST_F(SpanGuardScopeTest, scoped_guard_conversion_pops_scope_on_this_thread)
|
||||
{
|
||||
{
|
||||
ScopedSpanGuard s(TraceCategory::Ledger, "ledger", "build");
|
||||
@@ -478,7 +478,7 @@ TEST_F(SpanGuardScopeTest, scopedGuard_conversion_pops_scope_on_this_thread)
|
||||
|
||||
// The SpanGuard produced by the conversion ends the span exactly once: the
|
||||
// moved-from ScopedSpanGuard must not re-end it on destruction.
|
||||
TEST_F(SpanGuardScopeTest, scopedGuard_conversion_result_ends_span_once)
|
||||
TEST_F(SpanGuardScopeTest, scoped_guard_conversion_result_ends_span_once)
|
||||
{
|
||||
{
|
||||
ScopedSpanGuard scoped(TraceCategory::Ledger, "ledger", "build");
|
||||
@@ -511,7 +511,7 @@ TEST_F(SpanGuardScopeTest, scopedGuard_conversion_result_ends_span_once)
|
||||
// stack ignores the LocalValue swap, so the span would stay visible off-store
|
||||
// (the EXPECT_NE below would fail). Passes only because the fixture installs the
|
||||
// coro-aware storage that binds the ambient stack to the active store.
|
||||
TEST_F(SpanGuardScopeTest, scopedGuard_survives_localvalue_store_swap)
|
||||
TEST_F(SpanGuardScopeTest, scoped_guard_survives_localvalue_store_swap)
|
||||
{
|
||||
namespace ctx = opentelemetry::context;
|
||||
namespace trc = opentelemetry::trace;
|
||||
@@ -618,7 +618,7 @@ TEST_F(SpanGuardScopeTest, activate_sets_ambient_without_owning)
|
||||
// OTel key-value-iterable, so a dropped or mistyped pair would be invisible
|
||||
// without reading the exported event back. Values are asserted individually as
|
||||
// well as by count: two attributes with one value blanked still counts as two.
|
||||
TEST_F(SpanGuardScopeTest, spanGuard_addEvent_records_name_and_attribute_values)
|
||||
TEST_F(SpanGuardScopeTest, span_guard_add_event_records_name_and_attribute_values)
|
||||
{
|
||||
namespace cs = consensus::span;
|
||||
|
||||
@@ -652,7 +652,7 @@ TEST_F(SpanGuardScopeTest, spanGuard_addEvent_records_name_and_attribute_values)
|
||||
// The name-only overload records the event with NO attributes, so a regression
|
||||
// that leaked attributes between the two overloads shows up here rather than as
|
||||
// an extra key on a production event.
|
||||
TEST_F(SpanGuardScopeTest, spanGuard_addEvent_without_attributes_records_bare_event)
|
||||
TEST_F(SpanGuardScopeTest, span_guard_add_event_without_attributes_records_bare_event)
|
||||
{
|
||||
namespace cs = consensus::span;
|
||||
|
||||
@@ -676,7 +676,7 @@ TEST_F(SpanGuardScopeTest, spanGuard_addEvent_without_attributes_records_bare_ev
|
||||
|
||||
// The scoped guard records event attributes too. consensus.accept.apply relies
|
||||
// on it for one tx.included event per transaction of the accepted set.
|
||||
TEST_F(SpanGuardScopeTest, scopedGuard_addEvent_records_name_and_attribute_values)
|
||||
TEST_F(SpanGuardScopeTest, scoped_guard_add_event_records_name_and_attribute_values)
|
||||
{
|
||||
namespace cs = consensus::span;
|
||||
|
||||
@@ -704,7 +704,7 @@ TEST_F(SpanGuardScopeTest, scopedGuard_addEvent_records_name_and_attribute_value
|
||||
// A scoped child of a captured context is the ambient parent of the spans
|
||||
// created after it on the same thread. A hash-derived root created inside that
|
||||
// scope stays a root. consensus.accept.apply relies on both.
|
||||
TEST_F(SpanGuardScopeTest, scopedChildOfCapturedContextIsAmbientForLaterSpans)
|
||||
TEST_F(SpanGuardScopeTest, scoped_child_of_captured_context_is_ambient_for_later_spans)
|
||||
{
|
||||
namespace cs = consensus::span;
|
||||
|
||||
@@ -755,7 +755,7 @@ TEST_F(SpanGuardScopeTest, scopedChildOfCapturedContextIsAmbientForLaterSpans)
|
||||
|
||||
// A forced-root span started while a PendingTraceId is active adopts that
|
||||
// pinned 16-byte trace_id and remains a true root (no parent).
|
||||
TEST_F(SpanGuardScopeTest, deterministicIdGenerator_forced_root_gets_pending_trace_id)
|
||||
TEST_F(SpanGuardScopeTest, deterministic_id_generator_forced_root_gets_pending_trace_id)
|
||||
{
|
||||
auto const h = makeTraceIdBytes();
|
||||
{
|
||||
@@ -776,7 +776,7 @@ TEST_F(SpanGuardScopeTest, deterministicIdGenerator_forced_root_gets_pending_tra
|
||||
|
||||
// A forced-root span with NO PendingTraceId gets a random (non-zero) trace_id,
|
||||
// never the deterministic hash -- the safety property when no id is pinned.
|
||||
TEST_F(SpanGuardScopeTest, deterministicIdGenerator_no_pending_gives_random_root)
|
||||
TEST_F(SpanGuardScopeTest, deterministic_id_generator_no_pending_gives_random_root)
|
||||
{
|
||||
auto const h = makeTraceIdBytes();
|
||||
{
|
||||
@@ -800,7 +800,7 @@ TEST_F(SpanGuardScopeTest, deterministicIdGenerator_no_pending_gives_random_root
|
||||
// child, so the pinned id stays available -- proven here by a trailing
|
||||
// forced-root span that DOES adopt it (which also consumes the id so
|
||||
// ~PendingTraceId's consumed-assert holds; see the report for this choice).
|
||||
TEST_F(SpanGuardScopeTest, deterministicIdGenerator_ambient_child_ignores_pending)
|
||||
TEST_F(SpanGuardScopeTest, deterministic_id_generator_ambient_child_ignores_pending)
|
||||
{
|
||||
auto const h = makeTraceIdBytes();
|
||||
{
|
||||
@@ -873,7 +873,7 @@ TEST_F(SpanGuardScopeTest, deterministicIdGenerator_ambient_child_ignores_pendin
|
||||
// builds) XRPL_ASSERT is a no-op, and under ENABLE_VOIDSTAR a failed assert
|
||||
// continues instead of aborting -- in both cases the worker would not crash and
|
||||
// EXPECT_DEATH would report a spurious failure.
|
||||
TEST_F(SpanGuardScopeTest, scopedGuard_cross_thread_death_asserts_at_wrong_store_destroy)
|
||||
TEST_F(SpanGuardScopeTest, scoped_guard_cross_thread_death_asserts_at_wrong_store_destroy)
|
||||
{
|
||||
#ifdef NDEBUG
|
||||
GTEST_SKIP() << "XRPL_ASSERT compiles to a no-op under NDEBUG (Release builds), so the "
|
||||
|
||||
Reference in New Issue
Block a user