LCOV - code coverage report
Current view: top level - src/tds/unittests - log_elision.c (source / functions) Hit Total Coverage
Test: FreeTDS coverage Lines: 48 48 100.0 %
Date: 2025-04-22 17:15:43 Functions: 2 2 100.0 %

          Line data    Source code
       1             : /* FreeTDS - Library of routines accessing Sybase and Microsoft databases
       2             :  * Copyright (C) 2021  Frediano Ziglio
       3             :  *
       4             :  * This library is free software; you can redistribute it and/or
       5             :  * modify it under the terms of the GNU Library General Public
       6             :  * License as published by the Free Software Foundation; either
       7             :  * version 2 of the License, or (at your option) any later version.
       8             :  *
       9             :  * This library is distributed in the hope that it will be useful,
      10             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      11             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      12             :  * Library General Public License for more details.
      13             :  *
      14             :  * You should have received a copy of the GNU Library General Public
      15             :  * License along with this library; if not, write to the
      16             :  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
      17             :  * Boston, MA 02111-1307, USA.
      18             :  */
      19             : 
      20             : /*
      21             :  * Check log elision implementation
      22             :  */
      23             : #include "common.h"
      24             : #include <assert.h>
      25             : #include <freetds/utils.h>
      26             : 
      27             : #if HAVE_UNISTD_H
      28             : #undef getpid
      29             : #include <unistd.h>
      30             : #endif /* HAVE_UNISTD_H */
      31             : 
      32             : #ifdef TDS_HAVE_MUTEX
      33             : enum {
      34             :         LOOP = 100,
      35             :         THREADS = 3,
      36             : };
      37             : 
      38          30 : static TDS_THREAD_PROC_DECLARE(log_func, idx_ptr)
      39             : {
      40          30 :         const int idx = TDS_PTR2INT(idx_ptr);
      41          30 :         const char letter = 'A' + idx;
      42             :         TDSDUMP_OFF_ITEM off_item;
      43          30 :         int n = idx, i;
      44             : 
      45             :         /* LOOP times */
      46        3030 :         for (i = 0; i < LOOP; ++i) {
      47             :                 /* send log */
      48        3000 :                 tdsdump_log(TDS_DBG_ERROR, "Some log from %c number %d\n", letter, n);
      49             : 
      50             :                 /* wait 1-10 ms */
      51        3000 :                 tds_sleep_ms((rand() % 10) + 1);
      52             : 
      53             :                 /* disable logs */
      54        3000 :                 tdsdump_off(&off_item);
      55             : 
      56             :                 /* send wrong log */
      57        3000 :                 tdsdump_log(TDS_DBG_ERROR, "Disabled log %c number %d\n", letter, n);
      58             : 
      59             :                 /* wait 1-10 ms */
      60        3000 :                 tds_sleep_ms((rand() % 10) + 1);
      61             : 
      62             :                 /* enable logs */
      63        3000 :                 tdsdump_on(&off_item);
      64             : 
      65        3000 :                 n += 3;
      66             :         }
      67             : 
      68          30 :         return TDS_THREAD_RESULT(0);
      69             : }
      70             : 
      71          10 : TEST_MAIN()
      72             : {
      73             :         int i, ret;
      74             :         tds_thread threads[THREADS];
      75             :         FILE *f;
      76             :         char line[1024];
      77          10 :         int wrong_lines = 0;
      78             :         int nexts[THREADS];
      79             : 
      80          10 :         tds_debug_flags = TDS_DBGFLAG_ALL | TDS_DBGFLAG_SOURCE;
      81             : 
      82             :         /* remove file */
      83          10 :         unlink("log_elision.out");
      84             : 
      85             :         /* set output file */
      86          10 :         tdsdump_open(TDS_DIR("log_elision.out"));
      87             : 
      88             :         /* THREADS thread */
      89          40 :         for (i = 0; i < THREADS; ++i) {
      90          30 :                 nexts[i] = i;
      91             :         }
      92          20 :         for (i = 1; i < THREADS; ++i) {
      93          40 :                 ret = tds_thread_create(&threads[i], log_func, TDS_INT2PTR(i));
      94          20 :                 assert(ret == 0);
      95             :         }
      96          10 :         log_func(TDS_INT2PTR(0));
      97          30 :         for (i = 1; i < THREADS; ++i) {
      98          40 :                 ret = tds_thread_join(threads[i], NULL);
      99          20 :                 assert(ret == 0);
     100             :         }
     101             : 
     102             :         /* close logs */
     103          10 :         tdsdump_close();
     104             : 
     105             :         /* open logs to read */
     106          10 :         f = fopen("log_elision.out", "r");
     107          10 :         assert(f != NULL);
     108             : 
     109             :         /* read line by line */
     110        3030 :         while (fgets(line, sizeof(line), f) != NULL) {
     111             :                 char thread_letter;
     112             :                 int num, idx;
     113             :                 char *start;
     114             : 
     115             :                 /* ignore some start lines */
     116        3020 :                 if (strstr(line, "log_elision.c") == NULL) {
     117          20 :                         assert(++wrong_lines < 4);
     118          20 :                         continue;
     119             :                 }
     120             : 
     121        3000 :                 start = strstr(line, ":Some log from");
     122        3000 :                 assert(start != NULL);
     123             : 
     124        3000 :                 ret = sscanf(start, ":Some log from %c number %d\n",
     125             :                              &thread_letter, &num);
     126        3000 :                 assert(ret == 2);
     127             : 
     128             :                 /* detect number of thread */
     129        3000 :                 assert(thread_letter >= 'A' && thread_letter < 'A' + THREADS);
     130        3000 :                 idx = thread_letter - 'A';
     131             : 
     132             :                 /* check number inside string match the next */
     133        3000 :                 assert(num == nexts[idx]);
     134        3000 :                 nexts[idx] += 3;
     135             :         }
     136          10 :         fclose(f);
     137          10 :         f = NULL;
     138             : 
     139             :         /* check we got all numbers */
     140          40 :         for (i = 0; i < THREADS; ++i) {
     141          30 :                 assert(nexts[i] == i + LOOP * 3);
     142             :         }
     143             : 
     144             :         /* cleanup file */
     145          10 :         unlink("log_elision.out");
     146             : 
     147          10 :         return 0;
     148             : }
     149             : #else   /* !TDS_HAVE_MUTEX */
     150             : TEST_MAIN()
     151             : {
     152             :         printf("Not possible for this platform.\n");
     153             :         return 0; /* TODO 77 ? */
     154             : }
     155             : #endif

Generated by: LCOV version 1.13