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/test_helpers.hpp" 31#include "atf-c++/macros.hpp" 32 33#include "config.hpp" 34 35namespace impl = atf::atf_run; 36namespace detail = atf::atf_run::detail; 37 38using atf::tests::vars_map; 39 40// ------------------------------------------------------------------------- 41// Tests for the "config" parser. 42// ------------------------------------------------------------------------- 43 44class config_reader : protected detail::atf_config_reader { 45 void 46 got_var(const std::string& name, const std::string& val) 47 { 48 m_calls.push_back("got_var(" + name + ", " + val + ")"); 49 } 50 51 void 52 got_eof(void) 53 { 54 m_calls.push_back("got_eof()"); 55 } 56 57public: 58 config_reader(std::istream& is) : 59 detail::atf_config_reader(is) 60 { 61 } 62 63 void 64 read(void) 65 { 66 atf_config_reader::read(); 67 } 68 69 std::vector< std::string > m_calls; 70}; 71 72ATF_TEST_CASE_WITHOUT_HEAD(config_1); 73ATF_TEST_CASE_BODY(config_1) 74{ 75 const char* input = 76 "Content-Type: application/X-atf-config; version=\"1\"\n" 77 "\n" 78 ; 79 80 const char* exp_calls[] = { 81 "got_eof()", 82 NULL 83 }; 84 85 const char* exp_errors[] = { 86 NULL 87 }; 88 89 do_parser_test< config_reader >(input, exp_calls, exp_errors); 90} 91 92ATF_TEST_CASE_WITHOUT_HEAD(config_2); 93ATF_TEST_CASE_BODY(config_2) 94{ 95 const char* input = 96 "Content-Type: application/X-atf-config; version=\"1\"\n" 97 "\n" 98 "# This is a comment on a line of its own.\n" 99 "# And this is another one.\n" 100 "\n" 101 " # Another after some whitespace.\n" 102 "\n" 103 "# The last one after an empty line.\n" 104 ; 105 106 const char* exp_calls[] = { 107 "got_eof()", 108 NULL 109 }; 110 111 const char* exp_errors[] = { 112 NULL 113 }; 114 115 do_parser_test< config_reader >(input, exp_calls, exp_errors); 116} 117 118ATF_TEST_CASE_WITHOUT_HEAD(config_3); 119ATF_TEST_CASE_BODY(config_3) 120{ 121 const char* input = 122 "Content-Type: application/X-atf-config; version=\"1\"\n" 123 "\n" 124 "var1=value1\n" 125 "var2 = value2\n" 126 "var3 = value3\n" 127 "var4 = value4\n" 128 "\n" 129 "var5=value5\n" 130 " var6=value6\n" 131 "\n" 132 "var7 = \"This is a long value.\"\n" 133 "var8 = \"Single-word\"\n" 134 "var9 = \" Single-word \"\n" 135 "var10 = Single-word\n" 136 ; 137 138 const char* exp_calls[] = { 139 "got_var(var1, value1)", 140 "got_var(var2, value2)", 141 "got_var(var3, value3)", 142 "got_var(var4, value4)", 143 "got_var(var5, value5)", 144 "got_var(var6, value6)", 145 "got_var(var7, This is a long value.)", 146 "got_var(var8, Single-word)", 147 "got_var(var9, Single-word )", 148 "got_var(var10, Single-word)", 149 "got_eof()", 150 NULL 151 }; 152 153 const char* exp_errors[] = { 154 NULL 155 }; 156 157 do_parser_test< config_reader >(input, exp_calls, exp_errors); 158} 159 160ATF_TEST_CASE_WITHOUT_HEAD(config_4); 161ATF_TEST_CASE_BODY(config_4) 162{ 163 const char* input = 164 "Content-Type: application/X-atf-config; version=\"1\"\n" 165 "\n" 166 "foo = bar # A comment.\n" 167 ; 168 169 const char* exp_calls[] = { 170 "got_var(foo, bar)", 171 "got_eof()", 172 NULL 173 }; 174 175 const char* exp_errors[] = { 176 NULL 177 }; 178 179 do_parser_test< config_reader >(input, exp_calls, exp_errors); 180} 181 182ATF_TEST_CASE_WITHOUT_HEAD(config_50); 183ATF_TEST_CASE_BODY(config_50) 184{ 185 const char* input = 186 "Content-Type: application/X-atf-config; version=\"1\"\n" 187 "\n" 188 "foo\n" 189 ; 190 191 const char* exp_calls[] = { 192 NULL 193 }; 194 195 const char* exp_errors[] = { 196 "3: Unexpected token `<<NEWLINE>>'; expected equal sign", 197 NULL 198 }; 199 200 do_parser_test< config_reader >(input, exp_calls, exp_errors); 201} 202 203ATF_TEST_CASE_WITHOUT_HEAD(config_51); 204ATF_TEST_CASE_BODY(config_51) 205{ 206 const char* input = 207 "Content-Type: application/X-atf-config; version=\"1\"\n" 208 "\n" 209 "foo bar\n" 210 "baz\n" 211 ; 212 213 const char* exp_calls[] = { 214 NULL 215 }; 216 217 const char* exp_errors[] = { 218 "3: Unexpected token `bar'; expected equal sign", 219 "4: Unexpected token `<<NEWLINE>>'; expected equal sign", 220 NULL 221 }; 222 223 do_parser_test< config_reader >(input, exp_calls, exp_errors); 224} 225 226ATF_TEST_CASE_WITHOUT_HEAD(config_52); 227ATF_TEST_CASE_BODY(config_52) 228{ 229 const char* input = 230 "Content-Type: application/X-atf-config; version=\"1\"\n" 231 "\n" 232 "foo =\n" 233 "bar = # A comment.\n" 234 ; 235 236 const char* exp_calls[] = { 237 NULL 238 }; 239 240 const char* exp_errors[] = { 241 "3: Unexpected token `<<NEWLINE>>'; expected word or quoted string", 242 "4: Unexpected token `#'; expected word or quoted string", 243 NULL 244 }; 245 246 do_parser_test< config_reader >(input, exp_calls, exp_errors); 247} 248 249ATF_TEST_CASE_WITHOUT_HEAD(config_53); 250ATF_TEST_CASE_BODY(config_53) 251{ 252 const char* input = 253 "Content-Type: application/X-atf-config; version=\"1\"\n" 254 "\n" 255 "foo = \"Correct value\" # With comment.\n" 256 "\n" 257 "bar = # A comment.\n" 258 "\n" 259 "baz = \"Last variable\"\n" 260 "\n" 261 "# End of file.\n" 262 ; 263 264 const char* exp_calls[] = { 265 "got_var(foo, Correct value)", 266 NULL 267 }; 268 269 const char* exp_errors[] = { 270 "5: Unexpected token `#'; expected word or quoted string", 271 NULL 272 }; 273 274 do_parser_test< config_reader >(input, exp_calls, exp_errors); 275} 276 277ATF_TEST_CASE_WITHOUT_HEAD(config_54); 278ATF_TEST_CASE_BODY(config_54) 279{ 280 const char* input = 281 "Content-Type: application/X-atf-config; version=\"1\"\n" 282 "\n" 283 "foo = \"\n" 284 "bar = \"text\n" 285 "baz = \"te\\\"xt\n" 286 "last = \"\\\"\n" 287 ; 288 289 const char* exp_calls[] = { 290 NULL 291 }; 292 293 const char* exp_errors[] = { 294 "3: Missing double quotes before end of line", 295 "4: Missing double quotes before end of line", 296 "5: Missing double quotes before end of line", 297 "6: Missing double quotes before end of line", 298 NULL 299 }; 300 301 do_parser_test< config_reader >(input, exp_calls, exp_errors); 302} 303 304// ------------------------------------------------------------------------- 305// Tests for the free functions. 306// ------------------------------------------------------------------------- 307 308ATF_TEST_CASE(merge_configs_both_empty); 309ATF_TEST_CASE_HEAD(merge_configs_both_empty) {} 310ATF_TEST_CASE_BODY(merge_configs_both_empty) { 311 vars_map lower, upper; 312 313 ATF_REQUIRE(impl::merge_configs(lower, upper).empty()); 314} 315 316ATF_TEST_CASE(merge_configs_lower_empty); 317ATF_TEST_CASE_HEAD(merge_configs_lower_empty) {} 318ATF_TEST_CASE_BODY(merge_configs_lower_empty) { 319 vars_map lower, upper; 320 upper["var"] = "value"; 321 322 vars_map merged = impl::merge_configs(lower, upper); 323 ATF_REQUIRE_EQ("value", merged["var"]); 324} 325 326ATF_TEST_CASE(merge_configs_upper_empty); 327ATF_TEST_CASE_HEAD(merge_configs_upper_empty) {} 328ATF_TEST_CASE_BODY(merge_configs_upper_empty) { 329 vars_map lower, upper; 330 lower["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_mixed); 337ATF_TEST_CASE_HEAD(merge_configs_mixed) {} 338ATF_TEST_CASE_BODY(merge_configs_mixed) { 339 vars_map lower, upper; 340 lower["var1"] = "value1"; 341 lower["var2"] = "value2-l"; 342 upper["var2"] = "value2-u"; 343 upper["var3"] = "value3"; 344 345 vars_map merged = impl::merge_configs(lower, upper); 346 ATF_REQUIRE_EQ("value1", merged["var1"]); 347 ATF_REQUIRE_EQ("value2-u", merged["var2"]); 348 ATF_REQUIRE_EQ("value3", merged["var3"]); 349} 350 351ATF_TEST_CASE(read_config_files_none); 352ATF_TEST_CASE_HEAD(read_config_files_none) {} 353ATF_TEST_CASE_BODY(read_config_files_none) { 354 ATF_REQUIRE(vars_map() == impl::read_config_files("test-suite")); 355} 356 357// ------------------------------------------------------------------------- 358// Main. 359// ------------------------------------------------------------------------- 360 361ATF_INIT_TEST_CASES(tcs) 362{ 363 ATF_ADD_TEST_CASE(tcs, config_1); 364 ATF_ADD_TEST_CASE(tcs, config_2); 365 ATF_ADD_TEST_CASE(tcs, config_3); 366 ATF_ADD_TEST_CASE(tcs, config_4); 367 ATF_ADD_TEST_CASE(tcs, config_50); 368 ATF_ADD_TEST_CASE(tcs, config_51); 369 ATF_ADD_TEST_CASE(tcs, config_52); 370 ATF_ADD_TEST_CASE(tcs, config_53); 371 ATF_ADD_TEST_CASE(tcs, config_54); 372 373 ATF_ADD_TEST_CASE(tcs, merge_configs_both_empty); 374 ATF_ADD_TEST_CASE(tcs, merge_configs_lower_empty); 375 ATF_ADD_TEST_CASE(tcs, merge_configs_upper_empty); 376 ATF_ADD_TEST_CASE(tcs, merge_configs_mixed); 377 378 ATF_ADD_TEST_CASE(tcs, read_config_files_none); 379} 380