-
Notifications
You must be signed in to change notification settings - Fork 76
Baseline processing (Baseline 2 of 3) #660
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Baseline processing (Baseline 2 of 3) #660
Conversation
- Add baseline_file option to GooseConfiguration and GooseDefaults - Create NullableFloat struct for handling null values in JSON - Add module declaration and public export for nullable module This is the first PR in splitting the baseline feature implementation.
- Add src/metrics/nullable.rs with NullableFloat struct for handling null values in JSON - Add src/metrics/delta.rs with delta calculation logic and Value enum - Implement DeltaValue trait for usize, f32, and NullableFloat - Export delta types in src/metrics.rs This completes the core infrastructure needed for baseline comparison feature.
The baseline_file field in GooseDefaults is intentionally unused in PR 1 since it only adds infrastructure. The field will be used in subsequent PRs (baseline-processing and baseline-reports). This fixes the dead code warning to allow PR 1 to be merged without warnings.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
📋 Review Summary
This PR introduces the core processing logic for the baseline comparison feature, which is a great step forward. The implementation of the DeltaValue trait and the Value enum provides a solid foundation for calculating and representing deltas.
🔍 General Feedback
- The code is well-structured, and the new
deltamodule is a good addition for organizing the baseline comparison logic. - The use of traits for delta calculation is a good design choice, making the system extensible.
- Unit tests are included and cover the new functionality well.
I've left a few inline comments with suggestions for improvement, mainly around simplifying the delta calculation for usize and improving the handling of NaN values in f32 deltas for better clarity.
LionsAd
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Targeted Review of PR #660: Baseline Processing
🔴 Critical Issues
1. Overflow Bug in usize::delta (Line 32)
// CURRENT (BUGGY):
if delta > ISIZE_MIN_ABS {
isize::MIN
} else {
-(delta as isize) // ← OVERFLOW when delta == ISIZE_MIN_ABS
}
// FIX: Use Gemini's elegant solution
fn delta(self, value: Self) -> Self::Delta {
let delta = (self as i128) - (value as i128);
delta.clamp(isize::MIN as i128, isize::MAX as i128) as isize
}2. Missing Type Implementations
PR description promises u64, u16, f64 but only implements usize and f32.
Add these implementations:
impl DeltaValue for u64 {
type Delta = i64;
fn delta(self, value: Self) -> Self::Delta {
let delta = (self as i128) - (value as i128);
delta.clamp(i64::MIN as i128, i64::MAX as i128) as i64
}
fn is_delta_positive(value: Self::Delta) -> bool { value.is_positive() }
}
impl DeltaValue for u16 {
type Delta = i16;
fn delta(self, value: Self) -> Self::Delta {
(self as i32 - value as i32) as i16 // No overflow possible
}
fn is_delta_positive(value: Self::Delta) -> bool { value.is_positive() }
}
impl DeltaValue for f64 {
type Delta = f64;
fn delta(self, value: Self) -> Self::Delta { self - value }
fn is_delta_positive(value: Self::Delta) -> bool { !value.is_sign_negative() }
}🟡 Important Fixes
3. Inconsistent Zero Formatting (Lines 54-56, 107-108)
Integer zero shows (0) but float zero shows (+0).
Fix float implementations:
// In f32 and NullableFloat implementations:
fn is_delta_positive(value: Self::Delta) -> bool {
value > 0.0 // ← Change from !value.is_sign_negative()
}4. Dead Code: DeltaTo Trait (Lines 177-180)
Exported but unused.
// REMOVE this trait entirely or implement it properly
pub trait DeltaTo {
fn delta_to(&mut self, other: &Self);
}5. Simplify Value::diff Method (Lines 80-95)
// CURRENT: Repetitive match arms
// BETTER:
pub fn diff(&mut self, other: T) {
let value = match self {
Self::Plain(value) => *value,
Self::Delta { value, .. } => *value,
};
*self = Self::Delta {
value,
delta: value.delta(other),
}
}🟢 Documentation & Polish
6. Fix Documentation (Line 18)
// CURRENT:
/// It's positive if it's not negative or zero
// BETTER:
/// Returns true if the delta represents an increase (positive value)
/// For floating point types, zero is considered non-positive
7. Add Missing Tests
#[test]
fn test_float_zero_formatting() {
let value = Value::from(NullableFloat(0.0));
assert_eq!(format!("{}", value), "0"); // Should not show (+0)
}
#[test]
fn test_nan_handling() {
let nan_value = NullableFloat(f32::NAN);
let delta = nan_value.delta(NullableFloat(1.0));
assert!(delta.is_nan());
}📋 Quick Checklist
- Fix overflow bug with
i128solution - Add
u64,u16,f64implementations - Fix zero formatting consistency
- Remove unused
DeltaTotrait - Simplify
Value::diffmethod - Update documentation
- Add NaN and edge case tests
Final Recommendation: REQUEST CHANGES
The foundation is excellent, but the overflow bug is critical and must be fixed. Once these changes are made, this will be a solid baseline feature implementation.
(Powered by Claude Code)
Baseline Processing Implementation (PR2)
Overview
This document covers the second phase of the baseline comparison feature implementation: core processing logic and delta calculation infrastructure. This builds upon the foundation established in PR1 (baseline-infrastructure).
PR Context
Base Branch:
baseline-infrastructure(notmain)Purpose: Core processing logic for baseline comparison
What This PR Accomplishes
This PR implements the core algorithmic and data structure components required for baseline comparison:
1. Delta Calculation Infrastructure (
src/metrics/delta.rs)DeltaValue Trait
Deltatype defines the result type for delta calculationsusize,f32,f64,u64,u16)ISIZE_MIN_ABSconstantValue Enum
Plain(T)variant for standalone valuesWithDelta { value: T, delta: T::Delta }for values with baseline comparisonDeltaValueOverflow Protection
ISIZE_MIN_ABSconstant for safe arithmetic operations2. Enhanced NullableFloat (
src/metrics/nullable.rs)Building on the basic
NullableFloatfrom PR1, this PR adds:DeltaValue Implementation
NullableFloatto participate in baseline comparisons3. Data Structure Enhancements (
src/metrics/common.rs)ReportOptions Structure
no_transaction_metrics,no_scenario_metrics,no_status_codesReportData Structure
Baseline Processing Functions
load_baseline_file(): Loads and validates baseline JSON filesprepare_data_with_baseline(): Processes metrics with baseline comparison4. Module Organization
Public API Exposure
DeltaValuetrait made public for external implementationsValue<T>enum exported for use in report generationIntegration Points
Why This PR Stops Here
This PR contains only the processing logic without report generation integration. This separation:
Key Files Added/Modified
src/metrics/delta.rs: Complete delta calculation infrastructuresrc/metrics/nullable.rs: Enhanced with DeltaValue implementationsrc/metrics/common.rs: Baseline processing and data structuressrc/metrics.rs: Module organization and public API exportsTechnical Implementation Details
Delta Calculation Algorithm
For numeric types, delta calculation follows the pattern:
NaN Handling Strategy
NullableFloatdelta calculation preserves NaN semantics:NaNcompared to any value results inNaNdeltaError Handling
Baseline processing includes comprehensive error handling:
Next Phase: PR3 (Reports Integration)
The third PR will integrate this processing logic with the report generation system:
Value<T>enumDependencies
This PR builds directly on the infrastructure from: