bareflank-hypervisor/bfvmm/tests/debug/debug_ring/test_debug_ring.cpp

205 lines
5.1 KiB
C++
Raw Permalink Normal View History

//
// Bareflank Hypervisor
// Copyright (C) 2015 Assured Information Security, Inc.
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
#include <catch/catch.hpp>
#include <bfgsl.h>
#include <bfnewdelete.h>
Build System Bug Fixes (#575) This patch addresses several bugs with the build system: - Lack of Windows support - Clang Tidy was not working properly - Making modifications to the source code would compile, but would not re-link resulting in issues - Removed excess file copying - Make clean now works - Removed unused or confusing folders in the build folder as part of the build process. It is now much easier to traverse the build folder for dependencies - The targets didn't work with extensions. This has been fixed. In addition, the following was also done under this patch - Intrinsics was moved to the top level and out of the VMM - Platform files are now in a folder called "platform" instead of "arch" - All subprojects have the same include/src/tests files structure - All intel specific code is properly organized to match intended namespacing - Removed dead code - A small part of the VMCS was converted to use the delegate pattern - All dependencies are now downloaded at configure time instead of compile time. - The cache directory is now cached by Travis CI - CMake output better matches old build system - Added make rebuild and separate clean targets to remove various parts of the build depending on needs. - Added targets for Clean, Tidy, Rebuild and Format for each subproject - Re-organized the cmake logic so that macros are not spread out - New validation removes unneeded complexity - Removed the need for the compiler wrapper, and in doing so, we now provide a simpilar set of toolchain files - Removed the need for Git repos. All external dependencies are downloaded using a zip or tarball - Libcxx and Libcxxabi are now in their own files. Much similar logic - Unit test CMake files have been greatly simplified - Each subproject is unaware of it's prefix and no long use VMM, USERSPACE or TEST variables in their cmake files - Fixed bugs with the flags - Renamed the varbiables in the default.cmake config to be more consistent and easier to follow in the rest of the code Signed-off-by: “rianquinn” <“rianquinn@gmail.com”>
2018-01-22 12:45:07 -07:00
#include <debug/debug_ring/debug_ring.h>
using namespace bfvmm;
debug_ring_resources_t *drr;
char rb[DEBUG_RING_SIZE];
char wb[DEBUG_RING_SIZE + 100];
void
init_wb(uint64_t num, char val = 'A')
{
for (auto i = 0U; i < num; i++) {
gsl::at(wb, i) = val;
}
gsl::at(wb, num) = 0;
}
TEST_CASE("get_drr: get_drr_invalid_drr")
{
CHECK(get_drr(0, nullptr) == GET_DRR_FAILURE);
}
TEST_CASE("get_drr: get_drr_invalid_vcpuid")
{
CHECK(get_drr(0x1000, &drr) == GET_DRR_FAILURE);
}
TEST_CASE("debug_ring: constructor_out_of_memory")
{
auto __ = gsl::finally([&] {
g_new_throws_bad_alloc = 0;
});
g_new_throws_bad_alloc = sizeof(debug_ring_resources_t);
debug_ring dr(0);
}
TEST_CASE("debug_ring: write_out_of_memory")
{
debug_ring dr(0);
CHECK_NOTHROW(dr.write("hello"));
}
TEST_CASE("debug_ring_read: read_with_invalid_drr")
{
CHECK(debug_ring_read(nullptr, static_cast<char *>(rb), DEBUG_RING_SIZE) == 0);
}
TEST_CASE("debug_ring_read: read_with_null_string")
{
debug_ring dr(0);
get_drr(0, &drr);
CHECK(debug_ring_read(drr, nullptr, DEBUG_RING_SIZE) == 0);
}
TEST_CASE("debug_ring_read: read_with_zero_length")
{
debug_ring dr(0);
get_drr(0, &drr);
CHECK(debug_ring_read(drr, static_cast<char *>(rb), 0) == 0);
}
TEST_CASE("write: write_with_zero_length")
{
debug_ring dr(0);
get_drr(0, &drr);
auto zero_len_wb = "";
CHECK_NOTHROW(dr.write(static_cast<const char *>(zero_len_wb)));
}
TEST_CASE("write: write_string_to_dr_that_is_larger_than_dr")
{
debug_ring dr(0);
get_drr(0, &drr);
init_wb(DEBUG_RING_SIZE);
CHECK_NOTHROW(dr.write(static_cast<const char *>(wb)));
}
TEST_CASE("write: write_string_to_dr_that_is_much_larger_than_dr")
{
debug_ring dr(0);
get_drr(0, &drr);
init_wb(DEBUG_RING_SIZE + 50);
CHECK_NOTHROW(dr.write(static_cast<const char *>(wb)));
}
TEST_CASE("write: write_one_small_string_to_dr")
{
debug_ring dr(0);
get_drr(0, &drr);
auto small_wb = "01234";
CHECK_NOTHROW(dr.write(static_cast<const char *>(small_wb)));
CHECK(debug_ring_read(drr, static_cast<char *>(rb), DEBUG_RING_SIZE) == 5);
}
TEST_CASE("write: fill_dr")
{
debug_ring dr(0);
get_drr(0, &drr);
init_wb(DEBUG_RING_SIZE - 1);
CHECK_NOTHROW(dr.write(static_cast<const char *>(wb)));
CHECK(debug_ring_read(drr, static_cast<char *>(rb), DEBUG_RING_SIZE) == DEBUG_RING_SIZE - 1);
CHECK(rb[DEBUG_RING_SIZE - 1] == '\0');
}
TEST_CASE("write: overcommit_dr")
{
debug_ring dr(0);
get_drr(0, &drr);
init_wb(DEBUG_RING_SIZE - 10, 'A');
CHECK_NOTHROW(dr.write(static_cast<const char *>(wb)));
init_wb(100, 'B');
CHECK_NOTHROW(dr.write(static_cast<const char *>(wb)));
CHECK(debug_ring_read(drr, static_cast<char *>(rb), DEBUG_RING_SIZE) == 100);
CHECK(rb[0] == 'B');
}
TEST_CASE("write: overcommit_dr_more_than_once")
{
debug_ring dr(0);
get_drr(0, &drr);
init_wb(DEBUG_RING_SIZE - 150, 'A');
CHECK_NOTHROW(dr.write(static_cast<const char *>(wb)));
init_wb(DEBUG_RING_SIZE - 150, 'B');
CHECK_NOTHROW(dr.write(static_cast<const char *>(wb)));
init_wb(DEBUG_RING_SIZE - 150, 'C');
CHECK_NOTHROW(dr.write(static_cast<const char *>(wb)));
CHECK(debug_ring_read(drr, static_cast<char *>(rb), DEBUG_RING_SIZE) == DEBUG_RING_SIZE - 150);
CHECK(rb[0] == 'C');
}
TEST_CASE("debug_ring_read: read_with_empty_dr")
{
debug_ring dr(0);
get_drr(0, &drr);
CHECK(debug_ring_read(drr, static_cast<char *>(rb), DEBUG_RING_SIZE) == 0);
}
TEST_CASE("write: acceptance_test_stress")
{
debug_ring dr(0);
get_drr(0, &drr);
auto small_wb = "012";
for (auto i = 0U; i < DEBUG_RING_SIZE; i++) {
dr.write(static_cast<const char *>(small_wb));
}
// The total number of bytes that we read out, should be equal to
// the total number of strings that can fit into the debug ring, minus
// the '\0' for each string (as they are stripped).
auto num = DEBUG_RING_SIZE / (strlen(static_cast<const char *>(small_wb)) + 1);
auto total = num * strlen(static_cast<const char *>(small_wb));
CHECK(debug_ring_read(drr, static_cast<char *>(rb), DEBUG_RING_SIZE) == total);
CHECK(rb[0] == '0');
}