xref: /netbsd-src/external/bsd/atf/dist/tools/config_file_test.cpp (revision d780102efefa02003390cc43ea410dbd0ebb4a85)
1*d780102eSjmmv //
2*d780102eSjmmv // Automated Testing Framework (atf)
3*d780102eSjmmv //
4*d780102eSjmmv // Copyright (c) 2010 The NetBSD Foundation, Inc.
5*d780102eSjmmv // All rights reserved.
6*d780102eSjmmv //
7*d780102eSjmmv // Redistribution and use in source and binary forms, with or without
8*d780102eSjmmv // modification, are permitted provided that the following conditions
9*d780102eSjmmv // are met:
10*d780102eSjmmv // 1. Redistributions of source code must retain the above copyright
11*d780102eSjmmv //    notice, this list of conditions and the following disclaimer.
12*d780102eSjmmv // 2. Redistributions in binary form must reproduce the above copyright
13*d780102eSjmmv //    notice, this list of conditions and the following disclaimer in the
14*d780102eSjmmv //    documentation and/or other materials provided with the distribution.
15*d780102eSjmmv //
16*d780102eSjmmv // THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
17*d780102eSjmmv // CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
18*d780102eSjmmv // INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19*d780102eSjmmv // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20*d780102eSjmmv // IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
21*d780102eSjmmv // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22*d780102eSjmmv // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
23*d780102eSjmmv // GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24*d780102eSjmmv // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
25*d780102eSjmmv // IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
26*d780102eSjmmv // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
27*d780102eSjmmv // IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28*d780102eSjmmv //
29*d780102eSjmmv 
30*d780102eSjmmv #include <atf-c++.hpp>
31*d780102eSjmmv 
32*d780102eSjmmv #include "config.hpp"
33*d780102eSjmmv #include "config_file.hpp"
34*d780102eSjmmv #include "env.hpp"
35*d780102eSjmmv #include "test_helpers.hpp"
36*d780102eSjmmv 
37*d780102eSjmmv namespace impl = tools::config_file;
38*d780102eSjmmv namespace detail = tools::config_file::detail;
39*d780102eSjmmv 
40*d780102eSjmmv namespace {
41*d780102eSjmmv 
42*d780102eSjmmv typedef std::map< std::string, std::string > vars_map;
43*d780102eSjmmv 
44*d780102eSjmmv } // anonymous namespace
45*d780102eSjmmv 
46*d780102eSjmmv namespace atf {
47*d780102eSjmmv namespace config {
48*d780102eSjmmv 
49*d780102eSjmmv void __reinit(void);
50*d780102eSjmmv 
51*d780102eSjmmv }  // namespace config
52*d780102eSjmmv }  // namespace atf
53*d780102eSjmmv 
54*d780102eSjmmv // -------------------------------------------------------------------------
55*d780102eSjmmv // Tests for the "config" parser.
56*d780102eSjmmv // -------------------------------------------------------------------------
57*d780102eSjmmv 
58*d780102eSjmmv class config_reader : protected detail::atf_config_reader {
59*d780102eSjmmv     void
got_var(const std::string & name,const std::string & val)60*d780102eSjmmv     got_var(const std::string& name, const std::string& val)
61*d780102eSjmmv     {
62*d780102eSjmmv         m_calls.push_back("got_var(" + name + ", " + val + ")");
63*d780102eSjmmv     }
64*d780102eSjmmv 
65*d780102eSjmmv     void
got_eof(void)66*d780102eSjmmv     got_eof(void)
67*d780102eSjmmv     {
68*d780102eSjmmv         m_calls.push_back("got_eof()");
69*d780102eSjmmv     }
70*d780102eSjmmv 
71*d780102eSjmmv public:
config_reader(std::istream & is)72*d780102eSjmmv     config_reader(std::istream& is) :
73*d780102eSjmmv         detail::atf_config_reader(is)
74*d780102eSjmmv     {
75*d780102eSjmmv     }
76*d780102eSjmmv 
77*d780102eSjmmv     void
read(void)78*d780102eSjmmv     read(void)
79*d780102eSjmmv     {
80*d780102eSjmmv         atf_config_reader::read();
81*d780102eSjmmv     }
82*d780102eSjmmv 
83*d780102eSjmmv     std::vector< std::string > m_calls;
84*d780102eSjmmv };
85*d780102eSjmmv 
86*d780102eSjmmv ATF_TEST_CASE_WITHOUT_HEAD(config_1);
ATF_TEST_CASE_BODY(config_1)87*d780102eSjmmv ATF_TEST_CASE_BODY(config_1)
88*d780102eSjmmv {
89*d780102eSjmmv     const char* input =
90*d780102eSjmmv         "Content-Type: application/X-atf-config; version=\"1\"\n"
91*d780102eSjmmv         "\n"
92*d780102eSjmmv     ;
93*d780102eSjmmv 
94*d780102eSjmmv     const char* exp_calls[] = {
95*d780102eSjmmv         "got_eof()",
96*d780102eSjmmv         NULL
97*d780102eSjmmv     };
98*d780102eSjmmv 
99*d780102eSjmmv     const char* exp_errors[] = {
100*d780102eSjmmv         NULL
101*d780102eSjmmv     };
102*d780102eSjmmv 
103*d780102eSjmmv     do_parser_test< config_reader >(input, exp_calls, exp_errors);
104*d780102eSjmmv }
105*d780102eSjmmv 
106*d780102eSjmmv ATF_TEST_CASE_WITHOUT_HEAD(config_2);
ATF_TEST_CASE_BODY(config_2)107*d780102eSjmmv ATF_TEST_CASE_BODY(config_2)
108*d780102eSjmmv {
109*d780102eSjmmv     const char* input =
110*d780102eSjmmv         "Content-Type: application/X-atf-config; version=\"1\"\n"
111*d780102eSjmmv         "\n"
112*d780102eSjmmv         "# This is a comment on a line of its own.\n"
113*d780102eSjmmv         "# And this is another one.\n"
114*d780102eSjmmv         "\n"
115*d780102eSjmmv         "	    # Another after some whitespace.\n"
116*d780102eSjmmv         "\n"
117*d780102eSjmmv         "# The last one after an empty line.\n"
118*d780102eSjmmv     ;
119*d780102eSjmmv 
120*d780102eSjmmv     const char* exp_calls[] = {
121*d780102eSjmmv         "got_eof()",
122*d780102eSjmmv         NULL
123*d780102eSjmmv     };
124*d780102eSjmmv 
125*d780102eSjmmv     const char* exp_errors[] = {
126*d780102eSjmmv         NULL
127*d780102eSjmmv     };
128*d780102eSjmmv 
129*d780102eSjmmv     do_parser_test< config_reader >(input, exp_calls, exp_errors);
130*d780102eSjmmv }
131*d780102eSjmmv 
132*d780102eSjmmv ATF_TEST_CASE_WITHOUT_HEAD(config_3);
ATF_TEST_CASE_BODY(config_3)133*d780102eSjmmv ATF_TEST_CASE_BODY(config_3)
134*d780102eSjmmv {
135*d780102eSjmmv     const char* input =
136*d780102eSjmmv         "Content-Type: application/X-atf-config; version=\"1\"\n"
137*d780102eSjmmv         "\n"
138*d780102eSjmmv         "var1=value1\n"
139*d780102eSjmmv         "var2 = value2\n"
140*d780102eSjmmv         "var3	=	value3\n"
141*d780102eSjmmv         "var4	    =	    value4\n"
142*d780102eSjmmv         "\n"
143*d780102eSjmmv         "var5=value5\n"
144*d780102eSjmmv         "    var6=value6\n"
145*d780102eSjmmv         "\n"
146*d780102eSjmmv         "var7 = \"This is a long value.\"\n"
147*d780102eSjmmv         "var8 = \"Single-word\"\n"
148*d780102eSjmmv         "var9 = \"    Single-word	\"\n"
149*d780102eSjmmv         "var10 = Single-word\n"
150*d780102eSjmmv     ;
151*d780102eSjmmv 
152*d780102eSjmmv     const char* exp_calls[] = {
153*d780102eSjmmv         "got_var(var1, value1)",
154*d780102eSjmmv         "got_var(var2, value2)",
155*d780102eSjmmv         "got_var(var3, value3)",
156*d780102eSjmmv         "got_var(var4, value4)",
157*d780102eSjmmv         "got_var(var5, value5)",
158*d780102eSjmmv         "got_var(var6, value6)",
159*d780102eSjmmv         "got_var(var7, This is a long value.)",
160*d780102eSjmmv         "got_var(var8, Single-word)",
161*d780102eSjmmv         "got_var(var9,     Single-word	)",
162*d780102eSjmmv         "got_var(var10, Single-word)",
163*d780102eSjmmv         "got_eof()",
164*d780102eSjmmv         NULL
165*d780102eSjmmv     };
166*d780102eSjmmv 
167*d780102eSjmmv     const char* exp_errors[] = {
168*d780102eSjmmv         NULL
169*d780102eSjmmv     };
170*d780102eSjmmv 
171*d780102eSjmmv     do_parser_test< config_reader >(input, exp_calls, exp_errors);
172*d780102eSjmmv }
173*d780102eSjmmv 
174*d780102eSjmmv ATF_TEST_CASE_WITHOUT_HEAD(config_4);
ATF_TEST_CASE_BODY(config_4)175*d780102eSjmmv ATF_TEST_CASE_BODY(config_4)
176*d780102eSjmmv {
177*d780102eSjmmv     const char* input =
178*d780102eSjmmv         "Content-Type: application/X-atf-config; version=\"1\"\n"
179*d780102eSjmmv         "\n"
180*d780102eSjmmv         "foo = bar # A comment.\n"
181*d780102eSjmmv     ;
182*d780102eSjmmv 
183*d780102eSjmmv     const char* exp_calls[] = {
184*d780102eSjmmv         "got_var(foo, bar)",
185*d780102eSjmmv         "got_eof()",
186*d780102eSjmmv         NULL
187*d780102eSjmmv     };
188*d780102eSjmmv 
189*d780102eSjmmv     const char* exp_errors[] = {
190*d780102eSjmmv         NULL
191*d780102eSjmmv     };
192*d780102eSjmmv 
193*d780102eSjmmv     do_parser_test< config_reader >(input, exp_calls, exp_errors);
194*d780102eSjmmv }
195*d780102eSjmmv 
196*d780102eSjmmv ATF_TEST_CASE_WITHOUT_HEAD(config_50);
ATF_TEST_CASE_BODY(config_50)197*d780102eSjmmv ATF_TEST_CASE_BODY(config_50)
198*d780102eSjmmv {
199*d780102eSjmmv     const char* input =
200*d780102eSjmmv         "Content-Type: application/X-atf-config; version=\"1\"\n"
201*d780102eSjmmv         "\n"
202*d780102eSjmmv         "foo\n"
203*d780102eSjmmv     ;
204*d780102eSjmmv 
205*d780102eSjmmv     const char* exp_calls[] = {
206*d780102eSjmmv         NULL
207*d780102eSjmmv     };
208*d780102eSjmmv 
209*d780102eSjmmv     const char* exp_errors[] = {
210*d780102eSjmmv         "3: Unexpected token `<<NEWLINE>>'; expected equal sign",
211*d780102eSjmmv         NULL
212*d780102eSjmmv     };
213*d780102eSjmmv 
214*d780102eSjmmv     do_parser_test< config_reader >(input, exp_calls, exp_errors);
215*d780102eSjmmv }
216*d780102eSjmmv 
217*d780102eSjmmv ATF_TEST_CASE_WITHOUT_HEAD(config_51);
ATF_TEST_CASE_BODY(config_51)218*d780102eSjmmv ATF_TEST_CASE_BODY(config_51)
219*d780102eSjmmv {
220*d780102eSjmmv     const char* input =
221*d780102eSjmmv         "Content-Type: application/X-atf-config; version=\"1\"\n"
222*d780102eSjmmv         "\n"
223*d780102eSjmmv         "foo bar\n"
224*d780102eSjmmv         "baz\n"
225*d780102eSjmmv     ;
226*d780102eSjmmv 
227*d780102eSjmmv     const char* exp_calls[] = {
228*d780102eSjmmv         NULL
229*d780102eSjmmv     };
230*d780102eSjmmv 
231*d780102eSjmmv     const char* exp_errors[] = {
232*d780102eSjmmv         "3: Unexpected token `bar'; expected equal sign",
233*d780102eSjmmv         "4: Unexpected token `<<NEWLINE>>'; expected equal sign",
234*d780102eSjmmv         NULL
235*d780102eSjmmv     };
236*d780102eSjmmv 
237*d780102eSjmmv     do_parser_test< config_reader >(input, exp_calls, exp_errors);
238*d780102eSjmmv }
239*d780102eSjmmv 
240*d780102eSjmmv ATF_TEST_CASE_WITHOUT_HEAD(config_52);
ATF_TEST_CASE_BODY(config_52)241*d780102eSjmmv ATF_TEST_CASE_BODY(config_52)
242*d780102eSjmmv {
243*d780102eSjmmv     const char* input =
244*d780102eSjmmv         "Content-Type: application/X-atf-config; version=\"1\"\n"
245*d780102eSjmmv         "\n"
246*d780102eSjmmv         "foo =\n"
247*d780102eSjmmv         "bar = # A comment.\n"
248*d780102eSjmmv     ;
249*d780102eSjmmv 
250*d780102eSjmmv     const char* exp_calls[] = {
251*d780102eSjmmv         NULL
252*d780102eSjmmv     };
253*d780102eSjmmv 
254*d780102eSjmmv     const char* exp_errors[] = {
255*d780102eSjmmv         "3: Unexpected token `<<NEWLINE>>'; expected word or quoted string",
256*d780102eSjmmv         "4: Unexpected token `#'; expected word or quoted string",
257*d780102eSjmmv         NULL
258*d780102eSjmmv     };
259*d780102eSjmmv 
260*d780102eSjmmv     do_parser_test< config_reader >(input, exp_calls, exp_errors);
261*d780102eSjmmv }
262*d780102eSjmmv 
263*d780102eSjmmv ATF_TEST_CASE_WITHOUT_HEAD(config_53);
ATF_TEST_CASE_BODY(config_53)264*d780102eSjmmv ATF_TEST_CASE_BODY(config_53)
265*d780102eSjmmv {
266*d780102eSjmmv     const char* input =
267*d780102eSjmmv         "Content-Type: application/X-atf-config; version=\"1\"\n"
268*d780102eSjmmv         "\n"
269*d780102eSjmmv         "foo = \"Correct value\" # With comment.\n"
270*d780102eSjmmv         "\n"
271*d780102eSjmmv         "bar = # A comment.\n"
272*d780102eSjmmv         "\n"
273*d780102eSjmmv         "baz = \"Last variable\"\n"
274*d780102eSjmmv         "\n"
275*d780102eSjmmv         "# End of file.\n"
276*d780102eSjmmv     ;
277*d780102eSjmmv 
278*d780102eSjmmv     const char* exp_calls[] = {
279*d780102eSjmmv         "got_var(foo, Correct value)",
280*d780102eSjmmv         NULL
281*d780102eSjmmv     };
282*d780102eSjmmv 
283*d780102eSjmmv     const char* exp_errors[] = {
284*d780102eSjmmv         "5: Unexpected token `#'; expected word or quoted string",
285*d780102eSjmmv         NULL
286*d780102eSjmmv     };
287*d780102eSjmmv 
288*d780102eSjmmv     do_parser_test< config_reader >(input, exp_calls, exp_errors);
289*d780102eSjmmv }
290*d780102eSjmmv 
291*d780102eSjmmv ATF_TEST_CASE_WITHOUT_HEAD(config_54);
ATF_TEST_CASE_BODY(config_54)292*d780102eSjmmv ATF_TEST_CASE_BODY(config_54)
293*d780102eSjmmv {
294*d780102eSjmmv     const char* input =
295*d780102eSjmmv         "Content-Type: application/X-atf-config; version=\"1\"\n"
296*d780102eSjmmv         "\n"
297*d780102eSjmmv         "foo = \"\n"
298*d780102eSjmmv         "bar = \"text\n"
299*d780102eSjmmv         "baz = \"te\\\"xt\n"
300*d780102eSjmmv         "last = \"\\\"\n"
301*d780102eSjmmv     ;
302*d780102eSjmmv 
303*d780102eSjmmv     const char* exp_calls[] = {
304*d780102eSjmmv         NULL
305*d780102eSjmmv     };
306*d780102eSjmmv 
307*d780102eSjmmv     const char* exp_errors[] = {
308*d780102eSjmmv         "3: Missing double quotes before end of line",
309*d780102eSjmmv         "4: Missing double quotes before end of line",
310*d780102eSjmmv         "5: Missing double quotes before end of line",
311*d780102eSjmmv         "6: Missing double quotes before end of line",
312*d780102eSjmmv         NULL
313*d780102eSjmmv     };
314*d780102eSjmmv 
315*d780102eSjmmv     do_parser_test< config_reader >(input, exp_calls, exp_errors);
316*d780102eSjmmv }
317*d780102eSjmmv 
318*d780102eSjmmv // -------------------------------------------------------------------------
319*d780102eSjmmv // Tests for the free functions.
320*d780102eSjmmv // -------------------------------------------------------------------------
321*d780102eSjmmv 
322*d780102eSjmmv ATF_TEST_CASE(merge_configs_both_empty);
ATF_TEST_CASE_HEAD(merge_configs_both_empty)323*d780102eSjmmv ATF_TEST_CASE_HEAD(merge_configs_both_empty) {}
ATF_TEST_CASE_BODY(merge_configs_both_empty)324*d780102eSjmmv ATF_TEST_CASE_BODY(merge_configs_both_empty) {
325*d780102eSjmmv     vars_map lower, upper;
326*d780102eSjmmv 
327*d780102eSjmmv     ATF_REQUIRE(impl::merge_configs(lower, upper).empty());
328*d780102eSjmmv }
329*d780102eSjmmv 
330*d780102eSjmmv ATF_TEST_CASE(merge_configs_lower_empty);
ATF_TEST_CASE_HEAD(merge_configs_lower_empty)331*d780102eSjmmv ATF_TEST_CASE_HEAD(merge_configs_lower_empty) {}
ATF_TEST_CASE_BODY(merge_configs_lower_empty)332*d780102eSjmmv ATF_TEST_CASE_BODY(merge_configs_lower_empty) {
333*d780102eSjmmv     vars_map lower, upper;
334*d780102eSjmmv     upper["var"] = "value";
335*d780102eSjmmv 
336*d780102eSjmmv     vars_map merged = impl::merge_configs(lower, upper);
337*d780102eSjmmv     ATF_REQUIRE_EQ("value", merged["var"]);
338*d780102eSjmmv }
339*d780102eSjmmv 
340*d780102eSjmmv ATF_TEST_CASE(merge_configs_upper_empty);
ATF_TEST_CASE_HEAD(merge_configs_upper_empty)341*d780102eSjmmv ATF_TEST_CASE_HEAD(merge_configs_upper_empty) {}
ATF_TEST_CASE_BODY(merge_configs_upper_empty)342*d780102eSjmmv ATF_TEST_CASE_BODY(merge_configs_upper_empty) {
343*d780102eSjmmv     vars_map lower, upper;
344*d780102eSjmmv     lower["var"] = "value";
345*d780102eSjmmv 
346*d780102eSjmmv     vars_map merged = impl::merge_configs(lower, upper);
347*d780102eSjmmv     ATF_REQUIRE_EQ("value", merged["var"]);
348*d780102eSjmmv }
349*d780102eSjmmv 
350*d780102eSjmmv ATF_TEST_CASE(merge_configs_mixed);
ATF_TEST_CASE_HEAD(merge_configs_mixed)351*d780102eSjmmv ATF_TEST_CASE_HEAD(merge_configs_mixed) {}
ATF_TEST_CASE_BODY(merge_configs_mixed)352*d780102eSjmmv ATF_TEST_CASE_BODY(merge_configs_mixed) {
353*d780102eSjmmv     vars_map lower, upper;
354*d780102eSjmmv     lower["var1"] = "value1";
355*d780102eSjmmv     lower["var2"] = "value2-l";
356*d780102eSjmmv     upper["var2"] = "value2-u";
357*d780102eSjmmv     upper["var3"] = "value3";
358*d780102eSjmmv 
359*d780102eSjmmv     vars_map merged = impl::merge_configs(lower, upper);
360*d780102eSjmmv     ATF_REQUIRE_EQ("value1", merged["var1"]);
361*d780102eSjmmv     ATF_REQUIRE_EQ("value2-u", merged["var2"]);
362*d780102eSjmmv     ATF_REQUIRE_EQ("value3", merged["var3"]);
363*d780102eSjmmv }
364*d780102eSjmmv 
365*d780102eSjmmv ATF_TEST_CASE(read_config_files_none);
ATF_TEST_CASE_HEAD(read_config_files_none)366*d780102eSjmmv ATF_TEST_CASE_HEAD(read_config_files_none) {}
ATF_TEST_CASE_BODY(read_config_files_none)367*d780102eSjmmv ATF_TEST_CASE_BODY(read_config_files_none) {
368*d780102eSjmmv     tools::env::set("ATF_CONFDIR", ".");
369*d780102eSjmmv     atf::config::__reinit();
370*d780102eSjmmv     ATF_REQUIRE(vars_map() == impl::read_config_files("test-suite"));
371*d780102eSjmmv }
372*d780102eSjmmv 
373*d780102eSjmmv // -------------------------------------------------------------------------
374*d780102eSjmmv // Main.
375*d780102eSjmmv // -------------------------------------------------------------------------
376*d780102eSjmmv 
ATF_INIT_TEST_CASES(tcs)377*d780102eSjmmv ATF_INIT_TEST_CASES(tcs)
378*d780102eSjmmv {
379*d780102eSjmmv     ATF_ADD_TEST_CASE(tcs, config_1);
380*d780102eSjmmv     ATF_ADD_TEST_CASE(tcs, config_2);
381*d780102eSjmmv     ATF_ADD_TEST_CASE(tcs, config_3);
382*d780102eSjmmv     ATF_ADD_TEST_CASE(tcs, config_4);
383*d780102eSjmmv     ATF_ADD_TEST_CASE(tcs, config_50);
384*d780102eSjmmv     ATF_ADD_TEST_CASE(tcs, config_51);
385*d780102eSjmmv     ATF_ADD_TEST_CASE(tcs, config_52);
386*d780102eSjmmv     ATF_ADD_TEST_CASE(tcs, config_53);
387*d780102eSjmmv     ATF_ADD_TEST_CASE(tcs, config_54);
388*d780102eSjmmv 
389*d780102eSjmmv     ATF_ADD_TEST_CASE(tcs, merge_configs_both_empty);
390*d780102eSjmmv     ATF_ADD_TEST_CASE(tcs, merge_configs_lower_empty);
391*d780102eSjmmv     ATF_ADD_TEST_CASE(tcs, merge_configs_upper_empty);
392*d780102eSjmmv     ATF_ADD_TEST_CASE(tcs, merge_configs_mixed);
393*d780102eSjmmv 
394*d780102eSjmmv     ATF_ADD_TEST_CASE(tcs, read_config_files_none);
395*d780102eSjmmv }
396