• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

randombit / botan / 5123321399

30 May 2023 04:06PM UTC coverage: 92.213% (+0.004%) from 92.209%
5123321399

Pull #3558

github

web-flow
Merge dd72f7389 into 057bcbc35
Pull Request #3558: Add braces around all if/else statements

75602 of 81986 relevant lines covered (92.21%)

11859779.3 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

81.71
/src/tests/test_os_utils.cpp
1
/*
2
* Testing operating system specific wrapper code
3
* (C) 2017 Jack Lloyd
4
*
5
* Botan is released under the Simplified BSD License (see license.txt)
6
*/
7

8
#include "tests.h"
9
#include <botan/internal/os_utils.h>
10

11
// For __ud2 intrinsic
12
#if defined(BOTAN_TARGET_COMPILER_IS_MSVC)
13
   #include <intrin.h>
14
#endif
15

16
namespace Botan_Tests {
17

18
namespace {
19

20
/*
21
uint32_t get_process_id();
22
uint64_t get_cpu_cycle_counter();
23
uint64_t get_system_timestamp_ns();
24
size_t get_memory_locking_limit();
25
void* allocate_locked_pages(size_t length);
26
void free_locked_pages(void* ptr, size_t length);
27
int run_cpu_instruction_probe(std::function<int ()> probe_fn);
28
*/
29

30
class OS_Utils_Tests final : public Test {
×
31
   public:
32
      std::vector<Test::Result> run() override {
1✔
33
         std::vector<Test::Result> results;
1✔
34

35
         results.push_back(test_get_process_id());
2✔
36
         results.push_back(test_get_cpu_cycle_counter());
2✔
37
         results.push_back(test_get_high_resolution_clock());
2✔
38
         results.push_back(test_get_cpu_numbers());
2✔
39
         results.push_back(test_get_system_timestamp());
2✔
40
         results.push_back(test_memory_locking());
2✔
41
         results.push_back(test_cpu_instruction_probe());
2✔
42

43
         return results;
1✔
44
      }
×
45

46
   private:
47
      static Test::Result test_get_process_id() {
1✔
48
         Test::Result result("OS::get_process_id");
1✔
49

50
         uint32_t pid1 = Botan::OS::get_process_id();
1✔
51
         uint32_t pid2 = Botan::OS::get_process_id();
1✔
52

53
         result.test_eq("PID same across calls", static_cast<size_t>(pid1), static_cast<size_t>(pid2));
1✔
54

55
#if defined(BOTAN_TARGET_OS_IS_LLVM) || defined(BOTAN_TARGET_OS_IS_NONE)
56
         result.test_eq("PID is expected to be zero on this platform", pid1, size_t(0));
57
#else
58
         result.test_ne("PID is non-zero on systems with processes", pid1, 0);
1✔
59
#endif
60

61
         return result;
1✔
62
      }
×
63

64
      static Test::Result test_get_cpu_cycle_counter() {
1✔
65
         const size_t max_trials = 1024;
1✔
66
         const size_t max_repeats = 32;
1✔
67

68
         Test::Result result("OS::get_cpu_cycle_counter");
1✔
69

70
         const uint64_t proc_ts1 = Botan::OS::get_cpu_cycle_counter();
1✔
71

72
         if(proc_ts1 == 0) {
1✔
73
            const uint64_t proc_ts2 = Botan::OS::get_cpu_cycle_counter();
×
74
            result.test_is_eq("Disabled processor timestamp stays at zero", proc_ts1, proc_ts2);
×
75
            return result;
×
76
         }
77

78
         size_t counts = 0;
79
         while(counts < max_trials && (Botan::OS::get_cpu_cycle_counter() == proc_ts1)) {
1✔
80
            ++counts;
×
81
         }
82

83
         result.test_lt("CPU cycle counter eventually changes value", counts, max_repeats);
1✔
84

85
         return result;
1✔
86
      }
×
87

88
      static Test::Result test_get_high_resolution_clock() {
1✔
89
         const size_t max_trials = 1024;
1✔
90
         const size_t max_repeats = 128;
1✔
91

92
         Test::Result result("OS::get_high_resolution_clock");
1✔
93

94
         // TODO better tests
95
         const uint64_t hr_ts1 = Botan::OS::get_high_resolution_clock();
1✔
96
         result.confirm("high resolution timestamp value is never zero", hr_ts1 != 0);
2✔
97

98
         size_t counts = 0;
1✔
99
         while(counts < max_trials && (Botan::OS::get_high_resolution_clock() == hr_ts1)) {
1✔
100
            ++counts;
×
101
         }
102

103
         result.test_lt("high resolution clock eventually changes value", counts, max_repeats);
1✔
104

105
         return result;
1✔
106
      }
×
107

108
      static Test::Result test_get_cpu_numbers() {
1✔
109
         Test::Result result("OS::get_cpu_available");
1✔
110

111
         const size_t ta = Botan::OS::get_cpu_available();
1✔
112

113
         result.test_gte("get_cpu_available is at least 1", ta, 1);
1✔
114

115
         return result;
1✔
116
      }
×
117

118
      static Test::Result test_get_system_timestamp() {
1✔
119
         // TODO better tests
120
         Test::Result result("OS::get_system_timestamp_ns");
1✔
121

122
         uint64_t sys_ts1 = Botan::OS::get_system_timestamp_ns();
1✔
123
         result.confirm("System timestamp value is never zero", sys_ts1 != 0);
2✔
124

125
         // do something that consumes a little time
126
         Botan::OS::get_process_id();
1✔
127

128
         uint64_t sys_ts2 = Botan::OS::get_system_timestamp_ns();
1✔
129

130
         result.confirm("System time moves forward", sys_ts1 <= sys_ts2);
2✔
131

132
         return result;
1✔
133
      }
×
134

135
      static Test::Result test_memory_locking() {
1✔
136
         Test::Result result("OS memory locked pages");
1✔
137

138
         // TODO any tests...
139

140
         return result;
1✔
141
      }
142

143
      static Test::Result test_cpu_instruction_probe() {
1✔
144
         Test::Result result("OS::run_cpu_instruction_probe");
1✔
145

146
         // OS::run_cpu_instruction_probe only implemented for Unix signals or Windows SEH
147

148
         std::function<int()> ok_fn = []() noexcept -> int { return 5; };
1✔
149
         const int run_rc = Botan::OS::run_cpu_instruction_probe(ok_fn);
1✔
150

151
         if(run_rc == -3) {
1✔
152
            result.test_note("run_cpu_instruction_probe not implemented on this platform");
×
153
            return {result};
×
154
         }
155

156
         result.confirm("Correct result returned by working probe fn", run_rc == 5);
3✔
157

158
         std::function<int()> crash_probe;
1✔
159

160
#if defined(BOTAN_TARGET_COMPILER_IS_MSVC)
161
         crash_probe = []() noexcept -> int {
162
            __ud2();
163
            return 3;
164
         };
165

166
#elif defined(BOTAN_USE_GCC_INLINE_ASM)
167

168
   #if defined(BOTAN_TARGET_CPU_IS_X86_FAMILY)
169
         crash_probe = []() noexcept -> int {
2✔
170
            asm volatile("ud2");
1✔
171
            return 3;
×
172
         };
1✔
173

174
   #elif defined(BOTAN_TARGET_CPU_IS_ARM_FAMILY)
175
         //ARM: asm volatile (".word 0xf7f0a000\n");
176
         // illegal instruction in both ARM and Thumb modes
177
         crash_probe = []() noexcept -> int {
178
            asm volatile(".word 0xe7f0def0\n");
179
            return 3;
180
         };
181

182
   #else
183
            /*
184
         PPC: "The instruction with primary opcode 0, when the instruction does not consist
185
         entirely of binary zeros"
186
         Others ?
187
         */
188
   #endif
189

190
#endif
191

192
         if(crash_probe) {
1✔
193
            const int crash_rc = Botan::OS::run_cpu_instruction_probe(crash_probe);
1✔
194
            result.confirm("Result for function executing undefined opcode", crash_rc < 0);
3✔
195
         }
196

197
         return result;
1✔
198
      }
2✔
199
};
200

201
BOTAN_REGISTER_TEST("utils", "os_utils", OS_Utils_Tests);
202

203
}  // namespace
204

205
}  // namespace Botan_Tests
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc