Skip to content

Commit 3ed1708

Browse files
Return Postponed if protected cache failed to open (#1472)
This allows read-only protected cache location at start. Later when there is a need to write to the protected cache it can be opened as mutable and it is going to be an error if we have no write permission at that time. Relates-To: OLPEDGE-2858 Signed-off-by: Rustam Gamidov <ext-rustam.gamidov@here.com>
1 parent 8f4627b commit 3ed1708

File tree

4 files changed

+96
-4
lines changed

4 files changed

+96
-4
lines changed

olp-cpp-sdk-core/src/cache/DefaultCacheImpl.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,7 @@ olp::cache::DefaultCache::StorageOpenResult ToStorageOpenResult(
144144
return StorageOpenResult::ProtectedCacheCorrupted;
145145
case olp::cache::OpenResult::Repaired:
146146
case olp::cache::OpenResult::Success:
147+
case olp::cache::OpenResult::Postponed:
147148
return StorageOpenResult::Success;
148149
}
149150

olp-cpp-sdk-core/src/cache/DiskCache.cpp

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (C) 2019-2023 HERE Europe B.V.
2+
* Copyright (C) 2019-2024 HERE Europe B.V.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -241,6 +241,15 @@ OpenResult DiskCache::Open(const std::string& data_path,
241241

242242
if (status.IsInvalidArgument() && is_read_only) {
243243
// Maybe folder with cache is an empty, so trying to create db and reopen it
244+
if (!repair_if_broken) {
245+
OLP_SDK_LOG_WARNING_F(kLogTag,
246+
"Open: failed, initialize attempt postponed, "
247+
"cache_path='%s', error='%s'",
248+
versioned_data_path.c_str(),
249+
status.ToString().c_str());
250+
return OpenResult::Postponed;
251+
}
252+
244253
status = InitializeDB(settings, versioned_data_path);
245254
if (!status.ok()) {
246255
return OpenResult::Fail;

olp-cpp-sdk-core/src/cache/DiskCache.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (C) 2019-2023 HERE Europe B.V.
2+
* Copyright (C) 2019-2024 HERE Europe B.V.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -63,7 +63,9 @@ enum class OpenResult {
6363
/// broken.
6464
Repaired,
6565
/// The store was successfully opened.
66-
Success
66+
Success,
67+
/// The openning was postponed. Could be empty readonly location.
68+
Postponed
6769
};
6870

6971
struct StorageSettings {

olp-cpp-sdk-core/tests/cache/DefaultCacheImplTest.cpp

Lines changed: 81 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (C) 2020 HERE Europe B.V.
2+
* Copyright (C) 2020-2024 HERE Europe B.V.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -33,6 +33,25 @@ namespace {
3333
namespace cache = olp::cache;
3434
using CacheType = cache::DefaultCache::CacheType;
3535

36+
bool SetRights(const std::string& path, bool readonly) {
37+
#if !defined(_WIN32) || defined(__MINGW32__)
38+
mode_t mode;
39+
if (readonly) {
40+
mode = S_IRUSR | S_IRGRP | S_IROTH;
41+
} else {
42+
mode = S_IRUSR | S_IWUSR | S_IXUSR;
43+
}
44+
mode = mode | S_IRGRP | S_IROTH;
45+
return chmod(path.c_str(), mode) == 0;
46+
#else
47+
DWORD attributes = GetFileAttributes(path.c_str());
48+
attributes = readonly ? attributes | FILE_ATTRIBUTE_READONLY
49+
: attributes & ~FILE_ATTRIBUTE_READONLY;
50+
BOOL result = SetFileAttributesA(path.c_str(), attributes);
51+
return result != 0;
52+
#endif
53+
}
54+
3655
class DefaultCacheImplTest : public ::testing::Test {
3756
public:
3857
void SetUp() override {
@@ -1332,4 +1351,65 @@ TEST_F(DefaultCacheImplTest, ProtectedCacheSize) {
13321351

13331352
EXPECT_LT(std::fabs(diff_percentage), acceptable_diff_percentage);
13341353
}
1354+
1355+
struct OpenTestParameters {
1356+
olp::cache::DefaultCache::StorageOpenResult expected_result;
1357+
olp::cache::OpenOptions open_options;
1358+
boost::optional<std::string> disk_path_mutable;
1359+
boost::optional<std::string> disk_path_protected;
1360+
};
1361+
1362+
class DefaultCacheImplOpenTest
1363+
: public DefaultCacheImplTest,
1364+
public testing::WithParamInterface<OpenTestParameters> {};
1365+
1366+
TEST_P(DefaultCacheImplOpenTest, ReadOnlyDir) {
1367+
const auto setup_dir = [&](const boost::optional<std::string>& cache_path) {
1368+
if (cache_path) {
1369+
if (olp::utils::Dir::Exists(*cache_path)) {
1370+
ASSERT_TRUE(olp::utils::Dir::Remove(*cache_path));
1371+
}
1372+
ASSERT_TRUE(olp::utils::Dir::Create(*cache_path));
1373+
ASSERT_TRUE(SetRights(*cache_path, true));
1374+
}
1375+
};
1376+
1377+
const auto reset_dir = [&](const boost::optional<std::string>& cache_path) {
1378+
if (cache_path) {
1379+
ASSERT_TRUE(olp::utils::Dir::Remove(*cache_path));
1380+
}
1381+
};
1382+
1383+
const OpenTestParameters test_params = GetParam();
1384+
1385+
ASSERT_NO_FATAL_FAILURE(setup_dir(test_params.disk_path_mutable));
1386+
ASSERT_NO_FATAL_FAILURE(setup_dir(test_params.disk_path_protected));
1387+
1388+
cache::CacheSettings settings;
1389+
settings.disk_path_mutable = test_params.disk_path_mutable;
1390+
settings.disk_path_protected = test_params.disk_path_protected;
1391+
settings.openOptions = test_params.open_options;
1392+
DefaultCacheImplHelper cache(settings);
1393+
EXPECT_EQ(test_params.expected_result, cache.Open());
1394+
1395+
ASSERT_NO_FATAL_FAILURE(reset_dir(test_params.disk_path_mutable));
1396+
ASSERT_NO_FATAL_FAILURE(reset_dir(test_params.disk_path_protected));
1397+
}
1398+
1399+
std::vector<OpenTestParameters> DefaultCacheImplOpenParams() {
1400+
const std::string cache_path =
1401+
olp::utils::Dir::TempDirectory() + "/unittest_readonly";
1402+
return {{olp::cache::DefaultCache::StorageOpenResult::Success,
1403+
olp::cache::OpenOptions::Default, boost::none, cache_path},
1404+
{olp::cache::DefaultCache::StorageOpenResult::Success,
1405+
olp::cache::OpenOptions::ReadOnly, boost::none, cache_path},
1406+
{olp::cache::DefaultCache::StorageOpenResult::OpenDiskPathFailure,
1407+
olp::cache::OpenOptions::Default, cache_path, boost::none},
1408+
{olp::cache::DefaultCache::StorageOpenResult::OpenDiskPathFailure,
1409+
olp::cache::OpenOptions::ReadOnly, cache_path, boost::none}};
1410+
}
1411+
1412+
INSTANTIATE_TEST_SUITE_P(, DefaultCacheImplOpenTest,
1413+
testing::ValuesIn(DefaultCacheImplOpenParams()));
1414+
13351415
} // namespace

0 commit comments

Comments
 (0)