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