diff --git a/src/platform/backends/hyperv/hyperv_snapshot.cpp b/src/platform/backends/hyperv/hyperv_snapshot.cpp index ee49765706..896cb30971 100644 --- a/src/platform/backends/hyperv/hyperv_snapshot.cpp +++ b/src/platform/backends/hyperv/hyperv_snapshot.cpp @@ -31,17 +31,19 @@ namespace mpl = mp::logging; namespace { -QString quoted(const QString& s) +std::string quoted(const std::string& s) { return '"' + s + '"'; } -bool snapshot_exists(mp::PowerShell& ps, const QString& vm_name, const QString& id) +bool snapshot_exists(mp::PowerShell& ps, const QString& vm_name, const std::string& id) { static const auto expected_error = QStringLiteral("ObjectNotFound"); QString output_err; - if (ps.run({"Get-VMCheckpoint", "-VMName", vm_name, "-Name", id}, nullptr, &output_err)) + if (ps.run({"Get-VMCheckpoint", "-VMName", vm_name, "-Name", QString::fromStdString(id)}, + nullptr, + &output_err)) return true; if (!output_err.contains(expected_error)) @@ -55,7 +57,7 @@ bool snapshot_exists(mp::PowerShell& ps, const QString& vm_name, const QString& return false; // we're good: the command failed with the expected error } -void require_unique_id(mp::PowerShell& ps, const QString& vm_name, const QString& id) +void require_unique_id(mp::PowerShell& ps, const QString& vm_name, const std::string& id) { if (snapshot_exists(ps, vm_name, id)) throw std::runtime_error{ @@ -78,7 +80,7 @@ mp::HyperVSnapshot::HyperVSnapshot(const std::string& name, { } -mp::HyperVSnapshot::HyperVSnapshot(const QString& filename, +mp::HyperVSnapshot::HyperVSnapshot(const std::filesystem::path& filename, HyperVVirtualMachine& vm, const VirtualMachineDescription& desc, PowerShell& power_shell) @@ -92,16 +94,21 @@ mp::HyperVSnapshot::HyperVSnapshot(const QString& filename, void mp::HyperVSnapshot::capture_impl() { require_unique_id(power_shell, vm_name, quoted_id); - power_shell.easy_run({"Checkpoint-VM", "-Name", vm_name, "-SnapshotName", quoted_id}, - "Could not create snapshot"); + power_shell.easy_run( + {"Checkpoint-VM", "-Name", vm_name, "-SnapshotName", QString::fromStdString(quoted_id)}, + "Could not create snapshot"); } void mp::HyperVSnapshot::erase_impl() { if (snapshot_exists(power_shell, vm_name, quoted_id)) - power_shell.easy_run( - {"Remove-VMCheckpoint", "-VMName", vm_name, "-Name", quoted_id, "-Confirm:$false"}, - "Could not delete snapshot"); + power_shell.easy_run({"Remove-VMCheckpoint", + "-VMName", + vm_name, + "-Name", + QString::fromStdString(quoted_id), + "-Confirm:$false"}, + "Could not delete snapshot"); else mpl::warn(vm_name.toStdString(), "Could not find underlying Hyper-V snapshot for \"{}\". Ignoring...", @@ -110,7 +117,11 @@ void mp::HyperVSnapshot::erase_impl() void mp::HyperVSnapshot::apply_impl() { - power_shell.easy_run( - {"Restore-VMCheckpoint", "-VMName", vm_name, "-Name", quoted_id, "-Confirm:$false"}, - "Could not apply snapshot"); + power_shell.easy_run({"Restore-VMCheckpoint", + "-VMName", + vm_name, + "-Name", + QString::fromStdString(quoted_id), + "-Confirm:$false"}, + "Could not apply snapshot"); } diff --git a/src/platform/backends/hyperv/hyperv_snapshot.h b/src/platform/backends/hyperv/hyperv_snapshot.h index c907c97e86..2e1dc75260 100644 --- a/src/platform/backends/hyperv/hyperv_snapshot.h +++ b/src/platform/backends/hyperv/hyperv_snapshot.h @@ -37,7 +37,7 @@ class HyperVSnapshot : public BaseSnapshot const QString& vm_name, HyperVVirtualMachine& vm, PowerShell& power_shell); - HyperVSnapshot(const QString& filename, + HyperVSnapshot(const std::filesystem::path& filename, HyperVVirtualMachine& vm, const VirtualMachineDescription& desc, PowerShell& power_shell); @@ -48,7 +48,7 @@ class HyperVSnapshot : public BaseSnapshot void apply_impl() override; private: - const QString quoted_id; + const std::string quoted_id; const QString vm_name; PowerShell& power_shell; }; diff --git a/src/platform/backends/hyperv/hyperv_virtual_machine.cpp b/src/platform/backends/hyperv/hyperv_virtual_machine.cpp index 47f7dd8a1d..cc78f1a150 100644 --- a/src/platform/backends/hyperv/hyperv_virtual_machine.cpp +++ b/src/platform/backends/hyperv/hyperv_virtual_machine.cpp @@ -548,5 +548,8 @@ auto mp::HyperVVirtualMachine::make_specific_snapshot(const std::string& snapsho auto mp::HyperVVirtualMachine::make_specific_snapshot(const QString& filename) -> std::shared_ptr { - return std::make_shared(filename, *this, desc, *power_shell); + return std::make_shared(MP_PLATFORM.qstr_to_path(filename), + *this, + desc, + *power_shell); } diff --git a/src/platform/backends/qemu/qemu_img_utils.cpp b/src/platform/backends/qemu/qemu_img_utils.cpp index 417f6b904a..2f6d3a6561 100644 --- a/src/platform/backends/qemu/qemu_img_utils.cpp +++ b/src/platform/backends/qemu/qemu_img_utils.cpp @@ -24,7 +24,8 @@ #include #include -#include +#include + #include #include @@ -146,10 +147,10 @@ std::filesystem::path mp::backend::convert_to_raw(const std::filesystem::path& i } bool mp::backend::instance_image_has_snapshot(const std::filesystem::path& image_path, - QString snapshot_tag) + const std::string& snapshot_tag) { - QRegularExpression regex{snapshot_tag.append(R"(\s)")}; - return QString{snapshot_list_output(image_path)}.contains(regex); + std::regex regex{snapshot_tag + R"(\s)"}; + return std::regex_search(snapshot_list_output(image_path).toStdString(), regex); } QByteArray mp::backend::snapshot_list_output(const std::filesystem::path& image_path) diff --git a/src/platform/backends/qemu/qemu_img_utils.h b/src/platform/backends/qemu/qemu_img_utils.h index 0c576548ee..318fb2d92e 100644 --- a/src/platform/backends/qemu/qemu_img_utils.h +++ b/src/platform/backends/qemu/qemu_img_utils.h @@ -22,6 +22,7 @@ #include #include +#include namespace multipass { @@ -44,7 +45,8 @@ void resize_instance_image(const MemorySize& disk_space, const std::filesystem:: std::filesystem::path convert_to_qcow_if_necessary(const std::filesystem::path& image_path); void amend_to_qcow2_v3(const std::filesystem::path& image_path); std::filesystem::path convert_to_raw(const std::filesystem::path& image_path); -bool instance_image_has_snapshot(const std::filesystem::path& image_path, QString snapshot_tag); +bool instance_image_has_snapshot(const std::filesystem::path& image_path, + const std::string& snapshot_tag); QByteArray snapshot_list_output(const std::filesystem::path& image_path); void delete_snapshot_from_image(const std::filesystem::path& image_path, const QString& snapshot_tag); diff --git a/src/platform/backends/qemu/qemu_snapshot.cpp b/src/platform/backends/qemu/qemu_snapshot.cpp index 6237b5a913..66a11fa352 100644 --- a/src/platform/backends/qemu/qemu_snapshot.cpp +++ b/src/platform/backends/qemu/qemu_snapshot.cpp @@ -32,29 +32,38 @@ namespace mp = multipass; namespace { -std::unique_ptr make_capture_spec(const QString& tag, +std::unique_ptr make_capture_spec(const std::string& tag, const std::filesystem::path& image_path) { return std::make_unique( - QStringList{"snapshot", "-c", tag, MP_PLATFORM.path_to_qstr(image_path)}, + QStringList{"snapshot", + "-c", + QString::fromStdString(tag), + MP_PLATFORM.path_to_qstr(image_path)}, /* src_img = */ "", image_path); } -std::unique_ptr make_restore_spec(const QString& tag, +std::unique_ptr make_restore_spec(const std::string& tag, const std::filesystem::path& image_path) { return std::make_unique( - QStringList{"snapshot", "-a", tag, MP_PLATFORM.path_to_qstr(image_path)}, + QStringList{"snapshot", + "-a", + QString::fromStdString(tag), + MP_PLATFORM.path_to_qstr(image_path)}, /* src_img = */ "", image_path); } -std::unique_ptr make_delete_spec(const QString& tag, +std::unique_ptr make_delete_spec(const std::string& tag, const std::filesystem::path& image_path) { return std::make_unique( - QStringList{"snapshot", "-d", tag, MP_PLATFORM.path_to_qstr(image_path)}, + QStringList{"snapshot", + "-d", + QString::fromStdString(tag), + MP_PLATFORM.path_to_qstr(image_path)}, /* src_img = */ "", image_path); } @@ -73,7 +82,7 @@ mp::QemuSnapshot::QemuSnapshot(const std::string& name, { } -mp::QemuSnapshot::QemuSnapshot(const QString& filename, +mp::QemuSnapshot::QemuSnapshot(const std::filesystem::path& filename, QemuVirtualMachine& vm, VirtualMachineDescription& desc) : BaseSnapshot{filename, vm, desc}, desc{desc}, image_path{desc.image.image_path} diff --git a/src/platform/backends/qemu/qemu_snapshot.h b/src/platform/backends/qemu/qemu_snapshot.h index c39fc5f58b..e8d67c446a 100644 --- a/src/platform/backends/qemu/qemu_snapshot.h +++ b/src/platform/backends/qemu/qemu_snapshot.h @@ -21,8 +21,6 @@ #include -#include - namespace multipass { class QemuVirtualMachine; @@ -38,7 +36,9 @@ class QemuSnapshot : public BaseSnapshot const VMSpecs& specs, QemuVirtualMachine& vm, VirtualMachineDescription& desc); - QemuSnapshot(const QString& filename, QemuVirtualMachine& vm, VirtualMachineDescription& desc); + QemuSnapshot(const std::filesystem::path& filename, + QemuVirtualMachine& vm, + VirtualMachineDescription& desc); protected: void capture_impl() override; diff --git a/src/platform/backends/qemu/qemu_virtual_machine.cpp b/src/platform/backends/qemu/qemu_virtual_machine.cpp index 4a1c5ed328..fa271cf858 100644 --- a/src/platform/backends/qemu/qemu_virtual_machine.cpp +++ b/src/platform/backends/qemu/qemu_virtual_machine.cpp @@ -780,7 +780,7 @@ bool multipass::QemuVirtualMachine::unplugged() auto mp::QemuVirtualMachine::make_specific_snapshot(const QString& filename) -> std::shared_ptr { - return std::make_shared(filename, *this, desc); + return std::make_shared(MP_PLATFORM.qstr_to_path(filename), *this, desc); } void mp::QemuVirtualMachine::fetch_ip(std::chrono::milliseconds timeout) diff --git a/src/platform/backends/shared/base_snapshot.cpp b/src/platform/backends/shared/base_snapshot.cpp index a55aff5060..0f4d0e64f7 100644 --- a/src/platform/backends/shared/base_snapshot.cpp +++ b/src/platform/backends/shared/base_snapshot.cpp @@ -20,15 +20,18 @@ #include #include +#include #include #include #include #include -#include - #include +#include #include + +#include + #include namespace mp = multipass; @@ -37,41 +40,33 @@ namespace { constexpr auto snapshot_extension = "snapshot.json"; constexpr auto index_digits = 4; // these two go together -const auto snapshot_template = - QStringLiteral("@s%1"); /* avoid confusion with snapshot names by prepending a character - that can't be part of the name (users can call a snapshot - "s1", but they cannot call it "@s1") */ - -QString derive_index_string(int index) -{ - return QString{"%1"}.arg(index, index_digits, 10, QLatin1Char('0')); -} +// Avoid confusion with snapshot names by prepending a character that can't be part of the name +// (users can call a snapshot "s1", but they cannot call it "@s1"). +constexpr auto snapshot_template = "@s{}"; -mp::SnapshotDescription read_snapshot_json(const QString& filename, +mp::SnapshotDescription read_snapshot_json(const std::filesystem::path& filename, const mp::VirtualMachine& vm, const mp::VirtualMachineDescription& vm_desc) { - QFile file{filename}; - if (!MP_FILEOPS.open(file, QIODevice::ReadOnly)) - throw std::runtime_error{ - fmt::format("Could not open snapshot file for for reading: {}", file.fileName())}; - - const auto& data = MP_FILEOPS.read_all(file); - if (data.isEmpty()) - throw std::runtime_error{fmt::format("Empty snapshot JSON: {}", file.fileName())}; - - try + if (auto data = MP_FILEOPS.try_read_file(filename)) { - const auto json = boost::json::parse(std::string_view(data)); - return value_to(json.at("snapshot"), - mp::SnapshotContext{vm, vm_desc}); - } - catch (const boost::system::system_error& e) - { - throw std::runtime_error{fmt::format("Could not parse snapshot JSON; error: {}; file: {}", - e.what(), - file.fileName())}; + try + { + const auto json = boost::json::parse(*data); + return value_to(json.at("snapshot"), + mp::SnapshotContext{vm, vm_desc}); + } + catch (const boost::system::system_error& e) + { + throw std::runtime_error{ + fmt::format("Could not parse snapshot JSON; error: {}; file: {}", + e.what(), + filename)}; + } } + + throw std::runtime_error{ + fmt::format("Could not open snapshot file for for reading: {}", filename)}; } std::shared_ptr find_parent(const mp::SnapshotDescription& desc, @@ -97,8 +92,8 @@ mp::BaseSnapshot::BaseSnapshot(SnapshotDescription desc, bool captured) : desc{std::move(desc)}, parent{std::move(parent)}, - id{snapshot_template.arg(this->desc.index)}, - storage_dir{vm.instance_directory()}, + id{fmt::format(snapshot_template, this->desc.index)}, + storage_dir{MP_PLATFORM.qstr_to_path(vm.instance_directory().path())}, captured{captured} { this->desc.parent_index = this->parent ? this->parent->get_index() : 0; @@ -108,8 +103,8 @@ mp::BaseSnapshot::BaseSnapshot(SnapshotDescription desc, mp::BaseSnapshot::BaseSnapshot(SnapshotDescription desc, VirtualMachine& vm, bool captured) : desc{std::move(desc)}, - id{snapshot_template.arg(desc.index)}, - storage_dir{vm.instance_directory()}, + id{fmt::format(snapshot_template, desc.index)}, + storage_dir{MP_PLATFORM.qstr_to_path(vm.instance_directory().path())}, captured{captured} { parent = find_parent(this->desc, vm); @@ -143,7 +138,7 @@ mp::BaseSnapshot::BaseSnapshot(const std::string& name, { } -mp::BaseSnapshot::BaseSnapshot(const QString& filename, +mp::BaseSnapshot::BaseSnapshot(const std::filesystem::path& filename, VirtualMachine& vm, const VirtualMachineDescription& desc) : BaseSnapshot{read_snapshot_json(filename, vm, desc), vm, /*captured=*/true} @@ -155,7 +150,7 @@ void mp::BaseSnapshot::persist() const assert(captured && "precondition: only captured snapshots can be persisted"); const std::unique_lock lock{mutex}; - auto snapshot_filepath = storage_dir.filePath(derive_snapshot_filename()); + auto snapshot_filepath = storage_dir / derive_snapshot_filename(); boost::json::value json = {{"snapshot", boost::json::value_from(desc)}}; MP_FILEOPS.write_transactionally(snapshot_filepath, pretty_print(json)); } @@ -167,8 +162,9 @@ auto mp::BaseSnapshot::erase_helper() if (!tmp_dir->isValid()) throw std::runtime_error{"Could not create temporary directory"}; - const auto snapshot_filename = derive_snapshot_filename(); - auto snapshot_filepath = storage_dir.filePath(snapshot_filename); + const auto snapshot_filename = QString::fromStdString(derive_snapshot_filename()); + QDir qstorage_dir = MP_PLATFORM.path_to_qstr(storage_dir); + auto snapshot_filepath = qstorage_dir.filePath(snapshot_filename); auto deleting_filepath = tmp_dir->filePath(snapshot_filename); QFile snapshot_file{snapshot_filepath}; @@ -195,7 +191,7 @@ void mp::BaseSnapshot::erase() rollback_snapshot_file.dismiss(); } -QString mp::BaseSnapshot::derive_snapshot_filename() const +std::string mp::BaseSnapshot::derive_snapshot_filename() const { - return QString{"%1.%2"}.arg(derive_index_string(desc.index), snapshot_extension); + return fmt::format("{0:0{1}}.{2}", desc.index, index_digits, snapshot_extension); } diff --git a/src/platform/backends/shared/base_snapshot.h b/src/platform/backends/shared/base_snapshot.h index b3a91a36b5..d067c86829 100644 --- a/src/platform/backends/shared/base_snapshot.h +++ b/src/platform/backends/shared/base_snapshot.h @@ -24,10 +24,9 @@ #include #include -#include - #include +#include #include namespace multipass @@ -45,7 +44,7 @@ class BaseSnapshot : public Snapshot std::shared_ptr parent, const VMSpecs& specs, const VirtualMachine& vm); - BaseSnapshot(const QString& filename, + BaseSnapshot(const std::filesystem::path& filename, VirtualMachine& vm, const VirtualMachineDescription& desc); @@ -78,7 +77,7 @@ class BaseSnapshot : public Snapshot void apply() final; protected: - const QString& get_id() const noexcept; + const std::string& get_id() const noexcept; virtual void capture_impl() = 0; virtual void erase_impl() = 0; @@ -92,8 +91,7 @@ class BaseSnapshot : public Snapshot BaseSnapshot(SnapshotDescription desc, VirtualMachine& vm, bool captured); auto erase_helper(); - QString derive_snapshot_filename() const; - QJsonObject serialize() const; + std::string derive_snapshot_filename() const; void persist() const; private: @@ -102,8 +100,8 @@ class BaseSnapshot : public Snapshot // This class is non-copyable and having these const simplifies thread safety. // NOLINTBEGIN(cppcoreguidelines-avoid-const-or-ref-data-members) - const QString id; - const QDir storage_dir; + const std::string id; + const std::filesystem::path storage_dir; // NOLINTEND(cppcoreguidelines-avoid-const-or-ref-data-members) bool captured; @@ -252,7 +250,7 @@ inline void multipass::BaseSnapshot::apply() // already persist) } -inline const QString& multipass::BaseSnapshot::get_id() const noexcept +inline const std::string& multipass::BaseSnapshot::get_id() const noexcept { return id; } diff --git a/src/platform/backends/virtualbox/virtualbox_snapshot.cpp b/src/platform/backends/virtualbox/virtualbox_snapshot.cpp index ac80a9a669..4bba5eb751 100644 --- a/src/platform/backends/virtualbox/virtualbox_snapshot.cpp +++ b/src/platform/backends/virtualbox/virtualbox_snapshot.cpp @@ -25,15 +25,16 @@ namespace mpu = multipass::utils; namespace { -bool snapshot_exists(const QString& vm_name, const QString& snapshot_id) +bool snapshot_exists(const QString& vm_name, const std::string& snapshot_id) { - return mpu::process_log_on_error("VBoxManage", - {"snapshot", vm_name, "showvminfo", snapshot_id}, - "Could not find snapshot: {}", - vm_name); + return mpu::process_log_on_error( + "VBoxManage", + {"snapshot", vm_name, "showvminfo", QString::fromStdString(snapshot_id)}, + "Could not find snapshot: {}", + vm_name); } -void require_unique_id(const QString& vm_name, const QString& snapshot_id) +void require_unique_id(const QString& vm_name, const std::string& snapshot_id) { if (snapshot_exists(vm_name, snapshot_id)) throw std::runtime_error{ @@ -55,7 +56,7 @@ mp::VirtualBoxSnapshot::VirtualBoxSnapshot(const std::string& name, { } -mp::VirtualBoxSnapshot::VirtualBoxSnapshot(const QString& filename, +mp::VirtualBoxSnapshot::VirtualBoxSnapshot(const std::filesystem::path& filename, VirtualBoxVirtualMachine& vm, const VirtualMachineDescription& desc) : BaseSnapshot{filename, vm, desc}, vm_name{QString::fromStdString(desc.vm_name)} @@ -69,10 +70,11 @@ void multipass::VirtualBoxSnapshot::capture_impl() const auto description_arg = QString{"--description=%1: %2"}.arg(get_name().c_str(), get_comment().c_str()); - mpu::process_throw_on_error("VBoxManage", - {"snapshot", vm_name, "take", id, description_arg}, - "Could not take snapshot: {}", - vm_name); + mpu::process_throw_on_error( + "VBoxManage", + {"snapshot", vm_name, "take", QString::fromStdString(id), description_arg}, + "Could not take snapshot: {}", + vm_name); } void multipass::VirtualBoxSnapshot::erase_impl() @@ -80,7 +82,7 @@ void multipass::VirtualBoxSnapshot::erase_impl() const auto& id = get_id(); if (snapshot_exists(vm_name, id)) mpu::process_throw_on_error("VBoxManage", - {"snapshot", vm_name, "delete", get_id()}, + {"snapshot", vm_name, "delete", QString::fromStdString(id)}, "Could not delete snapshot: {}", vm_name); else @@ -91,8 +93,9 @@ void multipass::VirtualBoxSnapshot::erase_impl() void multipass::VirtualBoxSnapshot::apply_impl() { + const auto id = QString::fromStdString(get_id()); mpu::process_throw_on_error("VBoxManage", - {"snapshot", vm_name, "restore", get_id()}, + {"snapshot", vm_name, "restore", id}, "Could not restore snapshot: {}", vm_name); } diff --git a/src/platform/backends/virtualbox/virtualbox_snapshot.h b/src/platform/backends/virtualbox/virtualbox_snapshot.h index 256c59776a..9dbd1f2912 100644 --- a/src/platform/backends/virtualbox/virtualbox_snapshot.h +++ b/src/platform/backends/virtualbox/virtualbox_snapshot.h @@ -34,7 +34,7 @@ class VirtualBoxSnapshot : public BaseSnapshot const QString& vm_name, const VMSpecs& specs, VirtualBoxVirtualMachine& vm); - VirtualBoxSnapshot(const QString& filename, + VirtualBoxSnapshot(const std::filesystem::path& filename, VirtualBoxVirtualMachine& vm, const VirtualMachineDescription& desc); diff --git a/src/platform/backends/virtualbox/virtualbox_virtual_machine.cpp b/src/platform/backends/virtualbox/virtualbox_virtual_machine.cpp index 933e3f8efc..647a0c0cd1 100644 --- a/src/platform/backends/virtualbox/virtualbox_virtual_machine.cpp +++ b/src/platform/backends/virtualbox/virtualbox_virtual_machine.cpp @@ -602,7 +602,7 @@ void mp::VirtualBoxVirtualMachine::remove_snapshots_from_backend() const auto multipass::VirtualBoxVirtualMachine::make_specific_snapshot(const QString& filename) -> std::shared_ptr { - return std::make_shared(filename, *this, desc); + return std::make_shared(MP_PLATFORM.qstr_to_path(filename), *this, desc); } auto multipass::VirtualBoxVirtualMachine::make_specific_snapshot(const std::string& snapshot_name, diff --git a/src/utils/file_ops.cpp b/src/utils/file_ops.cpp index 1abae6b4b7..072f614b98 100644 --- a/src/utils/file_ops.cpp +++ b/src/utils/file_ops.cpp @@ -18,6 +18,7 @@ #include #include #include +#include #include #include @@ -155,7 +156,7 @@ void mp::FileOps::write_transactionally(const QString& file_name, const QByteArr void mp::FileOps::write_transactionally(const fs::path& file_name, std::string_view data) const { - write_transactionally(QString::fromStdString(file_name.string()), data); + write_transactionally(MP_PLATFORM.path_to_qstr(file_name), data); } // LCOV_EXCL_START diff --git a/tests/unit/qemu/test_qemu_snapshot.cpp b/tests/unit/qemu/test_qemu_snapshot.cpp index 071cdff061..e15b70eb02 100644 --- a/tests/unit/qemu/test_qemu_snapshot.cpp +++ b/tests/unit/qemu/test_qemu_snapshot.cpp @@ -24,6 +24,7 @@ #include "tests/unit/path.h" #include "tests/unit/stub_ssh_key_provider.h" +#include #include #include #include @@ -61,7 +62,10 @@ struct TestQemuSnapshot : public Test mp::QemuSnapshot loaded_snapshot() { - return mp::QemuSnapshot{mpt::test_data_path_for("test_snapshot.json"), vm, desc}; + return mp::QemuSnapshot{ + MP_PLATFORM.qstr_to_path(mpt::test_data_path_for("test_snapshot.json")), + vm, + desc}; } template @@ -150,7 +154,10 @@ TEST_F(TestQemuSnapshot, initializesBasePropertiesFromJson) const auto parent = std::make_shared(); EXPECT_CALL(vm, get_snapshot(2)).WillOnce(Return(parent)); - const mp::QemuSnapshot snapshot{mpt::test_data_path_for("test_snapshot.json"), vm, desc}; + const mp::QemuSnapshot snapshot{ + MP_PLATFORM.qstr_to_path(mpt::test_data_path_for("test_snapshot.json")), + vm, + desc}; EXPECT_EQ(snapshot.get_name(), "snapshot3"); EXPECT_EQ(snapshot.get_comment(), "A comment"); EXPECT_EQ(snapshot.get_parent(), parent); diff --git a/tests/unit/test_base_snapshot.cpp b/tests/unit/test_base_snapshot.cpp index 2e7a945d94..e2aa6a0923 100644 --- a/tests/unit/test_base_snapshot.cpp +++ b/tests/unit/test_base_snapshot.cpp @@ -24,6 +24,7 @@ #include #include +#include #include #include #include @@ -95,12 +96,12 @@ struct TestBaseSnapshot : public Test json.at("snapshot").as_object()[key] = new_value; } - QString plant_snapshot_json(const boost::json::value& json, - const QString& filename = "snapshot.json") const + std::filesystem::path plant_snapshot_json(const boost::json::value& json, + const QString& filename = "snapshot.json") const { const auto file_path = vm.tmp_dir->filePath(filename); mpt::make_file_with_content(file_path, serialize(json)); - return file_path; + return MP_PLATFORM.qstr_to_path(file_path); } QString derive_persisted_snapshot_file_path(int index) @@ -115,7 +116,8 @@ struct TestBaseSnapshot : public Test NiceMock vm{}; const mpt::MockCloudInitFileOps::GuardedMock mock_cloud_init_file_ops_injection = mpt::MockCloudInitFileOps::inject(); - QString test_json_file_path = mpt::test_data_path_for(test_json_filename); + std::filesystem::path test_json_file_path = + MP_PLATFORM.qstr_to_path(mpt::test_data_path_for(test_json_filename)); }; TEST_F(TestBaseSnapshot, adoptsGivenValidName) @@ -684,22 +686,13 @@ TEST_F(TestBaseSnapshot, throwsIfUnableToOpenFile) { auto [mock_file_ops, guard] = mpt::MockFileOps::inject(); - EXPECT_CALL(*mock_file_ops, open(mpt::FileNameMatches(Eq(test_json_file_path)), _)) - .WillOnce(Return(false)); + EXPECT_CALL(*mock_file_ops, try_read_file(Eq(test_json_file_path))) + .WillOnce(Return(std::nullopt)); MP_EXPECT_THROW_THAT((MockBaseSnapshot{test_json_file_path, vm, desc}), std::runtime_error, mpt::match_what(AllOf(HasSubstr("Could not open"), - HasSubstr(test_json_file_path.toStdString())))); -} - -TEST_F(TestBaseSnapshot, throwsOnEmptyFile) -{ - const auto snapshot_file_path = vm.tmp_dir->filePath("wrong"); - mpt::make_file_with_content(snapshot_file_path, ""); - MP_EXPECT_THROW_THAT((MockBaseSnapshot{snapshot_file_path, vm, desc}), - std::runtime_error, - mpt::match_what(HasSubstr("Empty"))); + HasSubstr(test_json_file_path.string())))); } TEST_F(TestBaseSnapshot, throwsOnEmptyJsonObject) @@ -726,7 +719,7 @@ TEST_F(TestBaseSnapshot, throwsOnBadFormat) "(Murray): Alright, then. ROLL! I shall ROLL through the gates of " "hell! Must you take the fun out of everything?"); - MP_EXPECT_THROW_THAT((MockBaseSnapshot{snapshot_file_path, vm, desc}), + MP_EXPECT_THROW_THAT((MockBaseSnapshot{MP_PLATFORM.qstr_to_path(snapshot_file_path), vm, desc}), std::runtime_error, mpt::match_what(HasSubstr("Could not parse snapshot JSON"))); }