LCOV - code coverage report
Current view: top level - tools/mserver - shutdowntest.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 92 163 56.4 %
Date: 2021-10-13 02:24:04 Functions: 6 6 100.0 %

          Line data    Source code
       1             : /*
       2             :  * This Source Code Form is subject to the terms of the Mozilla Public
       3             :  * License, v. 2.0.  If a copy of the MPL was not distributed with this
       4             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       5             :  *
       6             :  * Copyright 1997 - July 2008 CWI, August 2008 - 2021 MonetDB B.V.
       7             :  */
       8             : 
       9             : #include "monetdb_config.h"
      10             : #include <string.h> /* strerror */
      11             : #include <locale.h>
      12             : #include "monet_options.h"
      13             : #include "mal.h"
      14             : #include "mal_session.h"
      15             : #include "mal_import.h"
      16             : #include "mal_client.h"
      17             : #include "mal_function.h"
      18             : #include "mal_authorize.h"
      19             : #include "msabaoth.h"
      20             : #include "mutils.h"
      21             : #include "mal_linker.h"
      22             : #include "sql_execute.h"
      23             : #include "sql_scenario.h"
      24             : 
      25             : static char* dbdir = NULL;
      26             : 
      27             : static int monetdb_initialized = 0;
      28             : 
      29          22 : static void* monetdb_connect(void) {
      30             :         Client conn = NULL;
      31          22 :         if (!monetdb_initialized) {
      32             :                 return NULL;
      33             :         }
      34          22 :         conn = MCinitClient(MAL_ADMIN, bstream_create(GDKstdin, 0), GDKstdout);
      35          22 :         if (!MCvalid(conn)) {
      36             :                 return NULL;
      37             :         }
      38          22 :         conn->curmodule = conn->usermodule = userModule();
      39             :         str msg;
      40          22 :         if ((msg = SQLinitClient(conn)) != MAL_SUCCEED) {
      41           0 :                 freeException(msg);
      42           0 :                 return NULL;
      43             :         }
      44          22 :         ((backend *) conn->sqlcontext)->mvc->session->auto_commit = 1;
      45          22 :         return conn;
      46             : }
      47             : 
      48          53 : static str monetdb_query(Client c, str query) {
      49             :         str retval;
      50          53 :         mvc* m = ((backend *) c->sqlcontext)->mvc;
      51          53 :         res_table* res = NULL;
      52             : 
      53          53 :         retval = SQLstatementIntern(c, query, "name", 1, 0, &res);
      54          53 :         if (retval == MAL_SUCCEED)
      55          53 :                 retval = SQLautocommit(m);
      56          53 :         if (retval != MAL_SUCCEED) {
      57           0 :                 printf("Failed to execute SQL query: %s\n", query);
      58           0 :                 freeException(retval);
      59           0 :                 exit(1);
      60             :                 return MAL_SUCCEED;
      61             :         }
      62          53 :         if (res) {
      63             :                 // print result columns
      64             : //              printf("%s (", res->cols->tn);
      65             : //              for(int i = 0; i < res->nr_cols; i++) {
      66             : //                      printf("%s", res->cols[i].name);
      67             : //                      printf(i + 1 == res->nr_cols ? ")\n" : ",");
      68             : //              }
      69          21 :                 SQLdestroyResult(res);
      70             :         }
      71             :         return MAL_SUCCEED;
      72             : }
      73             : 
      74          22 : static void monetdb_disconnect(void* conn) {
      75          22 :         if (!MCvalid((Client) conn)) {
      76             :                 return;
      77             :         }
      78          22 :         str msg = SQLexitClient((Client) conn);
      79          22 :         freeException(msg);
      80          22 :         MCcloseClient((Client) conn);
      81             : }
      82             : 
      83          11 : static str monetdb_initialize(void) {
      84          11 :         opt *set = NULL;
      85          11 :         volatile int setlen = 0; /* use volatile for setjmp */
      86             :         str retval = MAL_SUCCEED;
      87             :         char *err;
      88             :         char prmodpath[FILENAME_MAX];
      89             :         const char *modpath = NULL;
      90             :         char *binpath = NULL;
      91             : 
      92          11 :         if (monetdb_initialized) return MAL_SUCCEED;
      93          11 :         monetdb_initialized = 1;
      94             : 
      95          11 :         if (setlocale(LC_CTYPE, "") == NULL) {
      96           0 :                 retval = GDKstrdup("setlocale() failed");
      97           0 :                 goto cleanup;
      98             :         }
      99             : 
     100          11 :         GDKfataljumpenable = 1;
     101          11 :         if(setjmp(GDKfataljump) != 0) {
     102           0 :                 retval = GDKfatalmsg;
     103             :                 // we will get here if GDKfatal was called.
     104           0 :                 if (retval == NULL) {
     105           0 :                         retval = GDKstrdup("GDKfatal() with unspecified error?");
     106             :                 }
     107           0 :                 goto cleanup;
     108             :         }
     109             : 
     110          11 :         binpath = get_bin_path();
     111             : 
     112          11 :         setlen = mo_builtin_settings(&set);
     113          11 :         setlen = mo_add_option(&set, setlen, opt_cmdline, "gdk_dbpath", dbdir);
     114             : 
     115          11 :         if (BBPaddfarm(dbdir, (1U << PERSISTENT) | (1U << TRANSIENT), false) != GDK_SUCCEED) {
     116           0 :                 retval = GDKstrdup("BBPaddfarm failed");
     117           0 :                 goto cleanup;
     118             :         }
     119          11 :         if (GDKinit(set, setlen, true) != GDK_SUCCEED) {
     120           0 :                 retval = GDKstrdup("GDKinit() failed");
     121           0 :                 goto cleanup;
     122             :         }
     123          11 :         GDKdebug |= NOSYNCMASK;
     124             : 
     125          11 :         if (GDKsetenv("mapi_disable", "true") != GDK_SUCCEED) {
     126           0 :                 retval = GDKstrdup("GDKsetenv failed");
     127           0 :                 goto cleanup;
     128             :         }
     129             : 
     130          11 :         if ((modpath = GDKgetenv("monet_mod_path")) == NULL) {
     131             :                 /* start probing based on some heuristics given the binary
     132             :                  * location:
     133             :                  * bin/mserver5 -> ../
     134             :                  * libX/monetdb5/lib/
     135             :                  * probe libX = lib, lib32, lib64, lib/64 */
     136          11 :                 char *libdirs[] = { "lib", "lib64", "lib/64", "lib32", NULL };
     137             :                 size_t i;
     138             :                 struct stat sb;
     139          11 :                 if (binpath != NULL) {
     140          11 :                         char *p = strrchr(binpath, DIR_SEP);
     141          11 :                         if (p != NULL)
     142          11 :                                 *p = '\0';
     143          11 :                         p = strrchr(binpath, DIR_SEP);
     144          11 :                         if (p != NULL) {
     145          11 :                                 *p = '\0';
     146          22 :                                 for (i = 0; libdirs[i] != NULL; i++) {
     147          22 :                                         int len = snprintf(prmodpath, sizeof(prmodpath), "%s%c%s%cmonetdb5",
     148             :                                                         binpath, DIR_SEP, libdirs[i], DIR_SEP);
     149          22 :                                         if (len == -1 || len >= FILENAME_MAX)
     150           0 :                                                 continue;
     151          22 :                                         if (MT_stat(prmodpath, &sb) == 0) {
     152             :                                                 modpath = prmodpath;
     153             :                                                 break;
     154             :                                         }
     155             :                                 }
     156             :                         } else {
     157           0 :                                 printf("#warning: unusable binary location, "
     158             :                                            "please use --set monet_mod_path=/path/to/... to "
     159             :                                            "allow finding modules\n");
     160           0 :                                 fflush(NULL);
     161             :                         }
     162             :                 } else {
     163           0 :                         printf("#warning: unable to determine binary location, "
     164             :                                    "please use --set monet_mod_path=/path/to/... to "
     165             :                                    "allow finding modules\n");
     166           0 :                         fflush(NULL);
     167             :                 }
     168          22 :                 if (modpath != NULL &&
     169          11 :                     GDKsetenv("monet_mod_path", modpath) != GDK_SUCCEED) {
     170           0 :                         retval = GDKstrdup("GDKsetenv failed");
     171           0 :                         goto cleanup;
     172             :                 }
     173             :         }
     174             : 
     175             :         /* configure sabaoth to use the right dbpath and active database */
     176          11 :         msab_dbpathinit(GDKgetenv("gdk_dbpath"));
     177             :         /* wipe out all cruft, if left over */
     178          11 :         if ((retval = msab_wildRetreat()) != NULL) {
     179             :                 /* just swallow the error */
     180           0 :                 free(retval);
     181             :         }
     182             :         /* From this point, the server should exit cleanly.  Discussion:
     183             :          * even earlier?  Sabaoth here registers the server is starting up. */
     184          11 :         if ((retval = msab_registerStarting()) != NULL) {
     185             :                 /* throw the error at the user, but don't die */
     186           0 :                 fprintf(stderr, "!%s\n", retval);
     187           0 :                 free(retval);
     188             :         }
     189             : 
     190             :         {
     191             :                 str lang = "mal";
     192             :                 /* we inited mal before, so publish its existence */
     193          11 :                 if ((retval = msab_marchScenario(lang)) != NULL) {
     194             :                         /* throw the error at the user, but don't die */
     195           0 :                         fprintf(stderr, "!%s\n", retval);
     196           0 :                         free(retval);
     197             :                 }
     198             :         }
     199             : 
     200             :         {
     201             :                 /* unlock the vault, first see if we can find the file which
     202             :                  * holds the secret */
     203             :                 char secret[1024];
     204             :                 char *secretp = secret;
     205             :                 FILE *secretf;
     206             :                 size_t len;
     207             : 
     208          11 :                 if (GDKgetenv("monet_vault_key") == NULL) {
     209             :                         /* use a default (hard coded, non safe) key */
     210          11 :                         snprintf(secret, sizeof(secret), "%s", "Xas632jsi2whjds8");
     211             :                 } else {
     212           0 :                         if ((secretf = fopen(GDKgetenv("monet_vault_key"), "r")) == NULL) {
     213           0 :                                 fprintf(stderr,
     214             :                                         "unable to open vault_key_file %s: %s\n",
     215           0 :                                         GDKgetenv("monet_vault_key"), strerror(errno));
     216             :                                 /* don't show this as a crash */
     217           0 :                                 err = msab_registerStop();
     218           0 :                                 if (err)
     219           0 :                                         free(err);
     220           0 :                                 exit(1);
     221             :                         }
     222           0 :                         len = fread(secret, 1, sizeof(secret), secretf);
     223           0 :                         secret[len] = '\0';
     224           0 :                         len = strlen(secret); /* secret can contain null-bytes */
     225           0 :                         if (len == 0) {
     226           0 :                                 fprintf(stderr, "vault key has zero-length!\n");
     227             :                                 /* don't show this as a crash */
     228           0 :                                 err = msab_registerStop();
     229           0 :                                 if (err)
     230           0 :                                         free(err);
     231           0 :                                 exit(1);
     232           0 :                         } else if (len < 5) {
     233           0 :                                 fprintf(stderr, "#warning: your vault key is too short "
     234             :                                                                 "(%zu), enlarge your vault key!\n", len);
     235             :                         }
     236           0 :                         fclose(secretf);
     237             :                 }
     238          11 :                 if ((retval = AUTHunlockVault(secretp)) != MAL_SUCCEED) {
     239             :                         /* don't show this as a crash */
     240           0 :                         err = msab_registerStop();
     241           0 :                         if (err)
     242           0 :                                 free(err);
     243           0 :                         fprintf(stderr, "%s\n", retval);
     244           0 :                         exit(1);
     245             :                 }
     246             :         }
     247             :         /* make sure the authorisation BATs are loaded */
     248          11 :         if ((retval = AUTHinitTables(NULL)) != MAL_SUCCEED) {
     249             :                 /* don't show this as a crash */
     250           0 :                 err = msab_registerStop();
     251           0 :                 if (err)
     252           0 :                         free(err);
     253           0 :                 fprintf(stderr, "%s\n", retval);
     254           0 :                 exit(1);
     255             :         }
     256             : 
     257             :         char *modules[2];
     258          11 :         modules[0] = "sql";
     259          11 :         modules[1] = 0;
     260          11 :         if (mal_init(modules, 1) != 0) { // mal_init() does not return meaningful codes on failure
     261           0 :                 retval = GDKstrdup("mal_init() failed");
     262           0 :                 goto cleanup;
     263             :         }
     264          11 :         GDKfataljumpenable = 0;
     265             : 
     266             :         if (retval != MAL_SUCCEED) {
     267             :                 printf("Failed to load SQL function: %s\n", retval);
     268             :                 retval = GDKstrdup(retval);
     269             :                 goto cleanup;
     270             :         }
     271             : 
     272             :         {
     273          11 :                 Client c = (Client) monetdb_connect();
     274             :                 char* query = "SELECT * FROM tables;";
     275          11 :                 retval = monetdb_query(c, query);
     276          11 :                 monetdb_disconnect(c);
     277             :         }
     278             : 
     279          11 :         mo_free_options(set, setlen);
     280             : 
     281             :         return MAL_SUCCEED;
     282           0 : cleanup:
     283           0 :         if (set)
     284           0 :                 mo_free_options(set, setlen);
     285           0 :         monetdb_initialized = 0;
     286           0 :         return retval;
     287             : }
     288             : 
     289          10 : static void monetdb_shutdown(void) {
     290          10 :         if (monetdb_initialized) {
     291          10 :                 mal_reset();
     292          10 :                 monetdb_initialized = 0;
     293             :         }
     294          10 : }
     295             : 
     296           1 : int main(int argc, char **argv) {
     297             :         str retval;
     298             :         Client c;
     299             :         int i = 0;
     300           1 :         if (argc <= 1) {
     301           0 :                 printf("Usage: shutdowntest [testdir]\n");
     302           0 :                 return -1;
     303             :         }
     304           1 :         dbdir = argv[1];
     305             : 
     306           1 :         retval = monetdb_initialize();
     307           1 :         if (retval != MAL_SUCCEED) {
     308           0 :                 printf("Failed first initialization: %s\n", retval);
     309           0 :                 return -1;
     310             :         }
     311           1 :         c = (Client) monetdb_connect();
     312           1 :         monetdb_query(c, "CREATE TABLE temporary_table(i INTEGER);");
     313           1 :         monetdb_query(c, "INSERT INTO temporary_table VALUES (3), (4);");
     314           1 :         monetdb_disconnect(c);
     315             : //      printf("Successfully initialized MonetDB.\n");
     316          11 :         for(i = 0; i < 10; i++) {
     317          10 :                 monetdb_shutdown();
     318             : //              printf("Successfully shutdown MonetDB.\n");
     319          10 :                 retval = monetdb_initialize();
     320          10 :                 if (retval != MAL_SUCCEED) {
     321           0 :                         printf("Failed MonetDB restart: %s\n", retval);
     322           0 :                         return -1;
     323             :                 }
     324             : //              printf("Successfully restarted MonetDB.\n");
     325          10 :                 c = (Client) monetdb_connect();
     326          10 :                 monetdb_query(c, "SELECT * FROM temporary_table;");
     327          10 :                 monetdb_query(c, "DROP TABLE temporary_table;");
     328          10 :                 monetdb_query(c, "CREATE TABLE temporary_table(i INTEGER);");
     329          10 :                 monetdb_query(c, "INSERT INTO temporary_table VALUES (3), (4);");
     330          10 :                 monetdb_disconnect(c);
     331             :         }
     332             :         return 0;
     333             : }

Generated by: LCOV version 1.14