(root)/
glibc-2.38/
inet/
tst-deadline.c
       1  /* Tests for computing deadlines for timeouts.
       2     Copyright (C) 2017-2023 Free Software Foundation, Inc.
       3     This file is part of the GNU C Library.
       4  
       5     The GNU C Library is free software; you can redistribute it and/or
       6     modify it under the terms of the GNU Lesser General Public
       7     License as published by the Free Software Foundation; either
       8     version 2.1 of the License, or (at your option) any later version.
       9  
      10     The GNU C Library is distributed in the hope that it will be useful,
      11     but WITHOUT ANY WARRANTY; without even the implied warranty of
      12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      13     Lesser General Public License for more details.
      14  
      15     You should have received a copy of the GNU Lesser General Public
      16     License along with the GNU C Library; if not, see
      17     <https://www.gnu.org/licenses/>.  */
      18  
      19  #include <inet/net-internal.h>
      20  #include <limits.h>
      21  #include <stdbool.h>
      22  #include <stdint.h>
      23  #include <support/check.h>
      24  
      25  /* Find the maximum value which can be represented in a time_t.  */
      26  static time_t
      27  time_t_max (void)
      28  {
      29    _Static_assert (0 > (time_t) -1, "time_t is signed");
      30    uintmax_t current = 1;
      31    while (true)
      32      {
      33        uintmax_t next = current * 2;
      34        /* This cannot happen because time_t is signed.  */
      35        TEST_VERIFY_EXIT (next > current);
      36        ++next;
      37        if ((time_t) next < 0 || next != (uintmax_t) (time_t) next)
      38          /* Value cannot be represented in time_t.  Return the previous
      39             value. */
      40          return current;
      41        current = next;
      42      }
      43  }
      44  
      45  static int
      46  do_test (void)
      47  {
      48    {
      49      struct deadline_current_time current_time = __deadline_current_time ();
      50      TEST_VERIFY (current_time.current.tv_sec >= 0);
      51      current_time = __deadline_current_time ();
      52      /* Due to CLOCK_MONOTONIC, either seconds or nanoseconds are
      53         greater than zero.  This is also true for the gettimeofday
      54         fallback.  */
      55      TEST_VERIFY (current_time.current.tv_sec >= 0);
      56      TEST_VERIFY (current_time.current.tv_sec > 0
      57                   || current_time.current.tv_nsec > 0);
      58    }
      59  
      60    /* Check basic computations of deadlines.  */
      61    struct deadline_current_time current_time = { { 1, 123456789 } };
      62    struct deadline deadline = __deadline_from_timeval
      63      (current_time, (struct timeval) { 0, 1 });
      64    TEST_VERIFY (deadline.absolute.tv_sec == 1);
      65    TEST_VERIFY (deadline.absolute.tv_nsec == 123457789);
      66    TEST_VERIFY (__deadline_to_ms (current_time, deadline) == 1);
      67  
      68    deadline = __deadline_from_timeval
      69      (current_time, ((struct timeval) { 0, 2 }));
      70    TEST_VERIFY (deadline.absolute.tv_sec == 1);
      71    TEST_VERIFY (deadline.absolute.tv_nsec == 123458789);
      72    TEST_VERIFY (__deadline_to_ms (current_time, deadline) == 1);
      73  
      74    deadline = __deadline_from_timeval
      75      (current_time, ((struct timeval) { 1, 0 }));
      76    TEST_VERIFY (deadline.absolute.tv_sec == 2);
      77    TEST_VERIFY (deadline.absolute.tv_nsec == 123456789);
      78    TEST_VERIFY (__deadline_to_ms (current_time, deadline) == 1000);
      79  
      80    /* Check if timeouts are correctly rounded up to the next
      81       millisecond.  */
      82    for (int i = 0; i < 999999; ++i)
      83      {
      84        ++current_time.current.tv_nsec;
      85        TEST_VERIFY (__deadline_to_ms (current_time, deadline) == 1000);
      86      }
      87  
      88    /* A full millisecond has elapsed, so the time to the deadline is
      89       now less than 1000.  */
      90    ++current_time.current.tv_nsec;
      91    TEST_VERIFY (__deadline_to_ms (current_time, deadline) == 999);
      92  
      93    /* Check __deadline_to_ms carry-over.  */
      94    current_time = (struct deadline_current_time) { { 9, 123456789 } };
      95    deadline = (struct deadline) { { 10, 122456789 } };
      96    TEST_VERIFY (__deadline_to_ms (current_time, deadline) == 999);
      97    deadline = (struct deadline) { { 10, 122456790 } };
      98    TEST_VERIFY (__deadline_to_ms (current_time, deadline) == 1000);
      99    deadline = (struct deadline) { { 10, 123456788 } };
     100    TEST_VERIFY (__deadline_to_ms (current_time, deadline) == 1000);
     101    deadline = (struct deadline) { { 10, 123456789 } };
     102    TEST_VERIFY (__deadline_to_ms (current_time, deadline) == 1000);
     103  
     104    /* Check __deadline_to_ms overflow.  */
     105    deadline = (struct deadline) { { INT_MAX - 1, 1 } };
     106    TEST_VERIFY (__deadline_to_ms (current_time, deadline) == INT_MAX);
     107  
     108    /* Check __deadline_to_ms for elapsed deadlines.  */
     109    current_time = (struct deadline_current_time) { { 9, 123456789 } };
     110    deadline.absolute = current_time.current;
     111    TEST_VERIFY (__deadline_to_ms (current_time, deadline) == 0);
     112    current_time = (struct deadline_current_time) { { 9, 123456790 } };
     113    TEST_VERIFY (__deadline_to_ms (current_time, deadline) == 0);
     114    current_time = (struct deadline_current_time) { { 10, 0 } };
     115    TEST_VERIFY (__deadline_to_ms (current_time, deadline) == 0);
     116    current_time = (struct deadline_current_time) { { 10, 123456788 } };
     117    TEST_VERIFY (__deadline_to_ms (current_time, deadline) == 0);
     118    current_time = (struct deadline_current_time) { { 10, 123456789 } };
     119    TEST_VERIFY (__deadline_to_ms (current_time, deadline) == 0);
     120  
     121    /* Check carry-over in __deadline_from_timeval.  */
     122    current_time = (struct deadline_current_time) { { 9, 998000001 } };
     123    for (int i = 0; i < 2000; ++i)
     124      {
     125        deadline = __deadline_from_timeval
     126          (current_time, (struct timeval) { 1, i });
     127        TEST_VERIFY (deadline.absolute.tv_sec == 10);
     128        TEST_VERIFY (deadline.absolute.tv_nsec == 998000001 + i * 1000);
     129      }
     130    for (int i = 2000; i < 3000; ++i)
     131      {
     132        deadline = __deadline_from_timeval
     133          (current_time, (struct timeval) { 2, i });
     134        TEST_VERIFY (deadline.absolute.tv_sec == 12);
     135        TEST_VERIFY (deadline.absolute.tv_nsec == 1 + (i - 2000) * 1000);
     136      }
     137  
     138    /* Check infinite deadlines.  */
     139    deadline = __deadline_from_timeval
     140      ((struct deadline_current_time) { { 0, 1000 * 1000 * 1000 - 1000 } },
     141       (struct timeval) { time_t_max (), 1 });
     142    TEST_VERIFY (__deadline_is_infinite (deadline));
     143    deadline = __deadline_from_timeval
     144      ((struct deadline_current_time) { { 0, 1000 * 1000 * 1000 - 1001 } },
     145       (struct timeval) { time_t_max (), 1 });
     146    TEST_VERIFY (!__deadline_is_infinite (deadline));
     147    deadline = __deadline_from_timeval
     148      ((struct deadline_current_time)
     149         { { time_t_max (), 1000 * 1000 * 1000 - 1000 } },
     150       (struct timeval) { 0, 1 });
     151    TEST_VERIFY (__deadline_is_infinite (deadline));
     152    deadline = __deadline_from_timeval
     153      ((struct deadline_current_time)
     154         { { time_t_max () / 2 + 1, 0 } },
     155       (struct timeval) { time_t_max () / 2 + 1, 0 });
     156    TEST_VERIFY (__deadline_is_infinite (deadline));
     157  
     158    /* Check __deadline_first behavior.  */
     159    deadline = __deadline_first
     160      ((struct deadline) { { 1, 2 } },
     161       (struct deadline) { { 1, 3 } });
     162    TEST_VERIFY (deadline.absolute.tv_sec == 1);
     163    TEST_VERIFY (deadline.absolute.tv_nsec == 2);
     164    deadline = __deadline_first
     165      ((struct deadline) { { 1, 3 } },
     166       (struct deadline) { { 1, 2 } });
     167    TEST_VERIFY (deadline.absolute.tv_sec == 1);
     168    TEST_VERIFY (deadline.absolute.tv_nsec == 2);
     169    deadline = __deadline_first
     170      ((struct deadline) { { 1, 2 } },
     171       (struct deadline) { { 2, 1 } });
     172    TEST_VERIFY (deadline.absolute.tv_sec == 1);
     173    TEST_VERIFY (deadline.absolute.tv_nsec == 2);
     174    deadline = __deadline_first
     175      ((struct deadline) { { 1, 2 } },
     176       (struct deadline) { { 2, 4 } });
     177    TEST_VERIFY (deadline.absolute.tv_sec == 1);
     178    TEST_VERIFY (deadline.absolute.tv_nsec == 2);
     179    deadline = __deadline_first
     180      ((struct deadline) { { 2, 4 } },
     181       (struct deadline) { { 1, 2 } });
     182    TEST_VERIFY (deadline.absolute.tv_sec == 1);
     183    TEST_VERIFY (deadline.absolute.tv_nsec == 2);
     184  
     185    return 0;
     186  }
     187  
     188  #include <support/test-driver.c>