diff --git a/iphone/Maps/Platform/IPhoneDownload.mm b/iphone/Maps/Platform/IPhoneDownload.mm index c0f6d2d9e3..6efbab40b4 100644 --- a/iphone/Maps/Platform/IPhoneDownload.mm +++ b/iphone/Maps/Platform/IPhoneDownload.mm @@ -72,7 +72,7 @@ NSLog(@"Error opening %s file for download: %s", tmpFile.c_str(), strerror(errno)); // notify observer about error and exit if (m_finishObserver) - m_finishObserver(originalUrl, false); + m_finishObserver(originalUrl, EHttpDownloadCantCreateFile); return NO; } @@ -87,7 +87,7 @@ NSLog(@"Can't create connection for url %s", originalUrl); // notify observer about error and exit if (m_finishObserver) - m_finishObserver(originalUrl, false); + m_finishObserver(originalUrl, EHttpDownloadNoConnectionAvailable); return NO; } @@ -112,7 +112,7 @@ remove((m_requestedFileName + DOWNLOADING_FILE_EXTENSION).c_str()); // notify user if (m_finishObserver) - m_finishObserver(m_url.c_str(), false); + m_finishObserver(m_url.c_str(), statusCode == 404 ? EHttpDownloadFileNotFound : EHttpDownloadFailed); // and selfdestruct... GetDownloadManager().CancelDownload(m_url.c_str()); return; @@ -160,7 +160,7 @@ } if (m_finishObserver) - m_finishObserver(m_url.c_str(), false); + m_finishObserver(m_url.c_str(), EHttpDownloadFailed); // and selfdestruct... GetDownloadManager().CancelDownload(m_url.c_str()); } @@ -184,7 +184,7 @@ } if (m_finishObserver) - m_finishObserver(m_url.c_str(), resultForGUI); + m_finishObserver(m_url.c_str(), resultForGUI ? EHttpDownloadOk : EHttpDownloadFileIsLocked); // and selfdestruct... GetDownloadManager().CancelDownload(m_url.c_str()); } diff --git a/platform/download_manager.hpp b/platform/download_manager.hpp index d117b1941f..c2f5d4e104 100644 --- a/platform/download_manager.hpp +++ b/platform/download_manager.hpp @@ -13,9 +13,11 @@ typedef boost::function TDownloadProgres enum DownloadResult { EHttpDownloadOk, - EHttpDownloadFileNotFound, // HTTP 404 + EHttpDownloadFileNotFound, // HTTP 404 EHttpDownloadFailed, - EHttpDownloadFileIsLocked // downloaded file can't replace existing locked file + EHttpDownloadFileIsLocked, // downloaded file can't replace existing locked file + EHttpDownloadCantCreateFile, // file for downloading can't be created + EHttpDownloadNoConnectionAvailable }; typedef boost::function TDownloadFinishedFunction; diff --git a/platform/platform_tests/download_test.cpp b/platform/platform_tests/download_test.cpp index 750b902f0f..2b37092f68 100644 --- a/platform/platform_tests/download_test.cpp +++ b/platform/platform_tests/download_test.cpp @@ -22,6 +22,12 @@ #define TEST_INVALID_URL "http://very_invalid_url.kotorogo.net/okak.test" +#define TEST_ABSENT_FILE_URL "http://mapswithme.com/unit_tests/not_existing_file" +#define TEST_ABSENT_FILE_NAME "not_existing_file" + +#define TEST_LOCKED_FILE_URL "http://mapswithme.com/unit_tests/1.txt" +#define TEST_LOCKED_FILE_NAME "locked_file.tmp" + #define TEST_BIG_FILE_URL "http://mapswithme.com/unit_tests/47kb.file" int gArgc = 1; @@ -49,7 +55,7 @@ template struct DlObserver { size_t m_downloadsProcessed; - bool m_result[TMaxDownloadsNum]; + DownloadResult m_result[TMaxDownloadsNum]; string m_url[TMaxDownloadsNum]; string m_progressUrl; @@ -57,14 +63,14 @@ struct DlObserver DlObserver() : m_downloadsProcessed(0) { for (size_t i = 0; i < TMaxDownloadsNum; ++i) - m_result[i] = false; + m_result[i] = EHttpDownloadFailed; } - void OnDownloadFinished(char const * url, bool successfully) + void OnDownloadFinished(char const * url, DownloadResult result) { ASSERT_EQUAL( m_progressUrl, url, () ); m_url[m_downloadsProcessed] = url; - m_result[m_downloadsProcessed] = successfully; + m_result[m_downloadsProcessed] = result; ++m_downloadsProcessed; if (m_downloadsProcessed >= TMaxDownloadsNum) STOP_WAITING_FOR_ASYNC_DOWNLOAD; // return control to test function body @@ -93,7 +99,7 @@ UNIT_TEST(SingleDownload) boost::bind(&DlObserver::OnDownloadFinished, &observer, _1, _2), boost::bind(&DlObserver::OnDownloadProgress, &observer, _1, _2)); WAIT_FOR_ASYNC_DOWNLOAD; - TEST( observer.m_result[0], ("Do you have internet connection?") ); + TEST_EQUAL( observer.m_result[0], EHttpDownloadOk, ("Do you have internet connection?") ); TEST( gPlatform.IsFileExists(TEST_FILE_NAME1), () ); FileWriter::DeleteFile(TEST_FILE_NAME1); } @@ -117,15 +123,15 @@ UNIT_TEST(MultiDownload) boost::bind(&DlObserver::OnDownloadProgress, &observer, _1, _2)); WAIT_FOR_ASYNC_DOWNLOAD; - TEST( observer.m_result[0], ("Do you have internet connection?") ); + TEST_EQUAL( observer.m_result[0], EHttpDownloadOk, ("Do you have internet connection?") ); TEST( gPlatform.IsFileExists(TEST_FILE_NAME1), () ); FileWriter::DeleteFile(TEST_FILE_NAME1); - TEST( observer.m_result[1], ("Do you have internet connection?") ); + TEST_EQUAL( observer.m_result[1], EHttpDownloadOk, ("Do you have internet connection?") ); TEST( gPlatform.IsFileExists(TEST_FILE_NAME2), () ); FileWriter::DeleteFile(TEST_FILE_NAME2); - TEST( observer.m_result[2], ("Do you have internet connection?") ); + TEST_EQUAL( observer.m_result[2], EHttpDownloadOk, ("Do you have internet connection?") ); TEST( gPlatform.IsFileExists(TEST_FILE_NAME3), () ); FileWriter::DeleteFile(TEST_FILE_NAME3); } @@ -134,15 +140,15 @@ UNIT_TEST(InvalidUrl) { size_t const NUM = 1; DlObserver observer; - // this should be set to false on error - observer.m_result[0] = true; + // this should be set to error + observer.m_result[0] = EHttpDownloadOk; gMgr.DownloadFile(TEST_INVALID_URL, TEST_FILE_NAME1, boost::bind(&DlObserver::OnDownloadFinished, &observer, _1, _2), boost::bind(&DlObserver::OnDownloadProgress, &observer, _1, _2)); WAIT_FOR_ASYNC_DOWNLOAD; - TEST_EQUAL( observer.m_result[0], false, () ); + TEST_EQUAL( observer.m_result[0], EHttpDownloadFailed, () ); FileWriter::DeleteFile(TEST_FILE_NAME1); } @@ -182,7 +188,7 @@ UNIT_TEST(DownloadFileExists) boost::bind(&DlObserver::OnDownloadProgress, &observer, _1, _2)); WAIT_FOR_ASYNC_DOWNLOAD; - TEST_EQUAL( observer.m_result[0], true, () ); + TEST_EQUAL( observer.m_result[0], EHttpDownloadOk, () ); { string str; @@ -192,21 +198,7 @@ UNIT_TEST(DownloadFileExists) FileWriter::DeleteFile(TEST_FILE_NAME1); } -/* not actual, now dlmgr doesn't notify client on canceling -UNIT_TEST(LongDownloadCanceling) -{ - // download is canceled inside OnDownloadProgress method in observer - DlObserver<1> observer; - observer.m_result[0] = true; - gMgr.DownloadFile(TEST_BIG_FILE_URL, TEST_FILE_NAME1, observer); - WAIT_FOR_ASYNC_DOWNLOAD; - TEST_EQUAL( observer.m_result[0], false, () ); - TEST_EQUAL( gPlatform.IsFileExists(TEST_FILE_NAME1), false, ("File should be deleted if download was canceled") ); - - FileWriter::DeleteFile(TEST_FILE_NAME1); -} -*/ UNIT_TEST(DownloadResume) { size_t const NUM = 1; @@ -224,7 +216,7 @@ UNIT_TEST(DownloadResume) boost::bind(&DlObserver::OnDownloadProgress, &observer1, _1, _2), false); WAIT_FOR_ASYNC_DOWNLOAD; - TEST_EQUAL( observer1.m_result[0], true, () ); + TEST_EQUAL( observer1.m_result[0], EHttpDownloadOk, () ); DlObserver observer2; gMgr.DownloadFile(TEST_FILE_URL1, TEST_FILE_NAME2, @@ -232,7 +224,7 @@ UNIT_TEST(DownloadResume) boost::bind(&DlObserver::OnDownloadProgress, &observer2, _1, _2), false); WAIT_FOR_ASYNC_DOWNLOAD; - TEST_EQUAL( observer2.m_result[0], true, () ); + TEST_EQUAL( observer2.m_result[0], EHttpDownloadOk, () ); uint64_t size1 = 4, size2 = 5; TEST( GetPlatform().GetFileSize(TEST_FILE_NAME1, size1), ()); @@ -251,7 +243,7 @@ UNIT_TEST(DownloadResume) boost::bind(&DlObserver::OnDownloadProgress, &observer3, _1, _2), true); WAIT_FOR_ASYNC_DOWNLOAD; - TEST_EQUAL( observer3.m_result[0], true, () ); + TEST_EQUAL( observer3.m_result[0], EHttpDownloadOk, () ); TEST( GetPlatform().GetFileSize(TEST_FILE_NAME1, size1), ()); TEST_EQUAL( size1, size2, () ); @@ -266,3 +258,41 @@ UNIT_TEST(DownloadResume) FileWriter::DeleteFile(TEST_FILE_NAME1); FileWriter::DeleteFile(TEST_FILE_NAME2); } + +UNIT_TEST(DownloadAbsentFile) +{ + size_t const NUM = 1; + DlObserver observer; + + gMgr.DownloadFile(TEST_ABSENT_FILE_URL, TEST_ABSENT_FILE_NAME, + boost::bind(&DlObserver::OnDownloadFinished, &observer, _1, _2), + boost::bind(&DlObserver::OnDownloadProgress, &observer, _1, _2)); + WAIT_FOR_ASYNC_DOWNLOAD; + + TEST_EQUAL( observer.m_result[0], EHttpDownloadFileNotFound, () ); + TEST( !GetPlatform().IsFileExists(TEST_ABSENT_FILE_NAME), () ); + + FileWriter::DeleteFile(TEST_ABSENT_FILE_NAME); +} + +// only on Windows files are actually locked by system +#ifdef OMIM_OS_WINDOWS +UNIT_TEST(DownloadLockedFile) +{ + { + size_t const NUM = 1; + DlObserver observer; + + FileWriter lockedFile(TEST_LOCKED_FILE_NAME); + TEST( GetPlatform().IsFileExists(TEST_LOCKED_FILE_NAME), () ); + + gMgr.DownloadFile(TEST_LOCKED_FILE_URL, TEST_LOCKED_FILE_NAME, + boost::bind(&DlObserver::OnDownloadFinished, &observer, _1, _2), + boost::bind(&DlObserver::OnDownloadProgress, &observer, _1, _2)); + WAIT_FOR_ASYNC_DOWNLOAD; + + TEST_EQUAL( observer.m_result[0], EHttpDownloadFileIsLocked, () ); + } + FileWriter::DeleteFile(TEST_LOCKED_FILE_NAME); +} +#endif diff --git a/platform/qt_download.cpp b/platform/qt_download.cpp index 3afbd0fcb0..a34f724648 100644 --- a/platform/qt_download.cpp +++ b/platform/qt_download.cpp @@ -94,7 +94,7 @@ QtDownload::QtDownload(QtDownloadManager & manager, char const * url, m_file = 0; if (m_finish) - m_finish(url, EHttpDownloadFailed); + m_finish(url, EHttpDownloadCantCreateFile); // mark itself to delete deleteLater(); return; diff --git a/storage/storage.cpp b/storage/storage.cpp index e79ed5efb5..23bfb414e5 100644 --- a/storage/storage.cpp +++ b/storage/storage.cpp @@ -286,7 +286,7 @@ namespace storage return UrlDecode(url.substr(url.find_last_of('/') + 1, string::npos)); } - void Storage::OnMapDownloadFinished(char const * url, bool successfully) + void Storage::OnMapDownloadFinished(char const * url, DownloadResult result) { if (m_queue.empty()) { @@ -294,7 +294,7 @@ namespace storage return; } - if (!successfully) + if (result != EHttpDownloadOk) { // remove failed country from the queue TIndex failedIndex = m_queue.front(); @@ -340,9 +340,9 @@ namespace storage TDownloadProgressFunction(), false); } - void Storage::OnUpdateDownloadFinished(char const * url, bool successfully) + void Storage::OnUpdateDownloadFinished(char const * url, DownloadResult result) { - if (!successfully) + if (result != EHttpDownloadOk) { LOG(LWARNING, ("Update check failed for url:", url)); if (m_observerUpdateCheck) diff --git a/storage/storage.hpp b/storage/storage.hpp index 4b12366a32..296a670bd6 100644 --- a/storage/storage.hpp +++ b/storage/storage.hpp @@ -96,9 +96,9 @@ namespace storage /// @name Called from DownloadManager //@{ - void OnMapDownloadFinished(char const * url, bool successfully); + void OnMapDownloadFinished(char const * url, DownloadResult result); void OnMapDownloadProgress(char const * url, TDownloadProgress progress); - void OnUpdateDownloadFinished(char const * url, bool successfully); + void OnUpdateDownloadFinished(char const * url, DownloadResult result); //@} /// @name Current impl supports only one observer