Repo created
This commit is contained in:
parent
4af19165ec
commit
68073add76
12458 changed files with 12350765 additions and 2 deletions
23
libs/platform/platform_tests_support/CMakeLists.txt
Normal file
23
libs/platform/platform_tests_support/CMakeLists.txt
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
project(platform_tests_support)
|
||||
|
||||
set(SRC
|
||||
async_gui_thread.hpp
|
||||
helpers.hpp
|
||||
scoped_dir.cpp
|
||||
scoped_dir.hpp
|
||||
scoped_file.cpp
|
||||
scoped_file.hpp
|
||||
scoped_mwm.cpp
|
||||
scoped_mwm.hpp
|
||||
test_socket.cpp
|
||||
test_socket.hpp
|
||||
writable_dir_changer.cpp
|
||||
writable_dir_changer.hpp
|
||||
)
|
||||
|
||||
omim_add_library(${PROJECT_NAME} ${SRC})
|
||||
|
||||
target_link_libraries(${PROJECT_NAME}
|
||||
platform
|
||||
indexer # feature::DataHeader::Save
|
||||
)
|
||||
29
libs/platform/platform_tests_support/async_gui_thread.hpp
Normal file
29
libs/platform/platform_tests_support/async_gui_thread.hpp
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
#pragma once
|
||||
|
||||
#include "platform/gui_thread.hpp"
|
||||
#include "platform/platform.hpp"
|
||||
|
||||
#include "base/thread_pool_delayed.hpp"
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace platform
|
||||
{
|
||||
namespace tests_support
|
||||
{
|
||||
class AsyncGuiThread
|
||||
{
|
||||
public:
|
||||
AsyncGuiThread()
|
||||
{
|
||||
GetPlatform().SetGuiThread(
|
||||
std::make_unique<base::DelayedThreadPool>(1 /* threadsCount */, base::DelayedThreadPool::Exit::ExecPending));
|
||||
}
|
||||
|
||||
virtual ~AsyncGuiThread() { GetPlatform().SetGuiThread(std::make_unique<platform::GuiThread>()); }
|
||||
|
||||
private:
|
||||
Platform::ThreadRunner m_runner;
|
||||
};
|
||||
} // namespace tests_support
|
||||
} // namespace platform
|
||||
21
libs/platform/platform_tests_support/helpers.hpp
Normal file
21
libs/platform/platform_tests_support/helpers.hpp
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
#pragma once
|
||||
|
||||
#if defined(OMIM_OS_MAC) || defined(OMIM_OS_LINUX)
|
||||
#include <sys/resource.h>
|
||||
#endif
|
||||
|
||||
namespace platform
|
||||
{
|
||||
namespace tests_support
|
||||
{
|
||||
inline void ChangeMaxNumberOfOpenFiles(size_t n)
|
||||
{
|
||||
#if defined(OMIM_OS_MAC) || defined(OMIM_OS_LINUX)
|
||||
struct rlimit rlp;
|
||||
getrlimit(RLIMIT_NOFILE, &rlp);
|
||||
rlp.rlim_cur = n;
|
||||
setrlimit(RLIMIT_NOFILE, &rlp);
|
||||
#endif
|
||||
}
|
||||
} // namespace tests_support
|
||||
} // namespace platform
|
||||
61
libs/platform/platform_tests_support/scoped_dir.cpp
Normal file
61
libs/platform/platform_tests_support/scoped_dir.cpp
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
#include "platform/platform_tests_support/scoped_dir.hpp"
|
||||
|
||||
#include "testing/testing.hpp"
|
||||
|
||||
#include "base/file_name_utils.hpp"
|
||||
#include "base/logging.hpp"
|
||||
|
||||
#include <sstream>
|
||||
|
||||
namespace platform
|
||||
{
|
||||
namespace tests_support
|
||||
{
|
||||
ScopedDir::ScopedDir(std::string const & relativePath)
|
||||
: m_fullPath(base::JoinPath(GetPlatform().WritableDir(), relativePath))
|
||||
, m_relativePath(relativePath)
|
||||
, m_reset(false)
|
||||
{
|
||||
Platform::EError ret = Platform::MkDir(GetFullPath());
|
||||
switch (ret)
|
||||
{
|
||||
case Platform::ERR_OK: break;
|
||||
case Platform::ERR_FILE_ALREADY_EXISTS:
|
||||
Platform::EFileType type;
|
||||
TEST_EQUAL(Platform::ERR_OK, Platform::GetFileType(GetFullPath(), type), ());
|
||||
TEST_EQUAL(Platform::EFileType::Directory, type, ());
|
||||
break;
|
||||
default: TEST(false, ("Can't create directory:", GetFullPath(), "error:", ret)); break;
|
||||
}
|
||||
}
|
||||
|
||||
ScopedDir::ScopedDir(ScopedDir const & parent, std::string const & name)
|
||||
: ScopedDir(base::JoinPath(parent.GetRelativePath(), name))
|
||||
{}
|
||||
|
||||
ScopedDir::~ScopedDir()
|
||||
{
|
||||
if (m_reset)
|
||||
return;
|
||||
|
||||
std::string const fullPath = GetFullPath();
|
||||
Platform::EError ret = Platform::RmDir(fullPath);
|
||||
switch (ret)
|
||||
{
|
||||
case Platform::ERR_OK: break;
|
||||
case Platform::ERR_FILE_DOES_NOT_EXIST:
|
||||
LOG(LERROR, (fullPath, "was deleted before destruction of ScopedDir."));
|
||||
break;
|
||||
case Platform::ERR_DIRECTORY_NOT_EMPTY: LOG(LERROR, ("There are files in", fullPath)); break;
|
||||
default: LOG(LERROR, ("Platform::RmDir() error for", fullPath, ":", ret)); break;
|
||||
}
|
||||
}
|
||||
|
||||
std::string DebugPrint(ScopedDir const & dir)
|
||||
{
|
||||
std::ostringstream os;
|
||||
os << "ScopedDir [" << dir.GetFullPath() << "]";
|
||||
return os.str();
|
||||
}
|
||||
} // namespace tests_support
|
||||
} // namespace platform
|
||||
43
libs/platform/platform_tests_support/scoped_dir.hpp
Normal file
43
libs/platform/platform_tests_support/scoped_dir.hpp
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
#pragma once
|
||||
|
||||
#include "platform/platform.hpp"
|
||||
|
||||
#include "base/macros.hpp"
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace platform
|
||||
{
|
||||
namespace tests_support
|
||||
{
|
||||
// Scoped test directory in a writable dir.
|
||||
class ScopedDir
|
||||
{
|
||||
public:
|
||||
/// Creates test dir in a writable directory.
|
||||
/// @param path Path for a testing directory, should be relative to writable-dir.
|
||||
ScopedDir(std::string const & relativePath);
|
||||
|
||||
ScopedDir(ScopedDir const & parent, std::string const & name);
|
||||
|
||||
~ScopedDir();
|
||||
|
||||
void Reset() { m_reset = true; }
|
||||
|
||||
std::string const & GetFullPath() const { return m_fullPath; }
|
||||
|
||||
std::string const & GetRelativePath() const { return m_relativePath; }
|
||||
|
||||
bool Exists() const { return GetPlatform().IsFileExistsByFullPath(GetFullPath()); }
|
||||
|
||||
private:
|
||||
std::string const m_fullPath;
|
||||
std::string const m_relativePath;
|
||||
bool m_reset;
|
||||
|
||||
DISALLOW_COPY_AND_MOVE(ScopedDir);
|
||||
};
|
||||
|
||||
std::string DebugPrint(ScopedDir const & dir);
|
||||
} // namespace tests_support
|
||||
} // namespace platform
|
||||
73
libs/platform/platform_tests_support/scoped_file.cpp
Normal file
73
libs/platform/platform_tests_support/scoped_file.cpp
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
#include "platform/platform_tests_support/scoped_file.hpp"
|
||||
|
||||
#include "testing/testing.hpp"
|
||||
|
||||
#include "platform/country_file.hpp"
|
||||
#include "platform/mwm_version.hpp"
|
||||
#include "platform/platform_tests_support/scoped_dir.hpp"
|
||||
|
||||
#include "coding/file_writer.hpp"
|
||||
#include "coding/internal/file_data.hpp"
|
||||
#include "coding/writer.hpp"
|
||||
|
||||
#include "base/assert.hpp"
|
||||
#include "base/file_name_utils.hpp"
|
||||
#include "base/logging.hpp"
|
||||
|
||||
#include <sstream>
|
||||
|
||||
namespace platform
|
||||
{
|
||||
namespace tests_support
|
||||
{
|
||||
ScopedFile::ScopedFile(std::string const & relativePath, Mode mode) : ScopedFile(relativePath, {} /* contents */, mode)
|
||||
{}
|
||||
|
||||
ScopedFile::ScopedFile(std::string const & relativePath, std::string const & contents)
|
||||
: ScopedFile(relativePath, contents, Mode::Create)
|
||||
{}
|
||||
|
||||
ScopedFile::ScopedFile(ScopedDir const & dir, CountryFile const & countryFile, MapFileType type)
|
||||
: ScopedFile(base::JoinPath(dir.GetRelativePath(), countryFile.GetFileName(type)), Mode::Create)
|
||||
{}
|
||||
|
||||
ScopedFile::ScopedFile(std::string const & relativePath, std::string const & contents, Mode mode)
|
||||
: m_fullPath(base::JoinPath(GetPlatform().WritableDir(), relativePath))
|
||||
{
|
||||
if (mode == Mode::DoNotCreate)
|
||||
return;
|
||||
|
||||
try
|
||||
{
|
||||
FileWriter writer(GetFullPath());
|
||||
writer.Write(contents.data(), contents.size());
|
||||
}
|
||||
catch (Writer::Exception const & e)
|
||||
{
|
||||
LOG(LERROR, ("Can't create test file:", e.what()));
|
||||
}
|
||||
|
||||
CHECK(Exists(), ("Can't create test file", GetFullPath()));
|
||||
}
|
||||
|
||||
ScopedFile::~ScopedFile()
|
||||
{
|
||||
if (m_reset)
|
||||
return;
|
||||
if (!Exists())
|
||||
{
|
||||
LOG(LERROR, ("File", GetFullPath(), "did not exist or was deleted before dtor of ScopedFile."));
|
||||
return;
|
||||
}
|
||||
if (!base::DeleteFileX(GetFullPath()))
|
||||
LOG(LERROR, ("Can't remove test file:", GetFullPath()));
|
||||
}
|
||||
|
||||
std::string DebugPrint(ScopedFile const & file)
|
||||
{
|
||||
std::ostringstream os;
|
||||
os << "ScopedFile [" << file.GetFullPath() << "]";
|
||||
return os.str();
|
||||
}
|
||||
} // namespace tests_support
|
||||
} // namespace platform
|
||||
60
libs/platform/platform_tests_support/scoped_file.hpp
Normal file
60
libs/platform/platform_tests_support/scoped_file.hpp
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
#pragma once
|
||||
|
||||
#include "platform/country_defines.hpp"
|
||||
#include "platform/platform.hpp"
|
||||
|
||||
#include "base/macros.hpp"
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace platform
|
||||
{
|
||||
class CountryFile;
|
||||
|
||||
namespace tests_support
|
||||
{
|
||||
class ScopedDir;
|
||||
|
||||
class ScopedFile
|
||||
{
|
||||
public:
|
||||
enum class Mode : uint32_t
|
||||
{
|
||||
// Create or overwrite the file and remove it at scope exit.
|
||||
Create,
|
||||
|
||||
// Remove the file at scope exit. The caller must
|
||||
// ensure that the file has been created by that time.
|
||||
DoNotCreate
|
||||
};
|
||||
|
||||
// Creates a scoped file in the specified mode.
|
||||
ScopedFile(std::string const & relativePath, Mode mode);
|
||||
|
||||
// Creates a scoped file in Mode::Create and writes |contents| to it.
|
||||
ScopedFile(std::string const & relativePath, std::string const & contents);
|
||||
|
||||
// Creates a scoped file in Mode::Create using the path inferred from |countryFile|
|
||||
// and |mapOptions|.
|
||||
ScopedFile(ScopedDir const & dir, CountryFile const & countryFile, MapFileType type);
|
||||
|
||||
~ScopedFile();
|
||||
|
||||
std::string const & GetFullPath() const { return m_fullPath; }
|
||||
|
||||
void Reset() { m_reset = true; }
|
||||
|
||||
bool Exists() const { return GetPlatform().IsFileExistsByFullPath(GetFullPath()); }
|
||||
|
||||
private:
|
||||
ScopedFile(std::string const & relativePath, std::string const & contents, Mode mode);
|
||||
|
||||
std::string const m_fullPath;
|
||||
bool m_reset = false;
|
||||
|
||||
DISALLOW_COPY_AND_MOVE(ScopedFile);
|
||||
};
|
||||
|
||||
std::string DebugPrint(ScopedFile const & file);
|
||||
} // namespace tests_support
|
||||
} // namespace platform
|
||||
40
libs/platform/platform_tests_support/scoped_mwm.cpp
Normal file
40
libs/platform/platform_tests_support/scoped_mwm.cpp
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
#include "scoped_mwm.hpp"
|
||||
|
||||
#include "defines.hpp"
|
||||
|
||||
#include "indexer/data_header.hpp"
|
||||
#include "indexer/feature_impl.hpp"
|
||||
|
||||
#include "platform/mwm_version.hpp"
|
||||
|
||||
#include "coding/file_writer.hpp"
|
||||
#include "coding/files_container.hpp"
|
||||
|
||||
#include "base/timer.hpp"
|
||||
|
||||
namespace platform
|
||||
{
|
||||
namespace tests_support
|
||||
{
|
||||
ScopedMwm::ScopedMwm(std::string const & relativePath) : m_file(relativePath, ScopedFile::Mode::Create)
|
||||
{
|
||||
FilesContainerW container(m_file.GetFullPath());
|
||||
|
||||
// Each writer must be in it's own scope to avoid conflicts on the final write.
|
||||
{
|
||||
auto w = container.GetWriter(VERSION_FILE_TAG);
|
||||
version::WriteVersion(*w, base::SecondsSinceEpoch());
|
||||
}
|
||||
|
||||
using namespace feature;
|
||||
DataHeader header;
|
||||
header.SetScales(feature::g_arrCountryScales);
|
||||
header.SetType(DataHeader::MapType::Country);
|
||||
|
||||
{
|
||||
auto w = container.GetWriter(HEADER_FILE_TAG);
|
||||
header.Save(*w);
|
||||
}
|
||||
}
|
||||
} // namespace tests_support
|
||||
} // namespace platform
|
||||
28
libs/platform/platform_tests_support/scoped_mwm.hpp
Normal file
28
libs/platform/platform_tests_support/scoped_mwm.hpp
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
#pragma once
|
||||
|
||||
#include "platform/platform_tests_support/scoped_file.hpp"
|
||||
|
||||
#include "base/macros.hpp"
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace platform
|
||||
{
|
||||
namespace tests_support
|
||||
{
|
||||
class ScopedFile;
|
||||
|
||||
class ScopedMwm
|
||||
{
|
||||
public:
|
||||
explicit ScopedMwm(std::string const & relativePath);
|
||||
|
||||
std::string const & GetFullPath() const { return m_file.GetFullPath(); }
|
||||
|
||||
private:
|
||||
ScopedFile m_file;
|
||||
|
||||
DISALLOW_COPY_AND_MOVE(ScopedMwm);
|
||||
};
|
||||
} // namespace tests_support
|
||||
} // namespace platform
|
||||
75
libs/platform/platform_tests_support/test_socket.cpp
Normal file
75
libs/platform/platform_tests_support/test_socket.cpp
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
#include "test_socket.hpp"
|
||||
|
||||
#include "base/assert.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
#include <chrono>
|
||||
|
||||
namespace platform
|
||||
{
|
||||
namespace tests_support
|
||||
{
|
||||
TestSocket::~TestSocket()
|
||||
{
|
||||
m_isConnected = false;
|
||||
}
|
||||
|
||||
bool TestSocket::Open(std::string const & host, uint16_t port)
|
||||
{
|
||||
if (m_isConnected)
|
||||
return false;
|
||||
|
||||
m_isConnected = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
void TestSocket::Close()
|
||||
{
|
||||
m_isConnected = false;
|
||||
}
|
||||
|
||||
bool TestSocket::Read(uint8_t * data, uint32_t count)
|
||||
{
|
||||
if (!m_isConnected)
|
||||
return false;
|
||||
|
||||
std::unique_lock<std::mutex> lock(m_inputMutex);
|
||||
|
||||
m_inputCondition.wait_for(lock, std::chrono::milliseconds(m_timeoutMs), [this]() { return !m_input.empty(); });
|
||||
if (m_input.size() < count)
|
||||
return false;
|
||||
|
||||
std::copy(m_input.begin(), m_input.end(), data);
|
||||
m_input.erase(m_input.begin(), m_input.begin() + count);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TestSocket::Write(uint8_t const * data, uint32_t count)
|
||||
{
|
||||
if (!m_isConnected)
|
||||
return false;
|
||||
|
||||
{
|
||||
std::lock_guard lg(m_outputMutex);
|
||||
m_output.insert(m_output.end(), data, data + count);
|
||||
}
|
||||
m_outputCondition.notify_one();
|
||||
return true;
|
||||
}
|
||||
|
||||
void TestSocket::SetTimeout(uint32_t milliseconds)
|
||||
{
|
||||
m_timeoutMs = milliseconds;
|
||||
}
|
||||
size_t TestSocket::ReadServer(std::vector<uint8_t> & destination)
|
||||
{
|
||||
std::unique_lock lock(m_outputMutex);
|
||||
m_outputCondition.wait_for(lock, std::chrono::milliseconds(m_timeoutMs), [this]() { return !m_output.empty(); });
|
||||
|
||||
size_t const outputSize = m_output.size();
|
||||
destination.insert(destination.end(), m_output.begin(), m_output.end());
|
||||
m_output.clear();
|
||||
return outputSize;
|
||||
}
|
||||
} // namespace tests_support
|
||||
} // namespace platform
|
||||
54
libs/platform/platform_tests_support/test_socket.hpp
Normal file
54
libs/platform/platform_tests_support/test_socket.hpp
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
#pragma once
|
||||
|
||||
#include "platform/socket.hpp"
|
||||
|
||||
#include <atomic>
|
||||
#include <condition_variable>
|
||||
#include <cstdint>
|
||||
#include <deque>
|
||||
#include <iterator>
|
||||
#include <mutex>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace platform
|
||||
{
|
||||
namespace tests_support
|
||||
{
|
||||
class TestSocket final : public Socket
|
||||
{
|
||||
public:
|
||||
// Socket overrides:
|
||||
~TestSocket();
|
||||
bool Open(std::string const & host, uint16_t port) override;
|
||||
void Close() override;
|
||||
bool Read(uint8_t * data, uint32_t count) override;
|
||||
bool Write(uint8_t const * data, uint32_t count) override;
|
||||
void SetTimeout(uint32_t milliseconds) override;
|
||||
|
||||
// Simulates server reading.
|
||||
// Waits for some data or timeout.
|
||||
// Returns size of read data.
|
||||
size_t ReadServer(std::vector<uint8_t> & destination);
|
||||
template <typename Container>
|
||||
void WriteServer(Container const & answer)
|
||||
{
|
||||
std::lock_guard<std::mutex> lg(m_inputMutex);
|
||||
m_input.insert(m_input.begin(), std::begin(answer), std::end(answer));
|
||||
m_inputCondition.notify_one();
|
||||
}
|
||||
|
||||
private:
|
||||
std::atomic<bool> m_isConnected = {false};
|
||||
std::atomic<uint32_t> m_timeoutMs = {100};
|
||||
|
||||
std::deque<uint8_t> m_input;
|
||||
std::mutex m_inputMutex;
|
||||
std::condition_variable m_inputCondition;
|
||||
|
||||
std::vector<uint8_t> m_output;
|
||||
std::mutex m_outputMutex;
|
||||
std::condition_variable m_outputCondition;
|
||||
};
|
||||
} // namespace tests_support
|
||||
} // namespace platform
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
#include "testing/testing.hpp"
|
||||
|
||||
#include "platform/platform_tests_support/writable_dir_changer.hpp"
|
||||
|
||||
#include "platform/platform.hpp"
|
||||
#include "platform/settings.hpp"
|
||||
|
||||
#include "coding/internal/file_data.hpp"
|
||||
|
||||
#include "base/file_name_utils.hpp"
|
||||
|
||||
WritableDirChanger::WritableDirChanger(std::string const & testDir, SettingsDirPolicy settingsDirPolicy)
|
||||
: m_writableDirBeforeTest(GetPlatform().WritableDir())
|
||||
, m_testDirFullPath(m_writableDirBeforeTest + testDir)
|
||||
, m_settingsDirPolicy(settingsDirPolicy)
|
||||
{
|
||||
Platform & platform = GetPlatform();
|
||||
platform.RmDirRecursively(m_testDirFullPath);
|
||||
TEST(!platform.IsFileExistsByFullPath(m_testDirFullPath), ());
|
||||
TEST_EQUAL(Platform::ERR_OK, platform.MkDir(m_testDirFullPath), ());
|
||||
platform.SetWritableDirForTests(m_testDirFullPath);
|
||||
if (m_settingsDirPolicy == SettingsDirPolicy::UseWritableDir)
|
||||
platform.SetSettingsDir(m_testDirFullPath);
|
||||
settings::Clear();
|
||||
}
|
||||
|
||||
WritableDirChanger::~WritableDirChanger()
|
||||
{
|
||||
settings::Clear();
|
||||
Platform & platform = GetPlatform();
|
||||
std::string const writableDirForTest = platform.WritableDir();
|
||||
platform.SetWritableDirForTests(m_writableDirBeforeTest);
|
||||
if (m_settingsDirPolicy == SettingsDirPolicy::UseWritableDir)
|
||||
platform.SetSettingsDir(m_writableDirBeforeTest);
|
||||
platform.RmDirRecursively(writableDirForTest);
|
||||
}
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
class WritableDirChanger
|
||||
{
|
||||
public:
|
||||
enum class SettingsDirPolicy
|
||||
{
|
||||
UseDefault,
|
||||
UseWritableDir
|
||||
};
|
||||
|
||||
WritableDirChanger(std::string const & testDir, SettingsDirPolicy settingsDirPolicy = SettingsDirPolicy::UseDefault);
|
||||
~WritableDirChanger();
|
||||
|
||||
private:
|
||||
std::string const m_writableDirBeforeTest;
|
||||
std::string const m_testDirFullPath;
|
||||
SettingsDirPolicy m_settingsDirPolicy;
|
||||
};
|
||||
Loading…
Add table
Add a link
Reference in a new issue