blob: 3a5b0c3178de6d7b5fd1a9621ea038694b6795c4 [file] [log] [blame]
// SPDX-License-Identifier: LGPL-2.1
/*
* Copyright (C) 2020 VMware Inc, Yordan Karadzhov (VMware) <y.karadz@gmail.com>
*/
// Boost
#define BOOST_TEST_MODULE KernelSharkTests
#include <boost/test/unit_test.hpp>
// KernelShark
#include "libkshark.h"
#include "libkshark-plugin.h"
#include "KsCmakeDef.hpp"
#define N_TEST_STREAMS 1000
BOOST_AUTO_TEST_CASE(add_remove_streams)
{
struct kshark_context *kshark_ctx = NULL;
int sd, free = 0, i;
BOOST_REQUIRE(kshark_instance(&kshark_ctx));
for (i = 0; i < N_TEST_STREAMS; ++i) {
sd = kshark_add_stream(kshark_ctx);
BOOST_CHECK_EQUAL(sd, free);
kshark_add_stream(kshark_ctx);
free = i / 2;
kshark_remove_stream(kshark_ctx, free);
sd = kshark_add_stream(kshark_ctx);
BOOST_CHECK_EQUAL(sd, free);
free = i / 2 + 1;
kshark_remove_stream(kshark_ctx, free);
}
BOOST_CHECK_EQUAL(kshark_ctx->n_streams, N_TEST_STREAMS);
while (sd > 0)
sd = kshark_add_stream(kshark_ctx);
BOOST_CHECK_EQUAL(kshark_ctx->n_streams, INT16_MAX + 1);
BOOST_CHECK_EQUAL(kshark_ctx->stream_info.array_size, INT16_MAX + 1);
BOOST_CHECK_EQUAL(sd, -ENODEV);
kshark_free(kshark_ctx);
}
BOOST_AUTO_TEST_CASE(get_stream)
{
kshark_context *kshark_ctx(nullptr);
kshark_data_stream *stream;
int sd;
BOOST_REQUIRE(kshark_instance(&kshark_ctx));
sd = kshark_add_stream(kshark_ctx);
stream = kshark_get_data_stream(kshark_ctx, sd);
BOOST_CHECK_EQUAL(stream, nullptr);
kshark_ctx->stream[sd]->interface = malloc(1);
stream = kshark_get_data_stream(kshark_ctx, sd);
BOOST_CHECK(stream != nullptr);
kshark_free(kshark_ctx);
}
BOOST_AUTO_TEST_CASE(close_all)
{
struct kshark_context *kshark_ctx(nullptr);
int sd, i;
BOOST_REQUIRE(kshark_instance(&kshark_ctx));
for (i = 0; i < N_TEST_STREAMS; ++i) {
sd = kshark_add_stream(kshark_ctx);
BOOST_CHECK_EQUAL(sd, i);
}
kshark_close_all(kshark_ctx);
BOOST_CHECK_EQUAL(kshark_ctx->n_streams, 0);
BOOST_CHECK_EQUAL(kshark_ctx->stream_info.next_free_stream_id, 0);
BOOST_CHECK_EQUAL(kshark_ctx->stream_info.max_stream_id, -1);
for (i = 0; i < kshark_ctx->stream_info.array_size; ++i)
BOOST_CHECK_EQUAL(kshark_ctx->stream[i], nullptr);
}
#define ARRAY_DEFAULT_SIZE 1000
BOOST_AUTO_TEST_CASE(doule_size_macro)
{
int i, n = ARRAY_DEFAULT_SIZE;
int *arr = (int *) malloc(n * sizeof(*arr));
bool ok;
for (i = 0; i < n; ++i)
arr[i] = i;
ok = KS_DOUBLE_SIZE(arr, n);
BOOST_CHECK_EQUAL(ok, true);
BOOST_CHECK_EQUAL(n, ARRAY_DEFAULT_SIZE * 2);
for (i = 0; i < ARRAY_DEFAULT_SIZE; ++i)
BOOST_CHECK_EQUAL(arr[i], i);
for (; i < n; ++i)
BOOST_CHECK_EQUAL(arr[i], 0);
}
#define N_VALUES 2 * KS_CONTAINER_DEFAULT_SIZE + 1
#define MAX_TS 100000
BOOST_AUTO_TEST_CASE(fill_data_container)
{
struct kshark_data_container *data = kshark_init_data_container();
struct kshark_entry entries[N_VALUES];
int64_t i, ts_last(0);
BOOST_CHECK_EQUAL(data->capacity, KS_CONTAINER_DEFAULT_SIZE);
for (i = 0; i < N_VALUES; ++i) {
entries[i].ts = rand() % MAX_TS;
kshark_data_container_append(data, &entries[i], 10 - entries[i].ts);
}
BOOST_CHECK_EQUAL(data->size, N_VALUES);
BOOST_CHECK_EQUAL(data->capacity, 4 * KS_CONTAINER_DEFAULT_SIZE);
kshark_data_container_sort(data);
BOOST_CHECK_EQUAL(data->capacity, N_VALUES);
for (i = 0; i < N_VALUES; ++i) {
BOOST_CHECK(data->data[i]->entry->ts >= ts_last);
BOOST_CHECK_EQUAL(data->data[i]->entry->ts,
10 - data->data[i]->field);
ts_last = data->data[i]->entry->ts;
}
i = kshark_find_entry_field_by_time(MAX_TS / 2, data->data,
0, N_VALUES - 1);
BOOST_CHECK(data->data[i - 1]->entry->ts < MAX_TS / 2);
BOOST_CHECK(data->data[i]->entry->ts >= MAX_TS / 2);
kshark_free_data_container(data);
}
struct test_context {
int a;
char b;
};
KS_DEFINE_PLUGIN_CONTEXT(struct test_context, free);
BOOST_AUTO_TEST_CASE(init_close_plugin)
{
struct test_context *ctx;
int i;
for (i = 0; i < N_TEST_STREAMS; ++i) {
ctx = __init(i);
ctx->a = i * 10;
ctx->b = 'z';
}
for (i = 0; i < N_TEST_STREAMS; ++i) {
ctx = __get_context(i);
BOOST_REQUIRE(ctx != NULL);
BOOST_CHECK_EQUAL(ctx->a, i * 10);
BOOST_CHECK_EQUAL(ctx->b, 'z');
__close(i);
BOOST_REQUIRE(__get_context(i) == NULL);
}
__close(-1);
}
#define PLUGIN_1_LIB "/plugin-dummy_dpi.so"
#define PLUGIN_1_NAME "dummy_dpi"
#define PLUGIN_2_LIB "/plugin-dummy_dpi_ctrl.so"
#define PLUGIN_2_NAME "dummy_dpi_ctrl"
#define INPUT_A_LIB "/input-dummy_input.so"
#define INPUT_A_NAME "dummy_input"
#define INPUT_B_LIB "/input-dummy_input_ctrl.so"
#define INPUT_B_NAME "dummy_input_ctrl"
std::string path(KS_TEST_DIR);
BOOST_AUTO_TEST_CASE(register_plugin)
{
kshark_plugin_list *p1, *p2, *i1, *i2, *x1, *x2;
kshark_generic_stream_interface *interface;
kshark_context *kshark_ctx(nullptr);
kshark_data_stream *stream;
std::string plugin;
int sd;
BOOST_REQUIRE(kshark_instance(&kshark_ctx));
BOOST_REQUIRE(kshark_ctx->plugins == nullptr);
BOOST_REQUIRE(kshark_ctx->inputs == nullptr);
BOOST_CHECK_EQUAL(kshark_ctx->n_plugins, 0);
plugin = path + PLUGIN_1_LIB;
p1 = kshark_register_plugin(kshark_ctx, PLUGIN_1_NAME, plugin.c_str());
BOOST_CHECK_EQUAL(kshark_ctx->n_plugins, 1);
BOOST_CHECK(kshark_ctx->plugins != nullptr);
BOOST_CHECK_EQUAL(kshark_ctx->plugins->next, nullptr);
BOOST_CHECK_EQUAL(kshark_ctx->plugins, p1);
BOOST_CHECK(p1 != nullptr);
BOOST_CHECK(p1->process_interface != nullptr);
BOOST_CHECK(p1->handle != nullptr);
BOOST_CHECK_EQUAL(strcmp(p1->file, plugin.c_str()), 0);
BOOST_CHECK_EQUAL(strcmp(p1->name, PLUGIN_1_NAME), 0);
BOOST_CHECK_EQUAL(p1->ctrl_interface, nullptr);
BOOST_CHECK_EQUAL(p1->readout_interface, nullptr);
plugin = path + PLUGIN_2_LIB;
p2 = kshark_register_plugin(kshark_ctx, PLUGIN_2_NAME, plugin.c_str());
BOOST_CHECK_EQUAL(kshark_ctx->n_plugins, 2);
BOOST_CHECK_EQUAL(kshark_ctx->plugins, p2);
BOOST_CHECK_EQUAL(kshark_ctx->plugins->next, p1);
BOOST_CHECK(p2 != nullptr);
BOOST_CHECK(p2->process_interface != nullptr);
BOOST_CHECK(p2->handle != nullptr);
BOOST_CHECK_EQUAL(strcmp(p2->file, plugin.c_str()), 0);
BOOST_CHECK_EQUAL(strcmp(p2->name, PLUGIN_2_NAME), 0);
BOOST_CHECK(p2->ctrl_interface != nullptr);
BOOST_CHECK_EQUAL(p2->readout_interface, nullptr);
plugin = path + INPUT_A_LIB;
i1 = kshark_register_plugin(kshark_ctx, INPUT_A_NAME, plugin.c_str());
BOOST_CHECK(i1 != nullptr);
BOOST_CHECK_EQUAL(kshark_ctx->n_plugins, 3);
BOOST_CHECK_EQUAL(kshark_ctx->n_inputs, 1);
BOOST_CHECK(kshark_ctx->inputs != nullptr);
BOOST_CHECK(i1->readout_interface != nullptr);
BOOST_CHECK(i1->handle != nullptr);
BOOST_CHECK_EQUAL(strcmp(i1->file, plugin.c_str()), 0);
BOOST_CHECK_EQUAL(strcmp(i1->name, INPUT_A_NAME), 0);
BOOST_CHECK_EQUAL(i1->ctrl_interface, nullptr);
BOOST_CHECK_EQUAL(i1->process_interface, nullptr);
plugin = path + INPUT_B_LIB;
i2 = kshark_register_plugin(kshark_ctx, INPUT_B_NAME, plugin.c_str());
BOOST_CHECK(i2 != nullptr);
BOOST_CHECK_EQUAL(kshark_ctx->n_plugins, 4);
BOOST_CHECK_EQUAL(kshark_ctx->n_inputs, 2);
BOOST_CHECK(i2->readout_interface != nullptr);
BOOST_CHECK(i2->handle != nullptr);
BOOST_CHECK(strcmp(i2->file, plugin.c_str()) == 0);
BOOST_CHECK(strcmp(i2->name, INPUT_B_NAME) == 0);
BOOST_CHECK(i2->ctrl_interface != nullptr);
BOOST_CHECK_EQUAL(i2->process_interface, nullptr);
x1 = kshark_find_plugin_by_name(kshark_ctx->plugins, PLUGIN_2_NAME);
BOOST_CHECK_EQUAL(x1, p2);
plugin = path + PLUGIN_2_LIB;
x2 = kshark_find_plugin(kshark_ctx->plugins, plugin.c_str());
BOOST_CHECK_EQUAL(x2, p2);
sd = kshark_add_stream(kshark_ctx);
interface =
(kshark_generic_stream_interface *) malloc(sizeof(*interface));
kshark_ctx->stream[sd]->interface = interface;
BOOST_CHECK_EQUAL(sd, 0);
stream = kshark_get_data_stream(kshark_ctx, sd);
BOOST_CHECK(stream != nullptr);
BOOST_CHECK_EQUAL(stream->plugins, nullptr);
kshark_register_plugin_to_stream(stream,
p1->process_interface,
true);
BOOST_CHECK_EQUAL(stream->n_plugins, 1);
BOOST_CHECK_EQUAL(stream->plugins->interface, p1->process_interface);
BOOST_CHECK_EQUAL(stream->plugins->next, nullptr);
kshark_register_plugin_to_stream(stream,
p2->process_interface,
true);
BOOST_CHECK_EQUAL(stream->n_plugins, 2);
BOOST_CHECK_EQUAL(stream->plugins->interface, p2->process_interface);
BOOST_CHECK_EQUAL(stream->plugins->next->interface, p1->process_interface);
kshark_unregister_plugin_from_stream(stream, p1->process_interface);
BOOST_CHECK_EQUAL(stream->n_plugins, 1);
BOOST_CHECK_EQUAL(stream->plugins->interface, p2->process_interface);
BOOST_CHECK_EQUAL(stream->plugins->next, nullptr);
kshark_free(kshark_ctx);
}
#define PLUGIN_ERR_LIB "/plugin-dummy_dpi_err.so"
#define PLUGIN_ERR_NAME "dummy_dpi_err"
BOOST_AUTO_TEST_CASE(handle_plugin)
{
kshark_dpi_list *dpi1, *dpi2, *dpi_err;
kshark_plugin_list *p1, *p2, *p_err;
kshark_context *kshark_ctx(nullptr);
kshark_data_stream *stream;
std::string plugin;
int sd, ret;
BOOST_REQUIRE(kshark_instance(&kshark_ctx));
BOOST_CHECK_EQUAL(kshark_ctx->plugins, nullptr);
BOOST_CHECK_EQUAL(kshark_ctx->n_plugins, 0);
plugin = path + PLUGIN_1_LIB;
p1 = kshark_register_plugin(kshark_ctx, PLUGIN_1_NAME, plugin.c_str());
plugin = path + PLUGIN_2_LIB;
p2 = kshark_register_plugin(kshark_ctx, PLUGIN_2_NAME, plugin.c_str());
BOOST_CHECK(kshark_ctx->plugins != nullptr);
BOOST_CHECK_EQUAL(kshark_ctx->n_plugins, 2);
sd = kshark_add_stream(kshark_ctx);
kshark_ctx->stream[sd]->interface = malloc(1);
stream = kshark_get_data_stream(kshark_ctx, sd);
BOOST_CHECK(stream != nullptr);
dpi1 = kshark_register_plugin_to_stream(stream,
p1->process_interface,
true);
BOOST_CHECK_EQUAL(dpi1->status, KSHARK_PLUGIN_ENABLED);
dpi2 = kshark_register_plugin_to_stream(stream,
p2->process_interface,
false);
BOOST_CHECK_EQUAL(dpi2->status, 0);
ret = kshark_handle_dpi(stream, dpi1, KSHARK_PLUGIN_INIT);
BOOST_CHECK_EQUAL(ret, 1);
BOOST_CHECK_EQUAL(dpi1->status,
KSHARK_PLUGIN_LOADED | KSHARK_PLUGIN_ENABLED);
ret = kshark_handle_dpi(stream, dpi2, KSHARK_PLUGIN_INIT);
BOOST_CHECK_EQUAL(ret, 0);
BOOST_CHECK_EQUAL(dpi2->status, 0);
dpi2->status |= KSHARK_PLUGIN_ENABLED;
ret = kshark_handle_dpi(stream, dpi2, KSHARK_PLUGIN_INIT);
BOOST_CHECK_EQUAL(ret, 2);
BOOST_CHECK_EQUAL(dpi1->status,
KSHARK_PLUGIN_LOADED | KSHARK_PLUGIN_ENABLED);
ret = kshark_handle_all_dpis(stream, KSHARK_PLUGIN_UPDATE);
BOOST_CHECK_EQUAL(ret, 0);
BOOST_CHECK_EQUAL(dpi1->status,
KSHARK_PLUGIN_LOADED | KSHARK_PLUGIN_ENABLED);
BOOST_CHECK_EQUAL(dpi2->status,
KSHARK_PLUGIN_LOADED | KSHARK_PLUGIN_ENABLED);
plugin = path + PLUGIN_ERR_LIB;
p_err = kshark_register_plugin(kshark_ctx, PLUGIN_ERR_NAME,
plugin.c_str());
BOOST_CHECK_EQUAL(kshark_ctx->n_plugins, 3);
dpi_err = kshark_register_plugin_to_stream(stream,
p_err->process_interface,
true);
BOOST_CHECK_EQUAL(ret, 0);
ret = kshark_handle_dpi(stream, dpi_err, KSHARK_PLUGIN_INIT);
BOOST_CHECK_EQUAL(dpi_err->status,
KSHARK_PLUGIN_FAILED | KSHARK_PLUGIN_ENABLED);
BOOST_CHECK_EQUAL(ret, 0);
ret = kshark_handle_dpi(stream, dpi_err, KSHARK_PLUGIN_CLOSE);
BOOST_CHECK_EQUAL(ret, 0);
BOOST_CHECK_EQUAL(dpi_err->status, KSHARK_PLUGIN_ENABLED);
ret = kshark_handle_all_dpis(stream, KSHARK_PLUGIN_CLOSE);
BOOST_CHECK_EQUAL(ret, -3);
kshark_free(kshark_ctx);
}
#define FAKE_DATA_FILE_A "test.ta"
#define FAKE_DATA_A_SIZE 200
#define FAKE_DATA_FILE_B "test.tb"
#define FAKE_DATA_B_SIZE 100
BOOST_AUTO_TEST_CASE(readout_plugins)
{
kshark_context *kshark_ctx(nullptr);
kshark_entry **entries{nullptr};
kshark_data_stream *stream;
std::string plugin, data;
int sd, i, n_entries;
int64_t ts_last(0);
BOOST_REQUIRE(kshark_instance(&kshark_ctx));
plugin = path + INPUT_A_LIB;
kshark_register_plugin(kshark_ctx, INPUT_A_NAME, plugin.c_str());
plugin = path + INPUT_B_LIB;
kshark_register_plugin(kshark_ctx, INPUT_B_NAME, plugin.c_str());
data = FAKE_DATA_FILE_A;
sd = kshark_open(kshark_ctx, data.c_str());
BOOST_CHECK_EQUAL(sd, 0);
stream = kshark_get_data_stream(kshark_ctx, sd);
BOOST_CHECK(stream != nullptr);
BOOST_CHECK(stream->interface != nullptr);
BOOST_CHECK_EQUAL(strcmp(stream->data_format, "format_a"), 0);
data = FAKE_DATA_FILE_B;
sd = kshark_open(kshark_ctx, data.c_str());
BOOST_CHECK_EQUAL(sd, 1);
stream = kshark_get_data_stream(kshark_ctx, sd);
BOOST_CHECK(stream != nullptr);
BOOST_CHECK(stream->interface != nullptr);
BOOST_CHECK_EQUAL(strcmp(stream->data_format, "format_b"), 0);
n_entries = kshark_load_all_entries(kshark_ctx, &entries);
BOOST_CHECK_EQUAL(n_entries, FAKE_DATA_A_SIZE + FAKE_DATA_B_SIZE);
for (i = 0; i < n_entries; ++i) {
BOOST_CHECK(ts_last <= entries[i]->ts);
ts_last = entries[i]->ts;
}
for (i = 0; i < n_entries; ++i)
free(entries[i]);
free(entries);
kshark_free(kshark_ctx);
}
BOOST_AUTO_TEST_CASE(check_font_found)
{
#ifdef TT_FONT_FILE
BOOST_REQUIRE(true);
#else
BOOST_REQUIRE(false);
#endif
}