blob: bd76f72acc5ca25dddd4c3375c82029bbe9f7b91 [file] [log] [blame]
Elly Fong-Jones6fb0d4b2012-10-06 14:10:37 -04001/*
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 Akerb12abad2012-10-16 01:25:00 -04008#include "config.h"
9
10#include "src/test_harness.h"
11#include "src/tlsdate.h"
Will Drewryc45952f2013-09-03 13:51:24 -050012#include "src/util.h"
Brian Akerb12abad2012-10-16 01:25:00 -040013
Will Drewryc45952f2013-09-03 13:51:24 -050014#include <event2/event.h>
Elly Fong-Jones6fb0d4b2012-10-06 14:10:37 -040015#include <fcntl.h>
16#include <limits.h>
17#include <stdlib.h>
18#include <unistd.h>
19
Will Drewryc45952f2013-09-03 13:51:24 -050020FIXTURE (tempdir)
21{
Jacob Appelbaum8d751a02012-10-30 16:39:58 +010022 char path[PATH_MAX];
Elly Fong-Jones6fb0d4b2012-10-06 14:10:37 -040023};
24
Will Drewryc45952f2013-09-03 13:51:24 -050025FIXTURE_SETUP (tempdir)
26{
Jacob Appelbaum8d751a02012-10-30 16:39:58 +010027 char *p;
Will Drewryc45952f2013-09-03 13:51:24 -050028 strncpy (self->path, "/tmp/tlsdated-unit-XXXXXX", sizeof (self->path));
29 p = mkdtemp (self->path);
30 ASSERT_NE (NULL, p);
Elly Fong-Jones6fb0d4b2012-10-06 14:10:37 -040031}
32
Will Drewryc45952f2013-09-03 13:51:24 -050033int rmrf (char *dir)
34{
Jacob Appelbaum8d751a02012-10-30 16:39:58 +010035 char buf[256];
Will Drewryc45952f2013-09-03 13:51:24 -050036 snprintf (buf, sizeof (buf), "rm -rf %s", dir);
37 return system (buf);
Elly Fong-Jones6fb0d4b2012-10-06 14:10:37 -040038}
39
Will Drewryc45952f2013-09-03 13:51:24 -050040FIXTURE_TEARDOWN (tempdir)
41{
42 ASSERT_EQ (0, rmrf (self->path));
Elly Fong-Jones6fb0d4b2012-10-06 14:10:37 -040043}
44
Will Drewryc45952f2013-09-03 13:51:24 -050045int write_time (const char *path, time_t time)
46{
47 int fd = open (path, O_WRONLY | O_TRUNC | O_CREAT, 0600);
Jacob Appelbaum8d751a02012-10-30 16:39:58 +010048 if (fd == -1)
49 return 1;
Will Drewryc45952f2013-09-03 13:51:24 -050050 if (save_timestamp_to_fd (fd, time))
Jacob Appelbaum8d751a02012-10-30 16:39:58 +010051 return 1;
Will Drewryc45952f2013-09-03 13:51:24 -050052 if (write (fd, &time, sizeof (time)) != sizeof (time))
53 {
54 close (fd);
55 return 1;
56 }
57 return close (fd);
Elly Fong-Jones6fb0d4b2012-10-06 14:10:37 -040058}
59
Will Drewryc45952f2013-09-03 13:51:24 -050060int read_time (const char *path, time_t* time)
61{
62 int fd = open (path, O_RDONLY);
Jacob Appelbaum8d751a02012-10-30 16:39:58 +010063 if (fd == -1)
64 return 1;
Will Drewryc45952f2013-09-03 13:51:24 -050065 if (read (fd, time, sizeof (*time)) != sizeof (*time))
66 {
67 close (fd);
68 return 1;
69 }
70 return close (fd);
Elly Fong-Jones6fb0d4b2012-10-06 14:10:37 -040071}
72
Will Drewryc45952f2013-09-03 13:51:24 -050073TEST (sane_time)
74{
75 ASSERT_EQ (0, is_sane_time (0));
76 ASSERT_EQ (0, is_sane_time (INT_MAX));
Elly Fong-Jones6fb0d4b2012-10-06 14:10:37 -040077}
78
Will Drewryc45952f2013-09-03 13:51:24 -050079TEST (sane_host_time)
80{
81 ASSERT_EQ (1, is_sane_time (time (NULL)));
Elly Fong-Jones6fb0d4b2012-10-06 14:10:37 -040082}
83
Will Drewryc45952f2013-09-03 13:51:24 -050084TEST_F (tempdir, load_time)
85{
Jacob Appelbaum8d751a02012-10-30 16:39:58 +010086 char buf[PATH_MAX];
87 time_t tm = 3;
Will Drewryc45952f2013-09-03 13:51:24 -050088 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-Jones6fb0d4b2012-10-06 14:10:37 -0400106}
107
Will Drewryc45952f2013-09-03 13:51:24 -0500108
109TEST_F (tempdir, save_time)
110{
Jacob Appelbaum8d751a02012-10-30 16:39:58 +0100111 char buf[PATH_MAX];
Will Drewryc45952f2013-09-03 13:51:24 -0500112 time_t now = time (NULL);
Jacob Appelbaum8d751a02012-10-30 16:39:58 +0100113 time_t tm;
Will Drewryc45952f2013-09-03 13:51:24 -0500114 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-Jones6fb0d4b2012-10-06 14:10:37 -0400118}
119
Will Drewryc45952f2013-09-03 13:51:24 -0500120FIXTURE (tlsdate)
121{
122 struct state state;
123 struct timeval timeout;
124};
125
126
127FIXTURE_SETUP (tlsdate)
128{
Will Drewryfb6fbcb2015-05-14 14:11:20 -0700129 memset (self, 0, sizeof (*self));
Will Drewryc45952f2013-09-03 13:51:24 -0500130 /* 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
145FIXTURE_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
171static int
172runner (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
189TEST_F (tlsdate, runner)
190{
191 struct source source =
192 {
elly0e35d052013-01-16 17:34:12 -0500193 .next = NULL,
Will Drewryc45952f2013-09-03 13:51:24 -0500194 .host = "host1",
195 .port = "port1",
196 .proxy = "proxy1"
elly0e35d052013-01-16 17:34:12 -0500197 };
Jacob Appelbaum8d751a02012-10-30 16:39:58 +0100198 char *args[] = { "/nonexistent", NULL, NULL };
199 extern char **environ;
Will Drewryc45952f2013-09-03 13:51:24 -0500200 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 Appelbaum8d751a02012-10-30 16:39:58 +0100207 args[0] = "/bin/false";
Will Drewryc45952f2013-09-03 13:51:24 -0500208 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));
elly9482b022013-01-18 12:30:35 -0500215 args[0] = "src/test/sleep-wrap";
Jacob Appelbaum8d751a02012-10-30 16:39:58 +0100216 args[1] = "3";
Will Drewryc45952f2013-09-03 13:51:24 -0500217 self->state.tries = 0;
218 self->state.last_sync_type = SYNC_TYPE_NONE;
219 EXPECT_EQ (0, runner (self, NULL));
Elly Fong-Jones6fb0d4b2012-10-06 14:10:37 -0400220}
221
Will Drewryc45952f2013-09-03 13:51:24 -0500222TEST (jitter)
223{
ellyccd12452013-01-11 14:44:17 -0500224 int i = 0;
225 int r;
226 const int kBase = 100;
227 const int kJitter = 25;
228 int nonequal = 0;
Will Drewryc45952f2013-09-03 13:51:24 -0500229 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);
ellyccd12452013-01-11 14:44:17 -0500238}
239
Will Drewryc45952f2013-09-03 13:51:24 -0500240TEST_F (tlsdate, rotate_hosts)
241{
242 struct source s2 =
243 {
elly0e35d052013-01-16 17:34:12 -0500244 .next = NULL,
245 .host = "host2",
246 .port = "port2",
247 .proxy = "proxy2"
248 };
Will Drewryc45952f2013-09-03 13:51:24 -0500249 struct source s1 =
250 {
elly0e35d052013-01-16 17:34:12 -0500251 .next = &s2,
252 .host = "host1",
253 .port = "port1",
254 .proxy = "proxy1"
255 };
Will Drewryc45952f2013-09-03 13:51:24 -0500256 char *args[] = { "src/test/check-host-1", NULL };
elly0e35d052013-01-16 17:34:12 -0500257 extern char **environ;
Will Drewryc45952f2013-09-03 13:51:24 -0500258 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));
elly0e35d052013-01-16 17:34:12 -0500278}
279
Will Drewryc45952f2013-09-03 13:51:24 -0500280TEST_F (tlsdate, proxy_override)
281{
282 struct source s1 =
283 {
ellybf90bd22013-02-22 14:45:17 -0500284 .next = NULL,
285 .host = "host",
286 .port = "port",
287 .proxy = NULL,
288 };
ellybf90bd22013-02-22 14:45:17 -0500289 char *args[] = { "src/test/proxy-override", NULL };
ellybf90bd22013-02-22 14:45:17 -0500290 extern char **environ;
Will Drewryc45952f2013-09-03 13:51:24 -0500291 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);
ellybf90bd22013-02-22 14:45:17 -0500298 s1.proxy = "socks5://bad.proxy";
Will Drewryc45952f2013-09-03 13:51:24 -0500299 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);
ellybf90bd22013-02-22 14:45:17 -0500308}
Elly Fong-Jones6fb0d4b2012-10-06 14:10:37 -0400309TEST_HARNESS_MAIN