(root)/
glib-2.79.0/
glib/
tests/
timer.c
       1  /* Unit tests for GTimer
       2   * Copyright (C) 2013 Red Hat, Inc.
       3   *
       4   * SPDX-License-Identifier: LicenseRef-old-glib-tests
       5   *
       6   * This work is provided "as is"; redistribution and modification
       7   * in whole or in part, in any medium, physical or electronic is
       8   * permitted without restriction.
       9   *
      10   * This work 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.
      13   *
      14   * In no event shall the authors or contributors be liable for any
      15   * direct, indirect, incidental, special, exemplary, or consequential
      16   * damages (including, but not limited to, procurement of substitute
      17   * goods or services; loss of use, data, or profits; or business
      18   * interruption) however caused and on any theory of liability, whether
      19   * in contract, strict liability, or tort (including negligence or
      20   * otherwise) arising in any way out of the use of this software, even
      21   * if advised of the possibility of such damage.
      22   *
      23   * Author: Matthias Clasen
      24   */
      25  
      26  /* We test a few deprecated APIs here. */
      27  #define GLIB_DISABLE_DEPRECATION_WARNINGS 1
      28  
      29  #include "glib.h"
      30  
      31  static void
      32  test_timer_basic (void)
      33  {
      34    GTimer *timer;
      35    gdouble elapsed;
      36    gulong micros;
      37  
      38    timer = g_timer_new ();
      39  
      40    g_timer_start (timer);
      41    elapsed = g_timer_elapsed (timer, NULL);
      42    g_timer_stop (timer);
      43    g_assert_cmpfloat (elapsed, <=, g_timer_elapsed (timer, NULL));
      44  
      45    g_timer_destroy (timer);
      46  
      47    timer = g_timer_new ();
      48  
      49    g_timer_start (timer);
      50    elapsed = g_timer_elapsed (timer, NULL);
      51    g_timer_stop (timer);
      52    g_assert_cmpfloat (elapsed, <=, g_timer_elapsed (timer, NULL));
      53  
      54    g_timer_destroy (timer);
      55  
      56    timer = g_timer_new ();
      57  
      58    elapsed = g_timer_elapsed (timer, &micros);
      59  
      60    g_assert_cmpfloat (elapsed, <, 1.0);
      61    g_assert_cmpfloat_with_epsilon (elapsed, micros / 1e6,  0.001);
      62  
      63    g_timer_destroy (timer);
      64  }
      65  
      66  static void
      67  test_timer_stop (void)
      68  {
      69    GTimer *timer;
      70    gdouble elapsed, elapsed2;
      71  
      72    timer = g_timer_new ();
      73  
      74    g_timer_stop (timer);
      75  
      76    elapsed = g_timer_elapsed (timer, NULL);
      77    g_usleep (100);
      78    elapsed2 = g_timer_elapsed (timer, NULL);
      79  
      80    g_assert_cmpfloat (elapsed, ==, elapsed2);
      81  
      82    g_timer_destroy (timer);
      83  }
      84  
      85  static void
      86  test_timer_continue (void)
      87  {
      88    GTimer *timer;
      89    gdouble elapsed, elapsed2;
      90  
      91    timer = g_timer_new ();
      92  
      93    /* Continue on a running timer */
      94    if (g_test_undefined ())
      95      {
      96        g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
      97                               "*assertion*== FALSE*");
      98        g_timer_continue (timer);
      99        g_test_assert_expected_messages ();
     100      }
     101  
     102    g_timer_reset (timer);
     103  
     104    /* Continue on a stopped timer */
     105    g_usleep (100);
     106    g_timer_stop (timer);
     107  
     108    elapsed = g_timer_elapsed (timer, NULL);
     109    g_timer_continue (timer);
     110    g_usleep (100);
     111    elapsed2 = g_timer_elapsed (timer, NULL);
     112  
     113    g_assert_cmpfloat (elapsed, <, elapsed2);
     114  
     115    g_timer_destroy (timer);
     116  }
     117  
     118  static void
     119  test_timer_reset (void)
     120  {
     121    GTimer *timer;
     122    gdouble elapsed, elapsed2;
     123  
     124    timer = g_timer_new ();
     125    g_usleep (100);
     126    g_timer_stop (timer);
     127  
     128    elapsed = g_timer_elapsed (timer, NULL);
     129    g_timer_reset (timer);
     130    elapsed2 = g_timer_elapsed (timer, NULL);
     131  
     132    g_assert_cmpfloat (elapsed, >, elapsed2);
     133  
     134    g_timer_destroy (timer);
     135  }
     136  
     137  static void
     138  test_timer_is_active (void)
     139  {
     140    GTimer *timer;
     141    gboolean is_active;
     142  
     143    timer = g_timer_new ();
     144    is_active = g_timer_is_active (timer);
     145    g_assert_true (is_active);
     146    g_timer_stop (timer);
     147    is_active = g_timer_is_active (timer);
     148    g_assert_false (is_active);
     149  
     150    g_timer_destroy (timer);
     151  }
     152  
     153  static void
     154  test_timeval_add (void)
     155  {
     156    GTimeVal time = { 1, 0 };
     157  
     158    g_time_val_add (&time, 10);
     159  
     160    g_assert_cmpint (time.tv_sec, ==, 1); 
     161    g_assert_cmpint (time.tv_usec, ==, 10); 
     162  
     163    g_time_val_add (&time, -500);
     164    g_assert_cmpint (time.tv_sec, ==, 0); 
     165    g_assert_cmpint (time.tv_usec, ==, G_USEC_PER_SEC - 490); 
     166  
     167    g_time_val_add (&time, 1000);
     168    g_assert_cmpint (time.tv_sec, ==, 1); 
     169    g_assert_cmpint (time.tv_usec, ==, 510);
     170  
     171    g_time_val_add (&time, 0);
     172    g_assert_cmpint (time.tv_sec, ==, 1);
     173    g_assert_cmpint (time.tv_usec, ==, 510);
     174  
     175    g_time_val_add (&time, -210);
     176    g_assert_cmpint (time.tv_sec, ==, 1);
     177    g_assert_cmpint (time.tv_usec, ==, 300);
     178  }
     179  
     180  typedef struct {
     181    gboolean success;
     182    const gchar *in;
     183    GTimeVal val;
     184  } TimeValParseTest;
     185  
     186  static void
     187  test_timeval_from_iso8601 (void)
     188  {
     189    gchar *old_tz = g_strdup (g_getenv ("TZ"));
     190    TimeValParseTest tests[] = {
     191      { TRUE, "1990-11-01T10:21:17Z", { 657454877, 0 } },
     192      { TRUE, "19901101T102117Z", { 657454877, 0 } },
     193      { TRUE, "19901101T102117+5", { 657454577, 0 } },
     194      { TRUE, "19901101T102117+3:15", { 657443177, 0 } },
     195      { TRUE, "  1990-11-01T10:21:17Z  ", { 657454877, 0 } },
     196      { TRUE, "1970-01-01T00:00:17.12Z", { 17, 120000 } },
     197      { TRUE, "1970-01-01T00:00:17.1234Z", { 17, 123400 } },
     198      { TRUE, "1970-01-01T00:00:17.123456Z", { 17, 123456 } },
     199      { TRUE, "1980-02-22T12:36:00+02:00", { 320063760, 0 } },
     200      { TRUE, "1980-02-22T10:36:00Z", { 320063760, 0 } },
     201      { TRUE, "1980-02-22T10:36:00", { 320063760, 0 } },
     202      { TRUE, "1980-02-22T12:36:00+02:00", { 320063760, 0 } },
     203      { TRUE, "19800222T053600-0500", { 320063760, 0 } },
     204      { TRUE, "1980-02-22T07:06:00-03:30", { 320063760, 0 } },
     205      { TRUE, "1980-02-22T10:36:00.050000Z", { 320063760, 50000 } },
     206      { TRUE, "1980-02-22T05:36:00,05-05:00", { 320063760, 50000 } },
     207      { TRUE, "19800222T123600.050000000+0200", { 320063760, 50000 } },
     208      { TRUE, "19800222T070600,0500-0330", { 320063760, 50000 } },
     209      { FALSE, "   ", { 0, 0 } },
     210      { FALSE, "x", { 0, 0 } },
     211      { FALSE, "123x", { 0, 0 } },
     212      { FALSE, "2001-10+x", { 0, 0 } },
     213      { FALSE, "1980-02-22", { 0, 0 } },
     214      { FALSE, "1980-02-22T", { 0, 0 } },
     215      { FALSE, "2001-10-08Tx", { 0, 0 } },
     216      { FALSE, "2001-10-08T10:11x", { 0, 0 } },
     217      { FALSE, "Wed Dec 19 17:20:20 GMT 2007", { 0, 0 } },
     218      { FALSE, "1980-02-22T10:36:00Zulu", { 0, 0 } },
     219      { FALSE, "2T0+819855292164632335", { 0, 0 } },
     220      { FALSE, "1980-02-22", { 320063760, 50000 } },
     221      { TRUE, "2018-08-03T14:08:05.446178377+01:00", { 1533301685, 446178 } },
     222      { FALSE, "2147483648-08-03T14:08:05.446178377+01:00", { 0, 0 } },
     223      { FALSE, "2018-13-03T14:08:05.446178377+01:00", { 0, 0 } },
     224      { FALSE, "2018-00-03T14:08:05.446178377+01:00", { 0, 0 } },
     225      { FALSE, "2018-08-00T14:08:05.446178377+01:00", { 0, 0 } },
     226      { FALSE, "2018-08-32T14:08:05.446178377+01:00", { 0, 0 } },
     227      { FALSE, "2018-08-03T24:08:05.446178377+01:00", { 0, 0 } },
     228      { FALSE, "2018-08-03T14:60:05.446178377+01:00", { 0, 0 } },
     229      { FALSE, "2018-08-03T14:08:63.446178377+01:00", { 0, 0 } },
     230      { FALSE, "2018-08-03T14:08:05.446178377+100:00", { 0, 0 } },
     231      { FALSE, "2018-08-03T14:08:05.446178377+01:60", { 0, 0 } },
     232      { TRUE, "20180803T140805.446178377+0100", { 1533301685, 446178 } },
     233      { FALSE, "21474836480803T140805.446178377+0100", { 0, 0 } },
     234      { FALSE, "20181303T140805.446178377+0100", { 0, 0 } },
     235      { FALSE, "20180003T140805.446178377+0100", { 0, 0 } },
     236      { FALSE, "20180800T140805.446178377+0100", { 0, 0 } },
     237      { FALSE, "20180832T140805.446178377+0100", { 0, 0 } },
     238      { FALSE, "20180803T240805.446178377+0100", { 0, 0 } },
     239      { FALSE, "20180803T146005.446178377+0100", { 0, 0 } },
     240      { FALSE, "20180803T140863.446178377+0100", { 0, 0 } },
     241      { FALSE, "20180803T140805.446178377+10000", { 0, 0 } },
     242      { FALSE, "20180803T140805.446178377+0160", { 0, 0 } },
     243      { TRUE, "+1980-02-22T12:36:00+02:00", { 320063760, 0 } },
     244      { FALSE, "-0005-01-01T00:00:00Z", { 0, 0 } },
     245      { FALSE, "2018-08-06", { 0, 0 } },
     246      { FALSE, "2018-08-06 13:51:00Z", { 0, 0 } },
     247      { TRUE, "20180803T140805,446178377+0100", { 1533301685, 446178 } },
     248      { TRUE, "2018-08-03T14:08:05.446178377-01:00", { 1533308885, 446178 } },
     249      { FALSE, "2018-08-03T14:08:05.446178377 01:00", { 0, 0 } },
     250      { TRUE, "1990-11-01T10:21:17", { 657454877, 0 } },
     251      { TRUE, "1990-11-01T10:21:17     ", { 657454877, 0 } },
     252    };
     253    GTimeVal out;
     254    gboolean success;
     255    gsize i;
     256  
     257    /* Always run in UTC so the comparisons of parsed values are valid. */
     258    if (!g_setenv ("TZ", "UTC", TRUE))
     259      {
     260        g_test_skip ("Failed to set TZ=UTC");
     261        return;
     262      }
     263  
     264    for (i = 0; i < G_N_ELEMENTS (tests); i++)
     265      {
     266        out.tv_sec = 0;
     267        out.tv_usec = 0;
     268        success = g_time_val_from_iso8601 (tests[i].in, &out);
     269        g_assert_cmpint (success, ==, tests[i].success);
     270        if (tests[i].success)
     271          {
     272            g_assert_cmpint (out.tv_sec, ==, tests[i].val.tv_sec);
     273            g_assert_cmpint (out.tv_usec, ==, tests[i].val.tv_usec);
     274          }
     275      }
     276  
     277    /* revert back user defined time zone */
     278    if (old_tz != NULL)
     279      g_assert_true (g_setenv ("TZ", old_tz, TRUE));
     280    else
     281      g_unsetenv ("TZ");
     282    tzset ();
     283  
     284    for (i = 0; i < G_N_ELEMENTS (tests); i++)
     285      {
     286        out.tv_sec = 0;
     287        out.tv_usec = 0;
     288        success = g_time_val_from_iso8601 (tests[i].in, &out);
     289        g_assert_cmpint (success, ==, tests[i].success);
     290      }
     291  
     292    g_free (old_tz);
     293  }
     294  
     295  typedef struct {
     296    GTimeVal val;
     297    const gchar *expected;
     298  } TimeValFormatTest;
     299  
     300  static void
     301  test_timeval_to_iso8601 (void)
     302  {
     303    TimeValFormatTest tests[] = {
     304      { { 657454877, 0 }, "1990-11-01T10:21:17Z" },
     305      { { 17, 123400 }, "1970-01-01T00:00:17.123400Z" }
     306    };
     307    gsize i;
     308    gchar *out;
     309    GTimeVal val;
     310    gboolean ret;
     311  
     312    g_unsetenv ("TZ");
     313  
     314    for (i = 0; i < G_N_ELEMENTS (tests); i++)
     315      {
     316        out = g_time_val_to_iso8601 (&(tests[i].val));
     317        g_assert_cmpstr (out, ==, tests[i].expected);
     318  
     319        ret = g_time_val_from_iso8601 (out, &val);
     320        g_assert (ret);
     321        g_assert_cmpint (val.tv_sec, ==, tests[i].val.tv_sec);
     322        g_assert_cmpint (val.tv_usec, ==, tests[i].val.tv_usec);
     323        g_free (out);
     324      }
     325  }
     326  
     327  /* Test error handling for g_time_val_to_iso8601() on dates which are too large. */
     328  static void
     329  test_timeval_to_iso8601_overflow (void)
     330  {
     331    GTimeVal val;
     332    gchar *out = NULL;
     333  
     334    if ((glong) G_MAXINT == G_MAXLONG)
     335      {
     336        g_test_skip ("G_MAXINT == G_MAXLONG - we can't make g_time_val_to_iso8601() overflow.");
     337        return;
     338      }
     339  
     340    g_unsetenv ("TZ");
     341  
     342    val.tv_sec = G_MAXLONG;
     343    val.tv_usec = G_USEC_PER_SEC - 1;
     344  
     345    out = g_time_val_to_iso8601 (&val);
     346    g_assert_null (out);
     347  }
     348  
     349  static void
     350  test_usleep_with_zero_wait (void)
     351  {
     352    GTimer *timer;
     353    unsigned int n_times_shorter = 0;
     354  
     355    timer = g_timer_new ();
     356  
     357    /* Test that g_usleep(0) sleeps for less time than g_usleep(1). We can’t
     358     * actually guarantee this, since the exact length of g_usleep(1) is not
     359     * guaranteed, but we can say that it probably should be longer 9 times out
     360     * of 10. */
     361    for (unsigned int i = 0; i < 10; i++)
     362      {
     363        gdouble elapsed0, elapsed1;
     364  
     365        g_timer_start (timer);
     366        g_usleep (0);
     367        elapsed0 = g_timer_elapsed (timer, NULL);
     368        g_timer_stop (timer);
     369  
     370        g_timer_start (timer);
     371        g_usleep (1);
     372        elapsed1 = g_timer_elapsed (timer, NULL);
     373        g_timer_stop (timer);
     374  
     375        if (elapsed0 <= elapsed1)
     376          n_times_shorter++;
     377      }
     378  
     379    g_assert_cmpuint (n_times_shorter, >=, 9);
     380  
     381    g_clear_pointer (&timer, g_timer_destroy);
     382  }
     383  
     384  int
     385  main (int argc, char *argv[])
     386  {
     387    g_test_init (&argc, &argv, NULL);
     388  
     389    g_test_add_func ("/timer/basic", test_timer_basic);
     390    g_test_add_func ("/timer/stop", test_timer_stop);
     391    g_test_add_func ("/timer/continue", test_timer_continue);
     392    g_test_add_func ("/timer/reset", test_timer_reset);
     393    g_test_add_func ("/timer/is_active", test_timer_is_active);
     394    g_test_add_func ("/timeval/add", test_timeval_add);
     395    g_test_add_func ("/timeval/from-iso8601", test_timeval_from_iso8601);
     396    g_test_add_func ("/timeval/to-iso8601", test_timeval_to_iso8601);
     397    g_test_add_func ("/timeval/to-iso8601/overflow", test_timeval_to_iso8601_overflow);
     398    g_test_add_func ("/usleep/with-zero-wait", test_usleep_with_zero_wait);
     399  
     400    return g_test_run ();
     401  }