blob: 269b7c85e9cc48577901fcc6fc624cb88a6d3d45 [file] [log] [blame]
// Copyright 2020 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package config_validator
import (
"config"
"fmt"
)
// This file contains logic to validate integer_buckets in protos.
// Check that int_buckets is set for the correct metrics and reports.
func checkHasIntBuckets(m config.MetricDefinition, r config.ReportDefinition) error {
if m.MetricType == config.MetricDefinition_INT_HISTOGRAM || m.MetricType == config.MetricDefinition_INTEGER_HISTOGRAM {
// IntBuckets should be defined in the metric.
if m.IntBuckets == nil {
return fmt.Errorf("%s metric types must define an int_buckets field.", m.MetricType)
}
// IntBuckets should not be redefined in a report.
if r.IntBuckets != nil {
return fmt.Errorf("Reports for a %s metric must not redefine int_buckets.", m.MetricType)
}
} else {
// Other metric types should not have int_buckets set.
if m.IntBuckets != nil {
return fmt.Errorf("int_buckets should not be specified for metrics of type %s.", m.MetricType)
}
// Check that specific report types contain int_buckets.
switch r.ReportType {
case config.ReportDefinition_PER_DEVICE_HISTOGRAM:
fallthrough
case config.ReportDefinition_INT_RANGE_HISTOGRAM:
fallthrough
case config.ReportDefinition_UNIQUE_DEVICE_HISTOGRAMS:
fallthrough
case config.ReportDefinition_HOURLY_VALUE_HISTOGRAMS:
fallthrough
case config.ReportDefinition_FLEETWIDE_HISTOGRAMS:
if r.IntBuckets == nil {
return fmt.Errorf("No int_buckets specified for report of type %s.", r.ReportType)
}
}
}
return nil
}
func validateIntBucketsForReport(m config.MetricDefinition, r config.ReportDefinition) error {
if err := checkHasIntBuckets(m, r); err != nil {
return err
}
if r.IntBuckets != nil {
// If it exists, the report bucket config takes priority.
return validateIntBuckets(*r.IntBuckets)
} else if m.IntBuckets != nil {
return validateIntBuckets(*m.IntBuckets)
}
return nil
}
// Validate the fields in an int_buckets.
func validateIntBuckets(bucket config.IntegerBuckets) error {
if bucket_value := bucket.GetLinear(); bucket_value != nil {
if bucket_value.NumBuckets < 1 {
return fmt.Errorf("Linear bucket must set a num_buckets greater than or equal to 1.")
}
if bucket_value.StepSize < 1 {
return fmt.Errorf("Linear bucket must set a step_size greater than or equal to 1.")
}
} else if bucket_value := bucket.GetExponential(); bucket_value != nil {
if bucket_value.NumBuckets < 1 {
return fmt.Errorf("Exponential bucket must set a num_buckets greater than or equal to 1.")
}
if bucket_value.InitialStep < 1 {
return fmt.Errorf("Exponential bucket must set an InitialStep greater than or equal to 1.")
}
if bucket_value.StepMultiplier < 1 {
return fmt.Errorf("Exponential bucket must set a step_multiplier greater than or equal to 1.")
}
} else {
return fmt.Errorf("int_config must define either a linear or exponential bucket definition.")
}
return nil
}