| // Copyright 2018 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" |
| "testing" |
| ) |
| |
| // makeValidReport returns a valid instance of config.ReportDefinition which |
| // can be modified to fail various validation checks for testing purposes. |
| func makeValidReport() config.ReportDefinition { |
| return makeValidReportWithName("the_report_name") |
| } |
| |
| func makeValidReportWithName(name string) config.ReportDefinition { |
| return config.ReportDefinition{ |
| Id: 10, |
| ReportName: name, |
| ReportType: config.ReportDefinition_EVENT_COMPONENT_OCCURRENCE_COUNT, |
| } |
| } |
| |
| // Test that makeValidReport returns a valid report. |
| func TestValidateMakeValidReport(t *testing.T) { |
| r := makeValidReport() |
| if err := validateReportDefinition(r); err != nil { |
| t.Errorf("Rejected valid report: %v", err) |
| } |
| } |
| |
| func TestDifferentReportId(t *testing.T) { |
| r := makeValidReport() |
| r.Id += 1 |
| |
| if err := validateReportDefinition(r); err != nil { |
| t.Error("Reject report with different report id.") |
| } |
| } |
| |
| func TestValidateInvalidName(t *testing.T) { |
| r := makeValidReportWithName("_invalid_name") |
| |
| if err := validateReportDefinition(r); err == nil { |
| t.Error("Accepted report with invalid name.") |
| } |
| } |
| |
| func TestValidateZeroReportId(t *testing.T) { |
| r := makeValidReportWithName("NRaMinLNcqiYmgEypLLVGnXymNpxJzqabtbbjLycCMEohvVzZtAYpah") |
| r.Id = 0 |
| |
| if err := validateReportDefinition(r); err == nil { |
| t.Error("Accepted report with 0 id.") |
| } |
| } |
| |
| func TestValidateUnsetReportType(t *testing.T) { |
| if err := validateReportType(config.MetricDefinition_EVENT_OCCURRED, config.ReportDefinition_REPORT_TYPE_UNSET); err == nil { |
| t.Error("Accepted report with no report type set.") |
| } |
| } |
| |
| // Test that validateLocalPrivacyNoiseLevel accepts a ReportDefinition if and only if it has a local_privacy_noise_level field. |
| func TestValidateLocalPrivacyNoiseLevel(t *testing.T) { |
| r := makeValidReport() |
| |
| if err := validateLocalPrivacyNoiseLevel(r); err == nil { |
| t.Error("Accepted report definition with local_privacy_noise_level unset.") |
| } |
| |
| r.LocalPrivacyNoiseLevel = config.ReportDefinition_SMALL |
| if err := validateLocalPrivacyNoiseLevel(r); err != nil { |
| t.Errorf("Rejected report definition with local_privacy_noise_level set: %v", err) |
| } |
| } |
| |
| // Test that validateWindowSize rejects a ReportDefinition with no window_size field, and a ReportDefinition with a |
| // window_size field where one of the window sizes is UNSET. |
| func TestValidateWindowSize(t *testing.T) { |
| r := makeValidReport() |
| |
| if err := validateWindowSize(r); err == nil { |
| t.Error("Accepted report definition without window_size field.") |
| } |
| |
| r.WindowSize = []config.WindowSize{config.WindowSize_WINDOW_1_DAY, config.WindowSize_UNSET} |
| if err := validateWindowSize(r); err == nil { |
| t.Error("Accepted report definition with an UNSET window size.") |
| } |
| |
| r.WindowSize = []config.WindowSize{config.WindowSize_WINDOW_1_DAY, config.WindowSize_WINDOW_7_DAYS} |
| if err := validateWindowSize(r); err != nil { |
| t.Errorf("Rejected report definition with valid window_size field: %v", err) |
| } |
| } |
| |
| // Test that local_privacy_noise_level must be set if the report type is SIMPLE_OCCURRENCE_COUNT. |
| func TestValidateReportDefinitionForSimpleOccurrenceCount(t *testing.T) { |
| r := makeValidReport() |
| r.ReportType = config.ReportDefinition_SIMPLE_OCCURRENCE_COUNT |
| |
| if err := validateReportDefinition(r); err == nil { |
| t.Error("Accepted report definition of type SIMPLE_OCCURRENCE_COUNT with local_privacy_noise_level unset.") |
| } |
| } |
| |
| // Test that local_privacy_noise_level and window_size must be set if the report type is UNIQUE_N_DAY_ACTIVES. |
| func TestValidateReportDefinitionForUniqueActives(t *testing.T) { |
| r := makeValidReport() |
| r.ReportType = config.ReportDefinition_UNIQUE_N_DAY_ACTIVES |
| |
| // Add a valid window_size, but not a local_privacy_noise_level. |
| r.WindowSize = []config.WindowSize{config.WindowSize_WINDOW_1_DAY} |
| if err := validateReportDefinition(r); err == nil { |
| t.Error("Accepted report definition of type UNIQUE_N_DAY_ACTIVES with local_privacy_noise_level unset.") |
| } |
| |
| // Remove window_size and add a local_privacy_noise_level. |
| r.WindowSize = []config.WindowSize{} |
| r.LocalPrivacyNoiseLevel = config.ReportDefinition_SMALL |
| if err := validateReportDefinition(r); err == nil { |
| t.Error("Accepted report definition of type UNIQUE_N_DAY_ACTIVES without window_size field.") |
| } |
| |
| // Add a valid window size to window_size, but also add an UNSET window size. |
| r.WindowSize = []config.WindowSize{config.WindowSize_WINDOW_1_DAY, config.WindowSize_UNSET} |
| if err := validateReportDefinition(r); err == nil { |
| t.Error("Accepted report definition of type UNIQUE_N_DAY_ACTIVES with window_size field containing an UNSET window size.") |
| } |
| } |
| |
| // Test that window_size must be set if the report type is PER_DEVICE_NUMERIC_STATS. |
| func TestValidateReportDefinitionForPerDeviceNumericStats(t *testing.T) { |
| r := makeValidReport() |
| r.ReportType = config.ReportDefinition_PER_DEVICE_NUMERIC_STATS |
| |
| if err := validateReportDefinition(r); err == nil { |
| t.Error("Accepted report definition of type PER_DEVICE_NUMERIC_STATS without window_size field.") |
| } |
| |
| // Add a valid window size to window_size, but also add an UNSET window size. |
| r.WindowSize = []config.WindowSize{config.WindowSize_WINDOW_1_DAY, config.WindowSize_UNSET} |
| if err := validateReportDefinition(r); err == nil { |
| t.Error("Accepted report definition of type PER_DEVICE_NUMERIC_STATS with window_size field containing an UNSET window size.") |
| } |
| } |
| |
| // Test that window_size must be set if the report type is PER_DEVICE_HISTOGRAM. |
| func TestValidateReportDefinitionForPerDeviceHistogram(t *testing.T) { |
| r := makeValidReport() |
| r.ReportType = config.ReportDefinition_PER_DEVICE_HISTOGRAM |
| |
| if err := validateReportDefinition(r); err == nil { |
| t.Error("No int_buckets specified for report of type PER_DEVICE_HISTOGRAM.") |
| } |
| |
| r.IntBuckets = &config.IntegerBuckets{} |
| if err := validateReportDefinition(r); err == nil { |
| t.Error("Accepted report definition of type PER_DEVICE_HISTOGRAM without window_size field.") |
| } |
| |
| // Add a valid window size to window_size, but also add an UNSET window size. |
| r.WindowSize = []config.WindowSize{config.WindowSize_WINDOW_1_DAY, config.WindowSize_UNSET} |
| if err := validateReportDefinition(r); err == nil { |
| t.Error("Accepted report definition of type PER_DEVICE_HISTOGRAM with window_size field containing an UNSET window size.") |
| } |
| } |
| |
| // Test percentiles range for NUMERIC_AGGREGATION report types. |
| func TestValidateReportDefinitionForNumericAggregation(t *testing.T) { |
| r := makeValidReport() |
| r.ReportType = config.ReportDefinition_NUMERIC_AGGREGATION |
| |
| // Test that percentiles are optional. |
| if err := validateReportDefinition(r); err != nil { |
| t.Error("Rejected report definition of type NUMERIC_AGGREGATION with no percentiles set.") |
| } |
| |
| // Test that percentiles between 0 and 100 are accepted. |
| r.Percentiles = []uint32{0, 25, 50, 75, 90, 99, 100} |
| if err := validateReportDefinition(r); err != nil { |
| t.Error("Rejected report definition of type NUMERIC_AGGREGATION with valid percentiles.") |
| } |
| |
| // Test that out of bounds percentiles are rejected. |
| r.Percentiles = []uint32{0, 25, 50, 75, 100, 101} |
| if err := validateReportDefinition(r); err == nil { |
| t.Error("Accepted report definition of type NUMERIC_AGGREGATION with invalid percentiles.") |
| } |
| } |