diff --git a/storage/storage_integration_tests/storage_downloading_tests.cpp b/storage/storage_integration_tests/storage_downloading_tests.cpp index 3b8d67b84d..06e9981054 100644 --- a/storage/storage_integration_tests/storage_downloading_tests.cpp +++ b/storage/storage_integration_tests/storage_downloading_tests.cpp @@ -11,17 +11,28 @@ #include "platform/platform_tests_support/writable_dir_changer.hpp" #include "coding/file_name_utils.hpp" +#include "coding/file_writer.hpp" +#include "coding/sha1.hpp" #include "base/scope_guard.hpp" #include "base/string_utils.hpp" #include "base/thread.hpp" -#include "std/bind.hpp" -#include "std/exception.hpp" -#include "std/string.hpp" +#include +#include +#include +#include using namespace platform; using namespace storage; +using namespace std; +using namespace std::placeholders; + +// Uncomment to enable the test that requires network and downloads a mwm several times. +//#define TEST_INTEGRITY +#ifndef TEST_INTEGRITY_ITERATIONS +#define TEST_INTEGRITY_ITERATIONS 5 +#endif namespace { @@ -122,3 +133,84 @@ UNIT_CLASS_TEST(Runner, SmallMwms_InterruptDownloadResumeDownload_Test) TEST_EQUAL(NodeStatus::OnDisk, attrs.m_status, ()); } } + +#ifdef TEST_INTEGRITY +UNIT_CLASS_TEST(Runner, DownloadIntegrity_Test) +{ + WritableDirChanger writableDirChanger(kMapTestDir); + + string mapPath; + coding::SHA1::Hash mapHash; + { + SCOPE_GUARD(deleteTestFileGuard, bind(&FileWriter::DeleteFileX, ref(mapPath))); + + Storage storage(COUNTRIES_FILE); + TEST(version::IsSingleMwm(storage.GetCurrentDataVersion()), ()); + + InitStorage(storage, [](TCountryId const & countryId, TLocalAndRemoteSize const & mapSize){}); + TEST(!storage.IsDownloadInProgress(), ()); + + storage.DownloadNode(kCountryId); + TEST(storage.IsDownloadInProgress(), ()); + testing::RunEventLoop(); + + auto localFile = storage.GetLatestLocalFile(kCountryId); + mapPath = localFile->GetPath(MapOptions::Map); + mapHash = coding::SHA1::Calculate(mapPath); + } + TEST_NOT_EQUAL(mapHash, coding::SHA1::Hash(), ()); + + uint32_t constexpr kIterationsCount = TEST_INTEGRITY_ITERATIONS; + for (uint32_t i = 0; i < kIterationsCount; ++i) + { + // Downloading with interruption. + uint32_t constexpr kInterruptionsCount = 10; + for (uint32_t j = 0; j < kInterruptionsCount; ++j) + { + SCOPE_GUARD(deleteTestFileGuard, bind(&FileWriter::DeleteFileX, ref(mapPath))); + + Storage storage(COUNTRIES_FILE); + TEST(version::IsSingleMwm(storage.GetCurrentDataVersion()), ()); + + auto onProgressFn = [i, j](TCountryId const & countryId, + TLocalAndRemoteSize const & mapSize) + { + TEST_EQUAL(countryId, kCountryId, ()); + auto progress = static_cast(mapSize.first) / mapSize.second; + auto interruptionProgress = + 0.1 + 0.75 * static_cast((i + j) % kInterruptionsCount) / kInterruptionsCount; + if (progress > interruptionProgress) + testing::StopEventLoop(); + }; + + InitStorage(storage, onProgressFn); + storage.DownloadNode(kCountryId); + testing::RunEventLoop(); + TEST(storage.IsDownloadInProgress(), ()); + } + + // Continue downloading. + coding::SHA1::Hash newHash; + { + Storage storage(COUNTRIES_FILE); + TEST(version::IsSingleMwm(storage.GetCurrentDataVersion()), ()); + + InitStorage(storage, [](TCountryId const & countryId, TLocalAndRemoteSize const & mapSize){}); + TEST(storage.IsDownloadInProgress(), ()); + + NodeAttrs attrs; + storage.GetNodeAttrs(kCountryId, attrs); + TEST_EQUAL(NodeStatus::Downloading, attrs.m_status, ()); + + storage.DownloadNode(kCountryId); + TEST(storage.IsDownloadInProgress(), ()); + testing::RunEventLoop(); + + newHash = coding::SHA1::Calculate(mapPath); + } + + // Check hashes. + TEST_EQUAL(mapHash, newHash, ()); + } +} +#endif