From e808fb424ae10baa31ba92a2e3bbec38689c246a Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Thu, 21 Jan 2021 23:57:24 -0500 Subject: [PATCH] testsuite: Stop requiring diff Unify the many copies of diff_with_file in one source file, and patch it to detect diff at runtime and fall back to a simple strcmp if we don't have it. Make all tests use this new testutils.c, and stop requiring diff for building the tests. This should let us allow to build on Windows with the default value for -Dbuild-tests. --- testsuite/css/change/meson.build | 1 + testsuite/css/change/test-css-change.c | 49 +------------- testsuite/css/nodes/meson.build | 2 +- testsuite/css/nodes/test-css-nodes.c | 49 +------------- testsuite/css/parser/meson.build | 2 +- testsuite/css/parser/test-css-parser.c | 62 +++--------------- testsuite/css/style/meson.build | 1 + testsuite/css/style/test-css-style.c | 54 ++-------------- testsuite/gtk/meson.build | 2 +- testsuite/gtk/test-focus-chain.c | 49 +------------- testsuite/meson.build | 4 -- testsuite/testutils.c | 88 ++++++++++++++++++++++++++ testsuite/testutils.h | 7 ++ 13 files changed, 116 insertions(+), 254 deletions(-) create mode 100644 testsuite/testutils.c create mode 100644 testsuite/testutils.h diff --git a/testsuite/css/change/meson.build b/testsuite/css/change/meson.build index 01a6829fbd..9409f483c1 100644 --- a/testsuite/css/change/meson.build +++ b/testsuite/css/change/meson.build @@ -13,6 +13,7 @@ testdatadir = join_paths(installed_test_datadir, 'css') test_change = executable( 'test-css-change', 'test-css-change.c', + '../../testutils.c', c_args: common_cflags, dependencies: libgtk_dep, install: get_option('install-tests'), diff --git a/testsuite/css/change/test-css-change.c b/testsuite/css/change/test-css-change.c index 830f53fbfd..1d60f0bcff 100644 --- a/testsuite/css/change/test-css-change.c +++ b/testsuite/css/change/test-css-change.c @@ -21,6 +21,7 @@ #include #include #include +#include "testsuite/testutils.h" #ifdef G_OS_WIN32 # include @@ -50,54 +51,6 @@ test_get_other_file (const char *ui_file, const char *extension) return g_string_free (file, FALSE); } -static char * -diff_with_file (const char *file1, - char *text, - gssize len, - GError **error) -{ - const char *command[] = { "diff", "-u", file1, NULL, NULL }; - char *diff, *tmpfile; - int fd; - - diff = NULL; - - if (len < 0) - len = strlen (text); - - /* write the text buffer to a temporary file */ - fd = g_file_open_tmp (NULL, &tmpfile, error); - if (fd < 0) - return NULL; - - if (write (fd, text, len) != (int) len) - { - close (fd); - g_set_error (error, - G_FILE_ERROR, G_FILE_ERROR_FAILED, - "Could not write data to temporary file '%s'", tmpfile); - goto done; - } - close (fd); - command[3] = tmpfile; - - /* run diff command */ - g_spawn_sync (NULL, - (char **) command, - NULL, - G_SPAWN_SEARCH_PATH, - NULL, NULL, - &diff, - NULL, NULL, - error); - -done: - g_unlink (tmpfile); - g_free (tmpfile); - - return diff; -} - static void style_context_changed (GtkWidget *window, const char **output) { diff --git a/testsuite/css/nodes/meson.build b/testsuite/css/nodes/meson.build index 97a739f1b3..eb619cf29c 100644 --- a/testsuite/css/nodes/meson.build +++ b/testsuite/css/nodes/meson.build @@ -10,7 +10,7 @@ nodetest_env.set('G_ENABLE_DIAGNOSTIC', '0') testexecdir = join_paths(installed_test_bindir, 'css', 'nodes') testdatadir = join_paths(installed_test_datadir, 'css') -test_nodes = executable('test-css-nodes', 'test-css-nodes.c', +test_nodes = executable('test-css-nodes', 'test-css-nodes.c', '../../testutils.c', c_args: common_cflags, install: get_option('install-tests'), install_dir: testexecdir, diff --git a/testsuite/css/nodes/test-css-nodes.c b/testsuite/css/nodes/test-css-nodes.c index 28bdfcb9b1..a44c4e4508 100644 --- a/testsuite/css/nodes/test-css-nodes.c +++ b/testsuite/css/nodes/test-css-nodes.c @@ -21,6 +21,7 @@ #include #include #include +#include "testsuite/testutils.h" #ifdef G_OS_WIN32 # include @@ -48,54 +49,6 @@ test_get_reference_file (const char *ui_file) return g_string_free (file, FALSE); } -static char * -diff_with_file (const char *file1, - char *text, - gssize len, - GError **error) -{ - const char *command[] = { "diff", "-u", file1, NULL, NULL }; - char *diff, *tmpfile; - int fd; - - diff = NULL; - - if (len < 0) - len = strlen (text); - - /* write the text buffer to a temporary file */ - fd = g_file_open_tmp (NULL, &tmpfile, error); - if (fd < 0) - return NULL; - - if (write (fd, text, len) != (int) len) - { - close (fd); - g_set_error (error, - G_FILE_ERROR, G_FILE_ERROR_FAILED, - "Could not write data to temporary file '%s'", tmpfile); - goto done; - } - close (fd); - command[3] = tmpfile; - - /* run diff command */ - g_spawn_sync (NULL, - (char **) command, - NULL, - G_SPAWN_SEARCH_PATH, - NULL, NULL, - &diff, - NULL, NULL, - error); - -done: - g_unlink (tmpfile); - g_free (tmpfile); - - return diff; -} - static void style_context_changed (GtkWidget *window, const char **output) { diff --git a/testsuite/css/parser/meson.build b/testsuite/css/parser/meson.build index 7e501aebda..f70753c2b5 100644 --- a/testsuite/css/parser/meson.build +++ b/testsuite/css/parser/meson.build @@ -1,7 +1,7 @@ testexecdir = join_paths(installed_test_bindir, 'css', 'parser') testdatadir = join_paths(installed_test_datadir, 'css') -test_parser = executable('test-css-parser', 'test-css-parser.c', +test_parser = executable('test-css-parser', 'test-css-parser.c', '../../testutils.c', c_args: common_cflags, install: get_option('install-tests'), install_dir: testexecdir, diff --git a/testsuite/css/parser/test-css-parser.c b/testsuite/css/parser/test-css-parser.c index b2c4f69746..5d18e00cb8 100644 --- a/testsuite/css/parser/test-css-parser.c +++ b/testsuite/css/parser/test-css-parser.c @@ -25,6 +25,7 @@ #include #include #include +#include "testsuite/testutils.h" #ifdef G_OS_WIN32 # include @@ -72,51 +73,6 @@ test_get_errors_file (const char *css_file) return g_string_free (file, FALSE); } -static GBytes * -diff_with_file (const char *file1, - char *text, - gssize len, - GError **error) -{ - GSubprocess *process; - GBytes *input, *output; - - process = g_subprocess_new (G_SUBPROCESS_FLAGS_STDIN_PIPE - | G_SUBPROCESS_FLAGS_STDOUT_PIPE, - error, - "diff", "-u", file1, "-", NULL); - if (process == NULL) - return NULL; - - input = g_bytes_new_static (text, len >= 0 ? len : strlen (text)); - if (!g_subprocess_communicate (process, - input, - NULL, - &output, - NULL, - error)) - { - g_object_unref (process); - g_bytes_unref (input); - return NULL; - } - - if (!g_subprocess_get_successful (process) && - /* this is the condition when the files differ */ - !(g_subprocess_get_if_exited (process) && g_subprocess_get_exit_status (process) == 1)) - { - g_clear_pointer (&output, g_bytes_unref); - g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, - "The `diff' process exited with error status %d", - g_subprocess_get_exit_status (process)); - } - - g_object_unref (process); - g_bytes_unref (input); - - return output; -} - static void append_error_value (GString *string, GType enum_type, @@ -167,7 +123,7 @@ parse_css_file (GFile *file, gboolean generate) GtkCssProvider *provider; char *css, *css_file, *reference_file, *errors_file; GString *errors; - GBytes *diff; + char *diff; GError *error = NULL; css_file = g_file_get_path (file); @@ -193,14 +149,13 @@ parse_css_file (GFile *file, gboolean generate) diff = diff_with_file (reference_file, css, -1, &error); g_assert_no_error (error); - if (diff && g_bytes_get_size (diff) > 0) + if (diff && diff[0]) { - g_test_message ("Resulting CSS doesn't match reference:\n%s", - (const char *) g_bytes_get_data (diff, NULL)); + g_test_message ("Resulting CSS doesn't match reference:\n%s", diff); g_test_fail (); } g_free (reference_file); - g_clear_pointer (&diff, g_bytes_unref); + g_free (diff); errors_file = test_get_errors_file (css_file); @@ -209,13 +164,12 @@ parse_css_file (GFile *file, gboolean generate) diff = diff_with_file (errors_file, errors->str, errors->len, &error); g_assert_no_error (error); - if (diff && g_bytes_get_size (diff) > 0) + if (diff && diff[0]) { - g_test_message ("Errors don't match expected errors:\n%s", - (const char *) g_bytes_get_data (diff, NULL)); + g_test_message ("Errors don't match expected errors:\n%s", diff); g_test_fail (); } - g_clear_pointer (&diff, g_bytes_unref); + g_free (diff); } else if (errors->str[0]) { diff --git a/testsuite/css/style/meson.build b/testsuite/css/style/meson.build index 4026c5f3be..9dc0f4c34c 100644 --- a/testsuite/css/style/meson.build +++ b/testsuite/css/style/meson.build @@ -19,6 +19,7 @@ cssresources = gnome.compile_resources( test_style = executable( 'test-css-style', 'test-css-style.c', + '../../testutils.c', cssresources, c_args: common_cflags, dependencies: libgtk_dep, diff --git a/testsuite/css/style/test-css-style.c b/testsuite/css/style/test-css-style.c index 5c40c5cdac..93367fc336 100644 --- a/testsuite/css/style/test-css-style.c +++ b/testsuite/css/style/test-css-style.c @@ -21,6 +21,7 @@ #include #include #include +#include "testsuite/testutils.h" #ifdef G_OS_WIN32 # include @@ -50,51 +51,6 @@ test_get_other_file (const char *ui_file, const char *extension) return g_string_free (file, FALSE); } -static GBytes * -diff_with_file (const char *file1, - char *text, - gssize len, - GError **error) -{ - GSubprocess *process; - GBytes *input, *output; - - process = g_subprocess_new (G_SUBPROCESS_FLAGS_STDIN_PIPE - | G_SUBPROCESS_FLAGS_STDOUT_PIPE, - error, - "diff", "-u", file1, "-", NULL); - if (process == NULL) - return NULL; - - input = g_bytes_new_static (text, len >= 0 ? len : strlen (text)); - if (!g_subprocess_communicate (process, - input, - NULL, - &output, - NULL, - error)) - { - g_object_unref (process); - g_bytes_unref (input); - return NULL; - } - - if (!g_subprocess_get_successful (process) && - /* this is the condition when the files differ */ - !(g_subprocess_get_if_exited (process) && g_subprocess_get_exit_status (process) == 1)) - { - g_clear_pointer (&output, g_bytes_unref); - g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, - "The `diff' process exited with error status %d", - g_subprocess_get_exit_status (process)); - } - - g_object_unref (process); - g_bytes_unref (input); - - return output; -} - static char * fixup_style_differences (const char *str) { @@ -133,7 +89,7 @@ load_ui_file (GFile *file, gboolean generate) GtkBuilder *builder; GtkWidget *window; char *output; - GBytes *diff; + char *diff; char *ui_file, *css_file, *reference_file; GtkCssProvider *provider; GError *error = NULL; @@ -174,13 +130,13 @@ load_ui_file (GFile *file, gboolean generate) diff = diff_with_file (reference_file, output, -1, &error); g_assert_no_error (error); - if (diff && g_bytes_get_size (diff) > 0) + if (diff && diff[0]) { - g_test_message ("Resulting output doesn't match reference:\n%s", (const char *) g_bytes_get_data (diff, NULL)); + g_test_message ("Resulting output doesn't match reference:\n%s", diff); g_test_fail (); } g_free (reference_file); - g_clear_pointer (&diff, g_bytes_unref); + g_free (diff); out: gtk_style_context_remove_provider_for_display (gdk_display_get_default (), diff --git a/testsuite/gtk/meson.build b/testsuite/gtk/meson.build index f3710546ef..382e6369e9 100644 --- a/testsuite/gtk/meson.build +++ b/testsuite/gtk/meson.build @@ -250,7 +250,7 @@ focus_chain_tests = [ focus_chain = executable( 'test-focus-chain', - sources: ['test-focus-chain.c'], + sources: ['test-focus-chain.c', '../testutils.c'], dependencies: libgtk_dep, c_args: common_cflags, install: get_option('install-tests'), diff --git a/testsuite/gtk/test-focus-chain.c b/testsuite/gtk/test-focus-chain.c index 033cec98b5..cffedc1add 100644 --- a/testsuite/gtk/test-focus-chain.c +++ b/testsuite/gtk/test-focus-chain.c @@ -21,6 +21,7 @@ #include #include #include +#include "testsuite/testutils.h" #ifdef G_OS_WIN32 # include @@ -38,54 +39,6 @@ struct { { GTK_DIR_RIGHT, "right" } }; -static char * -diff_with_file (const char *file1, - char *text, - gssize len, - GError **error) -{ - const char *command[] = { "diff", "-u", file1, NULL, NULL }; - char *diff, *tmpfile; - int fd; - - diff = NULL; - - if (len < 0) - len = strlen (text); - - /* write the text buffer to a temporary file */ - fd = g_file_open_tmp (NULL, &tmpfile, error); - if (fd < 0) - return NULL; - - if (write (fd, text, len) != (int) len) - { - close (fd); - g_set_error (error, - G_FILE_ERROR, G_FILE_ERROR_FAILED, - "Could not write data to temporary file '%s'", tmpfile); - goto done; - } - close (fd); - command[3] = tmpfile; - - /* run diff command */ - g_spawn_sync (NULL, - (char **) command, - NULL, - G_SPAWN_SEARCH_PATH, - NULL, NULL, - &diff, - NULL, NULL, - error); - -done: - g_unlink (tmpfile); - g_free (tmpfile); - - return diff; -} - static void check_focus_states (GtkWidget *focus_widget) { diff --git a/testsuite/meson.build b/testsuite/meson.build index 4ef7cced9a..fafe6ea140 100644 --- a/testsuite/meson.build +++ b/testsuite/meson.build @@ -2,10 +2,6 @@ gtk_libexecdir = join_paths(gtk_prefix, get_option('libexecdir')) installed_test_bindir = join_paths(gtk_libexecdir, 'installed-tests', 'gtk-4.0') installed_test_datadir = join_paths(gtk_datadir, 'installed-tests', 'gtk-4.0') -# We call diff in various tests, so we need to check it's available, -# otherwise we're going to have failures down the line -diff = find_program('diff', required: true) - common_env = [ 'GIO_USE_VOLUME_MONITOR=unix', 'GSETTINGS_BACKEND=memory', diff --git a/testsuite/testutils.c b/testsuite/testutils.c new file mode 100644 index 0000000000..3d537e80dc --- /dev/null +++ b/testsuite/testutils.c @@ -0,0 +1,88 @@ +/* + * Copyright © 2021 Red Hat, Inc. + * + * This library 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.1 of the License, or (at your option) any later version. + * + * This library 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 Lesser General Public + * License along with this library. If not, see . + * + * Authors: Matthias Clasen + */ + +#include +#include +#include +#include "testsuite/testutils.h" + +char * +diff_with_file (const char *file1, + char *text, + gssize len, + GError **error) +{ + const char *command[] = { "diff", "-u", file1, NULL, NULL }; + char *diff, *tmpfile; + int fd; + + diff = NULL; + + if (g_find_program_in_path ("diff")) + { + if (len < 0) + len = strlen (text); + + /* write the text buffer to a temporary file */ + fd = g_file_open_tmp (NULL, &tmpfile, error); + if (fd < 0) + return NULL; + + if (write (fd, text, len) != (int) len) + { + close (fd); + g_set_error (error, + G_FILE_ERROR, G_FILE_ERROR_FAILED, + "Could not write data to temporary file '%s'", tmpfile); + goto done; + } + close (fd); + command[3] = tmpfile; + + /* run diff command */ + g_spawn_sync (NULL, + (char **) command, + NULL, + G_SPAWN_SEARCH_PATH, + NULL, NULL, + &diff, + NULL, NULL, + error); + +done: + g_unlink (tmpfile); + g_free (tmpfile); + } + else + { + char *buf1; + gsize len1; + + if (!g_file_get_contents (file1, &buf1, &len1, error)) + return NULL; + + if ((len != -1 && len != len1) || + strncmp (text, buf1, len1) != 0) + diff = g_strdup ("Files differ.\n"); + + g_free (buf1); + } + + return diff; +} diff --git a/testsuite/testutils.h b/testsuite/testutils.h new file mode 100644 index 0000000000..7250ca6160 --- /dev/null +++ b/testsuite/testutils.h @@ -0,0 +1,7 @@ +#pragma once + +char * diff_with_file (const char *file1, + char *text, + gssize len, + GError **error); +