1
1
#include < mbgl/test/stub_file_source.hpp>
2
2
#include < mbgl/test/fake_file_source.hpp>
3
+ #include < mbgl/test/fixture_log_observer.hpp>
4
+ #include < mbgl/test/sqlite3_test_fs.hpp>
3
5
4
6
#include < mbgl/storage/offline.hpp>
5
7
#include < mbgl/storage/offline_database.hpp>
10
12
#include < mbgl/util/compression.hpp>
11
13
#include < mbgl/util/string.hpp>
12
14
15
+ #include < sqlite3.hpp>
13
16
#include < gtest/gtest.h>
14
17
#include < iostream>
15
18
16
19
using namespace mbgl ;
17
20
using namespace std ::literals::string_literals;
21
+ using mapbox::sqlite::ResultCode;
22
+
23
+ static constexpr const char * filename = " test/fixtures/offline_download/offline.db" ;
24
+ #ifndef __QT__ // Qt doesn't expose the ability to register virtual file system handlers.
25
+ static constexpr const char * filename_test_fs = " file:test/fixtures/offline_download/offline.db?vfs=test_fs" ;
26
+ #endif
27
+
28
+ static void deleteDatabaseFiles () {
29
+ // Delete leftover journaling files as well.
30
+ util::deleteFile (filename);
31
+ util::deleteFile (filename + " -wal" s);
32
+ util::deleteFile (filename + " -journal" s);
33
+ }
34
+
35
+ static FixtureLog::Message warning (ResultCode code, const char * message) {
36
+ return { EventSeverity::Warning, Event::Database, static_cast <int64_t >(code), message };
37
+ }
18
38
19
39
class MockObserver : public OfflineRegionObserver {
20
40
public:
@@ -37,9 +57,12 @@ class MockObserver : public OfflineRegionObserver {
37
57
38
58
class OfflineTest {
39
59
public:
60
+ OfflineTest (const std::string& path = " :memory:" ) : db(path) {
61
+ }
62
+
40
63
util::RunLoop loop;
41
64
StubFileSource fileSource;
42
- OfflineDatabase db { " :memory: " } ;
65
+ OfflineDatabase db;
43
66
std::size_t size = 0 ;
44
67
45
68
optional<OfflineRegion> createRegion () {
@@ -636,3 +659,56 @@ TEST(OfflineDownload, Deactivate) {
636
659
637
660
test.loop .run ();
638
661
}
662
+
663
+ #ifndef __QT__ // Qt doesn't expose the ability to register virtual file system handlers.
664
+ TEST (OfflineDownload, DiskFull) {
665
+ FixtureLog log ;
666
+ deleteDatabaseFiles ();
667
+ test::SQLite3TestFS fs;
668
+
669
+ OfflineTest test{ filename_test_fs };
670
+ EXPECT_EQ (0u , log .uncheckedCount ());
671
+
672
+ auto region = test.createRegion ();
673
+ ASSERT_TRUE (region);
674
+ EXPECT_EQ (0u , log .uncheckedCount ());
675
+
676
+ // Simulate a full disk.
677
+ fs.setWriteLimit (8192 );
678
+
679
+ OfflineDownload download (
680
+ region->getID (),
681
+ OfflineTilePyramidRegionDefinition (" http://127.0.0.1:3000/style.json" , LatLngBounds::world (), 0.0 , 0.0 , 1.0 ),
682
+ test.db , test.fileSource );
683
+
684
+ bool hasRequestedStyle = false ;
685
+
686
+ test.fileSource .styleResponse = [&] (const Resource& resource) {
687
+ EXPECT_EQ (" http://127.0.0.1:3000/style.json" , resource.url );
688
+ hasRequestedStyle = true ;
689
+ return test.response (" empty.style.json" );
690
+ };
691
+
692
+ auto observer = std::make_unique<MockObserver>();
693
+
694
+ observer->statusChangedFn = [&] (OfflineRegionStatus status) {
695
+ EXPECT_EQ (OfflineRegionDownloadState::Active, status.downloadState );
696
+ EXPECT_EQ (0u , status.completedResourceCount );
697
+ EXPECT_EQ (0u , status.completedResourceSize );
698
+ EXPECT_EQ (hasRequestedStyle, status.requiredResourceCountIsPrecise );
699
+ EXPECT_FALSE (status.complete ());
700
+
701
+ if (hasRequestedStyle) {
702
+ EXPECT_EQ (1u , log .count (warning (ResultCode::Full, " Can't write region resources: database or disk is full" )));
703
+ EXPECT_EQ (0u , log .uncheckedCount ());
704
+ test.loop .stop ();
705
+ }
706
+ };
707
+
708
+ download.setObserver (std::move (observer));
709
+ download.setState (OfflineRegionDownloadState::Active);
710
+
711
+ test.loop .run ();
712
+ EXPECT_EQ (0u , log .uncheckedCount ());
713
+ }
714
+ #endif // __QT__
0 commit comments