blob: ab9d4be79a79d7c190285ee072005272c67b8919 [file] [log] [blame]
//
// Copyright 2019 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#include "proto/util.h"
#include <string>
#include "gmock/gmock.h"
#include "gtest/gtest.h"
namespace differential_privacy {
namespace {
using ::testing::Eq;
const double kLowerBound = -2.5;
const double kUpperBound = 3.2;
const double kConfidenceLevel = 0.95;
const std::vector<double> kLowerBounds = {-1.2, -3.4, -5.6, -7.8, -9.0};
const std::vector<double> kUpperBounds = {1.2, 3.4, 5.6, 7.8, 9.0};
const std::vector<double> kConfidenceLevels = {0.1, 0.25, 0.50, 0.75, 0.99};
TEST(UtilTest, GetSetValueTypeInt) {
ValueType v;
SetValue(&v, 10);
EXPECT_TRUE(v.has_int_value());
EXPECT_THAT(GetValue<int64_t>(v), Eq(10));
}
TEST(UtilTest, GetSetValueTypeString) {
ValueType v;
SetValue(&v, "test");
EXPECT_TRUE(v.has_string_value());
EXPECT_THAT(GetValue<std::string>(v), Eq("test"));
}
TEST(UtilTest, GetSetValueTypeFloat) {
ValueType v;
SetValue(&v, 10.0);
EXPECT_TRUE(v.has_float_value());
EXPECT_THAT(GetValue<double>(v), Eq(10.0));
}
TEST(UtilTest, MakeOutputString) {
std::string s = "hello";
Output output = MakeOutput<std::string>(s);
EXPECT_EQ(GetValue<std::string>(output), s);
}
TEST(UtilTest, MakeOutputInt) {
int i = 1;
Output output = MakeOutput<int>(i);
EXPECT_EQ(GetValue<int>(output), i);
}
TEST(UtilTest, MakeOutputFloat) {
double d = .1;
Output output = MakeOutput<double>(d);
EXPECT_EQ(GetValue<double>(output), d);
}
TEST(UtilTest, MakeOutputStringWithConfidenceInterval) {
std::string s = "hello";
ConfidenceInterval ci;
ci.set_lower_bound(kLowerBound);
ci.set_upper_bound(kUpperBound);
ci.set_confidence_level(kConfidenceLevel);
Output output = MakeOutput<std::string>(s, ci);
ConfidenceInterval output_ci = GetNoiseConfidenceInterval(output);
EXPECT_EQ(GetValue<std::string>(output), s);
EXPECT_EQ(output_ci.lower_bound(), ci.lower_bound());
EXPECT_EQ(output_ci.upper_bound(), ci.upper_bound());
EXPECT_EQ(output_ci.confidence_level(), ci.confidence_level());
// Although the ErrorReport.noise_confidence_interval is deprecated, we still
// keep it updated for a more seamless transition for existing clients. After
// some time, we should no longer use ErrorReport.noise_confidence_interval.
// But for now, test to make sure ErrorReport.noise_confidence_interval is
// being set.
EXPECT_EQ(output.error_report().noise_confidence_interval().lower_bound(),
ci.lower_bound());
EXPECT_EQ(output.error_report().noise_confidence_interval().upper_bound(),
ci.upper_bound());
EXPECT_EQ(
output.error_report().noise_confidence_interval().confidence_level(),
ci.confidence_level());
}
TEST(UtilTest, MakeOutputIntWithConfidenceInterval) {
int i = 1;
ConfidenceInterval ci;
ci.set_lower_bound(kLowerBound);
ci.set_upper_bound(kUpperBound);
ci.set_confidence_level(kConfidenceLevel);
Output output = MakeOutput<int>(i, ci);
ConfidenceInterval output_ci = GetNoiseConfidenceInterval(output);
EXPECT_EQ(GetValue<int>(output), i);
EXPECT_EQ(output_ci.lower_bound(), ci.lower_bound());
EXPECT_EQ(output_ci.upper_bound(), ci.upper_bound());
EXPECT_EQ(output_ci.confidence_level(), ci.confidence_level());
// Although the ErrorReport.noise_confidence_interval is deprecated, we still
// keep it updated for a more seamless transition for existing clients. After
// some time, we should no longer use ErrorReport.noise_confidence_interval.
// But for now, test to make sure ErrorReport.noise_confidence_interval is
// being set.
EXPECT_EQ(output.error_report().noise_confidence_interval().lower_bound(),
ci.lower_bound());
EXPECT_EQ(output.error_report().noise_confidence_interval().upper_bound(),
ci.upper_bound());
EXPECT_EQ(
output.error_report().noise_confidence_interval().confidence_level(),
ci.confidence_level());
}
TEST(UtilTest, MakeOutputFloatWithConfidenceInterval) {
double d = .1;
ConfidenceInterval ci;
ci.set_lower_bound(kLowerBound);
ci.set_upper_bound(kUpperBound);
ci.set_confidence_level(kConfidenceLevel);
Output output = MakeOutput<double>(d, ci);
ConfidenceInterval output_ci = GetNoiseConfidenceInterval(output);
EXPECT_EQ(GetValue<double>(output), d);
EXPECT_EQ(output_ci.lower_bound(), ci.lower_bound());
EXPECT_EQ(output_ci.upper_bound(), ci.upper_bound());
EXPECT_EQ(output_ci.confidence_level(), ci.confidence_level());
// Although the ErrorReport.noise_confidence_interval is deprecated, we still
// keep it updated for a more seamless transition for existing clients. After
// some time, we should no longer use ErrorReport.noise_confidence_interval.
// But for now, test to make sure ErrorReport.noise_confidence_interval is
// being set.
EXPECT_EQ(output.error_report().noise_confidence_interval().lower_bound(),
ci.lower_bound());
EXPECT_EQ(output.error_report().noise_confidence_interval().upper_bound(),
ci.upper_bound());
EXPECT_EQ(
output.error_report().noise_confidence_interval().confidence_level(),
ci.confidence_level());
}
TEST(UtilTest, AddToOutputString) {
Output output;
AddToOutput<std::string>(&output, "1");
EXPECT_EQ(GetValue<std::string>(output), "1");
}
TEST(UtilTest, AddToOutputInt) {
Output output;
AddToOutput<int>(&output, 1);
EXPECT_EQ(GetValue<int>(output), 1);
}
TEST(UtilTest, AddToOutputFloat) {
Output output;
AddToOutput<double>(&output, .5);
EXPECT_EQ(GetValue<double>(output), .5);
}
TEST(UtilTest, AddToOutputStringWithConfidenceInterval) {
Output output;
ConfidenceInterval ci;
ci.set_lower_bound(kLowerBound);
ci.set_upper_bound(kUpperBound);
ci.set_confidence_level(kConfidenceLevel);
AddToOutput<std::string>(&output, "1", ci);
ConfidenceInterval output_ci = GetNoiseConfidenceInterval(output);
EXPECT_EQ(GetValue<std::string>(output), "1");
EXPECT_EQ(output_ci.lower_bound(), ci.lower_bound());
EXPECT_EQ(output_ci.upper_bound(), ci.upper_bound());
EXPECT_EQ(output_ci.confidence_level(), ci.confidence_level());
}
TEST(UtilTest, AddToOutputIntWithConfidenceInterval) {
Output output;
ConfidenceInterval ci;
ci.set_lower_bound(kLowerBound);
ci.set_upper_bound(kUpperBound);
ci.set_confidence_level(kConfidenceLevel);
AddToOutput<int>(&output, 1, ci);
ConfidenceInterval output_ci = GetNoiseConfidenceInterval(output);
EXPECT_EQ(GetValue<int>(output), 1);
EXPECT_EQ(output_ci.lower_bound(), ci.lower_bound());
EXPECT_EQ(output_ci.upper_bound(), ci.upper_bound());
EXPECT_EQ(output_ci.confidence_level(), ci.confidence_level());
}
TEST(UtilTest, AddToOutputFloatWithConfidenceInterval) {
Output output;
ConfidenceInterval ci;
ci.set_lower_bound(kLowerBound);
ci.set_upper_bound(kUpperBound);
ci.set_confidence_level(kConfidenceLevel);
AddToOutput<double>(&output, .5, ci);
ConfidenceInterval output_ci = GetNoiseConfidenceInterval(output);
EXPECT_EQ(GetValue<double>(output), .5);
EXPECT_EQ(output_ci.lower_bound(), ci.lower_bound());
EXPECT_EQ(output_ci.upper_bound(), ci.upper_bound());
EXPECT_EQ(output_ci.confidence_level(), ci.confidence_level());
}
TEST(UtilTest, MultipleAddToOutputStringWithConfidenceInterval) {
std::vector<std::string> data = {"1", "-2", "3", "-4", "5"};
Output output;
for (int i = 0; i < data.size(); ++i) {
ConfidenceInterval ci;
ci.set_lower_bound(kLowerBounds[i]);
ci.set_upper_bound(kUpperBounds[i]);
ci.set_confidence_level(kConfidenceLevels[i]);
AddToOutput<std::string>(&output, data[i], ci);
}
for (int i = 0; i < data.size(); ++i) {
ConfidenceInterval output_ci = GetNoiseConfidenceInterval(output, i);
EXPECT_EQ(GetValue<std::string>(output, i), data[i]);
EXPECT_EQ(output_ci.lower_bound(), kLowerBounds[i]);
EXPECT_EQ(output_ci.upper_bound(), kUpperBounds[i]);
EXPECT_EQ(output_ci.confidence_level(), kConfidenceLevels[i]);
}
}
TEST(UtilTest, MultipleAddToOutputIntWithConfidenceInterval) {
std::vector<int> data = {1, -2, 3, -4, 5};
Output output;
for (int i = 0; i < data.size(); ++i) {
ConfidenceInterval ci;
ci.set_lower_bound(kLowerBounds[i]);
ci.set_upper_bound(kUpperBounds[i]);
ci.set_confidence_level(kConfidenceLevels[i]);
AddToOutput<int>(&output, data[i], ci);
}
for (int i = 0; i < data.size(); ++i) {
ConfidenceInterval output_ci = GetNoiseConfidenceInterval(output, i);
EXPECT_EQ(GetValue<int>(output, i), data[i]);
EXPECT_EQ(output_ci.lower_bound(), kLowerBounds[i]);
EXPECT_EQ(output_ci.upper_bound(), kUpperBounds[i]);
EXPECT_EQ(output_ci.confidence_level(), kConfidenceLevels[i]);
}
}
TEST(UtilTest, MultipleAddToOutputFloatWithConfidenceInterval) {
std::vector<double> data = {1.0, -2.3, 4.5, -6.7, 8.9};
Output output;
for (int i = 0; i < data.size(); ++i) {
ConfidenceInterval ci;
ci.set_lower_bound(kLowerBounds[i]);
ci.set_upper_bound(kUpperBounds[i]);
ci.set_confidence_level(kConfidenceLevels[i]);
AddToOutput<double>(&output, data[i], ci);
}
for (int i = 0; i < data.size(); ++i) {
ConfidenceInterval output_ci = GetNoiseConfidenceInterval(output, i);
EXPECT_EQ(GetValue<double>(output, i), data[i]);
EXPECT_EQ(output_ci.lower_bound(), kLowerBounds[i]);
EXPECT_EQ(output_ci.upper_bound(), kUpperBounds[i]);
EXPECT_EQ(output_ci.confidence_level(), kConfidenceLevels[i]);
}
}
TEST(UtilTest, MakeValueType) {
ValueType v = MakeValueType(1.0);
EXPECT_TRUE(v.has_float_value());
EXPECT_EQ(v.float_value(), 1.0);
}
} // namespace
} // namespace differential_privacy