diff options
author | Jack Lloyd <[email protected]> | 2017-01-22 14:31:01 -0500 |
---|---|---|
committer | Jack Lloyd <[email protected]> | 2017-01-22 14:40:03 -0500 |
commit | ef8c214eb28abc36ddc4ffff467c51ed69cae63c (patch) | |
tree | 5cfff5f1aa1a108ff35c50b9c58a9661d9a2d0be /src/tests/test_os_utils.cpp | |
parent | 2dc8d318194ae31b2bedc17c2e153d6e76e8791d (diff) |
Add basic test for OS utils
Mainly driven by missing test for OS::run_cpu_instruction_probe.
Currently only works on x86 and ARM. Tested on x86-64 native and aarch64 qemu.
Diffstat (limited to 'src/tests/test_os_utils.cpp')
-rw-r--r-- | src/tests/test_os_utils.cpp | 147 |
1 files changed, 147 insertions, 0 deletions
diff --git a/src/tests/test_os_utils.cpp b/src/tests/test_os_utils.cpp new file mode 100644 index 000000000..5b5e69d8d --- /dev/null +++ b/src/tests/test_os_utils.cpp @@ -0,0 +1,147 @@ +/* +* Testing operating system specific wrapper code +* (C) 2017 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include "tests.h" +#include <botan/internal/os_utils.h> + +namespace Botan_Tests { + +namespace { + +/* +uint32_t get_process_id(); +uint64_t get_processor_timestamp(); +uint64_t get_system_timestamp_ns(); +size_t get_memory_locking_limit(); +void* allocate_locked_pages(size_t length); +void free_locked_pages(void* ptr, size_t length); +int run_cpu_instruction_probe(std::function<int ()> probe_fn); +*/ + +class OS_Utils_Tests : public Test + { + public: + std::vector<Test::Result> run() + { + std::vector<Test::Result> results; + + results.push_back(test_get_process_id()); + results.push_back(test_get_processor_timestamp()); + results.push_back(test_get_system_timestamp()); + results.push_back(test_memory_locking()); + results.push_back(test_cpu_instruction_probe()); + + return results; + } + + private: + + Test::Result test_get_process_id() + { + Test::Result result("OS::get_process_id"); + + uint32_t pid1 = Botan::OS::get_process_id(); + uint32_t pid2 = Botan::OS::get_process_id(); + + result.test_eq("PID same across calls", static_cast<size_t>(pid1), static_cast<size_t>(pid2)); + +#if defined(BOTAN_TARGET_OS_TYPE_IS_UNIKERNEL) + result.test_eq("PID is zero on unikernel systems", pid1, 0); +#else + result.test_ne("PID is non-zero on systems with processes", pid1, 0); +#endif + + return result; + } + + Test::Result test_get_processor_timestamp() + { + Test::Result result("OS::get_processor_timestamp"); + + uint64_t proc_ts1 = Botan::OS::get_processor_timestamp(); + result.test_ne("Processor timestamp value is never zero", proc_ts1, 0); + + // do something that consumes a little time + Botan::OS::get_process_id(); + + uint64_t proc_ts2 = Botan::OS::get_processor_timestamp(); + + result.test_ne("Processor timestamp does not duplicate", proc_ts1, proc_ts2); + return result; + } + + Test::Result test_get_system_timestamp() + { + Test::Result result("OS::get_system_timestamp_ns"); + + uint64_t sys_ts1 = Botan::OS::get_system_timestamp_ns(); + result.test_ne("System timestamp value is never zero", sys_ts1, 0); + + // do something that consumes a little time + Botan::OS::get_process_id(); + + uint64_t sys_ts2 = Botan::OS::get_system_timestamp_ns(); + + result.confirm("System time moves forward", sys_ts1 <= sys_ts2); + + return result; + + return result; + } + + Test::Result test_memory_locking() + { + Test::Result result("OS memory locked pages"); + return result; + } + + Test::Result test_cpu_instruction_probe() + { + Test::Result result("OS::run_cpu_instruction_probe"); + + std::function<int ()> ok_fn = []() { return 5; }; + const int run_rc = Botan::OS::run_cpu_instruction_probe(ok_fn); + result.confirm("Correct result returned by working probe fn", run_rc == 5); + + std::function<int ()> throw_fn = []() { throw 3.14159; return 5; }; + const int throw_rc = Botan::OS::run_cpu_instruction_probe(throw_fn); + result.confirm("Error return if probe function threw exception", throw_rc < 0); + +#if defined(BOTAN_USE_GCC_INLINE_ASM) + + std::function<int ()> crash_probe; + +#if defined(BOTAN_TARGET_CPU_IS_X86_FAMILY) + crash_probe = []() { asm volatile("ud2"); return 3; }; +#elif defined(BOTAN_TARGET_CPU_IS_ARM_FAMILY) + //ARM: asm volatile (".word 0xf7f0a000\n"); + // illegal instruction in both ARM and Thumb modes + crash_probe = []() { asm volatile(".word 0xe7f0def0\n"); return 3; }; +#else + /* + PPC: "The instruction with primary opcode 0, when the instruction does not consist + entirely of binary zeros" + Others ? + */ +#endif + + if(crash_probe) + { + const int crash_rc = Botan::OS::run_cpu_instruction_probe(crash_probe); + result.confirm("Result for function executing undefined opcode", crash_rc < 0); + } +#endif + + return result; + } +}; + +BOTAN_REGISTER_TEST("os_utils", OS_Utils_Tests); + +} + +} |