test_debug_ring.cpp
Go to the documentation of this file.
1 //
2 // Bareflank Hypervisor
3 //
4 // Copyright (C) 2015 Assured Information Security, Inc.
5 // Author: Rian Quinn <quinnr@ainfosec.com>
6 // Author: Brendan Kerrigan <kerriganb@ainfosec.com>
7 //
8 // This library is free software; you can redistribute it and/or
9 // modify it under the terms of the GNU Lesser General Public
10 // License as published by the Free Software Foundation; either
11 // version 2.1 of the License, or (at your option) any later version.
12 //
13 // This library is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 // Lesser General Public License for more details.
17 //
18 // You should have received a copy of the GNU Lesser General Public
19 // License along with this library; if not, write to the Free Software
20 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 
22 #include <test.h>
23 #include <debug_ring/debug_ring.h>
24 
25 #include <gsl/gsl>
26 
28 
30 char wb[DEBUG_RING_SIZE + 100];
31 
32 bool out_of_memory = false;
33 
34 void *
35 operator new(std::size_t size)
36 {
37  if (out_of_memory)
38  throw std::bad_alloc();
39  else
40  return malloc(size);
41 }
42 
43 void
44 operator delete(void *ptr, std::size_t size) throw()
45 {
46  (void) size;
47  free(ptr);
48 }
49 
50 void
51 operator delete(void *ptr) throw()
52 {
53  operator delete(ptr, std::size_t(0));
54 }
55 
56 void
57 init_wb(uint64_t num, char val = 'A')
58 {
59  for (auto i = 0U; i < num; i++)
60  gsl::at(wb, i) = val;
61 
62  gsl::at(wb, num) = 0;
63 }
64 
65 void
66 debug_ring_ut::test_get_drr_invalid_drr()
67 {
68  this->expect_true(get_drr(0, nullptr) == GET_DRR_FAILURE);
69 }
70 
71 void
72 debug_ring_ut::test_get_drr_invalid_vcpuid()
73 {
74  this->expect_true(get_drr(0x1000, &drr) == GET_DRR_FAILURE);
75 }
76 
77 void
78 debug_ring_ut::test_constructor_out_of_memory()
79 {
80  out_of_memory = true;
81  debug_ring dr(0);
82  out_of_memory = false;
83 }
84 
85 void
86 debug_ring_ut::test_write_out_of_memory()
87 {
88  out_of_memory = true;
89  debug_ring dr(0);
90  out_of_memory = false;
91  this->expect_no_exception([&] { dr.write("hello"); });
92 }
93 
94 void
95 debug_ring_ut::test_read_with_invalid_drr()
96 {
97  this->expect_true(debug_ring_read(nullptr, static_cast<char *>(rb), DEBUG_RING_SIZE) == 0);
98 }
99 
100 void
101 debug_ring_ut::test_read_with_null_string()
102 {
103  debug_ring dr(0);
104  get_drr(0, &drr);
105 
106  this->expect_true(debug_ring_read(drr, nullptr, DEBUG_RING_SIZE) == 0);
107 }
108 
109 void
110 debug_ring_ut::test_read_with_zero_length()
111 {
112  debug_ring dr(0);
113  get_drr(0, &drr);
114 
115  this->expect_true(debug_ring_read(drr, static_cast<char *>(rb), 0) == 0);
116 }
117 
118 void
119 debug_ring_ut::test_write_with_zero_length()
120 {
121  debug_ring dr(0);
122  get_drr(0, &drr);
123 
124  auto zero_len_wb = "";
125 
126  this->expect_no_exception([&] { dr.write(static_cast<const char *>(zero_len_wb)); });
127 }
128 
129 void
130 debug_ring_ut::test_write_string_to_dr_that_is_larger_than_dr()
131 {
132  debug_ring dr(0);
133  get_drr(0, &drr);
134 
136 
137  this->expect_no_exception([&] { dr.write(static_cast<const char *>(wb)); });
138 }
139 
140 void
141 debug_ring_ut::test_write_string_to_dr_that_is_much_larger_than_dr()
142 {
143  debug_ring dr(0);
144  get_drr(0, &drr);
145 
146  init_wb(DEBUG_RING_SIZE + 50);
147 
148  this->expect_no_exception([&] { dr.write(static_cast<const char *>(wb)); });
149 }
150 
151 void
152 debug_ring_ut::test_write_one_small_string_to_dr()
153 {
154  debug_ring dr(0);
155  get_drr(0, &drr);
156 
157  auto small_wb = "01234";
158 
159  this->expect_no_exception([&] { dr.write(static_cast<const char *>(small_wb)); });
160  this->expect_true(debug_ring_read(drr, static_cast<char *>(rb), DEBUG_RING_SIZE) == 5);
161 }
162 
163 void
164 debug_ring_ut::test_fill_dr()
165 {
166  debug_ring dr(0);
167  get_drr(0, &drr);
168 
170 
171  this->expect_no_exception([&] { dr.write(static_cast<const char *>(wb)); });
172  this->expect_true(debug_ring_read(drr, static_cast<char *>(rb), DEBUG_RING_SIZE) == DEBUG_RING_SIZE);
173  this->expect_true(rb[DEBUG_RING_SIZE - 1] == '\0');
174 }
175 
176 void
177 debug_ring_ut::test_overcommit_dr()
178 {
179  debug_ring dr(0);
180  get_drr(0, &drr);
181 
182  init_wb(DEBUG_RING_SIZE - 10, 'A');
183  this->expect_no_exception([&] { dr.write(static_cast<const char *>(wb)); });
184 
185  init_wb(100, 'B');
186  this->expect_no_exception([&] { dr.write(static_cast<const char *>(wb)); });
187 
188  this->expect_true(debug_ring_read(drr, static_cast<char *>(rb), DEBUG_RING_SIZE) == 100);
189  this->expect_true(rb[0] == 'B');
190 }
191 
192 void
193 debug_ring_ut::test_overcommit_dr_more_than_once()
194 {
195  debug_ring dr(0);
196  get_drr(0, &drr);
197 
198  init_wb(DEBUG_RING_SIZE - 150, 'A');
199  this->expect_no_exception([&] { dr.write(static_cast<const char *>(wb)); });
200 
201  init_wb(DEBUG_RING_SIZE - 150, 'B');
202  this->expect_no_exception([&] { dr.write(static_cast<const char *>(wb)); });
203 
204  init_wb(DEBUG_RING_SIZE - 150, 'C');
205  this->expect_no_exception([&] { dr.write(static_cast<const char *>(wb)); });
206 
207  this->expect_true(debug_ring_read(drr, static_cast<char *>(rb), DEBUG_RING_SIZE) == DEBUG_RING_SIZE - 150);
208  this->expect_true(rb[0] == 'C');
209 }
210 
211 void
212 debug_ring_ut::test_read_with_empty_dr()
213 {
214  debug_ring dr(0);
215  get_drr(0, &drr);
216 
217  this->expect_true(debug_ring_read(drr, static_cast<char *>(rb), DEBUG_RING_SIZE) == 0);
218 }
219 
220 void
221 debug_ring_ut::acceptance_test_stress()
222 {
223  debug_ring dr(0);
224  get_drr(0, &drr);
225 
226  auto small_wb = "012";
227 
228  for (auto i = 0U; i < DEBUG_RING_SIZE; i++)
229  dr.write(static_cast<const char *>(small_wb));
230 
231  // The total number of bytes that we read out, should be equal to
232  // the total number of strings that can fit into the debug ring, minus
233  // the '\0' for each string (as they are stripped).
234 
235  auto num = DEBUG_RING_SIZE / (strlen(static_cast<const char *>(small_wb)) + 1);
236  auto total = num * strlen(static_cast<const char *>(small_wb));
237 
238  this->expect_true(debug_ring_read(drr, static_cast<char *>(rb), DEBUG_RING_SIZE) == total);
239  this->expect_true(rb[0] == '0');
240 }
void free(void *ptr)
Definition: syscall.cpp:370
char wb[DEBUG_RING_SIZE+100]
int64_t get_drr(uint64_t vcpuid, struct debug_ring_resources_t **drr)
#define expect_no_exception(f)
Definition: unittest.h:198
void * malloc(size_t size)
Definition: syscall.cpp:364
virtual void write(const std::string &str) noexcept
Definition: debug_ring.cpp:79
#define GET_DRR_FAILURE
Definition: error_codes.h:74
void init_wb(uint64_t num, char val='A')
uint64_t debug_ring_read(struct debug_ring_resources_t *drr, char *str, uint64_t len)
debug_ring_resources_t * drr
constexpr const auto size
bool out_of_memory
#define DEBUG_RING_SIZE
Definition: constants.h:206
debug_ring * dr
char rb[DEBUG_RING_SIZE]
#define expect_true(a)