Blame inet/tst-deadline.c

Packit 6c4009
/* Tests for computing deadlines for timeouts.
Packit 6c4009
   Copyright (C) 2017-2018 Free Software Foundation, Inc.
Packit 6c4009
   This file is part of the GNU C Library.
Packit 6c4009
Packit 6c4009
   The GNU C Library is free software; you can redistribute it and/or
Packit 6c4009
   modify it under the terms of the GNU Lesser General Public
Packit 6c4009
   License as published by the Free Software Foundation; either
Packit 6c4009
   version 2.1 of the License, or (at your option) any later version.
Packit 6c4009
Packit 6c4009
   The GNU C Library is distributed in the hope that it will be useful,
Packit 6c4009
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 6c4009
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit 6c4009
   Lesser General Public License for more details.
Packit 6c4009
Packit 6c4009
   You should have received a copy of the GNU Lesser General Public
Packit 6c4009
   License along with the GNU C Library; if not, see
Packit 6c4009
   <http://www.gnu.org/licenses/>.  */
Packit 6c4009
Packit 6c4009
#include <inet/net-internal.h>
Packit 6c4009
#include <limits.h>
Packit 6c4009
#include <stdbool.h>
Packit 6c4009
#include <stdint.h>
Packit 6c4009
#include <support/check.h>
Packit 6c4009
Packit 6c4009
/* Find the maximum value which can be represented in a time_t.  */
Packit 6c4009
static time_t
Packit 6c4009
time_t_max (void)
Packit 6c4009
{
Packit 6c4009
  _Static_assert (0 > (time_t) -1, "time_t is signed");
Packit 6c4009
  uintmax_t current = 1;
Packit 6c4009
  while (true)
Packit 6c4009
    {
Packit 6c4009
      uintmax_t next = current * 2;
Packit 6c4009
      /* This cannot happen because time_t is signed.  */
Packit 6c4009
      TEST_VERIFY_EXIT (next > current);
Packit 6c4009
      ++next;
Packit 6c4009
      if ((time_t) next < 0 || next != (uintmax_t) (time_t) next)
Packit 6c4009
        /* Value cannot be represented in time_t.  Return the previous
Packit 6c4009
           value. */
Packit 6c4009
        return current;
Packit 6c4009
      current = next;
Packit 6c4009
    }
Packit 6c4009
}
Packit 6c4009
Packit 6c4009
static int
Packit 6c4009
do_test (void)
Packit 6c4009
{
Packit 6c4009
  {
Packit 6c4009
    struct deadline_current_time current_time = __deadline_current_time ();
Packit 6c4009
    TEST_VERIFY (current_time.current.tv_sec >= 0);
Packit 6c4009
    current_time = __deadline_current_time ();
Packit 6c4009
    /* Due to CLOCK_MONOTONIC, either seconds or nanoseconds are
Packit 6c4009
       greater than zero.  This is also true for the gettimeofday
Packit 6c4009
       fallback.  */
Packit 6c4009
    TEST_VERIFY (current_time.current.tv_sec >= 0);
Packit 6c4009
    TEST_VERIFY (current_time.current.tv_sec > 0
Packit 6c4009
                 || current_time.current.tv_nsec > 0);
Packit 6c4009
  }
Packit 6c4009
Packit 6c4009
  /* Check basic computations of deadlines.  */
Packit 6c4009
  struct deadline_current_time current_time = { { 1, 123456789 } };
Packit 6c4009
  struct deadline deadline = __deadline_from_timeval
Packit 6c4009
    (current_time, (struct timeval) { 0, 1 });
Packit 6c4009
  TEST_VERIFY (deadline.absolute.tv_sec == 1);
Packit 6c4009
  TEST_VERIFY (deadline.absolute.tv_nsec == 123457789);
Packit 6c4009
  TEST_VERIFY (__deadline_to_ms (current_time, deadline) == 1);
Packit 6c4009
Packit 6c4009
  deadline = __deadline_from_timeval
Packit 6c4009
    (current_time, ((struct timeval) { 0, 2 }));
Packit 6c4009
  TEST_VERIFY (deadline.absolute.tv_sec == 1);
Packit 6c4009
  TEST_VERIFY (deadline.absolute.tv_nsec == 123458789);
Packit 6c4009
  TEST_VERIFY (__deadline_to_ms (current_time, deadline) == 1);
Packit 6c4009
Packit 6c4009
  deadline = __deadline_from_timeval
Packit 6c4009
    (current_time, ((struct timeval) { 1, 0 }));
Packit 6c4009
  TEST_VERIFY (deadline.absolute.tv_sec == 2);
Packit 6c4009
  TEST_VERIFY (deadline.absolute.tv_nsec == 123456789);
Packit 6c4009
  TEST_VERIFY (__deadline_to_ms (current_time, deadline) == 1000);
Packit 6c4009
Packit 6c4009
  /* Check if timeouts are correctly rounded up to the next
Packit 6c4009
     millisecond.  */
Packit 6c4009
  for (int i = 0; i < 999999; ++i)
Packit 6c4009
    {
Packit 6c4009
      ++current_time.current.tv_nsec;
Packit 6c4009
      TEST_VERIFY (__deadline_to_ms (current_time, deadline) == 1000);
Packit 6c4009
    }
Packit 6c4009
Packit 6c4009
  /* A full millisecond has elapsed, so the time to the deadline is
Packit 6c4009
     now less than 1000.  */
Packit 6c4009
  ++current_time.current.tv_nsec;
Packit 6c4009
  TEST_VERIFY (__deadline_to_ms (current_time, deadline) == 999);
Packit 6c4009
Packit 6c4009
  /* Check __deadline_to_ms carry-over.  */
Packit 6c4009
  current_time = (struct deadline_current_time) { { 9, 123456789 } };
Packit 6c4009
  deadline = (struct deadline) { { 10, 122456789 } };
Packit 6c4009
  TEST_VERIFY (__deadline_to_ms (current_time, deadline) == 999);
Packit 6c4009
  deadline = (struct deadline) { { 10, 122456790 } };
Packit 6c4009
  TEST_VERIFY (__deadline_to_ms (current_time, deadline) == 1000);
Packit 6c4009
  deadline = (struct deadline) { { 10, 123456788 } };
Packit 6c4009
  TEST_VERIFY (__deadline_to_ms (current_time, deadline) == 1000);
Packit 6c4009
  deadline = (struct deadline) { { 10, 123456789 } };
Packit 6c4009
  TEST_VERIFY (__deadline_to_ms (current_time, deadline) == 1000);
Packit 6c4009
Packit 6c4009
  /* Check __deadline_to_ms overflow.  */
Packit 6c4009
  deadline = (struct deadline) { { INT_MAX - 1, 1 } };
Packit 6c4009
  TEST_VERIFY (__deadline_to_ms (current_time, deadline) == INT_MAX);
Packit 6c4009
Packit 6c4009
  /* Check __deadline_to_ms for elapsed deadlines.  */
Packit 6c4009
  current_time = (struct deadline_current_time) { { 9, 123456789 } };
Packit 6c4009
  deadline.absolute = current_time.current;
Packit 6c4009
  TEST_VERIFY (__deadline_to_ms (current_time, deadline) == 0);
Packit 6c4009
  current_time = (struct deadline_current_time) { { 9, 123456790 } };
Packit 6c4009
  TEST_VERIFY (__deadline_to_ms (current_time, deadline) == 0);
Packit 6c4009
  current_time = (struct deadline_current_time) { { 10, 0 } };
Packit 6c4009
  TEST_VERIFY (__deadline_to_ms (current_time, deadline) == 0);
Packit 6c4009
  current_time = (struct deadline_current_time) { { 10, 123456788 } };
Packit 6c4009
  TEST_VERIFY (__deadline_to_ms (current_time, deadline) == 0);
Packit 6c4009
  current_time = (struct deadline_current_time) { { 10, 123456789 } };
Packit 6c4009
  TEST_VERIFY (__deadline_to_ms (current_time, deadline) == 0);
Packit 6c4009
Packit 6c4009
  /* Check carry-over in __deadline_from_timeval.  */
Packit 6c4009
  current_time = (struct deadline_current_time) { { 9, 998000001 } };
Packit 6c4009
  for (int i = 0; i < 2000; ++i)
Packit 6c4009
    {
Packit 6c4009
      deadline = __deadline_from_timeval
Packit 6c4009
        (current_time, (struct timeval) { 1, i });
Packit 6c4009
      TEST_VERIFY (deadline.absolute.tv_sec == 10);
Packit 6c4009
      TEST_VERIFY (deadline.absolute.tv_nsec == 998000001 + i * 1000);
Packit 6c4009
    }
Packit 6c4009
  for (int i = 2000; i < 3000; ++i)
Packit 6c4009
    {
Packit 6c4009
      deadline = __deadline_from_timeval
Packit 6c4009
        (current_time, (struct timeval) { 2, i });
Packit 6c4009
      TEST_VERIFY (deadline.absolute.tv_sec == 12);
Packit 6c4009
      TEST_VERIFY (deadline.absolute.tv_nsec == 1 + (i - 2000) * 1000);
Packit 6c4009
    }
Packit 6c4009
Packit 6c4009
  /* Check infinite deadlines.  */
Packit 6c4009
  deadline = __deadline_from_timeval
Packit 6c4009
    ((struct deadline_current_time) { { 0, 1000 * 1000 * 1000 - 1000 } },
Packit 6c4009
     (struct timeval) { time_t_max (), 1 });
Packit 6c4009
  TEST_VERIFY (__deadline_is_infinite (deadline));
Packit 6c4009
  deadline = __deadline_from_timeval
Packit 6c4009
    ((struct deadline_current_time) { { 0, 1000 * 1000 * 1000 - 1001 } },
Packit 6c4009
     (struct timeval) { time_t_max (), 1 });
Packit 6c4009
  TEST_VERIFY (!__deadline_is_infinite (deadline));
Packit 6c4009
  deadline = __deadline_from_timeval
Packit 6c4009
    ((struct deadline_current_time)
Packit 6c4009
       { { time_t_max (), 1000 * 1000 * 1000 - 1000 } },
Packit 6c4009
     (struct timeval) { 0, 1 });
Packit 6c4009
  TEST_VERIFY (__deadline_is_infinite (deadline));
Packit 6c4009
  deadline = __deadline_from_timeval
Packit 6c4009
    ((struct deadline_current_time)
Packit 6c4009
       { { time_t_max () / 2 + 1, 0 } },
Packit 6c4009
     (struct timeval) { time_t_max () / 2 + 1, 0 });
Packit 6c4009
  TEST_VERIFY (__deadline_is_infinite (deadline));
Packit 6c4009
Packit 6c4009
  /* Check __deadline_first behavior.  */
Packit 6c4009
  deadline = __deadline_first
Packit 6c4009
    ((struct deadline) { { 1, 2 } },
Packit 6c4009
     (struct deadline) { { 1, 3 } });
Packit 6c4009
  TEST_VERIFY (deadline.absolute.tv_sec == 1);
Packit 6c4009
  TEST_VERIFY (deadline.absolute.tv_nsec == 2);
Packit 6c4009
  deadline = __deadline_first
Packit 6c4009
    ((struct deadline) { { 1, 3 } },
Packit 6c4009
     (struct deadline) { { 1, 2 } });
Packit 6c4009
  TEST_VERIFY (deadline.absolute.tv_sec == 1);
Packit 6c4009
  TEST_VERIFY (deadline.absolute.tv_nsec == 2);
Packit 6c4009
  deadline = __deadline_first
Packit 6c4009
    ((struct deadline) { { 1, 2 } },
Packit 6c4009
     (struct deadline) { { 2, 1 } });
Packit 6c4009
  TEST_VERIFY (deadline.absolute.tv_sec == 1);
Packit 6c4009
  TEST_VERIFY (deadline.absolute.tv_nsec == 2);
Packit 6c4009
  deadline = __deadline_first
Packit 6c4009
    ((struct deadline) { { 1, 2 } },
Packit 6c4009
     (struct deadline) { { 2, 4 } });
Packit 6c4009
  TEST_VERIFY (deadline.absolute.tv_sec == 1);
Packit 6c4009
  TEST_VERIFY (deadline.absolute.tv_nsec == 2);
Packit 6c4009
  deadline = __deadline_first
Packit 6c4009
    ((struct deadline) { { 2, 4 } },
Packit 6c4009
     (struct deadline) { { 1, 2 } });
Packit 6c4009
  TEST_VERIFY (deadline.absolute.tv_sec == 1);
Packit 6c4009
  TEST_VERIFY (deadline.absolute.tv_nsec == 2);
Packit 6c4009
Packit 6c4009
  return 0;
Packit 6c4009
}
Packit 6c4009
Packit 6c4009
#include <support/test-driver.c>