[glib-networking/wip/tingping/pkcs11: 7/7] Fix sporadic failures in PKCS#11 client auth test




commit 0a659d0a51d2e50d06249e3b2f289ebc339def4f
Author: Michael Catanzaro <mcatanzaro gnome org>
Date:   Thu Dec 3 11:24:36 2020 -0600

    Fix sporadic failures in PKCS#11 client auth test
    
    This was hard. The problem was that the mock PKCS#11 module accepts only
    a single PKCS#11 session at a time. The test normally creates one
    session, closes it, creates another, and closes it. But sometimes the
    first session doesn't get closed before the second is created, and the
    test breaks. The problem is that the PKCS#11 session is created and
    closed by the GTlsClientConnection. The test creates two, and unrefs the
    first one before creating the second, but other refs are held by the
    first connection's GTasks. These GTasks complete in idle callbacks, and
    if one idle fails to run before we finish iterating the main loop, the
    first GTlsClientConnection won't be destroyed and so the first PKCS#11
    session won't be closed in time. Note there is no bug in the
    implementation, and nothing is leaked; rather, it's just not destroyed
    soon enough for the test.
    
    Fix this by iterating the test's main context until the first connection
    is destroyed.

 tls/tests/connection.c | 27 ++++++++++++++++++++++++++-
 1 file changed, 26 insertions(+), 1 deletion(-)
---
diff --git a/tls/tests/connection.c b/tls/tests/connection.c
index 7692efd..036df04 100644
--- a/tls/tests/connection.c
+++ b/tls/tests/connection.c
@@ -1067,11 +1067,26 @@ test_client_auth_connection (TestConnection *test,
   g_object_unref (cert);
 }
 
+#ifdef BACKEND_IS_GNUTLS
+static void
+run_until_object_is_destroyed (GMainContext *context,
+                               GWeakRef     *weak_ref)
+{
+  GObject *object;
+
+  while ((object = g_weak_ref_get (weak_ref)))
+    {
+      g_object_unref (object);
+      g_main_context_iteration (context, FALSE);
+    }
+}
+#endif
+
 static void
 test_client_auth_pkcs11_connection (TestConnection *test,
                                     gconstpointer   data)
 {
-#if !defined (BACKEND_IS_GNUTLS)
+#ifndef BACKEND_IS_GNUTLS
   g_test_skip ("This backend does not support PKCS #11");
 #else
   GIOStream *connection;
@@ -1081,6 +1096,7 @@ test_client_auth_pkcs11_connection (TestConnection *test,
   gboolean cas_changed;
   GSocketClient *client;
   GTlsInteraction *interaction;
+  GWeakRef weak_ref;
 
   test->database = g_tls_file_database_new (tls_test_file_path ("ca-roots.pem"), &error);
   g_assert_no_error (error);
@@ -1094,6 +1110,8 @@ test_client_auth_pkcs11_connection (TestConnection *test,
   g_assert_nonnull (test->client_connection);
   g_object_unref (connection);
 
+  g_weak_ref_init (&weak_ref, test->client_connection);
+
   g_tls_connection_set_interaction (G_TLS_CONNECTION (test->client_connection), interaction);
   g_tls_connection_set_database (G_TLS_CONNECTION (test->client_connection), test->database);
 
@@ -1128,6 +1146,13 @@ test_client_auth_pkcs11_connection (TestConnection *test,
   g_object_unref (test->client_connection);
   g_clear_object (&test->server_connection);
 
+  /* The mock PKCS#11 module allows only a single PKCS#11 connection at a time.
+   * This means we have to ensure the original GTlsClientConnection is finalized
+   * before creating the next one.
+   */
+  run_until_object_is_destroyed (test->context, &weak_ref);
+  g_weak_ref_clear (&weak_ref);
+
   /* Now start a new connection to the same server with a different client cert.
    * Also test using a single URI matching both the cert and private key.
    */


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]