Skip to content

Commit

Permalink
Minor cleaning of test_helpers.
Browse files Browse the repository at this point in the history
  • Loading branch information
Holt59 committed Jun 25, 2024
1 parent 9239e0f commit b526e8d
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 51 deletions.
28 changes: 22 additions & 6 deletions src/shared/test_helpers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

namespace test {

std::string FuncFailed::msg(const char* func, const char* arg1, const unsigned long* res, const char* what)
std::string FuncFailed::msg(std::string_view func, const char* arg1, const unsigned long* res, const char* what)
{
std::string buffer;
buffer.reserve(128);
Expand All @@ -26,6 +26,25 @@ namespace test {
return buffer;
}


ScopedFILE ScopedFILE::open(const std::filesystem::path& filepath, std::wstring_view mode, errno_t& err) {
FILE* fp = nullptr;
err = _wfopen_s(&fp, filepath.c_str(), mode.data());
if (err || !fp) {
return ScopedFILE();
}
return ScopedFILE(fp);
}

ScopedFILE ScopedFILE::open(const std::filesystem::path& filepath, std::wstring_view mode) {
errno_t err;
auto file = open(filepath, mode, err);
if (err || !file) {
throw_testWinFuncFailed("_wfopen_s", filepath.string().c_str(), err);
}
return file;
}

path path_of_test_bin(const path& relative) {
path base(winapi::wide::getModuleFileName(nullptr));
return relative.empty() ? base.parent_path() : base.parent_path() / relative;
Expand Down Expand Up @@ -87,10 +106,7 @@ namespace test {
{
using namespace std;

ScopedFILE f;
errno_t err = _wfopen_s(f, file.c_str(), binary ? L"rb" : L"rt");
if (err || !f)
throw_testWinFuncFailed("_wfopen_s", file.string().c_str(), err);
const auto f = ScopedFILE::open(file, binary ? L"rb" : L"rt");

if (fseek(f, 0, SEEK_END))
throw_testWinFuncFailed("fseek", (unsigned long) 0);
Expand All @@ -107,7 +123,7 @@ namespace test {
std::vector<char> content(static_cast<size_t>(size));
content.resize(fread(content.data(), sizeof(char), content.size(), f));

return std::move(content);
return content;
}

bool compare_files(const path& file1, const path& file2, bool binary)
Expand Down
64 changes: 39 additions & 25 deletions src/shared/test_helpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,28 +4,29 @@

#include "windows_sane.h"

#include <memory>
#include <filesystem>

namespace test {

class FuncFailed : public std::runtime_error
{
public:
FuncFailed(const char* func)
: std::runtime_error(msg(func)) {}
FuncFailed(const char* func, unsigned long res)
: std::runtime_error(msg(func, nullptr, &res)) {}
FuncFailed(const char* func, const char* arg1)
: std::runtime_error(msg(func, arg1)) {}
FuncFailed(const char* func, const char* arg1, unsigned long res)
: std::runtime_error(msg(func, arg1, &res)) {}
FuncFailed(const char* func, const char* what, const char* arg1)
: std::runtime_error(msg(func, arg1, nullptr, what)) {}
FuncFailed(const char* func, const char* what, const char* arg1, unsigned long res)
: std::runtime_error(msg(func, arg1, &res, what)) {}
FuncFailed(const char* func)
: std::runtime_error(msg(func)) {}
FuncFailed(const char* func, unsigned long res)
: std::runtime_error(msg(func, nullptr, &res)) {}
FuncFailed(const char* func, const char* arg1)
: std::runtime_error(msg(func, arg1)) {}
FuncFailed(const char* func, const char* arg1, unsigned long res)
: std::runtime_error(msg(func, arg1, &res)) {}
FuncFailed(const char* func, const char* what, const char* arg1)
: std::runtime_error(msg(func, arg1, nullptr, what)) {}
FuncFailed(const char* func, const char* what, const char* arg1, unsigned long res)
: std::runtime_error(msg(func, arg1, &res, what)) {}

private:
std::string msg(const char* func, const char* arg1 = nullptr, const unsigned long* res = nullptr, const char* what = nullptr);
std::string msg(std::string_view func, const char* arg1 = nullptr, const unsigned long* res = nullptr, const char* what = nullptr);
};

class WinFuncFailed : public std::runtime_error
Expand All @@ -52,12 +53,12 @@ namespace test {
return WinFuncFailed(std::format("{} failed : result=({:#x}), lastError={}", func, res, m_gle));
}

WinFuncFailed operator()(std::basic_string_view<char> func, std::basic_string_view<char> arg1)
WinFuncFailed operator()(std::string_view func, std::basic_string_view<char> arg1)
{
return WinFuncFailed(std::format("{} failed : {}, lastError={}", func, arg1, m_gle));
}

WinFuncFailed operator()(std::basic_string_view<char> func, std::basic_string_view<char> arg1, unsigned long res)
WinFuncFailed operator()(std::string_view func, std::basic_string_view<char> arg1, unsigned long res)
{
return WinFuncFailed(std::format("{} failed : {}, result=({:#x}), lastError={}", func, arg1, res, m_gle));
}
Expand All @@ -68,25 +69,38 @@ namespace test {

// trick to guarantee the evalutation of GetLastError() before the evalution of the parameters to the WinFuncFailed message generation
template <class... Args>
[[noreturn]] void throw_testWinFuncFailed(std::basic_string_view<char> func, Args&&... args) {
[[noreturn]] void throw_testWinFuncFailed(std::string_view func, Args&&... args) {
::test::WinFuncFailedGenerator exceptionGenerator;
throw exceptionGenerator(func, std::forward<Args>(args)... );
}

class ScopedFILE {
public:
ScopedFILE(FILE* f = nullptr) : m_f(f) {}

// try to open the given filepath with the given mode, if it fails, set err to
// the return code of _wfopen_s and return a nulled scoped file
//
static ScopedFILE open(const std::filesystem::path& filepath, std::wstring_view mode, errno_t& err);

// same as above but throw a WinFuncFailed() exception if opening the file failed
//
static ScopedFILE open(const std::filesystem::path& filepath, std::wstring_view mode);

public:
ScopedFILE(FILE* f = nullptr) : m_f(f, &fclose) {}

ScopedFILE(ScopedFILE&& other) noexcept = default;
~ScopedFILE() = default;

ScopedFILE(const ScopedFILE&) = delete;
ScopedFILE(ScopedFILE&& other) noexcept : m_f(other.m_f) { other.m_f = nullptr; }
~ScopedFILE() { if (m_f) fclose(m_f); }

void close() { if (m_f) { fclose(m_f); m_f = nullptr; } }
void close() { m_f = nullptr; }

operator bool() const { return static_cast<bool>(m_f); }
operator FILE*() const { return m_f.get(); }

operator bool() const { return m_f; }
operator FILE*() const { return m_f; }
operator FILE**() { return &m_f; }
private:
FILE* m_f;
std::unique_ptr<FILE, decltype(&fclose)> m_f;
};

using std::filesystem::path;
Expand Down
27 changes: 7 additions & 20 deletions test/usvfs_test/usvfs_test_base.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -100,14 +100,11 @@ class usvfs_connector {
using path = test::path;

usvfs_connector(const usvfs_test_options& options)
: m_exit_future(m_exit_signal.get_future())
: m_usvfs_log(test::ScopedFILE::open(options.usvfs_log, L"wt")),
m_exit_future(m_exit_signal.get_future())
{
winapi::ex::wide::createPath(options.usvfs_log.parent_path().c_str());

errno_t err = _wfopen_s(m_usvfs_log, options.usvfs_log.c_str(), L"wt");
if (err || !m_usvfs_log)
throw_testWinFuncFailed("_wfopen_s", options.usvfs_log.string().c_str(), err);

std::wcout << "Connecting VFS..." << std::endl;

std::unique_ptr<usvfsParameters, decltype(&usvfsFreeParameters)> parameters{
Expand Down Expand Up @@ -273,11 +270,7 @@ class mappings_reader

mappings_list read(const path& mapfile)
{
test::ScopedFILE map;
errno_t err = _wfopen_s(map, mapfile.c_str(), L"rt");
if (err || !map)
throw_testWinFuncFailed("_wfopen_s", mapfile.string().c_str(), err);

const auto map = test::ScopedFILE::open(mapfile, L"rt");
mappings_list mappings;

char line[1024];
Expand Down Expand Up @@ -564,10 +557,7 @@ bool usvfs_test_base::recursive_compare_dirs(path rel_path, path gold_base, path

test::ScopedFILE usvfs_test_base::output()
{
test::ScopedFILE log;
errno_t err = _wfopen_s(log, m_o.output.c_str(), m_clean_output ? L"wt" : L"at");
if (err || !log)
throw_testWinFuncFailed("_wfopen_s", m_o.output.string().c_str(), err);
auto log = test::ScopedFILE::open(m_o.output, m_clean_output ? L"wt" : L"at");
m_clean_output = false;
return log;
}
Expand All @@ -576,23 +566,20 @@ void usvfs_test_base::clean_output()
{
using namespace std;

test::ScopedFILE in;
errno_t err = _wfopen_s(in, m_o.output.c_str(), L"rt");
errno_t err;
auto in = test::ScopedFILE::open(m_o.output, L"rt", err);
if (err == ENOENT) {
wcerr << L"warning: no " << m_o.output << L" to clean." << endl;
return;
}
else if (err || !in)
throw_testWinFuncFailed("_wfopen_s", m_o.output.string().c_str(), err);

test::ScopedFILE out;
path clean = m_o.output.parent_path() / m_o.output.stem();
clean += OUTPUT_CLEAN_SUFFIX;
clean += m_o.output.extension();
err = _wfopen_s(out, clean.c_str(), L"wt");
if (err || !in)
throw_testWinFuncFailed("_wfopen_s", clean.string().c_str(), err);

auto out = test::ScopedFILE::open(clean, L"wt");
wcout << L"Cleaning " << m_o.output << " to " << clean << endl;

char line[1024];
Expand Down

0 comments on commit b526e8d

Please sign in to comment.