blob: a8933947c62f2bfcabfcb896a16250950e1f2086 [file]
//
// 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 "base/percentile.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "proto/summary.pb.h"
namespace differential_privacy {
namespace base {
namespace {
template <typename T>
class PercentileTest : public ::testing::Test {};
typedef ::testing::Types<int64_t, double> NumericTypes;
TYPED_TEST_SUITE(PercentileTest, NumericTypes);
TYPED_TEST(PercentileTest, EmptyInputSet) {
Percentile<TypeParam> percentile;
EXPECT_EQ(percentile.num_values(), 0);
EXPECT_EQ(std::make_pair(0.0, 1.0), percentile.GetRelativeRank(1));
}
TYPED_TEST(PercentileTest, SingletonInputSet) {
Percentile<TypeParam> percentile;
percentile.Add(1);
EXPECT_EQ(percentile.num_values(), 1);
EXPECT_EQ(std::make_pair(0.0, 0.0), percentile.GetRelativeRank(0));
EXPECT_EQ(std::make_pair(0.0, 1.0), percentile.GetRelativeRank(1));
EXPECT_EQ(std::make_pair(1.0, 1.0), percentile.GetRelativeRank(10));
}
TYPED_TEST(PercentileTest, SmallInputSet) {
Percentile<TypeParam> percentile;
percentile.Add(5);
percentile.Add(3);
percentile.Add(3);
percentile.Add(5);
percentile.Add(1);
EXPECT_EQ(percentile.num_values(), 5);
EXPECT_EQ(std::make_pair(0.0, 0.0), percentile.GetRelativeRank(-1));
EXPECT_EQ(std::make_pair(0.0, 0.2), percentile.GetRelativeRank(1));
EXPECT_EQ(std::make_pair(0.2, 0.2), percentile.GetRelativeRank(2));
EXPECT_EQ(std::make_pair(0.2, 0.6), percentile.GetRelativeRank(3));
EXPECT_EQ(std::make_pair(0.6, 0.6), percentile.GetRelativeRank(4));
EXPECT_EQ(std::make_pair(0.6, 1.0), percentile.GetRelativeRank(5));
EXPECT_EQ(std::make_pair(1.0, 1.0), percentile.GetRelativeRank(6));
}
TYPED_TEST(PercentileTest, LargeInputSet) {
Percentile<TypeParam> percentile;
int num_repeats = 3;
TypeParam num_values = 10000;
for (TypeParam i = num_values; i > 0; --i) {
for (int j = 0; j < num_repeats; ++j) {
percentile.Add(i);
}
}
EXPECT_EQ(std::make_pair(52.0 / num_values, 53.0 / num_values),
percentile.GetRelativeRank(53));
EXPECT_EQ(std::make_pair(0.0, 1.0 / num_values),
percentile.GetRelativeRank(1));
EXPECT_EQ(std::make_pair((num_values - 1.0) / num_values, 1.0),
percentile.GetRelativeRank(num_values));
}
TYPED_TEST(PercentileTest, Reset) {
Percentile<TypeParam> percentile;
percentile.Add(1);
percentile.Reset();
EXPECT_EQ(percentile.num_values(), 0);
}
TYPED_TEST(PercentileTest, Memory) {
Percentile<TypeParam> percentile;
int64_t small_memory = percentile.Memory();
percentile.Add(1);
int64_t large_memory = percentile.Memory();
EXPECT_LT(small_memory, large_memory);
}
TYPED_TEST(PercentileTest, SerializeMerge) {
Percentile<TypeParam> percentile;
percentile.Add(4);
BinarySearchSummary summary;
percentile.SerializeToProto(summary.mutable_input());
Percentile<TypeParam> percentile2;
percentile2.Add(2);
percentile2.MergeFromProto(summary.input());
percentile2.Add(3);
percentile2.Add(1);
EXPECT_EQ(std::make_pair(.25, .5), percentile2.GetRelativeRank(2));
}
} // namespace
} // namespace base
} // namespace differential_privacy