From 0c4e48e54752314ac2cfbfec3296fd0df419bc47 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= Date: Fri, 14 Oct 2022 13:57:25 +0400 Subject: [PATCH 01/11] tests/file-thumbnail: make it work with win32 paths MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On Win32, we get paths with mixed \\ and /, use GFile to resolve and normalize the paths before comparing. Signed-off-by: Marc-André Lureau --- gio/tests/file-thumbnail.c | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/gio/tests/file-thumbnail.c b/gio/tests/file-thumbnail.c index 6e8768a73..5fd265f36 100644 --- a/gio/tests/file-thumbnail.c +++ b/gio/tests/file-thumbnail.c @@ -207,26 +207,25 @@ test_valid_thumbnail_size (gconstpointer data) { GFile *source; GFile *thumbnail; + GFile *f; GError *error = NULL; GFileInfo *info; const gchar *size = data; - char *thumbnail_path; thumbnail = create_thumbnail_from_test_file ("valid.png", size, &source); info = g_file_query_info (source, THUMBNAILS_ATTRIBS, G_FILE_QUERY_INFO_NONE, NULL, &error); g_assert_no_error (error); - thumbnail_path = g_file_get_path (thumbnail); - g_assert_true (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_THUMBNAIL_PATH)); g_assert_true (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_THUMBNAIL_IS_VALID)); g_assert_false (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_THUMBNAILING_FAILED)); + f = g_file_new_for_path (g_file_info_get_attribute_byte_string (info, G_FILE_ATTRIBUTE_THUMBNAIL_PATH)); g_assert_cmpstr ( - g_file_info_get_attribute_byte_string (info, G_FILE_ATTRIBUTE_THUMBNAIL_PATH), + g_file_peek_path (f), ==, - thumbnail_path + g_file_peek_path (thumbnail) ); /* TODO: We can't really test this without having a proper thumbnail created @@ -238,7 +237,7 @@ test_valid_thumbnail_size (gconstpointer data) g_clear_object (&thumbnail); g_clear_error (&error); g_clear_object (&info); - g_free (thumbnail_path); + g_clear_object (&f); } static void @@ -310,7 +309,7 @@ test_thumbnails_size_priority (void) for (i = 0; i < G_N_ELEMENTS (SIZES_NAMES); i++) { GFile *thumbnail = create_thumbnail (source, SIZES_NAMES[i]); - gchar *thumbnail_path = g_file_get_path (thumbnail); + GFile *f; g_ptr_array_add (sized_thumbnails, thumbnail); @@ -322,14 +321,15 @@ test_thumbnails_size_priority (void) g_assert_true (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_THUMBNAIL_IS_VALID)); g_assert_false (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_THUMBNAILING_FAILED)); + f = g_file_new_for_path (g_file_info_get_attribute_byte_string (info, G_FILE_ATTRIBUTE_THUMBNAIL_PATH)); g_assert_cmpstr ( - g_file_info_get_attribute_byte_string (info, G_FILE_ATTRIBUTE_THUMBNAIL_PATH), + g_file_peek_path (f), ==, - thumbnail_path + g_file_peek_path (thumbnail) ); - g_free (thumbnail_path); g_clear_object (&info); + g_clear_object (&f); } g_assert_cmpuint (sized_thumbnails->len, ==, G_N_ELEMENTS (SIZES_NAMES)); @@ -339,7 +339,7 @@ test_thumbnails_size_priority (void) { GFile *thumbnail = g_ptr_array_index (sized_thumbnails, i - 1); GFile *less_priority_thumbnail = g_ptr_array_index (sized_thumbnails, i - 2); - gchar *thumbnail_path = g_file_get_path (less_priority_thumbnail); + GFile *f; g_file_delete (thumbnail, NULL, &error); g_assert_no_error (error); @@ -352,14 +352,15 @@ test_thumbnails_size_priority (void) g_assert_true (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_THUMBNAIL_IS_VALID)); g_assert_false (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_THUMBNAILING_FAILED)); + f = g_file_new_for_path (g_file_info_get_attribute_byte_string (info, G_FILE_ATTRIBUTE_THUMBNAIL_PATH)); g_assert_cmpstr ( - g_file_info_get_attribute_byte_string (info, G_FILE_ATTRIBUTE_THUMBNAIL_PATH), + g_file_peek_path (f), ==, - thumbnail_path + g_file_peek_path (less_priority_thumbnail) ); - g_free (thumbnail_path); g_clear_object (&info); + g_clear_object (&f); } /* And now let's remove the last valid one, so that failed should have priority */ From 06543f669975733f5d2ad688a3d3231bb19c1cc5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= Date: Fri, 14 Oct 2022 14:04:18 +0400 Subject: [PATCH 02/11] tests/assert-msg-test: add exe extension on win32 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Marc-André Lureau --- glib/tests/assert-msg-test.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/glib/tests/assert-msg-test.py b/glib/tests/assert-msg-test.py index 01bedce91..603bfc459 100755 --- a/glib/tests/assert-msg-test.py +++ b/glib/tests/assert-msg-test.py @@ -59,13 +59,16 @@ class TestAssertMessage(unittest.TestCase): self.__gdb = shutil.which("gdb") self.timeout_seconds = 10 # seconds per test + ext = "" + if os.name == "nt": + ext = ".exe" if "G_TEST_BUILDDIR" in os.environ: self.__assert_msg_test = os.path.join( - os.environ["G_TEST_BUILDDIR"], "assert-msg-test" + os.environ["G_TEST_BUILDDIR"], "assert-msg-test" + ext ) else: self.__assert_msg_test = os.path.join( - os.path.dirname(__file__), "assert-msg-test" + os.path.dirname(__file__), "assert-msg-test" + ext ) print("assert-msg-test:", self.__assert_msg_test) From 64e12059e3276b092473276b0d9c0b09d20e81f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= Date: Fri, 14 Oct 2022 14:12:59 +0400 Subject: [PATCH 03/11] tests/assert-msg-test: it is not a script (anymore?) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes running the program on win32. Signed-off-by: Marc-André Lureau --- glib/tests/assert-msg-test.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/glib/tests/assert-msg-test.py b/glib/tests/assert-msg-test.py index 603bfc459..ddb12d595 100755 --- a/glib/tests/assert-msg-test.py +++ b/glib/tests/assert-msg-test.py @@ -74,10 +74,6 @@ class TestAssertMessage(unittest.TestCase): def runAssertMessage(self, *args): argv = [self.__assert_msg_test] - # shebang lines are not supported on native - # Windows consoles - if os.name == "nt": - argv.insert(0, sys.executable) argv.extend(args) print("Running:", argv) From 2c94b422b29aca34d4f5b8822e3a6d507ebb0f43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= Date: Fri, 14 Oct 2022 14:04:18 +0400 Subject: [PATCH 04/11] tests/assert-msg-test: abort() exit code is 3 on win32 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Marc-André Lureau --- glib/tests/assert-msg-test.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/glib/tests/assert-msg-test.py b/glib/tests/assert-msg-test.py index ddb12d595..ca0f559c4 100755 --- a/glib/tests/assert-msg-test.py +++ b/glib/tests/assert-msg-test.py @@ -134,7 +134,10 @@ class TestAssertMessage(unittest.TestCase): """Test running g_assert() and fail the program.""" result = self.runAssertMessage() - self.assertEqual(result.info.returncode, -6) + if os.name == "nt": + self.assertEqual(result.info.returncode, 3) + else: + self.assertEqual(result.info.returncode, -6) self.assertIn("assertion failed: (42 < 0)", result.out) def test_gdb_gassert(self): From ab7940e8115e52a0b4be92aebe5f18136fb018c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= Date: Fri, 14 Oct 2022 15:05:25 +0400 Subject: [PATCH 05/11] tests/assert-msg-test: fix opening temporary file in GDB MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On Win32, the file cannot be opened a second time, it must be closed first. Signed-off-by: Marc-André Lureau --- glib/tests/assert-msg-test.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/glib/tests/assert-msg-test.py b/glib/tests/assert-msg-test.py index ca0f559c4..5e5f3fb23 100755 --- a/glib/tests/assert-msg-test.py +++ b/glib/tests/assert-msg-test.py @@ -146,12 +146,14 @@ class TestAssertMessage(unittest.TestCase): self.skipTest("GDB is not installed, skipping this test!") with tempfile.NamedTemporaryFile( - prefix="assert-msg-test-", suffix=".gdb", mode="w" + prefix="assert-msg-test-", suffix=".gdb", mode="w", delete=False ) as tmp: - tmp.write(GDB_SCRIPT) - tmp.flush() - - result = self.runGdbAssertMessage("-x", tmp.name, self.__assert_msg_test) + try: + tmp.write(GDB_SCRIPT) + tmp.close() + result = self.runGdbAssertMessage("-x", tmp.name, self.__assert_msg_test) + finally: + os.unlink(tmp.name) # Some CI environments disable ptrace (as they’re running in a # container). If so, skip the test as there’s nothing we can do. From 0d5a885e5a3ffffba8d0961d4d22cea99d905987 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= Date: Fri, 14 Oct 2022 16:46:05 +0400 Subject: [PATCH 06/11] gio/locafileinfo: fix set_mtime_atime on win32 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use a similar behaviour as the utime()/posix implementation and query the current times to allow modifying only usec/nsecs parts. Fixes tests/g-file-info on win32. Signed-off-by: Marc-André Lureau --- gio/glocalfileinfo.c | 161 ++++++++++++++++++++++++++----------------- 1 file changed, 96 insertions(+), 65 deletions(-) diff --git a/gio/glocalfileinfo.c b/gio/glocalfileinfo.c index b2a497a44..9c88c9176 100644 --- a/gio/glocalfileinfo.c +++ b/gio/glocalfileinfo.c @@ -2441,6 +2441,26 @@ set_symlink (char *filename, } #endif +#if defined (HAVE_UTIMES) || defined (HAVE_UTIMENSAT) || defined(G_OS_WIN32) +static int +lazy_stat (const char *filename, + GStatBuf *statbuf, + gboolean *called_stat) +{ + int res; + + if (*called_stat) + return 0; + + res = g_stat (filename, statbuf); + + if (res == 0) + *called_stat = TRUE; + + return res; +} +#endif + #if defined (G_OS_WIN32) /* From * https://support.microsoft.com/en-ca/help/167296/how-to-convert-a-unix-time-t-to-a-win32-filetime-or-systemtime @@ -2546,6 +2566,8 @@ set_mtime_atime (const char *filename, FILETIME *p_mtime = NULL; FILETIME *p_atime = NULL; DWORD gle; + GStatBuf statbuf; + gboolean got_stat = FALSE; /* ATIME */ if (atime_value) @@ -2554,30 +2576,44 @@ set_mtime_atime (const char *filename, return FALSE; val_usec = 0; val_nsec = 0; - if (atime_usec_value && - !get_uint32 (atime_usec_value, &val_usec, error)) - return FALSE; - - /* Convert to nanoseconds. Clamp the usec value if it’s going to overflow, - * as %G_MAXINT32 will trigger a ‘too big’ error in - * _g_win32_unix_time_to_filetime() anyway. */ - val_nsec = (val_usec > G_MAXINT32 / 1000) ? G_MAXINT32 : (val_usec * 1000); - - if (atime_nsec_value && - !get_uint32 (atime_nsec_value, &val_nsec, error)) - return FALSE; - if (val_nsec > 0) - { - if (!_g_win32_unix_time_to_filetime (val, val_nsec, &atime, error)) - return FALSE; - } - else - { - if (!_g_win32_unix_time_to_filetime (val, val_usec, &atime, error)) - return FALSE; - } - p_atime = &atime; } + else + { + if (lazy_stat (filename, &statbuf, &got_stat) == 0) + { + val = statbuf.st_atime; +#if defined (HAVE_STRUCT_STAT_ST_ATIMENSEC) + val_nsec = statbuf.st_atimensec; +#elif defined (HAVE_STRUCT_STAT_ST_ATIM_TV_NSEC) + val_nsec = statbuf.st_atim.tv_nsec; +#endif + } + } + + if (atime_usec_value && + !get_uint32 (atime_usec_value, &val_usec, error)) + return FALSE; + + /* Convert to nanoseconds. Clamp the usec value if it’s going to overflow, + * as %G_MAXINT32 will trigger a ‘too big’ error in + * _g_win32_unix_time_to_filetime() anyway. */ + val_nsec = (val_usec > G_MAXINT32 / 1000) ? G_MAXINT32 : (val_usec * 1000); + + if (atime_nsec_value && + !get_uint32 (atime_nsec_value, &val_nsec, error)) + return FALSE; + if (val_nsec > 0) + { + if (!_g_win32_unix_time_to_filetime (val, val_nsec, &atime, error)) + return FALSE; + } + else + { + if (!_g_win32_unix_time_to_filetime (val, val_usec, &atime, error)) + return FALSE; + } + + p_atime = &atime; /* MTIME */ if (mtime_value) @@ -2586,30 +2622,43 @@ set_mtime_atime (const char *filename, return FALSE; val_usec = 0; val_nsec = 0; - if (mtime_usec_value && - !get_uint32 (mtime_usec_value, &val_usec, error)) - return FALSE; - - /* Convert to nanoseconds. Clamp the usec value if it’s going to overflow, - * as %G_MAXINT32 will trigger a ‘too big’ error in - * _g_win32_unix_time_to_filetime() anyway. */ - val_nsec = (val_usec > G_MAXINT32 / 1000) ? G_MAXINT32 : (val_usec * 1000); - - if (mtime_nsec_value && - !get_uint32 (mtime_nsec_value, &val_nsec, error)) - return FALSE; - if (val_nsec > 0) - { - if (!_g_win32_unix_time_to_filetime (val, val_nsec, &mtime, error)) - return FALSE; - } - else - { - if (!_g_win32_unix_time_to_filetime (val, val_usec, &mtime, error)) - return FALSE; - } - p_mtime = &mtime; } + else + { + if (lazy_stat (filename, &statbuf, &got_stat) == 0) + { + val = statbuf.st_mtime; +#if defined (HAVE_STRUCT_STAT_ST_MTIMENSEC) + val_nsec = statbuf.st_mtimensec; +#elif defined (HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC) + val_nsec = statbuf.st_mtim.tv_nsec; +#endif + } + } + + if (mtime_usec_value && + !get_uint32 (mtime_usec_value, &val_usec, error)) + return FALSE; + + /* Convert to nanoseconds. Clamp the usec value if it’s going to overflow, + * as %G_MAXINT32 will trigger a ‘too big’ error in + * _g_win32_unix_time_to_filetime() anyway. */ + val_nsec = (val_usec > G_MAXINT32 / 1000) ? G_MAXINT32 : (val_usec * 1000); + + if (mtime_nsec_value && + !get_uint32 (mtime_nsec_value, &val_nsec, error)) + return FALSE; + if (val_nsec > 0) + { + if (!_g_win32_unix_time_to_filetime (val, val_nsec, &mtime, error)) + return FALSE; + } + else + { + if (!_g_win32_unix_time_to_filetime (val, val_usec, &mtime, error)) + return FALSE; + } + p_mtime = &mtime; filename_utf16 = g_utf8_to_utf16 (filename, -1, NULL, NULL, error); @@ -2654,24 +2703,6 @@ set_mtime_atime (const char *filename, return res; } #elif defined (HAVE_UTIMES) || defined (HAVE_UTIMENSAT) -static int -lazy_stat (char *filename, - struct stat *statbuf, - gboolean *called_stat) -{ - int res; - - if (*called_stat) - return 0; - - res = g_stat (filename, statbuf); - - if (res == 0) - *called_stat = TRUE; - - return res; -} - static gboolean set_mtime_atime (char *filename, const GFileAttributeValue *mtime_value, @@ -2684,7 +2715,7 @@ set_mtime_atime (char *filename, { int res; guint64 val = 0; - struct stat statbuf; + GStatBuf statbuf; gboolean got_stat = FALSE; #ifdef HAVE_UTIMENSAT struct timespec times_n[2] = { {0, 0}, {0, 0} }; From f16b700cb6a8b03a3182ab5c26074e718f08b8b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= Date: Fri, 14 Oct 2022 16:58:13 +0400 Subject: [PATCH 07/11] tests/thread-pool-slow: change num-threads limit check MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There is no guarantee that the thread pool will reach its limit afaict, it depends how the system schedule the various threads. This fixes random test failure on win32. Signed-off-by: Marc-André Lureau --- glib/tests/thread-pool-slow.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/glib/tests/thread-pool-slow.c b/glib/tests/thread-pool-slow.c index ae16426be..356464de7 100644 --- a/glib/tests/thread-pool-slow.c +++ b/glib/tests/thread-pool-slow.c @@ -291,7 +291,7 @@ test_thread_sort (gboolean sort) } g_assert_cmpint (g_thread_pool_get_max_threads (pool), ==, (gint) max_threads); - g_assert_cmpuint (g_thread_pool_get_num_threads (pool), ==, + g_assert_cmpuint (g_thread_pool_get_num_threads (pool), <=, (guint) g_thread_pool_get_max_threads (pool)); g_thread_pool_free (pool, TRUE, TRUE); } From b440a0f0cbf5742551d58290458c250809d22731 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= Date: Fri, 14 Oct 2022 17:42:07 +0400 Subject: [PATCH 08/11] tests/thread-pool-slow: do not pass confusing value to sort function MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit That value isn't used by the callback. Signed-off-by: Marc-André Lureau --- glib/tests/thread-pool-slow.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/glib/tests/thread-pool-slow.c b/glib/tests/thread-pool-slow.c index 356464de7..f4a4ad727 100644 --- a/glib/tests/thread-pool-slow.c +++ b/glib/tests/thread-pool-slow.c @@ -274,7 +274,7 @@ test_thread_sort (gboolean sort) if (sort) { g_thread_pool_set_sort_function (pool, test_thread_sort_compare_func, - GUINT_TO_POINTER (69)); + NULL); } for (i = 0; i < limit; i++) { From 64fb6b3b468376ead08c76fd58f529b2a26348d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= Date: Fri, 14 Oct 2022 17:09:55 +0400 Subject: [PATCH 09/11] tests/contenttype: icon name text/plain doesn't have text-x-generic on win32 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The g_content_type_get_icon() function for win32 can lookup the DefaultIcon associated with .txt and return a different result. Signed-off-by: Marc-André Lureau --- gio/tests/contenttype.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gio/tests/contenttype.c b/gio/tests/contenttype.c index 6cfd366ff..7fd97f453 100644 --- a/gio/tests/contenttype.c +++ b/gio/tests/contenttype.c @@ -252,10 +252,10 @@ test_icon (void) names = g_themed_icon_get_names (G_THEMED_ICON (icon)); #ifdef __APPLE__ g_assert_true (g_strv_contains (names, "text-*")); +#elif defined(G_OS_WIN32) + g_assert_cmpuint (g_strv_length ((GStrv) names), >, 0); #else -#ifndef G_OS_WIN32 g_assert_true (g_strv_contains (names, "text-plain")); -#endif g_assert_true (g_strv_contains (names, "text-x-generic")); #endif } From bbe367022424a96bcd387c0c79ff1175dcb90f35 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= Date: Fri, 14 Oct 2022 17:13:31 +0400 Subject: [PATCH 10/11] tests/gobject-query: it is not a script (anymore?) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Marc-André Lureau --- gobject/tests/gobject-query.py | 6 ------ 1 file changed, 6 deletions(-) diff --git a/gobject/tests/gobject-query.py b/gobject/tests/gobject-query.py index 094f37d3c..0325f70d2 100644 --- a/gobject/tests/gobject-query.py +++ b/gobject/tests/gobject-query.py @@ -55,12 +55,6 @@ class TestGobjectQuery(unittest.TestCase): def runGobjectQuery(self, *args): argv = [self.__gobject_query] - - # shebang lines are not supported on native - # Windows consoles - if os.name == "nt": - argv.insert(0, sys.executable) - argv.extend(args) print("Running:", argv) From fd68558eecb67375dda73b14ad100a69b954bb8f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= Date: Fri, 14 Oct 2022 17:24:57 +0400 Subject: [PATCH 11/11] tests/gobject-query.py: make it work on msys2/win32 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit For unclear reasons, universal_newlines=True doesn't seem to set the text encoding correctly. Even if I set only encoding='utf-8', the test fails. The combination here works for me, \o/. Signed-off-by: Marc-André Lureau --- gobject/tests/gobject-query.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/gobject/tests/gobject-query.py b/gobject/tests/gobject-query.py index 0325f70d2..84370a151 100644 --- a/gobject/tests/gobject-query.py +++ b/gobject/tests/gobject-query.py @@ -69,7 +69,8 @@ class TestGobjectQuery(unittest.TestCase): stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=env, - universal_newlines=True, + text=True, + encoding='utf-8', ) info.check_returncode() out = info.stdout.strip()