blob: 9a33610193f64517e0cadca97bd9487b2b7659ed [file] [log] [blame]
// 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.
#include "peridot/lib/rng/system_random.h"
#include <algorithm>
#include <random>
#include <vector>
#include "gmock/gmock.h"
#include "gtest/gtest.h"
namespace rng {
namespace {
using ::testing::ElementsAre;
using ::testing::Ge;
using ::testing::Le;
using ::testing::SizeIs;
TEST(TestRandomTest, InUniquePtr) {
auto test_random = std::make_unique<SystemRandom>();
std::unique_ptr<Random> random = std::move(test_random);
EXPECT_TRUE(random);
}
TEST(SystemRandomTest, MiscRandomTest) {
constexpr size_t kNbElement = 20;
SystemRandom random;
std::vector<uint32_t> v1;
for (size_t i = 0; i < kNbElement; ++i) {
v1.push_back(random.Draw<uint32_t>());
}
EXPECT_TRUE(std::any_of(v1.begin(), v1.end(),
[](const uint8_t& v) { return v != 0; }));
std::vector<uint8_t> v2(kNbElement, 0);
random.Draw(&v2);
EXPECT_TRUE(std::any_of(v2.begin(), v2.end(),
[](const uint8_t& v) { return v != 0; }));
uint8_t bytes[kNbElement];
random.Draw(bytes, kNbElement);
EXPECT_TRUE(std::any_of(bytes, bytes + kNbElement,
[](const uint8_t& v) { return v != 0; }));
}
TEST(SystemRandomTest, BitGeneratorTest) {
constexpr size_t kNbElement = 100;
SystemRandom random;
auto engine = random.NewBitGenerator<uint32_t>();
std::discrete_distribution<> d({1, 1, 1, 1});
std::set<uint32_t> s;
for (size_t i = 0; i < kNbElement; ++i) {
s.insert(d(engine));
}
EXPECT_THAT(s, ElementsAre(0, 1, 2, 3));
}
TEST(SystemRandomTest, RandomStructTest) {
constexpr size_t kNbElement = 64;
struct S {
uint64_t array[kNbElement];
};
SystemRandom random;
auto s1 = random.Draw<S>();
std::set<uint64_t> v1(s1.array, s1.array + kNbElement);
EXPECT_THAT(v1, SizeIs(Ge(kNbElement - 2)));
auto s2 = random.Draw<S>();
std::set<uint64_t> v2(s2.array, s2.array + kNbElement);
std::vector<uint64_t> common_data;
set_intersection(v1.begin(), v1.end(), v2.begin(), v2.end(),
std::back_inserter(common_data));
EXPECT_THAT(common_data, SizeIs(Le(2u)));
}
TEST(SystemRandomTest, IndependantDraws) {
constexpr size_t kNbElement = 20;
SystemRandom random1;
SystemRandom random2;
std::vector<uint8_t> v1(kNbElement, 0);
std::vector<uint8_t> v2(kNbElement, 0);
random1.Draw(&v1);
random2.Draw(&v2);
EXPECT_NE(v1, v2);
}
} // namespace
} // namespace rng