Home | History | Annotate | Download | only in src
      1 /*
      2  * tlsdated-unittest.c - tlsdated unit tests
      3  * Copyright (c) 2012 The Chromium Authors. All rights reserved.
      4  * Use of this source code is governed by a BSD-style license that can be
      5  * found in the LICENSE file.
      6  */
      7 
      8 #include "config.h"
      9 
     10 #include "src/test_harness.h"
     11 #include "src/tlsdate.h"
     12 #include "src/util.h"
     13 
     14 #include <event2/event.h>
     15 #include <fcntl.h>
     16 #include <limits.h>
     17 #include <stdlib.h>
     18 #include <sys/time.h>
     19 #include <unistd.h>
     20 
     21 FIXTURE (tempdir)
     22 {
     23   char path[PATH_MAX];
     24 };
     25 
     26 FIXTURE_SETUP (tempdir)
     27 {
     28   char *p;
     29   strncpy (self->path, "/tmp/tlsdated-unit-XXXXXX", sizeof (self->path));
     30   p = mkdtemp (self->path);
     31   ASSERT_NE (NULL, p);
     32 }
     33 
     34 FIXTURE_TEARDOWN(tempdir) {
     35   char buf[256];
     36   snprintf(buf, sizeof(buf), "%s/load", self->path);
     37   unlink(buf);
     38   snprintf(buf, sizeof(buf), "%s/save", self->path);
     39   unlink(buf);
     40   ASSERT_EQ(0, rmdir(self->path));
     41 }
     42 
     43 int write_time (const char *path, time_t time)
     44 {
     45   int fd = open (path, O_WRONLY | O_TRUNC | O_CREAT, 0600);
     46   if (fd == -1)
     47     return 1;
     48   if (save_timestamp_to_fd (fd, time))
     49     return 1;
     50   if (write (fd, &time, sizeof (time)) != sizeof (time))
     51     {
     52       close (fd);
     53       return 1;
     54     }
     55   return close (fd);
     56 }
     57 
     58 int read_time (const char *path, time_t* time)
     59 {
     60   int fd = open (path, O_RDONLY);
     61   if (fd == -1)
     62     return 1;
     63   if (read (fd, time, sizeof (*time)) != sizeof (*time))
     64     {
     65       close (fd);
     66       return 1;
     67     }
     68   return close (fd);
     69 }
     70 
     71 TEST (sane_time)
     72 {
     73   ASSERT_EQ (0, is_sane_time (0));
     74   ASSERT_EQ (0, is_sane_time (INT_MAX));
     75 }
     76 
     77 TEST (sane_host_time)
     78 {
     79   ASSERT_EQ (1, is_sane_time (time (NULL)));
     80 }
     81 
     82 TEST_F (tempdir, load_time)
     83 {
     84   char buf[PATH_MAX];
     85   time_t tm = 3;
     86   time_t now = time (NULL);
     87   snprintf (buf, sizeof (buf), "%s/load", self->path);
     88   ASSERT_EQ (0, write_time (buf, 0));
     89   ASSERT_EQ (-1, load_disk_timestamp (buf, &tm));
     90   ASSERT_EQ (3, tm);
     91   ASSERT_EQ (0, write_time (buf, INT_MAX));
     92   ASSERT_EQ (-1, load_disk_timestamp (buf, &tm));
     93   ASSERT_EQ (3, tm);
     94   ASSERT_EQ (0, write_time (buf, now));
     95   ASSERT_EQ (0, truncate (buf, 2));
     96   ASSERT_EQ (-1, load_disk_timestamp (buf, &tm));
     97   ASSERT_EQ (3, tm);
     98   ASSERT_EQ (0, unlink (buf));
     99   ASSERT_EQ (-1, load_disk_timestamp (buf, &tm));
    100   ASSERT_EQ (3, tm);
    101   ASSERT_EQ (0, write_time (buf, now));
    102   ASSERT_EQ (0, load_disk_timestamp (buf, &tm));
    103   ASSERT_EQ (now, tm);
    104 }
    105 
    106 
    107 TEST_F (tempdir, save_time)
    108 {
    109   char buf[PATH_MAX];
    110   time_t now = time (NULL);
    111   time_t tm;
    112   snprintf (buf, sizeof (buf), "%s/save", self->path);
    113   ASSERT_EQ (0, write_time (buf, now));
    114   ASSERT_EQ (0, read_time (buf, &tm));
    115   EXPECT_EQ (now, tm);
    116 }
    117 
    118 FIXTURE (tlsdate)
    119 {
    120   struct state state;
    121   struct timeval timeout;
    122 };
    123 
    124 
    125 FIXTURE_SETUP (tlsdate)
    126 {
    127   memset (self, 0, sizeof (*self));
    128   /* TODO(wad) make this use the same function tlsdated uses. */
    129   self->state.base = event_base_new();
    130   set_conf_defaults (&self->state.opts);
    131   ASSERT_NE (NULL, self->state.base);
    132   event_base_priority_init (self->state.base, MAX_EVENT_PRIORITIES);
    133   ASSERT_EQ (0, setup_sigchld_event (&self->state, 1));
    134   self->state.events[E_TLSDATE] = event_new (self->state.base, -1, EV_TIMEOUT,
    135                                   action_run_tlsdate, &self->state);
    136   ASSERT_NE (NULL, self->state.events[E_TLSDATE]);
    137   event_priority_set (self->state.events[E_TLSDATE], PRI_NET);
    138   /* The timeout and fd will be filled in per-call. */
    139   ASSERT_EQ (0, setup_tlsdate_status (&self->state));
    140   self->timeout.tv_sec = 1;
    141 }
    142 
    143 FIXTURE_TEARDOWN (tlsdate)
    144 {
    145   int i;
    146   for (i = 0; i < E_MAX; ++i)
    147     {
    148       struct event *e = self->state.events[i];
    149       if (e)
    150         {
    151           int fd = event_get_fd (e);
    152           if (fd >= 0 && ! (event_get_events (e) & EV_SIGNAL))
    153             close (fd);
    154           event_free (e);
    155           self->state.events[i] = NULL;
    156         }
    157     }
    158   /* The other half was closed above. */
    159   close (self->state.tlsdate_monitor_fd);
    160   if (self->state.tlsdate_pid)
    161     {
    162       kill (self->state.tlsdate_pid, SIGKILL);
    163       waitpid (self->state.tlsdate_pid, NULL, WNOHANG);
    164     }
    165   if (self->state.base)
    166     event_base_free (self->state.base);
    167 }
    168 
    169 static int
    170 runner (FIXTURE_DATA (tlsdate) *self, time_t *newtime)
    171 {
    172   if (newtime)
    173     *newtime = 0;
    174   trigger_event (&self->state, E_TLSDATE, 0);
    175   event_base_loopexit (self->state.base, &self->timeout);
    176   if (event_base_dispatch (self->state.base))
    177     return -1;
    178   if (self->state.last_time)
    179     {
    180       if (newtime)
    181         *newtime = self->state.last_time;
    182       return 0;
    183     }
    184   return 1;
    185 }
    186 
    187 TEST_F (tlsdate, runner_multi)
    188 {
    189   struct source source =
    190   {
    191     .next = NULL,
    192     .host = "host1",
    193     .port = "port1",
    194     .proxy = "proxy1"
    195   };
    196   char *args[] = { "/nonexistent", NULL, NULL };
    197   extern char **environ;
    198   self->state.opts.sources = &source;
    199   self->state.opts.base_argv = args;
    200   self->state.opts.subprocess_tries = 2;
    201   self->state.opts.subprocess_wait_between_tries = 1;
    202   self->state.opts.max_tries = 3;
    203   self->state.envp = environ;
    204   EXPECT_EQ (1, runner (self, NULL));
    205   args[0] = "/bin/false";
    206   self->state.tries = 0;
    207   self->state.last_sync_type = SYNC_TYPE_NONE;
    208   EXPECT_EQ (1, runner (self, NULL));
    209   args[0] = "src/test/check-host-1";
    210   self->state.tries = 0;
    211   self->state.last_sync_type = SYNC_TYPE_NONE;
    212   EXPECT_EQ (0, runner (self, NULL));
    213   args[0] = "src/test/sleep-wrap";
    214   args[1] = "3";
    215   self->state.tries = 0;
    216   self->state.last_sync_type = SYNC_TYPE_NONE;
    217   EXPECT_EQ (0, runner (self, NULL));
    218 }
    219 
    220 TEST (jitter)
    221 {
    222   int i = 0;
    223   int r;
    224   const int kBase = 100;
    225   const int kJitter = 25;
    226   int nonequal = 0;
    227   for (i = 0; i < 1000; i++)
    228     {
    229       r = add_jitter (kBase, kJitter);
    230       EXPECT_GE (r, kBase - kJitter);
    231       EXPECT_LE (r, kBase + kJitter);
    232       if (r != kBase)
    233         nonequal++;
    234     }
    235   EXPECT_NE (nonequal, 0);
    236 }
    237 
    238 TEST_F (tlsdate, rotate_hosts)
    239 {
    240   struct source s2 =
    241   {
    242     .next = NULL,
    243     .host = "host2",
    244     .port = "port2",
    245     .proxy = "proxy2"
    246   };
    247   struct source s1 =
    248   {
    249     .next = &s2,
    250     .host = "host1",
    251     .port = "port1",
    252     .proxy = "proxy1"
    253   };
    254   char *args[] = { "src/test/check-host-1",  NULL };
    255   extern char **environ;
    256   self->state.envp = environ;
    257   self->state.opts.sources = &s1;
    258   self->state.opts.base_argv = args;
    259   self->state.opts.subprocess_tries = 2;
    260   self->state.opts.subprocess_wait_between_tries = 1;
    261   self->state.opts.max_tries = 5;
    262   self->timeout.tv_sec = 2;
    263   EXPECT_EQ (0, runner (self, NULL));
    264   self->state.tries = 0;
    265   args[0] = "src/test/check-host-2";
    266   self->state.last_sync_type = SYNC_TYPE_NONE;
    267   EXPECT_EQ (0, runner (self, NULL));
    268   self->state.tries = 0;
    269   args[0] = "src/test/check-host-1";
    270   self->state.last_sync_type = SYNC_TYPE_NONE;
    271   EXPECT_EQ (0, runner (self, NULL));
    272   self->state.tries = 0;
    273   args[0] = "src/test/check-host-2";
    274   self->state.last_sync_type = SYNC_TYPE_NONE;
    275   EXPECT_EQ (0, runner (self, NULL));
    276 }
    277 
    278 TEST_F (tlsdate, proxy_override)
    279 {
    280   struct source s1 =
    281   {
    282     .next = NULL,
    283     .host = "host",
    284     .port = "port",
    285     .proxy = NULL,
    286   };
    287   char *args[] = { "src/test/proxy-override", NULL };
    288   extern char **environ;
    289   self->state.envp = environ;
    290   self->state.opts.sources = &s1;
    291   self->state.opts.base_argv = args;
    292   self->state.opts.subprocess_tries = 2;
    293   self->state.opts.subprocess_wait_between_tries = 1;
    294   EXPECT_EQ (0, runner (self, NULL));
    295   EXPECT_EQ (RECENT_COMPILE_DATE + 1, self->state.last_time);
    296   s1.proxy = "socks5://bad.proxy";
    297   self->state.tries = 0;
    298   self->state.last_sync_type = SYNC_TYPE_NONE;
    299   EXPECT_EQ (0, runner (self, NULL));
    300   EXPECT_EQ (RECENT_COMPILE_DATE + 3, self->state.last_time);
    301   self->state.opts.proxy = "socks5://good.proxy";
    302   self->state.tries = 0;
    303   self->state.last_sync_type = SYNC_TYPE_NONE;
    304   EXPECT_EQ (0, runner (self, NULL));
    305   EXPECT_EQ (RECENT_COMPILE_DATE + 2, self->state.last_time);
    306 }
    307 
    308 FIXTURE(mock_platform) {
    309   struct platform platform;
    310   struct platform *old_platform;
    311 };
    312 
    313 FIXTURE_SETUP(mock_platform) {
    314   self->old_platform = platform;
    315   self->platform.rtc_open = NULL;
    316   self->platform.rtc_write = NULL;
    317   self->platform.rtc_read = NULL;
    318   self->platform.rtc_close = NULL;
    319   platform = &self->platform;
    320 }
    321 
    322 FIXTURE_TEARDOWN(mock_platform) {
    323   platform = self->old_platform;
    324 }
    325 
    326 /* TODO: leap_tests, time_setter tests. */
    327 
    328 TEST_HARNESS_MAIN
    329