[gegl] tests: Exercise buffer sharing via on-disk
- From: Øyvind Kolås <ok src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gegl] tests: Exercise buffer sharing via on-disk
- Date: Sun, 29 Jan 2017 23:24:04 +0000 (UTC)
commit d4d67171ea67206e80fd0f13dd4364fb671dc7fe
Author: Jon Nordby <jononor gmail com>
Date: Sat Jan 28 20:12:43 2017 +0100
tests: Exercise buffer sharing via on-disk
tests/simple/.gitignore | 2 +
tests/simple/Makefile.am | 1 +
tests/simple/test-buffer-sharing.c | 216 ++++++++++++++++++++++++++++++++++++
3 files changed, 219 insertions(+), 0 deletions(-)
---
diff --git a/tests/simple/.gitignore b/tests/simple/.gitignore
index 8c645a0..4e86370 100644
--- a/tests/simple/.gitignore
+++ b/tests/simple/.gitignore
@@ -33,3 +33,5 @@
/test-buffer-hot-tile
/test-node-passthrough
/test-serialize
+/test-buffer-sharing.data.gegl
+/test-buffer-sharing
diff --git a/tests/simple/Makefile.am b/tests/simple/Makefile.am
index 467f4f2..e28680a 100644
--- a/tests/simple/Makefile.am
+++ b/tests/simple/Makefile.am
@@ -5,6 +5,7 @@ noinst_PROGRAMS = \
test-buffer-changes \
test-buffer-extract \
test-buffer-hot-tile \
+ test-buffer-sharing \
test-buffer-tile-voiding \
test-change-processor-rect \
test-convert-format \
diff --git a/tests/simple/test-buffer-sharing.c b/tests/simple/test-buffer-sharing.c
new file mode 100644
index 0000000..46975ca
--- /dev/null
+++ b/tests/simple/test-buffer-sharing.c
@@ -0,0 +1,216 @@
+/*
+ * 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/>.
+ *
+ * Copyright (C) 2017 Jon Nordby <jononor gmail com>
+ */
+
+#include <gegl.h>
+
+// in order of progression
+typedef enum _TestState {
+ TestInvalid = 0,
+ TestInitialized,
+ TestSetBlue,
+ TestWaitingForBlue,
+ TestAssertBlue,
+ TestSetYellow,
+ TestWaitingForYellow,
+ TestAssertYellow,
+ TestFailed,
+ TestSucceed,
+} TestState;
+
+typedef struct _TestData {
+ GMainLoop *loop;
+ GeglBuffer *a;
+ GeglBuffer *b;
+ TestState state;
+} TestData;
+
+static void
+print_color(GeglColor *color) {
+ unsigned char rgba[4];
+ const Babl *format = babl_format("R'G'B'A u8");
+ gegl_color_get_pixel(color, format, (gpointer)rgba);
+ g_print("[%d, %d, %d, %d]",
+ rgba[0], rgba[1], rgba[2], rgba[3]);
+}
+
+static gboolean
+assert_color_equal(GeglColor *expect, GeglColor *actual) {
+ const Babl *format = babl_format("R'G'B'A u8");
+ unsigned char e[4];
+ unsigned char a[4];
+ gegl_color_get_pixel(expect, format, (gpointer)e);
+ gegl_color_get_pixel(actual, format, (gpointer)a);
+
+ const gboolean equal =
+ a[0] == e[0] &&
+ a[1] == e[1] &&
+ a[2] == e[2] &&
+ a[3] == e[3];
+
+ if (!equal) {
+ print_color(expect);
+ g_print(" != ");
+ print_color(actual);
+ g_print("\n");
+ return FALSE;
+ }
+ return TRUE;
+}
+
+static GeglColor *
+buffer_get_color(GeglBuffer *buffer) {
+ const int pixels = 1;
+ guint8 pixel[4];
+ GeglRectangle r = { 0, 0, 1, pixels };
+ unsigned char contents[pixels*4];
+ const Babl *format = babl_format("R'G'B'A u8");
+ gegl_buffer_get(buffer, &r, 1.0, format, (gpointer)(pixel), GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_CLAMP);
+ GeglColor *color = gegl_color_new(NULL);
+ gegl_color_set_pixel(color, format, (gpointer)pixel);
+ return color;
+}
+
+// Core state-machine
+static void
+test_change_state(TestData *data, TestState new) {
+ GeglColor *blue = gegl_color_new("blue");
+ GeglColor *yellow = gegl_color_new("yellow");
+ GeglRectangle rect = { 0, 0, 100, 100 };
+
+ data->state = new;
+
+ switch (data->state) {
+ // test actions and checking
+ case TestSetBlue:
+ // Write blue to A, should be reflected in B
+ gegl_buffer_set_extent(data->a, &rect);
+ gegl_buffer_set_color(data->a, &rect, blue);
+ gegl_buffer_flush(data->a);
+ test_change_state(data, TestWaitingForBlue);
+ break;
+ case TestAssertBlue:
+ {
+ GeglColor *actual = buffer_get_color(data->a);
+ const gboolean pass = assert_color_equal(blue, actual);
+ test_change_state(data, (pass) ? TestSetYellow : TestFailed);
+ }
+ break;
+ case TestSetYellow:
+ // Write blue to A, should be reflected in B
+ gegl_buffer_set_extent(data->a, &rect);
+ gegl_buffer_set_color(data->a, &rect, yellow);
+ gegl_buffer_flush(data->a);
+ test_change_state(data, TestWaitingForYellow);
+ break;
+ case TestAssertYellow:
+ {
+ GeglColor *actual = buffer_get_color(data->a);
+ const gboolean pass = assert_color_equal(yellow, actual);
+ test_change_state(data, (pass) ? TestSucceed : TestFailed);
+ }
+ break;
+ // handled elsewhere
+ case TestWaitingForYellow:
+ case TestInitialized:
+ case TestWaitingForBlue:
+ break;
+ // exit
+ case TestInvalid:
+ case TestFailed:
+ case TestSucceed:
+ g_main_loop_quit(data->loop);
+ break;
+ }
+}
+
+static void
+on_buffer_changed(GeglBuffer *buffer,
+ const GeglRectangle *rect,
+ gpointer user_data)
+{
+ TestData *test = (TestData *)user_data;
+ //g_print("changed! %d %d %d %d \n", rect->x, rect->y, rect->width, rect->height);
+
+ if (test->state == TestWaitingForBlue) {
+ test_change_state(test, TestAssertBlue);
+ } else if (test->state == TestWaitingForYellow) {
+ test_change_state(test, TestAssertYellow);
+ } else {
+ test_change_state(test, TestFailed);
+ }
+}
+
+static gboolean
+on_timeout(gpointer user_data) {
+ TestData *test = (TestData *)user_data;
+ g_print("timeout!\n");
+ test_change_state(test, TestFailed);
+ return FALSE;
+}
+
+static void
+test_init(TestData *data) {
+ const gchar *file_path = "test-buffer-sharing.data.gegl";
+
+ // ensure we're starting from nothing
+ if (g_access(file_path, 0) == 0) {
+ g_remove(file_path);
+ }
+ data->loop = g_main_loop_new(NULL, TRUE);
+ data->a = gegl_buffer_open(file_path);
+ // FIXME: if not setting an extent and adding some data, the written on-disk file seems to be corrupt
+ GeglRectangle rect = { 0, 0, 100, 100 };
+ GeglColor *blank = gegl_color_new("transparent");
+ gegl_buffer_set_extent(data->a, &rect);
+ gegl_buffer_set_color(data->a, &rect, blank);
+ gegl_buffer_flush(data->a); // ensure file exists on disk
+
+ sleep(1);
+
+ // B observes the same on-disk buffer
+ data->b = gegl_buffer_open(file_path);
+ data->state = TestInitialized;
+
+ gegl_buffer_signal_connect(data->b, "changed", on_buffer_changed, data);
+ g_timeout_add_seconds(10, on_timeout, data);
+}
+
+static void
+test_destroy(TestData *data) {
+
+ g_object_unref(data->a);
+ g_object_unref(data->b);
+}
+
+int
+main (int argc,
+ char *argv[])
+{
+ TestData test;
+ gegl_init (&argc, &argv);
+ TestData *data = &test;
+
+ test_init(data);
+
+ test_change_state(data, TestSetBlue);
+
+ g_main_loop_run(data->loop);
+ const int exitcode = (data->state == TestSucceed) ? 0 : 1;
+ g_print("%s\n", (data->state == TestSucceed) ? "PASS" : "FAIL");
+ test_destroy(data);
+ return exitcode;
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]