blob: 926db9c73bc30b754c0f3ca1965f2de477b7b38e [file] [log] [blame]
// Copyright 2019 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.
// Tests the constructors for formatting JSON output.
package source_generator
import (
"config"
"privacy"
"reflect"
"testing"
)
var testParamRecords = [][]string{
{"1.0", "10000", "1", "0.0024182694032788277", "9"},
{"1.0", "20000", "1", "0.0013450710102915764", "10"},
{"1.0", "10000", "2", "0.004249398596584797", "7"},
{"1.0", "20000", "2", "0.002368534915149212", "9"},
{"1.0", "10000", "10", "0.019537480548024178", "4"},
{"1.0", "20000", "10", "0.011127800680696964", "5"},
{"5.0", "10000", "1", "0.000906200148165226", "12"},
{"5.0", "20000", "1", "0.000491277314722538", "15"},
{"5.0", "10000", "2", "0.0009743086993694305", "12"},
{"5.0", "20000", "2", "0.0005256505683064461", "14"},
{"5.0", "10000", "10", "0.0014028092846274376", "10"},
{"5.0", "20000", "10", "0.0007524723187088966", "13"},
}
func constructTestJsonOutputter(t *testing.T) jsonOutputter {
paramsCalc, err := privacy.NewPrivacyEncodingParamsCalculatorForTesting(testParamRecords)
if err != nil {
t.Errorf("Failed to create error calculator.")
}
errorCalc := privacy.NewErrorCalculator(*paramsCalc)
return jsonOutputter{errorCalc}
}
func TestConstructorsHandleNil(t *testing.T) {
jo := constructTestJsonOutputter(t)
r := jo.makeJSONReport(nil, nil)
if reflect.DeepEqual(r, (jsonReport{})) == false {
t.Errorf("makeJSONReport failed to return empty report got = %#v", r)
}
m := jo.makeJSONMetric(nil)
if reflect.DeepEqual(m, (jsonMetric{})) == false {
t.Errorf("makeJSONMetric failed to return empty metric got = %#v", m)
}
p := jo.makeJSONProject(nil)
if reflect.DeepEqual(p, (jsonProject{})) == false {
t.Errorf("makeJSONProject failed to return empty project got = %#v", p)
}
c := jo.makeJSONCustomer(nil)
if reflect.DeepEqual(c, (jsonCustomer{})) == false {
t.Errorf("makeJSONCustomer failed to return empty customer got = %#v", c)
}
rg := jo.makeJSONRegistry(nil)
if reflect.DeepEqual(rg, (jsonRegistry{})) == false {
t.Errorf("makeJSONRegistry failed to return empty registry got = %#v", rg)
}
}
func TestMakeErrorEstimates(t *testing.T) {
jo := constructTestJsonOutputter(t)
r := config.ReportDefinition{
ReportType: config.ReportDefinition_UNIQUE_DEVICE_COUNTS,
PrivacyLevel: config.ReportDefinition_LOW_PRIVACY,
LocalAggregationProcedure: config.ReportDefinition_SELECT_FIRST,
}
m := config.MetricDefinition{
MetricType: config.MetricDefinition_OCCURRENCE,
}
want := jsonError{
"LOW_PRIVACY": jsonErrorEstimate{
Epsilon: 10,
Estimates: map[uint64]float64{10000: 3.014414887122711, 100000: 7.014287737614043, 1000000: 22.18112541464989},
},
"MEDIUM_PRIVACY": jsonErrorEstimate{
Epsilon: 5,
Estimates: map[uint64]float64{10000: 3.014414887122711, 100000: 7.014287737614043, 1000000: 22.18112541464989},
},
"HIGH_PRIVACY": jsonErrorEstimate{
Epsilon: 1,
Estimates: map[uint64]float64{10000: 4.935511431266572, 100000: 11.621179768978688, 1000000: 36.749397168242034},
},
}
got := jo.makeErrorEstimates(&r, &m, []uint64{10000, 100000, 1000000})
if reflect.DeepEqual(want, got) == false {
t.Errorf("makeJSONReport(%v)\n\n GOT: %v\nWANT: %v", r, got, want)
}
}
func TestMakeJSONReport(t *testing.T) {
jo := constructTestJsonOutputter(t)
name := "test_name"
id := uint32(123456789)
candidateFile := "test_file_name"
candidateList := []string{"candidate1", "candidate2"}
systemProfile := []config.SystemProfileField{config.SystemProfileField_OS, config.SystemProfileField_ARCH}
aggregationPercentile := uint32(80)
eventVectorBufferMax := uint64(10)
stringBufferMax := uint32(1234)
r := config.ReportDefinition{
ReportName: name,
Id: id,
ReportType: config.ReportDefinition_SIMPLE_OCCURRENCE_COUNT,
LocalPrivacyNoiseLevel: config.ReportDefinition_NOISE_LEVEL_UNSET,
PrivacyLevel: config.ReportDefinition_LOW_PRIVACY,
CandidateFile: candidateFile,
CandidateList: candidateList,
EventVectorBufferMax: eventVectorBufferMax,
StringBufferMax: stringBufferMax,
SystemProfileField: systemProfile,
AggregationType: config.ReportDefinition_SUM,
WindowSize: []config.WindowSize{config.WindowSize_WINDOW_7_DAYS},
LocalAggregationPeriod: config.WindowSize_WINDOW_7_DAYS,
LocalAggregationProcedure: config.ReportDefinition_SUM_PROCEDURE,
LocalAggregationProcedurePercentileN: aggregationPercentile,
}
m := config.MetricDefinition{
MetricName: name,
Id: id,
MetricType: config.MetricDefinition_EVENT_OCCURRED,
}
want := jsonReport{
Name: name,
Id: id,
ReportType: "SIMPLE_OCCURRENCE_COUNT",
ReportTypeId: int32(config.ReportDefinition_SIMPLE_OCCURRENCE_COUNT),
LocalPrivacyNoiseLevel: "NOISE_LEVEL_UNSET",
PrivacyLevel: "LOW_PRIVACY",
ErrorEstimates: nil,
CandidateFile: candidateFile,
CandidateList: candidateList,
EventVectorBufferMax: eventVectorBufferMax,
StringBufferMax: stringBufferMax,
SystemProfileField: []string{"OS", "ARCH"},
AggregationType: "SUM",
WindowSize: []string{"WINDOW_7_DAYS"},
LocalAggregationPeriod: 7,
LocalAggregationProcedure: "SUM_PROCEDURE",
LocalAggregationProcedurePercentileN: aggregationPercentile,
}
got := jo.makeJSONReport(&r, &m)
if reflect.DeepEqual(want, got) == false {
t.Errorf("makeJSONReport(%#v)\n\n GOT: %#v\nWANT: %#v", r, got, want)
}
}
func TestMakeJSONMetric(t *testing.T) {
jo := constructTestJsonOutputter(t)
name := "test_name"
id := uint32(123456789)
owners := []string{"owners", "owner2"}
expirationDate := "2019/11/05"
reports := []*config.ReportDefinition{nil, nil}
meta := config.MetricDefinition_Metadata{
ExpirationDate: expirationDate,
Owner: owners,
}
dimension := []*config.MetricDefinition_MetricDimension{
&config.MetricDefinition_MetricDimension{
Dimension: "test_dimension",
MaxEventCode: 3,
},
}
metricUnitOther := "test_metric_unit"
candidateFile := "test_candidate_file_string"
protoName := "test_proto_name"
replacementId := uint32(12345)
m := config.MetricDefinition{
MetricName: name,
Id: id,
MetricType: config.MetricDefinition_EVENT_OCCURRED,
MetaData: &meta,
MetricDimensions: dimension,
MetricSemantics: []config.MetricSemantics{
config.MetricSemantics_CPU,
config.MetricSemantics_DATA_SIZE,
},
MetricUnits: config.MetricUnits_NANOSECONDS,
MetricUnitsOther: metricUnitOther,
StringCandidateFile: candidateFile,
ProtoName: protoName,
ReplacementMetricId: replacementId,
Reports: reports,
}
emptyReports := []jsonReport{jsonReport{}, jsonReport{}}
want := jsonMetric{
Name: name,
Id: id,
MetricType: "EVENT_OCCURRED",
Owners: owners,
ExpirationDate: expirationDate,
Dimensions: []string{"test_dimension"},
MaxEventCode: []uint32{3},
Semantics: []string{"CPU", "DATA_SIZE"},
Units: "NANOSECONDS",
UnitsOther: metricUnitOther,
StringCandidateFile: candidateFile,
ProtoName: protoName,
ReplacementMetricId: replacementId,
Reports: emptyReports,
}
got := jo.makeJSONMetric(&m)
if reflect.DeepEqual(want, got) == false {
t.Errorf("makeJSONMetric(%#v)\n\n GOT: %#v\nWANT: %#v", m, got, want)
}
}
func TestMakeJSONMetricEmptyMetadata(t *testing.T) {
jo := constructTestJsonOutputter(t)
name := "test_name"
reports := []*config.ReportDefinition{nil, nil}
m := config.MetricDefinition{
MetricName: name,
MetaData: nil,
Reports: reports,
}
emptyReports := []jsonReport{jsonReport{}, jsonReport{}}
want := jsonMetric{
Name: name,
MetricType: "UNSET",
Units: "METRIC_UNITS_OTHER",
Reports: emptyReports,
}
got := jo.makeJSONMetric(&m)
if reflect.DeepEqual(want, got) == false {
t.Errorf("makeJSONMetric(%#v)\n\n GOT: %#v\nWANT: %#v", m, got, want)
}
}
func TestMakeJSONProject(t *testing.T) {
jo := constructTestJsonOutputter(t)
name := "test_name"
id := uint32(123456789)
metrics := []*config.MetricDefinition{nil, nil}
contact := "contact_test_string"
p := config.ProjectConfig{
ProjectName: name,
ProjectId: id,
Metrics: metrics,
ProjectContact: contact,
}
emptyMetrics := []jsonMetric{jsonMetric{}, jsonMetric{}}
want := jsonProject{
Name: name,
Id: id,
Contact: contact,
Metrics: emptyMetrics,
}
got := jo.makeJSONProject(&p)
if reflect.DeepEqual(want, got) == false {
t.Errorf("makeJSONProject(%#v)\n\n GOT: %#v\nWANT: %#v", p, got, want)
}
}
func TestMakeJSONCustomer(t *testing.T) {
jo := constructTestJsonOutputter(t)
name := "test_name"
id := uint32(123456789)
projects := []*config.ProjectConfig{nil, nil}
c := config.CustomerConfig{
CustomerName: name,
CustomerId: id,
Projects: projects,
}
emptyProjects := []jsonProject{jsonProject{}, jsonProject{}}
want := jsonCustomer{
Name: name,
Id: id,
Projects: emptyProjects,
}
got := jo.makeJSONCustomer(&c)
if reflect.DeepEqual(want, got) == false {
t.Errorf("makeJSONCustomer(%#v)\n\n GOT: %#v\nWANT: %#v", c, got, want)
}
}
func TestMakeJSONRegistry(t *testing.T) {
jo := constructTestJsonOutputter(t)
customers := []*config.CustomerConfig{nil, nil}
r := config.CobaltRegistry{
Customers: customers,
}
emptyCustomers := []jsonCustomer{jsonCustomer{}, jsonCustomer{}}
want := jsonRegistry{
Customers: emptyCustomers,
}
got := jo.makeJSONRegistry(&r)
if reflect.DeepEqual(want, got) == false {
t.Errorf("makeJSONRegistry(%#v)\n\n GOT: %#v\nWANT: %#v", r, got, want)
}
}