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