LTP GCOV extension - code coverage report
Current view: directory - dblib/unittests - thread.c
Test: FreeTDS coverage
Date: 2008-11-21 Instrumented lines: 116
Code covered: 74.1 % Executed lines: 86

       1                 : /* 
       2                 :  * Purpose: Test dblib thread safety
       3                 :  */
       4                 : 
       5                 : #if HAVE_CONFIG_H
       6                 : #include <config.h>
       7                 : #endif /* HAVE_CONFIG_H */
       8                 : 
       9                 : #include <stdio.h>
      10                 : 
      11                 : #if HAVE_STDLIB_H
      12                 : #include <stdlib.h>
      13                 : #endif /* HAVE_STDLIB_H */
      14                 : 
      15                 : #if HAVE_STRING_H
      16                 : #include <string.h>
      17                 : #endif /* HAVE_STRING_H */
      18                 : 
      19                 : #include <sqlfront.h>
      20                 : #include <sqldb.h>
      21                 : 
      22                 : #ifdef TDS_HAVE_PTHREAD_MUTEX
      23                 : #include <unistd.h>
      24                 : #include <pthread.h>
      25                 : 
      26                 : #include "common.h"
      27                 : 
      28                 : static char software_version[] = "$Id: thread.c,v 1.6 2005/12/01 12:23:53 freddy77 Exp $";
      29                 : static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
      30                 : 
      31                 : static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
      32                 : 
      33                 : static int result = 0;
      34                 : static int thread_count = 0;
      35                 : 
      36                 : #define ROWS 20
      37                 : #define NUM_THREAD 10
      38                 : #define NUM_LOOP 100
      39                 : 
      40                 : static void
      41                 : set_failed(void)
      42               0 : {
      43               0 :         pthread_mutex_lock(&mutex);
      44               0 :         result = 1;
      45               0 :         pthread_mutex_unlock(&mutex);
      46               0 : }
      47                 : 
      48                 : static int
      49                 : test(DBPROCESS *dbproc)
      50            2000 : {
      51                 :         int i;
      52                 :         char teststr[1024];
      53                 :         DBINT testint;
      54                 : 
      55                 : 
      56                 :         /* fprintf(stdout, "select\n"); */
      57            2000 :         dbcmd(dbproc, "select * from dblib_thread order by i");
      58            2000 :         dbsqlexec(dbproc);
      59                 : 
      60            2000 :         if (dbresults(dbproc) != SUCCEED) {
      61               0 :                 fprintf(stdout, "Was expecting a result set.\n");
      62               0 :                 set_failed();
      63               0 :                 return 1;
      64                 :         }
      65                 : 
      66            2000 :         if (SUCCEED != dbbind(dbproc, 1, INTBIND, -1, (BYTE *) & testint)) {
      67               0 :                 fprintf(stderr, "Had problem with bind\n");
      68               0 :                 abort();
      69                 :         }
      70            2000 :         if (SUCCEED != dbbind(dbproc, 2, STRINGBIND, -1, (BYTE *) teststr)) {
      71               0 :                 fprintf(stderr, "Had problem with bind\n");
      72               0 :                 abort();
      73                 :         }
      74                 : 
      75           42000 :         for (i = 0; i < ROWS; i++) {
      76                 :                 char expected[64];
      77                 : 
      78           40000 :                 sprintf(expected, "row %d", i);
      79                 : 
      80           40000 :                 memset(teststr, 'x', sizeof(teststr));
      81           40000 :                 teststr[0] = 0;
      82           40000 :                 teststr[sizeof(teststr) - 1] = 0;
      83           40000 :                 if (REG_ROW != dbnextrow(dbproc)) {
      84               0 :                         fprintf(stderr, "Failed.  Expected a row\n");
      85               0 :                         set_failed();
      86               0 :                         return 1;
      87                 :                 }
      88           40000 :                 if (testint != i) {
      89               0 :                         fprintf(stderr, "Failed.  Expected i to be %d, was %d\n", i, (int) testint);
      90               0 :                         abort();
      91                 :                 }
      92           40000 :                 if (0 != strncmp(teststr, expected, strlen(expected))) {
      93               0 :                         fprintf(stdout, "Failed.  Expected s to be |%s|, was |%s|\n", expected, teststr);
      94               0 :                         abort();
      95                 :                 }
      96                 :                 /* printf("Read a row of data -> %d |%s|\n", (int) testint, teststr); */
      97                 :         }
      98                 : 
      99                 : 
     100            2000 :         if (dbnextrow(dbproc) != NO_MORE_ROWS) {
     101               0 :                 fprintf(stderr, "Was expecting no more rows\n");
     102               0 :                 set_failed();
     103               0 :                 return 1;
     104                 :         }
     105                 : 
     106            2000 :         dbcancel(dbproc);
     107                 : 
     108            2000 :         return 0;
     109                 : }
     110                 : 
     111                 : static void *
     112                 : thread_test(void * arg)
     113              20 : {
     114                 :         int i;
     115              20 :         int num = (int) arg;
     116                 :         DBPROCESS *dbproc;
     117                 :         LOGINREC *login;
     118                 : 
     119              20 :         login = dblogin();
     120              20 :         DBSETLPWD(login, PASSWORD);
     121              20 :         DBSETLUSER(login, USER);
     122              20 :         DBSETLAPP(login, "thread");
     123                 : 
     124              20 :         dbproc = dbopen(login, SERVER);
     125              20 :         if (!dbproc) {
     126               0 :                 dbloginfree(login);
     127               0 :                 fprintf(stderr, "Unable to connect to %s\n", SERVER);
     128               0 :                 set_failed();
     129               0 :                 return NULL;
     130                 :         }
     131              20 :         dbloginfree(login);
     132                 : 
     133              20 :         if (strlen(DATABASE))
     134              20 :                 dbuse(dbproc, DATABASE);
     135                 : 
     136              20 :         pthread_mutex_lock(&mutex);
     137              20 :         ++thread_count;
     138              20 :         pthread_mutex_unlock(&mutex);
     139                 : 
     140              20 :         printf("thread %2d waiting for all threads to start\n", num+1);
     141              20 :         pthread_mutex_lock(&mutex);
     142             148 :         while (thread_count < NUM_THREAD) {
     143             108 :                 pthread_mutex_unlock(&mutex);
     144             108 :                 sleep(1);
     145             108 :                 pthread_mutex_lock(&mutex);
     146                 :         }
     147              20 :         pthread_mutex_unlock(&mutex);
     148                 : 
     149            2020 :         for (i = 1; i <= NUM_LOOP; ++i) {
     150            2000 :                 printf("thread %2d of %2d loop %d\n", num+1, NUM_THREAD, i);
     151            2000 :                 if (test(dbproc) || result != 0)
     152                 :                         break;
     153                 :         }
     154                 : 
     155              20 :         dbclose(dbproc);
     156              20 :         return NULL;
     157                 : }
     158                 : 
     159                 : int
     160                 : main(int argc, char **argv)
     161               2 : {
     162                 :         int i;
     163                 :         pthread_t th[NUM_THREAD];
     164                 :         DBPROCESS *dbproc;
     165                 :         LOGINREC *login;
     166                 : 
     167               2 :         read_login_info(argc, argv);
     168                 : 
     169               2 :         fprintf(stdout, "Start\n");
     170                 : 
     171               2 :         dbinit();
     172                 : 
     173               2 :         dberrhandle(syb_err_handler);
     174               2 :         dbmsghandle(syb_msg_handler);
     175                 : 
     176               2 :         fprintf(stdout, "About to logon\n");
     177                 : 
     178               2 :         login = dblogin();
     179               2 :         DBSETLPWD(login, PASSWORD);
     180               2 :         DBSETLUSER(login, USER);
     181               2 :         DBSETLAPP(login, "thread");
     182                 : 
     183               2 :         fprintf(stdout, "About to open \"%s\"\n", SERVER);
     184                 : 
     185               2 :         dbproc = dbopen(login, SERVER);
     186               2 :         if (!dbproc) {
     187               0 :                 fprintf(stderr, "Unable to connect to %s\n", SERVER);
     188               0 :                 return 1;
     189                 :         }
     190                 : 
     191               2 :         dbloginfree(login);
     192                 : 
     193               2 :         if (strlen(DATABASE))
     194               2 :                 dbuse(dbproc, DATABASE);
     195                 : 
     196               2 :         fprintf(stdout, "Dropping table\n");
     197               2 :         dbcmd(dbproc, "drop table dblib_thread");
     198               2 :         dbsqlexec(dbproc);
     199               2 :         while (dbresults(dbproc) == SUCCEED) {
     200                 :                 /* nop */
     201                 :         }
     202                 : 
     203               2 :         fprintf(stdout, "creating table\n");
     204               2 :         dbcmd(dbproc, "create table dblib_thread (i int not null, s char(10) not null)");
     205               2 :         dbsqlexec(dbproc);
     206               4 :         while (dbresults(dbproc) == SUCCEED) {
     207                 :                 /* nop */
     208                 :         }
     209                 : 
     210               2 :         fprintf(stdout, "insert\n");
     211              42 :         for (i = 0; i < ROWS; i++) {
     212                 :                 char cmd[128];
     213                 : 
     214              40 :                 sprintf(cmd, "insert into dblib_thread values (%d, 'row %d')", i, i);
     215              40 :                 dbcmd(dbproc, cmd);
     216              40 :                 dbsqlexec(dbproc);
     217              80 :                 while (dbresults(dbproc) == SUCCEED) {
     218                 :                         /* nop */
     219                 :                 }
     220                 :         }
     221                 : 
     222              22 :         for (i = 0; i < NUM_THREAD; ++i) {
     223              20 :                 if (pthread_create(&th[i], NULL, thread_test, (void *) i) != 0)
     224                 :                 {
     225               0 :                         fprintf(stderr, "Error creating thread\n");
     226               0 :                         return 1;
     227                 :                 }
     228                 :                 /* MSSQL rejects the connections if they come in too fast */
     229              20 :                 sleep(1);
     230                 :         }
     231                 : 
     232              22 :         for (i = 0; i < NUM_THREAD; ++i) {
     233              20 :                 pthread_join(th[i], NULL);
     234              20 :                 fprintf(stdout, "thread: %d exited\n", i + 1);
     235                 :         }
     236                 : 
     237               2 :         fprintf(stdout, "Dropping table\n");
     238               2 :         dbcmd(dbproc, "drop table dblib_thread");
     239               2 :         dbsqlexec(dbproc);
     240               4 :         while (dbresults(dbproc) == SUCCEED) {
     241                 :                 /* nop */
     242                 :         }
     243                 : 
     244               2 :         dbexit();
     245                 : 
     246               2 :         return result;
     247                 : }
     248                 : 
     249                 : #else /* !TDS_HAVE_PTHREAD_MUTEX */
     250                 : 
     251                 : int
     252                 : main(int argc, char **argv)
     253                 : {
     254                 :         return 0;
     255                 : }
     256                 : #endif

Generated by: LTP GCOV extension version 1.6