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 31
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 = 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);
50 struct conf *conf = conf_create();
51 CHECK_STR_EQ("", conf->base_dir);
52 CHECK_STR_EQ_FREE1(format("%s/.ccache", get_home_directory()),
54 CHECK_INT_EQ(2, conf->cache_dir_levels);
55 CHECK_STR_EQ("", conf->compiler);
56 CHECK_STR_EQ("mtime", conf->compiler_check);
57 CHECK(!conf->compression);
58 CHECK_INT_EQ(6, conf->compression_level);
59 CHECK_STR_EQ("", conf->cpp_extension);
60 CHECK(conf->direct_mode);
61 CHECK(!conf->disable);
62 CHECK_STR_EQ("", conf->extra_files_to_hash);
63 CHECK(!conf->hard_link);
64 CHECK(conf->hash_dir);
65 CHECK_STR_EQ("", conf->ignore_headers_in_manifest);
66 CHECK(!conf->keep_comments_cpp);
67 CHECK_FLOAT_EQ(0.8f, conf->limit_multiple);
68 CHECK_STR_EQ("", conf->log_file);
69 CHECK_INT_EQ(0, conf->max_files);
70 CHECK_INT_EQ((uint64_t)5 * 1000 * 1000 * 1000, conf->max_size);
71 CHECK_STR_EQ("", conf->path);
72 CHECK_STR_EQ("", conf->prefix_command);
73 CHECK_STR_EQ("", conf->prefix_command_cpp);
74 CHECK(!conf->read_only);
75 CHECK(!conf->read_only_direct);
76 CHECK(!conf->recache);
77 CHECK(conf->run_second_cpp);
78 CHECK_INT_EQ(0, conf->sloppiness);
80 CHECK_STR_EQ("", conf->temporary_dir);
81 CHECK_INT_EQ(UINT_MAX, conf->umask);
86 TEST(conf_read_valid_config)
88 struct conf *conf = conf_create();
90 putenv("USER=rabbit");
91 user = getenv("USER");
92 CHECK_STR_EQ("rabbit", user);
96 "base_dir = /$USER/foo/${USER} \n"
98 "base_dir = C:/$USER/foo/${USER}\n"
101 "cache_dir = $USER$/${USER}/.ccache\n"
105 " cache_dir_levels = 4\n"
106 "\t compiler = foo\n"
107 "compiler_check = none\n"
109 "compression_level= 2\n"
110 "cpp_extension = .foo\n"
111 "direct_mode = false\n"
113 "extra_files_to_hash = a:b c:$USER\n"
116 "ignore_headers_in_manifest = a:b/c\n"
117 "keep_comments_cpp = true\n"
118 "limit_multiple = 1.0\n"
119 "log_file = $USER${USER} \n"
123 "prefix_command = x$USER\n"
124 "prefix_command_cpp = y\n"
126 "read_only_direct = true\n"
128 "run_second_cpp = false\n"
129 "sloppiness = file_macro ,time_macros, include_file_mtime,include_file_ctime,file_stat_matches,pch_defines , no_system_headers \n"
131 "temporary_dir = ${USER}_foo\n"
133 "unify = true"); // Note: no newline.
134 CHECK(conf_read(conf, "ccache.conf", &errmsg));
138 CHECK_STR_EQ_FREE1(format("/%s/foo/%s", user, user), conf->base_dir);
140 CHECK_STR_EQ_FREE1(format("C:/%s/foo/%s", user, user), conf->base_dir);
142 CHECK_STR_EQ_FREE1(format("%s$/%s/.ccache", user, user), conf->cache_dir);
143 CHECK_INT_EQ(4, conf->cache_dir_levels);
144 CHECK_STR_EQ("foo", conf->compiler);
145 CHECK_STR_EQ("none", conf->compiler_check);
146 CHECK(conf->compression);
147 CHECK_INT_EQ(2, conf->compression_level);
148 CHECK_STR_EQ(".foo", conf->cpp_extension);
149 CHECK(!conf->direct_mode);
150 CHECK(conf->disable);
151 CHECK_STR_EQ_FREE1(format("a:b c:%s", user), conf->extra_files_to_hash);
152 CHECK(conf->hard_link);
153 CHECK(!conf->hash_dir);
154 CHECK_STR_EQ("a:b/c", conf->ignore_headers_in_manifest);
155 CHECK(conf->keep_comments_cpp);
156 CHECK_FLOAT_EQ(1.0, conf->limit_multiple);
157 CHECK_STR_EQ_FREE1(format("%s%s", user, user), conf->log_file);
158 CHECK_INT_EQ(17, conf->max_files);
159 CHECK_INT_EQ(123 * 1000 * 1000, conf->max_size);
160 CHECK_STR_EQ_FREE1(format("%s.x", user), conf->path);
161 CHECK_STR_EQ_FREE1(format("x%s", user), conf->prefix_command);
162 CHECK_STR_EQ("y", conf->prefix_command_cpp);
163 CHECK(conf->read_only);
164 CHECK(conf->read_only_direct);
165 CHECK(conf->recache);
166 CHECK(!conf->run_second_cpp);
167 CHECK_INT_EQ(SLOPPY_INCLUDE_FILE_MTIME|SLOPPY_INCLUDE_FILE_CTIME|
168 SLOPPY_FILE_MACRO|SLOPPY_TIME_MACROS|
169 SLOPPY_FILE_STAT_MATCHES|SLOPPY_NO_SYSTEM_HEADERS|
173 CHECK_STR_EQ_FREE1(format("%s_foo", user), conf->temporary_dir);
174 CHECK_INT_EQ(0777, conf->umask);
180 TEST(conf_read_with_missing_equal_sign)
182 struct conf *conf = conf_create();
184 create_file("ccache.conf", "no equal sign");
185 CHECK(!conf_read(conf, "ccache.conf", &errmsg));
186 CHECK_STR_EQ_FREE2("ccache.conf:1: missing equal sign",
191 TEST(conf_read_with_bad_config_key)
193 struct conf *conf = conf_create();
195 create_file("ccache.conf", "# Comment\nfoo = bar");
196 CHECK(!conf_read(conf, "ccache.conf", &errmsg));
197 CHECK_STR_EQ_FREE2("ccache.conf:2: unknown configuration option \"foo\"",
202 TEST(conf_read_invalid_bool)
204 struct conf *conf = conf_create();
207 create_file("ccache.conf", "disable=");
208 CHECK(!conf_read(conf, "ccache.conf", &errmsg));
209 CHECK_STR_EQ_FREE2("ccache.conf:1: not a boolean value: \"\"",
212 create_file("ccache.conf", "disable=foo");
213 CHECK(!conf_read(conf, "ccache.conf", &errmsg));
214 CHECK_STR_EQ_FREE2("ccache.conf:1: not a boolean value: \"foo\"",
219 TEST(conf_read_invalid_env_string)
221 struct conf *conf = conf_create();
223 create_file("ccache.conf", "base_dir = ${foo");
224 CHECK(!conf_read(conf, "ccache.conf", &errmsg));
225 CHECK_STR_EQ_FREE2("ccache.conf:1: syntax error: missing '}' after \"foo\"",
227 // Other cases tested in test_util.c.
231 TEST(conf_read_empty_umask)
233 struct conf *conf = conf_create();
235 create_file("ccache.conf", "umask = ");
236 CHECK(conf_read(conf, "ccache.conf", &errmsg));
237 CHECK_INT_EQ(conf->umask, UINT_MAX);
241 TEST(conf_read_invalid_size)
243 struct conf *conf = conf_create();
245 create_file("ccache.conf", "max_size = foo");
246 CHECK(!conf_read(conf, "ccache.conf", &errmsg));
247 CHECK_STR_EQ_FREE2("ccache.conf:1: invalid size: \"foo\"",
249 // Other cases tested in test_util.c.
253 TEST(conf_read_invalid_sloppiness)
255 struct conf *conf = conf_create();
257 create_file("ccache.conf", "sloppiness = file_macro, foo");
258 CHECK(!conf_read(conf, "ccache.conf", &errmsg));
259 CHECK_STR_EQ_FREE2("ccache.conf:1: unknown sloppiness: \"foo\"",
264 TEST(conf_read_invalid_unsigned)
266 struct conf *conf = conf_create();
269 create_file("ccache.conf", "max_files =");
270 CHECK(!conf_read(conf, "ccache.conf", &errmsg));
271 CHECK_STR_EQ_FREE2("ccache.conf:1: invalid unsigned integer: \"\"",
274 create_file("ccache.conf", "max_files = -42");
275 CHECK(!conf_read(conf, "ccache.conf", &errmsg));
276 CHECK_STR_EQ_FREE2("ccache.conf:1: invalid unsigned integer: \"-42\"",
279 create_file("ccache.conf", "max_files = foo");
280 CHECK(!conf_read(conf, "ccache.conf", &errmsg));
281 CHECK_STR_EQ_FREE2("ccache.conf:1: invalid unsigned integer: \"foo\"",
287 TEST(verify_absolute_base_dir)
289 struct conf *conf = conf_create();
292 create_file("ccache.conf", "base_dir = relative/path");
293 CHECK(!conf_read(conf, "ccache.conf", &errmsg));
294 CHECK_STR_EQ_FREE2("ccache.conf:1: not an absolute path: \"relative/path\"",
297 create_file("ccache.conf", "base_dir =");
298 CHECK(conf_read(conf, "ccache.conf", &errmsg));
303 TEST(verify_dir_levels)
305 struct conf *conf = conf_create();
308 create_file("ccache.conf", "cache_dir_levels = 0");
309 CHECK(!conf_read(conf, "ccache.conf", &errmsg));
311 "ccache.conf:1: cache directory levels must be between 1 and 8",
313 create_file("ccache.conf", "cache_dir_levels = 9");
314 CHECK(!conf_read(conf, "ccache.conf", &errmsg));
316 "ccache.conf:1: cache directory levels must be between 1 and 8",
322 TEST(conf_update_from_environment)
324 struct conf *conf = conf_create();
327 putenv("CCACHE_COMPRESS=1");
328 CHECK(conf_update_from_environment(conf, &errmsg));
329 CHECK(conf->compression);
331 x_unsetenv("CCACHE_COMPRESS");
332 putenv("CCACHE_NOCOMPRESS=1");
333 CHECK(conf_update_from_environment(conf, &errmsg));
334 CHECK(!conf->compression);
339 TEST(conf_set_new_value)
344 create_file("ccache.conf", "path = vanilla\n");
345 CHECKM(conf_set_value_in_file("ccache.conf", "stats", "chocolate", &errmsg),
347 data = read_text_file("ccache.conf", 0);
349 CHECK_STR_EQ_FREE2("path = vanilla\nstats = chocolate\n", data);
352 TEST(conf_set_existing_value)
357 create_file("ccache.conf", "path = chocolate\nstats = chocolate\n");
358 CHECKM(conf_set_value_in_file("ccache.conf", "path", "vanilla", &errmsg),
360 data = read_text_file("ccache.conf", 0);
362 CHECK_STR_EQ_FREE2("path = vanilla\nstats = chocolate\n", data);
365 TEST(conf_print_items)
394 .run_second_cpp = false,
395 SLOPPY_FILE_MACRO|SLOPPY_INCLUDE_FILE_MTIME|
396 SLOPPY_INCLUDE_FILE_CTIME|SLOPPY_TIME_MACROS|
397 SLOPPY_FILE_STAT_MATCHES|SLOPPY_PCH_DEFINES|
398 SLOPPY_NO_SYSTEM_HEADERS,
407 conf.item_origins = x_malloc(N_CONFIG_ITEMS * sizeof(char *));
408 for (i = 0; i < N_CONFIG_ITEMS; ++i) {
410 conf.item_origins[i] = format("origin%zu", i);
412 conf.item_origins[i] = format("origin%u", (unsigned) i);
416 conf_print_items(&conf, conf_item_receiver, NULL);
417 CHECK_INT_EQ(N_CONFIG_ITEMS, n_received_conf_items);
418 CHECK_STR_EQ("base_dir = bd", received_conf_items[n++].descr);
419 CHECK_STR_EQ("cache_dir = cd", received_conf_items[n++].descr);
420 CHECK_STR_EQ("cache_dir_levels = 7", received_conf_items[n++].descr);
421 CHECK_STR_EQ("compiler = c", received_conf_items[n++].descr);
422 CHECK_STR_EQ("compiler_check = cc", received_conf_items[n++].descr);
423 CHECK_STR_EQ("compression = true", received_conf_items[n++].descr);
424 CHECK_STR_EQ("compression_level = 8", received_conf_items[n++].descr);
425 CHECK_STR_EQ("cpp_extension = ce", received_conf_items[n++].descr);
426 CHECK_STR_EQ("direct_mode = false", received_conf_items[n++].descr);
427 CHECK_STR_EQ("disable = true", received_conf_items[n++].descr);
428 CHECK_STR_EQ("extra_files_to_hash = efth", received_conf_items[n++].descr);
429 CHECK_STR_EQ("hard_link = true", received_conf_items[n++].descr);
430 CHECK_STR_EQ("hash_dir = false", received_conf_items[n++].descr);
431 CHECK_STR_EQ("ignore_headers_in_manifest = ihim",
432 received_conf_items[n++].descr);
433 CHECK_STR_EQ("keep_comments_cpp = true", received_conf_items[n++].descr);
434 CHECK_STR_EQ("limit_multiple = 0.0", received_conf_items[n++].descr);
435 CHECK_STR_EQ("log_file = lf", received_conf_items[n++].descr);
436 CHECK_STR_EQ("max_files = 4711", received_conf_items[n++].descr);
437 CHECK_STR_EQ("max_size = 98.7M", received_conf_items[n++].descr);
438 CHECK_STR_EQ("path = p", received_conf_items[n++].descr);
439 CHECK_STR_EQ("prefix_command = pc", received_conf_items[n++].descr);
440 CHECK_STR_EQ("prefix_command_cpp = pcc", received_conf_items[n++].descr);
441 CHECK_STR_EQ("read_only = true", received_conf_items[n++].descr);
442 CHECK_STR_EQ("read_only_direct = true", received_conf_items[n++].descr);
443 CHECK_STR_EQ("recache = true", received_conf_items[n++].descr);
444 CHECK_STR_EQ("run_second_cpp = false", received_conf_items[n++].descr);
445 CHECK_STR_EQ("sloppiness = file_macro, include_file_mtime,"
446 " include_file_ctime, time_macros, pch_defines,"
447 " file_stat_matches, no_system_headers",
448 received_conf_items[n++].descr);
449 CHECK_STR_EQ("stats = false", received_conf_items[n++].descr);
450 CHECK_STR_EQ("temporary_dir = td", received_conf_items[n++].descr);
451 CHECK_STR_EQ("umask = 022", received_conf_items[n++].descr);
452 CHECK_STR_EQ("unify = true", received_conf_items[n++].descr);
454 for (i = 0; i < N_CONFIG_ITEMS; ++i) {
456 char *expected = format("origin%zu", i);
458 char *expected = format("origin%u", (unsigned) i);
460 CHECK_STR_EQ_FREE1(expected, received_conf_items[i].origin);
463 free_received_conf_items();
464 free(conf.item_origins);