[Boost-bugs] [Boost C++ Libraries] #13024: Using function as data source in BOOST_DATA_TEST_CASE initiate the conflict with static variables initialization

Subject: [Boost-bugs] [Boost C++ Libraries] #13024: Using function as data source in BOOST_DATA_TEST_CASE initiate the conflict with static variables initialization
From: Boost C++ Libraries (noreply_at_[hidden])
Date: 2017-05-11 08:04:43


#13024: Using function as data source in BOOST_DATA_TEST_CASE initiate the conflict
with static variables initialization
------------------------------+---------------------
 Reporter: mikhail@… | Owner: rogeeff
     Type: Bugs | Status: new
Milestone: To Be Determined | Component: test
  Version: Boost 1.64.0 | Severity: Problem
 Keywords: |
------------------------------+---------------------
 I got the crash like [https://svn.boost.org/trac/boost/ticket/12987
 here](ticket 12987) when switched my tests from boost v1.63.0 to v1.64.0.
 I'm using `BOOST_DATA_TEST_CASE` with a function as the second parameter.
 My function uses `boost::filesystem::path` to walk through directory and
 collect data files:
 {{{
 static std::vector<boost::filesystem::path> get_files()
 {
     std::vector<boost::filesystem::path> result;
     boost::system::error_code error;
     boost::filesystem::directory_iterator it("C:\\", error);
     for (boost::filesystem::directory_iterator const eit; it != eit; ++it)
         if (is_regular_file(it->status()))
             result.push_back(it->path());
     return result;
 }

 BOOST_DATA_TEST_CASE(test, get_files(), file_name)
 {
     std::cout << file_name << std::endl;
 }
 }}}

 I was very surprised when found that my `get_files()` called during static
 variables initialization (from `_initterm()`):
 {{{
 Exception thrown at 0x0000000000000000 in BoostTests.exe: 0xC0000005:
 Access violation executing location 0x0000000000000000. occurred

 0000000000000000() Unknown
 BoostTests.exe!`anonymous namespace'::make_permissions(const
 boost::filesystem::path & p, unsigned long attr) Line 629 C++
 BoostTests.exe!`anonymous namespace'::dir_itr_first(void * & handle, const
 boost::filesystem::path & dir,
 std::basic_string<wchar_t,std::char_traits<wchar_t>,std::allocator<wchar_t>
> & target, boost::filesystem::file_status & sf,
 boost::filesystem::file_status & symlink_sf) Line 2275 C++
 BoostTests.exe!boost::filesystem::detail::directory_iterator_construct(boost::filesystem::directory_iterator
 & it, const boost::filesystem::path & p, boost::system::error_code * ec)
 Line 2374 C++
 BoostTests.exe!boost::filesystem::directory_iterator::directory_iterator(const
 boost::filesystem::path & p, boost::system::error_code & ec) Line 907
 C++
 BoostTests.exe!get_files() Line 15 C++
 BoostTests.exe!test::`dynamic initializer for 'testcase_registrar2222''()
 Line 22 C++
 BoostTests.exe!_initterm(void(*)() * first, void(*)() * last) Line 22
 C++
 [External Code]
 }}}

 On my opinion the data collection has to be run immediately before test
 starting. I see some bonuses in this approach:
 - no unnecessary data collecting when user run only selected set of tests;
 - correct and suitable error handling for function, now any exception
 means crash;

 After some investigation I found that `test_case_gen` runs test creating
 in constructor to fill `m_test_cases` variable which is used only during
 `next()` call. However, `next()` also called from static context from
 `auto_test_unit_registrar`. And this is the problem!

 Could you please change the boost test behavior to grant that test
 collecting will be made in test main method, but not during static
 variable initialization?

-- 
Ticket URL: <https://svn.boost.org/trac/boost/ticket/13024>
Boost C++ Libraries <http://www.boost.org/>
Boost provides free peer-reviewed portable C++ source libraries.

This archive was generated by hypermail 2.1.7 : 2017-05-11 08:08:47 UTC