1b0d29bc4SBrooks Davis // Copyright 2014 The Kyua Authors. 2b0d29bc4SBrooks Davis // All rights reserved. 3b0d29bc4SBrooks Davis // 4b0d29bc4SBrooks Davis // Redistribution and use in source and binary forms, with or without 5b0d29bc4SBrooks Davis // modification, are permitted provided that the following conditions are 6b0d29bc4SBrooks Davis // met: 7b0d29bc4SBrooks Davis // 8b0d29bc4SBrooks Davis // * Redistributions of source code must retain the above copyright 9b0d29bc4SBrooks Davis // notice, this list of conditions and the following disclaimer. 10b0d29bc4SBrooks Davis // * Redistributions in binary form must reproduce the above copyright 11b0d29bc4SBrooks Davis // notice, this list of conditions and the following disclaimer in the 12b0d29bc4SBrooks Davis // documentation and/or other materials provided with the distribution. 13b0d29bc4SBrooks Davis // * Neither the name of Google Inc. nor the names of its contributors 14b0d29bc4SBrooks Davis // may be used to endorse or promote products derived from this software 15b0d29bc4SBrooks Davis // without specific prior written permission. 16b0d29bc4SBrooks Davis // 17b0d29bc4SBrooks Davis // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18b0d29bc4SBrooks Davis // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19b0d29bc4SBrooks Davis // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20b0d29bc4SBrooks Davis // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21b0d29bc4SBrooks Davis // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22b0d29bc4SBrooks Davis // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23b0d29bc4SBrooks Davis // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24b0d29bc4SBrooks Davis // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25b0d29bc4SBrooks Davis // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26b0d29bc4SBrooks Davis // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27b0d29bc4SBrooks Davis // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28b0d29bc4SBrooks Davis 29b0d29bc4SBrooks Davis #include "drivers/report_junit.hpp" 30b0d29bc4SBrooks Davis 31b0d29bc4SBrooks Davis #include <sstream> 32b0d29bc4SBrooks Davis #include <vector> 33b0d29bc4SBrooks Davis 34b0d29bc4SBrooks Davis #include <atf-c++.hpp> 35b0d29bc4SBrooks Davis 36b0d29bc4SBrooks Davis #include "drivers/scan_results.hpp" 37b0d29bc4SBrooks Davis #include "engine/filters.hpp" 38b0d29bc4SBrooks Davis #include "model/context.hpp" 39b0d29bc4SBrooks Davis #include "model/metadata.hpp" 40b0d29bc4SBrooks Davis #include "model/test_case.hpp" 41b0d29bc4SBrooks Davis #include "model/test_program.hpp" 42b0d29bc4SBrooks Davis #include "model/test_result.hpp" 43b0d29bc4SBrooks Davis #include "store/write_backend.hpp" 44b0d29bc4SBrooks Davis #include "store/write_transaction.hpp" 45b0d29bc4SBrooks Davis #include "utils/datetime.hpp" 46b0d29bc4SBrooks Davis #include "utils/format/macros.hpp" 47b0d29bc4SBrooks Davis #include "utils/fs/path.hpp" 48b0d29bc4SBrooks Davis #include "utils/optional.ipp" 49b0d29bc4SBrooks Davis #include "utils/units.hpp" 50b0d29bc4SBrooks Davis 51b0d29bc4SBrooks Davis namespace datetime = utils::datetime; 52b0d29bc4SBrooks Davis namespace fs = utils::fs; 53b0d29bc4SBrooks Davis namespace units = utils::units; 54b0d29bc4SBrooks Davis 55b0d29bc4SBrooks Davis using utils::none; 56b0d29bc4SBrooks Davis 57b0d29bc4SBrooks Davis 58b0d29bc4SBrooks Davis namespace { 59b0d29bc4SBrooks Davis 60b0d29bc4SBrooks Davis 61b0d29bc4SBrooks Davis /// Formatted metadata for a test case with defaults. 62b0d29bc4SBrooks Davis static const char* const default_metadata = 63b0d29bc4SBrooks Davis "allowed_architectures is empty\n" 64b0d29bc4SBrooks Davis "allowed_platforms is empty\n" 65b0d29bc4SBrooks Davis "description is empty\n" 66*257e70f1SIgor Ostapenko "execenv is empty\n" 67*257e70f1SIgor Ostapenko "execenv_jail_params is empty\n" 68b0d29bc4SBrooks Davis "has_cleanup = false\n" 69b0d29bc4SBrooks Davis "is_exclusive = false\n" 70b0d29bc4SBrooks Davis "required_configs is empty\n" 71b0d29bc4SBrooks Davis "required_disk_space = 0\n" 72b0d29bc4SBrooks Davis "required_files is empty\n" 73b0d29bc4SBrooks Davis "required_memory = 0\n" 74b0d29bc4SBrooks Davis "required_programs is empty\n" 75b0d29bc4SBrooks Davis "required_user is empty\n" 76b0d29bc4SBrooks Davis "timeout = 300\n"; 77b0d29bc4SBrooks Davis 78b0d29bc4SBrooks Davis 79b0d29bc4SBrooks Davis /// Formatted metadata for a test case constructed with the "with_metadata" flag 80b0d29bc4SBrooks Davis /// set to true in add_tests. 81b0d29bc4SBrooks Davis static const char* const overriden_metadata = 82b0d29bc4SBrooks Davis "allowed_architectures is empty\n" 83b0d29bc4SBrooks Davis "allowed_platforms is empty\n" 84b0d29bc4SBrooks Davis "description = Textual description\n" 85*257e70f1SIgor Ostapenko "execenv is empty\n" 86*257e70f1SIgor Ostapenko "execenv_jail_params is empty\n" 87b0d29bc4SBrooks Davis "has_cleanup = false\n" 88b0d29bc4SBrooks Davis "is_exclusive = false\n" 89b0d29bc4SBrooks Davis "required_configs is empty\n" 90b0d29bc4SBrooks Davis "required_disk_space = 0\n" 91b0d29bc4SBrooks Davis "required_files is empty\n" 92b0d29bc4SBrooks Davis "required_memory = 0\n" 93b0d29bc4SBrooks Davis "required_programs is empty\n" 94b0d29bc4SBrooks Davis "required_user is empty\n" 95b0d29bc4SBrooks Davis "timeout = 5678\n"; 96b0d29bc4SBrooks Davis 97b0d29bc4SBrooks Davis 98b0d29bc4SBrooks Davis /// Populates the context of the given database. 99b0d29bc4SBrooks Davis /// 100b0d29bc4SBrooks Davis /// \param tx Transaction to use for the writes to the database. 101b0d29bc4SBrooks Davis /// \param env_vars Number of environment variables to add to the context. 102b0d29bc4SBrooks Davis static void 103b0d29bc4SBrooks Davis add_context(store::write_transaction& tx, const std::size_t env_vars) 104b0d29bc4SBrooks Davis { 105b0d29bc4SBrooks Davis std::map< std::string, std::string > env; 106b0d29bc4SBrooks Davis for (std::size_t i = 0; i < env_vars; i++) 107b0d29bc4SBrooks Davis env[F("VAR%s") % i] = F("Value %s") % i; 108b0d29bc4SBrooks Davis const model::context context(fs::path("/root"), env); 109b0d29bc4SBrooks Davis (void)tx.put_context(context); 110b0d29bc4SBrooks Davis } 111b0d29bc4SBrooks Davis 112b0d29bc4SBrooks Davis 113b0d29bc4SBrooks Davis /// Adds a new test program with various test cases to the given database. 114b0d29bc4SBrooks Davis /// 115b0d29bc4SBrooks Davis /// \param tx Transaction to use for the writes to the database. 116b0d29bc4SBrooks Davis /// \param prog Test program name. 117b0d29bc4SBrooks Davis /// \param results Collection of results for the added test cases. The size of 118b0d29bc4SBrooks Davis /// this vector indicates the number of tests in the test program. 119b0d29bc4SBrooks Davis /// \param with_metadata Whether to add metadata overrides to the test cases. 120b0d29bc4SBrooks Davis /// \param with_output Whether to add stdout/stderr messages to the test cases. 121b0d29bc4SBrooks Davis static void 122b0d29bc4SBrooks Davis add_tests(store::write_transaction& tx, 123b0d29bc4SBrooks Davis const char* prog, 124b0d29bc4SBrooks Davis const std::vector< model::test_result >& results, 125b0d29bc4SBrooks Davis const bool with_metadata, const bool with_output) 126b0d29bc4SBrooks Davis { 127b0d29bc4SBrooks Davis model::test_program_builder test_program_builder( 128b0d29bc4SBrooks Davis "plain", fs::path(prog), fs::path("/root"), "suite"); 129b0d29bc4SBrooks Davis 130b0d29bc4SBrooks Davis for (std::size_t j = 0; j < results.size(); j++) { 131b0d29bc4SBrooks Davis model::metadata_builder builder; 132b0d29bc4SBrooks Davis if (with_metadata) { 133b0d29bc4SBrooks Davis builder.set_description("Textual description"); 134b0d29bc4SBrooks Davis builder.set_timeout(datetime::delta(5678, 0)); 135b0d29bc4SBrooks Davis } 136b0d29bc4SBrooks Davis test_program_builder.add_test_case(F("t%s") % j, builder.build()); 137b0d29bc4SBrooks Davis } 138b0d29bc4SBrooks Davis 139b0d29bc4SBrooks Davis const model::test_program test_program = test_program_builder.build(); 140b0d29bc4SBrooks Davis const int64_t tp_id = tx.put_test_program(test_program); 141b0d29bc4SBrooks Davis 142b0d29bc4SBrooks Davis for (std::size_t j = 0; j < results.size(); j++) { 143b0d29bc4SBrooks Davis const int64_t tc_id = tx.put_test_case(test_program, F("t%s") % j, 144b0d29bc4SBrooks Davis tp_id); 145b0d29bc4SBrooks Davis const datetime::timestamp start = 146b0d29bc4SBrooks Davis datetime::timestamp::from_microseconds(0); 147b0d29bc4SBrooks Davis const datetime::timestamp end = 148b0d29bc4SBrooks Davis datetime::timestamp::from_microseconds(j * 1000000 + 500000); 149b0d29bc4SBrooks Davis tx.put_result(results[j], tc_id, start, end); 150b0d29bc4SBrooks Davis 151b0d29bc4SBrooks Davis if (with_output) { 152b0d29bc4SBrooks Davis atf::utils::create_file("fake-out", F("stdout file %s") % j); 153b0d29bc4SBrooks Davis tx.put_test_case_file("__STDOUT__", fs::path("fake-out"), tc_id); 154b0d29bc4SBrooks Davis atf::utils::create_file("fake-err", F("stderr file %s") % j); 155b0d29bc4SBrooks Davis tx.put_test_case_file("__STDERR__", fs::path("fake-err"), tc_id); 156b0d29bc4SBrooks Davis } 157b0d29bc4SBrooks Davis } 158b0d29bc4SBrooks Davis } 159b0d29bc4SBrooks Davis 160b0d29bc4SBrooks Davis 161b0d29bc4SBrooks Davis } // anonymous namespace 162b0d29bc4SBrooks Davis 163b0d29bc4SBrooks Davis 164b0d29bc4SBrooks Davis ATF_TEST_CASE_WITHOUT_HEAD(junit_classname); 165b0d29bc4SBrooks Davis ATF_TEST_CASE_BODY(junit_classname) 166b0d29bc4SBrooks Davis { 167b0d29bc4SBrooks Davis const model::test_program test_program = model::test_program_builder( 168b0d29bc4SBrooks Davis "plain", fs::path("dir1/dir2/program"), fs::path("/root"), "suite") 169b0d29bc4SBrooks Davis .build(); 170b0d29bc4SBrooks Davis 171b0d29bc4SBrooks Davis ATF_REQUIRE_EQ("dir1.dir2.program", drivers::junit_classname(test_program)); 172b0d29bc4SBrooks Davis } 173b0d29bc4SBrooks Davis 174b0d29bc4SBrooks Davis 175b0d29bc4SBrooks Davis ATF_TEST_CASE_WITHOUT_HEAD(junit_duration); 176b0d29bc4SBrooks Davis ATF_TEST_CASE_BODY(junit_duration) 177b0d29bc4SBrooks Davis { 178b0d29bc4SBrooks Davis ATF_REQUIRE_EQ("0.457", 179b0d29bc4SBrooks Davis drivers::junit_duration(datetime::delta(0, 456700))); 180b0d29bc4SBrooks Davis ATF_REQUIRE_EQ("3.120", 181b0d29bc4SBrooks Davis drivers::junit_duration(datetime::delta(3, 120000))); 182b0d29bc4SBrooks Davis ATF_REQUIRE_EQ("5.000", drivers::junit_duration(datetime::delta(5, 0))); 183b0d29bc4SBrooks Davis } 184b0d29bc4SBrooks Davis 185b0d29bc4SBrooks Davis 186b0d29bc4SBrooks Davis ATF_TEST_CASE_WITHOUT_HEAD(junit_metadata__defaults); 187b0d29bc4SBrooks Davis ATF_TEST_CASE_BODY(junit_metadata__defaults) 188b0d29bc4SBrooks Davis { 189b0d29bc4SBrooks Davis const model::metadata metadata = model::metadata_builder().build(); 190b0d29bc4SBrooks Davis 191b0d29bc4SBrooks Davis const std::string expected = std::string() 192b0d29bc4SBrooks Davis + drivers::junit_metadata_header 193b0d29bc4SBrooks Davis + default_metadata; 194b0d29bc4SBrooks Davis 195b0d29bc4SBrooks Davis ATF_REQUIRE_EQ(expected, drivers::junit_metadata(metadata)); 196b0d29bc4SBrooks Davis } 197b0d29bc4SBrooks Davis 198b0d29bc4SBrooks Davis 199b0d29bc4SBrooks Davis ATF_TEST_CASE_WITHOUT_HEAD(junit_metadata__overrides); 200b0d29bc4SBrooks Davis ATF_TEST_CASE_BODY(junit_metadata__overrides) 201b0d29bc4SBrooks Davis { 202b0d29bc4SBrooks Davis const model::metadata metadata = model::metadata_builder() 203b0d29bc4SBrooks Davis .add_allowed_architecture("arch1") 204b0d29bc4SBrooks Davis .add_allowed_platform("platform1") 205b0d29bc4SBrooks Davis .set_description("This is a test") 206*257e70f1SIgor Ostapenko .set_execenv("jail") 207*257e70f1SIgor Ostapenko .set_execenv_jail_params("vnet") 208b0d29bc4SBrooks Davis .set_has_cleanup(true) 209b0d29bc4SBrooks Davis .set_is_exclusive(true) 210b0d29bc4SBrooks Davis .add_required_config("config1") 211b0d29bc4SBrooks Davis .set_required_disk_space(units::bytes(456)) 212b0d29bc4SBrooks Davis .add_required_file(fs::path("file1")) 213b0d29bc4SBrooks Davis .set_required_memory(units::bytes(123)) 214b0d29bc4SBrooks Davis .add_required_program(fs::path("prog1")) 215b0d29bc4SBrooks Davis .set_required_user("root") 216b0d29bc4SBrooks Davis .set_timeout(datetime::delta(10, 0)) 217b0d29bc4SBrooks Davis .build(); 218b0d29bc4SBrooks Davis 219b0d29bc4SBrooks Davis const std::string expected = std::string() 220b0d29bc4SBrooks Davis + drivers::junit_metadata_header 221b0d29bc4SBrooks Davis + "allowed_architectures = arch1\n" 222b0d29bc4SBrooks Davis + "allowed_platforms = platform1\n" 223b0d29bc4SBrooks Davis + "description = This is a test\n" 224*257e70f1SIgor Ostapenko + "execenv = jail\n" 225*257e70f1SIgor Ostapenko + "execenv_jail_params = vnet\n" 226b0d29bc4SBrooks Davis + "has_cleanup = true\n" 227b0d29bc4SBrooks Davis + "is_exclusive = true\n" 228b0d29bc4SBrooks Davis + "required_configs = config1\n" 229b0d29bc4SBrooks Davis + "required_disk_space = 456\n" 230b0d29bc4SBrooks Davis + "required_files = file1\n" 231b0d29bc4SBrooks Davis + "required_memory = 123\n" 232b0d29bc4SBrooks Davis + "required_programs = prog1\n" 233b0d29bc4SBrooks Davis + "required_user = root\n" 234b0d29bc4SBrooks Davis + "timeout = 10\n"; 235b0d29bc4SBrooks Davis 236b0d29bc4SBrooks Davis ATF_REQUIRE_EQ(expected, drivers::junit_metadata(metadata)); 237b0d29bc4SBrooks Davis } 238b0d29bc4SBrooks Davis 239b0d29bc4SBrooks Davis 240b0d29bc4SBrooks Davis ATF_TEST_CASE_WITHOUT_HEAD(junit_timing); 241b0d29bc4SBrooks Davis ATF_TEST_CASE_BODY(junit_timing) 242b0d29bc4SBrooks Davis { 243b0d29bc4SBrooks Davis const std::string expected = std::string() 244b0d29bc4SBrooks Davis + drivers::junit_timing_header + 245b0d29bc4SBrooks Davis "Start time: 2015-06-12T01:02:35.123456Z\n" 246b0d29bc4SBrooks Davis "End time: 2016-07-13T18:47:10.000001Z\n" 247b0d29bc4SBrooks Davis "Duration: 34364674.877s\n"; 248b0d29bc4SBrooks Davis 249b0d29bc4SBrooks Davis const datetime::timestamp start_time = 250b0d29bc4SBrooks Davis datetime::timestamp::from_values(2015, 6, 12, 1, 2, 35, 123456); 251b0d29bc4SBrooks Davis const datetime::timestamp end_time = 252b0d29bc4SBrooks Davis datetime::timestamp::from_values(2016, 7, 13, 18, 47, 10, 1); 253b0d29bc4SBrooks Davis 254b0d29bc4SBrooks Davis ATF_REQUIRE_EQ(expected, drivers::junit_timing(start_time, end_time)); 255b0d29bc4SBrooks Davis } 256b0d29bc4SBrooks Davis 257b0d29bc4SBrooks Davis 258b0d29bc4SBrooks Davis ATF_TEST_CASE_WITHOUT_HEAD(report_junit_hooks__minimal); 259b0d29bc4SBrooks Davis ATF_TEST_CASE_BODY(report_junit_hooks__minimal) 260b0d29bc4SBrooks Davis { 261b0d29bc4SBrooks Davis store::write_backend backend = store::write_backend::open_rw( 262b0d29bc4SBrooks Davis fs::path("test.db")); 263b0d29bc4SBrooks Davis store::write_transaction tx = backend.start_write(); 264b0d29bc4SBrooks Davis add_context(tx, 0); 265b0d29bc4SBrooks Davis tx.commit(); 266b0d29bc4SBrooks Davis backend.close(); 267b0d29bc4SBrooks Davis 268b0d29bc4SBrooks Davis std::ostringstream output; 269b0d29bc4SBrooks Davis 270b0d29bc4SBrooks Davis drivers::report_junit_hooks hooks(output); 271b0d29bc4SBrooks Davis drivers::scan_results::drive(fs::path("test.db"), 272b0d29bc4SBrooks Davis std::set< engine::test_filter >(), 273b0d29bc4SBrooks Davis hooks); 274b0d29bc4SBrooks Davis 275b0d29bc4SBrooks Davis const char* expected = 276b0d29bc4SBrooks Davis "<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>\n" 277b0d29bc4SBrooks Davis "<testsuite>\n" 278b0d29bc4SBrooks Davis "<properties>\n" 279b0d29bc4SBrooks Davis "<property name=\"cwd\" value=\"/root\"/>\n" 280b0d29bc4SBrooks Davis "</properties>\n" 281b0d29bc4SBrooks Davis "</testsuite>\n"; 282b0d29bc4SBrooks Davis ATF_REQUIRE_EQ(expected, output.str()); 283b0d29bc4SBrooks Davis } 284b0d29bc4SBrooks Davis 285b0d29bc4SBrooks Davis 286b0d29bc4SBrooks Davis ATF_TEST_CASE_WITHOUT_HEAD(report_junit_hooks__some_tests); 287b0d29bc4SBrooks Davis ATF_TEST_CASE_BODY(report_junit_hooks__some_tests) 288b0d29bc4SBrooks Davis { 289b0d29bc4SBrooks Davis std::vector< model::test_result > results1; 290b0d29bc4SBrooks Davis results1.push_back(model::test_result( 291b0d29bc4SBrooks Davis model::test_result_broken, "Broken")); 292b0d29bc4SBrooks Davis results1.push_back(model::test_result( 293b0d29bc4SBrooks Davis model::test_result_expected_failure, "XFail")); 294b0d29bc4SBrooks Davis results1.push_back(model::test_result( 295b0d29bc4SBrooks Davis model::test_result_failed, "Failed")); 296b0d29bc4SBrooks Davis std::vector< model::test_result > results2; 297b0d29bc4SBrooks Davis results2.push_back(model::test_result( 298b0d29bc4SBrooks Davis model::test_result_passed)); 299b0d29bc4SBrooks Davis results2.push_back(model::test_result( 300b0d29bc4SBrooks Davis model::test_result_skipped, "Skipped")); 301b0d29bc4SBrooks Davis 302b0d29bc4SBrooks Davis store::write_backend backend = store::write_backend::open_rw( 303b0d29bc4SBrooks Davis fs::path("test.db")); 304b0d29bc4SBrooks Davis store::write_transaction tx = backend.start_write(); 305b0d29bc4SBrooks Davis add_context(tx, 2); 306b0d29bc4SBrooks Davis add_tests(tx, "dir/prog-1", results1, false, false); 307b0d29bc4SBrooks Davis add_tests(tx, "dir/sub/prog-2", results2, true, true); 308b0d29bc4SBrooks Davis tx.commit(); 309b0d29bc4SBrooks Davis backend.close(); 310b0d29bc4SBrooks Davis 311b0d29bc4SBrooks Davis std::ostringstream output; 312b0d29bc4SBrooks Davis 313b0d29bc4SBrooks Davis drivers::report_junit_hooks hooks(output); 314b0d29bc4SBrooks Davis drivers::scan_results::drive(fs::path("test.db"), 315b0d29bc4SBrooks Davis std::set< engine::test_filter >(), 316b0d29bc4SBrooks Davis hooks); 317b0d29bc4SBrooks Davis 318b0d29bc4SBrooks Davis const std::string expected = std::string() + 319b0d29bc4SBrooks Davis "<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>\n" 320b0d29bc4SBrooks Davis "<testsuite>\n" 321b0d29bc4SBrooks Davis "<properties>\n" 322b0d29bc4SBrooks Davis "<property name=\"cwd\" value=\"/root\"/>\n" 323b0d29bc4SBrooks Davis "<property name=\"env.VAR0\" value=\"Value 0\"/>\n" 324b0d29bc4SBrooks Davis "<property name=\"env.VAR1\" value=\"Value 1\"/>\n" 325b0d29bc4SBrooks Davis "</properties>\n" 326b0d29bc4SBrooks Davis 327b0d29bc4SBrooks Davis "<testcase classname=\"dir.prog-1\" name=\"t0\" time=\"0.500\">\n" 328b0d29bc4SBrooks Davis "<error message=\"Broken\"/>\n" 329b0d29bc4SBrooks Davis "<system-err>" 330b0d29bc4SBrooks Davis + drivers::junit_metadata_header + 331b0d29bc4SBrooks Davis default_metadata 332b0d29bc4SBrooks Davis + drivers::junit_timing_header + 333b0d29bc4SBrooks Davis "Start time: 1970-01-01T00:00:00.000000Z\n" 334b0d29bc4SBrooks Davis "End time: 1970-01-01T00:00:00.500000Z\n" 335b0d29bc4SBrooks Davis "Duration: 0.500s\n" 336b0d29bc4SBrooks Davis + drivers::junit_stderr_header + 337b0d29bc4SBrooks Davis "<EMPTY>\n" 338b0d29bc4SBrooks Davis "</system-err>\n" 339b0d29bc4SBrooks Davis "</testcase>\n" 340b0d29bc4SBrooks Davis 341b0d29bc4SBrooks Davis "<testcase classname=\"dir.prog-1\" name=\"t1\" time=\"1.500\">\n" 342b0d29bc4SBrooks Davis "<system-err>" 343b0d29bc4SBrooks Davis "Expected failure result details\n" 344b0d29bc4SBrooks Davis "-------------------------------\n" 345b0d29bc4SBrooks Davis "\n" 346b0d29bc4SBrooks Davis "XFail\n" 347b0d29bc4SBrooks Davis "\n" 348b0d29bc4SBrooks Davis + drivers::junit_metadata_header + 349b0d29bc4SBrooks Davis default_metadata 350b0d29bc4SBrooks Davis + drivers::junit_timing_header + 351b0d29bc4SBrooks Davis "Start time: 1970-01-01T00:00:00.000000Z\n" 352b0d29bc4SBrooks Davis "End time: 1970-01-01T00:00:01.500000Z\n" 353b0d29bc4SBrooks Davis "Duration: 1.500s\n" 354b0d29bc4SBrooks Davis + drivers::junit_stderr_header + 355b0d29bc4SBrooks Davis "<EMPTY>\n" 356b0d29bc4SBrooks Davis "</system-err>\n" 357b0d29bc4SBrooks Davis "</testcase>\n" 358b0d29bc4SBrooks Davis 359b0d29bc4SBrooks Davis "<testcase classname=\"dir.prog-1\" name=\"t2\" time=\"2.500\">\n" 360b0d29bc4SBrooks Davis "<failure message=\"Failed\"/>\n" 361b0d29bc4SBrooks Davis "<system-err>" 362b0d29bc4SBrooks Davis + drivers::junit_metadata_header + 363b0d29bc4SBrooks Davis default_metadata 364b0d29bc4SBrooks Davis + drivers::junit_timing_header + 365b0d29bc4SBrooks Davis "Start time: 1970-01-01T00:00:00.000000Z\n" 366b0d29bc4SBrooks Davis "End time: 1970-01-01T00:00:02.500000Z\n" 367b0d29bc4SBrooks Davis "Duration: 2.500s\n" 368b0d29bc4SBrooks Davis + drivers::junit_stderr_header + 369b0d29bc4SBrooks Davis "<EMPTY>\n" 370b0d29bc4SBrooks Davis "</system-err>\n" 371b0d29bc4SBrooks Davis "</testcase>\n" 372b0d29bc4SBrooks Davis 373b0d29bc4SBrooks Davis "<testcase classname=\"dir.sub.prog-2\" name=\"t0\" time=\"0.500\">\n" 374b0d29bc4SBrooks Davis "<system-out>stdout file 0</system-out>\n" 375b0d29bc4SBrooks Davis "<system-err>" 376b0d29bc4SBrooks Davis + drivers::junit_metadata_header + 377b0d29bc4SBrooks Davis overriden_metadata 378b0d29bc4SBrooks Davis + drivers::junit_timing_header + 379b0d29bc4SBrooks Davis "Start time: 1970-01-01T00:00:00.000000Z\n" 380b0d29bc4SBrooks Davis "End time: 1970-01-01T00:00:00.500000Z\n" 381b0d29bc4SBrooks Davis "Duration: 0.500s\n" 382b0d29bc4SBrooks Davis + drivers::junit_stderr_header + 383b0d29bc4SBrooks Davis "stderr file 0</system-err>\n" 384b0d29bc4SBrooks Davis "</testcase>\n" 385b0d29bc4SBrooks Davis 386b0d29bc4SBrooks Davis "<testcase classname=\"dir.sub.prog-2\" name=\"t1\" time=\"1.500\">\n" 387b0d29bc4SBrooks Davis "<skipped/>\n" 388b0d29bc4SBrooks Davis "<system-out>stdout file 1</system-out>\n" 389b0d29bc4SBrooks Davis "<system-err>" 390b0d29bc4SBrooks Davis "Skipped result details\n" 391b0d29bc4SBrooks Davis "----------------------\n" 392b0d29bc4SBrooks Davis "\n" 393b0d29bc4SBrooks Davis "Skipped\n" 394b0d29bc4SBrooks Davis "\n" 395b0d29bc4SBrooks Davis + drivers::junit_metadata_header + 396b0d29bc4SBrooks Davis overriden_metadata 397b0d29bc4SBrooks Davis + drivers::junit_timing_header + 398b0d29bc4SBrooks Davis "Start time: 1970-01-01T00:00:00.000000Z\n" 399b0d29bc4SBrooks Davis "End time: 1970-01-01T00:00:01.500000Z\n" 400b0d29bc4SBrooks Davis "Duration: 1.500s\n" 401b0d29bc4SBrooks Davis + drivers::junit_stderr_header + 402b0d29bc4SBrooks Davis "stderr file 1</system-err>\n" 403b0d29bc4SBrooks Davis "</testcase>\n" 404b0d29bc4SBrooks Davis 405b0d29bc4SBrooks Davis "</testsuite>\n"; 406b0d29bc4SBrooks Davis ATF_REQUIRE_EQ(expected, output.str()); 407b0d29bc4SBrooks Davis } 408b0d29bc4SBrooks Davis 409b0d29bc4SBrooks Davis 410b0d29bc4SBrooks Davis ATF_INIT_TEST_CASES(tcs) 411b0d29bc4SBrooks Davis { 412b0d29bc4SBrooks Davis ATF_ADD_TEST_CASE(tcs, junit_classname); 413b0d29bc4SBrooks Davis 414b0d29bc4SBrooks Davis ATF_ADD_TEST_CASE(tcs, junit_duration); 415b0d29bc4SBrooks Davis 416b0d29bc4SBrooks Davis ATF_ADD_TEST_CASE(tcs, junit_metadata__defaults); 417b0d29bc4SBrooks Davis ATF_ADD_TEST_CASE(tcs, junit_metadata__overrides); 418b0d29bc4SBrooks Davis 419b0d29bc4SBrooks Davis ATF_ADD_TEST_CASE(tcs, junit_timing); 420b0d29bc4SBrooks Davis 421b0d29bc4SBrooks Davis ATF_ADD_TEST_CASE(tcs, report_junit_hooks__minimal); 422b0d29bc4SBrooks Davis ATF_ADD_TEST_CASE(tcs, report_junit_hooks__some_tests); 423b0d29bc4SBrooks Davis } 424