df344c553bfc37d0de555c363ada36f0996d19e6
[platform/upstream/ccache.git] / test / test_conf.c
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 conf_item_receiver(const char *descr, const char *origin, void *context)
32 {
33         (void)context;
34         received_conf_items[n_received_conf_items].descr = x_strdup(descr);
35         received_conf_items[n_received_conf_items].origin = origin;
36         ++n_received_conf_items;
37 }
38
39 static void
40 free_received_conf_items(void)
41 {
42         while (n_received_conf_items > 0) {
43                 --n_received_conf_items;
44                 free(received_conf_items[n_received_conf_items].descr);
45         }
46 }
47
48 TEST_SUITE(conf)
49
50 TEST(conf_create)
51 {
52         struct conf *conf = conf_create();
53         CHECK_STR_EQ("", conf->base_dir);
54         CHECK_STR_EQ_FREE1(format("%s/.ccache", get_home_directory()),
55                            conf->cache_dir);
56         CHECK_INT_EQ(2, conf->cache_dir_levels);
57         CHECK_STR_EQ("", conf->compiler);
58         CHECK_STR_EQ("mtime", conf->compiler_check);
59         CHECK(!conf->compression);
60         CHECK_INT_EQ(6, conf->compression_level);
61         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->log_file);
68         CHECK_INT_EQ(0, conf->max_files);
69         CHECK_INT_EQ((uint64_t)5 * 1000 * 1000 * 1000, conf->max_size);
70         CHECK_STR_EQ("", conf->path);
71         CHECK_STR_EQ("", conf->prefix_command);
72         CHECK(!conf->read_only);
73         CHECK(!conf->read_only_direct);
74         CHECK(!conf->recache);
75         CHECK(!conf->run_second_cpp);
76         CHECK_INT_EQ(0, conf->sloppiness);
77         CHECK(conf->stats);
78         CHECK_STR_EQ("", conf->temporary_dir);
79         CHECK_INT_EQ(UINT_MAX, conf->umask);
80         CHECK(!conf->unify);
81         conf_free(conf);
82 }
83
84 TEST(conf_read_valid_config)
85 {
86         struct conf *conf = conf_create();
87         char *errmsg, *user;
88         putenv("USER=rabbit");
89         user = getenv("USER");
90         CHECK_STR_EQ("rabbit", user);
91         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         CHECK(conf_read(conf, "ccache.conf", &errmsg));
125         CHECK(!errmsg);
126
127         CHECK_STR_EQ_FREE1(format("/%s/foo/%s", user, user), conf->base_dir);
128         CHECK_STR_EQ_FREE1(format("%s$/%s/.ccache", user, user), conf->cache_dir);
129         CHECK_INT_EQ(4, conf->cache_dir_levels);
130         CHECK_STR_EQ("foo", conf->compiler);
131         CHECK_STR_EQ("none", conf->compiler_check);
132         CHECK(conf->compression);
133         CHECK_INT_EQ(2, conf->compression_level);
134         CHECK_STR_EQ(".foo", conf->cpp_extension);
135         CHECK(!conf->direct_mode);
136         CHECK(conf->disable);
137         CHECK_STR_EQ_FREE1(format("a:b c:%s", user), conf->extra_files_to_hash);
138         CHECK(conf->hard_link);
139         CHECK(conf->hash_dir);
140         CHECK_STR_EQ_FREE1(format("%s%s", user, user), conf->log_file);
141         CHECK_INT_EQ(17, conf->max_files);
142         CHECK_INT_EQ(123 * 1000 * 1000, conf->max_size);
143         CHECK_STR_EQ_FREE1(format("%s.x", user), conf->path);
144         CHECK_STR_EQ_FREE1(format("x%s", user), conf->prefix_command);
145         CHECK(conf->read_only);
146         CHECK(conf->read_only_direct);
147         CHECK(conf->recache);
148         CHECK(conf->run_second_cpp);
149         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         CHECK(!conf->stats);
154         CHECK_STR_EQ_FREE1(format("%s_foo", user), conf->temporary_dir);
155         CHECK_INT_EQ(0777, conf->umask);
156         CHECK(conf->unify);
157
158         conf_free(conf);
159 }
160
161 TEST(conf_read_with_missing_equal_sign)
162 {
163         struct conf *conf = conf_create();
164         char *errmsg;
165         create_file("ccache.conf", "no equal sign");
166         CHECK(!conf_read(conf, "ccache.conf", &errmsg));
167         CHECK_STR_EQ_FREE2("ccache.conf:1: missing equal sign",
168                            errmsg);
169         conf_free(conf);
170 }
171
172 TEST(conf_read_with_bad_config_key)
173 {
174         struct conf *conf = conf_create();
175         char *errmsg;
176         create_file("ccache.conf", "# Comment\nfoo = bar");
177         CHECK(!conf_read(conf, "ccache.conf", &errmsg));
178         CHECK_STR_EQ_FREE2("ccache.conf:2: unknown configuration option \"foo\"",
179                            errmsg);
180         conf_free(conf);
181 }
182
183 TEST(conf_read_invalid_bool)
184 {
185         struct conf *conf = conf_create();
186         char *errmsg;
187
188         create_file("ccache.conf", "disable=");
189         CHECK(!conf_read(conf, "ccache.conf", &errmsg));
190         CHECK_STR_EQ_FREE2("ccache.conf:1: not a boolean value: \"\"",
191                            errmsg);
192
193         create_file("ccache.conf", "disable=foo");
194         CHECK(!conf_read(conf, "ccache.conf", &errmsg));
195         CHECK_STR_EQ_FREE2("ccache.conf:1: not a boolean value: \"foo\"",
196                            errmsg);
197         conf_free(conf);
198 }
199
200 TEST(conf_read_invalid_env_string)
201 {
202         struct conf *conf = conf_create();
203         char *errmsg;
204         create_file("ccache.conf", "base_dir = ${foo");
205         CHECK(!conf_read(conf, "ccache.conf", &errmsg));
206         CHECK_STR_EQ_FREE2("ccache.conf:1: syntax error: missing '}' after \"foo\"",
207                            errmsg);
208         /* Other cases tested in test_util.c. */
209         conf_free(conf);
210 }
211
212 TEST(conf_read_empty_umask)
213 {
214         struct conf *conf = conf_create();
215         char *errmsg;
216         create_file("ccache.conf", "umask = ");
217         CHECK(conf_read(conf, "ccache.conf", &errmsg));
218         CHECK_INT_EQ(conf->umask, UINT_MAX);
219         conf_free(conf);
220 }
221
222 TEST(conf_read_invalid_size)
223 {
224         struct conf *conf = conf_create();
225         char *errmsg;
226         create_file("ccache.conf", "max_size = foo");
227         CHECK(!conf_read(conf, "ccache.conf", &errmsg));
228         CHECK_STR_EQ_FREE2("ccache.conf:1: invalid size: \"foo\"",
229                            errmsg);
230         /* Other cases tested in test_util.c. */
231         conf_free(conf);
232 }
233
234 TEST(conf_read_invalid_sloppiness)
235 {
236         struct conf *conf = conf_create();
237         char *errmsg;
238         create_file("ccache.conf", "sloppiness = file_macro, foo");
239         CHECK(!conf_read(conf, "ccache.conf", &errmsg));
240         CHECK_STR_EQ_FREE2("ccache.conf:1: unknown sloppiness: \"foo\"",
241                            errmsg);
242         conf_free(conf);
243 }
244
245 TEST(conf_read_invalid_unsigned)
246 {
247         struct conf *conf = conf_create();
248         char *errmsg;
249
250         create_file("ccache.conf", "max_files =");
251         CHECK(!conf_read(conf, "ccache.conf", &errmsg));
252         CHECK_STR_EQ_FREE2("ccache.conf:1: invalid unsigned integer: \"\"",
253                            errmsg);
254
255         create_file("ccache.conf", "max_files = -42");
256         CHECK(!conf_read(conf, "ccache.conf", &errmsg));
257         CHECK_STR_EQ_FREE2("ccache.conf:1: invalid unsigned integer: \"-42\"",
258                            errmsg);
259
260         create_file("ccache.conf", "max_files = foo");
261         CHECK(!conf_read(conf, "ccache.conf", &errmsg));
262         CHECK_STR_EQ_FREE2("ccache.conf:1: invalid unsigned integer: \"foo\"",
263                            errmsg);
264
265         conf_free(conf);
266 }
267
268 TEST(verify_absolute_base_dir)
269 {
270         struct conf *conf = conf_create();
271         char *errmsg;
272
273         create_file("ccache.conf", "base_dir = relative/path");
274         CHECK(!conf_read(conf, "ccache.conf", &errmsg));
275         CHECK_STR_EQ_FREE2("ccache.conf:1: not an absolute path: \"relative/path\"",
276                            errmsg);
277
278         create_file("ccache.conf", "base_dir =");
279         CHECK(conf_read(conf, "ccache.conf", &errmsg));
280
281         conf_free(conf);
282 }
283
284 TEST(verify_dir_levels)
285 {
286         struct conf *conf = conf_create();
287         char *errmsg;
288
289         create_file("ccache.conf", "cache_dir_levels = 0");
290         CHECK(!conf_read(conf, "ccache.conf", &errmsg));
291         CHECK_STR_EQ_FREE2(
292           "ccache.conf:1: cache directory levels must be between 1 and 8",
293           errmsg);
294         create_file("ccache.conf", "cache_dir_levels = 9");
295         CHECK(!conf_read(conf, "ccache.conf", &errmsg));
296         CHECK_STR_EQ_FREE2(
297           "ccache.conf:1: cache directory levels must be between 1 and 8",
298           errmsg);
299
300         conf_free(conf);
301 }
302
303 TEST(conf_update_from_environment)
304 {
305         struct conf *conf = conf_create();
306         char *errmsg;
307
308         putenv("CCACHE_COMPRESS=1");
309         CHECK(conf_update_from_environment(conf, &errmsg));
310         CHECK(conf->compression);
311
312         x_unsetenv("CCACHE_COMPRESS");
313         putenv("CCACHE_NOCOMPRESS=1");
314         CHECK(conf_update_from_environment(conf, &errmsg));
315         CHECK(!conf->compression);
316
317         conf_free(conf);
318 }
319
320 TEST(conf_set_new_value)
321 {
322         char *errmsg;
323         char *data;
324
325         create_file("ccache.conf", "path = vanilla\n");
326         CHECK(conf_set_value_in_file("ccache.conf", "stats", "chocolate", &errmsg));
327         data = read_text_file("ccache.conf", 0);
328         CHECK(data);
329         CHECK_STR_EQ_FREE2("path = vanilla\nstats = chocolate\n", data);
330 }
331
332 TEST(conf_set_existing_value)
333 {
334         char *errmsg;
335         char *data;
336
337         create_file("ccache.conf", "path = chocolate\nstats = chocolate\n");
338         CHECK(conf_set_value_in_file("ccache.conf", "path", "vanilla", &errmsg));
339         data = read_text_file("ccache.conf", 0);
340         CHECK(data);
341         CHECK_STR_EQ_FREE2("path = vanilla\nstats = chocolate\n", data);
342 }
343
344 TEST(conf_print_items)
345 {
346         size_t i;
347         struct conf conf = {
348                 "bd",
349                 "cd",
350                 7,
351                 "c",
352                 "cc",
353                 true,
354                 8,
355                 "ce",
356                 false,
357                 true,
358                 "efth",
359                 true,
360                 true,
361                 "lf",
362                 4711,
363                 98.7 * 1000 * 1000,
364                 "p",
365                 "pc",
366                 true,
367                 true,
368                 true,
369                 true,
370                 SLOPPY_FILE_MACRO|SLOPPY_INCLUDE_FILE_MTIME|
371                 SLOPPY_INCLUDE_FILE_CTIME|SLOPPY_TIME_MACROS|
372                 SLOPPY_FILE_STAT_MATCHES,
373                 false,
374                 "td",
375                 022,
376                 true,
377                 NULL
378         };
379         size_t n = 0;
380
381         conf.item_origins = x_malloc(N_CONFIG_ITEMS * sizeof(char *));
382         for (i = 0; i < N_CONFIG_ITEMS; ++i) {
383                 conf.item_origins[i] = format("origin%zu", i);
384         }
385
386         conf_print_items(&conf, conf_item_receiver, NULL);
387         CHECK_INT_EQ(N_CONFIG_ITEMS, n_received_conf_items);
388         CHECK_STR_EQ("base_dir = bd", received_conf_items[n++].descr);
389         CHECK_STR_EQ("cache_dir = cd", received_conf_items[n++].descr);
390         CHECK_STR_EQ("cache_dir_levels = 7", received_conf_items[n++].descr);
391         CHECK_STR_EQ("compiler = c", received_conf_items[n++].descr);
392         CHECK_STR_EQ("compiler_check = cc", received_conf_items[n++].descr);
393         CHECK_STR_EQ("compression = true", received_conf_items[n++].descr);
394         CHECK_STR_EQ("compression_level = 8", received_conf_items[n++].descr);
395         CHECK_STR_EQ("cpp_extension = ce", received_conf_items[n++].descr);
396         CHECK_STR_EQ("direct_mode = false", received_conf_items[n++].descr);
397         CHECK_STR_EQ("disable = true", received_conf_items[n++].descr);
398         CHECK_STR_EQ("extra_files_to_hash = efth", received_conf_items[n++].descr);
399         CHECK_STR_EQ("hard_link = true", received_conf_items[n++].descr);
400         CHECK_STR_EQ("hash_dir = true", received_conf_items[n++].descr);
401         CHECK_STR_EQ("log_file = lf", received_conf_items[n++].descr);
402         CHECK_STR_EQ("max_files = 4711", received_conf_items[n++].descr);
403         CHECK_STR_EQ("max_size = 98.7M", received_conf_items[n++].descr);
404         CHECK_STR_EQ("path = p", received_conf_items[n++].descr);
405         CHECK_STR_EQ("prefix_command = pc", received_conf_items[n++].descr);
406         CHECK_STR_EQ("read_only = true", received_conf_items[n++].descr);
407         CHECK_STR_EQ("read_only_direct = true", received_conf_items[n++].descr);
408         CHECK_STR_EQ("recache = true", received_conf_items[n++].descr);
409         CHECK_STR_EQ("run_second_cpp = true", received_conf_items[n++].descr);
410         CHECK_STR_EQ("sloppiness = file_macro, include_file_mtime,"
411                      " include_file_ctime, time_macros, file_stat_matches",
412                      received_conf_items[n++].descr);
413         CHECK_STR_EQ("stats = false", received_conf_items[n++].descr);
414         CHECK_STR_EQ("temporary_dir = td", received_conf_items[n++].descr);
415         CHECK_STR_EQ("umask = 022", received_conf_items[n++].descr);
416         CHECK_STR_EQ("unify = true", received_conf_items[n++].descr);
417
418         for (i = 0; i < N_CONFIG_ITEMS; ++i) {
419                 char *expected = format("origin%zu", i);
420                 CHECK_STR_EQ(expected, received_conf_items[i].origin);
421         }
422
423         free_received_conf_items();
424         free(conf.item_origins);
425 }
426
427 TEST_SUITE_END