Code clean-up, duplicate code refactoring (#2467)
Co-authored-by: Dhiren Vispute <dhiren.vispute@microsoft.com>
This commit is contained in:
Родитель
5ad65e59e2
Коммит
574d41b49c
|
@ -53,8 +53,8 @@ struct test_control_info
|
|||
// The number of threads allocated per jit program.
|
||||
uint32_t threads_count{0};
|
||||
|
||||
// The run time for each jit program test thread in seconds.
|
||||
uint32_t duration{0};
|
||||
// The run time for each jit program test thread in minutes.
|
||||
uint32_t duration_minutes{0};
|
||||
|
||||
// Flag to enable verbose progress output.
|
||||
bool verbose_output{false};
|
||||
|
@ -63,7 +63,7 @@ struct test_control_info
|
|||
bool extension_restart_enabled{false};
|
||||
|
||||
// Delay between extension restarts (in milliseconds).
|
||||
uint32_t extension_restart_delay{0};
|
||||
uint32_t extension_restart_delay_ms{0};
|
||||
|
||||
// Programs to load.
|
||||
std::vector<std::string> programs;
|
||||
|
@ -82,7 +82,7 @@ struct stress_test_thread_context
|
|||
std::string file_name;
|
||||
bpf_prog_type program_type;
|
||||
ebpf_execution_type_t execution_type;
|
||||
uint32_t runtime{0};
|
||||
uint32_t duration_minutes{0};
|
||||
fd_t map_fd;
|
||||
ebpf_result_t result;
|
||||
};
|
||||
|
|
|
@ -62,10 +62,10 @@ get_test_control_info()
|
|||
test_control_info test_control{0};
|
||||
|
||||
test_control.threads_count = _test_threads_count_arg;
|
||||
test_control.duration = _test_duration_arg;
|
||||
test_control.duration_minutes = _test_duration_arg;
|
||||
test_control.verbose_output = _test_verbose_output_arg;
|
||||
test_control.extension_restart_enabled = _extension_restart_arg;
|
||||
test_control.extension_restart_delay = _extension_restart_delay_arg;
|
||||
test_control.extension_restart_delay_ms = _extension_restart_delay_arg;
|
||||
test_control.programs = _jit_programs;
|
||||
|
||||
return test_control;
|
||||
|
|
|
@ -63,21 +63,6 @@ _km_test_init()
|
|||
// No programs specified on the command line, so use the preferred default.
|
||||
_global_test_control_info.programs.push_back({"cgroup_sock_addr"});
|
||||
}
|
||||
|
||||
if (_global_test_control_info.programs.size()) {
|
||||
LOG_INFO("test programs:");
|
||||
for (const auto& program : _global_test_control_info.programs) {
|
||||
LOG_INFO("\t{}", program);
|
||||
}
|
||||
}
|
||||
|
||||
LOG_INFO("test threads per program : {}", _global_test_control_info.threads_count);
|
||||
LOG_INFO("test duration (in minutes) : {}", _global_test_control_info.duration);
|
||||
LOG_INFO("test verbose output : {}", _global_test_control_info.verbose_output);
|
||||
LOG_INFO("test extension restart : {}", _global_test_control_info.extension_restart_enabled);
|
||||
if (_global_test_control_info.extension_restart_enabled) {
|
||||
LOG_INFO("test extension restart delay: {} ms", _global_test_control_info.extension_restart_delay);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -168,6 +153,8 @@ _restart_extension(const std::string& extension_name, uint32_t timeout)
|
|||
SC_HANDLE scm_handle = nullptr;
|
||||
SC_HANDLE service_handle = nullptr;
|
||||
|
||||
REQUIRE(extension_name.size() != 0);
|
||||
|
||||
// Get a handle to the SCM database.
|
||||
scm_handle = OpenSCManager(nullptr, nullptr, SC_MANAGER_ALL_ACCESS);
|
||||
if (scm_handle == nullptr) {
|
||||
|
@ -180,7 +167,7 @@ _restart_extension(const std::string& extension_name, uint32_t timeout)
|
|||
service_handle = OpenService(
|
||||
scm_handle, ws_extension_name.c_str(), (SERVICE_STOP | SERVICE_QUERY_STATUS | SERVICE_ENUMERATE_DEPENDENTS));
|
||||
if (service_handle == nullptr) {
|
||||
LOG_ERROR("FATAL ERROR: OpenService failed. Error: {}", GetLastError());
|
||||
LOG_ERROR("FATAL ERROR: OpenService failed. Service:{}, Error: {}", extension_name, GetLastError());
|
||||
CloseServiceHandle(scm_handle);
|
||||
status = false;
|
||||
goto exit;
|
||||
|
@ -210,6 +197,45 @@ exit:
|
|||
return status;
|
||||
}
|
||||
|
||||
static std::thread
|
||||
_start_extension_restart_thread(
|
||||
const std::string& extension_name, uint32_t restart_delay_ms, uint32_t thread_lifetime_minutes)
|
||||
{
|
||||
return std::thread(
|
||||
[&](uint32_t local_restart_delay_ms, uint32_t local_thread_lifetime_minutes) {
|
||||
// Delay the start of this thread for a bit to allow the ebpf programs to attach successfully. There's a
|
||||
// window where if the extension is unloading/unloaded, an incoming attach might fail.
|
||||
std::this_thread::sleep_for(std::chrono::seconds(3));
|
||||
|
||||
// Bump up the priority of this thread so it doesn't get bogged down by the test threads.
|
||||
if (!SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST)) {
|
||||
auto error = GetLastError();
|
||||
LOG_WARN(
|
||||
"WARNING:{} - Failed to increase 'extension restart' thread priority. Error: {}", __func__, error);
|
||||
}
|
||||
|
||||
using sc = std::chrono::steady_clock;
|
||||
auto endtime = sc::now() + std::chrono::minutes(local_thread_lifetime_minutes);
|
||||
while (sc::now() < endtime) {
|
||||
|
||||
// Drivers can sometimes take some time to stop and (re)start and we need to poll until we can determine
|
||||
// the final status. 10 (ten) seconds seems a reasonable time for this polling.
|
||||
constexpr uint32_t RESTART_TIMEOUT_SECONDS = 10;
|
||||
LOG_VERBOSE("Toggling extension state for {} extension...", extension_name);
|
||||
if (!_restart_extension(extension_name, RESTART_TIMEOUT_SECONDS)) {
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
LOG_VERBOSE(
|
||||
"Next restart for {} extension after a delay of {} ms", extension_name, local_restart_delay_ms);
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(local_restart_delay_ms));
|
||||
}
|
||||
LOG_INFO("**** Extension restart thread done. Exiting. ****");
|
||||
},
|
||||
restart_delay_ms,
|
||||
thread_lifetime_minutes);
|
||||
}
|
||||
|
||||
struct bpf_object_ptr_deleter
|
||||
{
|
||||
void
|
||||
|
@ -274,7 +300,7 @@ struct thread_context
|
|||
thread_role_type role{};
|
||||
uint32_t thread_index{};
|
||||
uint32_t compartment_id{};
|
||||
uint32_t duration{};
|
||||
uint32_t duration_minutes{};
|
||||
bool extension_restart_enabled{};
|
||||
fd_t map_fd;
|
||||
fd_t program_fd;
|
||||
|
@ -531,7 +557,7 @@ static void
|
|||
_test_thread_function(thread_context& context)
|
||||
{
|
||||
using sc = std::chrono::steady_clock;
|
||||
auto endtime = sc::now() + std::chrono::minutes(context.duration);
|
||||
auto endtime = sc::now() + std::chrono::minutes(context.duration_minutes);
|
||||
while (sc::now() < endtime) {
|
||||
if (context.role == thread_role_type::CREATOR) {
|
||||
_do_creator_work(context);
|
||||
|
@ -630,7 +656,7 @@ _mt_prog_load_stress_test(ebpf_execution_type_t program_type, const test_control
|
|||
}
|
||||
context_entry.thread_index = (compartment_id - 1);
|
||||
context_entry.compartment_id = compartment_id;
|
||||
context_entry.duration = test_control_info.duration;
|
||||
context_entry.duration_minutes = test_control_info.duration_minutes;
|
||||
context_entry.extension_restart_enabled = test_control_info.extension_restart_enabled;
|
||||
compartment_id++;
|
||||
|
||||
|
@ -639,43 +665,13 @@ _mt_prog_load_stress_test(ebpf_execution_type_t program_type, const test_control
|
|||
thread_entry = std::move(std::thread(_test_thread_function, std::ref(context_entry)));
|
||||
}
|
||||
|
||||
// If requested, start the 'extension stop-and-restart' thread for extension for this program type.
|
||||
if (test_control_info.extension_restart_enabled) {
|
||||
|
||||
// If requested, start the 'extension stop-and-restart' thread for extension for this program type.
|
||||
extension_restart_thread_table.push_back(std::thread([&]() {
|
||||
// Delay the start of this thread for a bit to allow the ebpf programs to attach successfully. There's a
|
||||
// window where if the extension is unloading/unloaded, an incoming attach might fail.
|
||||
std::this_thread::sleep_for(std::chrono::seconds(3));
|
||||
|
||||
// Bump up the priority of this thread so it doesn't get bogged down by the test threads.
|
||||
if (!SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST)) {
|
||||
auto error = GetLastError();
|
||||
LOG_WARN(
|
||||
"WARNING:{} - Failed to increase 'extension restart' thread priority. Error: {}",
|
||||
__func__,
|
||||
error);
|
||||
}
|
||||
|
||||
using sc = std::chrono::steady_clock;
|
||||
auto endtime = sc::now() + std::chrono::minutes(test_control_info.duration);
|
||||
while (sc::now() < endtime) {
|
||||
|
||||
// Drivers can sometimes take some time to stop and (re)start and we need to poll until we can
|
||||
// determine the final status. 10 (ten) seconds seems a reasonable time for this polling.
|
||||
constexpr uint32_t RESTART_TIMEOUT_SECONDS = 10;
|
||||
LOG_VERBOSE("Toggling extension state for {} extension...", program_attribs.extension_name);
|
||||
if (!_restart_extension(program_attribs.extension_name, RESTART_TIMEOUT_SECONDS)) {
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
LOG_VERBOSE(
|
||||
"Next restart for {} extension after a delay of {} ms",
|
||||
program_attribs.extension_name,
|
||||
test_control_info.extension_restart_delay);
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(test_control_info.extension_restart_delay));
|
||||
}
|
||||
LOG_INFO("**** Extension restart thread done. Exiting. ****");
|
||||
}));
|
||||
auto restart_thread = _start_extension_restart_thread(
|
||||
std::ref(program_attribs.extension_name),
|
||||
test_control_info.extension_restart_delay_ms,
|
||||
test_control_info.duration_minutes);
|
||||
extension_restart_thread_table.push_back(std::move(restart_thread));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -850,7 +846,7 @@ _invoke_test_thread_function(thread_context& context)
|
|||
// will/should resume once the extension is reloaded. Note that the count will not exactly match the actual connect
|
||||
// attempts as the program will not be invoked for connect attempts made while the extension is restarting.
|
||||
using sc = std::chrono::steady_clock;
|
||||
auto endtime = sc::now() + std::chrono::minutes(context.duration);
|
||||
auto endtime = sc::now() + std::chrono::minutes(context.duration_minutes);
|
||||
while (sc::now() < endtime) {
|
||||
|
||||
uint16_t key = remote_port;
|
||||
|
@ -904,8 +900,6 @@ _mt_invoke_prog_stress_test(ebpf_execution_type_t program_type, const test_contr
|
|||
total_threads, {{}, {}, false, {}, thread_role_type::ROLE_NOT_SET, 0, 0, 0, false, 0, 0, object_table});
|
||||
std::vector<std::thread> test_thread_table(total_threads);
|
||||
|
||||
// Another table for the 'extension restart' thread.
|
||||
std::vector<std::thread> extension_restart_thread_table{};
|
||||
std::vector<std::pair<std::string, std::string>> program_file_map_names = {
|
||||
{{"cgroup_count_connect4.sys"}, {"connect4_count_map"}},
|
||||
{{"cgroup_count_connect6.sys"}, {"connect6_count_map"}}};
|
||||
|
@ -922,7 +916,7 @@ _mt_invoke_prog_stress_test(ebpf_execution_type_t program_type, const test_contr
|
|||
context_entry.role = (i == 0 ? thread_role_type::MONITOR_IPV4 : thread_role_type::MONITOR_IPV6);
|
||||
context_entry.thread_index = i;
|
||||
context_entry.compartment_id = UNSPECIFIED_COMPARTMENT_ID;
|
||||
context_entry.duration = test_control_info.duration;
|
||||
context_entry.duration_minutes = test_control_info.duration_minutes;
|
||||
context_entry.extension_restart_enabled = test_control_info.extension_restart_enabled;
|
||||
|
||||
// Now create the thread.
|
||||
|
@ -930,41 +924,15 @@ _mt_invoke_prog_stress_test(ebpf_execution_type_t program_type, const test_contr
|
|||
thread_entry = std::move(std::thread(_invoke_test_thread_function, std::ref(context_entry)));
|
||||
}
|
||||
|
||||
// Another table for the 'extension restart' threads.
|
||||
std::vector<std::thread> extension_restart_thread_table{};
|
||||
|
||||
// If requested, start the 'extension stop-and-restart' thread for extension for this program type.
|
||||
std::string extension_name = {"netebpfext"};
|
||||
if (test_control_info.extension_restart_enabled) {
|
||||
|
||||
// Start the 'extension stop-and-restart' thread for extension for this program type.
|
||||
extension_restart_thread_table.push_back(std::thread([&]() {
|
||||
// Delay the start of this thread for a bit to allow the ebpf programs to attach successfully. There's a
|
||||
// window where if the extension is unloading/unloaded, an incoming attach might fail.
|
||||
std::this_thread::sleep_for(std::chrono::seconds(3));
|
||||
|
||||
// Bump up the priority of this thread so it doesn't get bogged down by the test threads.
|
||||
if (!SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST)) {
|
||||
error = GetLastError();
|
||||
LOG_WARN("WARNING:{} - Unable to increase 'extension restart' thread priority", __func__, error);
|
||||
}
|
||||
|
||||
std::string extension_name = {"netebpfext"};
|
||||
using sc = std::chrono::steady_clock;
|
||||
auto endtime = sc::now() + std::chrono::minutes(test_control_info.duration);
|
||||
while (sc::now() < endtime) {
|
||||
LOG_VERBOSE("Toggling extension state for '{}' extension...", extension_name.c_str());
|
||||
|
||||
// Drivers can sometimes take some time to stop and (re)start and we need to poll until we can
|
||||
// determine the final status. 10 (ten) seconds seems a reasonable timeout for this polling.
|
||||
constexpr uint32_t RESTART_TIMEOUT_SECONDS = 10;
|
||||
if (!_restart_extension(extension_name, RESTART_TIMEOUT_SECONDS)) {
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
LOG_VERBOSE(
|
||||
"Next restart for {} extension after a delay of {} ms",
|
||||
extension_name,
|
||||
test_control_info.extension_restart_delay);
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(test_control_info.extension_restart_delay));
|
||||
}
|
||||
LOG_INFO("**** Extension restart thread done. Exiting. ****");
|
||||
}));
|
||||
auto restart_thread = _start_extension_restart_thread(
|
||||
std::ref(extension_name), test_control_info.extension_restart_delay_ms, test_control_info.duration_minutes);
|
||||
extension_restart_thread_table.push_back(std::move(restart_thread));
|
||||
}
|
||||
|
||||
// Wait for threads to terminate.
|
||||
|
@ -1000,7 +968,7 @@ _invoke_mt_sockaddr_thread_function(thread_context& context)
|
|||
(reinterpret_cast<PSOCKADDR_IN>(&remote_endpoint))->sin_port = htons(remote_port);
|
||||
|
||||
using sc = std::chrono::steady_clock;
|
||||
auto endtime = sc::now() + std::chrono::minutes(context.duration);
|
||||
auto endtime = sc::now() + std::chrono::minutes(context.duration_minutes);
|
||||
while (sc::now() < endtime) {
|
||||
|
||||
// Now send out a small burst of TCP 'connect' attempts for the duration of the test. We do this to increase
|
||||
|
@ -1046,7 +1014,7 @@ _mt_sockaddr_invoke_program_test(const test_control_info& test_control_info)
|
|||
context_entry.is_native_program = true;
|
||||
context_entry.role = thread_role_type::MONITOR_IPV6;
|
||||
context_entry.thread_index = i;
|
||||
context_entry.duration = test_control_info.duration;
|
||||
context_entry.duration_minutes = test_control_info.duration_minutes;
|
||||
context_entry.extension_restart_enabled = test_control_info.extension_restart_enabled;
|
||||
|
||||
// Now create the thread.
|
||||
|
@ -1054,43 +1022,15 @@ _mt_sockaddr_invoke_program_test(const test_control_info& test_control_info)
|
|||
thread_entry = std::move(std::thread(_invoke_mt_sockaddr_thread_function, std::ref(context_entry)));
|
||||
}
|
||||
|
||||
// Another table for the 'extension restart' thread.
|
||||
// Another table for the 'extension restart' threads.
|
||||
std::vector<std::thread> extension_restart_thread_table{};
|
||||
|
||||
// If requested, start the 'extension stop-and-restart' thread for extension for this program type.
|
||||
std::string extension_name = {"netebpfext"};
|
||||
if (test_control_info.extension_restart_enabled) {
|
||||
|
||||
// Start the 'extension stop-and-restart' thread for extension for this program type.
|
||||
extension_restart_thread_table.push_back(std::thread([&]() {
|
||||
// Delay the start of this thread for a bit to allow the ebpf programs to attach successfully. There's a
|
||||
// window where if the extension is unloading/unloaded, an incoming attach might fail.
|
||||
std::this_thread::sleep_for(std::chrono::seconds(3));
|
||||
|
||||
// Bump up the priority of this thread so it doesn't get bogged down by the test threads.
|
||||
if (!SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST)) {
|
||||
error = GetLastError();
|
||||
LOG_WARN("WARNING:{} - Unable to increase 'extension restart' thread priority", __func__, error);
|
||||
}
|
||||
|
||||
std::string extension_name = {"netebpfext"};
|
||||
using sc = std::chrono::steady_clock;
|
||||
auto endtime = sc::now() + std::chrono::minutes(test_control_info.duration);
|
||||
while (sc::now() < endtime) {
|
||||
LOG_VERBOSE("Toggling extension state for '{}' extension...", extension_name.c_str());
|
||||
|
||||
// Drivers can sometimes take some time to stop and (re)start and we need to poll until we can
|
||||
// determine the final status. 10 (ten) seconds seems a reasonable timeout for this polling.
|
||||
constexpr uint32_t RESTART_TIMEOUT_SECONDS = 10;
|
||||
if (!_restart_extension(extension_name, RESTART_TIMEOUT_SECONDS)) {
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
LOG_VERBOSE(
|
||||
"Next restart for {} extension after a delay of {} ms",
|
||||
extension_name,
|
||||
test_control_info.extension_restart_delay);
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(test_control_info.extension_restart_delay));
|
||||
}
|
||||
LOG_INFO("**** Extension restart thread done. Exiting. ****");
|
||||
}));
|
||||
auto restart_thread = _start_extension_restart_thread(
|
||||
std::ref(extension_name), test_control_info.extension_restart_delay_ms, test_control_info.duration_minutes);
|
||||
extension_restart_thread_table.push_back(std::move(restart_thread));
|
||||
}
|
||||
|
||||
// Wait for threads to terminate.
|
||||
|
@ -1107,6 +1047,18 @@ _mt_sockaddr_invoke_program_test(const test_control_info& test_control_info)
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
_print_test_control_info(const test_control_info& test_control_info)
|
||||
{
|
||||
LOG_INFO("test threads per program : {}", test_control_info.threads_count);
|
||||
LOG_INFO("test duration (in minutes) : {}", test_control_info.duration_minutes);
|
||||
LOG_INFO("test verbose output : {}", test_control_info.verbose_output);
|
||||
LOG_INFO("test extension restart : {}", test_control_info.extension_restart_enabled);
|
||||
if (test_control_info.extension_restart_enabled) {
|
||||
LOG_INFO("test extension restart delay: {} ms", test_control_info.extension_restart_delay_ms);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("jit_load_attach_detach_unload_random_v4_test", "[mt_stress_test]")
|
||||
{
|
||||
// This test attempts to load the same JIT'ed ebpf program multiple times in different threads. This test
|
||||
|
@ -1121,6 +1073,8 @@ TEST_CASE("jit_load_attach_detach_unload_random_v4_test", "[mt_stress_test]")
|
|||
_km_test_init();
|
||||
LOG_INFO("\nStarting test *** jit_load_attach_detach_unload_random_v4_test ***");
|
||||
test_control_info local_test_control_info = _global_test_control_info;
|
||||
|
||||
_print_test_control_info(local_test_control_info);
|
||||
_mt_prog_load_stress_test(EBPF_EXECUTION_JIT, local_test_control_info);
|
||||
}
|
||||
|
||||
|
@ -1136,12 +1090,12 @@ TEST_CASE("native_load_attach_detach_unload_random_v4_test", "[mt_stress_test]")
|
|||
_km_test_init();
|
||||
LOG_INFO("\nStarting test *** native_load_attach_detach_unload_random_v4_test ***");
|
||||
test_control_info local_test_control_info = _global_test_control_info;
|
||||
if (!local_test_control_info.extension_restart_enabled) {
|
||||
|
||||
// Enable the 'extension restart' thread to enable user mode error suppression.
|
||||
// (The restart delay is set to a default value or the value specified (if any) on the command line)
|
||||
local_test_control_info.extension_restart_enabled = true;
|
||||
}
|
||||
// Enforce enabling of the 'extension restart' thread for this test for increased stress.
|
||||
// (The restart delay is set to the default value or the value specified (if any) on the command line.)
|
||||
local_test_control_info.extension_restart_enabled = true;
|
||||
|
||||
_print_test_control_info(local_test_control_info);
|
||||
_mt_prog_load_stress_test(EBPF_EXECUTION_NATIVE, local_test_control_info);
|
||||
}
|
||||
|
||||
|
@ -1157,15 +1111,15 @@ TEST_CASE("native_unique_load_attach_detach_unload_random_v4_test", "[mt_stress_
|
|||
_km_test_init();
|
||||
LOG_INFO("\nStarting test *** native_unique_load_attach_detach_unload_random_v4_test ***");
|
||||
test_control_info local_test_control_info = _global_test_control_info;
|
||||
if (!local_test_control_info.extension_restart_enabled) {
|
||||
|
||||
// Enable the 'extension restart' thread.
|
||||
// (The restart delay is set to a default value or the value specified (if any) on the command line.
|
||||
local_test_control_info.extension_restart_enabled = true;
|
||||
}
|
||||
// Enforce enabling of the 'extension restart' thread for this test for increased stress.
|
||||
// (The restart delay is set to the default value or the value specified (if any) on the command line.)
|
||||
local_test_control_info.extension_restart_enabled = true;
|
||||
|
||||
// Use a unique native driver for each 'creator' thread.
|
||||
local_test_control_info.use_unique_native_programs = true;
|
||||
|
||||
_print_test_control_info(local_test_control_info);
|
||||
_mt_prog_load_stress_test(EBPF_EXECUTION_NATIVE, local_test_control_info);
|
||||
}
|
||||
|
||||
|
@ -1195,7 +1149,12 @@ TEST_CASE("native_invoke_program_restart_extension_v4_test", "[mt_stress_test]")
|
|||
_km_test_init();
|
||||
LOG_INFO("\nStarting test *** native_invoke_program_restart_extension_v4_test ***");
|
||||
test_control_info local_test_control_info = _global_test_control_info;
|
||||
|
||||
// Enforce enabling of the 'extension restart' thread for this test for increased stress.
|
||||
// (The restart delay is set to the default value or the value specified (if any) on the command line.)
|
||||
local_test_control_info.extension_restart_enabled = true;
|
||||
|
||||
_print_test_control_info(local_test_control_info);
|
||||
_mt_invoke_prog_stress_test(EBPF_EXECUTION_NATIVE, local_test_control_info);
|
||||
}
|
||||
|
||||
|
@ -1217,10 +1176,12 @@ TEST_CASE("sockaddr_invoke_program_test", "[mt_stress_test]")
|
|||
// We ignore the result of the 'connect' attempt as the intent here is to test the parallel invocation of the
|
||||
// WFP callout and ensure this test doesn't cause kernel mode crashes.
|
||||
//
|
||||
// 3. Start the 'extension restart' thread in parallel to continuously restart the netebpf extension.
|
||||
// 3. If specified, start the 'extension restart' thread as well to continuously restart the netebpf extension.
|
||||
|
||||
_km_test_init();
|
||||
LOG_INFO("\nStarting test *** sockaddr_invoke_program_test ***");
|
||||
test_control_info local_test_control_info = _global_test_control_info;
|
||||
|
||||
_print_test_control_info(local_test_control_info);
|
||||
_mt_sockaddr_invoke_program_test(local_test_control_info);
|
||||
}
|
||||
|
|
|
@ -8,13 +8,14 @@ _This application requires the `ebpfapi.dll` to be present in the DLL load path
|
|||
binary._
|
||||
|
||||
*Test specific command-line options (all optional, defaults used if not specified):*
|
||||
- `-tt=NNNN`: Number of test threads to create.
|
||||
- `-td=NNNN`: Test run-time in minutes.
|
||||
- `-vo=<true|false>`: Enable verbose output (default: false).
|
||||
- `-er=<true|false>`: Restart extension.
|
||||
- `-erd=NNNN`: Extension restart delay (in milliseconds).
|
||||
- `-tt=NNNN`: Number of test threads to create (Default: hard-coded).
|
||||
- `-td=NNNN`: Test duration in minutes (Default: hard-coded).
|
||||
- `-vo=<true|false>`: Enable verbose output (Default: false).
|
||||
- `-er=<true|false>`: Restart extension (Default: false, where supported).
|
||||
- `-erd=NNNN`: Extension restart delay in milliseconds (Default: hard-coded).
|
||||
|
||||
_This is a 'Catch2' test application and hence if no test name is provided on the command line, all tests are run in a sequential manner._
|
||||
_This is a 'Catch2' test application and hence if no test name is provided on the command line, all tests are run in a
|
||||
sequential manner._
|
||||
|
||||
|
||||
This application provides the following tests:
|
||||
|
@ -22,22 +23,19 @@ This application provides the following tests:
|
|||
## 1.1. jit_load_attach_detach_unload_random_v4_test
|
||||
|
||||
|
||||
This test creates threads to randomly `load`, `attach`, `detach` and `close` JIT'ed ebpf program(s). (Details in code comments)
|
||||
This test creates threads to randomly `load`, `attach`, `detach` and `close` JIT'ed ebpf program(s).
|
||||
_(Details in code comments.)_
|
||||
|
||||
Sample commandline invocations:
|
||||
|
||||
### 1.1.1. `ebpf_stress_test_km jit_load_attach_detach_unload_random_v4_test`
|
||||
- thread set size, test run-time: uses default values
|
||||
- test trace output: none
|
||||
- extension restart: disabled
|
||||
- Uses default values for all supported options.
|
||||
|
||||
|
||||
### 1.1.2. `ebpf_stress_test_km -tt=32 -td=5 -er=true jit_load_attach_detach_unload_random_v4_test`
|
||||
- thread set size: 32
|
||||
- test run-time: 5 minutes.
|
||||
- test trace output: none
|
||||
- extension restart: enabled
|
||||
- extension restart delay: default.
|
||||
- Creates 32 test threads.
|
||||
- Runs test for 5 minutes.
|
||||
- Extension restart is enabled.
|
||||
|
||||
|
||||
## 1.2. native_load_attach_detach_unload_random_v4_test
|
||||
|
@ -48,9 +46,12 @@ program (.sys file). The command line options and their interpretation is identi
|
|||
Sample command line invocations:
|
||||
|
||||
### 1.2.1. `ebpf_stress_test_km native_load_attach_detach_unload_random_v4_test`
|
||||
- use defaults.
|
||||
- Uses default values for all supported options.
|
||||
|
||||
### 1.2.2. `ebpf_stress_test_km -tt=32 -td=5 -er=true native_load_attach_detach_unload_random_v4_test`
|
||||
- Creates 32 test threads.
|
||||
- Runs test for 5 minutes.
|
||||
- Extension restart is enabled.
|
||||
|
||||
|
||||
## 1.3. native_unique_load_attach_detach_unload_random_v4_test
|
||||
|
@ -59,6 +60,9 @@ This test extends the ```native_load_attach_detach_unload_random_v4_test``` to u
|
|||
(The test makes unique copies of the same base native program at runtime). All other behavior is identical.
|
||||
|
||||
### 1.3.1. `ebpf_stress_test_km -tt=32 -td=5 -er=true native_unique_load_attach_detach_unload_random_v4_test`
|
||||
- Creates 32 test threads.
|
||||
- Runs test for 5 minutes.
|
||||
- Extension restart enabled.
|
||||
|
||||
|
||||
## 1.4. native_invoke_program_restart_extension_v4_test
|
||||
|
@ -70,10 +74,34 @@ This test ignores the `-tt`, `-er` and `-erd` commandline parameters.
|
|||
Sample command line invocations:
|
||||
|
||||
### 1.4.1. `ebpf_stress_test_km native_invoke_program_restart_extension_v4_test`
|
||||
- uses default run-time value.
|
||||
- Uses default values for all supported options.
|
||||
|
||||
### 1.4.2. `ebpf_stress_test_km -td=15 -vo=true native_invoke_program_restart_extension_v4_test`
|
||||
- runs test for 15 minutes, verbose test trace output enabled.
|
||||
- Runs test for 15 minutes.
|
||||
- Verbose test trace output enabled.
|
||||
|
||||
|
||||
## 1.5. sockaddr_invoke_program_test
|
||||
This test first loads a specific native eBPF program. It then creates the specified # of threads where each thread
|
||||
attempts a TCP 'connect' to the remote endpoint `[::1]:<target_port + thread_context.thread_index>` continuously in a
|
||||
loop. The test set up ensures that the `thread_index` passed in each `thread_context` is unique to that thread.
|
||||
|
||||
This causes the invocation of the in-kernel eBPF program which returns some (arbitrary) decision based on the end-point
|
||||
port number.
|
||||
|
||||
This test can be run with or without the extension restart option.
|
||||
|
||||
Sample command line invocations:
|
||||
|
||||
### 1.5.1. `ebpf_stress_test_km sockaddr_invoke_program_test`
|
||||
- Uses default values for all supported options.
|
||||
|
||||
### 1.5.2. `ebpf_stress_test_km -tt=32 -td=15 -vo=true -er=true -erd=250 sockaddr_invoke_program_test`
|
||||
- Creates 32 test threads.
|
||||
- Runs test for 15 minutes.
|
||||
- Verbose test trace output enabled.
|
||||
- Extension restart enabled.
|
||||
- Delay of 250 ms between successive extension restarts.
|
||||
|
||||
|
||||
# 2.0. ebpf_stress_test_um.exe (test sources in .\um\)
|
||||
|
@ -81,7 +109,7 @@ Sample command line invocations:
|
|||
This test application provides tests that are meant to be run against the user mode 'mock' of the eBPF sub-system. This
|
||||
application does not require the presence of the eBPF kernel drivers and can be run on the dev machine as well.
|
||||
|
||||
_This application requires the ```ebpfapi.dll``` to be present in the DLL load path or in the same directory as this
|
||||
_This application requires the `ebpfapi.dll` to be present in the DLL load path or in the same directory as this
|
||||
binary._
|
||||
|
||||
|
||||
|
@ -98,15 +126,15 @@ This application provides the following tests:
|
|||
|
||||
## 2.1. load_attach_detach_unload_sequential_test
|
||||
This test loads, attaches, detaches and closes (in a sequential manner) the specified JIT'ed programs in their
|
||||
respective thread sets. The test currently supprorts the `droppacket` and `bindmonitor_tailcall` programs only.
|
||||
Either one or both can be specified, else `droppacket` is used by default.
|
||||
respective thread sets. The test currently supprorts the `droppacket` and `bindmonitor_tailcall` programs only. Either
|
||||
one or both can be specified, else `droppacket` is used by default.
|
||||
|
||||
Sample command line invocations:
|
||||
|
||||
### 2.1.1. `ebpf_stress_test_um load_attach_detach_unload_sequential_test`
|
||||
- uses default run-time values for threads and run-time, loads `droppacket`
|
||||
- Uses default values for all supported options.
|
||||
|
||||
### 2.1.2. `ebpf_stress_test_km -tp="droppacket, bindmonitor_tailcall" -tt=32 -td=30 load_attach_detach_unload_sequential_test`
|
||||
- uses `droppacket` and `bindmonitor_tailcall` programs
|
||||
- creates a 32 thread set.
|
||||
- runs the test for 30 minutes.
|
||||
- Uses `droppacket` and `bindmonitor_tailcall` programs.
|
||||
- creates 32 test threads.
|
||||
- Runs the test for 30 minutes.
|
||||
|
|
|
@ -80,7 +80,7 @@ _bindmonitor_tailcall_stress_thread_function(const stress_test_thread_context& t
|
|||
{
|
||||
uint32_t count{0};
|
||||
using sc = std::chrono::steady_clock;
|
||||
auto endtime = sc::now() + std::chrono::minutes(test_params.runtime);
|
||||
auto endtime = sc::now() + std::chrono::minutes(test_params.duration_minutes);
|
||||
while (sc::now() < endtime) {
|
||||
|
||||
LOG_VERBOSE(
|
||||
|
@ -142,7 +142,7 @@ _droppacket_stress_thread_function(const stress_test_thread_context& test_params
|
|||
UNREFERENCED_PARAMETER(test_params);
|
||||
uint32_t count{0};
|
||||
using sc = std::chrono::steady_clock;
|
||||
auto endtime = sc::now() + std::chrono::minutes(test_params.runtime);
|
||||
auto endtime = sc::now() + std::chrono::minutes(test_params.duration_minutes);
|
||||
while (sc::now() < endtime) {
|
||||
|
||||
LOG_VERBOSE(
|
||||
|
@ -270,7 +270,7 @@ um_test_init()
|
|||
LOG_INFO("\t{}", program);
|
||||
}
|
||||
LOG_INFO("test threads per program : {}", _test_control_info.threads_count);
|
||||
LOG_INFO("test duration (in minutes): {}", _test_control_info.duration);
|
||||
LOG_INFO("test duration (in minutes): {}", _test_control_info.duration_minutes);
|
||||
LOG_INFO("test verbose output : {}", _test_control_info.verbose_output);
|
||||
});
|
||||
}
|
||||
|
@ -317,7 +317,7 @@ TEST_CASE("load_attach_detach_unload_sequential_test", "[mt_stress_test]")
|
|||
local_context.file_name = program_attributes.jit_file_name;
|
||||
local_context.program_type = program_attributes.program_type;
|
||||
local_context.execution_type = program_attributes.execution_type;
|
||||
local_context.runtime = _test_control_info.duration;
|
||||
local_context.duration_minutes = _test_control_info.duration_minutes;
|
||||
|
||||
// ...And spawn the required test threads.
|
||||
auto [tv, ttc] = spawn_test_threads(
|
||||
|
|
Загрузка…
Ссылка в новой задаче