diff options
author | Yuri Gorshenin <y@maps.me> | 2015-06-16 13:24:50 +0300 |
---|---|---|
committer | Alex Zolotarev <alex@maps.me> | 2015-09-23 02:51:37 +0300 |
commit | 6afccd14ac29c038bd2261168d0e66c91ff79e1f (patch) | |
tree | 5764fd28ec9beabc8673b33e0eab604fd618dbce /platform | |
parent | c53d7f1494773d1c5b499e858caa7fab436ac5fa (diff) |
Review fixes.
Diffstat (limited to 'platform')
-rw-r--r-- | platform/country_defines.cpp | 12 | ||||
-rw-r--r-- | platform/country_defines.hpp | 10 | ||||
-rw-r--r-- | platform/country_file.cpp | 9 | ||||
-rw-r--r-- | platform/country_file.hpp | 5 | ||||
-rw-r--r-- | platform/local_country_file.cpp | 30 | ||||
-rw-r--r-- | platform/local_country_file.hpp | 3 | ||||
-rw-r--r-- | platform/local_country_file_utils.cpp | 149 | ||||
-rw-r--r-- | platform/local_country_file_utils.hpp | 37 | ||||
-rw-r--r-- | platform/platform.cpp | 2 | ||||
-rw-r--r-- | platform/platform.hpp | 1 | ||||
-rw-r--r-- | platform/platform_qt.cpp | 2 | ||||
-rw-r--r-- | platform/platform_tests/country_file_tests.cpp | 10 | ||||
-rw-r--r-- | platform/platform_tests/local_country_file_tests.cpp | 197 |
13 files changed, 384 insertions, 83 deletions
diff --git a/platform/country_defines.cpp b/platform/country_defines.cpp index fa5a5ec31f..5a3ab9e8f5 100644 --- a/platform/country_defines.cpp +++ b/platform/country_defines.cpp @@ -2,13 +2,23 @@ #include "base/assert.hpp" +bool HasOptions(TMapOptions options, TMapOptions bits) +{ + return (static_cast<uint8_t>(options) & static_cast<uint8_t>(bits)) == static_cast<uint8_t>(bits); +} + +TMapOptions SetOptions(TMapOptions options, TMapOptions bits) +{ + return static_cast<TMapOptions>(static_cast<uint8_t>(options) | static_cast<uint8_t>(bits)); +} + string DebugPrint(TMapOptions options) { switch (options) { case TMapOptions::ENothing: return "Nothing"; - case TMapOptions::EMapOnly: + case TMapOptions::EMap: return "MapOnly"; case TMapOptions::ECarRouting: return "CarRouting"; diff --git a/platform/country_defines.hpp b/platform/country_defines.hpp index 57ba90de80..11e6f97842 100644 --- a/platform/country_defines.hpp +++ b/platform/country_defines.hpp @@ -1,15 +1,17 @@ #pragma once #include "std/string.hpp" -#include "3party/enum_flags.hpp" -ENUM_FLAGS(TMapOptions) -enum class TMapOptions +enum class TMapOptions : uint8_t { ENothing = 0x0, - EMapOnly = 0x1, + EMap = 0x1, ECarRouting = 0x2, EMapWithCarRouting = 0x3 }; +bool HasOptions(TMapOptions options, TMapOptions bits); + +TMapOptions SetOptions(TMapOptions options, TMapOptions bits); + string DebugPrint(TMapOptions options); diff --git a/platform/country_file.cpp b/platform/country_file.cpp index 2055e5cb14..8fffb2a52d 100644 --- a/platform/country_file.cpp +++ b/platform/country_file.cpp @@ -4,6 +4,8 @@ #include "base/assert.hpp" #include "std/sstream.hpp" +namespace platform +{ CountryFile::CountryFile() : m_mapSize(0), m_routingSize(0) {} CountryFile::CountryFile(string const & name) : m_name(name), m_mapSize(0), m_routingSize(0) {} @@ -14,7 +16,7 @@ string CountryFile::GetNameWithExt(TMapOptions file) const { switch (file) { - case TMapOptions::EMapOnly: + case TMapOptions::EMap: return m_name + DATA_FILE_EXTENSION; case TMapOptions::ECarRouting: return m_name + DATA_FILE_EXTENSION + ROUTING_FILE_EXTENSION; @@ -33,9 +35,9 @@ void CountryFile::SetRemoteSizes(uint32_t mapSize, uint32_t routingSize) uint32_t CountryFile::GetRemoteSize(TMapOptions filesMask) const { uint32_t size = 0; - if (filesMask & TMapOptions::EMapOnly) + if (HasOptions(filesMask, TMapOptions::EMap)) size += m_mapSize; - if (filesMask & TMapOptions::ECarRouting) + if (HasOptions(filesMask, TMapOptions::ECarRouting)) size += m_routingSize; return size; } @@ -46,3 +48,4 @@ string DebugPrint(CountryFile const & file) os << "CountryFile [" << file.m_name << "]"; return os.str(); } +} // namespace platform diff --git a/platform/country_file.hpp b/platform/country_file.hpp index 342ad8b4fc..e23a81e85e 100644 --- a/platform/country_file.hpp +++ b/platform/country_file.hpp @@ -3,9 +3,11 @@ #include "platform/country_defines.hpp" #include "std/string.hpp" +namespace platform +{ // This class represents a country file name and sizes of // corresponding map files on a server, which should correspond to an -// entry in counties.txt file. Also, this class can be used to +// entry in countries.txt file. Also, this class can be used to // represent a hand-made-country name. Instances of this class don't // represent paths to disk files. class CountryFile @@ -34,3 +36,4 @@ private: }; string DebugPrint(CountryFile const & file); +} // namespace platform diff --git a/platform/local_country_file.cpp b/platform/local_country_file.cpp index 621a4e7a3f..48c9f92da8 100644 --- a/platform/local_country_file.cpp +++ b/platform/local_country_file.cpp @@ -8,6 +8,8 @@ #include "std/sstream.hpp" +namespace platform +{ LocalCountryFile::LocalCountryFile() : m_version(0), m_files(TMapOptions::ENothing), m_mapSize(0), m_routingSize() { @@ -32,21 +34,23 @@ void LocalCountryFile::SyncWithDisk() Platform & platform = GetPlatform(); - string const mapPath = GetPath(TMapOptions::EMapOnly); - if (platform.GetFileSizeByName(mapPath, m_mapSize)) - m_files = m_files | TMapOptions::EMapOnly; + if (platform.GetFileSizeByName(GetPath(TMapOptions::EMap), m_mapSize)) + m_files = SetOptions(m_files, TMapOptions::EMap); string const routingPath = GetPath(TMapOptions::ECarRouting); if (platform.GetFileSizeByName(routingPath, m_routingSize)) - m_files = m_files | TMapOptions::ECarRouting; + m_files = SetOptions(m_files, TMapOptions::ECarRouting); } void LocalCountryFile::DeleteFromDisk() { - for (TMapOptions file : {TMapOptions::EMapOnly, TMapOptions::ECarRouting}) + for (TMapOptions file : {TMapOptions::EMap, TMapOptions::ECarRouting}) { if (OnDisk(file)) - my::DeleteFileX(GetPath(file)); + { + bool const deleted = my::DeleteFileX(GetPath(file)); + ASSERT(deleted, (file, "from", *this, "wasn't deleted from disk.")); + } } } @@ -58,9 +62,9 @@ string LocalCountryFile::GetPath(TMapOptions file) const uint32_t LocalCountryFile::GetSize(TMapOptions filesMask) const { uint64_t size64 = 0; - if (filesMask & TMapOptions::EMapOnly) + if (HasOptions(filesMask, TMapOptions::EMap)) size64 += m_mapSize; - if (filesMask & TMapOptions::ECarRouting) + if (HasOptions(filesMask, TMapOptions::ECarRouting)) size64 += m_routingSize; uint32_t const size32 = static_cast<uint32_t>(size64); ASSERT_EQUAL(size32, size64, ()); @@ -73,12 +77,17 @@ bool LocalCountryFile::operator<(LocalCountryFile const & rhs) const return m_countryFile < rhs.m_countryFile; if (m_version != rhs.m_version) return m_version < rhs.m_version; - return m_files < rhs.m_files; + if (m_directory != rhs.m_directory) + return m_directory < rhs.m_directory; + if (m_files != rhs.m_files) + return m_files < rhs.m_files; + return false; } bool LocalCountryFile::operator==(LocalCountryFile const & rhs) const { - return m_countryFile == rhs.m_countryFile && m_version == rhs.m_version && m_files == rhs.m_files; + return m_directory == rhs.m_directory && m_countryFile == rhs.m_countryFile && + m_version == rhs.m_version && m_files == rhs.m_files; } // static @@ -97,3 +106,4 @@ string DebugPrint(LocalCountryFile const & file) << file.m_version << ", " << DebugPrint(file.m_files) << "]"; return os.str(); } +} // namespace platform diff --git a/platform/local_country_file.hpp b/platform/local_country_file.hpp index 87570bdb06..c73975f772 100644 --- a/platform/local_country_file.hpp +++ b/platform/local_country_file.hpp @@ -6,6 +6,8 @@ #include "std/string.hpp" #include "std/vector.hpp" +namespace platform +{ // This class represents a path to disk files corresponding to some // country region. class LocalCountryFile @@ -71,3 +73,4 @@ private: }; string DebugPrint(LocalCountryFile const & file); +} // namespace platform diff --git a/platform/local_country_file_utils.cpp b/platform/local_country_file_utils.cpp index e01b5c69bd..cba1ac3dbb 100644 --- a/platform/local_country_file_utils.cpp +++ b/platform/local_country_file_utils.cpp @@ -2,17 +2,71 @@ #include "platform/platform.hpp" #include "coding/file_name_utils.hpp" - +#include "coding/file_writer.hpp" +#include "base/string_utils.hpp" +#include "base/logging.hpp" #include "std/algorithm.hpp" #include "std/cctype.hpp" -namespace local_country_file_utils +namespace platform { namespace { size_t const kMaxTimestampLength = 18; + +bool IsSpecialFile(string const & file) { return file == "." || file == ".."; } } // namespace +void CleanupMapsDirectory() +{ + Platform & platform = GetPlatform(); + + string const mapsDir = platform.WritableDir(); + + // Remove partially downloaded maps. + { + Platform::FilesList files; + string const regexp = "\\" DATA_FILE_EXTENSION "\\.(downloading2?$|resume2?$)"; + platform.GetFilesByRegExp(mapsDir, regexp, files); + for (string const & file : files) + FileWriter::DeleteFileX(file); + } + + // Find and remove Brazil and Japan maps. + vector<LocalCountryFile> localFiles; + FindAllLocalMaps(localFiles); + for (LocalCountryFile & localFile : localFiles) + { + CountryFile const countryFile = localFile.GetCountryFile(); + if (countryFile.GetNameWithoutExt() == "Japan" || countryFile.GetNameWithoutExt() == "Brazil") + { + localFile.SyncWithDisk(); + localFile.DeleteFromDisk(); + } + } + + // Try to delete empty folders. + Platform::FilesList subdirs; + Platform::GetFilesByType(mapsDir, Platform::FILE_TYPE_DIRECTORY, subdirs); + for (string const & subdir : subdirs) + { + int64_t version; + if (ParseVersion(subdir, version)) + { + vector<string> files; + string const subdirPath = my::JoinFoldersToPath(mapsDir, subdir); + platform.GetFilesByType(subdirPath, + Platform::FILE_TYPE_REGULAR | Platform::FILE_TYPE_DIRECTORY, files); + if (all_of(files.begin(), files.end(), &IsSpecialFile)) + { + Platform::EError ret = Platform::RmDir(subdirPath); + ASSERT_EQUAL(Platform::ERR_OK, ret, + ("Can't remove empty directory:", subdirPath, "error:", ret)); + } + } + } +} + void FindAllLocalMapsInDirectory(string const & directory, int64_t version, vector<LocalCountryFile> & localFiles) { @@ -22,11 +76,10 @@ void FindAllLocalMapsInDirectory(string const & directory, int64_t version, platform.GetFilesByRegExp(directory, ".*\\" DATA_FILE_EXTENSION "$", files); for (string const & file : files) { + // Remove DATA_FILE_EXTENSION and use base name as a country file name. string name = file; my::GetNameWithoutExt(name); - - CountryFile const countryFile(name); - localFiles.emplace_back(directory, countryFile, version); + localFiles.emplace_back(directory, CountryFile(name), version); } } @@ -34,7 +87,13 @@ void FindAllLocalMaps(vector<LocalCountryFile> & localFiles) { vector<LocalCountryFile> allFiles; Platform & platform = GetPlatform(); - for (string const & directory : {platform.ResourcesDir(), platform.WritableDir()}) + vector<string> baseDirectories = { + platform.ResourcesDir(), platform.WritableDir(), + }; + sort(baseDirectories.begin(), baseDirectories.end()); + baseDirectories.erase(unique(baseDirectories.begin(), baseDirectories.end()), + baseDirectories.end()); + for (string const & directory : baseDirectories) { FindAllLocalMapsInDirectory(directory, 0 /* version */, allFiles); @@ -47,12 +106,35 @@ void FindAllLocalMaps(vector<LocalCountryFile> & localFiles) FindAllLocalMapsInDirectory(my::JoinFoldersToPath(directory, subdir), version, allFiles); } } -#ifdef OMIM_OS_ANDROID +#if defined(OMIM_OS_ANDROID) // On Android World and WorldCoasts can be stored in alternative /Android/obb/ path. - FindAllLocalMapsInDirectory("/Android/obb/", 0 /* version */, allFiles); -#endif - sort(allFiles.begin(), allFiles.end()); - allFiles.erase(unique(allFiles.begin(), allFiles.end()), allFiles.end()); + for (string const & file : {WORLD_FILE_NAME, WORLD_COASTS_FILE_NAME}) + { + bool found = false; + for (LocalCountryFile const & localFile : allFiles) + { + if (localFile.GetCountryFile().GetNameWithoutExt() == file) + { + found = true; + break; + } + } + if (!found) + { + try + { + ModelReaderPtr reader = platform.GetReader(file + DATA_FILE_EXTENSION); + allFiles.emplace_back(my::GetDirectory(reader.GetName()), CountryFile(file), + 0 /* version */); + } + catch (FileAbsentException const & e) + { + LOG(LERROR, ("Can't find map file for", file, ".")); + } + } + } +#endif // defined(OMIM_OS_ANDROID) + localFiles.insert(localFiles.end(), allFiles.begin(), allFiles.end()); } @@ -60,14 +142,41 @@ bool ParseVersion(string const & s, int64_t & version) { if (s.empty() || s.size() > kMaxTimestampLength) return false; - if (!all_of(s.begin(), s.end(), [](char c) -> bool - { - return isdigit(c); - })) - return false; - version = 0; - for (char c : s) - version = version * 10 + c - '0'; + int64_t v = 0; + for (char const c : s) + { + if (!isdigit(c)) + return false; + v = v * 10 + c - '0'; + } + version = v; return true; } -} // namespace local_country_file_utils + +shared_ptr<LocalCountryFile> PreparePlaceForCountryFiles(CountryFile const & countryFile, + int64_t version) +{ + Platform & platform = GetPlatform(); + if (version == 0) + return make_shared<LocalCountryFile>(platform.WritableDir(), countryFile, version); + string const directory = + my::JoinFoldersToPath(platform.WritableDir(), strings::to_string(version)); + switch (platform.MkDir(directory)) + { + case Platform::ERR_OK: + return make_shared<LocalCountryFile>(directory, countryFile, version); + case Platform::ERR_FILE_ALREADY_EXISTS: + { + Platform::EFileType type; + if (Platform::GetFileType(directory, type) != Platform::ERR_OK || + type != Platform::FILE_TYPE_DIRECTORY) + { + return shared_ptr<LocalCountryFile>(); + } + return make_shared<LocalCountryFile>(directory, countryFile, version); + } + default: + return shared_ptr<LocalCountryFile>(); + }; +} +} // namespace platform diff --git a/platform/local_country_file_utils.hpp b/platform/local_country_file_utils.hpp index 74b7775375..2b9b852c17 100644 --- a/platform/local_country_file_utils.hpp +++ b/platform/local_country_file_utils.hpp @@ -2,14 +2,47 @@ #include "platform/local_country_file.hpp" +#include "std/shared_ptr.hpp" #include "std/utility.hpp" #include "std/vector.hpp" -namespace local_country_file_utils +namespace platform { +// Removes partially downloaded maps, empty directories and old +// (format v1) maps. Also, removes old (splitted) Japan and Brazil +// maps. +void CleanupMapsDirectory(); + +// Finds all local map files in a directory. Version of these files is +// passed as an argument. void FindAllLocalMapsInDirectory(string const & directory, int64_t version, vector<LocalCountryFile> & localFiles); + +// Finds all local map files in resources and writable +// directory. Also, for Android, checks /Android/obb directory. +// Directories should have the following structure: +// +// dir/*.mwm -- map files, base name should correspond to countries.txt, +// -- version is assumed to be zero (unknown). +// dir/*.mwm.routing -- routing files for corresponding map files, +// -- version is assumed to be zero (unknown). +// dir/[0-9]+/*.mwm -- map files, base name should correspond to countries.txt, +// -- version is assumed to be the name of a directory. +// dir/[0-9]{1,18}/*.mwm.routing -- routing file for corresponding map files, +// -- version is assumed to be the name of a directory. +// +// We can't derive version of a map file from its header because +// currently header stores format version + individual mwm's file +// generation timestamp, not timestamp mentioned in countries.txt. void FindAllLocalMaps(vector<LocalCountryFile> & localFiles); +// Tries to parse a version from a string of size not longer than 18 +// symbols and representing an unsigned decimal number. Leading zeroes +// are allowed. bool ParseVersion(string const & s, int64_t & version); -} // namespace local_country_file_utils + +// When version is zero, uses writable directory, otherwise, creates +// directory with name equal to decimal representation of version. +shared_ptr<LocalCountryFile> PreparePlaceForCountryFiles(CountryFile const & countryFile, + int64_t version); +} // namespace platform diff --git a/platform/platform.cpp b/platform/platform.cpp index e9c2841a2b..76d0fe2c38 100644 --- a/platform/platform.cpp +++ b/platform/platform.cpp @@ -20,6 +20,8 @@ Platform::EError Platform::ErrnoToError() return ERR_ACCESS_FAILED; case ENOTEMPTY: return ERR_DIRECTORY_NOT_EMPTY; + case EEXIST: + return ERR_FILE_ALREADY_EXISTS; default: return ERR_UNKNOWN; } diff --git a/platform/platform.hpp b/platform/platform.hpp index 28698ed1c2..91f86740d7 100644 --- a/platform/platform.hpp +++ b/platform/platform.hpp @@ -25,6 +25,7 @@ public: ERR_FILE_DOES_NOT_EXIST, ERR_ACCESS_FAILED, ERR_DIRECTORY_NOT_EMPTY, + ERR_FILE_ALREADY_EXISTS, ERR_UNKNOWN }; diff --git a/platform/platform_qt.cpp b/platform/platform_qt.cpp index 5d4e185dde..004c273446 100644 --- a/platform/platform_qt.cpp +++ b/platform/platform_qt.cpp @@ -59,6 +59,8 @@ int Platform::VideoMemoryLimit() const Platform::EError Platform::MkDir(string const & dirName) const { + if (QDir().exists(dirName.c_str())) + return Platform::ERR_FILE_ALREADY_EXISTS; if(!QDir().mkdir(dirName.c_str())) { LOG(LWARNING, ("Can't create directory: ", dirName)); diff --git a/platform/platform_tests/country_file_tests.cpp b/platform/platform_tests/country_file_tests.cpp index b160876a5b..136aceede6 100644 --- a/platform/platform_tests/country_file_tests.cpp +++ b/platform/platform_tests/country_file_tests.cpp @@ -3,24 +3,26 @@ #include "defines.hpp" #include "platform/country_file.hpp" +namespace platform +{ UNIT_TEST(CountryFile_Smoke) { CountryFile countryFile("TestCountry"); TEST_EQUAL("TestCountry", countryFile.GetNameWithoutExt(), ()); - TEST_EQUAL("TestCountry" DATA_FILE_EXTENSION, countryFile.GetNameWithExt(TMapOptions::EMapOnly), - ()); + TEST_EQUAL("TestCountry" DATA_FILE_EXTENSION, countryFile.GetNameWithExt(TMapOptions::EMap), ()); TEST_EQUAL("TestCountry" DATA_FILE_EXTENSION ROUTING_FILE_EXTENSION, countryFile.GetNameWithExt(TMapOptions::ECarRouting), ()); TEST_EQUAL(0, countryFile.GetRemoteSize(TMapOptions::ENothing), ()); - TEST_EQUAL(0, countryFile.GetRemoteSize(TMapOptions::EMapOnly), ()); + TEST_EQUAL(0, countryFile.GetRemoteSize(TMapOptions::EMap), ()); TEST_EQUAL(0, countryFile.GetRemoteSize(TMapOptions::ECarRouting), ()); TEST_EQUAL(0, countryFile.GetRemoteSize(TMapOptions::EMapWithCarRouting), ()); countryFile.SetRemoteSizes(1 /* mapSize */, 2 /* routingSize */); TEST_EQUAL(0, countryFile.GetRemoteSize(TMapOptions::ENothing), ()); - TEST_EQUAL(1, countryFile.GetRemoteSize(TMapOptions::EMapOnly), ()); + TEST_EQUAL(1, countryFile.GetRemoteSize(TMapOptions::EMap), ()); TEST_EQUAL(2, countryFile.GetRemoteSize(TMapOptions::ECarRouting), ()); TEST_EQUAL(3, countryFile.GetRemoteSize(TMapOptions::EMapWithCarRouting), ()); } +} // namespace platform diff --git a/platform/platform_tests/local_country_file_tests.cpp b/platform/platform_tests/local_country_file_tests.cpp index 0ae32e93e5..5594a4e63f 100644 --- a/platform/platform_tests/local_country_file_tests.cpp +++ b/platform/platform_tests/local_country_file_tests.cpp @@ -16,22 +16,73 @@ #include "std/bind.hpp" #include "std/set.hpp" -using namespace local_country_file_utils; - +namespace platform +{ namespace { -void CreateTestDir(string const & testDir) +template <typename T> +bool Contains(vector<T> const & v, T const & t) { - Platform & platform = GetPlatform(); - TEST(!Platform::IsFileExistsByFullPath(testDir), - ("Please, remove", testDir, "before running the test.")); - TEST_EQUAL(Platform::ERR_OK, platform.MkDir(testDir), ("Can't create directory", testDir)); + return find(v.begin(), v.end(), t) != v.end(); } +class ScopedTestDir +{ +public: + ScopedTestDir(string const & path) : m_path(path), m_reset(false) + { + Platform & platform = GetPlatform(); + Platform::EError ret = platform.MkDir(m_path); + switch (ret) + { + case Platform::ERR_OK: + break; + case Platform::ERR_FILE_ALREADY_EXISTS: + Platform::EFileType type; + TEST_EQUAL(Platform::ERR_OK, Platform::GetFileType(m_path, type), ()); + TEST_EQUAL(Platform::FILE_TYPE_DIRECTORY, type, ()); + break; + default: + CHECK(false, ("Can't create directory:", m_path, "error:", ret)); + break; + } + } + + ~ScopedTestDir() + { + if (m_reset) + return; + + Platform::EError ret = Platform::RmDir(m_path); + switch (ret) + { + case Platform::ERR_OK: + break; + case Platform::ERR_FILE_DOES_NOT_EXIST: + LOG(LWARNING, (m_path, "was deleted before destruction of ScopedTestDir.")); + break; + case Platform::ERR_DIRECTORY_NOT_EMPTY: + LOG(LWARNING, ("There are files in", m_path)); + break; + default: + LOG(LWARNING, ("Platform::RmDir() error:", ret)); + break; + } + } + + inline void Reset() { m_reset = true; } + + inline string const GetPath() const { return m_path; } + +private: + string const m_path; + bool m_reset; + + DISALLOW_COPY_AND_MOVE(ScopedTestDir); +}; + void CreateTestFile(string const & testFile, string const & contents) { - TEST(!Platform::IsFileExistsByFullPath(testFile), - ("Please, remove", testFile, "before running the test.")); { FileWriter writer(testFile); writer.Write(contents.data(), contents.size()); @@ -59,6 +110,7 @@ UNIT_TEST(LocalCountryFile_ParseVersion) TEST_EQUAL(version, 999999999999999999, ()); TEST(!ParseVersion("1000000000000000000", version), ()); + TEST(!ParseVersion("00000000000000000000000000000000123", version), ()); TEST(!ParseVersion("", version), ()); TEST(!ParseVersion("150309 ", version), ()); @@ -75,8 +127,7 @@ UNIT_TEST(LocalCountryFile_Smoke) LocalCountryFile localFile("/test-dir", countryFile, 150309); - TEST_EQUAL("/test-dir/TestCountry" DATA_FILE_EXTENSION, localFile.GetPath(TMapOptions::EMapOnly), - ()); + TEST_EQUAL("/test-dir/TestCountry" DATA_FILE_EXTENSION, localFile.GetPath(TMapOptions::EMap), ()); TEST_EQUAL("/test-dir/TestCountry" DATA_FILE_EXTENSION ROUTING_FILE_EXTENSION, localFile.GetPath(TMapOptions::ECarRouting), ()); @@ -86,14 +137,14 @@ UNIT_TEST(LocalCountryFile_Smoke) // Any statement is true about elements of an empty set. TEST(localFile.OnDisk(TMapOptions::ENothing), ()); - TEST(!localFile.OnDisk(TMapOptions::EMapOnly), ()); + TEST(!localFile.OnDisk(TMapOptions::EMap), ()); TEST(!localFile.OnDisk(TMapOptions::ECarRouting), ()); TEST(!localFile.OnDisk(TMapOptions::EMapWithCarRouting), ()); TEST_EQUAL("/test-dir", localFile.GetDirectory(), ()); TEST_EQUAL(0, localFile.GetSize(TMapOptions::ENothing), ()); - TEST_EQUAL(0, localFile.GetSize(TMapOptions::EMapOnly), ()); + TEST_EQUAL(0, localFile.GetSize(TMapOptions::EMap), ()); TEST_EQUAL(0, localFile.GetSize(TMapOptions::ECarRouting), ()); TEST_EQUAL(0, localFile.GetSize(TMapOptions::EMapWithCarRouting), ()); @@ -109,31 +160,31 @@ UNIT_TEST(LocalCountryFile_DiskFiles) CountryFile countryFile("TestCountry"); countryFile.SetRemoteSizes(1 /* mapSize */, 2 /* routingSize */); - string const testMapFile = my::JoinFoldersToPath( - platform.WritableDir(), countryFile.GetNameWithExt(TMapOptions::EMapOnly)); + string const testMapFile = + my::JoinFoldersToPath(platform.WritableDir(), countryFile.GetNameWithExt(TMapOptions::EMap)); string const testRoutingFile = my::JoinFoldersToPath( platform.WritableDir(), countryFile.GetNameWithExt(TMapOptions::ECarRouting)); LocalCountryFile localFile(platform.WritableDir(), countryFile, 0 /* version */); - TEST(!localFile.OnDisk(TMapOptions::EMapOnly), ()); + TEST(!localFile.OnDisk(TMapOptions::EMap), ()); TEST(!localFile.OnDisk(TMapOptions::ECarRouting), ()); TEST(!localFile.OnDisk(TMapOptions::EMapWithCarRouting), ()); CreateTestFile(testMapFile, "map"); localFile.SyncWithDisk(); - TEST(localFile.OnDisk(TMapOptions::EMapOnly), ()); + TEST(localFile.OnDisk(TMapOptions::EMap), ()); TEST(!localFile.OnDisk(TMapOptions::ECarRouting), ()); TEST(!localFile.OnDisk(TMapOptions::EMapWithCarRouting), ()); - TEST_EQUAL(3, localFile.GetSize(TMapOptions::EMapOnly), ()); + TEST_EQUAL(3, localFile.GetSize(TMapOptions::EMap), ()); CreateTestFile(testRoutingFile, "routing"); localFile.SyncWithDisk(); - TEST(localFile.OnDisk(TMapOptions::EMapOnly), ()); + TEST(localFile.OnDisk(TMapOptions::EMap), ()); TEST(localFile.OnDisk(TMapOptions::ECarRouting), ()); TEST(localFile.OnDisk(TMapOptions::EMapWithCarRouting), ()); - TEST_EQUAL(3, localFile.GetSize(TMapOptions::EMapOnly), ()); + TEST_EQUAL(3, localFile.GetSize(TMapOptions::EMap), ()); TEST_EQUAL(7, localFile.GetSize(TMapOptions::ECarRouting), ()); TEST_EQUAL(10, localFile.GetSize(TMapOptions::EMapWithCarRouting), ()); @@ -144,6 +195,52 @@ UNIT_TEST(LocalCountryFile_DiskFiles) ("Routing file", testRoutingFile, "wasn't deleted by LocalCountryFile.")); } +UNIT_TEST(LocalCountryFile_DirectoryCleanup) +{ + Platform & platform = GetPlatform(); + string const mapsDir = platform.WritableDir(); + + CountryFile japanFile("Japan"); + CountryFile brazilFile("Brazil"); + CountryFile irelandFile("Ireland"); + + ScopedTestDir testDir1(my::JoinFoldersToPath(mapsDir, "1")); + LocalCountryFile japanLocalFile(testDir1.GetPath(), japanFile, 1 /* version */); + CreateTestFile(japanLocalFile.GetPath(TMapOptions::EMap), "Japan"); + + ScopedTestDir testDir2(my::JoinFoldersToPath(mapsDir, "2")); + LocalCountryFile brazilLocalFile(testDir2.GetPath(), brazilFile, 2 /* version */); + CreateTestFile(brazilLocalFile.GetPath(TMapOptions::EMap), "Brazil"); + + ScopedTestDir testDir3(my::JoinFoldersToPath(mapsDir, "3")); + + LocalCountryFile irelandLocalFile(testDir2.GetPath(), irelandFile, 2 /* version */); + CreateTestFile(irelandLocalFile.GetPath(TMapOptions::EMap), "Ireland"); + + vector<LocalCountryFile> localFiles; + FindAllLocalMaps(localFiles); + TEST(Contains(localFiles, japanLocalFile), (japanLocalFile)); + TEST(Contains(localFiles, brazilLocalFile), (brazilLocalFile)); + TEST(Contains(localFiles, irelandLocalFile), (irelandLocalFile)); + + CleanupMapsDirectory(); + + japanLocalFile.SyncWithDisk(); + TEST_EQUAL(TMapOptions::ENothing, japanLocalFile.GetFiles(), ()); + TEST(!Platform::IsFileExistsByFullPath(testDir1.GetPath()), ("Empty directory wasn't removed.")); + testDir1.Reset(); + + brazilLocalFile.SyncWithDisk(); + TEST_EQUAL(TMapOptions::ENothing, brazilLocalFile.GetFiles(), ()); + + irelandLocalFile.SyncWithDisk(); + TEST_EQUAL(TMapOptions::EMap, irelandLocalFile.GetFiles(), ()); + irelandLocalFile.DeleteFromDisk(); + + TEST(!Platform::IsFileExistsByFullPath(testDir3.GetPath()), ("Empty directory wasn't removed.")); + testDir3.Reset(); +} + // Creates test-dir and following files: // * test-dir/Ireland.mwm // * test-dir/Netherlands.mwm @@ -158,41 +255,39 @@ UNIT_TEST(LocalCountryFile_DirectoryLookup) Platform & platform = GetPlatform(); - string const testDir = my::JoinFoldersToPath(platform.WritableDir(), "test-dir"); - CreateTestDir(testDir); - MY_SCOPE_GUARD(removeTestDir, bind(&Platform::RmDir, testDir)); + ScopedTestDir testDir(my::JoinFoldersToPath(platform.WritableDir(), "test-dir")); string const testIrelandMapFile = - my::JoinFoldersToPath(testDir, irelandFile.GetNameWithExt(TMapOptions::EMapOnly)); + my::JoinFoldersToPath(testDir.GetPath(), irelandFile.GetNameWithExt(TMapOptions::EMap)); CreateTestFile(testIrelandMapFile, "Ireland-map"); MY_SCOPE_GUARD(removeTestIrelandMapFile, bind(&FileWriter::DeleteFileX, testIrelandMapFile)); string const testNetherlandsMapFile = - my::JoinFoldersToPath(testDir, netherlandsFile.GetNameWithExt(TMapOptions::EMapOnly)); + my::JoinFoldersToPath(testDir.GetPath(), netherlandsFile.GetNameWithExt(TMapOptions::EMap)); CreateTestFile(testNetherlandsMapFile, "Netherlands-map"); MY_SCOPE_GUARD(removeTestNetherlandsMapFile, bind(&FileWriter::DeleteFileX, testNetherlandsMapFile)); - string const testNetherlandsRoutingFile = - my::JoinFoldersToPath(testDir, netherlandsFile.GetNameWithExt(TMapOptions::ECarRouting)); + string const testNetherlandsRoutingFile = my::JoinFoldersToPath( + testDir.GetPath(), netherlandsFile.GetNameWithExt(TMapOptions::ECarRouting)); CreateTestFile(testNetherlandsRoutingFile, "Netherlands-routing"); MY_SCOPE_GUARD(removeTestNetherlandsRoutingFile, bind(&FileWriter::DeleteFileX, testNetherlandsRoutingFile)); vector<LocalCountryFile> localFiles; - FindAllLocalMapsInDirectory(testDir, 150309, localFiles); + FindAllLocalMapsInDirectory(testDir.GetPath(), 150309, localFiles); sort(localFiles.begin(), localFiles.end()); for (LocalCountryFile & localFile : localFiles) localFile.SyncWithDisk(); - LocalCountryFile expectedIrelandFile(testDir, irelandFile, 150309); - expectedIrelandFile.m_files = TMapOptions::EMapOnly; + LocalCountryFile expectedIrelandFile(testDir.GetPath(), irelandFile, 150309); + expectedIrelandFile.m_files = TMapOptions::EMap; - LocalCountryFile expectedNetherlandsFile(testDir, netherlandsFile, 150309); + LocalCountryFile expectedNetherlandsFile(testDir.GetPath(), netherlandsFile, 150309); expectedNetherlandsFile.m_files = TMapOptions::EMapWithCarRouting; vector<LocalCountryFile> expectedLocalFiles = {expectedIrelandFile, expectedNetherlandsFile}; - + sort(expectedLocalFiles.begin(), expectedLocalFiles.end()); TEST_EQUAL(expectedLocalFiles, localFiles, ()); } @@ -206,18 +301,15 @@ UNIT_TEST(LocalCountryFile_AllLocalFilesLookup) Platform & platform = GetPlatform(); - string const testDir = my::JoinFoldersToPath(platform.WritableDir(), "010101"); - CreateTestDir(testDir); - MY_SCOPE_GUARD(removeTestDir, bind(&Platform::RmDir, testDir)); + ScopedTestDir testDir(my::JoinFoldersToPath(platform.WritableDir(), "010101")); string const testItalyMapFile = - my::JoinFoldersToPath(testDir, italyFile.GetNameWithExt(TMapOptions::EMapOnly)); + my::JoinFoldersToPath(testDir.GetPath(), italyFile.GetNameWithExt(TMapOptions::EMap)); CreateTestFile(testItalyMapFile, "Italy-map"); MY_SCOPE_GUARD(remoteTestItalyMapFile, bind(&FileWriter::DeleteFileX, testItalyMapFile)); vector<LocalCountryFile> localFiles; FindAllLocalMaps(localFiles); - LOG(LINFO, (localFiles)); multiset<LocalCountryFile> localFilesSet(localFiles.begin(), localFiles.end()); LocalCountryFile expectedWorldFile(platform.WritableDir(), CountryFile(WORLD_FILE_NAME), @@ -228,6 +320,35 @@ UNIT_TEST(LocalCountryFile_AllLocalFilesLookup) CountryFile(WORLD_COASTS_FILE_NAME), 0 /* version */); TEST_EQUAL(1, localFilesSet.count(expectedWorldCoastsFile), ()); - LocalCountryFile expectedItalyFile(testDir, italyFile, 10101); + LocalCountryFile expectedItalyFile(testDir.GetPath(), italyFile, 10101); TEST_EQUAL(1, localFilesSet.count(expectedItalyFile), ()); } + +UNIT_TEST(LocalCountryFile_PreparePlaceForCountryFiles) +{ + Platform & platform = GetPlatform(); + + CountryFile italyFile("Italy"); + LocalCountryFile expectedItalyFile(platform.WritableDir(), italyFile, 0 /* version */); + shared_ptr<LocalCountryFile> italyLocalFile = + PreparePlaceForCountryFiles(italyFile, 0 /* version */); + TEST(italyLocalFile.get(), ()); + TEST_EQUAL(expectedItalyFile, *italyLocalFile, ()); + + ScopedTestDir directoryForV1(my::JoinFoldersToPath(platform.WritableDir(), "1")); + + CountryFile germanyFile("Germany"); + LocalCountryFile expectedGermanyFile(directoryForV1.GetPath(), germanyFile, 1 /* version */); + shared_ptr<LocalCountryFile> germanyLocalFile = + PreparePlaceForCountryFiles(germanyFile, 1 /* version */); + TEST(germanyLocalFile.get(), ()); + TEST_EQUAL(expectedGermanyFile, *germanyLocalFile, ()); + + CountryFile franceFile("France"); + LocalCountryFile expectedFranceFile(directoryForV1.GetPath(), franceFile, 1 /* version */); + shared_ptr<LocalCountryFile> franceLocalFile = + PreparePlaceForCountryFiles(franceFile, 1 /* version */); + TEST(franceLocalFile.get(), ()); + TEST_EQUAL(expectedFranceFile, *franceLocalFile, ()); +} +} // namespace platform |