This commit has the initial ODK library. Partners may use this code to begin integrating the ODK library into their platform. The functionality is not complete, but this should help partners get an early start playing with build files.
148 lines
4.0 KiB
C++
148 lines
4.0 KiB
C++
// Copyright 2019 Google LLC. All Rights Reserved. This file and proprietary
|
|
// source code may only be used and distributed under the Widevine Master
|
|
// License Agreement.
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <chrono>
|
|
#include <limits>
|
|
#include <string>
|
|
#include <thread>
|
|
|
|
#include <gmock/gmock.h>
|
|
#include <gtest/gtest.h>
|
|
|
|
#include "cdm_random.h"
|
|
|
|
namespace wvcdm {
|
|
|
|
namespace {
|
|
// Random data vector lengths.
|
|
constexpr size_t kVectorLength = 1024;
|
|
constexpr size_t kMaxRandomDataLength =
|
|
CdmRandomGenerator::kMaxRandomDataLength;
|
|
constexpr size_t kAboveMaxRandomDataLength = std::numeric_limits<size_t>::max();
|
|
|
|
constexpr size_t kRandomTrialCount = 100;
|
|
constexpr size_t kThreadCount = 16;
|
|
constexpr unsigned int kSeeds[] = {0, 1337, 1565904109, 776964657};
|
|
|
|
class CdmRandomGeneratorTest : public testing::TestWithParam<unsigned int> {};
|
|
} // namespace
|
|
|
|
TEST_P(CdmRandomGeneratorTest, AllMethods) {
|
|
const unsigned int seed = GetParam();
|
|
CdmRandomGenerator rng;
|
|
rng.Seed();
|
|
rng.Seed(seed);
|
|
|
|
rng.Rand();
|
|
rng();
|
|
|
|
rng.RandomInRange(1234, 1000000);
|
|
rng.RandomInRange(1000000);
|
|
|
|
rng.RandomData(kVectorLength);
|
|
|
|
rng.RandomBool();
|
|
}
|
|
|
|
TEST_P(CdmRandomGeneratorTest, RandomInRange) {
|
|
const unsigned int seed = GetParam();
|
|
CdmRandomGenerator rng(seed);
|
|
|
|
for (size_t i = 0; i < kRandomTrialCount; ++i) {
|
|
const int rand_int = rng.Rand();
|
|
EXPECT_GE(rand_int, 0);
|
|
EXPECT_LE(rand_int, RAND_MAX);
|
|
}
|
|
|
|
// Range size of 1.
|
|
const uint64_t rand_u64_1 = rng.RandomInRange(100, 100);
|
|
EXPECT_EQ(rand_u64_1, 100ul);
|
|
|
|
// Range size of 2.
|
|
const uint64_t rand_u64_2 = rng.RandomInRange(1234, 1235);
|
|
EXPECT_GE(rand_u64_2, 1234ul);
|
|
EXPECT_LE(rand_u64_2, 1235ul);
|
|
|
|
// Small range.
|
|
const uint64_t rand_u64_3 = rng.RandomInRange(10);
|
|
EXPECT_LE(rand_u64_3, 10ul);
|
|
|
|
// Max range, mainly checking that nothing crashes.
|
|
rng.RandomInRange(0, std::numeric_limits<uint64_t>::max());
|
|
|
|
// Invalid range representation. Should swap the bounds.
|
|
const uint64_t rand_u64_4 = rng.RandomInRange(1235, 1234);
|
|
EXPECT_GE(rand_u64_4, 1234ul);
|
|
EXPECT_LE(rand_u64_4, 1235ul);
|
|
}
|
|
|
|
TEST_P(CdmRandomGeneratorTest, RandomDataLength) {
|
|
const unsigned int seed = GetParam();
|
|
CdmRandomGenerator rng(seed);
|
|
|
|
const std::string empty_data = rng.RandomData(0);
|
|
EXPECT_EQ(empty_data.size(), 0ul);
|
|
|
|
const std::string data = rng.RandomData(kVectorLength);
|
|
EXPECT_EQ(data.size(), kVectorLength);
|
|
|
|
const std::string max_data = rng.RandomData(kMaxRandomDataLength);
|
|
EXPECT_EQ(max_data.size(), kMaxRandomDataLength);
|
|
|
|
// Requesting data above the maximum length will result in an error,
|
|
// returning an empty string.
|
|
const std::string error_data = rng.RandomData(kAboveMaxRandomDataLength);
|
|
EXPECT_EQ(error_data.size(), 0ul);
|
|
}
|
|
|
|
TEST_P(CdmRandomGeneratorTest, Reproducibility) {
|
|
const unsigned int seed = GetParam();
|
|
CdmRandomGenerator rng(seed);
|
|
const std::string random_data_1 = rng.RandomData(kVectorLength);
|
|
// Reset generator.
|
|
rng.Seed(seed);
|
|
const std::string random_data_2 = rng.RandomData(kVectorLength);
|
|
EXPECT_EQ(random_data_1, random_data_2);
|
|
}
|
|
|
|
TEST_P(CdmRandomGeneratorTest, ThreadSafety) {
|
|
const unsigned int seed = GetParam();
|
|
CdmRandomGenerator rng(seed);
|
|
bool barrier = true;
|
|
|
|
auto thread_job = [&]() {
|
|
while (barrier) {
|
|
std::this_thread::sleep_for(std::chrono::microseconds(1));
|
|
}
|
|
for (size_t i = 0; i < kRandomTrialCount; ++i) {
|
|
rng.Rand();
|
|
}
|
|
};
|
|
|
|
std::vector<std::thread> threads;
|
|
for (size_t i = 0; i < kThreadCount; ++i) {
|
|
threads.push_back(std::thread(thread_job));
|
|
}
|
|
std::this_thread::sleep_for(std::chrono::microseconds(100));
|
|
barrier = false;
|
|
for (auto& thread : threads) {
|
|
thread.join();
|
|
}
|
|
}
|
|
|
|
INSTANTIATE_TEST_CASE_P(VariousSeeds, CdmRandomGeneratorTest,
|
|
testing::ValuesIn(kSeeds));
|
|
|
|
TEST(CdmRandomTest, AllMethods) {
|
|
CdmRandom::Rand();
|
|
CdmRandom::RandomInRange(1234, 1000000);
|
|
CdmRandom::RandomInRange(1000000);
|
|
CdmRandom::RandomData(kVectorLength);
|
|
CdmRandom::RandomBool();
|
|
}
|
|
|
|
} // namespace wvcdm
|