diff options
author | Marat Dukhan <maratek@gmail.com> | 2017-05-08 05:13:19 -0400 |
---|---|---|
committer | Marat Dukhan <maratek@gmail.com> | 2017-05-08 09:52:29 +0000 |
commit | 51a3427a3abf103c59925cb734ef4c4aa14316ce (patch) | |
tree | aa843a38c60020a77e95646cc835c9ff7503bba3 | |
parent | 1a6cf6bb66a6f1a6cb9861088e5f5623daaab04a (diff) | |
download | cpuinfo-51a3427a3abf103c59925cb734ef4c4aa14316ce.tar.gz |
Add mocking and test with Raspberry Pi 2 /proc/cpuinfo
-rwxr-xr-x | configure.py | 8 | ||||
-rw-r--r-- | include/cpuinfo-mock.h | 26 | ||||
-rw-r--r-- | src/arm/linux/api.h | 1 | ||||
-rw-r--r-- | src/arm/linux/cpuinfo.c | 23 | ||||
-rw-r--r-- | src/arm/linux/init.c | 2 | ||||
-rw-r--r-- | test/init.cc | 2 | ||||
-rw-r--r-- | test/raspberry-pi2.cc | 316 |
7 files changed, 369 insertions, 9 deletions
diff --git a/configure.py b/configure.py index 9ae5b09..2338a70 100755 --- a/configure.py +++ b/configure.py @@ -5,6 +5,7 @@ import confu parser = confu.standard_parser("cpuinfo configuration script") parser.add_argument("--log", dest="log_level", choices=("none", "error", "warning", "info", "debug"), default="error") +parser.add_argument("--mock", dest="mock", action="store_true") def main(args): @@ -12,7 +13,8 @@ def main(args): build = confu.Build.from_options(options) macros = { - "CPUINFO_LOG_LEVEL": {"none": 0, "error": 1, "warning": 2, "info": 3, "debug": 4}[options.log_level] + "CPUINFO_LOG_LEVEL": {"none": 0, "error": 1, "warning": 2, "info": 3, "debug": 4}[options.log_level], + "CPUINFO_MOCK": int(options.mock) } if build.target.is_linux: macros["_GNU_SOURCE"] = 1 @@ -52,6 +54,10 @@ def main(args): with build.options(source_dir="test", deps=[build, build.deps.googletest]): build.unittest("init-test", build.cxx("init.cc")) + if options.mock: + with build.options(macros={"CPUINFO_MOCK": int(options.mock)}): + if build.target.is_arm and build.target.is_linux: + build.unittest("raspberry-pi2-test", build.cxx("raspberry-pi2.cc")) return build diff --git a/include/cpuinfo-mock.h b/include/cpuinfo-mock.h new file mode 100644 index 0000000..09ef36b --- /dev/null +++ b/include/cpuinfo-mock.h @@ -0,0 +1,26 @@ +#pragma once +#ifndef CPUINFO_MOCK_H +#define CPUINFO_MOCK_H + +#include <cpuinfo.h> + +#if !defined(CPUINFO_MOCK) || !(CPUINFO_MOCK) + #error This header is intended only for test use +#endif + + +#ifdef __cplusplus +extern "C" { +#endif + + +#if CPUINFO_ARCH_ARM && defined(__linux__) + void CPUINFO_ABI cpuinfo_set_proc_cpuinfo_path(const char* path); +#endif + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* CPUINFO_MOCK_H */ diff --git a/src/arm/linux/api.h b/src/arm/linux/api.h index 4e13e00..fe0dc1e 100644 --- a/src/arm/linux/api.h +++ b/src/arm/linux/api.h @@ -94,7 +94,6 @@ struct proc_cpuinfo { }; struct proc_cpuinfo* cpuinfo_arm_linux_parse_proc_cpuinfo( - const char* filename, uint32_t processors_count[restrict static 1]); void cpuinfo_arm_linux_decode_isa_from_proc_cpuinfo( diff --git a/src/arm/linux/cpuinfo.c b/src/arm/linux/cpuinfo.c index 76e1a1f..aade677 100644 --- a/src/arm/linux/cpuinfo.c +++ b/src/arm/linux/cpuinfo.c @@ -11,10 +11,23 @@ #include <fcntl.h> #include <sched.h> +#if CPUINFO_MOCK + #include <cpuinfo-mock.h> +#endif #include <arm/linux/api.h> #include <log.h> +static const char* proc_cpuinfo_path = "/proc/cpuinfo"; + +#if CPUINFO_MOCK + void cpuinfo_set_proc_cpuinfo_path(const char* path) { + /* Note: this leaks memory */ + proc_cpuinfo_path = strdup(path); + } +#endif + + /* * Size, in chars, of the on-stack buffer used for parsing cpu lists. * This is also the limit on the length of a single entry @@ -714,7 +727,7 @@ static uint32_t parse_line( return processor_number; } -struct proc_cpuinfo* cpuinfo_arm_linux_parse_proc_cpuinfo(const char* filename, uint32_t processors_count_ptr[restrict static 1]) { +struct proc_cpuinfo* cpuinfo_arm_linux_parse_proc_cpuinfo(uint32_t processors_count_ptr[restrict static 1]) { int file = -1; struct proc_cpuinfo* processors = NULL; struct proc_cpuinfo* result = NULL; @@ -729,10 +742,10 @@ struct proc_cpuinfo* cpuinfo_arm_linux_parse_proc_cpuinfo(const char* filename, goto cleanup; } - cpuinfo_log_debug("parsing cpu info from file %s", filename); - file = open(filename, O_RDONLY); + cpuinfo_log_debug("parsing cpu info from file %s", proc_cpuinfo_path); + file = open(proc_cpuinfo_path, O_RDONLY); if (file == -1) { - cpuinfo_log_error("failed to open %s: %s", filename, strerror(errno)); + cpuinfo_log_error("failed to open %s: %s", proc_cpuinfo_path, strerror(errno)); goto cleanup; } @@ -743,7 +756,7 @@ struct proc_cpuinfo* cpuinfo_arm_linux_parse_proc_cpuinfo(const char* filename, do { bytes_read = read(file, data_start, (size_t) (buffer_end - data_start)); if (bytes_read < 0) { - cpuinfo_log_error("failed to read file %s at position %zu: %s", filename, position, strerror(errno)); + cpuinfo_log_error("failed to read file %s at position %zu: %s", proc_cpuinfo_path, position, strerror(errno)); goto cleanup; } diff --git a/src/arm/linux/init.c b/src/arm/linux/init.c index 53f3e1e..5e47858 100644 --- a/src/arm/linux/init.c +++ b/src/arm/linux/init.c @@ -25,7 +25,7 @@ void cpuinfo_arm_linux_init(void) { uint32_t l1d_count = 0; uint32_t l2_count = 0; - struct proc_cpuinfo* proc_cpuinfo_entries = cpuinfo_arm_linux_parse_proc_cpuinfo("/proc/cpuinfo", &proc_cpuinfo_count); + struct proc_cpuinfo* proc_cpuinfo_entries = cpuinfo_arm_linux_parse_proc_cpuinfo(&proc_cpuinfo_count); if (proc_cpuinfo_count != 0) { cpuinfo_arm_linux_decode_isa_from_proc_cpuinfo( diff --git a/test/init.cc b/test/init.cc index 25ddd64..4b6e28e 100644 --- a/test/init.cc +++ b/test/init.cc @@ -477,4 +477,4 @@ int main(int argc, char* argv[]) { cpuinfo_initialize(); ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); -}
\ No newline at end of file +} diff --git a/test/raspberry-pi2.cc b/test/raspberry-pi2.cc new file mode 100644 index 0000000..edaa106 --- /dev/null +++ b/test/raspberry-pi2.cc @@ -0,0 +1,316 @@ +#include <gtest/gtest.h> + +#include <cpuinfo.h> +#include <cpuinfo-mock.h> + + +TEST(PROCESSORS, count) { + ASSERT_EQ(4, cpuinfo_processors_count); +} + +TEST(PROCESSORS, non_null) { + ASSERT_TRUE(cpuinfo_processors); +} + +TEST(PROCESSORS, vendor_arm) { + for (uint32_t i = 0; i < cpuinfo_processors_count; i++) { + ASSERT_EQ(cpuinfo_vendor_arm, cpuinfo_processors[i].vendor); + } +} + +TEST(PROCESSORS, uarch_cortex_a7) { + for (uint32_t i = 0; i < cpuinfo_processors_count; i++) { + ASSERT_EQ(cpuinfo_uarch_cortex_a7, cpuinfo_processors[i].uarch); + } +} + +TEST(ISA, thumb) { + ASSERT_TRUE(cpuinfo_isa.thumb); +} + +TEST(ISA, thumb2) { + ASSERT_TRUE(cpuinfo_isa.thumb2); +} + +TEST(ISA, thumbee) { + ASSERT_FALSE(cpuinfo_isa.thumbee); +} + +TEST(ISA, jazelle) { + ASSERT_FALSE(cpuinfo_isa.jazelle); +} + +TEST(ISA, armv5e) { + ASSERT_TRUE(cpuinfo_isa.armv5e); +} + +TEST(ISA, armv6) { + ASSERT_TRUE(cpuinfo_isa.armv6); +} + +TEST(ISA, armv6k) { + ASSERT_TRUE(cpuinfo_isa.armv6k); +} + +TEST(ISA, armv7) { + ASSERT_TRUE(cpuinfo_isa.armv7); +} + +TEST(ISA, armv7mp) { + ASSERT_TRUE(cpuinfo_isa.armv7mp); +} + +TEST(ISA, idiv) { + ASSERT_TRUE(cpuinfo_isa.idiv); +} + +TEST(ISA, vfpv2) { + ASSERT_FALSE(cpuinfo_isa.vfpv2); +} + +TEST(ISA, vfpv3) { + ASSERT_TRUE(cpuinfo_isa.vfpv3); +} + +TEST(ISA, d32) { + ASSERT_TRUE(cpuinfo_isa.d32); +} + +TEST(ISA, fp16) { + ASSERT_TRUE(cpuinfo_isa.fp16); +} + +TEST(ISA, fma) { + ASSERT_TRUE(cpuinfo_isa.fma); +} + +TEST(ISA, wmmx) { + ASSERT_FALSE(cpuinfo_isa.wmmx); +} + +TEST(ISA, wmmx2) { + ASSERT_FALSE(cpuinfo_isa.wmmx2); +} + +TEST(ISA, neon) { + ASSERT_TRUE(cpuinfo_isa.neon); +} + +TEST(ISA, aes) { + ASSERT_FALSE(cpuinfo_isa.aes); +} + +TEST(ISA, sha1) { + ASSERT_FALSE(cpuinfo_isa.sha1); +} + +TEST(ISA, sha2) { + ASSERT_FALSE(cpuinfo_isa.sha2); +} + +TEST(ISA, pmull) { + ASSERT_FALSE(cpuinfo_isa.pmull); +} + +TEST(ISA, crc32) { + ASSERT_FALSE(cpuinfo_isa.crc32); +} + +TEST(L1I, count) { + cpuinfo_caches l1i = cpuinfo_get_l1i_cache(); + ASSERT_EQ(4, l1i.count); +} + +TEST(L1I, non_null) { + cpuinfo_caches l1i = cpuinfo_get_l1i_cache(); + ASSERT_TRUE(l1i.instances); +} + +TEST(L1I, size) { + cpuinfo_caches l1i = cpuinfo_get_l1i_cache(); + for (uint32_t k = 0; k < l1i.count; k++) { + ASSERT_EQ(32 * 1024, l1i.instances[k].size); + } +} + +TEST(L1I, associativity) { + cpuinfo_caches l1i = cpuinfo_get_l1i_cache(); + for (uint32_t k = 0; k < l1i.count; k++) { + ASSERT_EQ(2, l1i.instances[k].associativity); + } +} + +TEST(L1I, sets) { + cpuinfo_caches l1i = cpuinfo_get_l1i_cache(); + for (uint32_t k = 0; k < l1i.count; k++) { + ASSERT_EQ(512, l1i.instances[k].sets); + } +} + +TEST(L1I, partitions) { + cpuinfo_caches l1i = cpuinfo_get_l1i_cache(); + for (uint32_t k = 0; k < l1i.count; k++) { + ASSERT_EQ(1, l1i.instances[k].partitions); + } +} + +TEST(L1I, line_size) { + cpuinfo_caches l1i = cpuinfo_get_l1i_cache(); + for (uint32_t k = 0; k < l1i.count; k++) { + ASSERT_EQ(32, l1i.instances[k].line_size); + } +} + +TEST(L1I, flags) { + cpuinfo_caches l1i = cpuinfo_get_l1i_cache(); + for (uint32_t k = 0; k < l1i.count; k++) { + ASSERT_EQ(0, l1i.instances[k].flags); + } +} + +TEST(L1I, processors) { + cpuinfo_caches l1i = cpuinfo_get_l1i_cache(); + for (uint32_t k = 0; k < l1i.count; k++) { + ASSERT_EQ(k, l1i.instances[k].thread_start); + ASSERT_EQ(1, l1i.instances[k].thread_count); + } +} + +TEST(L1D, count) { + cpuinfo_caches l1d = cpuinfo_get_l1d_cache(); + ASSERT_EQ(4, l1d.count); +} + +TEST(L1D, non_null) { + cpuinfo_caches l1d = cpuinfo_get_l1d_cache(); + ASSERT_TRUE(l1d.instances); +} + +TEST(L1D, size) { + cpuinfo_caches l1d = cpuinfo_get_l1d_cache(); + for (uint32_t k = 0; k < l1d.count; k++) { + ASSERT_EQ(32 * 1024, l1d.instances[k].size); + } +} + +TEST(L1D, associativity) { + cpuinfo_caches l1d = cpuinfo_get_l1d_cache(); + for (uint32_t k = 0; k < l1d.count; k++) { + ASSERT_EQ(4, l1d.instances[k].associativity); + } +} + +TEST(L1D, sets) { + cpuinfo_caches l1d = cpuinfo_get_l1d_cache(); + for (uint32_t k = 0; k < l1d.count; k++) { + ASSERT_EQ(128, l1d.instances[k].sets); + } +} + +TEST(L1D, partitions) { + cpuinfo_caches l1d = cpuinfo_get_l1d_cache(); + for (uint32_t k = 0; k < l1d.count; k++) { + ASSERT_EQ(1, l1d.instances[k].partitions); + } +} + +TEST(L1D, line_size) { + cpuinfo_caches l1d = cpuinfo_get_l1d_cache(); + for (uint32_t k = 0; k < l1d.count; k++) { + ASSERT_EQ(64, l1d.instances[k].line_size); + } +} + +TEST(L1D, flags) { + cpuinfo_caches l1d = cpuinfo_get_l1d_cache(); + for (uint32_t k = 0; k < l1d.count; k++) { + ASSERT_EQ(0, l1d.instances[k].flags); + } +} + +TEST(L1D, processors) { + cpuinfo_caches l1d = cpuinfo_get_l1d_cache(); + for (uint32_t k = 0; k < l1d.count; k++) { + ASSERT_EQ(k, l1d.instances[k].thread_start); + ASSERT_EQ(1, l1d.instances[k].thread_count); + } +} + +TEST(L2, count) { + cpuinfo_caches l2 = cpuinfo_get_l2_cache(); + ASSERT_EQ(1, l2.count); +} + +TEST(L2, non_null) { + cpuinfo_caches l2 = cpuinfo_get_l2_cache(); + ASSERT_TRUE(l2.instances); +} + +TEST(L2, size) { + cpuinfo_caches l2 = cpuinfo_get_l2_cache(); + for (uint32_t k = 0; k < l2.count; k++) { + ASSERT_EQ(512 * 1024, l2.instances[k].size); + } +} + +TEST(L2, associativity) { + cpuinfo_caches l2 = cpuinfo_get_l2_cache(); + for (uint32_t k = 0; k < l2.count; k++) { + ASSERT_EQ(8, l2.instances[k].associativity); + } +} + +TEST(L2, sets) { + cpuinfo_caches l2 = cpuinfo_get_l2_cache(); + for (uint32_t k = 0; k < l2.count; k++) { + ASSERT_EQ(1024, l2.instances[k].sets); + } +} + +TEST(L2, partitions) { + cpuinfo_caches l2 = cpuinfo_get_l2_cache(); + for (uint32_t k = 0; k < l2.count; k++) { + ASSERT_EQ(1, l2.instances[k].partitions); + } +} + +TEST(L2, line_size) { + cpuinfo_caches l2 = cpuinfo_get_l2_cache(); + for (uint32_t k = 0; k < l2.count; k++) { + ASSERT_EQ(64, l2.instances[k].line_size); + } +} + +TEST(L2, flags) { + cpuinfo_caches l2 = cpuinfo_get_l2_cache(); + for (uint32_t k = 0; k < l2.count; k++) { + ASSERT_EQ(0, l2.instances[k].flags); + } +} + +TEST(L2, processors) { + cpuinfo_caches l2 = cpuinfo_get_l2_cache(); + for (uint32_t k = 0; k < l2.count; k++) { + ASSERT_EQ(0, l2.instances[k].thread_start); + ASSERT_EQ(4, l2.instances[k].thread_count); + } +} + +TEST(L3, none) { + cpuinfo_caches l3 = cpuinfo_get_l3_cache(); + ASSERT_EQ(0, l3.count); + ASSERT_FALSE(l3.instances); +} + +TEST(L4, none) { + cpuinfo_caches l4 = cpuinfo_get_l4_cache(); + ASSERT_EQ(0, l4.count); + ASSERT_FALSE(l4.instances); +} + +int main(int argc, char* argv[]) { + cpuinfo_set_proc_cpuinfo_path("test/cpuinfo/raspberrypi2.log"); + cpuinfo_initialize(); + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} |