blob: dac360bb7d73d71b9164bbb6613482c07a080081 [file] [log] [blame]
// Copyright 2021 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 "src/sys/fuzzing/framework/target/module.h"
#include <random>
#include <gtest/gtest.h>
#include "src/sys/fuzzing/framework/testing/module.h"
namespace fuzzing {
namespace {
// Unit tests.
TEST(ModuleTest, Identifier) {
// Prepare a fixed module.
std::vector<ModulePC> pc_table1;
for (size_t i = 0; i < FakeFrameworkModule::kNumPCs; ++i) {
pc_table1.emplace_back(0x1000 + i * 0x10, (i % 8) == 0);
}
FakeFrameworkModule module1(std::move(pc_table1));
Identifier expected = {9595151602815918885ULL, 10676851608648082213ULL};
EXPECT_EQ(module1.id(), expected);
// Shifting all the PCs by a random basis does not affect the source ID, i.e., the ID is
// independent of where it is mapped in memory.
std::vector<ModulePC> pc_table2;
for (size_t i = 0; i < FakeFrameworkModule::kNumPCs; ++i) {
pc_table2.emplace_back(0xdeadbeef + i * 0x10, (i % 8) == 0);
}
FakeFrameworkModule module2(std::move(pc_table2));
EXPECT_EQ(module1.id(), module2.id());
// Changing the counters has no effect on identifiers.
memset(module1.counters(), 1, module1.num_pcs());
EXPECT_EQ(module1.id(), expected);
// Check for collisions. This isn't exhaustive; it is simply a smoke test to check if things are
// very broken.
for (uint32_t i = 0; i < 100; ++i) {
FakeFrameworkModule moduleN(/* seed */ i);
EXPECT_NE(moduleN.id(), expected);
}
}
TEST(ModuleTest, UpdateAndClear) {
FakeFrameworkModule module;
std::minstd_rand prng(1);
// Initial contents are shared.
for (size_t i = 0; i < module.num_pcs(); ++i) {
module[i] = static_cast<uint8_t>(prng());
}
std::vector<uint8_t> expected(module.counters(), module.counters_end());
SharedMemory shmem;
shmem.LinkMirrored(module.Share());
auto* data = shmem.data();
module.Update();
std::vector<uint8_t> actual(data, data + module.num_pcs());
EXPECT_EQ(actual, expected);
// Changes to counters are not reflected until an |Update|.
for (size_t i = 0; i < module.num_pcs(); ++i) {
module[i] = static_cast<uint8_t>(prng());
}
actual = std::vector<uint8_t>(data, data + module.num_pcs());
EXPECT_EQ(actual, expected);
module.Update();
expected = std::vector<uint8_t>(module.counters(), module.counters_end());
actual = std::vector<uint8_t>(data, data + module.num_pcs());
EXPECT_EQ(actual, expected);
// Clearing resets counters to zero (but does not |Update|, for performance reasons).
module.Clear();
actual = std::vector<uint8_t>(data, data + module.num_pcs());
EXPECT_EQ(actual, expected);
expected = std::vector<uint8_t>(module.num_pcs(), 0);
actual = std::vector<uint8_t>(module.counters(), module.counters_end());
EXPECT_EQ(actual, expected);
}
} // namespace
} // namespace fuzzing