blob: 5c27e55a8f05d50b9478d02237871360eb6b2fd6 [file] [log] [blame]
// Copyright 2020 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 "memory_patterns.h"
#include <vector>
#include <gtest/gtest.h>
#include "memory_range.h"
namespace hwstress {
namespace {
TEST(Util, RotatePattern) {
ASSERT_EQ(RotatePattern({}, 5), std::vector<uint64_t>{});
ASSERT_EQ(RotatePattern({0x11223344'aabbccdd}, 0), std::vector<uint64_t>{0x112233'44aabbccdd});
ASSERT_EQ(RotatePattern({0x11223344'aabbccdd}, 8), std::vector<uint64_t>{0xdd112233'44aabbcc});
ASSERT_EQ(RotatePattern({0x00000000'00000001}, 1), std::vector<uint64_t>{0x80000000'00000000});
ASSERT_EQ(RotatePattern({0x80000000'00000000}, 63), std::vector<uint64_t>{0x00000000'00000001});
ASSERT_EQ(RotatePattern({0xaaaaaaaa'aaaaaaaa, 0xbbbbbbbb'bbbbbbbb, 0xcccccccc'cccccccc}, 8),
(std::vector<uint64_t>{0xccaaaaaa'aaaaaaaa, 0xaabbbbbb'bbbbbbbb, 0xbbcccccc'cccccccc}));
}
TEST(Util, NegateWords) {
ASSERT_EQ(NegateWords({0xffff'ffff'ffff'ffff}), std::vector<uint64_t>{0x0000'0000'0000'0000});
ASSERT_EQ(NegateWords({0x0000'0000'0000'0000}), std::vector<uint64_t>{0xffff'ffff'ffff'ffff});
}
TEST(WritePattern, Simple) {
// Write out a simple pattern to memory.
uint8_t memory[ZX_PAGE_SIZE];
WritePattern(memory, SimplePattern(0x55555555'55555555ul));
// Ensure it was written correctly.
for (uint8_t x : memory) {
EXPECT_EQ(x, 0x55);
}
}
TEST(SimplePattern, EndianCheck) {
// Write out a pattern to memory.
uint8_t memory[ZX_PAGE_SIZE];
WritePattern(memory, SimplePattern(0x00112233'44556677ul));
// Ensure that bytes were written in the correct (big-endian) order.
for (size_t i = 0; i < ZX_PAGE_SIZE; i += 8) {
EXPECT_EQ(memory[i + 0], 0x00);
EXPECT_EQ(memory[i + 1], 0x11);
EXPECT_EQ(memory[i + 2], 0x22);
EXPECT_EQ(memory[i + 3], 0x33);
EXPECT_EQ(memory[i + 4], 0x44);
EXPECT_EQ(memory[i + 5], 0x55);
EXPECT_EQ(memory[i + 6], 0x66);
EXPECT_EQ(memory[i + 7], 0x77);
}
}
TEST(MultiWordPattern, EndianCheck) {
// Write out a pattern to memory.
uint8_t memory[ZX_PAGE_SIZE];
WritePattern(memory, MultiWordPattern({0x00112233'44556677ul, 0x8899aabb'ccddeeff}));
// Ensure that bytes were written in the correct (big-endian) order.
for (size_t i = 0; i < ZX_PAGE_SIZE; i += 16) {
EXPECT_EQ(memory[i + 0], 0x00);
EXPECT_EQ(memory[i + 1], 0x11);
EXPECT_EQ(memory[i + 2], 0x22);
EXPECT_EQ(memory[i + 3], 0x33);
EXPECT_EQ(memory[i + 4], 0x44);
EXPECT_EQ(memory[i + 5], 0x55);
EXPECT_EQ(memory[i + 6], 0x66);
EXPECT_EQ(memory[i + 7], 0x77);
EXPECT_EQ(memory[i + 8], 0x88);
EXPECT_EQ(memory[i + 9], 0x99);
EXPECT_EQ(memory[i + 10], 0xaa);
EXPECT_EQ(memory[i + 11], 0xbb);
EXPECT_EQ(memory[i + 12], 0xcc);
EXPECT_EQ(memory[i + 13], 0xdd);
EXPECT_EQ(memory[i + 14], 0xee);
EXPECT_EQ(memory[i + 15], 0xff);
}
}
TEST(VerifyPattern, Simple) {
// Write out a pattern to memory, and ensure it verifies correctly.
uint8_t memory[ZX_PAGE_SIZE];
memset(memory, 0x55, ZX_PAGE_SIZE);
EXPECT_EQ(std::nullopt, VerifyPattern(memory, SimplePattern(0x55555555'55555555)));
// Change the memory to have incorrect bytes at various locations, and ensure
// we see the errors.
for (int bad_byte_index :
std::initializer_list<int>{0, 1, 2, 3, 4, 5, 6, 7, 8, ZX_PAGE_SIZE - 1}) {
memset(memory, 0x55, ZX_PAGE_SIZE);
memory[bad_byte_index] = 0x0;
EXPECT_TRUE(VerifyPattern(memory, SimplePattern(0x55555555'55555555)).has_value());
}
}
TEST(RandomPattern, EveryBitSet) {
// Generate random patterns. Ensure that we see every bit as a "1" and every
// bit as a "0" at least once. (An rng engine used during development was only
// producing 63-bits of output, for example.)
auto pattern = RandomPattern();
uint64_t seen_one_bit = 0;
uint64_t seen_zero_bit = 0;
for (int i = 0; i < 1000; i++) {
uint64_t x = pattern();
seen_one_bit |= x;
seen_zero_bit |= ~x;
}
EXPECT_EQ(seen_one_bit, ~0ul) << "After 1000 iterations, at least 1 bit hasn't been seen as 0";
EXPECT_EQ(seen_zero_bit, ~0ul) << "After 1000 iterations, at least 1 bit hasn't been seen as 1";
}
} // namespace
} // namespace hwstress