Skip to content

Commit

Permalink
update(libsinsp/tests): support async event generation from sinsp_wit…
Browse files Browse the repository at this point in the history
…h_test_input

Signed-off-by: Luca Guerra <[email protected]>
  • Loading branch information
LucaGuerra authored and poiana committed Nov 24, 2023
1 parent d9a7511 commit 682a4a9
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 80 deletions.
80 changes: 7 additions & 73 deletions userspace/libsinsp/test/events_injection.ut.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,83 +4,16 @@
#include "test_utils.h"


static void encode_async_event(scap_evt* scapevt, uint64_t tid, const char* data)
{
struct scap_plugin_params
{};

static uint32_t plug_id[2] = {sizeof (uint32_t), 0};

size_t totlen = sizeof(scap_evt) + sizeof(plug_id) + sizeof(uint32_t) + strlen(data) + 1;

scapevt->tid = -1;
scapevt->len = (uint32_t)totlen;
scapevt->type = PPME_ASYNCEVENT_E;
scapevt->nparams = 2;

char* buff = (char *)scapevt + sizeof(struct ppm_evt_hdr);
memcpy(buff, (char*)plug_id, sizeof(plug_id));
buff += sizeof(plug_id);

char* valptr = buff + sizeof(uint32_t);

auto* data_len_ptr = (uint32_t*)buff;
*data_len_ptr = (uint32_t)strlen(data) + 1;
memcpy(valptr, data, *data_len_ptr);
}

class sinsp_evt_generator
{
private:
struct scap_buff
{
uint8_t data[128];
};

public:
sinsp_evt_generator() = default;
sinsp_evt_generator(sinsp_evt_generator&&) = default;
~sinsp_evt_generator() = default;

scap_evt* get(size_t idx)
{
return scap_ptrs[idx];
}

scap_evt* back()
{
return scap_ptrs.back();
}

std::unique_ptr<sinsp_evt> next(uint64_t ts = (uint64_t) -1)
{
scaps.emplace_back(new scap_buff());
scap_ptrs.emplace_back((scap_evt*)scaps.back()->data);

encode_async_event(scap_ptrs.back(), 1, "dummy_data");

auto event = std::make_unique<sinsp_evt>();
event->m_pevt = scap_ptrs.back();
event->m_cpuid = 0;
event->m_pevt->ts = ts;
return event;
};

private:
std::vector<std::shared_ptr<scap_buff> > scaps;
std::vector<scap_evt*> scap_ptrs; // gdb watch helper
};

TEST_F(sinsp_with_test_input, event_async_queue)
{
open_inspector();
m_inspector.m_lastevent_ts = 123;

sinsp_evt_generator evt_gen;
sinsp_evt* evt{};
const scap_evt *scap_evt;

// inject event
m_inspector.handle_async_event(evt_gen.next());
scap_evt = add_async_event(-1, -1, PPME_ASYNCEVENT_E, 3,
100, "event_name", scap_const_sized_buffer{NULL, 0});

// create test input event
auto* scap_evt0 = add_event(increasing_ts(), 1, PPME_SYSCALL_OPEN_X, 6, (uint64_t)3, "/tmp/the_file",
Expand All @@ -90,7 +23,7 @@ TEST_F(sinsp_with_test_input, event_async_queue)
auto res = m_inspector.next(&evt);
ASSERT_EQ(res, SCAP_SUCCESS);
ASSERT_NE(evt, nullptr);
ASSERT_EQ(evt->m_pevt, evt_gen.back());
ASSERT_EQ(evt->m_pevt, scap_evt);
ASSERT_EQ(evt->m_pevt->ts, 123);
ASSERT_TRUE(m_inspector.m_async_events_queue.empty());

Expand All @@ -100,7 +33,8 @@ TEST_F(sinsp_with_test_input, event_async_queue)
uint64_t injected_ts = scap_evt0->ts + 10;
for (int i = 0; i < 10; ++i)
{
m_inspector.handle_async_event(evt_gen.next(injected_ts + i));
add_async_event(injected_ts + i, -1, PPME_ASYNCEVENT_E, 3,
100, "event_name", scap_const_sized_buffer{NULL, 0});
}

// create input[1] ivent
Expand All @@ -118,7 +52,7 @@ TEST_F(sinsp_with_test_input, event_async_queue)
{
res = m_inspector.next(&evt);
ASSERT_EQ(res, SCAP_SUCCESS);
ASSERT_EQ(evt->m_pevt, evt_gen.get(i+1));
ASSERT_EQ(evt->m_pevt, m_async_events[i+1]);
ASSERT_TRUE(last_ts <= evt->m_pevt->ts);
last_ts = evt->m_pevt->ts;
}
Expand Down
51 changes: 44 additions & 7 deletions userspace/libsinsp/test/sinsp_with_test_input.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,11 @@ class sinsp_with_test_input : public ::testing::Test {
{
free(m_events[i]);
}

for (size_t i = 0; i < m_async_events.size(); i++)
{
free(m_async_events[i]);
}
}

sinsp m_inspector;
Expand Down Expand Up @@ -106,19 +111,15 @@ class sinsp_with_test_input : public ::testing::Test {
throw std::runtime_error("could not retrieve last event or internal error (event vector size: " + std::to_string(m_events.size()) + std::string(")"));
}

scap_evt* add_event_v(uint64_t ts, uint64_t tid, ppm_event_code event_type, uint32_t n, va_list args)
// Generates and allocates a new event.
scap_evt* create_event_v(uint64_t ts, uint64_t tid, ppm_event_code event_type, uint32_t n, va_list args)
{
struct scap_sized_buffer event_buf = {NULL, 0};
size_t event_size = 0;
char error[SCAP_LASTERR_SIZE] = {'\0'};
va_list args2;
va_copy(args2, args);

if (ts < m_last_recorded_timestamp) {
va_end(args2);
throw std::runtime_error("the test framework does not currently support out of order events with decreasing timestamps");
}

int32_t ret = scap_event_encode_params_v(event_buf, &event_size, error, event_type, n, args);

if(ret != SCAP_INPUT_TOO_SMALL) {
Expand Down Expand Up @@ -147,16 +148,51 @@ class sinsp_with_test_input : public ::testing::Test {
event->ts = ts;
event->tid = tid;

va_end(args2);
return event;
}

scap_evt* add_event_v(uint64_t ts, uint64_t tid, ppm_event_code event_type, uint32_t n, va_list args)
{
if (ts < m_last_recorded_timestamp) {
throw std::runtime_error("the test framework does not currently support out of order events with decreasing timestamps");
}

scap_evt *event = create_event_v(ts, tid, event_type, n, args);

uint64_t evtoffset = m_events.size() - m_test_data->event_count;
m_events.push_back(event);
m_test_data->events = m_events.data() + evtoffset;
m_test_data->event_count = m_events.size() - evtoffset;
m_last_recorded_timestamp = ts;

va_end(args2);
return event;
}

scap_evt* add_async_event(uint64_t ts, uint64_t tid, ppm_event_code event_type, uint32_t n, ...)
{
va_list args;
va_start(args, n);
scap_evt *ret = add_async_event_v(ts, tid, event_type, n, args);
va_end(args);

return ret;
}

scap_evt* add_async_event_v(uint64_t ts, uint64_t tid, ppm_event_code event_type, uint32_t n, va_list args)
{
scap_evt *scap_event = create_event_v(ts, tid, event_type, n, args);
m_async_events.push_back(scap_event);

auto event = std::make_unique<sinsp_evt>();
event->m_pevt = scap_event;
event->m_cpuid = 0;
event->m_pevt->ts = ts;
m_inspector.handle_async_event(std::move(event));

return scap_event;
}

/*=============================== PROCESS GENERATION ===========================*/

// Allowed event types: PPME_SYSCALL_CLONE_20_X, PPME_SYSCALL_FORK_20_X, PPME_SYSCALL_VFORK_20_X, PPME_SYSCALL_CLONE3_X
Expand Down Expand Up @@ -473,6 +509,7 @@ class sinsp_with_test_input : public ::testing::Test {

std::unique_ptr<scap_test_input_data> m_test_data;
std::vector<scap_evt*> m_events;
std::vector<scap_evt*> m_async_events;

std::vector<scap_threadinfo> m_threads;
std::vector<std::vector<scap_fdinfo>> m_fdinfos;
Expand Down

0 comments on commit 682a4a9

Please sign in to comment.