diff options
| author | Will Hawkins <[email protected]> | 2023-07-14 10:55:02 -0400 |
|---|---|---|
| committer | Will Hawkins <[email protected]> | 2023-07-14 10:58:51 -0400 |
| commit | df37c3e0d572ff3b4b4de3e9919402e8e0ccf971 (patch) | |
| tree | 62e35137fa3d233f5506804775b6c71e728e71c3 | |
| parent | 399eda676f7889accf72231c6696b89de7ea3fae (diff) | |
Parameterize Percentile in RPM Calculations
Make the percentile used by RPM calculations user-controlled. Note: A
percentile-based calculation is not part of the spec. This is an
optional feature.
Signed-off-by: Will Hawkins <[email protected]>
| -rw-r--r-- | constants/constants.go | 13 | ||||
| -rw-r--r-- | networkQuality.go | 10 | ||||
| -rw-r--r-- | rpm/calculations.go | 2 | ||||
| -rw-r--r-- | rpm/parameters.go | 8 | ||||
| -rw-r--r-- | rpm/parameters_test.go | 41 | ||||
| -rw-r--r-- | series/statistics.go | 2 |
6 files changed, 46 insertions, 30 deletions
diff --git a/constants/constants.go b/constants/constants.go index 7a8d562..fdfd1f2 100644 --- a/constants/constants.go +++ b/constants/constants.go @@ -23,16 +23,6 @@ var ( // saturate the network. AdditiveNumberOfLoadGeneratingConnections uint64 = 1 - // The number of previous instantaneous measurements to consider when generating the so-called - // instantaneous moving averages of a measurement. - InstantaneousThroughputMeasurementCount uint64 = 4 - InstantaneousProbeMeasurementCount uint64 = 4 - // The number of instantaneous moving averages to consider when determining stability. - InstantaneousMovingAverageStabilityCount uint64 = 4 - // The standard deviation cutoff used to determine stability among the K preceding moving averages - // of a measurement (as a percentage of the mean). - StabilityStandardDeviation float64 = 5.0 - // The amount of time that the client will cooldown if it is in debug mode. CooldownPeriod time.Duration = 4 * time.Second @@ -56,6 +46,7 @@ type SpecParametersCliOptions struct { Mnp int Mps int Ptc float64 + P int } -var SpecParameterCliOptionsDefaults = SpecParametersCliOptions{Mad: 4, Id: 1, Tmp: 5, Sdt: 5.0, Mnp: 16, Mps: 100, Ptc: 0.05} +var SpecParameterCliOptionsDefaults = SpecParametersCliOptions{Mad: 4, Id: 1, Tmp: 5, Sdt: 5.0, Mnp: 16, Mps: 100, Ptc: 0.05, P: 90} diff --git a/networkQuality.go b/networkQuality.go index 9671eb3..3bd6767 100644 --- a/networkQuality.go +++ b/networkQuality.go @@ -109,6 +109,11 @@ var ( constants.SpecParameterCliOptionsDefaults.Ptc, "Percentage of the (discovered) total network capacity that probes are allowed to consume.", ) + rpmp = flag.Int( + "rpm.p", + constants.SpecParameterCliOptionsDefaults.P, + "Percentile of results to consider when calculating responsiveness.", + ) sslKeyFileName = flag.String( "ssl-key-file", @@ -172,7 +177,7 @@ func main() { } specParameters, err := rpm.SpecParametersFromArguments(*rpmtimeout, *rpmmad, *rpmid, - *rpmtmp, *rpmsdt, *rpmmnp, *rpmmps, *rpmptc) + *rpmtmp, *rpmsdt, *rpmmnp, *rpmmps, *rpmptc, *rpmp) if err != nil { fmt.Fprintf( os.Stderr, @@ -846,7 +851,8 @@ func main() { if *calculateExtendedStats { fmt.Println(extendedStats.Repr()) } - directionResult := rpm.CalculateRpm(perDirectionSelfRtts, perDirectionForeignRtts, specParameters.TrimmedMeanPct, 90) + directionResult := rpm.CalculateRpm(perDirectionSelfRtts, perDirectionForeignRtts, + specParameters.TrimmedMeanPct, specParameters.Percentile) if *debugCliFlag { fmt.Printf("(%s RPM Calculation stats): %v\n", direction.DirectionLabel, directionResult.ToString()) } diff --git a/rpm/calculations.go b/rpm/calculations.go index 4b61413..8b3cf92 100644 --- a/rpm/calculations.go +++ b/rpm/calculations.go @@ -36,7 +36,7 @@ type Rpm[Data utilities.Number] struct { } func CalculateRpm[Data utilities.Number, Bucket constraints.Ordered]( - selfRtts series.WindowSeries[Data, Bucket], aggregatedForeignRtts series.WindowSeries[Data, Bucket], trimming uint, percentile int, + selfRtts series.WindowSeries[Data, Bucket], aggregatedForeignRtts series.WindowSeries[Data, Bucket], trimming uint, percentile uint, ) Rpm[Data] { // There may be more than one round trip accumulated together. If that is the case, // we will blow them apart in to three separate measurements and each one will just diff --git a/rpm/parameters.go b/rpm/parameters.go index aff8639..1d7e065 100644 --- a/rpm/parameters.go +++ b/rpm/parameters.go @@ -30,9 +30,10 @@ type SpecParameters struct { MaxParallelConns int ProbeInterval time.Duration ProbeCapacityPct float64 + Percentile uint } -func SpecParametersFromArguments(timeout int, mad int, id int, tmp uint, sdt float64, mnp int, mps int, ptc float64) (*SpecParameters, error) { +func SpecParametersFromArguments(timeout int, mad int, id int, tmp uint, sdt float64, mnp int, mps int, ptc float64, p int) (*SpecParameters, error) { if timeout <= 0 { return nil, fmt.Errorf("cannot specify a 0 or negative timeout for the test") } @@ -57,6 +58,9 @@ func SpecParametersFromArguments(timeout int, mad int, id int, tmp uint, sdt flo if ptc <= 0 { return nil, fmt.Errorf("cannot specify a 0 or negative probe capacity for the test") } + if p < 1 || p >= 100 { + return nil, fmt.Errorf("percentile for statistical calculations (%v) is invalid", p) + } testTimeout := time.Second * time.Duration(timeout) evalInterval := time.Second * time.Duration(id) probeInterval := utilities.PerSecondToInterval(int64(mps)) @@ -64,7 +68,7 @@ func SpecParametersFromArguments(timeout int, mad int, id int, tmp uint, sdt flo params := SpecParameters{ TestTimeout: testTimeout, MovingAvgDist: mad, EvalInterval: evalInterval, TrimmedMeanPct: tmp, StdDevTolerance: sdt, - MaxParallelConns: mnp, ProbeInterval: probeInterval, ProbeCapacityPct: ptc, + MaxParallelConns: mnp, ProbeInterval: probeInterval, ProbeCapacityPct: ptc, Percentile: uint(p), } return ¶ms, nil } diff --git a/rpm/parameters_test.go b/rpm/parameters_test.go index 4a955c5..2035a99 100644 --- a/rpm/parameters_test.go +++ b/rpm/parameters_test.go @@ -20,74 +20,89 @@ import ( ) func TestSpecParametersFromArgumentsBadTimeout(t *testing.T) { - _, err := SpecParametersFromArguments(0, 0, 0, 0, 0, 0, 0, 0) + _, err := SpecParametersFromArguments(0, 0, 0, 0, 0, 0, 0, 0, 0) if err == nil || !strings.Contains(err.Error(), "timeout") { t.Fatalf("0 timeout improperly allowed.") } - _, err = SpecParametersFromArguments(-1, 0, 0, 0, 0, 0, 0, 0) + _, err = SpecParametersFromArguments(-1, 0, 0, 0, 0, 0, 0, 0, 0) if err == nil || !strings.Contains(err.Error(), "timeout") { t.Fatalf("negative timeout improperly allowed.") } } func TestSpecParametersFromArgumentsBadMad(t *testing.T) { - _, err := SpecParametersFromArguments(1, 0, 0, 0, 0, 0, 0, 0) + _, err := SpecParametersFromArguments(1, 0, 0, 0, 0, 0, 0, 0, 0) if err == nil || !strings.Contains(err.Error(), "moving-average") { t.Fatalf("0 mad improperly allowed.") } - _, err = SpecParametersFromArguments(1, 0, 0, 0, 0, 0, 0, 0) + _, err = SpecParametersFromArguments(1, 0, 0, 0, 0, 0, 0, 0, 0) if err == nil || !strings.Contains(err.Error(), "moving-average") { t.Fatalf("negative mad improperly allowed.") } } func TestSpecParametersFromArgumentsBadId(t *testing.T) { - _, err := SpecParametersFromArguments(1, 1, 0, 0, 0, 0, 0, 0) + _, err := SpecParametersFromArguments(1, 1, 0, 0, 0, 0, 0, 0, 0) if err == nil || !strings.Contains(err.Error(), "reevaluation") { t.Fatalf("0 id improperly allowed.") } - _, err = SpecParametersFromArguments(1, 1, -1, 0, 0, 0, 0, 0) + _, err = SpecParametersFromArguments(1, 1, -1, 0, 0, 0, 0, 0, 0) if err == nil || !strings.Contains(err.Error(), "reevaluation") { t.Fatalf("negative id improperly allowed.") } } func TestSpecParametersFromArgumentsBadSdt(t *testing.T) { - _, err := SpecParametersFromArguments(1, 1, 1, 1, -1, 0, 0, 0) + _, err := SpecParametersFromArguments(1, 1, 1, 1, -1, 0, 0, 0, 0) if err == nil || !strings.Contains(err.Error(), "deviation") { t.Fatalf("0 sdt improperly allowed.") } } func TestSpecParametersFromArgumentsBadMnp(t *testing.T) { - _, err := SpecParametersFromArguments(1, 1, 1, 1, 1, 0, 0, 0) + _, err := SpecParametersFromArguments(1, 1, 1, 1, 1, 0, 0, 0, 0) if err == nil || !strings.Contains(err.Error(), "parallel") { t.Fatalf("0 mnp improperly allowed.") } - _, err = SpecParametersFromArguments(1, 1, 1, 1, 1, -1, 0, 0) + _, err = SpecParametersFromArguments(1, 1, 1, 1, 1, -1, 0, 0, 0) if err == nil || !strings.Contains(err.Error(), "parallel") { t.Fatalf("negative mnp improperly allowed.") } } func TestSpecParametersFromArgumentsBadMps(t *testing.T) { - _, err := SpecParametersFromArguments(1, 1, 1, 1, 1, 1, 0, 0) + _, err := SpecParametersFromArguments(1, 1, 1, 1, 1, 1, 0, 0, 0) if err == nil || !strings.Contains(err.Error(), "probing interval") { t.Fatalf("0 mps improperly allowed.") } - _, err = SpecParametersFromArguments(1, 1, 1, 1, 1, 1, -1, 0) + _, err = SpecParametersFromArguments(1, 1, 1, 1, 1, 1, -1, 0, 0) if err == nil || !strings.Contains(err.Error(), "probing interval") { t.Fatalf("negative mps improperly allowed.") } } func TestSpecParametersFromArgumentsBadPtc(t *testing.T) { - _, err := SpecParametersFromArguments(1, 1, 1, 1, 1, 1, 1, 0) + _, err := SpecParametersFromArguments(1, 1, 1, 1, 1, 1, 1, 0, 0) if err == nil || !strings.Contains(err.Error(), "capacity") { t.Fatalf("0 ptc improperly allowed.") } - _, err = SpecParametersFromArguments(1, 1, 1, 1, 1, 1, 1, -1) + _, err = SpecParametersFromArguments(1, 1, 1, 1, 1, 1, 1, -1, 0) if err == nil || !strings.Contains(err.Error(), "capacity") { t.Fatalf("negative ptc improperly allowed.") } } + +func TestSpecParametersFromArgumentsBadP(t *testing.T) { + _, err := SpecParametersFromArguments(1, 1, 1, 1, 1, 1, 1, 1, -1) + if err == nil || !strings.Contains(err.Error(), "percentile") { + t.Fatalf("-1 percentile improperly allowed.") + } + _, err = SpecParametersFromArguments(1, 1, 1, 1, 1, 1, 1, 1, 0) + if err == nil || !strings.Contains(err.Error(), "percentile") { + t.Fatalf("0 percentile improperly allowed.") + } + _, err = SpecParametersFromArguments(1, 1, 1, 1, 1, 1, 1, 1, 101) + if err == nil || !strings.Contains(err.Error(), "percentile") { + t.Fatalf("percentile greater than 100 improperly allowed.") + } +} diff --git a/series/statistics.go b/series/statistics.go index 2742aa7..96ec93b 100644 --- a/series/statistics.go +++ b/series/statistics.go @@ -18,7 +18,7 @@ func SeriesStandardDeviation[Data utilities.Number, Bucket constraints.Ordered]( return complete, utilities.CalculateStandardDeviation[Data](values) } -func Percentile[Data utilities.Number, Bucket constraints.Ordered](s WindowSeries[Data, Bucket], p int) (bool, Data) { +func Percentile[Data utilities.Number, Bucket constraints.Ordered](s WindowSeries[Data, Bucket], p uint) (bool, Data) { complete := s.Complete() inputValues := s.GetValues() |
