test_try_catch.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 <string>
24 #include <exception.h>
25 
27 {
34 };
35 
37 
38 auto g_raii_count = 0;
39 
40 class raii
41 {
42 public:
43  raii() = default;
44  ~raii() { g_raii_count++; }
45 };
46 
47 void
49 { throw true; }
50 
51 void
53 { throw 5; }
54 
55 void
57 { throw "1234"; }
58 
59 void
61 { throw std::string("1234"); }
62 
63 void
65 { throw std::exception(); }
66 
67 void
69 { throw bfn::general_exception(); }
70 
71 std::ostream &operator<<(std::ostream &os, const raii &unused)
72 {
73  (void) unused;
74 
76  return os;
77 }
78 
79 void
81 {
82  switch (g_throw_type)
83  {
84  case throw_bool:
86  case throw_int:
88  case throw_cstr:
90  case throw_string:
92  case throw_exception:
96  }
97 }
98 
99 void
101 { level2(); }
102 
103 void
104 bfunwind_ut::test_catch_all()
105 {
106  auto caught = false;
107 
108  try
109  {
111  level1();
112  }
113  catch (...)
114  {
115  caught = true;
116  }
117 
118  this->expect_true(caught);
119 }
120 
121 void
122 bfunwind_ut::test_catch_bool()
123 {
124  auto caught = false;
125 
126  try
127  {
129  level1();
130  }
131  catch (bool val)
132  {
133  caught = true;
134  this->expect_true(val);
135  }
136  catch (...)
137  {}
138 
139  this->expect_true(caught);
140 }
141 
142 void
143 bfunwind_ut::test_catch_int()
144 {
145  auto caught = false;
146 
147  try
148  {
150  level1();
151  }
152  catch (int val)
153  {
154  caught = true;
155  this->expect_true(val == 5);
156  }
157  catch (...)
158  {}
159 
160  this->expect_true(caught);
161 }
162 
163 void
164 bfunwind_ut::test_catch_cstr()
165 {
166  auto caught = false;
167 
168  try
169  {
171  level1();
172  }
173  catch (const char *val)
174  {
175  caught = true;
176  this->expect_true(strcmp(val, "1234") == 0);
177  }
178  catch (...)
179  {}
180 
181  this->expect_true(caught);
182 }
183 
184 void
185 bfunwind_ut::test_catch_string()
186 {
187  auto caught = false;
188 
189  try
190  {
192  level1();
193  }
194  catch (std::string &val)
195  {
196  caught = true;
197  this->expect_true(val.compare("1234") == 0);
198  }
199  catch (...)
200  {}
201 
202  this->expect_true(caught);
203 }
204 
205 void
206 bfunwind_ut::test_catch_exception()
207 {
208  auto caught = false;
209 
210  try
211  {
213  level1();
214  }
215  catch (std::exception &e)
216  {
217  caught = true;
218  }
219  catch (...)
220  {}
221 
222  this->expect_true(caught);
223 }
224 
225 void
226 bfunwind_ut::test_catch_custom_exception()
227 {
228  auto caught = false;
229 
230  try
231  {
233  level1();
234  }
235  catch (bfn::general_exception &ge)
236  {
237  caught = true;
238  }
239  catch (...)
240  {}
241 
242  this->expect_true(caught);
243 }
244 
245 void
246 bfunwind_ut::test_catch_multiple_catches_per_function()
247 {
248  auto caught = false;
249 
250  try
251  {
253  }
254  catch (std::exception &e)
255  {
256  caught = true;
257  }
258 
259  this->expect_true(caught);
260  caught = false;
261 
262  try
263  {
265  }
266  catch (std::exception &e)
267  {
268  caught = true;
269  }
270 
271  this->expect_true(caught);
272  caught = false;
273 
274  try
275  {
277  }
278  catch (std::exception &e)
279  {
280  caught = true;
281  }
282 
283  this->expect_true(caught);
284 }
285 
286 void
287 bfunwind_ut::test_catch_raii()
288 {
289  auto caught = false;
290 
291  try
292  {
293  g_raii_count = 0;
294  auto raii1 = raii();
295  auto raii2 = raii();
296  auto raii3 = raii();
297  auto raii4 = raii();
298  auto raii5 = raii();
299 
301  }
302  catch (std::exception &e)
303  {
304  caught = true;
305  }
306 
307  this->expect_true(caught);
308  this->expect_true(g_raii_count == 5);
309 }
310 
311 void
312 bfunwind_ut::test_catch_throw_from_stream()
313 {
314  auto caught = false;
315 
316  try
317  {
318  auto raii1 = raii();
319  std::cout << raii1 << '\n';
320  }
321  catch (std::exception &e)
322  {
323  caught = true;
324  }
325 
326  this->expect_true(caught);
327 }
328 
329 void
330 bfunwind_ut::test_catch_nested_throw_in_catch()
331 {
332  auto caught1 = false;
333  auto caught2 = false;
334 
335  try
336  {
337  try
338  {
340  }
341  catch (std::exception &e)
342  {
343  caught1 = true;
345  }
346 
347  }
348  catch (std::exception &e)
349  {
350  caught2 = true;
351  }
352 
353  this->expect_true(caught1);
354  this->expect_true(caught2);
355 }
356 
357 void
358 bfunwind_ut::test_catch_nested_throw_outside_catch()
359 {
360  auto caught1 = false;
361  auto caught2 = false;
362 
363  try
364  {
365  try
366  {
368  }
369  catch (std::exception &e)
370  {
371  caught1 = true;
372  }
373 
375  }
376  catch (std::exception &e)
377  {
378  caught2 = true;
379  }
380 
381  this->expect_true(caught1);
382  this->expect_true(caught2);
383 }
384 
385 void
386 bfunwind_ut::test_catch_nested_throw_uncaught()
387 {
388  auto caught1 = false;
389  auto caught2 = false;
390 
391  try
392  {
393  try
394  {
396  }
397  catch (bool val)
398  {
399  caught1 = true;
400  }
401  }
402  catch (std::exception &e)
403  {
404  caught2 = true;
405  }
406 
407  this->expect_false(caught1);
408  this->expect_true(caught2);
409 }
410 
411 void
412 bfunwind_ut::test_catch_nested_throw_rethrow()
413 {
414  auto caught1 = false;
415  auto caught2 = false;
416 
417  try
418  {
419  try
420  {
422  }
423  catch (std::exception &e)
424  {
425  caught1 = true;
426  throw e;
427  }
428  }
429  catch (std::exception &e)
430  {
431  caught2 = true;
432  }
433 
434  this->expect_true(caught1);
435  this->expect_true(caught2);
436 }
437 
438 void
439 bfunwind_ut::test_catch_throw_with_lots_of_register_mods()
440 {
441  auto caught = false;
442 
443  auto r01 = 1;
444  auto r02 = 2;
445  auto r03 = 3;
446  auto r04 = 4;
447  auto r05 = 5;
448  auto r06 = 6;
449  auto r07 = 7;
450 
451  try
452  {
454  }
455  catch (std::exception &e)
456  {
457  caught = true;
458  }
459 
460  this->expect_true(caught);
461  this->expect_true(r01 == 1);
462  this->expect_true(r02 == 2);
463  this->expect_true(r03 == 3);
464  this->expect_true(r04 == 4);
465  this->expect_true(r05 == 5);
466  this->expect_true(r06 == 6);
467  this->expect_true(r07 == 7);
468 
469  caught = false;
470 
471  auto r11 = 1;
472  auto r12 = 2;
473  auto r13 = 3;
474  auto r14 = 4;
475  auto r15 = 5;
476  auto r16 = 6;
477  auto r17 = 7;
478 
479  try
480  {
482  }
483  catch (std::exception &e)
484  {
485  caught = true;
486  }
487 
488  this->expect_true(caught);
489  this->expect_true(r11 == 1);
490  this->expect_true(r12 == 2);
491  this->expect_true(r13 == 3);
492  this->expect_true(r14 == 4);
493  this->expect_true(r15 == 5);
494  this->expect_true(r16 == 6);
495  this->expect_true(r17 == 7);
496 }
void throw_int_func()
std::ostream & operator<<(std::ostream &os, const raii &unused)
void throw_custom_exception_func()
throw_type g_throw_type
auto g_raii_count
void throw_string_func()
void level1()
void level2()
throw_type
#define expect_false(a)
void throw_exception_func()
void throw_cstr_func()
#define expect_true(a)
void throw_bool_func()