1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
|
#include "testing/testing.hpp"
#include "storage/storage_integration_tests/test_defines.hpp"
#include "map/framework.hpp"
#include "platform/http_request.hpp"
#include "platform/local_country_file_utils.hpp"
#include "platform/platform.hpp"
#include "platform/platform_tests_support/scoped_dir.hpp"
#include "platform/platform_tests_support/writable_dir_changer.hpp"
#include "coding/file_name_utils.hpp"
#include "storage/storage.hpp"
#include "base/assert.hpp"
#include "std/condition_variable.hpp"
#include "std/mutex.hpp"
#include "std/set.hpp"
#include "std/unique_ptr.hpp"
using namespace platform;
using namespace storage;
namespace
{
TCountryId const kGroupCountryId = "New Zealand";
TCountriesSet const kLeafCountriesIds = {"Tokelau",
"New Zealand North_Auckland",
"New Zealand North_Wellington",
"New Zealand South_Canterbury",
"New Zealand South_Southland"};
string GetMwmFilePath(string const & version, TCountryId const & countryId)
{
return my::JoinFoldersToPath({GetPlatform().WritableDir(), version},
countryId + DATA_FILE_EXTENSION);
}
string GetMwmDownloadingFilePath(string const & version, TCountryId const & countryId)
{
return my::JoinFoldersToPath({GetPlatform().WritableDir(), version},
countryId + DATA_FILE_EXTENSION READY_FILE_EXTENSION DOWNLOADING_FILE_EXTENSION);
}
string GetMwmResumeFilePath(string const & version, TCountryId const & countryId)
{
return my::JoinFoldersToPath({GetPlatform().WritableDir(), version},
countryId + DATA_FILE_EXTENSION READY_FILE_EXTENSION RESUME_FILE_EXTENSION);
}
void DownloadGroup(Storage & storage, bool oneByOne)
{
Platform & platform = GetPlatform();
string const version = strings::to_string(storage.GetCurrentDataVersion());
// Get children nodes for the group node.
TCountriesVec children;
// All nodes in subtree (including the root) for the group node.
storage.GetChildren(kGroupCountryId, children);
TCountriesSet subTree;
storage.ForEachInSubtree(kGroupCountryId, [&subTree](TCountryId const & descendantId, bool /* groupNode */)
{
subTree.insert(descendantId);
});
TCountriesSet changed;
auto onChangeCountryFn = [&](TCountryId const & countryId)
{
TEST(subTree.find(countryId) != subTree.end(), (countryId));
changed.insert(countryId);
if (!storage.IsDownloadInProgress())
{
// Stop waiting when all chilren will be downloaded.
testing::StopEventLoop();
}
};
TCountriesSet downloadedChecker;
auto onProgressFn = [&](TCountryId const & countryId, TLocalAndRemoteSize const & mapSize)
{
TEST(subTree.find(countryId) != subTree.end(), ());
if (mapSize.first == mapSize.second)
{
auto const res = downloadedChecker.insert(countryId);
TEST_EQUAL(res.second, true, ()); // Every child is downloaded only once.
}
};
int const subsrcibtionId = storage.Subscribe(onChangeCountryFn, onProgressFn);
// Check group node is not downloaded
TCountriesVec downloaded, available;
storage.GetChildrenInGroups(storage.GetRootId(), downloaded, available);
TEST(downloaded.empty(), ());
// Check children nodes are not downloaded
storage.GetChildrenInGroups(kGroupCountryId, downloaded, available);
TEST(downloaded.empty(), ());
// Check status for the all children nodes is set to ENotDownloaded.
TMwmSize totalGroupSize = 0;
for (auto const & countryId : children)
{
TEST_EQUAL(Status::ENotDownloaded, storage.CountryStatusEx(countryId), ());
NodeAttrs attrs;
storage.GetNodeAttrs(countryId, attrs);
TEST_EQUAL(NodeStatus::NotDownloaded, attrs.m_status, ());
TEST_GREATER(attrs.m_mwmSize, 0, ());
totalGroupSize += attrs.m_mwmSize;
}
// Check status for the group node is set to ENotDownloaded.
NodeAttrs attrs;
storage.GetNodeAttrs(kGroupCountryId, attrs);
TEST_EQUAL(NodeStatus::NotDownloaded, attrs.m_status, ());
TEST_EQUAL(attrs.m_mwmSize, totalGroupSize, ());
attrs = NodeAttrs();
// Check there is no mwm or any other files for the children nodes.
for (auto const & countryId : children)
{
string const mwmFullPath = GetMwmFilePath(version, countryId);
string const downloadingFullPath = GetMwmDownloadingFilePath(version, countryId);
string const resumeFullPath = GetMwmResumeFilePath(version, countryId);
TEST(!platform.IsFileExistsByFullPath(mwmFullPath), ());
TEST(!platform.IsFileExistsByFullPath(downloadingFullPath), ());
TEST(!platform.IsFileExistsByFullPath(resumeFullPath), ());
}
// Download the group.
if (oneByOne)
{
for (auto const & countryId : children)
storage.DownloadNode(countryId);
}
else
{
storage.DownloadNode(kGroupCountryId);
}
// Wait for downloading of all children.
testing::RunEventLoop();
// Check if all nodes in the subtree have been downloaded and changed.
TEST_EQUAL(changed, subTree, ());
TEST_EQUAL(downloadedChecker, subTree, ());
// Check status for the group node is set to EOnDisk.
storage.GetNodeAttrs(kGroupCountryId, attrs);
TEST_EQUAL(NodeStatus::OnDisk, attrs.m_status, ());
// Check status for the all children nodes is set to EOnDisk.
for (auto const & countryId : children)
{
TEST_EQUAL(Status::EOnDisk, storage.CountryStatusEx(countryId), ());
NodeAttrs attrs;
storage.GetNodeAttrs(countryId, attrs);
TEST_EQUAL(NodeStatus::OnDisk, attrs.m_status, ());
}
// Check there is only mwm files are present and no any other for the children nodes.
for (auto const & countryId : children)
{
string const mwmFullPath = GetMwmFilePath(version, countryId);
string const downloadingFullPath = GetMwmDownloadingFilePath(version, countryId);
string const resumeFullPath = GetMwmResumeFilePath(version, countryId);
TEST(platform.IsFileExistsByFullPath(mwmFullPath), ());
TEST(!platform.IsFileExistsByFullPath(downloadingFullPath), ());
TEST(!platform.IsFileExistsByFullPath(resumeFullPath), ());
}
// Check group is downloaded.
storage.GetChildrenInGroups(storage.GetRootId(), downloaded, available);
TEST_EQUAL(downloaded, TCountriesVec({kGroupCountryId}), ());
// Check all group children are downloaded.
storage.GetChildrenInGroups(kGroupCountryId, downloaded, available);
TEST_EQUAL(TCountriesSet(children.begin(), children.end()),
TCountriesSet(downloaded.begin(), downloaded.end()), ());
storage.Unsubscribe(subsrcibtionId);
}
void DeleteGroup(Storage & storage, bool oneByOne)
{
Platform & platform = GetPlatform();
string const version = strings::to_string(storage.GetCurrentDataVersion());
// Get children nodes for the group node.
TCountriesVec v;
storage.GetChildren(kGroupCountryId, v);
TCountriesSet const children(v.begin(), v.end());
v.clear();
// Check group node is downloaded.
TCountriesVec downloaded, available;
storage.GetChildrenInGroups(storage.GetRootId(), downloaded, available);
TEST_EQUAL(downloaded, TCountriesVec({kGroupCountryId}), ());
// Check children nodes are downloaded.
storage.GetChildrenInGroups(kGroupCountryId, downloaded, available);
TEST_EQUAL(children, TCountriesSet(downloaded.begin(), downloaded.end()), ());
// Check there are mwm files for the children nodes.
for (auto const & countryId : children)
{
string const mwmFullPath = GetMwmFilePath(version, countryId);
TEST(platform.IsFileExistsByFullPath(mwmFullPath), ());
}
// Delete the group
if (oneByOne)
{
for (auto const & countryId : children)
storage.DeleteNode(countryId);
}
else
{
storage.DeleteNode(kGroupCountryId);
}
// Check state for the group node is set to NotDownloaded and NoError.
NodeAttrs attrs;
storage.GetNodeAttrs(kGroupCountryId, attrs);
TEST_EQUAL(NodeStatus::NotDownloaded, attrs.m_status, ());
// Check state for the all children nodes is set to NotDownloaded and NoError.
for (auto const & countryId : children)
{
TEST_EQUAL(Status::ENotDownloaded, storage.CountryStatusEx(countryId), ());
NodeAttrs attrs;
storage.GetNodeAttrs(countryId, attrs);
TEST_EQUAL(NodeStatus::NotDownloaded, attrs.m_status, ());
}
// Check there are no mwm files for the children nodes.
for (auto const & countryId : children)
{
string const mwmFullPath = GetMwmFilePath(version, countryId);
TEST(!platform.IsFileExistsByFullPath(mwmFullPath), ());
}
// Check group is not downloaded.
storage.GetChildrenInGroups(storage.GetRootId(), downloaded, available);
TEST(downloaded.empty(), ());
// Check all children nodes are not downloaded.
storage.GetChildrenInGroups(kGroupCountryId, downloaded, available);
TEST(downloaded.empty(), ());
}
void TestDownloadDelete(bool downloadOneByOne, bool deleteOneByOne)
{
WritableDirChanger writableDirChanger(kMapTestDir);
Storage storage(COUNTRIES_FILE);
TEST(version::IsSingleMwm(storage.GetCurrentDataVersion()), ());
string const version = strings::to_string(storage.GetCurrentDataVersion());
auto onUpdatedFn = [&](TCountryId const &, storage::TLocalFilePtr const localCountryFile)
{
TCountryId const countryId = localCountryFile->GetCountryName();
TEST(kLeafCountriesIds.find(countryId) != kLeafCountriesIds.end(), ());
};
storage.Init(onUpdatedFn, [](TCountryId const &, storage::TLocalFilePtr const){return false;});
storage.RegisterAllLocalMaps();
storage.SetDownloadingUrlsForTesting({kTestWebServer});
tests_support::ScopedDir cleanupVersionDir(version);
// Check children for the kGroupCountryId
TCountriesVec children;
storage.GetChildren(kGroupCountryId, children);
TEST_EQUAL(TCountriesSet(children.begin(), children.end()), kLeafCountriesIds, ());
DownloadGroup(storage, downloadOneByOne);
DeleteGroup(storage, deleteOneByOne);
}
} // namespace
UNIT_TEST(SmallMwms_GroupDownloadDelete_Test1)
{
TestDownloadDelete(false, false);
}
UNIT_TEST(SmallMwms_GroupDownloadDelete_Test2)
{
TestDownloadDelete(false, true);
}
UNIT_TEST(SmallMwms_GroupDownloadDelete_Test3)
{
TestDownloadDelete(true, false);
}
UNIT_TEST(SmallMwms_GroupDownloadDelete_Test4)
{
TestDownloadDelete(true, true);
}
|