1 // Copyright (C) 2011-2018 Joel Rosdahl
3 // This program is free software; you can redistribute it and/or modify it
4 // under the terms of the GNU General Public License as published by the Free
5 // Software Foundation; either version 3 of the License, or (at your option)
8 // This program is distributed in the hope that it will be useful, but WITHOUT
9 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 // You should have received a copy of the GNU General Public License along with
14 // this program; if not, write to the Free Software Foundation, Inc., 51
15 // Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17 #include "../src/conf.h"
18 #include "framework.h"
21 #define N_CONFIG_ITEMS 33
25 } received_conf_items[N_CONFIG_ITEMS];
26 static size_t n_received_conf_items = 0;
29 conf_item_receiver(const char *descr, const char *origin, void *context)
32 received_conf_items[n_received_conf_items].descr = x_strdup(descr);
33 received_conf_items[n_received_conf_items].origin = x_strdup(origin);
34 ++n_received_conf_items;
38 free_received_conf_items(void)
40 while (n_received_conf_items > 0) {
41 --n_received_conf_items;
42 free(received_conf_items[n_received_conf_items].descr);
43 free(received_conf_items[n_received_conf_items].origin);
51 struct conf *conf = conf_create();
52 CHECK_STR_EQ("", conf->base_dir);
53 CHECK_STR_EQ_FREE1(format("%s/.ccache", get_home_directory()),
55 CHECK_INT_EQ(2, conf->cache_dir_levels);
56 CHECK_STR_EQ("", conf->compiler);
57 CHECK_STR_EQ("mtime", conf->compiler_check);
58 CHECK(!conf->compression);
59 CHECK_INT_EQ(6, conf->compression_level);
60 CHECK_STR_EQ("", conf->cpp_extension);
62 CHECK(conf->direct_mode);
63 CHECK(!conf->disable);
64 CHECK_STR_EQ("", conf->extra_files_to_hash);
65 CHECK(!conf->hard_link);
66 CHECK(conf->hash_dir);
67 CHECK_STR_EQ("", conf->ignore_headers_in_manifest);
68 CHECK(!conf->keep_comments_cpp);
69 CHECK_DOUBLE_EQ(0.8, conf->limit_multiple);
70 CHECK_STR_EQ("", conf->log_file);
71 CHECK_INT_EQ(0, conf->max_files);
72 CHECK_INT_EQ((uint64_t)5 * 1000 * 1000 * 1000, conf->max_size);
73 CHECK_STR_EQ("", conf->path);
74 CHECK(!conf->pch_external_checksum);
75 CHECK_STR_EQ("", conf->prefix_command);
76 CHECK_STR_EQ("", conf->prefix_command_cpp);
77 CHECK(!conf->read_only);
78 CHECK(!conf->read_only_direct);
79 CHECK(!conf->recache);
80 CHECK(conf->run_second_cpp);
81 CHECK_INT_EQ(0, conf->sloppiness);
83 CHECK_STR_EQ("", conf->temporary_dir);
84 CHECK_INT_EQ(UINT_MAX, conf->umask);
89 TEST(conf_read_valid_config)
91 struct conf *conf = conf_create();
93 putenv("USER=rabbit");
94 user = getenv("USER");
95 CHECK_STR_EQ("rabbit", user);
99 "base_dir = /$USER/foo/${USER} \n"
101 "base_dir = C:/$USER/foo/${USER}\n"
104 "cache_dir = $USER$/${USER}/.ccache\n"
108 " cache_dir_levels = 4\n"
109 "\t compiler = foo\n"
110 "compiler_check = none\n"
112 "compression_level= 2\n"
113 "cpp_extension = .foo\n"
114 "direct_mode = false\n"
116 "extra_files_to_hash = a:b c:$USER\n"
119 "ignore_headers_in_manifest = a:b/c\n"
120 "keep_comments_cpp = true\n"
121 "limit_multiple = 1.0\n"
122 "log_file = $USER${USER} \n"
126 "pch_external_checksum = true\n"
127 "prefix_command = x$USER\n"
128 "prefix_command_cpp = y\n"
130 "read_only_direct = true\n"
132 "run_second_cpp = false\n"
133 "sloppiness = file_macro ,time_macros, include_file_mtime,include_file_ctime,file_stat_matches,file_stat_matches_ctime,pch_defines , no_system_headers \n"
135 "temporary_dir = ${USER}_foo\n"
137 "unify = true"); // Note: no newline.
138 CHECK(conf_read(conf, "ccache.conf", &errmsg));
142 CHECK_STR_EQ_FREE1(format("/%s/foo/%s", user, user), conf->base_dir);
144 CHECK_STR_EQ_FREE1(format("C:/%s/foo/%s", user, user), conf->base_dir);
146 CHECK_STR_EQ_FREE1(format("%s$/%s/.ccache", user, user), conf->cache_dir);
147 CHECK_INT_EQ(4, conf->cache_dir_levels);
148 CHECK_STR_EQ("foo", conf->compiler);
149 CHECK_STR_EQ("none", conf->compiler_check);
150 CHECK(conf->compression);
151 CHECK_INT_EQ(2, conf->compression_level);
152 CHECK_STR_EQ(".foo", conf->cpp_extension);
153 CHECK(!conf->direct_mode);
154 CHECK(conf->disable);
155 CHECK_STR_EQ_FREE1(format("a:b c:%s", user), conf->extra_files_to_hash);
156 CHECK(conf->hard_link);
157 CHECK(!conf->hash_dir);
158 CHECK_STR_EQ("a:b/c", conf->ignore_headers_in_manifest);
159 CHECK(conf->keep_comments_cpp);
160 CHECK_DOUBLE_EQ(1.0, conf->limit_multiple);
161 CHECK_STR_EQ_FREE1(format("%s%s", user, user), conf->log_file);
162 CHECK_INT_EQ(17, conf->max_files);
163 CHECK_INT_EQ(123 * 1000 * 1000, conf->max_size);
164 CHECK_STR_EQ_FREE1(format("%s.x", user), conf->path);
165 CHECK(conf->pch_external_checksum);
166 CHECK_STR_EQ_FREE1(format("x%s", user), conf->prefix_command);
167 CHECK_STR_EQ("y", conf->prefix_command_cpp);
168 CHECK(conf->read_only);
169 CHECK(conf->read_only_direct);
170 CHECK(conf->recache);
171 CHECK(!conf->run_second_cpp);
172 CHECK_INT_EQ(SLOPPY_INCLUDE_FILE_MTIME|SLOPPY_INCLUDE_FILE_CTIME|
173 SLOPPY_FILE_MACRO|SLOPPY_TIME_MACROS|
174 SLOPPY_FILE_STAT_MATCHES|SLOPPY_FILE_STAT_MATCHES_CTIME|
175 SLOPPY_NO_SYSTEM_HEADERS|SLOPPY_PCH_DEFINES,
178 CHECK_STR_EQ_FREE1(format("%s_foo", user), conf->temporary_dir);
179 CHECK_INT_EQ(0777, conf->umask);
185 TEST(conf_read_with_missing_equal_sign)
187 struct conf *conf = conf_create();
189 create_file("ccache.conf", "no equal sign");
190 CHECK(!conf_read(conf, "ccache.conf", &errmsg));
191 CHECK_INT_EQ(errno, 0);
192 CHECK_STR_EQ_FREE2("ccache.conf:1: missing equal sign",
197 TEST(conf_read_with_bad_config_key)
199 struct conf *conf = conf_create();
201 create_file("ccache.conf", "# Comment\nfoo = bar");
202 CHECK(!conf_read(conf, "ccache.conf", &errmsg));
203 CHECK_INT_EQ(errno, 0);
204 CHECK_STR_EQ_FREE2("ccache.conf:2: unknown configuration option \"foo\"",
209 TEST(conf_read_invalid_bool)
211 struct conf *conf = conf_create();
214 create_file("ccache.conf", "disable=");
215 CHECK(!conf_read(conf, "ccache.conf", &errmsg));
216 CHECK_INT_EQ(errno, 0);
217 CHECK_STR_EQ_FREE2("ccache.conf:1: not a boolean value: \"\"",
220 create_file("ccache.conf", "disable=foo");
221 CHECK(!conf_read(conf, "ccache.conf", &errmsg));
222 CHECK_INT_EQ(errno, 0);
223 CHECK_STR_EQ_FREE2("ccache.conf:1: not a boolean value: \"foo\"",
228 TEST(conf_read_invalid_env_string)
230 struct conf *conf = conf_create();
232 create_file("ccache.conf", "base_dir = ${foo");
233 CHECK(!conf_read(conf, "ccache.conf", &errmsg));
234 CHECK_INT_EQ(errno, 0);
235 CHECK_STR_EQ_FREE2("ccache.conf:1: syntax error: missing '}' after \"foo\"",
237 // Other cases tested in test_util.c.
241 TEST(conf_read_empty_umask)
243 struct conf *conf = conf_create();
245 create_file("ccache.conf", "umask = ");
246 CHECK(conf_read(conf, "ccache.conf", &errmsg));
247 CHECK_INT_EQ(conf->umask, UINT_MAX);
251 TEST(conf_read_invalid_size)
253 struct conf *conf = conf_create();
255 create_file("ccache.conf", "max_size = foo");
256 CHECK(!conf_read(conf, "ccache.conf", &errmsg));
257 CHECK_INT_EQ(errno, 0);
258 CHECK_STR_EQ_FREE2("ccache.conf:1: invalid size: \"foo\"",
260 // Other cases tested in test_util.c.
264 TEST(conf_read_invalid_sloppiness)
266 struct conf *conf = conf_create();
268 create_file("ccache.conf", "sloppiness = file_macro, foo");
269 CHECK(!conf_read(conf, "ccache.conf", &errmsg));
270 CHECK_INT_EQ(errno, 0);
271 CHECK_STR_EQ_FREE2("ccache.conf:1: unknown sloppiness: \"foo\"",
276 TEST(conf_read_invalid_unsigned)
278 struct conf *conf = conf_create();
281 create_file("ccache.conf", "max_files =");
282 CHECK(!conf_read(conf, "ccache.conf", &errmsg));
283 CHECK_INT_EQ(errno, 0);
284 CHECK_STR_EQ_FREE2("ccache.conf:1: invalid unsigned integer: \"\"",
287 create_file("ccache.conf", "max_files = -42");
288 CHECK(!conf_read(conf, "ccache.conf", &errmsg));
289 CHECK_STR_EQ_FREE2("ccache.conf:1: invalid unsigned integer: \"-42\"",
292 create_file("ccache.conf", "max_files = foo");
293 CHECK(!conf_read(conf, "ccache.conf", &errmsg));
294 CHECK_STR_EQ_FREE2("ccache.conf:1: invalid unsigned integer: \"foo\"",
300 TEST(conf_read_missing_config_file)
302 struct conf *conf = conf_create();
304 CHECK(!conf_read(conf, "ccache.conf", &errmsg));
305 CHECK_INT_EQ(errno, ENOENT);
308 TEST(verify_absolute_base_dir)
310 struct conf *conf = conf_create();
313 create_file("ccache.conf", "base_dir = relative/path");
314 CHECK(!conf_read(conf, "ccache.conf", &errmsg));
315 CHECK_STR_EQ_FREE2("ccache.conf:1: not an absolute path: \"relative/path\"",
318 create_file("ccache.conf", "base_dir =");
319 CHECK(conf_read(conf, "ccache.conf", &errmsg));
324 TEST(verify_dir_levels)
326 struct conf *conf = conf_create();
329 create_file("ccache.conf", "cache_dir_levels = 0");
330 CHECK(!conf_read(conf, "ccache.conf", &errmsg));
332 "ccache.conf:1: cache directory levels must be between 1 and 8",
334 create_file("ccache.conf", "cache_dir_levels = 9");
335 CHECK(!conf_read(conf, "ccache.conf", &errmsg));
337 "ccache.conf:1: cache directory levels must be between 1 and 8",
343 TEST(conf_update_from_environment)
345 struct conf *conf = conf_create();
348 putenv("CCACHE_COMPRESS=1");
349 CHECK(conf_update_from_environment(conf, &errmsg));
350 CHECK(conf->compression);
352 x_unsetenv("CCACHE_COMPRESS");
353 putenv("CCACHE_NOCOMPRESS=1");
354 CHECK(conf_update_from_environment(conf, &errmsg));
355 CHECK(!conf->compression);
360 TEST(conf_set_new_value)
365 create_file("ccache.conf", "path = vanilla\n");
366 CHECKM(conf_set_value_in_file("ccache.conf", "stats", "chocolate", &errmsg),
368 data = read_text_file("ccache.conf", 0);
370 CHECK_STR_EQ_FREE2("path = vanilla\nstats = chocolate\n", data);
373 TEST(conf_set_existing_value)
378 create_file("ccache.conf", "path = chocolate\nstats = chocolate\n");
379 CHECKM(conf_set_value_in_file("ccache.conf", "path", "vanilla", &errmsg),
381 data = read_text_file("ccache.conf", 0);
383 CHECK_STR_EQ_FREE2("path = vanilla\nstats = chocolate\n", data);
386 TEST(conf_print_existing_value)
388 struct conf *conf = conf_create();
389 conf->max_files = 42;
392 FILE *log = fopen("log", "w");
394 CHECK(conf_print_value(conf, "max_files", log, &errmsg));
398 FILE *log = fopen("log", "r");
401 CHECK(fgets(buf, sizeof(buf), log));
402 CHECK_STR_EQ("42\n", buf);
408 TEST(conf_print_unknown_value)
410 struct conf *conf = conf_create();
413 FILE *log = fopen("log", "w");
415 CHECK(!conf_print_value(conf, "foo", log, &errmsg));
416 CHECK_STR_EQ_FREE2("unknown configuration option \"foo\"",
421 FILE *log = fopen("log", "r");
424 CHECK(!fgets(buf, sizeof(buf), log));
430 TEST(conf_print_items)
461 .run_second_cpp = false,
462 SLOPPY_FILE_MACRO|SLOPPY_INCLUDE_FILE_MTIME|
463 SLOPPY_INCLUDE_FILE_CTIME|SLOPPY_TIME_MACROS|
464 SLOPPY_FILE_STAT_MATCHES|SLOPPY_FILE_STAT_MATCHES_CTIME|
465 SLOPPY_PCH_DEFINES|SLOPPY_NO_SYSTEM_HEADERS,
474 conf.item_origins = x_malloc(N_CONFIG_ITEMS * sizeof(char *));
475 for (i = 0; i < N_CONFIG_ITEMS; ++i) {
477 conf.item_origins[i] = format("origin%zu", i);
479 conf.item_origins[i] = format("origin%u", (unsigned) i);
483 conf_print_items(&conf, conf_item_receiver, NULL);
484 CHECK_INT_EQ(N_CONFIG_ITEMS, n_received_conf_items);
485 CHECK_STR_EQ("base_dir = bd", received_conf_items[n++].descr);
486 CHECK_STR_EQ("cache_dir = cd", received_conf_items[n++].descr);
487 CHECK_STR_EQ("cache_dir_levels = 7", received_conf_items[n++].descr);
488 CHECK_STR_EQ("compiler = c", received_conf_items[n++].descr);
489 CHECK_STR_EQ("compiler_check = cc", received_conf_items[n++].descr);
490 CHECK_STR_EQ("compression = true", received_conf_items[n++].descr);
491 CHECK_STR_EQ("compression_level = 8", received_conf_items[n++].descr);
492 CHECK_STR_EQ("cpp_extension = ce", received_conf_items[n++].descr);
493 CHECK_STR_EQ("debug = false", received_conf_items[n++].descr);
494 CHECK_STR_EQ("direct_mode = false", received_conf_items[n++].descr);
495 CHECK_STR_EQ("disable = true", received_conf_items[n++].descr);
496 CHECK_STR_EQ("extra_files_to_hash = efth", received_conf_items[n++].descr);
497 CHECK_STR_EQ("hard_link = true", received_conf_items[n++].descr);
498 CHECK_STR_EQ("hash_dir = false", received_conf_items[n++].descr);
499 CHECK_STR_EQ("ignore_headers_in_manifest = ihim",
500 received_conf_items[n++].descr);
501 CHECK_STR_EQ("keep_comments_cpp = true", received_conf_items[n++].descr);
502 CHECK_STR_EQ("limit_multiple = 0.0", received_conf_items[n++].descr);
503 CHECK_STR_EQ("log_file = lf", received_conf_items[n++].descr);
504 CHECK_STR_EQ("max_files = 4711", received_conf_items[n++].descr);
505 CHECK_STR_EQ("max_size = 98.7M", received_conf_items[n++].descr);
506 CHECK_STR_EQ("path = p", received_conf_items[n++].descr);
507 CHECK_STR_EQ("pch_external_checksum = true", received_conf_items[n++].descr);
508 CHECK_STR_EQ("prefix_command = pc", received_conf_items[n++].descr);
509 CHECK_STR_EQ("prefix_command_cpp = pcc", received_conf_items[n++].descr);
510 CHECK_STR_EQ("read_only = true", received_conf_items[n++].descr);
511 CHECK_STR_EQ("read_only_direct = true", received_conf_items[n++].descr);
512 CHECK_STR_EQ("recache = true", received_conf_items[n++].descr);
513 CHECK_STR_EQ("run_second_cpp = false", received_conf_items[n++].descr);
514 CHECK_STR_EQ("sloppiness = file_macro, include_file_mtime,"
515 " include_file_ctime, time_macros, pch_defines,"
516 " file_stat_matches, file_stat_matches_ctime, no_system_headers",
517 received_conf_items[n++].descr);
518 CHECK_STR_EQ("stats = false", received_conf_items[n++].descr);
519 CHECK_STR_EQ("temporary_dir = td", received_conf_items[n++].descr);
520 CHECK_STR_EQ("umask = 022", received_conf_items[n++].descr);
521 CHECK_STR_EQ("unify = true", received_conf_items[n++].descr);
523 for (i = 0; i < N_CONFIG_ITEMS; ++i) {
525 char *expected = format("origin%zu", i);
527 char *expected = format("origin%u", (unsigned) i);
529 CHECK_STR_EQ_FREE1(expected, received_conf_items[i].origin);
532 free_received_conf_items();
533 free(conf.item_origins);