Branch data Line data Source code
1 : : /*
2 : : * Copyright (C) 2011-2014 Joel Rosdahl
3 : : *
4 : : * This program is free software; you can redistribute it and/or modify it
5 : : * under the terms of the GNU General Public License as published by the Free
6 : : * Software Foundation; either version 3 of the License, or (at your option)
7 : : * any later version.
8 : : *
9 : : * This program is distributed in the hope that it will be useful, but WITHOUT
10 : : * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 : : * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 : : * more details.
13 : : *
14 : : * You should have received a copy of the GNU General Public License along with
15 : : * this program; if not, write to the Free Software Foundation, Inc., 51
16 : : * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17 : : */
18 : :
19 : : #include "conf.h"
20 : : #include "test/framework.h"
21 : : #include "test/util.h"
22 : :
23 : : #define N_CONFIG_ITEMS 27
24 : : static struct {
25 : : char *descr;
26 : : const char *origin;
27 : : } received_conf_items[N_CONFIG_ITEMS];
28 : : static size_t n_received_conf_items = 0;
29 : :
30 : : static void
31 : 27 : conf_item_receiver(const char *descr, const char *origin, void *context)
32 : : {
33 : : (void)context;
34 : 27 : received_conf_items[n_received_conf_items].descr = x_strdup(descr);
35 : 27 : received_conf_items[n_received_conf_items].origin = origin;
36 : 27 : ++n_received_conf_items;
37 : 27 : }
38 : :
39 : : static void
40 : 1 : free_received_conf_items(void)
41 : : {
42 [ + + ]: 28 : while (n_received_conf_items > 0) {
43 : 27 : --n_received_conf_items;
44 : 27 : free(received_conf_items[n_received_conf_items].descr);
45 : : }
46 : 1 : }
47 : :
48 : 1 : TEST_SUITE(conf)
49 : :
50 [ + - ]: 1 : TEST(conf_create)
51 : : {
52 : 1 : struct conf *conf = conf_create();
53 [ - + ]: 1 : CHECK_STR_EQ("", conf->base_dir);
54 [ - + ]: 1 : CHECK_STR_EQ_FREE1(format("%s/.ccache", get_home_directory()),
55 : : conf->cache_dir);
56 [ - + ]: 1 : CHECK_INT_EQ(2, conf->cache_dir_levels);
57 [ - + ]: 1 : CHECK_STR_EQ("", conf->compiler);
58 [ - + ]: 1 : CHECK_STR_EQ("mtime", conf->compiler_check);
59 [ + - ]: 1 : CHECK(!conf->compression);
60 [ - + ]: 1 : CHECK_INT_EQ(6, conf->compression_level);
61 [ - + ]: 1 : CHECK_STR_EQ("", conf->cpp_extension);
62 [ + - ]: 1 : CHECK(conf->direct_mode);
63 [ + - ]: 1 : CHECK(!conf->disable);
64 [ - + ]: 1 : CHECK_STR_EQ("", conf->extra_files_to_hash);
65 [ + - ]: 1 : CHECK(!conf->hard_link);
66 [ + - ]: 1 : CHECK(!conf->hash_dir);
67 [ - + ]: 1 : CHECK_STR_EQ("", conf->log_file);
68 [ - + ]: 1 : CHECK_INT_EQ(0, conf->max_files);
69 [ - + ]: 1 : CHECK_INT_EQ((uint64_t)5 * 1000 * 1000 * 1000, conf->max_size);
70 [ - + ]: 1 : CHECK_STR_EQ("", conf->path);
71 [ - + ]: 1 : CHECK_STR_EQ("", conf->prefix_command);
72 [ + - ]: 1 : CHECK(!conf->read_only);
73 [ + - ]: 1 : CHECK(!conf->read_only_direct);
74 [ + - ]: 1 : CHECK(!conf->recache);
75 [ + - ]: 1 : CHECK(!conf->run_second_cpp);
76 [ - + ]: 1 : CHECK_INT_EQ(0, conf->sloppiness);
77 [ + - ]: 1 : CHECK(conf->stats);
78 [ - + ]: 1 : CHECK_STR_EQ("", conf->temporary_dir);
79 [ - + ]: 1 : CHECK_INT_EQ(UINT_MAX, conf->umask);
80 [ + - ]: 1 : CHECK(!conf->unify);
81 : 1 : conf_free(conf);
82 : : }
83 : :
84 [ + - ]: 1 : TEST(conf_read_valid_config)
85 : : {
86 : 1 : struct conf *conf = conf_create();
87 : : char *errmsg, *user;
88 : 1 : putenv("USER=rabbit");
89 : 1 : user = getenv("USER");
90 [ - + ]: 1 : CHECK_STR_EQ("rabbit", user);
91 : 1 : create_file(
92 : : "ccache.conf",
93 : : "base_dir = /$USER/foo/${USER} \n"
94 : : "cache_dir=\n"
95 : : "cache_dir = $USER$/${USER}/.ccache\n"
96 : : "\n"
97 : : "\n"
98 : : " #A comment\n"
99 : : " cache_dir_levels = 4\n"
100 : : "\t compiler = foo\n"
101 : : "compiler_check = none\n"
102 : : "compression=true\n"
103 : : "compression_level= 2\n"
104 : : "cpp_extension = .foo\n"
105 : : "direct_mode = false\n"
106 : : "disable = true\n"
107 : : "extra_files_to_hash = a:b c:$USER\n"
108 : : "hard_link = true\n"
109 : : "hash_dir = true\n"
110 : : "log_file = $USER${USER} \n"
111 : : "max_files = 17\n"
112 : : "max_size = 123M\n"
113 : : "path = $USER.x\n"
114 : : "prefix_command = x$USER\n"
115 : : "read_only = true\n"
116 : : "read_only_direct = true\n"
117 : : "recache = true\n"
118 : : "run_second_cpp = true\n"
119 : : "sloppiness = file_macro ,time_macros, include_file_mtime,include_file_ctime,file_stat_matches pch_defines \n"
120 : : "stats = false\n"
121 : : "temporary_dir = ${USER}_foo\n"
122 : : "umask = 777\n"
123 : : "unify = true"); /* Note: no newline */
124 [ + - ]: 1 : CHECK(conf_read(conf, "ccache.conf", &errmsg));
125 [ + - ]: 1 : CHECK(!errmsg);
126 : :
127 [ - + ]: 1 : CHECK_STR_EQ_FREE1(format("/%s/foo/%s", user, user), conf->base_dir);
128 [ - + ]: 1 : CHECK_STR_EQ_FREE1(format("%s$/%s/.ccache", user, user), conf->cache_dir);
129 [ - + ]: 1 : CHECK_INT_EQ(4, conf->cache_dir_levels);
130 [ - + ]: 1 : CHECK_STR_EQ("foo", conf->compiler);
131 [ - + ]: 1 : CHECK_STR_EQ("none", conf->compiler_check);
132 [ + - ]: 1 : CHECK(conf->compression);
133 [ - + ]: 1 : CHECK_INT_EQ(2, conf->compression_level);
134 [ - + ]: 1 : CHECK_STR_EQ(".foo", conf->cpp_extension);
135 [ + - ]: 1 : CHECK(!conf->direct_mode);
136 [ + - ]: 1 : CHECK(conf->disable);
137 [ - + ]: 1 : CHECK_STR_EQ_FREE1(format("a:b c:%s", user), conf->extra_files_to_hash);
138 [ + - ]: 1 : CHECK(conf->hard_link);
139 [ + - ]: 1 : CHECK(conf->hash_dir);
140 [ - + ]: 1 : CHECK_STR_EQ_FREE1(format("%s%s", user, user), conf->log_file);
141 [ - + ]: 1 : CHECK_INT_EQ(17, conf->max_files);
142 [ - + ]: 1 : CHECK_INT_EQ(123 * 1000 * 1000, conf->max_size);
143 [ - + ]: 1 : CHECK_STR_EQ_FREE1(format("%s.x", user), conf->path);
144 [ - + ]: 1 : CHECK_STR_EQ_FREE1(format("x%s", user), conf->prefix_command);
145 [ + - ]: 1 : CHECK(conf->read_only);
146 [ + - ]: 1 : CHECK(conf->read_only_direct);
147 [ + - ]: 1 : CHECK(conf->recache);
148 [ + - ]: 1 : CHECK(conf->run_second_cpp);
149 [ - + ]: 1 : CHECK_INT_EQ(SLOPPY_INCLUDE_FILE_MTIME|SLOPPY_INCLUDE_FILE_CTIME|
150 : : SLOPPY_FILE_MACRO|SLOPPY_TIME_MACROS|
151 : : SLOPPY_FILE_STAT_MATCHES|SLOPPY_PCH_DEFINES,
152 : : conf->sloppiness);
153 [ + - ]: 1 : CHECK(!conf->stats);
154 [ - + ]: 1 : CHECK_STR_EQ_FREE1(format("%s_foo", user), conf->temporary_dir);
155 [ - + ]: 1 : CHECK_INT_EQ(0777, conf->umask);
156 [ + - ]: 1 : CHECK(conf->unify);
157 : :
158 : 1 : conf_free(conf);
159 : : }
160 : :
161 [ + - ]: 1 : TEST(conf_read_with_missing_equal_sign)
162 : : {
163 : 1 : struct conf *conf = conf_create();
164 : : char *errmsg;
165 : 1 : create_file("ccache.conf", "no equal sign");
166 [ + - ]: 1 : CHECK(!conf_read(conf, "ccache.conf", &errmsg));
167 [ - + ]: 1 : CHECK_STR_EQ_FREE2("ccache.conf:1: missing equal sign",
168 : : errmsg);
169 : 1 : conf_free(conf);
170 : : }
171 : :
172 [ + - ]: 1 : TEST(conf_read_with_bad_config_key)
173 : : {
174 : 1 : struct conf *conf = conf_create();
175 : : char *errmsg;
176 : 1 : create_file("ccache.conf", "# Comment\nfoo = bar");
177 [ + - ]: 1 : CHECK(!conf_read(conf, "ccache.conf", &errmsg));
178 [ - + ]: 1 : CHECK_STR_EQ_FREE2("ccache.conf:2: unknown configuration option \"foo\"",
179 : : errmsg);
180 : 1 : conf_free(conf);
181 : : }
182 : :
183 [ + - ]: 1 : TEST(conf_read_invalid_bool)
184 : : {
185 : 1 : struct conf *conf = conf_create();
186 : : char *errmsg;
187 : :
188 : 1 : create_file("ccache.conf", "disable=");
189 [ + - ]: 1 : CHECK(!conf_read(conf, "ccache.conf", &errmsg));
190 [ - + ]: 1 : CHECK_STR_EQ_FREE2("ccache.conf:1: not a boolean value: \"\"",
191 : : errmsg);
192 : :
193 : 1 : create_file("ccache.conf", "disable=foo");
194 [ + - ]: 1 : CHECK(!conf_read(conf, "ccache.conf", &errmsg));
195 [ - + ]: 1 : CHECK_STR_EQ_FREE2("ccache.conf:1: not a boolean value: \"foo\"",
196 : : errmsg);
197 : 1 : conf_free(conf);
198 : : }
199 : :
200 [ + - ]: 1 : TEST(conf_read_invalid_env_string)
201 : : {
202 : 1 : struct conf *conf = conf_create();
203 : : char *errmsg;
204 : 1 : create_file("ccache.conf", "base_dir = ${foo");
205 [ + - ]: 1 : CHECK(!conf_read(conf, "ccache.conf", &errmsg));
206 [ - + ]: 1 : CHECK_STR_EQ_FREE2("ccache.conf:1: syntax error: missing '}' after \"foo\"",
207 : : errmsg);
208 : : /* Other cases tested in test_util.c. */
209 : 1 : conf_free(conf);
210 : : }
211 : :
212 [ + - ]: 1 : TEST(conf_read_empty_umask)
213 : : {
214 : 1 : struct conf *conf = conf_create();
215 : : char *errmsg;
216 : 1 : create_file("ccache.conf", "umask = ");
217 [ + - ]: 1 : CHECK(conf_read(conf, "ccache.conf", &errmsg));
218 [ - + ]: 1 : CHECK_INT_EQ(conf->umask, UINT_MAX);
219 : 1 : conf_free(conf);
220 : : }
221 : :
222 [ + - ]: 1 : TEST(conf_read_invalid_size)
223 : : {
224 : 1 : struct conf *conf = conf_create();
225 : : char *errmsg;
226 : 1 : create_file("ccache.conf", "max_size = foo");
227 [ + - ]: 1 : CHECK(!conf_read(conf, "ccache.conf", &errmsg));
228 [ - + ]: 1 : CHECK_STR_EQ_FREE2("ccache.conf:1: invalid size: \"foo\"",
229 : : errmsg);
230 : : /* Other cases tested in test_util.c. */
231 : 1 : conf_free(conf);
232 : : }
233 : :
234 [ + - ]: 1 : TEST(conf_read_invalid_sloppiness)
235 : : {
236 : 1 : struct conf *conf = conf_create();
237 : : char *errmsg;
238 : 1 : create_file("ccache.conf", "sloppiness = file_macro, foo");
239 [ + - ]: 1 : CHECK(!conf_read(conf, "ccache.conf", &errmsg));
240 [ - + ]: 1 : CHECK_STR_EQ_FREE2("ccache.conf:1: unknown sloppiness: \"foo\"",
241 : : errmsg);
242 : 1 : conf_free(conf);
243 : : }
244 : :
245 [ + - ]: 1 : TEST(conf_read_invalid_unsigned)
246 : : {
247 : 1 : struct conf *conf = conf_create();
248 : : char *errmsg;
249 : :
250 : 1 : create_file("ccache.conf", "max_files =");
251 [ + - ]: 1 : CHECK(!conf_read(conf, "ccache.conf", &errmsg));
252 [ - + ]: 1 : CHECK_STR_EQ_FREE2("ccache.conf:1: invalid unsigned integer: \"\"",
253 : : errmsg);
254 : :
255 : 1 : create_file("ccache.conf", "max_files = -42");
256 [ + - ]: 1 : CHECK(!conf_read(conf, "ccache.conf", &errmsg));
257 [ - + ]: 1 : CHECK_STR_EQ_FREE2("ccache.conf:1: invalid unsigned integer: \"-42\"",
258 : : errmsg);
259 : :
260 : 1 : create_file("ccache.conf", "max_files = foo");
261 [ + - ]: 1 : CHECK(!conf_read(conf, "ccache.conf", &errmsg));
262 [ - + ]: 1 : CHECK_STR_EQ_FREE2("ccache.conf:1: invalid unsigned integer: \"foo\"",
263 : : errmsg);
264 : :
265 : 1 : conf_free(conf);
266 : : }
267 : :
268 [ + - ]: 1 : TEST(verify_absolute_base_dir)
269 : : {
270 : 1 : struct conf *conf = conf_create();
271 : : char *errmsg;
272 : :
273 : 1 : create_file("ccache.conf", "base_dir = relative/path");
274 [ + - ]: 1 : CHECK(!conf_read(conf, "ccache.conf", &errmsg));
275 [ - + ]: 1 : CHECK_STR_EQ_FREE2("ccache.conf:1: not an absolute path: \"relative/path\"",
276 : : errmsg);
277 : :
278 : 1 : create_file("ccache.conf", "base_dir =");
279 [ + - ]: 1 : CHECK(conf_read(conf, "ccache.conf", &errmsg));
280 : :
281 : 1 : conf_free(conf);
282 : : }
283 : :
284 [ + - ]: 1 : TEST(verify_dir_levels)
285 : : {
286 : 1 : struct conf *conf = conf_create();
287 : : char *errmsg;
288 : :
289 : 1 : create_file("ccache.conf", "cache_dir_levels = 0");
290 [ + - ]: 1 : CHECK(!conf_read(conf, "ccache.conf", &errmsg));
291 [ - + ]: 1 : CHECK_STR_EQ_FREE2("ccache.conf:1: cache directory levels must be between 1 and 8",
292 : : errmsg);
293 : 1 : create_file("ccache.conf", "cache_dir_levels = 9");
294 [ + - ]: 1 : CHECK(!conf_read(conf, "ccache.conf", &errmsg));
295 [ - + ]: 1 : CHECK_STR_EQ_FREE2("ccache.conf:1: cache directory levels must be between 1 and 8",
296 : : errmsg);
297 : :
298 : 1 : conf_free(conf);
299 : : }
300 : :
301 [ + - ]: 1 : TEST(conf_update_from_environment)
302 : : {
303 : 1 : struct conf *conf = conf_create();
304 : : char *errmsg;
305 : :
306 : 1 : putenv("CCACHE_COMPRESS=1");
307 [ + - ]: 1 : CHECK(conf_update_from_environment(conf, &errmsg));
308 [ + - ]: 1 : CHECK(conf->compression);
309 : :
310 : 1 : x_unsetenv("CCACHE_COMPRESS");
311 : 1 : putenv("CCACHE_NOCOMPRESS=1");
312 [ + - ]: 1 : CHECK(conf_update_from_environment(conf, &errmsg));
313 [ + - ]: 1 : CHECK(!conf->compression);
314 : :
315 : 1 : conf_free(conf);
316 : : }
317 : :
318 [ + - ]: 1 : TEST(conf_set_new_value)
319 : : {
320 : : char *errmsg;
321 : : char *data;
322 : :
323 : 1 : create_file("ccache.conf", "path = vanilla\n");
324 [ + - ]: 1 : CHECK(conf_set_value_in_file("ccache.conf", "stats", "chocolate", &errmsg));
325 : 1 : data = read_text_file("ccache.conf", 0);
326 [ + - ]: 1 : CHECK(data);
327 [ - + ]: 1 : CHECK_STR_EQ_FREE2("path = vanilla\nstats = chocolate\n", data);
328 : : }
329 : :
330 [ + - ]: 1 : TEST(conf_set_existing_value)
331 : : {
332 : : char *errmsg;
333 : : char *data;
334 : :
335 : 1 : create_file("ccache.conf", "path = chocolate\nstats = chocolate\n");
336 [ + - ]: 1 : CHECK(conf_set_value_in_file("ccache.conf", "path", "vanilla", &errmsg));
337 : 1 : data = read_text_file("ccache.conf", 0);
338 [ + - ]: 1 : CHECK(data);
339 [ - + ]: 1 : CHECK_STR_EQ_FREE2("path = vanilla\nstats = chocolate\n", data);
340 : : }
341 : :
342 [ + - ]: 1 : TEST(conf_print_items)
343 : : {
344 : : size_t i;
345 : : struct conf conf = {
346 : : "bd",
347 : : "cd",
348 : : 7,
349 : : "c",
350 : : "cc",
351 : : true,
352 : : 8,
353 : : "ce",
354 : : false,
355 : : true,
356 : : "efth",
357 : : true,
358 : : true,
359 : : "lf",
360 : : 4711,
361 : : 98.7 * 1000 * 1000,
362 : : "p",
363 : : "pc",
364 : : true,
365 : : true,
366 : : true,
367 : : true,
368 : : SLOPPY_FILE_MACRO|SLOPPY_INCLUDE_FILE_MTIME|
369 : : SLOPPY_INCLUDE_FILE_CTIME|SLOPPY_TIME_MACROS|
370 : : SLOPPY_FILE_STAT_MATCHES,
371 : : false,
372 : : "td",
373 : : 022,
374 : : true,
375 : : NULL
376 : 1 : };
377 : 1 : size_t n = 0;
378 : :
379 : 1 : conf.item_origins = x_malloc(N_CONFIG_ITEMS * sizeof(char *));
380 [ + + ]: 28 : for (i = 0; i < N_CONFIG_ITEMS; ++i) {
381 : 27 : conf.item_origins[i] = format("origin%zu", i);
382 : : }
383 : :
384 : 1 : conf_print_items(&conf, conf_item_receiver, NULL);
385 [ - + ]: 1 : CHECK_INT_EQ(N_CONFIG_ITEMS, n_received_conf_items);
386 [ - + ]: 1 : CHECK_STR_EQ("base_dir = bd", received_conf_items[n++].descr);
387 [ - + ]: 1 : CHECK_STR_EQ("cache_dir = cd", received_conf_items[n++].descr);
388 [ - + ]: 1 : CHECK_STR_EQ("cache_dir_levels = 7", received_conf_items[n++].descr);
389 [ - + ]: 1 : CHECK_STR_EQ("compiler = c", received_conf_items[n++].descr);
390 [ - + ]: 1 : CHECK_STR_EQ("compiler_check = cc", received_conf_items[n++].descr);
391 [ - + ]: 1 : CHECK_STR_EQ("compression = true", received_conf_items[n++].descr);
392 [ - + ]: 1 : CHECK_STR_EQ("compression_level = 8", received_conf_items[n++].descr);
393 [ - + ]: 1 : CHECK_STR_EQ("cpp_extension = ce", received_conf_items[n++].descr);
394 [ - + ]: 1 : CHECK_STR_EQ("direct_mode = false", received_conf_items[n++].descr);
395 [ - + ]: 1 : CHECK_STR_EQ("disable = true", received_conf_items[n++].descr);
396 [ - + ]: 1 : CHECK_STR_EQ("extra_files_to_hash = efth", received_conf_items[n++].descr);
397 [ - + ]: 1 : CHECK_STR_EQ("hard_link = true", received_conf_items[n++].descr);
398 [ - + ]: 1 : CHECK_STR_EQ("hash_dir = true", received_conf_items[n++].descr);
399 [ - + ]: 1 : CHECK_STR_EQ("log_file = lf", received_conf_items[n++].descr);
400 [ - + ]: 1 : CHECK_STR_EQ("max_files = 4711", received_conf_items[n++].descr);
401 [ - + ]: 1 : CHECK_STR_EQ("max_size = 98.7M", received_conf_items[n++].descr);
402 [ - + ]: 1 : CHECK_STR_EQ("path = p", received_conf_items[n++].descr);
403 [ - + ]: 1 : CHECK_STR_EQ("prefix_command = pc", received_conf_items[n++].descr);
404 [ - + ]: 1 : CHECK_STR_EQ("read_only = true", received_conf_items[n++].descr);
405 [ - + ]: 1 : CHECK_STR_EQ("read_only_direct = true", received_conf_items[n++].descr);
406 [ - + ]: 1 : CHECK_STR_EQ("recache = true", received_conf_items[n++].descr);
407 [ - + ]: 1 : CHECK_STR_EQ("run_second_cpp = true", received_conf_items[n++].descr);
408 [ - + ]: 1 : CHECK_STR_EQ("sloppiness = file_macro, include_file_mtime,"
409 : : " include_file_ctime, time_macros, file_stat_matches",
410 : : received_conf_items[n++].descr);
411 [ - + ]: 1 : CHECK_STR_EQ("stats = false", received_conf_items[n++].descr);
412 [ - + ]: 1 : CHECK_STR_EQ("temporary_dir = td", received_conf_items[n++].descr);
413 [ - + ]: 1 : CHECK_STR_EQ("umask = 022", received_conf_items[n++].descr);
414 [ - + ]: 1 : CHECK_STR_EQ("unify = true", received_conf_items[n++].descr);
415 : :
416 [ + + ]: 28 : for (i = 0; i < N_CONFIG_ITEMS; ++i) {
417 : 27 : char *expected = format("origin%zu", i);
418 [ - + ]: 27 : CHECK_STR_EQ(expected, received_conf_items[i].origin);
419 : : }
420 : :
421 : 1 : free_received_conf_items();
422 : 1 : free(conf.item_origins);
423 : : }
424 : :
425 : 1 : TEST_SUITE_END
|