mirror of
https://github.com/varun-r-mallya/sysprof.git
synced 2025-12-31 20:36:25 +00:00
1021 lines
31 KiB
C
1021 lines
31 KiB
C
/* test-capture.c
|
|
*
|
|
* Copyright 2016 Christian Hergert <christian@hergert.me>
|
|
*
|
|
* This file 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 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This file 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 General Public License
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#define G_LOG_DOMAIN "test-capture"
|
|
|
|
#include "config.h"
|
|
|
|
#include <fcntl.h>
|
|
#include <glib.h>
|
|
#include <glib/gstdio.h>
|
|
#include <string.h>
|
|
#include <sysprof-capture.h>
|
|
#include <sys/types.h>
|
|
#include <unistd.h>
|
|
|
|
#include "sysprof-platform.h"
|
|
#include "sysprof-capture-util-private.h"
|
|
|
|
static void
|
|
copy_into (const SysprofCaptureJitmap *src,
|
|
GHashTable *dst)
|
|
{
|
|
SysprofCaptureJitmapIter iter;
|
|
SysprofCaptureAddress addr;
|
|
const char *name;
|
|
|
|
sysprof_capture_jitmap_iter_init (&iter, src);
|
|
while (sysprof_capture_jitmap_iter_next (&iter, &addr, &name))
|
|
g_hash_table_insert (dst, GSIZE_TO_POINTER (addr), g_strdup (name));
|
|
}
|
|
|
|
static void
|
|
test_reader_basic (void)
|
|
{
|
|
SysprofCaptureReader *reader;
|
|
SysprofCaptureWriter *writer;
|
|
g_autoptr(GHashTable) jmap = NULL;
|
|
GError *error = NULL;
|
|
gint64 t = SYSPROF_CAPTURE_CURRENT_TIME;
|
|
guint i;
|
|
gint r;
|
|
|
|
writer = sysprof_capture_writer_new ("capture-file", 0);
|
|
g_assert (writer != NULL);
|
|
g_assert_cmpint (sysprof_capture_writer_get_buffer_size (writer), ==, _sysprof_getpagesize()*64);
|
|
|
|
sysprof_capture_writer_flush (writer);
|
|
|
|
reader = sysprof_capture_reader_new ("capture-file");
|
|
g_assert_nonnull (reader);
|
|
|
|
for (i = 0; i < 100; i++)
|
|
{
|
|
gchar str[16];
|
|
|
|
g_snprintf (str, sizeof str, "%d", i);
|
|
|
|
r = sysprof_capture_writer_add_map (writer, t, -1, -1, i, i + 1, i + 2, i + 3, str);
|
|
g_assert_cmpint (r, ==, TRUE);
|
|
}
|
|
|
|
sysprof_capture_writer_flush (writer);
|
|
|
|
for (i = 0; i < 100; i++)
|
|
{
|
|
SysprofCaptureFrameType type = -1;
|
|
const SysprofCaptureMap *map;
|
|
gchar str[16];
|
|
|
|
g_snprintf (str, sizeof str, "%d", i);
|
|
|
|
if (!sysprof_capture_reader_peek_type (reader, &type))
|
|
g_assert_not_reached ();
|
|
|
|
g_assert_cmpint (type, ==, SYSPROF_CAPTURE_FRAME_MAP);
|
|
|
|
map = sysprof_capture_reader_read_map (reader);
|
|
|
|
g_assert (map != NULL);
|
|
g_assert_cmpint (map->frame.pid, ==, -1);
|
|
g_assert_cmpint (map->frame.cpu, ==, -1);
|
|
g_assert_cmpint (map->start, ==, i);
|
|
g_assert_cmpint (map->end, ==, i + 1);
|
|
g_assert_cmpint (map->offset, ==, i + 2);
|
|
g_assert_cmpint (map->inode, ==, i + 3);
|
|
g_assert_cmpstr (map->filename, ==, str);
|
|
}
|
|
|
|
/* Now that we have read a frame, we should start having updated
|
|
* end times with each incoming frame.
|
|
*/
|
|
g_assert_cmpint (0, !=, sysprof_capture_reader_get_end_time (reader));
|
|
|
|
for (i = 0; i < 100; i++)
|
|
{
|
|
r = sysprof_capture_writer_add_timestamp (writer, t, i, -1);
|
|
g_assert_cmpint (r, ==, TRUE);
|
|
}
|
|
|
|
sysprof_capture_writer_flush (writer);
|
|
|
|
for (i = 0; i < 100; i++)
|
|
{
|
|
SysprofCaptureFrameType type = -1;
|
|
const SysprofCaptureTimestamp *ts;
|
|
|
|
if (!sysprof_capture_reader_peek_type (reader, &type))
|
|
g_assert_not_reached ();
|
|
|
|
g_assert_cmpint (type, ==, SYSPROF_CAPTURE_FRAME_TIMESTAMP);
|
|
|
|
ts = sysprof_capture_reader_read_timestamp (reader);
|
|
|
|
g_assert (ts != NULL);
|
|
g_assert_cmpint (ts->frame.cpu, ==, i);
|
|
g_assert_cmpint (ts->frame.pid, ==, -1);
|
|
}
|
|
|
|
for (i = 0; i < 100; i++)
|
|
{
|
|
r = sysprof_capture_writer_add_exit (writer, t, i, -1);
|
|
g_assert_cmpint (r, ==, TRUE);
|
|
}
|
|
|
|
sysprof_capture_writer_flush (writer);
|
|
|
|
for (i = 0; i < 100; i++)
|
|
{
|
|
SysprofCaptureFrameType type = -1;
|
|
const SysprofCaptureExit *ex;
|
|
|
|
if (!sysprof_capture_reader_peek_type (reader, &type))
|
|
g_assert_not_reached ();
|
|
|
|
g_assert_cmpint (type, ==, SYSPROF_CAPTURE_FRAME_EXIT);
|
|
|
|
ex = sysprof_capture_reader_read_exit (reader);
|
|
|
|
g_assert (ex != NULL);
|
|
g_assert_cmpint (ex->frame.cpu, ==, i);
|
|
g_assert_cmpint (ex->frame.pid, ==, -1);
|
|
}
|
|
|
|
for (i = 0; i < 100; i++)
|
|
{
|
|
char cmdline[32];
|
|
|
|
g_snprintf (cmdline, sizeof cmdline, "program-%d", i);
|
|
r = sysprof_capture_writer_add_process (writer, t, -1, i, cmdline);
|
|
g_assert_cmpint (r, ==, TRUE);
|
|
}
|
|
|
|
sysprof_capture_writer_flush (writer);
|
|
|
|
for (i = 0; i < 100; i++)
|
|
{
|
|
SysprofCaptureFrameType type = -1;
|
|
const SysprofCaptureProcess *pr;
|
|
char str[32];
|
|
|
|
g_snprintf (str, sizeof str, "program-%d", i);
|
|
|
|
if (!sysprof_capture_reader_peek_type (reader, &type))
|
|
g_assert_not_reached ();
|
|
|
|
g_assert_cmpint (type, ==, SYSPROF_CAPTURE_FRAME_PROCESS);
|
|
|
|
pr = sysprof_capture_reader_read_process (reader);
|
|
|
|
g_assert (pr != NULL);
|
|
g_assert_cmpint (pr->frame.cpu, ==, -1);
|
|
g_assert_cmpint (pr->frame.pid, ==, i);
|
|
g_assert_cmpstr (pr->cmdline, ==, str);
|
|
}
|
|
|
|
for (i = 0; i < 100; i++)
|
|
{
|
|
r = sysprof_capture_writer_add_fork (writer, t, i, -1, i);
|
|
g_assert_cmpint (r, ==, TRUE);
|
|
}
|
|
|
|
sysprof_capture_writer_flush (writer);
|
|
|
|
for (i = 0; i < 100; i++)
|
|
{
|
|
SysprofCaptureFrameType type = -1;
|
|
const SysprofCaptureFork *ex;
|
|
|
|
if (!sysprof_capture_reader_peek_type (reader, &type))
|
|
g_assert_not_reached ();
|
|
|
|
g_assert_cmpint (type, ==, SYSPROF_CAPTURE_FRAME_FORK);
|
|
|
|
ex = sysprof_capture_reader_read_fork (reader);
|
|
|
|
g_assert (ex != NULL);
|
|
g_assert_cmpint (ex->frame.cpu, ==, i);
|
|
g_assert_cmpint (ex->frame.pid, ==, -1);
|
|
g_assert_cmpint (ex->child_pid, ==, i);
|
|
}
|
|
|
|
{
|
|
SysprofCaptureCounter counters[10];
|
|
guint base = sysprof_capture_writer_request_counter (writer, G_N_ELEMENTS (counters));
|
|
|
|
t = SYSPROF_CAPTURE_CURRENT_TIME;
|
|
|
|
for (i = 0; i < G_N_ELEMENTS (counters); i++)
|
|
{
|
|
g_snprintf (counters[i].category, sizeof counters[i].category, "cat%d", i);
|
|
g_snprintf (counters[i].name, sizeof counters[i].name, "name%d", i);
|
|
g_snprintf (counters[i].description, sizeof counters[i].description, "desc%d", i);
|
|
counters[i].id = base + i;
|
|
counters[i].type = 0;
|
|
counters[i].value.v64 = i * G_GINT64_CONSTANT (100000000000);
|
|
}
|
|
|
|
r = sysprof_capture_writer_define_counters (writer, t, -1, -1, counters, G_N_ELEMENTS (counters));
|
|
g_assert_cmpint (r, ==, TRUE);
|
|
}
|
|
|
|
sysprof_capture_writer_flush (writer);
|
|
|
|
{
|
|
const SysprofCaptureCounterDefine *def;
|
|
|
|
def = sysprof_capture_reader_read_counter_define (reader);
|
|
g_assert (def != NULL);
|
|
g_assert_cmpint (def->n_counters, ==, 10);
|
|
|
|
for (i = 0; i < def->n_counters; i++)
|
|
{
|
|
g_autofree gchar *cat = g_strdup_printf ("cat%d", i);
|
|
g_autofree gchar *name = g_strdup_printf ("name%d", i);
|
|
g_autofree gchar *desc = g_strdup_printf ("desc%d", i);
|
|
|
|
g_assert_cmpstr (def->counters[i].category, ==, cat);
|
|
g_assert_cmpstr (def->counters[i].name, ==, name);
|
|
g_assert_cmpstr (def->counters[i].description, ==, desc);
|
|
}
|
|
}
|
|
|
|
for (i = 0; i < 1000; i++)
|
|
{
|
|
guint ids[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
|
|
SysprofCaptureCounterValue values[10] = { {1}, {2}, {3}, {4}, {5}, {6}, {7}, {8}, {9}, {10} };
|
|
|
|
r = sysprof_capture_writer_set_counters (writer, t, -1, -1, ids, values, G_N_ELEMENTS (values));
|
|
g_assert_cmpint (r, ==, TRUE);
|
|
}
|
|
|
|
sysprof_capture_writer_flush (writer);
|
|
|
|
for (i = 0; i < 1000; i++)
|
|
{
|
|
const SysprofCaptureCounterSet *set;
|
|
|
|
set = sysprof_capture_reader_read_counter_set (reader);
|
|
g_assert (set != NULL);
|
|
|
|
/* 8 per chunk */
|
|
g_assert_cmpint (set->n_values, ==, 2);
|
|
|
|
g_assert_cmpint (1, ==, set->values[0].ids[0]);
|
|
g_assert_cmpint (2, ==, set->values[0].ids[1]);
|
|
g_assert_cmpint (3, ==, set->values[0].ids[2]);
|
|
g_assert_cmpint (4, ==, set->values[0].ids[3]);
|
|
g_assert_cmpint (5, ==, set->values[0].ids[4]);
|
|
g_assert_cmpint (6, ==, set->values[0].ids[5]);
|
|
g_assert_cmpint (7, ==, set->values[0].ids[6]);
|
|
g_assert_cmpint (8, ==, set->values[0].ids[7]);
|
|
g_assert_cmpint (9, ==, set->values[1].ids[0]);
|
|
g_assert_cmpint (10, ==, set->values[1].ids[1]);
|
|
g_assert_cmpint (1, ==, set->values[0].values[0].v64);
|
|
g_assert_cmpint (2, ==, set->values[0].values[1].v64);
|
|
g_assert_cmpint (3, ==, set->values[0].values[2].v64);
|
|
g_assert_cmpint (4, ==, set->values[0].values[3].v64);
|
|
g_assert_cmpint (5, ==, set->values[0].values[4].v64);
|
|
g_assert_cmpint (6, ==, set->values[0].values[5].v64);
|
|
g_assert_cmpint (7, ==, set->values[0].values[6].v64);
|
|
g_assert_cmpint (8, ==, set->values[0].values[7].v64);
|
|
g_assert_cmpint (9, ==, set->values[1].values[0].v64);
|
|
g_assert_cmpint (10, ==, set->values[1].values[1].v64);
|
|
}
|
|
|
|
for (i = 0; i < 1000; i++)
|
|
{
|
|
SysprofCaptureAddress addr;
|
|
gchar str[32];
|
|
|
|
g_snprintf (str, sizeof str, "jitstring-%d", i);
|
|
|
|
addr = sysprof_capture_writer_add_jitmap (writer, str);
|
|
g_assert_cmpint (addr, ==, (i + 1) | SYSPROF_CAPTURE_JITMAP_MARK);
|
|
}
|
|
|
|
sysprof_capture_writer_flush (writer);
|
|
|
|
i = 0;
|
|
|
|
jmap = g_hash_table_new_full (NULL, NULL, NULL, g_free);
|
|
|
|
for (;;)
|
|
{
|
|
SysprofCaptureFrameType type = -1;
|
|
const SysprofCaptureJitmap *jitmap;
|
|
|
|
if (sysprof_capture_reader_peek_type (reader, &type))
|
|
g_assert_cmpint (type, ==, SYSPROF_CAPTURE_FRAME_JITMAP);
|
|
else
|
|
break;
|
|
|
|
jitmap = sysprof_capture_reader_read_jitmap (reader);
|
|
g_assert_nonnull (jitmap);
|
|
|
|
i += jitmap->n_jitmaps;
|
|
|
|
copy_into (jitmap, jmap);
|
|
}
|
|
|
|
g_assert_cmpint (1000, ==, i);
|
|
|
|
for (i = 0; i < 1000; i++)
|
|
{
|
|
SysprofCaptureAddress addr = ((SysprofCaptureAddress)i + 1L) | SYSPROF_CAPTURE_JITMAP_MARK;
|
|
const gchar *mapped = g_hash_table_lookup (jmap, (gpointer)addr);
|
|
gchar str[32];
|
|
|
|
g_snprintf (str, sizeof str, "jitstring-%d", i);
|
|
g_assert_cmpstr (str, ==, mapped);
|
|
}
|
|
|
|
{
|
|
SysprofCaptureFrameType type = -1;
|
|
|
|
if (sysprof_capture_reader_peek_type (reader, &type))
|
|
g_assert_not_reached ();
|
|
}
|
|
|
|
for (i = 1; i <= 1000; i++)
|
|
{
|
|
SysprofCaptureAddress *addrs;
|
|
guint j;
|
|
|
|
addrs = alloca (i * sizeof *addrs);
|
|
|
|
for (j = 0; j < i; j++)
|
|
addrs[j] = i;
|
|
|
|
if (!sysprof_capture_writer_add_sample (writer, t, -1, -1, -2, addrs, i))
|
|
g_assert_not_reached ();
|
|
}
|
|
|
|
sysprof_capture_writer_flush (writer);
|
|
|
|
for (i = 1; i <= 1000; i++)
|
|
{
|
|
SysprofCaptureFrameType type = -1;
|
|
const SysprofCaptureSample *sample;
|
|
guint j;
|
|
|
|
if (!sysprof_capture_reader_peek_type (reader, &type))
|
|
g_assert_not_reached ();
|
|
|
|
g_assert_cmpint (type, ==, SYSPROF_CAPTURE_FRAME_SAMPLE);
|
|
|
|
sample = sysprof_capture_reader_read_sample (reader);
|
|
|
|
g_assert (sample != NULL);
|
|
g_assert_cmpint (sample->frame.time, ==, t);
|
|
g_assert_cmpint (sample->frame.cpu, ==, -1);
|
|
g_assert_cmpint (sample->frame.pid, ==, -1);
|
|
g_assert_cmpint (sample->tid, ==, -2);
|
|
g_assert_cmpint (sample->n_addrs, ==, i);
|
|
|
|
for (j = 0; j < i; j++)
|
|
g_assert_cmpint (sample->addrs[j], ==, i);
|
|
}
|
|
|
|
{
|
|
SysprofCaptureFrameType type = -1;
|
|
|
|
if (sysprof_capture_reader_peek_type (reader, &type))
|
|
g_assert_not_reached ();
|
|
}
|
|
|
|
r = sysprof_capture_writer_save_as (writer, "capture-file.bak");
|
|
g_assert_true (r);
|
|
g_assert (g_file_test ("capture-file.bak", G_FILE_TEST_IS_REGULAR));
|
|
|
|
/* make sure contents are equal */
|
|
{
|
|
g_autofree gchar *buf1 = NULL;
|
|
g_autofree gchar *buf2 = NULL;
|
|
gsize buf1len = 0;
|
|
gsize buf2len = 0;
|
|
|
|
r = g_file_get_contents ("capture-file.bak", &buf1, &buf1len, &error);
|
|
g_assert_no_error (error);
|
|
g_assert_true (r);
|
|
|
|
r = g_file_get_contents ("capture-file", &buf2, &buf2len, &error);
|
|
g_assert_no_error (error);
|
|
g_assert_true (r);
|
|
|
|
g_assert_cmpint (buf1len, >, 0);
|
|
g_assert_cmpint (buf2len, >, 0);
|
|
|
|
g_assert_cmpint (buf1len, ==, buf2len);
|
|
g_assert_true (0 == memcmp (buf1, buf2, buf1len));
|
|
}
|
|
|
|
g_clear_pointer (&writer, sysprof_capture_writer_unref);
|
|
g_clear_pointer (&reader, sysprof_capture_reader_unref);
|
|
|
|
reader = sysprof_capture_reader_new ("capture-file.bak");
|
|
g_assert_nonnull (reader);
|
|
|
|
for (i = 0; i < 2; i++)
|
|
{
|
|
SysprofCaptureFrameType type = -1;
|
|
guint count = 0;
|
|
|
|
while (sysprof_capture_reader_peek_type (reader, &type))
|
|
{
|
|
count++;
|
|
if (!sysprof_capture_reader_skip (reader))
|
|
g_assert_not_reached ();
|
|
}
|
|
|
|
g_assert_cmpint (count, >, 1500);
|
|
|
|
sysprof_capture_reader_reset (reader);
|
|
}
|
|
|
|
sysprof_capture_reader_unref (reader);
|
|
|
|
g_unlink ("capture-file");
|
|
g_unlink ("capture-file.bak");
|
|
}
|
|
|
|
static void
|
|
test_writer_splice (void)
|
|
{
|
|
SysprofCaptureWriter *writer1;
|
|
SysprofCaptureWriter *writer2;
|
|
SysprofCaptureReader *reader;
|
|
SysprofCaptureFrameType type;
|
|
guint i;
|
|
gint r;
|
|
|
|
writer1 = sysprof_capture_writer_new ("writer1.syscap", 0);
|
|
writer2 = sysprof_capture_writer_new ("writer2.syscap", 0);
|
|
|
|
for (i = 0; i < 1000; i++)
|
|
sysprof_capture_writer_add_timestamp (writer1, SYSPROF_CAPTURE_CURRENT_TIME, -1, -1);
|
|
|
|
r = sysprof_capture_writer_splice (writer1, writer2);
|
|
g_assert_true (r);
|
|
|
|
g_clear_pointer (&writer1, sysprof_capture_writer_unref);
|
|
g_clear_pointer (&writer2, sysprof_capture_writer_unref);
|
|
|
|
reader = sysprof_capture_reader_new ("writer2.syscap");
|
|
g_assert_nonnull (reader);
|
|
|
|
for (i = 0; i < 1000; i++)
|
|
{
|
|
const SysprofCaptureTimestamp *ts = sysprof_capture_reader_read_timestamp (reader);
|
|
|
|
g_assert (ts != NULL);
|
|
g_assert_cmpint (ts->frame.cpu, ==, -1);
|
|
g_assert_cmpint (ts->frame.pid, ==, -1);
|
|
g_assert_cmpint (ts->frame.time, >, 0);
|
|
}
|
|
|
|
r = sysprof_capture_reader_peek_type (reader, &type);
|
|
g_assert_cmpint (r, ==, FALSE);
|
|
|
|
g_clear_pointer (&reader, sysprof_capture_reader_unref);
|
|
|
|
g_unlink ("writer1.syscap");
|
|
g_unlink ("writer2.syscap");
|
|
}
|
|
|
|
static void
|
|
test_reader_splice (void)
|
|
{
|
|
SysprofCaptureWriter *writer1;
|
|
SysprofCaptureWriter *writer2;
|
|
SysprofCaptureReader *reader;
|
|
SysprofCaptureFrameType type;
|
|
guint i;
|
|
guint count;
|
|
gint r;
|
|
|
|
writer1 = sysprof_capture_writer_new ("writer1.syscap", 0);
|
|
writer2 = sysprof_capture_writer_new ("writer2.syscap", 0);
|
|
|
|
for (i = 0; i < 1000; i++)
|
|
sysprof_capture_writer_add_timestamp (writer1, SYSPROF_CAPTURE_CURRENT_TIME, -1, -1);
|
|
|
|
r = sysprof_capture_writer_flush (writer1);
|
|
g_assert_cmpint (r, ==, TRUE);
|
|
|
|
g_clear_pointer (&writer1, sysprof_capture_writer_unref);
|
|
|
|
reader = sysprof_capture_reader_new ("writer1.syscap");
|
|
g_assert_nonnull (reader);
|
|
|
|
/* advance to the end of the reader to non-start boundary for fd */
|
|
|
|
for (i = 0; i < 1000; i++)
|
|
{
|
|
const SysprofCaptureTimestamp *ts = sysprof_capture_reader_read_timestamp (reader);
|
|
|
|
g_assert (ts != NULL);
|
|
g_assert_cmpint (ts->frame.cpu, ==, -1);
|
|
g_assert_cmpint (ts->frame.pid, ==, -1);
|
|
g_assert_cmpint (ts->frame.time, >, 0);
|
|
}
|
|
|
|
r = sysprof_capture_reader_peek_type (reader, &type);
|
|
g_assert_cmpint (r, ==, FALSE);
|
|
|
|
r = sysprof_capture_reader_splice (reader, writer2);
|
|
g_assert_true (r);
|
|
|
|
g_clear_pointer (&reader, sysprof_capture_reader_unref);
|
|
g_clear_pointer (&writer2, sysprof_capture_writer_unref);
|
|
|
|
reader = sysprof_capture_reader_new ("writer2.syscap");
|
|
g_assert_nonnull (reader);
|
|
|
|
for (i = 0; i < 1000; i++)
|
|
{
|
|
const SysprofCaptureTimestamp *ts = sysprof_capture_reader_read_timestamp (reader);
|
|
|
|
g_assert (ts != NULL);
|
|
g_assert_cmpint (ts->frame.cpu, ==, -1);
|
|
g_assert_cmpint (ts->frame.pid, ==, -1);
|
|
g_assert_cmpint (ts->frame.time, >, 0);
|
|
}
|
|
|
|
r = sysprof_capture_reader_peek_type (reader, &type);
|
|
g_assert_cmpint (r, ==, FALSE);
|
|
|
|
g_clear_pointer (&reader, sysprof_capture_reader_unref);
|
|
|
|
reader = sysprof_capture_reader_new ("writer2.syscap");
|
|
g_assert_nonnull (reader);
|
|
|
|
r = sysprof_capture_reader_save_as (reader, "writer3.syscap");
|
|
g_assert_true (r);
|
|
|
|
g_clear_pointer (&reader, sysprof_capture_reader_unref);
|
|
|
|
reader = sysprof_capture_reader_new ("writer3.syscap");
|
|
g_assert_nonnull (reader);
|
|
|
|
count = 0;
|
|
while (sysprof_capture_reader_skip (reader))
|
|
count++;
|
|
g_assert_cmpint (count, ==, 1000);
|
|
|
|
g_clear_pointer (&reader, sysprof_capture_reader_unref);
|
|
|
|
g_unlink ("writer1.syscap");
|
|
g_unlink ("writer2.syscap");
|
|
g_unlink ("writer3.syscap");
|
|
}
|
|
|
|
static void
|
|
test_reader_writer_log (void)
|
|
{
|
|
SysprofCaptureWriter *writer;
|
|
SysprofCaptureReader *reader;
|
|
const SysprofCaptureLog *log;
|
|
SysprofCaptureFrameType type;
|
|
gint r;
|
|
|
|
writer = sysprof_capture_writer_new ("log1.syscap", 0);
|
|
|
|
sysprof_capture_writer_add_log (writer, SYSPROF_CAPTURE_CURRENT_TIME, -1, -1, G_LOG_LEVEL_DEBUG, "my-domain-1", "log message 1");
|
|
sysprof_capture_writer_add_log (writer, SYSPROF_CAPTURE_CURRENT_TIME, -1, -1, G_LOG_LEVEL_DEBUG, "my-domain-2", "log message 2");
|
|
sysprof_capture_writer_add_log (writer, SYSPROF_CAPTURE_CURRENT_TIME, -1, -1, G_LOG_LEVEL_DEBUG, "my-domain-3", "log message 3");
|
|
|
|
g_clear_pointer (&writer, sysprof_capture_writer_unref);
|
|
|
|
reader = sysprof_capture_reader_new ("log1.syscap");
|
|
g_assert_nonnull (reader);
|
|
|
|
log = sysprof_capture_reader_read_log (reader);
|
|
g_assert_nonnull (log);
|
|
g_assert_cmpstr (log->domain, ==, "my-domain-1");
|
|
g_assert_cmpint (log->severity, ==, G_LOG_LEVEL_DEBUG);
|
|
g_assert_cmpstr (log->message, ==, "log message 1");
|
|
g_assert_cmpint (log->frame.time, >, 0);
|
|
g_assert_cmpint (log->frame.cpu, ==, -1);
|
|
|
|
log = sysprof_capture_reader_read_log (reader);
|
|
g_assert_nonnull (log);
|
|
g_assert_cmpstr (log->domain, ==, "my-domain-2");
|
|
g_assert_cmpint (log->severity, ==, G_LOG_LEVEL_DEBUG);
|
|
g_assert_cmpstr (log->message, ==, "log message 2");
|
|
g_assert_cmpint (log->frame.time, >, 0);
|
|
g_assert_cmpint (log->frame.cpu, ==, -1);
|
|
|
|
log = sysprof_capture_reader_read_log (reader);
|
|
g_assert_nonnull (log);
|
|
g_assert_cmpstr (log->domain, ==, "my-domain-3");
|
|
g_assert_cmpint (log->severity, ==, G_LOG_LEVEL_DEBUG);
|
|
g_assert_cmpstr (log->message, ==, "log message 3");
|
|
g_assert_cmpint (log->frame.time, >, 0);
|
|
g_assert_cmpint (log->frame.cpu, ==, -1);
|
|
|
|
r = sysprof_capture_reader_peek_type (reader, &type);
|
|
g_assert_cmpint (r, ==, FALSE);
|
|
|
|
g_clear_pointer (&reader, sysprof_capture_reader_unref);
|
|
|
|
g_unlink ("log1.syscap");
|
|
}
|
|
|
|
static void
|
|
test_reader_writer_mark (void)
|
|
{
|
|
SysprofCaptureWriter *writer;
|
|
SysprofCaptureReader *reader;
|
|
const SysprofCaptureMark *mark;
|
|
SysprofCaptureFrameType type;
|
|
gint r;
|
|
|
|
writer = sysprof_capture_writer_new ("mark1.syscap", 0);
|
|
|
|
sysprof_capture_writer_add_mark (writer, SYSPROF_CAPTURE_CURRENT_TIME, -1, -1, 125, "thread-0", "Draw", "hdmi-1");
|
|
sysprof_capture_writer_add_mark (writer, SYSPROF_CAPTURE_CURRENT_TIME, -1, -1, 0, "thread-1", "Deadline", "hdmi-1");
|
|
|
|
g_clear_pointer (&writer, sysprof_capture_writer_unref);
|
|
|
|
reader = sysprof_capture_reader_new ("mark1.syscap");
|
|
g_assert_nonnull (reader);
|
|
|
|
mark = sysprof_capture_reader_read_mark (reader);
|
|
g_assert_nonnull (mark);
|
|
g_assert_cmpstr (mark->group, ==, "thread-0");
|
|
g_assert_cmpstr (mark->name, ==, "Draw");
|
|
g_assert_cmpint (mark->duration, ==, 125);
|
|
g_assert_cmpstr (mark->message, ==, "hdmi-1");
|
|
g_assert_cmpint (mark->frame.time, >, 0);
|
|
g_assert_cmpint (mark->frame.cpu, ==, -1);
|
|
|
|
mark = sysprof_capture_reader_read_mark (reader);
|
|
g_assert_nonnull (mark);
|
|
g_assert_cmpstr (mark->group, ==, "thread-1");
|
|
g_assert_cmpstr (mark->name, ==, "Deadline");
|
|
g_assert_cmpint (mark->duration, ==, 0);
|
|
g_assert_cmpstr (mark->message, ==, "hdmi-1");
|
|
g_assert_cmpint (mark->frame.time, >, 0);
|
|
g_assert_cmpint (mark->frame.cpu, ==, -1);
|
|
|
|
r = sysprof_capture_reader_peek_type (reader, &type);
|
|
g_assert_cmpint (r, ==, FALSE);
|
|
|
|
g_clear_pointer (&reader, sysprof_capture_reader_unref);
|
|
|
|
g_unlink ("mark1.syscap");
|
|
}
|
|
|
|
static void
|
|
test_reader_writer_metadata (void)
|
|
{
|
|
SysprofCaptureWriter *writer;
|
|
SysprofCaptureReader *reader;
|
|
const SysprofCaptureMetadata *metadata;
|
|
SysprofCaptureFrameType type;
|
|
gint r;
|
|
|
|
writer = sysprof_capture_writer_new ("metadata1.syscap", 0);
|
|
|
|
#define STR1 "[Something]\nhere=1\n"
|
|
#define STR2 "[and]\nthere=2\n"
|
|
|
|
sysprof_capture_writer_add_metadata (writer, SYSPROF_CAPTURE_CURRENT_TIME, -1, -1, "aid.cpu", STR1, -1);
|
|
sysprof_capture_writer_add_metadata (writer, SYSPROF_CAPTURE_CURRENT_TIME, -1, -1, "aid.mem", STR2, strlen (STR2));
|
|
|
|
g_clear_pointer (&writer, sysprof_capture_writer_unref);
|
|
|
|
reader = sysprof_capture_reader_new ("metadata1.syscap");
|
|
g_assert_nonnull (reader);
|
|
|
|
metadata = sysprof_capture_reader_read_metadata (reader);
|
|
g_assert_nonnull (metadata);
|
|
g_assert_cmpstr (metadata->id, ==, "aid.cpu");
|
|
g_assert_cmpstr (metadata->metadata, ==, STR1);
|
|
g_assert_cmpint (metadata->frame.time, >, 0);
|
|
g_assert_cmpint (metadata->frame.cpu, ==, -1);
|
|
|
|
metadata = sysprof_capture_reader_read_metadata (reader);
|
|
g_assert_nonnull (metadata);
|
|
g_assert_cmpstr (metadata->id, ==, "aid.mem");
|
|
g_assert_cmpstr (metadata->metadata, ==, STR2);
|
|
g_assert_cmpint (metadata->frame.time, >, 0);
|
|
g_assert_cmpint (metadata->frame.cpu, ==, -1);
|
|
|
|
r = sysprof_capture_reader_peek_type (reader, &type);
|
|
g_assert_cmpint (r, ==, FALSE);
|
|
|
|
g_clear_pointer (&reader, sysprof_capture_reader_unref);
|
|
|
|
g_unlink ("metadata1.syscap");
|
|
}
|
|
|
|
static void
|
|
test_reader_writer_file (void)
|
|
{
|
|
g_autofree gchar *data = NULL;
|
|
g_autofree gchar *testfile = NULL;
|
|
GByteArray *buf = g_byte_array_new ();
|
|
const char **files;
|
|
SysprofCaptureWriter *writer;
|
|
SysprofCaptureReader *reader;
|
|
SysprofCaptureFrameType type;
|
|
const char *srcdir;
|
|
gsize data_len;
|
|
guint count = 0;
|
|
gint fd;
|
|
gint new_fd;
|
|
gint r;
|
|
|
|
srcdir = g_getenv ("G_TEST_SRCDIR");
|
|
g_assert_nonnull (srcdir);
|
|
|
|
/* We need a file that does not change from read to read */
|
|
testfile = g_build_filename (srcdir, "meson.build", NULL);
|
|
g_assert_nonnull (testfile);
|
|
|
|
writer = sysprof_capture_writer_new ("file1.syscap", 0);
|
|
fd = g_open (testfile, O_RDONLY);
|
|
|
|
r = g_file_get_contents (testfile, &data, &data_len, NULL);
|
|
g_assert_true (r);
|
|
|
|
lseek (fd, 0L, SEEK_SET);
|
|
sysprof_capture_writer_add_file_fd (writer, SYSPROF_CAPTURE_CURRENT_TIME, -1, -1, testfile, fd);
|
|
|
|
lseek (fd, 0L, SEEK_SET);
|
|
sysprof_capture_writer_add_file_fd (writer, SYSPROF_CAPTURE_CURRENT_TIME, -1, -1, testfile, fd);
|
|
|
|
close (fd);
|
|
|
|
sysprof_capture_writer_flush (writer);
|
|
g_clear_pointer (&writer, sysprof_capture_writer_unref);
|
|
|
|
reader = sysprof_capture_reader_new ("file1.syscap");
|
|
g_assert_nonnull (reader);
|
|
|
|
while (count < 2)
|
|
{
|
|
const SysprofCaptureFileChunk *file;
|
|
|
|
r = sysprof_capture_reader_peek_type (reader, &type);
|
|
g_assert_true (r);
|
|
g_assert_cmpint (type, ==, SYSPROF_CAPTURE_FRAME_FILE_CHUNK);
|
|
|
|
file = sysprof_capture_reader_read_file (reader);
|
|
g_assert_nonnull (file);
|
|
g_assert_cmpstr (file->path, ==, testfile);
|
|
|
|
if (count == 0)
|
|
g_byte_array_append (buf, file->data, file->len);
|
|
|
|
count += file->is_last;
|
|
}
|
|
|
|
g_assert_cmpint (data_len, ==, buf->len);
|
|
g_assert_cmpint (0, ==, memcmp (data, buf->data, data_len));
|
|
|
|
r = sysprof_capture_reader_peek_type (reader, &type);
|
|
g_assert_cmpint (r, ==, FALSE);
|
|
|
|
sysprof_capture_reader_reset (reader);
|
|
files = sysprof_capture_reader_list_files (reader);
|
|
g_assert_nonnull (files);
|
|
g_assert_cmpstr (files[0], ==, testfile);
|
|
g_assert_null (files[1]);
|
|
free (files);
|
|
|
|
sysprof_capture_reader_reset (reader);
|
|
new_fd = sysprof_memfd_create ("[sysprof-capture-file]");
|
|
g_assert_cmpint (new_fd, !=, -1);
|
|
|
|
r = sysprof_capture_reader_read_file_fd (reader, testfile, new_fd);
|
|
g_assert_true (r);
|
|
|
|
close (new_fd);
|
|
|
|
g_clear_pointer (&reader, sysprof_capture_reader_unref);
|
|
g_clear_pointer (&buf, g_byte_array_unref);
|
|
|
|
g_unlink ("file1.syscap");
|
|
}
|
|
|
|
static void
|
|
test_reader_writer_cat_jitmap (void)
|
|
{
|
|
SysprofCaptureWriter *writer1;
|
|
SysprofCaptureWriter *writer2;
|
|
SysprofCaptureWriter *res;
|
|
SysprofCaptureReader *reader;
|
|
const SysprofCaptureSample *sample;
|
|
SysprofCaptureAddress addrs[20];
|
|
gboolean r;
|
|
|
|
writer1 = sysprof_capture_writer_new ("jitmap1.syscap", 0);
|
|
writer2 = sysprof_capture_writer_new ("jitmap2.syscap", 0);
|
|
res = sysprof_capture_writer_new ("jitmap-joined.syscap", 0);
|
|
|
|
for (guint i = 0; i < G_N_ELEMENTS (addrs); i++)
|
|
{
|
|
g_autofree gchar *str = g_strdup_printf ("jitmap_%d (writer1)", i);
|
|
addrs[i] = sysprof_capture_writer_add_jitmap (writer1, str);
|
|
}
|
|
|
|
sysprof_capture_writer_add_sample (writer1,
|
|
SYSPROF_CAPTURE_CURRENT_TIME,
|
|
-1,
|
|
getpid (),
|
|
-1,
|
|
addrs,
|
|
G_N_ELEMENTS (addrs));
|
|
|
|
for (guint i = 0; i < G_N_ELEMENTS (addrs); i++)
|
|
{
|
|
g_autofree gchar *str = g_strdup_printf ("jitmap_%d (writer2)", i);
|
|
addrs[i] = sysprof_capture_writer_add_jitmap (writer2, str);
|
|
}
|
|
|
|
sysprof_capture_writer_add_sample (writer2,
|
|
SYSPROF_CAPTURE_CURRENT_TIME,
|
|
-1,
|
|
getpid (),
|
|
-1,
|
|
addrs,
|
|
G_N_ELEMENTS (addrs));
|
|
|
|
reader = sysprof_capture_writer_create_reader (writer1);
|
|
g_assert_nonnull (reader);
|
|
r = sysprof_capture_writer_cat (res, reader);
|
|
g_assert_true (r);
|
|
sysprof_capture_writer_unref (writer1);
|
|
sysprof_capture_reader_unref (reader);
|
|
|
|
reader = sysprof_capture_writer_create_reader (writer2);
|
|
g_assert_nonnull (reader);
|
|
r = sysprof_capture_writer_cat (res, reader);
|
|
g_assert_true (r);
|
|
sysprof_capture_writer_unref (writer2);
|
|
sysprof_capture_reader_unref (reader);
|
|
|
|
reader = sysprof_capture_writer_create_reader (res);
|
|
g_assert_nonnull (reader);
|
|
sysprof_capture_reader_read_jitmap (reader);
|
|
sample = sysprof_capture_reader_read_sample (reader);
|
|
g_assert_cmpint (sample->frame.pid, ==, getpid ());
|
|
g_assert_cmpint (sample->n_addrs, ==, G_N_ELEMENTS (addrs));
|
|
g_assert_cmpint (sample->addrs[0], !=, sample->addrs[1]);
|
|
sysprof_capture_reader_unref (reader);
|
|
|
|
sysprof_capture_writer_unref (res);
|
|
|
|
g_unlink ("jitmap1.syscap");
|
|
g_unlink ("jitmap2.syscap");
|
|
g_unlink ("jitmap-joined.syscap");
|
|
}
|
|
|
|
static void
|
|
test_writer_memory_alloc_free (void)
|
|
{
|
|
SysprofCaptureWriter *writer;
|
|
SysprofCaptureReader *reader;
|
|
SysprofCaptureAddress addrs[20] = {
|
|
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
|
|
11, 12, 13, 14, 15, 16, 17, 18, 19,
|
|
};
|
|
gboolean r;
|
|
|
|
writer = sysprof_capture_writer_new ("memory.syscap", 0);
|
|
|
|
for (guint i = 0; i < 20; i++)
|
|
{
|
|
r = sysprof_capture_writer_add_allocation_copy (writer,
|
|
SYSPROF_CAPTURE_CURRENT_TIME,
|
|
i % 4,
|
|
i % 3,
|
|
i % 7,
|
|
i,
|
|
i * 2,
|
|
addrs,
|
|
i);
|
|
g_assert_true (r);
|
|
}
|
|
|
|
sysprof_capture_writer_flush (writer);
|
|
|
|
reader = sysprof_capture_writer_create_reader (writer);
|
|
g_assert_nonnull (reader);
|
|
|
|
for (guint i = 0; i < 20; i++)
|
|
{
|
|
const SysprofCaptureAllocation *ev;
|
|
|
|
ev = sysprof_capture_reader_read_allocation (reader);
|
|
g_assert_nonnull (ev);
|
|
g_assert_cmpint (ev->frame.type, ==, SYSPROF_CAPTURE_FRAME_ALLOCATION);
|
|
|
|
g_assert_cmpint (ev->frame.cpu, ==, i % 4);
|
|
g_assert_cmpint (ev->frame.pid, ==, i % 3);
|
|
g_assert_cmpint (ev->tid, ==, i % 7);
|
|
g_assert_cmpint (ev->alloc_addr, ==, i);
|
|
g_assert_cmpint (ev->alloc_size, ==, i * 2);
|
|
g_assert_cmpint (ev->n_addrs, ==, i);
|
|
|
|
for (guint j = 0; j < i; j++)
|
|
{
|
|
g_assert_cmpint (ev->addrs[j], ==, j);
|
|
}
|
|
}
|
|
|
|
sysprof_capture_writer_unref (writer);
|
|
sysprof_capture_reader_unref (reader);
|
|
|
|
g_unlink ("memory.syscap");
|
|
}
|
|
|
|
static void
|
|
test_reader_writer_overlay (void)
|
|
{
|
|
SysprofCaptureWriter *writer;
|
|
SysprofCaptureReader *reader;
|
|
const SysprofCaptureOverlay *ev;
|
|
SysprofCaptureFrameType type;
|
|
gint r;
|
|
|
|
writer = sysprof_capture_writer_new ("overlay1.syscap", 0);
|
|
|
|
sysprof_capture_writer_add_overlay (writer, SYSPROF_CAPTURE_CURRENT_TIME, -1, -1, 123, "/foo", "/bar");
|
|
sysprof_capture_writer_add_overlay (writer, SYSPROF_CAPTURE_CURRENT_TIME, -1, -1, 0, "/app", "/bin");
|
|
sysprof_capture_writer_add_overlay (writer, SYSPROF_CAPTURE_CURRENT_TIME, -1, -1, 7, "/home/user/.local/share/containers/storage/overlay/1111111111111111111111111111111111111111111111111111111111111111/diff", "/");
|
|
|
|
g_clear_pointer (&writer, sysprof_capture_writer_unref);
|
|
|
|
reader = sysprof_capture_reader_new ("overlay1.syscap");
|
|
g_assert_nonnull (reader);
|
|
|
|
ev = sysprof_capture_reader_read_overlay (reader);
|
|
g_assert_nonnull (ev);
|
|
g_assert_cmpint (ev->layer, ==, 123);
|
|
g_assert_cmpint (ev->src_len, ==, 4);
|
|
g_assert_cmpint (ev->dst_len, ==, 4);
|
|
g_assert_cmpstr (ev->data, ==, "/foo");
|
|
g_assert_cmpstr (ev->data+ev->src_len+1, ==, "/bar");
|
|
|
|
ev = sysprof_capture_reader_read_overlay (reader);
|
|
g_assert_nonnull (ev);
|
|
g_assert_cmpint (ev->layer, ==, 0);
|
|
g_assert_cmpint (ev->src_len, ==, 4);
|
|
g_assert_cmpint (ev->dst_len, ==, 4);
|
|
g_assert_cmpstr (ev->data, ==, "/app");
|
|
g_assert_cmpstr (ev->data+ev->src_len+1, ==, "/bin");
|
|
|
|
ev = sysprof_capture_reader_read_overlay (reader);
|
|
g_assert_nonnull (ev);
|
|
g_assert_cmpint (ev->layer, ==, 7);
|
|
g_assert_cmpint (ev->src_len, ==, 120);
|
|
g_assert_cmpint (ev->dst_len, ==, 1);
|
|
g_assert_cmpstr (ev->data, ==, "/home/user/.local/share/containers/storage/overlay/1111111111111111111111111111111111111111111111111111111111111111/diff");
|
|
g_assert_cmpstr (ev->data+ev->src_len+1, ==, "/");
|
|
|
|
r = sysprof_capture_reader_peek_type (reader, &type);
|
|
g_assert_cmpint (r, ==, FALSE);
|
|
|
|
g_clear_pointer (&reader, sysprof_capture_reader_unref);
|
|
|
|
g_unlink ("overlay1.syscap");
|
|
}
|
|
|
|
int
|
|
main (int argc,
|
|
char *argv[])
|
|
{
|
|
sysprof_clock_init ();
|
|
g_test_init (&argc, &argv, NULL);
|
|
g_test_add_func ("/SysprofCapture/ReaderWriter", test_reader_basic);
|
|
g_test_add_func ("/SysprofCapture/ReaderWriter/alloc_free", test_writer_memory_alloc_free);
|
|
g_test_add_func ("/SysprofCapture/Writer/splice", test_writer_splice);
|
|
g_test_add_func ("/SysprofCapture/Reader/splice", test_reader_splice);
|
|
g_test_add_func ("/SysprofCapture/ReaderWriter/log", test_reader_writer_log);
|
|
g_test_add_func ("/SysprofCapture/ReaderWriter/mark", test_reader_writer_mark);
|
|
g_test_add_func ("/SysprofCapture/ReaderWriter/metadata", test_reader_writer_metadata);
|
|
g_test_add_func ("/SysprofCapture/ReaderWriter/file", test_reader_writer_file);
|
|
g_test_add_func ("/SysprofCapture/ReaderWriter/cat-jitmap", test_reader_writer_cat_jitmap);
|
|
g_test_add_func ("/SysprofCapture/ReaderWriter/overlay", test_reader_writer_overlay);
|
|
return g_test_run ();
|
|
}
|