Imported Upstream version 3.5.1
[platform/upstream/ccache.git] / unittest / test_conf.c
1 // Copyright (C) 2011-2018 Joel Rosdahl
2 //
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)
6 // any later version.
7 //
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
11 // more details.
12 //
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
16
17 #include "../src/conf.h"
18 #include "framework.h"
19 #include "util.h"
20
21 #define N_CONFIG_ITEMS 33
22 static struct {
23         char *descr;
24         char *origin;
25 } received_conf_items[N_CONFIG_ITEMS];
26 static size_t n_received_conf_items = 0;
27
28 static void
29 conf_item_receiver(const char *descr, const char *origin, void *context)
30 {
31         (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;
35 }
36
37 static void
38 free_received_conf_items(void)
39 {
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);
44         }
45 }
46
47 TEST_SUITE(conf)
48
49 TEST(conf_create)
50 {
51         struct conf *conf = conf_create();
52         CHECK_STR_EQ("", conf->base_dir);
53         CHECK_STR_EQ_FREE1(format("%s/.ccache", get_home_directory()),
54                            conf->cache_dir);
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);
61         CHECK(!conf->debug);
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);
82         CHECK(conf->stats);
83         CHECK_STR_EQ("", conf->temporary_dir);
84         CHECK_INT_EQ(UINT_MAX, conf->umask);
85         CHECK(!conf->unify);
86         conf_free(conf);
87 }
88
89 TEST(conf_read_valid_config)
90 {
91         struct conf *conf = conf_create();
92         char *errmsg, *user;
93         putenv("USER=rabbit");
94         user = getenv("USER");
95         CHECK_STR_EQ("rabbit", user);
96         create_file(
97                 "ccache.conf",
98 #ifndef _WIN32
99                 "base_dir =  /$USER/foo/${USER} \n"
100 #else
101                 "base_dir = C:/$USER/foo/${USER}\n"
102 #endif
103                 "cache_dir=\n"
104                 "cache_dir = $USER$/${USER}/.ccache\n"
105                 "\n"
106                 "\n"
107                 "  #A comment\n"
108                 " cache_dir_levels = 4\n"
109                 "\t compiler = foo\n"
110                 "compiler_check = none\n"
111                 "compression=true\n"
112                 "compression_level= 2\n"
113                 "cpp_extension = .foo\n"
114                 "direct_mode = false\n"
115                 "disable = true\n"
116                 "extra_files_to_hash = a:b c:$USER\n"
117                 "hard_link = true\n"
118                 "hash_dir = false\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"
123                 "max_files = 17\n"
124                 "max_size = 123M\n"
125                 "path = $USER.x\n"
126                 "pch_external_checksum = true\n"
127                 "prefix_command = x$USER\n"
128                 "prefix_command_cpp = y\n"
129                 "read_only = true\n"
130                 "read_only_direct = true\n"
131                 "recache = 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"
134                 "stats = false\n"
135                 "temporary_dir = ${USER}_foo\n"
136                 "umask = 777\n"
137                 "unify = true"); // Note: no newline.
138         CHECK(conf_read(conf, "ccache.conf", &errmsg));
139         CHECK(!errmsg);
140
141 #ifndef _WIN32
142         CHECK_STR_EQ_FREE1(format("/%s/foo/%s", user, user), conf->base_dir);
143 #else
144         CHECK_STR_EQ_FREE1(format("C:/%s/foo/%s", user, user), conf->base_dir);
145 #endif
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,
176                      conf->sloppiness);
177         CHECK(!conf->stats);
178         CHECK_STR_EQ_FREE1(format("%s_foo", user), conf->temporary_dir);
179         CHECK_INT_EQ(0777, conf->umask);
180         CHECK(conf->unify);
181
182         conf_free(conf);
183 }
184
185 TEST(conf_read_with_missing_equal_sign)
186 {
187         struct conf *conf = conf_create();
188         char *errmsg;
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",
193                            errmsg);
194         conf_free(conf);
195 }
196
197 TEST(conf_read_with_bad_config_key)
198 {
199         struct conf *conf = conf_create();
200         char *errmsg;
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\"",
205                            errmsg);
206         conf_free(conf);
207 }
208
209 TEST(conf_read_invalid_bool)
210 {
211         struct conf *conf = conf_create();
212         char *errmsg;
213
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: \"\"",
218                            errmsg);
219
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\"",
224                            errmsg);
225         conf_free(conf);
226 }
227
228 TEST(conf_read_invalid_env_string)
229 {
230         struct conf *conf = conf_create();
231         char *errmsg;
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\"",
236                            errmsg);
237         // Other cases tested in test_util.c.
238         conf_free(conf);
239 }
240
241 TEST(conf_read_empty_umask)
242 {
243         struct conf *conf = conf_create();
244         char *errmsg;
245         create_file("ccache.conf", "umask = ");
246         CHECK(conf_read(conf, "ccache.conf", &errmsg));
247         CHECK_INT_EQ(conf->umask, UINT_MAX);
248         conf_free(conf);
249 }
250
251 TEST(conf_read_invalid_size)
252 {
253         struct conf *conf = conf_create();
254         char *errmsg;
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\"",
259                            errmsg);
260         // Other cases tested in test_util.c.
261         conf_free(conf);
262 }
263
264 TEST(conf_read_invalid_sloppiness)
265 {
266         struct conf *conf = conf_create();
267         char *errmsg;
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\"",
272                            errmsg);
273         conf_free(conf);
274 }
275
276 TEST(conf_read_invalid_unsigned)
277 {
278         struct conf *conf = conf_create();
279         char *errmsg;
280
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: \"\"",
285                            errmsg);
286
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\"",
290                            errmsg);
291
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\"",
295                            errmsg);
296
297         conf_free(conf);
298 }
299
300 TEST(conf_read_missing_config_file)
301 {
302         struct conf *conf = conf_create();
303         char *errmsg;
304         CHECK(!conf_read(conf, "ccache.conf", &errmsg));
305         CHECK_INT_EQ(errno, ENOENT);
306 }
307
308 TEST(verify_absolute_base_dir)
309 {
310         struct conf *conf = conf_create();
311         char *errmsg;
312
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\"",
316                            errmsg);
317
318         create_file("ccache.conf", "base_dir =");
319         CHECK(conf_read(conf, "ccache.conf", &errmsg));
320
321         conf_free(conf);
322 }
323
324 TEST(verify_dir_levels)
325 {
326         struct conf *conf = conf_create();
327         char *errmsg;
328
329         create_file("ccache.conf", "cache_dir_levels = 0");
330         CHECK(!conf_read(conf, "ccache.conf", &errmsg));
331         CHECK_STR_EQ_FREE2(
332                 "ccache.conf:1: cache directory levels must be between 1 and 8",
333                 errmsg);
334         create_file("ccache.conf", "cache_dir_levels = 9");
335         CHECK(!conf_read(conf, "ccache.conf", &errmsg));
336         CHECK_STR_EQ_FREE2(
337                 "ccache.conf:1: cache directory levels must be between 1 and 8",
338                 errmsg);
339
340         conf_free(conf);
341 }
342
343 TEST(conf_update_from_environment)
344 {
345         struct conf *conf = conf_create();
346         char *errmsg;
347
348         putenv("CCACHE_COMPRESS=1");
349         CHECK(conf_update_from_environment(conf, &errmsg));
350         CHECK(conf->compression);
351
352         x_unsetenv("CCACHE_COMPRESS");
353         putenv("CCACHE_NOCOMPRESS=1");
354         CHECK(conf_update_from_environment(conf, &errmsg));
355         CHECK(!conf->compression);
356
357         conf_free(conf);
358 }
359
360 TEST(conf_set_new_value)
361 {
362         char *errmsg;
363         char *data;
364
365         create_file("ccache.conf", "path = vanilla\n");
366         CHECKM(conf_set_value_in_file("ccache.conf", "stats", "chocolate", &errmsg),
367                errmsg);
368         data = read_text_file("ccache.conf", 0);
369         CHECK(data);
370         CHECK_STR_EQ_FREE2("path = vanilla\nstats = chocolate\n", data);
371 }
372
373 TEST(conf_set_existing_value)
374 {
375         char *errmsg;
376         char *data;
377
378         create_file("ccache.conf", "path = chocolate\nstats = chocolate\n");
379         CHECKM(conf_set_value_in_file("ccache.conf", "path", "vanilla", &errmsg),
380                errmsg);
381         data = read_text_file("ccache.conf", 0);
382         CHECK(data);
383         CHECK_STR_EQ_FREE2("path = vanilla\nstats = chocolate\n", data);
384 }
385
386 TEST(conf_print_existing_value)
387 {
388         struct conf *conf = conf_create();
389         conf->max_files = 42;
390         char *errmsg;
391         {
392                 FILE *log = fopen("log", "w");
393                 CHECK(log);
394                 CHECK(conf_print_value(conf, "max_files", log, &errmsg));
395                 fclose(log);
396         }
397         {
398                 FILE *log = fopen("log", "r");
399                 CHECK(log);
400                 char buf[100];
401                 CHECK(fgets(buf, sizeof(buf), log));
402                 CHECK_STR_EQ("42\n", buf);
403                 fclose(log);
404         }
405         conf_free(conf);
406 }
407
408 TEST(conf_print_unknown_value)
409 {
410         struct conf *conf = conf_create();
411         char *errmsg;
412         {
413                 FILE *log = fopen("log", "w");
414                 CHECK(log);
415                 CHECK(!conf_print_value(conf, "foo", log, &errmsg));
416                 CHECK_STR_EQ_FREE2("unknown configuration option \"foo\"",
417                                    errmsg);
418                 fclose(log);
419         }
420         {
421                 FILE *log = fopen("log", "r");
422                 CHECK(log);
423                 char buf[100];
424                 CHECK(!fgets(buf, sizeof(buf), log));
425                 fclose(log);
426         }
427         conf_free(conf);
428 }
429
430 TEST(conf_print_items)
431 {
432         size_t i;
433         struct conf conf = {
434                 "bd",
435                 "cd",
436                 7,
437                 "c",
438                 "cc",
439                 true,
440                 8,
441                 "ce",
442                 false,
443                 false,
444                 true,
445                 "efth",
446                 true,
447                 .hash_dir = false,
448                 "ihim",
449                 true,
450                 0.0,
451                 "lf",
452                 4711,
453                 98.7 * 1000 * 1000,
454                 "p",
455                 true,
456                 "pc",
457                 "pcc",
458                 true,
459                 true,
460                 true,
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,
466                 false,
467                 "td",
468                 022,
469                 true,
470                 NULL
471         };
472         size_t n = 0;
473
474         conf.item_origins = x_malloc(N_CONFIG_ITEMS * sizeof(char *));
475         for (i = 0; i < N_CONFIG_ITEMS; ++i) {
476 #ifndef __MINGW32__
477                 conf.item_origins[i] = format("origin%zu", i);
478 #else
479                 conf.item_origins[i] = format("origin%u", (unsigned) i);
480 #endif
481         }
482
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);
522
523         for (i = 0; i < N_CONFIG_ITEMS; ++i) {
524 #ifndef __MINGW32__
525                 char *expected = format("origin%zu", i);
526 #else
527                 char *expected = format("origin%u", (unsigned) i);
528 #endif
529                 CHECK_STR_EQ_FREE1(expected, received_conf_items[i].origin);
530         }
531
532         free_received_conf_items();
533         free(conf.item_origins);
534 }
535
536 TEST_SUITE_END