This is an automated email from the git hooks/post-receive script. sebastic pushed a commit to branch master in repository libosmium.
commit 919222e216666fef283b8f7fe537b7b143b18acb Author: Bas Couwenberg <[email protected]> Date: Sat Aug 26 08:55:42 2017 +0200 New upstream version 2.13.1 --- CHANGELOG.md | 32 ++++- CMakeLists.txt | 2 +- NOTES_FOR_DEVELOPERS.md | 34 ++++- appveyor.yml | 8 ++ build-appveyor.bat | 6 +- examples/osmium_dump_internal.cpp | 11 ++ examples/osmium_index_lookup.cpp | 43 ++++-- examples/osmium_location_cache_create.cpp | 9 +- examples/osmium_location_cache_use.cpp | 9 +- include/osmium/index/detail/mmap_vector_file.hpp | 2 +- include/osmium/io/detail/input_format.hpp | 16 +-- include/osmium/io/detail/opl_input_format.hpp | 98 +++++++------ include/osmium/io/detail/output_format.hpp | 30 ++++ include/osmium/io/file.hpp | 3 + include/osmium/io/file_format.hpp | 17 ++- include/osmium/thread/pool.hpp | 2 +- include/osmium/util/file.hpp | 46 ++++++- include/osmium/util/memory_mapping.hpp | 2 +- include/osmium/version.hpp | 4 +- test/examples/CMakeLists.txt | 33 ++++- test/examples/t/change_tags/.gitattributes | 1 + test/examples/t/dump_internal/CMakeLists.txt | 45 +++--- test/t/io/data-cr.opl | 1 + test/t/io/test_file_formats.cpp | 40 ++++++ test/t/io/test_opl_parser.cpp | 166 +++++++++++++++++++++++ test/t/memory/test_item.cpp | 16 ++- test/t/osm/test_location.cpp | 20 +-- test/t/thread/test_pool.cpp | 4 +- test/t/util/.gitattributes | 1 + test/t/util/known_file_size | 1 + test/t/util/test_file.cpp | 92 +++++-------- test/t/util/test_memory_mapping.cpp | 20 ++- 32 files changed, 620 insertions(+), 194 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9d90ae3..2493e0a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,35 @@ This project adheres to [Semantic Versioning](http://semver.org/). ### Fixed +## [2.13.1] - 2017-08-25 + +### Added + +- New "blackhole" file format which throws away all data written into it. + Used for benchmarking. + +### Changed + +- When reading OPL files, CRLF file endings are now handled correctly. +- Reduce the max number of threads allowed for the `Pool` to 32. This should + still be plenty and might help with test failures on some architectures. + +### Fixed + +- Tests now run correctly independent of git `core.autocrlf` setting. +- Set binary mode for all files on Windows in example code. +- Low-level file functions now set an invalid parameter handler on Windows + to properly handle errors. +- Restore earlier behaviour allowing zero-length mmap. It is important to + allow zero-length memory mapping, because it is possible that such an index + is empty, for instance when one type of object is missing from an input + file as in https://github.com/osmcode/osmium-tool/issues/65. Drawback is + that files must be opened read-write for this to work, even if we only + want to read from them. +- Use Approx() to compare floating point values in tests. +- Fix broken `Item` test on 32 bit platforms. + + ## [2.13.0] - 2017-08-15 ### Added @@ -710,7 +739,8 @@ This project adheres to [Semantic Versioning](http://semver.org/). Doxygen (up to version 1.8.8). This version contains a workaround to fix this. -[unreleased]: https://github.com/osmcode/libosmium/compare/v2.13.0...HEAD +[unreleased]: https://github.com/osmcode/libosmium/compare/v2.13.1...HEAD +[2.13.1]: https://github.com/osmcode/libosmium/compare/v2.13.0...v2.13.1 [2.13.0]: https://github.com/osmcode/libosmium/compare/v2.12.2...v2.13.0 [2.12.2]: https://github.com/osmcode/libosmium/compare/v2.12.1...v2.12.2 [2.12.1]: https://github.com/osmcode/libosmium/compare/v2.12.0...v2.12.1 diff --git a/CMakeLists.txt b/CMakeLists.txt index 3c5e62f..e278875 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -25,7 +25,7 @@ project(libosmium) set(LIBOSMIUM_VERSION_MAJOR 2) set(LIBOSMIUM_VERSION_MINOR 13) -set(LIBOSMIUM_VERSION_PATCH 0) +set(LIBOSMIUM_VERSION_PATCH 1) set(LIBOSMIUM_VERSION "${LIBOSMIUM_VERSION_MAJOR}.${LIBOSMIUM_VERSION_MINOR}.${LIBOSMIUM_VERSION_PATCH}") diff --git a/NOTES_FOR_DEVELOPERS.md b/NOTES_FOR_DEVELOPERS.md index 5f84494..4bd9d68 100644 --- a/NOTES_FOR_DEVELOPERS.md +++ b/NOTES_FOR_DEVELOPERS.md @@ -12,7 +12,7 @@ All Osmium code MUST be in the `osmium` namespace or one of its sub-namespaces. ## Include-Only Osmium is a include-only library. You can't compile the library itself. There -is no libosmium.so. +is no `libosmium.so` or `libosmium.dll`. One drawback ist that you can't have static data in classes, because there is no place to put this data. @@ -69,7 +69,7 @@ different. * Template parameters are single uppercase letters or start with uppercase `T` and use CamelCase. * Always use `typename` in templates, not `class`: `template <typename T>`. -* The ellipsis in variadic template never has a space to the left of it and +* The ellipsis in a variadic template never has a space to the left of it and always has a space to the right: `template <typename... TArgs>` etc. Keep to the indentation and other styles used in the code. @@ -92,6 +92,19 @@ between compilers due to different C++11 support. Usually all code must work on Linux, OSX, and Windows. Execptions are allowed for some minor functionality, but please discuss this first. +When writing code and tests, care must be taken that everything works with the +CR line ending convention used on Linux and OSX and the CRLF line ending used +on Windows. Note that `git` can be run with different settings regarding line +ending rewritings on different machines making things more difficult. Some +files have been "forced" to LF line endings using `.gitattributes` files. + + +## 32bit systems + +Libosmium tries to work on 32bit systems whereever possible. But there are +some parts which will not work on 32bit systems, mainly because the amount +of main memory available is not enough for it to work anyway. + ## Checking your code @@ -118,9 +131,20 @@ used to define mappings for iwyu. See the IWYU tool at ## Testing -There are a unit tests using the Catch Unit Test Framework in the `test` -directory and some data tests in `test/osm-testdata`. They are built by the -default cmake config. Run `ctest` to run them. Many more tests are needed. +There are unit tests using the Catch Unit Test Framework in the `test` +directory, some data tests in `test/osm-testdata` and tests of the examples in +`test/examples`. They are built by the default cmake config. Run `ctest` to +run them. We can always use more tests. + +Tests are run automatically using the Travis (Linux/Mac) and Appveyor (Windows) +services. We automatically create coverage reports on Codevoc.io. Note that +the coverage percentages reported are not always accurate, because code that +is not used in tests at all will not necessarily end up in the binary and +the code coverage tool will not know it is there. + +[](https://travis-ci.org/osmcode/libosmium) +[](https://ci.appveyor.com/project/Mapbox/libosmium) +[](https://codecov.io/gh/osmcode/libosmium) ## Documenting the code diff --git a/appveyor.yml b/appveyor.yml index d1eea30..ca77ae6 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -7,7 +7,13 @@ environment: matrix: - config: Dev + autocrlf: true + - config: Dev + autocrlf: false + - config: RelWithDebInfo + autocrlf: true - config: RelWithDebInfo + autocrlf: false shallow_clone: true @@ -16,6 +22,8 @@ os: Visual Studio 2015 # scripts that are called at very beginning, before repo cloning init: + - git config --global core.autocrlf %autocrlf% + - git config --get core.autocrlf # clone directory clone_folder: c:\projects\libosmium diff --git a/build-appveyor.bat b/build-appveyor.bat index b4f45f3..ef9da5f 100644 --- a/build-appveyor.bat +++ b/build-appveyor.bat @@ -97,12 +97,14 @@ ECHO calling^: %CMAKE_CMD% %CMAKE_CMD% IF %ERRORLEVEL% NEQ 0 GOTO ERROR +SET avlogger= +IF /I "%APPVEYOR%"=="True" SET avlogger=/logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll" + msbuild libosmium.sln ^ /p:Configuration=%config% ^ /toolsversion:14.0 ^ /p:Platform=x64 ^ -/p:PlatformToolset=v140 ^ -/logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll" +/p:PlatformToolset=v140 %avlogger% IF %ERRORLEVEL% NEQ 0 GOTO ERROR ctest --output-on-failure ^ diff --git a/examples/osmium_dump_internal.cpp b/examples/osmium_dump_internal.cpp index 58f49b3..78229da 100644 --- a/examples/osmium_dump_internal.cpp +++ b/examples/osmium_dump_internal.cpp @@ -36,6 +36,10 @@ #include <sys/stat.h> // for open #include <sys/types.h> // for open +#ifdef _WIN32 +# include <io.h> // for _setmode +#endif + #ifdef _MSC_VER # include <direct.h> #endif @@ -72,6 +76,9 @@ public: std::cerr << "Can't open index file '" << filename << "': " << std::strerror(errno) << "\n"; std::exit(2); } +#ifdef _WIN32 + _setmode(m_fd, _O_BINARY); +#endif } ~IndexFile() { @@ -114,6 +121,10 @@ int main(int argc, char* argv[]) { std::exit(2); } +#ifdef _WIN32 + _setmode(data_fd, _O_BINARY); +#endif + // These indexes store the offset in the data file where each node, way, // or relation is stored. offset_index_type node_index; diff --git a/examples/osmium_index_lookup.cpp b/examples/osmium_index_lookup.cpp index 4449e70..2af2378 100644 --- a/examples/osmium_index_lookup.cpp +++ b/examples/osmium_index_lookup.cpp @@ -33,6 +33,10 @@ #include <sys/types.h> // for open #include <vector> // for std::vector +#ifdef _WIN32 +# include <io.h> // for _setmode +#endif + // Disk-based indexes #include <osmium/index/map/dense_file_array.hpp> #include <osmium/index/map/sparse_file_array.hpp> @@ -243,7 +247,7 @@ public: std::exit(2); } - if (m_dump && !m_ids.empty()) { + if (m_dump == !m_ids.empty()) { std::cerr << "Need option --dump or --search, but not both\n"; std::exit(2); } @@ -308,26 +312,35 @@ int main(int argc, char* argv[]) { Options options{argc, argv}; // Open the index file. - const int fd = open(options.filename(), O_RDWR); + const int fd = ::open(options.filename(), O_RDWR); if (fd < 0) { std::cerr << "Can not open file '" << options.filename() << "': " << std::strerror(errno) << '\n'; std::exit(2); } - // Depending on the type of index, we have different implementations. - if (options.type_is("location")) { - // index id -> location - const auto index = create<osmium::Location>(options.dense_format(), fd); - return run(*index, options); - } else if (options.type_is("id")) { - // index id -> id - const auto index = create<osmium::unsigned_object_id_type>(options.dense_format(), fd); - return run(*index, options); - } else { - // index id -> offset - const auto index = create<std::size_t>(options.dense_format(), fd); - return run(*index, options); +#ifdef _WIN32 + _setmode(fd, _O_BINARY); +#endif + + try { + // Depending on the type of index, we have different implementations. + if (options.type_is("location")) { + // index id -> location + const auto index = create<osmium::Location>(options.dense_format(), fd); + return run(*index, options); + } else if (options.type_is("id")) { + // index id -> id + const auto index = create<osmium::unsigned_object_id_type>(options.dense_format(), fd); + return run(*index, options); + } else { + // index id -> offset + const auto index = create<std::size_t>(options.dense_format(), fd); + return run(*index, options); + } + } catch(const std::exception& e) { + std::cerr << "Error: " << e.what() << '\n'; + std::exit(1); } } diff --git a/examples/osmium_location_cache_create.cpp b/examples/osmium_location_cache_create.cpp index c01dd97..a7119df 100644 --- a/examples/osmium_location_cache_create.cpp +++ b/examples/osmium_location_cache_create.cpp @@ -33,6 +33,10 @@ #include <sys/stat.h> // for open #include <sys/types.h> // for open +#ifdef _WIN32 +# include <io.h> // for _setmode +#endif + // Allow any format of input files (XML, PBF, ...) #include <osmium/io/any_input.hpp> @@ -68,11 +72,14 @@ int main(int argc, char* argv[]) { osmium::io::Reader reader{input_filename, osmium::osm_entity_bits::node}; // Initialize location index on disk creating a new file. - const int fd = open(cache_filename.c_str(), O_RDWR | O_CREAT | O_TRUNC, 0666); + const int fd = ::open(cache_filename.c_str(), O_RDWR | O_CREAT | O_TRUNC, 0666); if (fd == -1) { std::cerr << "Can not open location cache file '" << cache_filename << "': " << std::strerror(errno) << "\n"; std::exit(1); } +#ifdef _WIN32 + _setmode(fd, _O_BINARY); +#endif index_type index{fd}; // The handler that stores all node locations in the index. diff --git a/examples/osmium_location_cache_use.cpp b/examples/osmium_location_cache_use.cpp index f5db0be..6af0fe6 100644 --- a/examples/osmium_location_cache_use.cpp +++ b/examples/osmium_location_cache_use.cpp @@ -33,6 +33,10 @@ #include <sys/stat.h> // for open #include <sys/types.h> // for open +#ifdef _WIN32 +# include <io.h> // for _setmode +#endif + // Allow any format of input files (XML, PBF, ...) #include <osmium/io/any_input.hpp> @@ -81,11 +85,14 @@ int main(int argc, char* argv[]) { osmium::io::Reader reader{input_filename, osmium::osm_entity_bits::way}; // Initialize location index on disk using an existing file - const int fd = open(cache_filename.c_str(), O_RDWR); + const int fd = ::open(cache_filename.c_str(), O_RDWR); if (fd == -1) { std::cerr << "Can not open location cache file '" << cache_filename << "': " << std::strerror(errno) << "\n"; return 1; } +#ifdef _WIN32 + _setmode(fd, _O_BINARY); +#endif index_type index{fd}; // The handler that adds node locations from the index to the ways. diff --git a/include/osmium/index/detail/mmap_vector_file.hpp b/include/osmium/index/detail/mmap_vector_file.hpp index ff0ca54..d853992 100644 --- a/include/osmium/index/detail/mmap_vector_file.hpp +++ b/include/osmium/index/detail/mmap_vector_file.hpp @@ -53,7 +53,7 @@ namespace osmium { template <typename T> class mmap_vector_file : public mmap_vector_base<T> { - std::size_t filesize(int fd) const { + static std::size_t filesize(int fd) { const auto size = osmium::util::file_size(fd); if (size % sizeof(T) != 0) { diff --git a/include/osmium/io/detail/input_format.hpp b/include/osmium/io/detail/input_format.hpp index 442c717..7ba6677 100644 --- a/include/osmium/io/detail/input_format.hpp +++ b/include/osmium/io/detail/input_format.hpp @@ -81,14 +81,6 @@ namespace osmium { return m_pool; } - std::string get_input() { - return m_input_queue.pop(); - } - - bool input_done() const { - return m_input_queue.has_reached_end_of_data(); - } - osmium::osm_entity_bits::type read_types() const noexcept { return m_read_which_entities; } @@ -148,6 +140,14 @@ namespace osmium { virtual void run() = 0; + std::string get_input() { + return m_input_queue.pop(); + } + + bool input_done() const { + return m_input_queue.has_reached_end_of_data(); + } + void parse() { try { run(); diff --git a/include/osmium/io/detail/opl_input_format.hpp b/include/osmium/io/detail/opl_input_format.hpp index 0d7a62d..f5fcd00 100644 --- a/include/osmium/io/detail/opl_input_format.hpp +++ b/include/osmium/io/detail/opl_input_format.hpp @@ -51,10 +51,56 @@ namespace osmium { namespace detail { + // Feed data coming in blocks line by line to the OPL parser + // function. This has been broken out of the OPLParser class + // where it belongs into a standalone template function to be + // better testable. + template <typename T> + void line_by_line(T& worker) { + std::string rest; + + while (!worker.input_done()) { + std::string input{worker.get_input()}; + std::string::size_type ppos = 0; + + if (!rest.empty()) { + ppos = input.find_first_of("\n\r"); + if (ppos == std::string::npos) { + rest.append(input); + continue; + } + rest.append(input, 0, ppos); + if (!rest.empty()) { + worker.parse_line(rest.data()); + rest.clear(); + } + ++ppos; + } + + for (auto pos = input.find_first_of("\n\r", ppos); + pos != std::string::npos; + pos = input.find_first_of("\n\r", ppos)) { + const char* data = &input[ppos]; + input[pos] = '\0'; + if (data[0] != '\0') { + worker.parse_line(data); + } + ppos = pos + 1; + if (ppos >= input.size()) { + break; + } + } + rest.assign(input, ppos, std::string::npos); + } + + if (!rest.empty()) { + worker.parse_line(rest.data()); + } + } + class OPLParser : public Parser { osmium::memory::Buffer m_buffer{1024*1024}; - const char* m_data = nullptr; uint64_t m_line_count = 0; void maybe_flush() { @@ -67,13 +113,6 @@ namespace osmium { } } - void parse_line() { - if (opl_parse_line(m_line_count, m_data, m_buffer, read_types())) { - maybe_flush(); - } - ++m_line_count; - } - public: explicit OPLParser(parser_arguments& args) : @@ -83,44 +122,17 @@ namespace osmium { ~OPLParser() noexcept final = default; + void parse_line(const char* data) { + if (opl_parse_line(m_line_count, data, m_buffer, read_types())) { + maybe_flush(); + } + ++m_line_count; + } + void run() final { osmium::thread::set_thread_name("_osmium_opl_in"); - std::string rest; - while (!input_done()) { - std::string input{get_input()}; - std::string::size_type ppos = 0; - - if (!rest.empty()) { - ppos = input.find('\n'); - if (ppos == std::string::npos) { - rest.append(input); - continue; - } - rest.append(input.substr(0, ppos)); - m_data = rest.data(); - parse_line(); - rest.clear(); - } - - std::string::size_type pos = input.find('\n', ppos); - while (pos != std::string::npos) { - m_data = &input[ppos]; - input[pos] = '\0'; - parse_line(); - ppos = pos + 1; - if (ppos >= input.size()) { - break; - } - pos = input.find('\n', ppos); - } - rest = input.substr(ppos); - } - - if (!rest.empty()) { - m_data = rest.data(); - parse_line(); - } + line_by_line(*this); if (m_buffer.committed() > 0) { send_to_output_queue(std::move(m_buffer)); diff --git a/include/osmium/io/detail/output_format.hpp b/include/osmium/io/detail/output_format.hpp index 5fe8bd9..21d5e86 100644 --- a/include/osmium/io/detail/output_format.hpp +++ b/include/osmium/io/detail/output_format.hpp @@ -197,6 +197,36 @@ namespace osmium { }; // class OutputFormatFactory + class BlackholeOutputFormat : public osmium::io::detail::OutputFormat { + + public: + + BlackholeOutputFormat(osmium::thread::Pool& pool, const osmium::io::File& /*file*/, future_string_queue_type& output_queue) : + OutputFormat(pool, output_queue) { + } + + BlackholeOutputFormat(const BlackholeOutputFormat&) = delete; + BlackholeOutputFormat& operator=(const BlackholeOutputFormat&) = delete; + + ~BlackholeOutputFormat() noexcept final = default; + + void write_buffer(osmium::memory::Buffer&& /*buffer*/) final { + } + + }; // class BlackholeOutputFormat + + // we want the register_output_format() function to run, setting + // the variable is only a side-effect, it will never be used + const bool registered_blackhole_output = osmium::io::detail::OutputFormatFactory::instance().register_output_format(osmium::io::file_format::blackhole, + [](osmium::thread::Pool& pool, const osmium::io::File& file, future_string_queue_type& output_queue) { + return new osmium::io::detail::BlackholeOutputFormat(pool, file, output_queue); + }); + + // dummy function to silence the unused variable warning from above + inline bool get_registered_blackhole_output() noexcept { + return registered_blackhole_output; + } + } // namespace detail } // namespace io diff --git a/include/osmium/io/file.hpp b/include/osmium/io/file.hpp index bf7c874..4b40924 100644 --- a/include/osmium/io/file.hpp +++ b/include/osmium/io/file.hpp @@ -235,6 +235,9 @@ namespace osmium { } else if (suffixes.back() == "debug") { m_file_format = file_format::debug; suffixes.pop_back(); + } else if (suffixes.back() == "blackhole") { + m_file_format = file_format::blackhole; + suffixes.pop_back(); } if (suffixes.empty()) { diff --git a/include/osmium/io/file_format.hpp b/include/osmium/io/file_format.hpp index 620082c..cde1299 100644 --- a/include/osmium/io/file_format.hpp +++ b/include/osmium/io/file_format.hpp @@ -40,13 +40,14 @@ namespace osmium { namespace io { enum class file_format { - unknown = 0, - xml = 1, - pbf = 2, - opl = 3, - json = 4, - o5m = 5, - debug = 6 + unknown = 0, + xml = 1, + pbf = 2, + opl = 3, + json = 4, + o5m = 5, + debug = 6, + blackhole = 7 }; enum class read_meta { @@ -68,6 +69,8 @@ namespace osmium { return "O5M"; case file_format::debug: return "DEBUG"; + case file_format::blackhole: + return "BLACKHOLE"; default: // file_format::unknown break; } diff --git a/include/osmium/thread/pool.hpp b/include/osmium/thread/pool.hpp index 5539e7a..ef64954 100644 --- a/include/osmium/thread/pool.hpp +++ b/include/osmium/thread/pool.hpp @@ -56,7 +56,7 @@ namespace osmium { // Maximum number of allowed pool threads (just to keep the user // from setting something silly). - constexpr const int max_pool_threads = 256; + constexpr const int max_pool_threads = 32; inline int get_pool_size(int num_threads, int user_setting, unsigned hardware_concurrency) { if (num_threads == 0) { diff --git a/include/osmium/util/file.hpp b/include/osmium/util/file.hpp index 431445b..4af6d77 100644 --- a/include/osmium/util/file.hpp +++ b/include/osmium/util/file.hpp @@ -47,6 +47,7 @@ DEALINGS IN THE SOFTWARE. # endif # include <io.h> # include <windows.h> +# include <crtdbg.h> #endif #ifndef _MSC_VER @@ -59,6 +60,44 @@ namespace osmium { namespace util { +#ifdef _MSC_VER + namespace detail { + + // Disable parameter validation on Windows and reenable it + // automatically when scope closes. + // https://docs.microsoft.com/en-us/cpp/c-runtime-library/parameter-validation + class disable_invalid_parameter_handler { + + static void invalid_parameter_handler( + const wchar_t* expression, + const wchar_t* function, + const wchar_t* file, + unsigned int line, + uintptr_t pReserved + ) { + // do nothing + } + + _invalid_parameter_handler old_handler; + int old_report_mode; + + public: + + disable_invalid_parameter_handler() : + old_handler(_set_thread_local_invalid_parameter_handler(invalid_parameter_handler)), + old_report_mode(_CrtSetReportMode(_CRT_ASSERT, 0)) { + } + + ~disable_invalid_parameter_handler() { + _CrtSetReportMode(_CRT_ASSERT, old_report_mode); + _set_thread_local_invalid_parameter_handler(old_handler); + } + + }; // class disable_invalid_parameter_handler + + } +#endif + /** * Get file size. * This is a small wrapper around a system call. @@ -70,9 +109,10 @@ namespace osmium { inline std::size_t file_size(int fd) { #ifdef _MSC_VER // Windows implementation + detail::disable_invalid_parameter_handler diph; // https://msdn.microsoft.com/en-us/library/dfbc2kec.aspx const auto size = ::_filelengthi64(fd); - if (size == -1L) { + if (size < 0) { throw std::system_error{errno, std::system_category(), "Could not get file size"}; } return static_cast<std::size_t>(size); @@ -93,6 +133,7 @@ namespace osmium { * @param name File name * @returns file size * @throws std::system_error If system call failed + * @pre name must not be nullptr */ inline std::size_t file_size(const char* name) { #ifdef _MSC_VER @@ -134,6 +175,7 @@ namespace osmium { */ inline void resize_file(int fd, std::size_t new_size) { #ifdef _WIN32 + detail::disable_invalid_parameter_handler diph; // https://msdn.microsoft.com/en-us/library/whx354w1.aspx if (::_chsize_s(fd, static_cast_with_assert<__int64>(new_size)) != 0) { #else @@ -166,6 +208,7 @@ namespace osmium { */ inline std::size_t file_offset(int fd) { #ifdef _MSC_VER + detail::disable_invalid_parameter_handler diph; // https://msdn.microsoft.com/en-us/library/1yee101t.aspx const auto offset = _lseeki64(fd, 0, SEEK_CUR); #else @@ -182,6 +225,7 @@ namespace osmium { */ inline bool isatty(int fd) { #ifdef _MSC_VER + detail::disable_invalid_parameter_handler diph; // https://msdn.microsoft.com/en-us/library/f4s0ddew.aspx return _isatty(fd) != 0; #else diff --git a/include/osmium/util/memory_mapping.hpp b/include/osmium/util/memory_mapping.hpp index a26e372..c405979 100644 --- a/include/osmium/util/memory_mapping.hpp +++ b/include/osmium/util/memory_mapping.hpp @@ -139,7 +139,7 @@ namespace osmium { static std::size_t check_size(std::size_t size) { if (size == 0) { - throw std::runtime_error{"Zero-sized mapping is not allowed."}; + return osmium::util::get_pagesize(); } return size; } diff --git a/include/osmium/version.hpp b/include/osmium/version.hpp index eb1aa36..004ad0e 100644 --- a/include/osmium/version.hpp +++ b/include/osmium/version.hpp @@ -35,8 +35,8 @@ DEALINGS IN THE SOFTWARE. #define LIBOSMIUM_VERSION_MAJOR 2 #define LIBOSMIUM_VERSION_MINOR 13 -#define LIBOSMIUM_VERSION_PATCH 0 +#define LIBOSMIUM_VERSION_PATCH 1 -#define LIBOSMIUM_VERSION_STRING "2.13.0" +#define LIBOSMIUM_VERSION_STRING "2.13.1" #endif // OSMIUM_VERSION_HPP diff --git a/test/examples/CMakeLists.txt b/test/examples/CMakeLists.txt index 90bf76e..f6d427d 100644 --- a/test/examples/CMakeLists.txt +++ b/test/examples/CMakeLists.txt @@ -8,13 +8,40 @@ message(STATUS "Configuring example tests") -file(GLOB _dirs RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/t/*) +set(EXAMPLE_TESTS + amenity_list + area_test + change_tags + convert + count + create_pois + debug + dump_internal + filter_discussions + index_lookup + location_cache + pub_names + read + read_with_progress + road_length + tiles +) -foreach(_dir ${_dirs}) +# This is the list of all tests that are in the repository. It should be the +# same as the configured list above, if not we'll find out about that below +# and create a fatal error. +file(GLOB _dirs RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}/t ${CMAKE_CURRENT_SOURCE_DIR}/t/*) + +foreach(_dir ${EXAMPLE_TESTS}) message(STATUS " adding test: ${_dir}") - add_subdirectory("${_dir}") + add_subdirectory("t/${_dir}") + list(REMOVE_ITEM _dirs ${_dir}) endforeach() +if(NOT ${_dirs} STREQUAL "") + message(FATAL_ERROR "Found example tests that are not configured: ${_dirs}") +endif() + message(STATUS "Configuring example tests - done") diff --git a/test/examples/t/change_tags/.gitattributes b/test/examples/t/change_tags/.gitattributes new file mode 100644 index 0000000..f4111dd --- /dev/null +++ b/test/examples/t/change_tags/.gitattributes @@ -0,0 +1 @@ +result.osm text eol=lf diff --git a/test/examples/t/dump_internal/CMakeLists.txt b/test/examples/t/dump_internal/CMakeLists.txt index 6938563..fa942ef 100644 --- a/test/examples/t/dump_internal/CMakeLists.txt +++ b/test/examples/t/dump_internal/CMakeLists.txt @@ -2,40 +2,35 @@ add_test(NAME examples_dump_internal COMMAND osmium_dump_internal ${CMAKE_CURRENT_SOURCE_DIR}/data.osm ${CMAKE_CURRENT_BINARY_DIR}/out) -# XXX Disable failing tests on Windows until we figure out what's wrong -# See https://github.com/osmcode/libosmium/issues/220 -if(NOT MSVC) - add_test(NAME examples_dump_internal_index_nodes - COMMAND osmium_index_lookup --list=${CMAKE_CURRENT_BINARY_DIR}/out/nodes.idx --type=offset --dump) +add_test(NAME examples_dump_internal_index_nodes + COMMAND osmium_index_lookup --list=${CMAKE_CURRENT_BINARY_DIR}/out/nodes.idx --type=offset --dump) - set_tests_properties(examples_dump_internal_index_nodes PROPERTIES - DEPENDS examples_dump_internal - PASS_REGULAR_EXPRESSION "^701000 .*\n701001 .*\n") +set_tests_properties(examples_dump_internal_index_nodes PROPERTIES + DEPENDS examples_dump_internal + PASS_REGULAR_EXPRESSION "^701000 .*\n701001 .*\n") - add_test(NAME examples_dump_internal_index_ways - COMMAND osmium_index_lookup --list=${CMAKE_CURRENT_BINARY_DIR}/out/ways.idx --type=offset --dump) +add_test(NAME examples_dump_internal_index_ways + COMMAND osmium_index_lookup --list=${CMAKE_CURRENT_BINARY_DIR}/out/ways.idx --type=offset --dump) - set_tests_properties(examples_dump_internal_index_ways PROPERTIES - DEPENDS examples_dump_internal - PASS_REGULAR_EXPRESSION "^701800 .*\n701801 .*\n") +set_tests_properties(examples_dump_internal_index_ways PROPERTIES + DEPENDS examples_dump_internal + PASS_REGULAR_EXPRESSION "^701800 .*\n701801 .*\n") - add_test(NAME examples_dump_internal_map_node2way_dump - COMMAND osmium_index_lookup --list=${CMAKE_CURRENT_BINARY_DIR}/out/node2way.map --type=id --dump) +add_test(NAME examples_dump_internal_map_node2way_dump + COMMAND osmium_index_lookup --list=${CMAKE_CURRENT_BINARY_DIR}/out/node2way.map --type=id --dump) - set_tests_properties(examples_dump_internal_map_node2way_dump PROPERTIES - DEPENDS examples_dump_internal - PASS_REGULAR_EXPRESSION "^701000 701800\n701000 701801\n701001 701800\n") +set_tests_properties(examples_dump_internal_map_node2way_dump PROPERTIES + DEPENDS examples_dump_internal + PASS_REGULAR_EXPRESSION "^701000 701800\n701000 701801\n701001 701800\n") - add_test(NAME examples_dump_internal_map_node2way_search - COMMAND osmium_index_lookup --list=${CMAKE_CURRENT_BINARY_DIR}/out/node2way.map --type=id --search=701002) +add_test(NAME examples_dump_internal_map_node2way_search + COMMAND osmium_index_lookup --list=${CMAKE_CURRENT_BINARY_DIR}/out/node2way.map --type=id --search=701002) - set_tests_properties(examples_dump_internal_map_node2way_search PROPERTIES - DEPENDS examples_dump_internal - PASS_REGULAR_EXPRESSION "^701002 701800\n701002 701801\n$") - -endif() +set_tests_properties(examples_dump_internal_map_node2way_search PROPERTIES + DEPENDS examples_dump_internal + PASS_REGULAR_EXPRESSION "^701002 701800\n701002 701801\n$") diff --git a/test/t/io/data-cr.opl b/test/t/io/data-cr.opl new file mode 100644 index 0000000..aef666e --- /dev/null +++ b/test/t/io/data-cr.opl @@ -0,0 +1 @@ +n1 v1 dV c1 t2014-01-01T00:00:00Z i1 utest T x1.02 y1.02 diff --git a/test/t/io/test_file_formats.cpp b/test/t/io/test_file_formats.cpp index 8b63f94..284d477 100644 --- a/test/t/io/test_file_formats.cpp +++ b/test/t/io/test_file_formats.cpp @@ -189,6 +189,46 @@ TEST_CASE("Override file format by suffix 'osh.opl.gz'") { f.check(); } +TEST_CASE("File format by suffix 'blackhole'") { + const osmium::io::File f{"test.blackhole"}; + REQUIRE(osmium::io::file_format::blackhole == f.format()); + REQUIRE(osmium::io::file_compression::none == f.compression()); + REQUIRE(false == f.has_multiple_object_versions()); + f.check(); +} + +TEST_CASE("Override file format by suffix 'blackhole'") { + const osmium::io::File f{"test", "blackhole"}; + REQUIRE(osmium::io::file_format::blackhole == f.format()); + REQUIRE(osmium::io::file_compression::none == f.compression()); + REQUIRE(false == f.has_multiple_object_versions()); + f.check(); +} + +TEST_CASE("Override file format by suffix 'osm.blackhole'") { + const osmium::io::File f{"test", "osm.blackhole"}; + REQUIRE(osmium::io::file_format::blackhole == f.format()); + REQUIRE(osmium::io::file_compression::none == f.compression()); + REQUIRE(false == f.has_multiple_object_versions()); + f.check(); +} + +TEST_CASE("Override file format by suffix 'osm.blackhole.bz2'") { + const osmium::io::File f{"test", "osm.blackhole.bz2"}; + REQUIRE(osmium::io::file_format::blackhole == f.format()); + REQUIRE(osmium::io::file_compression::bzip2 == f.compression()); + REQUIRE(false == f.has_multiple_object_versions()); + f.check(); +} + +TEST_CASE("Override file format by suffix 'osh.blackhole.gz'") { + const osmium::io::File f{"test", "osh.blackhole.gz"}; + REQUIRE(osmium::io::file_format::blackhole == f.format()); + REQUIRE(osmium::io::file_compression::gzip == f.compression()); + REQUIRE(true == f.has_multiple_object_versions()); + f.check(); +} + TEST_CASE("Override file format by suffix 'osh.pbf'") { const osmium::io::File f{"test", "osh.pbf"}; REQUIRE(osmium::io::file_format::pbf == f.format()); diff --git a/test/t/io/test_opl_parser.cpp b/test/t/io/test_opl_parser.cpp index 7ecf2b8..88cd570 100644 --- a/test/t/io/test_opl_parser.cpp +++ b/test/t/io/test_opl_parser.cpp @@ -1052,6 +1052,16 @@ TEST_CASE("Parse OPL using Reader") { REQUIRE(node.id() == 1); } +TEST_CASE("Parse OPL with CRLF line ending using Reader") { + osmium::io::File file{with_data_dir("t/io/data-cr.opl")}; + osmium::io::Reader reader{file}; + + const auto buffer = reader.read(); + REQUIRE(buffer); + const auto& node = buffer.get<osmium::Node>(0); + REQUIRE(node.id() == 1); +} + TEST_CASE("Parse OPL with missing newline using Reader") { osmium::io::File file{with_data_dir("t/io/data-nonl.opl")}; osmium::io::Reader reader{file}; @@ -1062,3 +1072,159 @@ TEST_CASE("Parse OPL with missing newline using Reader") { REQUIRE(node.id() == 1); } +class lbl_tester { + + std::vector<std::string> m_inputs; + std::vector<std::string> m_outputs; + +public: + + lbl_tester(const std::initializer_list<std::string>& inputs, + const std::initializer_list<std::string>& outputs) : + m_inputs(inputs), + m_outputs(outputs) { + } + + bool input_done() { + return m_inputs.empty(); + } + + std::string get_input() { + REQUIRE_FALSE(m_inputs.empty()); + std::string data = std::move(m_inputs.front()); + m_inputs.erase(m_inputs.begin()); + return data; + } + + void parse_line(const char *data) { + REQUIRE_FALSE(m_outputs.empty()); + REQUIRE(m_outputs.front() == data); + m_outputs.erase(m_outputs.begin()); + } + + void check() { + REQUIRE(m_inputs.empty()); + REQUIRE(m_outputs.empty()); + } + +}; // class lbl_tester + +void check_lbl(const std::initializer_list<std::string>& in, + const std::initializer_list<std::string>& out) { + lbl_tester tester{in, out}; + osmium::io::detail::line_by_line(tester); + tester.check(); +} + +TEST_CASE("line_by_line for OPL parser 1") { + check_lbl({""}, {}); +} + +TEST_CASE("line_by_line for OPL parser 2") { + check_lbl({"\n"}, {}); +} + +TEST_CASE("line_by_line for OPL parser 3") { + check_lbl({"foo\n"}, {"foo"}); +} + +TEST_CASE("line_by_line for OPL parser 4") { + check_lbl({"foo"}, {"foo"}); +} + +TEST_CASE("line_by_line for OPL parser 5") { + check_lbl({"foo\nbar\n"}, {"foo", "bar"}); +} + +TEST_CASE("line_by_line for OPL parser 6") { + check_lbl({"foo\nbar"}, {"foo", "bar"}); +} + +TEST_CASE("line_by_line for OPL parser 7") { + check_lbl({"foo\nbar\nbaz\n"}, {"foo", "bar", "baz"}); +} + +TEST_CASE("line_by_line for OPL parser 8") { + check_lbl({"foo\n", "bar\n"}, {"foo", "bar"}); +} + +TEST_CASE("line_by_line for OPL parser 9") { + check_lbl({"foo\nb", "ar\n"}, {"foo", "bar"}); +} + +TEST_CASE("line_by_line for OPL parser 10") { + check_lbl({"foo\nb", "ar\n", "baz\n"}, {"foo", "bar", "baz"}); +} + +TEST_CASE("line_by_line for OPL parser 11") { + check_lbl({"foo", "\nbar\n"}, {"foo", "bar"}); +} + +TEST_CASE("line_by_line for OPL parser 12") { + check_lbl({"foo", "\nbar"}, {"foo", "bar"}); +} + +TEST_CASE("line_by_line for OPL parser 13") { + check_lbl({"foo", "\nbar", "\n"}, {"foo", "bar"}); +} + +TEST_CASE("line_by_line for OPL parser 14") { + check_lbl({"foo\n", "b", "ar\n"}, {"foo", "bar"}); +} + +TEST_CASE("line_by_line for OPL parser 15") { + check_lbl({"foo\n", "ba", "r\n"}, {"foo", "bar"}); +} + +TEST_CASE("line_by_line for OPL parser 16") { + check_lbl({"foo", "\n", "bar\n"}, {"foo", "bar"}); +} + +TEST_CASE("line_by_line for OPL parser 17") { + check_lbl({"foo\r\nbar\r\n"}, {"foo", "bar"}); +} + +TEST_CASE("line_by_line for OPL parser 18") { + check_lbl({"foo\r\nb", "ar\r\n"}, {"foo", "bar"}); +} + +TEST_CASE("line_by_line for OPL parser 19") { + check_lbl({"foo\r\nb", "ar\n", "baz\r\n"}, {"foo", "bar", "baz"}); +} + +TEST_CASE("line_by_line for OPL parser 20") { + check_lbl({"foo", "\r\nbar\r\n"}, {"foo", "bar"}); +} + +TEST_CASE("line_by_line for OPL parser 21") { + check_lbl({"foo\r", "\nbar"}, {"foo", "bar"}); +} + +TEST_CASE("line_by_line for OPL parser 22") { + check_lbl({"foo", "\r\nbar\r", "\n"}, {"foo", "bar"}); +} + +TEST_CASE("line_by_line for OPL parser 23") { + check_lbl({"foo\r\n", "b", "ar\r\n"}, {"foo", "bar"}); +} + +TEST_CASE("line_by_line for OPL parser 24") { + check_lbl({"foo\n", "ba", "r\r\n"}, {"foo", "bar"}); +} + +TEST_CASE("line_by_line for OPL parser 25") { + check_lbl({"foo", "\n", "bar\r\n"}, {"foo", "bar"}); +} + +TEST_CASE("line_by_line for OPL parser 26") { + check_lbl({"foo", "\n\r", "bar\r"}, {"foo", "bar"}); +} + +TEST_CASE("line_by_line for OPL parser 27") { + check_lbl({"foo\r", "bar\n\r"}, {"foo", "bar"}); +} + +TEST_CASE("line_by_line for OPL parser 28") { + check_lbl({"foo\nb", "ar"}, {"foo", "bar"}); +} + diff --git a/test/t/memory/test_item.cpp b/test/t/memory/test_item.cpp index a81003d..81e18a9 100644 --- a/test/t/memory/test_item.cpp +++ b/test/t/memory/test_item.cpp @@ -14,12 +14,16 @@ TEST_CASE("padded length") { REQUIRE(osmium::memory::padded_length(2147483648) == 2147483648); REQUIRE(osmium::memory::padded_length(2147483650) == 2147483656); - REQUIRE(osmium::memory::padded_length(4294967295) == 4294967296); - REQUIRE(osmium::memory::padded_length(4294967296) == 4294967296); - REQUIRE(osmium::memory::padded_length(4294967297) == 4294967304); + // The following checks only make sense on a 64 bit system (with + // sizeof(size_t) == 8), because the numbers are too large for 32 bit. + // The casts to size_t do nothing on a 64 bit system, on a 32 bit system + // they bring the numbers into the right range and everything still works. + REQUIRE(osmium::memory::padded_length(static_cast<std::size_t>(4294967295)) == static_cast<std::size_t>(4294967296)); + REQUIRE(osmium::memory::padded_length(static_cast<std::size_t>(4294967296)) == static_cast<std::size_t>(4294967296)); + REQUIRE(osmium::memory::padded_length(static_cast<std::size_t>(4294967297)) == static_cast<std::size_t>(4294967304)); - REQUIRE(osmium::memory::padded_length(7999999999) == 8000000000); - REQUIRE(osmium::memory::padded_length(8000000000) == 8000000000); - REQUIRE(osmium::memory::padded_length(8000000001) == 8000000008); + REQUIRE(osmium::memory::padded_length(static_cast<std::size_t>(7999999999)) == static_cast<std::size_t>(8000000000)); + REQUIRE(osmium::memory::padded_length(static_cast<std::size_t>(8000000000)) == static_cast<std::size_t>(8000000000)); + REQUIRE(osmium::memory::padded_length(static_cast<std::size_t>(8000000001)) == static_cast<std::size_t>(8000000008)); } diff --git a/test/t/osm/test_location.cpp b/test/t/osm/test_location.cpp index 28cf16e..a47a49c 100644 --- a/test/t/osm/test_location.cpp +++ b/test/t/osm/test_location.cpp @@ -25,32 +25,32 @@ TEST_CASE("Location instantiation with double parameters") { REQUIRE_FALSE(loc1.is_undefined()); REQUIRE(12000000 == loc1.x()); REQUIRE(45000000 == loc1.y()); - REQUIRE(1.2 == loc1.lon()); - REQUIRE(4.5 == loc1.lat()); + REQUIRE(1.2 == Approx(loc1.lon())); + REQUIRE(4.5 == Approx(loc1.lat())); const osmium::Location loc2{loc1}; - REQUIRE(4.5 == loc2.lat()); + REQUIRE(4.5 == Approx(loc2.lat())); const osmium::Location loc3 = loc1; - REQUIRE(4.5 == loc3.lat()); + REQUIRE(4.5 == Approx(loc3.lat())); } TEST_CASE("Location instantiation with double parameters constructor with universal initializer") { const osmium::Location loc{2.2, 3.3}; - REQUIRE(2.2 == loc.lon()); - REQUIRE(3.3 == loc.lat()); + REQUIRE(2.2 == Approx(loc.lon())); + REQUIRE(3.3 == Approx(loc.lat())); } TEST_CASE("Location instantiation with double parameters constructor with initializer list") { const osmium::Location loc({4.4, 5.5}); - REQUIRE(4.4 == loc.lon()); - REQUIRE(5.5 == loc.lat()); + REQUIRE(4.4 == Approx(loc.lon())); + REQUIRE(5.5 == Approx(loc.lat())); } TEST_CASE("Location instantiation with double parameters operator equal") { const osmium::Location loc = {5.5, 6.6}; - REQUIRE(5.5 == loc.lon()); - REQUIRE(6.6 == loc.lat()); + REQUIRE(5.5 == Approx(loc.lon())); + REQUIRE(6.6 == Approx(loc.lat())); } TEST_CASE("Location equality") { diff --git a/test/t/thread/test_pool.cpp b/test/t/thread/test_pool.cpp index 5f0e5b6..567d8de 100644 --- a/test/t/thread/test_pool.cpp +++ b/test/t/thread/test_pool.cpp @@ -43,8 +43,8 @@ TEST_CASE("number of threads in pool") { REQUIRE(osmium::thread::detail::get_pool_size( 0, 8, 16) == 8); // outliers - REQUIRE(osmium::thread::detail::get_pool_size(-100, 0, 16) == 1); - REQUIRE(osmium::thread::detail::get_pool_size(1000, 0, 16) == 256); + REQUIRE(osmium::thread::detail::get_pool_size(-100, 0, 16) == 1); + REQUIRE(osmium::thread::detail::get_pool_size(1000, 0, 16) == 32); } diff --git a/test/t/util/.gitattributes b/test/t/util/.gitattributes new file mode 100644 index 0000000..a22ace4 --- /dev/null +++ b/test/t/util/.gitattributes @@ -0,0 +1 @@ +known_file_size text eol=lf diff --git a/test/t/util/known_file_size b/test/t/util/known_file_size new file mode 100644 index 0000000..1369e1e --- /dev/null +++ b/test/t/util/known_file_size @@ -0,0 +1 @@ +this file has size 22 diff --git a/test/t/util/test_file.cpp b/test/t/util/test_file.cpp index 17afd07..a5d65ce 100644 --- a/test/t/util/test_file.cpp +++ b/test/t/util/test_file.cpp @@ -1,71 +1,51 @@ #include "catch.hpp" +#include "utils.hpp" +#include <osmium/io/detail/read_write.hpp> #include <osmium/util/file.hpp> -#ifdef _WIN32 -#include <crtdbg.h> -// https://msdn.microsoft.com/en-us/library/ksazx244.aspx -// https://msdn.microsoft.com/en-us/library/a9yf33zb.aspx -class DoNothingInvalidParameterHandler { - - static void invalid_parameter_handler( - const wchar_t* expression, - const wchar_t* function, - const wchar_t* file, - unsigned int line, - uintptr_t pReserved - ) { - // do nothing - } - - _invalid_parameter_handler old_handler; - -public: - - DoNothingInvalidParameterHandler() : - old_handler(_set_invalid_parameter_handler(invalid_parameter_handler)) { - _CrtSetReportMode(_CRT_ASSERT, 0); - } - - ~DoNothingInvalidParameterHandler() { - _set_invalid_parameter_handler(old_handler); - } - -}; // class InvalidParameterHandler -#endif - - -TEST_CASE("file_size") { - -#ifdef _WIN32 - DoNothingInvalidParameterHandler handler; -#endif +TEST_CASE("file_size(int) and file_offset() of known file") { + std::string file_name{with_data_dir("t/util/known_file_size")}; + const int fd = osmium::io::detail::open_for_reading(file_name); + REQUIRE(fd > 0); + REQUIRE(osmium::util::file_size(fd) == 22); + REQUIRE(osmium::util::file_offset(fd) == 0); + REQUIRE_FALSE(osmium::util::isatty(fd)); +} - SECTION("illegal fd should throw") { - REQUIRE_THROWS_AS(osmium::util::file_size(-1), const std::system_error&); - } +TEST_CASE("file_size(std::string) of known file") { + std::string file_name{with_data_dir("t/util/known_file_size")}; + REQUIRE(osmium::util::file_size(file_name) == 22); +} - SECTION("unused fd should throw") { - // its unlikely that fd 1000 is open... - REQUIRE_THROWS_AS(osmium::util::file_size(1000), const std::system_error&); - } +TEST_CASE("file_size(const char*) of known file") { + std::string file_name{with_data_dir("t/util/known_file_size")}; + REQUIRE(osmium::util::file_size(file_name.c_str()) == 22); +} +TEST_CASE("file_size() with illegal fd should throw") { + REQUIRE_THROWS_AS(osmium::util::file_size(-1), const std::system_error&); } -TEST_CASE("resize_file") { +TEST_CASE("file_size() with unused fd should throw") { + // its unlikely that fd 1000 is open... + REQUIRE_THROWS_AS(osmium::util::file_size(1000), const std::system_error&); +} -#ifdef _WIN32 - DoNothingInvalidParameterHandler handler; -#endif +TEST_CASE("file_size() of unknown file should throw") { + REQUIRE_THROWS_AS(osmium::util::file_size("unknown file"), const std::system_error&); +} - SECTION("illegal fd should throw") { - REQUIRE_THROWS_AS(osmium::util::resize_file(-1, 10), const std::system_error&); - } +TEST_CASE("resize_file() with illegal fd should throw") { + REQUIRE_THROWS_AS(osmium::util::resize_file(-1, 10), const std::system_error&); +} - SECTION("unused fd should throw") { - // its unlikely that fd 1000 is open... - REQUIRE_THROWS_AS(osmium::util::resize_file(1000, 10), const std::system_error&); - } +TEST_CASE("resize_file() with unused fd should throw") { + // its unlikely that fd 1000 is open... + REQUIRE_THROWS_AS(osmium::util::resize_file(1000, 10), const std::system_error&); +} +TEST_CASE("get_pagesize()") { + REQUIRE(osmium::util::get_pagesize() > 0); } diff --git a/test/t/util/test_memory_mapping.cpp b/test/t/util/test_memory_mapping.cpp index 966f670..7330aaf 100644 --- a/test/t/util/test_memory_mapping.cpp +++ b/test/t/util/test_memory_mapping.cpp @@ -32,8 +32,9 @@ TEST_CASE("Anonymous mapping: simple memory mapping should work") { mapping.unmap(); // second unmap is okay } -TEST_CASE("Anonymous mapping: memory mapping of zero length should fail") { - REQUIRE_THROWS(osmium::util::MemoryMapping(0, osmium::util::MemoryMapping::mapping_mode::write_private)); +TEST_CASE("Anonymous mapping: memory mapping of zero length should result in memory mapping of pagesize length") { + osmium::util::MemoryMapping mapping{0, osmium::util::MemoryMapping::mapping_mode::write_private}; + REQUIRE(mapping.size() == osmium::util::get_pagesize()); } TEST_CASE("Anonymous mapping: moving a memory mapping should work") { @@ -145,6 +146,21 @@ TEST_CASE("File-based mapping: writing to a mapped file should work") { REQUIRE(0 == unlink(filename)); } +TEST_CASE("File-based mapping: Reading from a zero-sized mapped file should work") { + char filename[] = "test_mmap_read_zero_XXXXXX"; + const int fd = mkstemp(filename); + REQUIRE(fd > 0); + + { + osmium::util::MemoryMapping mapping{0, osmium::util::MemoryMapping::mapping_mode::readonly, fd}; + REQUIRE(mapping.size() > 0); + mapping.unmap(); + } + + REQUIRE(0 == close(fd)); + REQUIRE(0 == unlink(filename)); +} + TEST_CASE("File-based mapping: writing to a privately mapped file should work") { char filename[] = "test_mmap_write_XXXXXX"; const int fd = mkstemp(filename); -- Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-grass/libosmium.git _______________________________________________ Pkg-grass-devel mailing list [email protected] http://lists.alioth.debian.org/cgi-bin/mailman/listinfo/pkg-grass-devel

