tree: start on massive tree refactor

The big thing going on here is that we are going to split up the libraries
a bit better, and remove GObject from the capture library. The libsysprof
library will bring in the capture library statically, so we can export the
symbols we want.

Eventually, we will bump the version to sysprof-3, but not yet.
This commit is contained in:
Christian Hergert
2019-05-07 20:52:05 -07:00
parent 5323cffdb3
commit 1708ad1b48
193 changed files with 1400 additions and 1136 deletions

52
src/tests/meson.build Normal file
View File

@ -0,0 +1,52 @@
test_env = [
'G_TEST_SRCDIR="@0@"'.format(meson.current_source_dir()),
'G_TEST_BUILDDIR="@0@"'.format(meson.current_build_dir()),
'G_DEBUG=gc-friendly',
'GSETTINGS_BACKEND=memory',
'MALLOC_CHECK_=2',
]
test_cflags = [
'-DTEST_DATA_DIR="@0@/data/"'.format(meson.current_source_dir()),
]
test_capture = executable('test-capture', 'test-capture.c',
c_args: test_cflags,
dependencies: libsysprof_capture_dep,
)
test_capture_cursor = executable('test-capture-cursor', 'test-capture-cursor.c',
c_args: test_cflags,
dependencies: libsysprof_capture_dep,
)
test('test-capture', test_capture, env: test_env)
test('test-capture-cursor', test_capture_cursor, env: test_env)
# Use ./tests/test-kallsyms /proc/kallsyms to test (as user or root)
test_kallsyms = executable('test-kallsyms', 'test-kallsyms.c',
c_args: test_cflags,
dependencies: libsysprof_dep,
)
if get_option('enable_gtk')
test_model_filter = executable('test-model-filter', 'test-model-filter.c',
c_args: test_cflags,
dependencies: libsysprof_ui_dep,
)
test_process_model = executable('test-process-model', 'test-process-model.c',
c_args: test_cflags,
dependencies: libsysprof_ui_dep,
)
test_zoom = executable('test-zoom', 'test-zoom.c',
c_args: test_cflags,
dependencies: libsysprof_ui_dep,
)
test('test-model-filter', test_model_filter, env: test_env)
test('test-zoom', test_zoom, env: test_env)
endif

View File

@ -0,0 +1,81 @@
/* test-capture-cursor.c
*
* Copyright 2016o-2019 Christian Hergert <chergert@redhat.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program 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 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/>.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
#include <glib/gstdio.h>
#include <sysprof-capture.h>
static gboolean
increment (const SpCaptureFrame *frame,
gpointer user_data)
{
gint *count= user_data;
(*count)++;
return TRUE;
}
static void
test_cursor_basic (void)
{
SpCaptureReader *reader;
SpCaptureWriter *writer;
SpCaptureCursor *cursor;
GError *error = NULL;
gint64 t = SP_CAPTURE_CURRENT_TIME;
guint i;
gint r;
gint count = 0;
writer = sp_capture_writer_new ("capture-cursor-file", 0);
g_assert (writer != NULL);
sp_capture_writer_flush (writer);
reader = sp_capture_reader_new ("capture-cursor-file", &error);
g_assert_no_error (error);
g_assert (reader != NULL);
for (i = 0; i < 100; i++)
{
r = sp_capture_writer_add_timestamp (writer, t, i, -1);
g_assert_cmpint (r, ==, TRUE);
}
sp_capture_writer_flush (writer);
cursor = sp_capture_cursor_new (reader);
sp_capture_cursor_foreach (cursor, increment, &count);
g_assert_cmpint (count, ==, 100);
g_clear_pointer (&cursor, sp_capture_cursor_unref);
sp_capture_reader_unref (reader);
sp_capture_writer_unref (writer);
g_unlink ("capture-cursor-file");
}
int
main (int argc,
char *argv[])
{
sp_clock_init ();
g_test_init (&argc, &argv, NULL);
g_test_add_func ("/SpCaptureCursor/basic", test_cursor_basic);
return g_test_run ();
}

619
src/tests/test-capture.c Normal file
View File

@ -0,0 +1,619 @@
/* 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 <glib/gstdio.h>
#include <sysprof-capture.h>
static void
test_reader_basic (void)
{
SpCaptureReader *reader;
SpCaptureWriter *writer;
GError *error = NULL;
gint64 t = SP_CAPTURE_CURRENT_TIME;
guint i;
gint r;
writer = sp_capture_writer_new ("capture-file", 0);
g_assert (writer != NULL);
sp_capture_writer_flush (writer);
reader = sp_capture_reader_new ("capture-file", &error);
g_assert_no_error (error);
g_assert (reader != NULL);
for (i = 0; i < 100; i++)
{
gchar str[16];
g_snprintf (str, sizeof str, "%d", i);
r = sp_capture_writer_add_map (writer, t, -1, -1, i, i + 1, i + 2, i + 3, str);
g_assert_cmpint (r, ==, TRUE);
}
sp_capture_writer_flush (writer);
for (i = 0; i < 100; i++)
{
SpCaptureFrameType type = -1;
const SpCaptureMap *map;
gchar str[16];
g_snprintf (str, sizeof str, "%d", i);
if (!sp_capture_reader_peek_type (reader, &type))
g_assert_not_reached ();
g_assert_cmpint (type, ==, SP_CAPTURE_FRAME_MAP);
map = sp_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, !=, sp_capture_reader_get_end_time (reader));
for (i = 0; i < 100; i++)
{
r = sp_capture_writer_add_timestamp (writer, t, i, -1);
g_assert_cmpint (r, ==, TRUE);
}
sp_capture_writer_flush (writer);
for (i = 0; i < 100; i++)
{
SpCaptureFrameType type = -1;
const SpCaptureTimestamp *ts;
if (!sp_capture_reader_peek_type (reader, &type))
g_assert_not_reached ();
g_assert_cmpint (type, ==, SP_CAPTURE_FRAME_TIMESTAMP);
ts = sp_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 = sp_capture_writer_add_exit (writer, t, i, -1);
g_assert_cmpint (r, ==, TRUE);
}
sp_capture_writer_flush (writer);
for (i = 0; i < 100; i++)
{
SpCaptureFrameType type = -1;
const SpCaptureExit *ex;
if (!sp_capture_reader_peek_type (reader, &type))
g_assert_not_reached ();
g_assert_cmpint (type, ==, SP_CAPTURE_FRAME_EXIT);
ex = sp_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 = sp_capture_writer_add_process (writer, t, -1, i, cmdline);
g_assert_cmpint (r, ==, TRUE);
}
sp_capture_writer_flush (writer);
for (i = 0; i < 100; i++)
{
SpCaptureFrameType type = -1;
const SpCaptureProcess *pr;
char str[32];
g_snprintf (str, sizeof str, "program-%d", i);
if (!sp_capture_reader_peek_type (reader, &type))
g_assert_not_reached ();
g_assert_cmpint (type, ==, SP_CAPTURE_FRAME_PROCESS);
pr = sp_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 = sp_capture_writer_add_fork (writer, t, i, -1, i);
g_assert_cmpint (r, ==, TRUE);
}
sp_capture_writer_flush (writer);
for (i = 0; i < 100; i++)
{
SpCaptureFrameType type = -1;
const SpCaptureFork *ex;
if (!sp_capture_reader_peek_type (reader, &type))
g_assert_not_reached ();
g_assert_cmpint (type, ==, SP_CAPTURE_FRAME_FORK);
ex = sp_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);
}
{
SpCaptureCounter counters[10];
guint base = sp_capture_writer_request_counter (writer, G_N_ELEMENTS (counters));
t = SP_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 = sp_capture_writer_define_counters (writer, t, -1, -1, counters, G_N_ELEMENTS (counters));
g_assert_cmpint (r, ==, TRUE);
}
sp_capture_writer_flush (writer);
{
const SpCaptureFrameCounterDefine *def;
def = sp_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 };
SpCaptureCounterValue values[10] = { {1}, {2}, {3}, {4}, {5}, {6}, {7}, {8}, {9}, {10} };
r = sp_capture_writer_set_counters (writer, t, -1, -1, ids, values, G_N_ELEMENTS (values));
g_assert_cmpint (r, ==, TRUE);
}
sp_capture_writer_flush (writer);
for (i = 0; i < 1000; i++)
{
const SpCaptureFrameCounterSet *set;
set = sp_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++)
{
SpCaptureAddress addr;
gchar str[32];
g_snprintf (str, sizeof str, "jitstring-%d", i);
addr = sp_capture_writer_add_jitmap (writer, str);
g_assert_cmpint (addr, ==, (i + 1) | SP_CAPTURE_JITMAP_MARK);
}
sp_capture_writer_flush (writer);
i = 0;
for (;;)
{
SpCaptureFrameType type = -1;
g_autoptr(GHashTable) ret = NULL;
if (sp_capture_reader_peek_type (reader, &type))
g_assert_cmpint (type, ==, SP_CAPTURE_FRAME_JITMAP);
else
break;
ret = sp_capture_reader_read_jitmap (reader);
g_assert (ret != NULL);
i += g_hash_table_size (ret);
}
g_assert_cmpint (1000, ==, i);
{
SpCaptureFrameType type = -1;
if (sp_capture_reader_peek_type (reader, &type))
g_assert_not_reached ();
}
for (i = 1; i <= 1000; i++)
{
SpCaptureAddress *addrs;
guint j;
addrs = alloca (i * sizeof *addrs);
for (j = 0; j < i; j++)
addrs[j] = i;
if (!sp_capture_writer_add_sample (writer, t, -1, -1, addrs, i))
g_assert_not_reached ();
}
sp_capture_writer_flush (writer);
for (i = 1; i <= 1000; i++)
{
SpCaptureFrameType type = -1;
const SpCaptureSample *sample;
guint j;
if (!sp_capture_reader_peek_type (reader, &type))
g_assert_not_reached ();
g_assert_cmpint (type, ==, SP_CAPTURE_FRAME_SAMPLE);
sample = sp_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->n_addrs, ==, i);
for (j = 0; j < i; j++)
g_assert_cmpint (sample->addrs[j], ==, i);
}
{
SpCaptureFrameType type = -1;
if (sp_capture_reader_peek_type (reader, &type))
g_assert_not_reached ();
}
r = sp_capture_writer_save_as (writer, "capture-file.bak", &error);
g_assert_no_error (error);
g_assert (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, sp_capture_writer_unref);
g_clear_pointer (&reader, sp_capture_reader_unref);
reader = sp_capture_reader_new ("capture-file.bak", &error);
g_assert_no_error (error);
g_assert (reader != NULL);
for (i = 0; i < 2; i++)
{
SpCaptureFrameType type = -1;
guint count = 0;
while (sp_capture_reader_peek_type (reader, &type))
{
count++;
if (!sp_capture_reader_skip (reader))
g_assert_not_reached ();
}
g_assert_cmpint (count, >, 1500);
sp_capture_reader_reset (reader);
}
sp_capture_reader_unref (reader);
g_unlink ("capture-file");
g_unlink ("capture-file.bak");
}
static void
test_writer_splice (void)
{
SpCaptureWriter *writer1;
SpCaptureWriter *writer2;
SpCaptureReader *reader;
SpCaptureFrameType type;
GError *error = NULL;
guint i;
gint r;
writer1 = sp_capture_writer_new ("writer1.syscap", 0);
writer2 = sp_capture_writer_new ("writer2.syscap", 0);
for (i = 0; i < 1000; i++)
sp_capture_writer_add_timestamp (writer1, SP_CAPTURE_CURRENT_TIME, -1, -1);
r = sp_capture_writer_splice (writer1, writer2, &error);
g_assert_no_error (error);
g_assert (r == TRUE);
g_clear_pointer (&writer1, sp_capture_writer_unref);
g_clear_pointer (&writer2, sp_capture_writer_unref);
reader = sp_capture_reader_new ("writer2.syscap", &error);
g_assert_no_error (error);
g_assert (reader != NULL);
for (i = 0; i < 1000; i++)
{
const SpCaptureTimestamp *ts = sp_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 = sp_capture_reader_peek_type (reader, &type);
g_assert_cmpint (r, ==, FALSE);
g_clear_pointer (&reader, sp_capture_reader_unref);
g_unlink ("writer1.syscap");
g_unlink ("writer2.syscap");
}
static void
test_reader_splice (void)
{
SpCaptureWriter *writer1;
SpCaptureWriter *writer2;
SpCaptureReader *reader;
SpCaptureFrameType type;
GError *error = NULL;
guint i;
guint count;
gint r;
writer1 = sp_capture_writer_new ("writer1.syscap", 0);
writer2 = sp_capture_writer_new ("writer2.syscap", 0);
for (i = 0; i < 1000; i++)
sp_capture_writer_add_timestamp (writer1, SP_CAPTURE_CURRENT_TIME, -1, -1);
r = sp_capture_writer_flush (writer1);
g_assert_cmpint (r, ==, TRUE);
g_clear_pointer (&writer1, sp_capture_writer_unref);
reader = sp_capture_reader_new ("writer1.syscap", &error);
g_assert_no_error (error);
g_assert (reader != NULL);
/* advance to the end of the reader to non-start boundary for fd */
for (i = 0; i < 1000; i++)
{
const SpCaptureTimestamp *ts = sp_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 = sp_capture_reader_peek_type (reader, &type);
g_assert_cmpint (r, ==, FALSE);
r = sp_capture_reader_splice (reader, writer2, &error);
g_assert_no_error (error);
g_assert_cmpint (r, ==, TRUE);
g_clear_pointer (&reader, sp_capture_reader_unref);
g_clear_pointer (&writer2, sp_capture_writer_unref);
reader = sp_capture_reader_new ("writer2.syscap", 0);
for (i = 0; i < 1000; i++)
{
const SpCaptureTimestamp *ts = sp_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 = sp_capture_reader_peek_type (reader, &type);
g_assert_cmpint (r, ==, FALSE);
g_clear_pointer (&reader, sp_capture_reader_unref);
reader = sp_capture_reader_new ("writer2.syscap", &error);
g_assert_no_error (error);
g_assert (reader != NULL);
r = sp_capture_reader_save_as (reader, "writer3.syscap", &error);
g_assert_no_error (error);
g_assert_cmpint (r, ==, TRUE);
g_clear_pointer (&reader, sp_capture_reader_unref);
reader = sp_capture_reader_new ("writer3.syscap", &error);
g_assert_no_error (error);
g_assert (reader != NULL);
count = 0;
while (sp_capture_reader_skip (reader))
count++;
g_assert_cmpint (count, ==, 1000);
g_clear_pointer (&reader, sp_capture_reader_unref);
g_unlink ("writer1.syscap");
g_unlink ("writer2.syscap");
g_unlink ("writer3.syscap");
}
static void
test_reader_writer_mark (void)
{
SpCaptureWriter *writer;
SpCaptureReader *reader;
const SpCaptureMark *mark;
SpCaptureFrameType type;
GError *error = NULL;
gint r;
writer = sp_capture_writer_new ("mark1.syscap", 0);
sp_capture_writer_add_mark (writer, SP_CAPTURE_CURRENT_TIME, -1, -1, 125, "thread-0", "Draw", "hdmi-1");
sp_capture_writer_add_mark (writer, SP_CAPTURE_CURRENT_TIME, -1, -1, 0, "thread-1", "Deadline", "hdmi-1");
g_clear_pointer (&writer, sp_capture_writer_unref);
reader = sp_capture_reader_new ("mark1.syscap", &error);
g_assert_no_error (error);
g_assert (reader != NULL);
mark = sp_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 = sp_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 = sp_capture_reader_peek_type (reader, &type);
g_assert_cmpint (r, ==, FALSE);
g_clear_pointer (&reader, sp_capture_reader_unref);
g_unlink ("mark1.syscap");
}
int
main (int argc,
char *argv[])
{
sp_clock_init ();
g_test_init (&argc, &argv, NULL);
g_test_add_func ("/SpCapture/ReaderWriter", test_reader_basic);
g_test_add_func ("/SpCapture/Writer/splice", test_writer_splice);
g_test_add_func ("/SpCapture/Reader/splice", test_reader_splice);
g_test_add_func ("/SpCapture/ReaderWriter/mark", test_reader_writer_mark);
return g_test_run ();
}

34
src/tests/test-kallsyms.c Normal file
View File

@ -0,0 +1,34 @@
#include "../shared/sp-address.h"
#include "../shared/sp-kallsyms.h"
#include <glib.h>
#include <stdlib.h>
int
main (gint argc,
gchar *argv[])
{
g_autoptr(SpKallsyms) kallsyms = NULL;
const gchar *name;
SpAddress addr = 0;
guint8 type;
if (argc < 2)
{
g_printerr ("usage: %s FILE\n", argv[0]);
return EXIT_FAILURE;
}
kallsyms = sp_kallsyms_new (argv[1]);
while (sp_kallsyms_next (kallsyms, &name, &addr, &type))
{
g_assert (name != NULL);
g_assert (addr != 0);
g_assert (type != 0);
g_print ("%s %"G_GUINT64_FORMAT"x\n", name, addr);
}
return EXIT_SUCCESS;
}

View File

@ -0,0 +1,247 @@
#include <sysprof-ui.h>
#include <string.h>
#define TEST_TYPE_ITEM (test_item_get_type())
struct _TestItem
{
GObject p;
guint n;
};
G_DECLARE_FINAL_TYPE (TestItem, test_item, TEST, ITEM, GObject)
G_DEFINE_TYPE (TestItem, test_item, G_TYPE_OBJECT)
static void
test_item_class_init (TestItemClass *klass)
{
}
static void
test_item_init (TestItem *self)
{
}
static TestItem *
test_item_new (guint n)
{
TestItem *item;
item = g_object_new (TEST_TYPE_ITEM, NULL);
item->n = n;
return item;
}
static gboolean
filter_func1 (GObject *object,
gpointer user_data)
{
return (TEST_ITEM (object)->n & 1) == 0;
}
static gboolean
filter_func2 (GObject *object,
gpointer user_data)
{
return (TEST_ITEM (object)->n & 1) == 1;
}
static void
test_basic (void)
{
GListStore *model;
SpModelFilter *filter;
TestItem *item;
guint i;
model = g_list_store_new (TEST_TYPE_ITEM);
g_assert (model);
filter = sp_model_filter_new (G_LIST_MODEL (model));
g_assert (filter);
for (i = 0; i < 1000; i++)
{
g_autoptr(TestItem) val = test_item_new (i);
g_list_store_append (model, val);
}
g_assert_cmpint (1000, ==, g_list_model_get_n_items (G_LIST_MODEL (model)));
g_assert_cmpint (1000, ==, g_list_model_get_n_items (G_LIST_MODEL (filter)));
g_assert_cmpint (1000, ==, g_list_model_get_n_items (G_LIST_MODEL (filter)));
sp_model_filter_set_filter_func (filter, filter_func1, NULL, NULL);
g_assert_cmpint (500, ==, g_list_model_get_n_items (G_LIST_MODEL (filter)));
for (i = 0; i < 500; i++)
{
g_autoptr(TestItem) ele = g_list_model_get_item (G_LIST_MODEL (filter), i);
g_assert (TEST_IS_ITEM (ele));
g_assert (filter_func1 (G_OBJECT (ele), NULL));
}
for (i = 0; i < 1000; i += 2)
g_list_store_remove (model, 998 - i);
g_assert_cmpint (500, ==, g_list_model_get_n_items (G_LIST_MODEL (model)));
g_assert_cmpint (0, ==, g_list_model_get_n_items (G_LIST_MODEL (filter)));
sp_model_filter_set_filter_func (filter, NULL, NULL, NULL);
g_assert_cmpint (500, ==, g_list_model_get_n_items (G_LIST_MODEL (filter)));
sp_model_filter_set_filter_func (filter, filter_func2, NULL, NULL);
g_assert_cmpint (500, ==, g_list_model_get_n_items (G_LIST_MODEL (filter)));
{
g_autoptr(TestItem) freeme = test_item_new (1001);
g_list_store_append (model, freeme);
}
for (i = 0; i < 500; i++)
g_list_store_remove (model, 0);
g_assert_cmpint (1, ==, g_list_model_get_n_items (G_LIST_MODEL (model)));
g_assert_cmpint (1, ==, g_list_model_get_n_items (G_LIST_MODEL (filter)));
sp_model_filter_set_filter_func (filter, NULL, NULL, NULL);
g_assert_cmpint (1, ==, g_list_model_get_n_items (G_LIST_MODEL (model)));
g_assert_cmpint (1, ==, g_list_model_get_n_items (G_LIST_MODEL (filter)));
item = g_list_model_get_item (G_LIST_MODEL (filter), 0);
g_assert (item);
g_assert (TEST_IS_ITEM (item));
g_assert_cmpint (item->n, ==, 1001);
g_clear_object (&item);
g_clear_object (&model);
g_clear_object (&filter);
}
static gboolean
filter_keyword_cb (GObject *object,
gpointer user_data)
{
SpProcessModelItem *item = SP_PROCESS_MODEL_ITEM (object);
const gchar *haystack = sp_process_model_item_get_command_line (item);
const gchar *needle = user_data;
return strstr (haystack, needle) != NULL;
}
static void
test_process (void)
{
SpProcessModel *model = sp_process_model_new ();
SpModelFilter *filter;
static gchar *searches[] = {
"a", "b", "foo", "bar", "gnome", "gnome-test",
"libexec", "/", ":", "gsd-",
};
filter = sp_model_filter_new (G_LIST_MODEL (model));
sp_process_model_reload (model);
for (guint i = 0; i < G_N_ELEMENTS (searches); i++)
{
const gchar *needle = searches[i];
guint n_items;
sp_model_filter_set_filter_func (filter, filter_keyword_cb, g_strdup (needle), g_free);
n_items = g_list_model_get_n_items (G_LIST_MODEL (filter));
for (guint j = 0; j < n_items; j++)
{
g_autoptr(SpProcessModelItem) item = g_list_model_get_item (G_LIST_MODEL (filter), j);
g_assert (SP_IS_PROCESS_MODEL_ITEM (item));
g_assert (filter_keyword_cb (G_OBJECT (item), (gchar *)needle));
//g_print ("%s: %s\n", needle, sp_process_model_item_get_command_line (item));
}
}
g_object_unref (filter);
g_object_unref (model);
}
static guint last_n_added = 0;
static guint last_n_removed = 0;
static guint last_changed_position = 0;
static void
model_items_changed_cb (SpModelFilter *filter,
guint position,
guint n_removed,
guint n_added,
GListModel *model)
{
last_n_added = n_added;
last_n_removed = n_removed;
last_changed_position = position;
}
static void
filter_items_changed_cb (SpModelFilter *filter,
guint position,
guint n_removed,
guint n_added,
GListModel *model)
{
g_assert_cmpint (n_added, ==, last_n_added);
g_assert_cmpint (n_removed, ==, last_n_removed);
g_assert_cmpint (position, ==, last_changed_position);
}
static void
test_items_changed (void)
{
SpModelFilter *filter;
GListStore *model;
guint i;
model = g_list_store_new (TEST_TYPE_ITEM);
g_assert (model);
g_signal_connect (model, "items-changed", G_CALLBACK (model_items_changed_cb), NULL);
filter = sp_model_filter_new (G_LIST_MODEL (model));
g_assert (filter);
g_signal_connect_after (filter, "items-changed", G_CALLBACK (filter_items_changed_cb), model);
/* The filter model is not filtered, so it must mirror whatever
* the child model does. In this case, test if the position of
* items-changed match.
*/
for (i = 0; i < 100; i++)
{
g_autoptr (TestItem) val = test_item_new (i);
g_list_store_append (model, val);
}
g_assert_cmpint (100, ==, g_list_model_get_n_items (G_LIST_MODEL (model)));
g_assert_cmpint (100, ==, g_list_model_get_n_items (G_LIST_MODEL (filter)));
for (i = 0; i < 100; i++)
g_list_store_remove (model, 0);
g_clear_object (&model);
g_clear_object (&filter);
}
gint
main (gint argc,
gchar *argv[])
{
g_test_init (&argc, &argv, NULL);
g_test_add_func ("/SpModelFilter/basic", test_basic);
g_test_add_func ("/SpModelFilter/process", test_process);
g_test_add_func ("/SpModelFilter/items-changed", test_items_changed);
return g_test_run ();
}

View File

@ -0,0 +1,96 @@
#include <sysprof.h>
#include <sysprof-ui.h>
#include <string.h>
static GtkWidget *list;
static GtkWidget *
create_row (gpointer item,
gpointer user_data)
{
return sp_process_model_row_new (item);
}
static gboolean
filter_cb (GObject *object,
gpointer user_data)
{
const gchar *needle = user_data;
const gchar *command = sp_process_model_item_get_command_line (SP_PROCESS_MODEL_ITEM (object));
return !!strstr (command, needle);
}
static void
on_entry_changed (GtkEntry *entry,
SpModelFilter *filter)
{
const gchar *text;
g_assert (GTK_IS_ENTRY (entry));
g_assert (SP_IS_MODEL_FILTER (filter));
text = gtk_entry_get_text (entry);
sp_model_filter_set_filter_func (filter, filter_cb, g_strdup (text), g_free);
//gtk_list_box_bind_model (GTK_LIST_BOX (list), G_LIST_MODEL (filter), create_row, NULL, NULL);
}
gint
main (gint argc,
gchar *argv[])
{
SpProcessModel *model;
SpModelFilter *filter;
GtkWidget *window;
GtkWidget *box;
GtkWidget *scroller;
GtkWidget *entry;
gtk_init (&argc, &argv);
window = g_object_new (GTK_TYPE_WINDOW,
"title", "Sysprof Process List",
"default-height", 700,
"default-width", 300,
NULL);
box = g_object_new (GTK_TYPE_BOX,
"orientation", GTK_ORIENTATION_VERTICAL,
"visible", TRUE,
NULL);
gtk_container_add (GTK_CONTAINER (window), box);
entry = g_object_new (GTK_TYPE_ENTRY,
"visible", TRUE,
NULL);
gtk_container_add (GTK_CONTAINER (box), entry);
scroller = g_object_new (GTK_TYPE_SCROLLED_WINDOW,
"visible", TRUE,
"expand", TRUE,
NULL);
gtk_container_add (GTK_CONTAINER (box), scroller);
list = g_object_new (GTK_TYPE_LIST_BOX,
"visible", TRUE,
NULL);
gtk_container_add (GTK_CONTAINER (scroller), list);
model = sp_process_model_new ();
filter = sp_model_filter_new (G_LIST_MODEL (model));
gtk_list_box_bind_model (GTK_LIST_BOX (list), G_LIST_MODEL (filter), create_row, NULL, NULL);
g_signal_connect (entry,
"changed",
G_CALLBACK (on_entry_changed),
filter);
gtk_window_present (GTK_WINDOW (window));
g_signal_connect (window, "delete-event", gtk_main_quit, NULL);
gtk_main ();
g_object_unref (model);
return 0;
}

46
src/tests/test-zoom.c Normal file
View File

@ -0,0 +1,46 @@
#include "sp-zoom-manager.h"
static void
test_zoom_manager (void)
{
SpZoomManager *zoom;
zoom = sp_zoom_manager_new ();
g_assert_cmpfloat (1.0, ==, sp_zoom_manager_get_zoom (zoom));
sp_zoom_manager_zoom_in (zoom);
g_assert_cmpfloat (1.1, ==, sp_zoom_manager_get_zoom (zoom));
sp_zoom_manager_zoom_in (zoom);
g_assert_cmpfloat (1.2, ==, sp_zoom_manager_get_zoom (zoom));
sp_zoom_manager_zoom_in (zoom);
g_assert_cmpfloat (1.33, ==, sp_zoom_manager_get_zoom (zoom));
sp_zoom_manager_zoom_out (zoom);
g_assert_cmpfloat (1.2, ==, sp_zoom_manager_get_zoom (zoom));
sp_zoom_manager_zoom_out (zoom);
g_assert_cmpfloat (1.1, ==, sp_zoom_manager_get_zoom (zoom));
sp_zoom_manager_zoom_out (zoom);
g_assert_cmpfloat (1.0, ==, sp_zoom_manager_get_zoom (zoom));
sp_zoom_manager_zoom_out (zoom);
g_assert_cmpfloat (.9, ==, sp_zoom_manager_get_zoom (zoom));
sp_zoom_manager_zoom_out (zoom);
g_assert_cmpfloat (.8, ==, sp_zoom_manager_get_zoom (zoom));
sp_zoom_manager_zoom_out (zoom);
g_assert_cmpfloat (.67, ==, sp_zoom_manager_get_zoom (zoom));
sp_zoom_manager_zoom_out (zoom);
g_assert_cmpfloat (.5, ==, sp_zoom_manager_get_zoom (zoom));
sp_zoom_manager_zoom_out (zoom);
g_assert_cmpfloat (.3, ==, sp_zoom_manager_get_zoom (zoom));
sp_zoom_manager_zoom_out (zoom);
g_assert_cmpfloat (.3 / 2, ==, sp_zoom_manager_get_zoom (zoom));
g_object_unref (zoom);
}
gint
main (gint argc,
gchar *argv[])
{
g_test_init (&argc, &argv, NULL);
g_test_add_func ("/ZoomManager/basic", test_zoom_manager);
return g_test_run ();
}