tests: add tests for internal utilities
Signed-off-by: Amneesh Singh <natto@weirdnatto.in>
This commit is contained in:
@@ -1,8 +1,8 @@
|
||||
#include "memory.hh"
|
||||
#include "header.hh"
|
||||
#include "util/bits.hh"
|
||||
#include "util/crypto.hh"
|
||||
#include "util/log.hh"
|
||||
#include "util/utils.hh"
|
||||
#include <bitset>
|
||||
#include <stdexcept>
|
||||
|
||||
|
@@ -14,19 +14,19 @@ get_bit(Int num, size_t n) {
|
||||
template<std::integral Int>
|
||||
inline void
|
||||
set_bit(Int& num, size_t n) {
|
||||
num |= (1 << n);
|
||||
num |= (static_cast<Int>(1) << n);
|
||||
}
|
||||
|
||||
template<std::integral Int>
|
||||
inline void
|
||||
rst_bit(Int& num, size_t n) {
|
||||
num &= ~(1 << n);
|
||||
num &= ~(static_cast<Int>(1) << n);
|
||||
}
|
||||
|
||||
template<std::integral Int>
|
||||
inline void
|
||||
chg_bit(Int& num, size_t n, bool x) {
|
||||
num = (num & ~(1 << n)) | (x << n);
|
||||
num = (num & ~(static_cast<Int>(1) << n)) | (static_cast<Int>(x) << n);
|
||||
}
|
||||
|
||||
/// read range of bits from start to end inclusive
|
||||
@@ -36,5 +36,5 @@ bit_range(Int num, size_t start, size_t end) {
|
||||
// NOTE: we do not require -1 if it is a signed integral
|
||||
Int left =
|
||||
std::numeric_limits<Int>::digits - (std::is_unsigned<Int>::value) - end;
|
||||
return num << left >> (left + start);
|
||||
return static_cast<Int>(num << left) >> (left + start);
|
||||
}
|
||||
|
@@ -2,7 +2,8 @@
|
||||
|
||||
#include <array>
|
||||
#include <bit>
|
||||
#include <fmt/core.h>
|
||||
#include <iomanip>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
// Why I wrote this myself? I do not know
|
||||
@@ -14,8 +15,8 @@ using std::rotr;
|
||||
template<typename std::size_t N>
|
||||
std::string
|
||||
sha256(std::array<uint8_t, N>& data) {
|
||||
std::stringstream ss;
|
||||
// Assuming 1 byte = 8 bits
|
||||
std::string string;
|
||||
size_t k = 512 - (N * 8 + 65) % 512;
|
||||
size_t L = N + (65 + k) / 8;
|
||||
size_t i = 0, j = 0;
|
||||
@@ -108,12 +109,12 @@ sha256(std::array<uint8_t, N>& data) {
|
||||
h[j] += h0[j];
|
||||
}
|
||||
|
||||
ss << std::hex << std::setfill('0');
|
||||
|
||||
for (j = 0; j < 8; j++)
|
||||
for (i = 0; i < 4; i++)
|
||||
fmt::format_to(std::back_inserter(string),
|
||||
"{:02x}",
|
||||
((h[j] >> (24 - i * 8)) & 0xFF));
|
||||
ss << std::setw(2) << ((h[j] >> (24 - i * 8)) & 0xFF);
|
||||
|
||||
return string;
|
||||
return ss.str();
|
||||
}
|
||||
}
|
@@ -6,12 +6,12 @@
|
||||
|
||||
namespace logging {
|
||||
namespace ansi {
|
||||
static constexpr std::string_view RED = "\033[31m";
|
||||
static constexpr std::string_view YELLOW = "\033[33m";
|
||||
static constexpr std::string_view MAGENTA = "\033[35m";
|
||||
static constexpr std::string_view WHITE = "\033[37m";
|
||||
static constexpr std::string_view BOLD = "\033[1m";
|
||||
static constexpr std::string_view RESET = "\033[0m";
|
||||
static constexpr auto RED = "\033[31m";
|
||||
static constexpr auto YELLOW = "\033[33m";
|
||||
static constexpr auto MAGENTA = "\033[35m";
|
||||
static constexpr auto WHITE = "\033[37m";
|
||||
static constexpr auto BOLD = "\033[1m";
|
||||
static constexpr auto RESET = "\033[0m";
|
||||
}
|
||||
|
||||
using fmt::print;
|
||||
@@ -20,8 +20,9 @@ class Logger {
|
||||
using LogLevel = matar::LogLevel;
|
||||
|
||||
public:
|
||||
Logger(LogLevel level = LogLevel::Debug)
|
||||
: level(0) {
|
||||
Logger(LogLevel level = LogLevel::Debug, FILE* stream = stderr)
|
||||
: level(0)
|
||||
, stream(stream) {
|
||||
set_level(level);
|
||||
}
|
||||
|
||||
@@ -69,14 +70,14 @@ class Logger {
|
||||
void set_level(LogLevel level) {
|
||||
this->level = (static_cast<uint8_t>(level) << 1) - 1;
|
||||
}
|
||||
void set_stream(std::ostream& stream) { this->stream = stream; }
|
||||
void set_stream(FILE* stream) { this->stream = stream; }
|
||||
|
||||
private:
|
||||
uint8_t level;
|
||||
std::reference_wrapper<std::ostream> stream = std::clog;
|
||||
FILE* stream;
|
||||
};
|
||||
}
|
||||
|
||||
extern logging::Logger glogger;
|
||||
|
||||
#define debug(x) logger.debug("{} = {}", #x, x);
|
||||
#define debug(x) glogger.debug("{} = {}", #x, x);
|
||||
|
@@ -1,7 +1,7 @@
|
||||
#include "bus.hh"
|
||||
#include <catch2/catch_test_macros.hpp>
|
||||
|
||||
#define TAG "bus"
|
||||
static constexpr auto TAG = "[bus]";
|
||||
|
||||
using namespace matar;
|
||||
|
||||
@@ -41,5 +41,3 @@ TEST_CASE_METHOD(BusFixture, "Word", TAG) {
|
||||
CHECK(bus.read_halfword(100724276) == 0x491D);
|
||||
CHECK(bus.read_byte(100724276) == 0x1D);
|
||||
}
|
||||
|
||||
#undef TAG
|
||||
|
@@ -32,7 +32,7 @@ class CpuFixture {
|
||||
};
|
||||
};
|
||||
|
||||
#define TAG "arm execution"
|
||||
static constexpr auto TAG = "[arm][execution]";
|
||||
|
||||
using namespace arm;
|
||||
|
||||
@@ -1051,5 +1051,3 @@ TEST_CASE_METHOD(CpuFixture, "Data Processing", TAG) {
|
||||
CHECK(cpu.spsr.raw() == cpu.cpsr.raw());
|
||||
}
|
||||
}
|
||||
|
||||
#undef TAG
|
||||
|
@@ -1,7 +1,7 @@
|
||||
#include "cpu/arm/instruction.hh"
|
||||
#include <catch2/catch_test_macros.hpp>
|
||||
|
||||
#define TAG "disassembler"
|
||||
static constexpr auto TAG = "[arm][disassembly]";
|
||||
|
||||
using namespace matar;
|
||||
using namespace arm;
|
||||
@@ -467,5 +467,3 @@ TEST_CASE("Software Interrupt", TAG) {
|
||||
CHECK(instruction.condition == Condition::EQ);
|
||||
CHECK(instruction.disassemble() == "SWIEQ");
|
||||
}
|
||||
|
||||
#undef TAG
|
||||
|
@@ -10,6 +10,7 @@ tests_sources = files(
|
||||
)
|
||||
|
||||
subdir('cpu')
|
||||
subdir('util')
|
||||
|
||||
catch2 = dependency('catch2', version: '>=3.4.0', static: true)
|
||||
catch2_tests = executable(
|
||||
|
106
tests/util/bits.cc
Normal file
106
tests/util/bits.cc
Normal file
@@ -0,0 +1,106 @@
|
||||
#include "util/bits.hh"
|
||||
#include <catch2/catch_test_macros.hpp>
|
||||
|
||||
static constexpr auto TAG = "[util][bits]";
|
||||
|
||||
TEST_CASE("8 bits", TAG) {
|
||||
uint8_t num = 45;
|
||||
|
||||
CHECK(get_bit(num, 0));
|
||||
CHECK(!get_bit(num, 1));
|
||||
CHECK(get_bit(num, 5));
|
||||
CHECK(!get_bit(num, 6));
|
||||
CHECK(!get_bit(num, 7));
|
||||
|
||||
set_bit(num, 6);
|
||||
CHECK(get_bit(num, 6));
|
||||
|
||||
rst_bit(num, 6);
|
||||
CHECK(!get_bit(num, 6));
|
||||
|
||||
chg_bit(num, 5, false);
|
||||
CHECK(!get_bit(num, 5));
|
||||
|
||||
chg_bit(num, 5, true);
|
||||
CHECK(get_bit(num, 5));
|
||||
|
||||
// 0b0110
|
||||
CHECK(bit_range(num, 1, 4) == 6);
|
||||
}
|
||||
|
||||
TEST_CASE("16 bits", TAG) {
|
||||
uint16_t num = 34587;
|
||||
|
||||
CHECK(get_bit(num, 0));
|
||||
CHECK(get_bit(num, 1));
|
||||
CHECK(!get_bit(num, 5));
|
||||
CHECK(!get_bit(num, 14));
|
||||
CHECK(get_bit(num, 15));
|
||||
|
||||
set_bit(num, 14);
|
||||
CHECK(get_bit(num, 14));
|
||||
|
||||
rst_bit(num, 14);
|
||||
CHECK(!get_bit(num, 14));
|
||||
|
||||
chg_bit(num, 5, true);
|
||||
CHECK(get_bit(num, 5));
|
||||
|
||||
// num = 45
|
||||
chg_bit(num, 5, false);
|
||||
CHECK(!get_bit(num, 5));
|
||||
|
||||
// 0b1000110
|
||||
CHECK(bit_range(num, 2, 8) == 70);
|
||||
}
|
||||
|
||||
TEST_CASE("32 bits", TAG) {
|
||||
uint32_t num = 3194142523;
|
||||
|
||||
CHECK(get_bit(num, 0));
|
||||
CHECK(get_bit(num, 1));
|
||||
CHECK(get_bit(num, 12));
|
||||
CHECK(get_bit(num, 29));
|
||||
CHECK(!get_bit(num, 30));
|
||||
CHECK(get_bit(num, 31));
|
||||
|
||||
set_bit(num, 30);
|
||||
CHECK(get_bit(num, 30));
|
||||
|
||||
rst_bit(num, 30);
|
||||
CHECK(!get_bit(num, 30));
|
||||
|
||||
chg_bit(num, 12, false);
|
||||
CHECK(!get_bit(num, 12));
|
||||
|
||||
chg_bit(num, 12, true);
|
||||
CHECK(get_bit(num, 12));
|
||||
|
||||
// 0b10011000101011111100111
|
||||
CHECK(bit_range(num, 3, 25) == 5003239);
|
||||
}
|
||||
|
||||
TEST_CASE("64 bits", TAG) {
|
||||
uint64_t num = 58943208889991935;
|
||||
|
||||
CHECK(get_bit(num, 0));
|
||||
CHECK(get_bit(num, 1));
|
||||
CHECK(!get_bit(num, 10));
|
||||
CHECK(get_bit(num, 55));
|
||||
CHECK(!get_bit(num, 60));
|
||||
|
||||
set_bit(num, 63);
|
||||
CHECK(get_bit(num, 63));
|
||||
|
||||
rst_bit(num, 63);
|
||||
CHECK(!get_bit(num, 63));
|
||||
|
||||
chg_bit(num, 10, true);
|
||||
CHECK(get_bit(num, 10));
|
||||
|
||||
chg_bit(num, 10, false);
|
||||
CHECK(!get_bit(num, 10));
|
||||
|
||||
// 0b011010001
|
||||
CHECK(bit_range(num, 39, 47) == 209);
|
||||
}
|
21
tests/util/crypto.cc
Normal file
21
tests/util/crypto.cc
Normal file
@@ -0,0 +1,21 @@
|
||||
#include "util/crypto.hh"
|
||||
#include <catch2/catch_test_macros.hpp>
|
||||
|
||||
static constexpr auto TAG = "[util][crypto]";
|
||||
|
||||
TEST_CASE("sha256 matar", TAG) {
|
||||
std::array<uint8_t, 5> data = { 'm', 'a', 't', 'a', 'r' };
|
||||
|
||||
CHECK(crypto::sha256(data) ==
|
||||
"3b02a908fd5743c0e868675bb6ae77d2a62b3b5f7637413238e2a1e0e94b6a53");
|
||||
}
|
||||
|
||||
TEST_CASE("sha256 forgis", TAG) {
|
||||
std::array<uint8_t, 32> data = { 'i', ' ', 'p', 'u', 't', ' ', 't', 'h',
|
||||
'e', ' ', 'n', 'e', 'w', ' ', 'f', 'o',
|
||||
'r', 'g', 'i', 's', ' ', 'o', 'n', ' ',
|
||||
't', 'h', 'e', ' ', 'j', 'e', 'e', 'p' };
|
||||
|
||||
CHECK(crypto::sha256(data) ==
|
||||
"cfddca2ce2673f355518cbe2df2a8522693c54723a469e8b36a4f68b90d2b759");
|
||||
}
|
4
tests/util/meson.build
Normal file
4
tests/util/meson.build
Normal file
@@ -0,0 +1,4 @@
|
||||
tests_sources += files(
|
||||
'bits.cc',
|
||||
'crypto.cc'
|
||||
)
|
Reference in New Issue
Block a user