LCOV - code coverage report
Current view: top level - src/tds/unittests - log_elision.c (source / functions) Hit Total Coverage
Test: FreeTDS coverage Lines: 45 45 100.0 %
Date: 2025-01-18 11:50:39 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             : enum {
      33             :         LOOP = 100,
      34             :         THREADS = 3,
      35             : };
      36             : 
      37          24 : static TDS_THREAD_PROC_DECLARE(log_func, idx_ptr)
      38             : {
      39          24 :         const int idx = TDS_PTR2INT(idx_ptr);
      40          24 :         const char letter = 'A' + idx;
      41             :         TDSDUMP_OFF_ITEM off_item;
      42          24 :         int n = idx, i;
      43             : 
      44             :         /* LOOP times */
      45        2424 :         for (i = 0; i < LOOP; ++i) {
      46             :                 /* send log */
      47        2400 :                 tdsdump_log(TDS_DBG_ERROR, "Some log from %c number %d\n", letter, n);
      48             : 
      49             :                 /* wait 1-10 ms */
      50        2400 :                 tds_sleep_ms((rand() % 10) + 1);
      51             : 
      52             :                 /* disable logs */
      53        2400 :                 tdsdump_off(&off_item);
      54             : 
      55             :                 /* send wrong log */
      56        2400 :                 tdsdump_log(TDS_DBG_ERROR, "Disabled log %c number %d\n", letter, n);
      57             : 
      58             :                 /* wait 1-10 ms */
      59        2400 :                 tds_sleep_ms((rand() % 10) + 1);
      60             : 
      61             :                 /* enable logs */
      62        2400 :                 tdsdump_on(&off_item);
      63             : 
      64        2400 :                 n += 3;
      65             :         }
      66             : 
      67          24 :         return TDS_THREAD_RESULT(0);
      68             : }
      69             : 
      70             : int
      71           8 : main(void)
      72             : {
      73             :         int i, ret;
      74             :         tds_thread threads[THREADS];
      75             :         FILE *f;
      76             :         char line[1024];
      77           8 :         int wrong_lines = 0;
      78             :         int nexts[THREADS];
      79             : 
      80           8 :         tds_debug_flags = TDS_DBGFLAG_ALL | TDS_DBGFLAG_SOURCE;
      81             : 
      82             :         /* remove file */
      83           8 :         unlink("log_elision.out");
      84             : 
      85             :         /* set output file */
      86           8 :         tdsdump_open(TDS_DIR("log_elision.out"));
      87             : 
      88             :         /* THREADS thread */
      89          32 :         for (i = 0; i < THREADS; ++i) {
      90          24 :                 nexts[i] = i;
      91             :         }
      92          16 :         for (i = 1; i < THREADS; ++i) {
      93          32 :                 ret = tds_thread_create(&threads[i], log_func, TDS_INT2PTR(i));
      94          16 :                 assert(ret == 0);
      95             :         }
      96           8 :         log_func(TDS_INT2PTR(0));
      97          24 :         for (i = 1; i < THREADS; ++i) {
      98          32 :                 ret = tds_thread_join(threads[i], NULL);
      99          16 :                 assert(ret == 0);
     100             :         }
     101             : 
     102             :         /* close logs */
     103           8 :         tdsdump_close();
     104             : 
     105             :         /* open logs to read */
     106           8 :         f = fopen("log_elision.out", "r");
     107           8 :         assert(f != NULL);
     108             : 
     109             :         /* read line by line */
     110        2424 :         while (fgets(line, sizeof(line), f) != NULL) {
     111             :                 char thread_letter;
     112             :                 int num_line, num, idx;
     113             : 
     114             :                 /* ignore some start lines */
     115        2416 :                 if (strstr(line, "log_elision.c") == NULL) {
     116          16 :                         assert(++wrong_lines < 4);
     117          16 :                         continue;
     118             :                 }
     119             : 
     120        2400 :                 ret = sscanf(line, "log_elision.c:%d:Some log from %c number %d\n",
     121             :                              &num_line, &thread_letter, &num);
     122        2400 :                 assert(ret == 3);
     123             : 
     124             :                 /* detect number of thread */
     125        2400 :                 assert(thread_letter >= 'A' && thread_letter < 'A' + THREADS);
     126        2400 :                 idx = thread_letter - 'A';
     127             : 
     128             :                 /* check number inside string match the next */
     129        2400 :                 assert(num == nexts[idx]);
     130        2400 :                 nexts[idx] += 3;
     131             :         }
     132           8 :         fclose(f);
     133           8 :         f = NULL;
     134             : 
     135             :         /* check we got all numbers */
     136          32 :         for (i = 0; i < THREADS; ++i) {
     137          24 :                 assert(nexts[i] == i + LOOP * 3);
     138             :         }
     139             : 
     140             :         /* cleanup file */
     141           8 :         unlink("log_elision.out");
     142             : 
     143             :         return 0;
     144             : }

Generated by: LCOV version 1.13