[libgda: 1/6] Test: Using unique database names for PostgreSQL




commit ee9020677eb4cf63b5923b0c3e3cb9eedfe45f65
Author: Pavlo Solntsev <p sun fun gmail com>
Date:   Sun Aug 16 23:58:24 2020 -0500

    Test: Using unique database names for PostgreSQL
    
    To avoid conflict between tests we need to use a unique database name
    every time the test starts.
    
    Some minor corrections to improve code quality were also added.

 .gitlab-ci.yml                                 |   8 +-
 tests/meta-store/check_meta_store_postgresql.c |  58 ++++++++-----
 tests/meta-store/common.c                      | 113 ++++++++++++++++++++++---
 tests/meta-store/common.h                      |   2 +-
 4 files changed, 142 insertions(+), 39 deletions(-)
---
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index a6c8fa537..2513e2660 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -15,7 +15,6 @@ stages:
   - deploy_doc
 
 variables:
-  POSTGRES_DB: test
   POSTGRES_USER: test
   POSTGRES_PASSWORD: test1
   POSTGRES_HOST: postgres
@@ -56,8 +55,8 @@ variables:
   SQLITE_DBCREATE_PARAMS: "DB_DIR=."
   SQLITE_CNC_PARAMS: "DB_DIR=."
   POSTGRESQL_DBCREATE_PARAMS: "HOST=$POSTGRES_HOST;ADM_LOGIN=$POSTGRES_USER;ADM_PASSWORD=$POSTGRES_PASSWORD"
-  POSTGRESQL_CNC_PARAMS: 
"HOST=$POSTGRES_HOST;USERNAME=$POSTGRES_USER;PASSWORD=$POSTGRES_PASSWORD;DB_NAME=$POSTGRES_DB"
-  POSTGRESQL_META_CNC: 
"DB_NAME=$POSTGRES_DB;HOST=$POSTGRES_HOST;USERNAME=$POSTGRES_USER;PASSWORD=$POSTGRES_PASSWORD"
+  POSTGRESQL_CNC_PARAMS: "HOST=$POSTGRES_HOST;USERNAME=$POSTGRES_USER;PASSWORD=$POSTGRES_PASSWORD"
+  POSTGRESQL_META_CNC: "HOST=$POSTGRES_HOST;USERNAME=$POSTGRES_USER;PASSWORD=$POSTGRES_PASSWORD"
   MYSQL_CNC_PARAMS: 
"DB_NAME=$MYSQL_DATABASE;HOST=$MYSQL_HOST;USERNAME=$MYSQL_USER;PASSWORD=$MYSQL_ROOT_PASSWORD"
   MYSQL_META_CNC: 
"DB_NAME=$MYSQL_DATABASE;HOST=$MYSQL_HOST;USERNAME=$MYSQL_USER;PASSWORD=$MYSQL_ROOT_PASSWORD"
   SQLITE_SO_DDL: "DB_DIR=.;DB_NAME=ci_test_db.db"
@@ -70,12 +69,11 @@ library_build:
   stage: build
   script:
   - export PGPASSWORD=$POSTGRES_PASSWORD
-  - psql -h "postgres" -U "$POSTGRES_USER" -d "$POSTGRES_DB" -c "SELECT 'OK' AS status;"
   - meson --prefix=/usr --buildtype=debug -Dgtk_doc=true --werror _build
   - cd _build
   - ninja
   - broadwayd &
-  - GDK_BACKEND=broadway meson test
+  - GDK_BACKEND=broadway ninja test
   - ninja install
   artifacts:
     when: on_failure
diff --git a/tests/meta-store/check_meta_store_postgresql.c b/tests/meta-store/check_meta_store_postgresql.c
index dc9061a80..e0e5e05c0 100644
--- a/tests/meta-store/check_meta_store_postgresql.c
+++ b/tests/meta-store/check_meta_store_postgresql.c
@@ -21,44 +21,64 @@
 #include <glib/gstdio.h>
 #include "common.h"
 
+extern gchar *dbname;
+
 int 
 main(G_GNUC_UNUSED int argc, G_GNUC_UNUSED char ** argv)
 {
        GdaConnection *cnc;
        GdaMetaStore *store;
-       gchar *cnc_string = NULL;
+       const gchar *cnc_string = NULL;
        GError *error = NULL;
        gboolean db_created = FALSE;
+       const gchar *dbcreate_params = NULL;
 
        gda_init ();
 
        /*cnc_string = "DB_NAME=test;HOST=localhost;USERNAME=test;PASSWORD=test1";*/
-       cnc_string = getenv ("POSTGRESQL_META_CNC");
+
+       cnc_string = g_getenv ("POSTGRESQL_META_CNC");
        if (!cnc_string)
        {
                g_print ("PostgreSQL test not run, please set the POSTGRESQL_META_CNC environment variable \n"
                                "For example 
'DB_NAME=$POSTGRES_DB;HOST=postgres;USERNAME=$POSTGRES_USER;PASSWORD=$POSTGRES_PASSWORD'\n");
                return EXIT_SUCCESS;
        }
+
+       dbcreate_params = g_getenv ("POSTGRESQL_DBCREATE_PARAMS");
+
+       if (!dbcreate_params)
+       {
+               g_print ("PostgreSQL test not run, please set the POSTGRESQL_DBCREATE_PARAMS environment 
variable \n");
+               return EXIT_SUCCESS;
+       }
+
+       db_created = test_setup("PostgreSQL", dbcreate_params);
+
+       if (!db_created) {
+               g_print ("Can't setup database\n");
+               return EXIT_FAILURE;
+       }
+// Append database name to the connection string
+       GString *new_cnc_string = g_string_new(cnc_string);
+       g_string_append_printf (new_cnc_string, ";DB_NAME=%s", dbname);
+
+       g_print ("Connection string: %s\n", new_cnc_string->str);
        /* connection try */
-       cnc = gda_connection_open_from_string ("PostgreSQL", cnc_string, NULL, GDA_CONNECTION_OPTIONS_NONE, 
&error);
-       if (cnc == NULL) {
-               // Try creating the database first
-               test_setup ("PostgreSQL");
-               g_clear_error (&error);
-               cnc = gda_connection_open_from_string ("PostgreSQL", cnc_string, NULL, 
GDA_CONNECTION_OPTIONS_NONE, &error);
-               if (cnc == NULL) {
-                       g_warning ("Connection no established. Error: %s\n",
-                                  error && error->message ? error->message : "No error was set");
-                       g_clear_error (&error);
-                       return EXIT_FAILURE;
-               }
-               db_created = TRUE;
+       cnc = gda_connection_open_from_string ("PostgreSQL", new_cnc_string->str, NULL, 
GDA_CONNECTION_OPTIONS_NONE, &error);
+
+
+       if (!cnc) {
+           g_warning ("Connection no established. Error: %s\n",
+                      error && error->message ? error->message : "No error was set");
+           g_clear_error (&error);
+           return EXIT_FAILURE;
        }
-       g_object_unref (cnc);
+
        /* Clean everything which might exist in the store */
        gchar *str;
-       str = g_strdup_printf ("PostgreSQL://%s", cnc_string);
+       str = g_strdup_printf ("PostgreSQL://%s", new_cnc_string->str);
+       g_string_free (new_cnc_string, TRUE);
        store = gda_meta_store_new (str);
        common_drop_all_tables (store);
        g_object_unref (store);
@@ -69,7 +89,6 @@ main(G_GNUC_UNUSED int argc, G_GNUC_UNUSED char ** argv)
 
        g_print ("STORE: %p, version: %d\n", store, store ? gda_meta_store_get_version (store) : 0);
 
-
        /* Tests */
        tests_group_1 (store);
        g_object_unref (store);
@@ -77,8 +96,9 @@ main(G_GNUC_UNUSED int argc, G_GNUC_UNUSED char ** argv)
                test_finish (cnc);
        }
 
-       g_print ("Test Ok.\n");
+       g_object_unref (cnc);
 
+       g_print ("Test OK.\n");
        return EXIT_SUCCESS;
 }
 
diff --git a/tests/meta-store/common.c b/tests/meta-store/common.c
index 29d0b96d1..b44139852 100644
--- a/tests/meta-store/common.c
+++ b/tests/meta-store/common.c
@@ -25,7 +25,8 @@ GSList *expected_changes;
 
 static void meta_changed_cb (GdaMetaStore *store, GSList *changes, gpointer data);
 static GError *suggest_update_cb (GdaMetaStore *store, GdaMetaContext *context, gpointer data);
-
+gchar *dbname = NULL;
+static GdaQuarkList *quark_list = NULL;
 /*
  * Declare a GdaMetaStore to test
  */
@@ -751,23 +752,70 @@ test_parameters (GdaMetaStore *store)
 }
 
 gboolean
-test_setup (const gchar *prov_id) {
+test_setup (const gchar *prov_id, const gchar *dbcreate_str) {
        GError *error = NULL;
        GdaServerOperation *opndb;
 
-       opndb = gda_server_operation_prepare_create_database (prov_id, "test", &error);
-       if (opndb == NULL) {
-               g_message ("Provider doesn't support database creation: %s",
-                          error && error->message ? error->message : "No error was set");
-               g_clear_error (&error);
-       } else {
-               if (!gda_server_operation_perform_create_database (opndb, prov_id, &error)) {
-                       g_warning ("Creating database error: %s",
-                          error && error->message ? error->message : "No error was set");
+       g_assert_null (quark_list);
+
+       quark_list = gda_quark_list_new_from_string (dbcreate_str);
+
+       /* We will use a unique name for database for every test.
+        * The format of the database name is:
+        * dbXXXXX where XXXXX is a string generated from the random int32 numbers
+        * that correspond to ASCII codes for characters a-z
+        */
+       GString *buffer = g_string_new ("db");
+
+       for (int i = 0; i < 7; ++i) {
+           gint32 character = g_random_int_range (97, 123);
+           buffer = g_string_append_c (buffer, character);
+       }
+
+       opndb = gda_server_operation_prepare_create_database (prov_id, buffer->str, &error);
+       dbname = g_string_free (buffer, FALSE);
+
+       g_assert_nonnull (opndb);
+
+       const gchar *value = NULL;
+       gboolean res;
+       value = gda_quark_list_find (quark_list, "HOST");
+       res = gda_server_operation_set_value_at (opndb, value, NULL, "/SERVER_CNX_P/HOST");
+       g_assert_true (res);
+
+       value = gda_quark_list_find (quark_list, "ADM_LOGIN");
+       res = gda_server_operation_set_value_at (opndb, value, NULL, "/SERVER_CNX_P/ADM_LOGIN");
+       g_assert_true (res);
+
+       value = gda_quark_list_find (quark_list, "ADM_PASSWORD");
+       res = gda_server_operation_set_value_at (opndb, value, NULL, "/SERVER_CNX_P/ADM_PASSWORD");
+       g_assert_true (res);
+
+       /* This operation may fail if the template1 database is locked by other process. We need
+        * to try again short time after when template1 is available
+        */
+       res = FALSE;
+
+       for (gint i = 0; i < 100; ++i) {
+               g_print ("Attempt to create database... %d\n", i);
+               res = gda_server_operation_perform_create_database (opndb, prov_id, &error);
+               if (!res) {
                        g_clear_error (&error);
-                       return FALSE;
+                       g_usleep(1E5);
+                       continue;
+               } else {
+                       break;
                }
        }
+
+       if (!res) {
+           g_warning ("Creating database error: %s",
+                      error && error->message ? error->message : "No error was set");
+           g_clear_error (&error);
+           g_free (dbname);
+           gda_quark_list_free (quark_list);
+           return FALSE;
+       }
        return TRUE;
 }
 
@@ -778,6 +826,9 @@ test_finish (GdaConnection *cnc) {
        GdaServerOperation *opndb;
        const gchar *prov_id;
 
+       g_assert_nonnull (dbname);
+       g_assert_nonnull (quark_list);
+
        prov_id = gda_connection_get_provider_name (cnc);
 
        if (!gda_connection_close (cnc, &error)) {
@@ -787,13 +838,47 @@ test_finish (GdaConnection *cnc) {
                return 1;
        }
 
-       opndb = gda_server_operation_prepare_drop_database (prov_id, "test", &error);
+       opndb = gda_server_operation_prepare_drop_database (prov_id, dbname, &error);
+       g_free (dbname);
+
+       const gchar *value = NULL;
+       gboolean res;
+       value = gda_quark_list_find (quark_list, "HOST");
+       res = gda_server_operation_set_value_at (opndb, value, NULL, "/SERVER_CNX_P/HOST");
+       g_assert_true (res);
+
+       value = gda_quark_list_find (quark_list, "ADM_LOGIN");
+       res = gda_server_operation_set_value_at (opndb, value, NULL, "/SERVER_CNX_P/ADM_LOGIN");
+       g_assert_true (res);
+
+       value = gda_quark_list_find (quark_list, "ADM_PASSWORD");
+       res = gda_server_operation_set_value_at (opndb, value, NULL, "/SERVER_CNX_P/ADM_PASSWORD");
+       g_assert_true (res);
+
+       gda_quark_list_free (quark_list);
+
        if (opndb == NULL) {
                g_message ("Provider doesn't support database dropping: %s",
                           error && error->message ? error->message : "No error was set");
                g_clear_error (&error);
        } else {
-               if (!gda_server_operation_perform_drop_database (opndb, prov_id, &error)) {
+               res = FALSE;
+
+               for (gint i = 0; i < 100; ++i) {
+                       g_print ("Attempt to drop database... %d\n", i);
+                       G_DEBUG_HERE();
+                       res = gda_server_operation_perform_drop_database (opndb, prov_id, &error);
+                       G_DEBUG_HERE();
+                       if (!res) {
+                               g_clear_error (&error);
+                               g_usleep (1E5);
+                               continue;
+                       } else {
+                               break;
+                       }
+               }
+
+               if (!res) {
                        g_warning ("Dropping database error: %s",
                           error && error->message ? error->message : "No error was set");
                        g_clear_error (&error);
diff --git a/tests/meta-store/common.h b/tests/meta-store/common.h
index 5452ebfba..ba01cb522 100644
--- a/tests/meta-store/common.h
+++ b/tests/meta-store/common.h
@@ -47,7 +47,7 @@ void     test_parameters (GdaMetaStore *store);
 void     tests_group_1 (GdaMetaStore *store);
 void     tests_group_2 (GdaMetaStore *store);
 
-gboolean test_setup (const gchar *prov_id);
+gboolean test_setup (const gchar *prov_id, const gchar *dbcreate_str);
 gboolean test_finish (GdaConnection *cnc);
 
 #endif


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