Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 25 additions & 26 deletions libmamba/tests/include/mambatests.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,13 @@

#include <array>
#include <functional>
#include <ranges>
#include <string_view>
#include <unordered_set>
#include <vector>

#include "mamba/core/context.hpp"
#include "mamba/core/invoke.hpp"
#include "mamba/core/output.hpp"
#include "mamba/fs/filesystem.hpp"
#include "mamba/util/environment.hpp"
Expand Down Expand Up @@ -91,8 +93,10 @@ namespace mambatests
};

// RAII helper for C++ tests that temporarily override fields on the shared Context
// singleton (see context()). Tests often need to point at a temp prefix, tweak channels,
// or flip feature flags; without restoration, later tests inherit stale state.
// singleton (see context()). A future improvement would be to give each test its own
// Context instance instead of mutating the singleton (see singletons() FIXME). Until then,
// tests often need to point at a temp prefix, tweak channels, or flip feature flags;
// without restoration, later tests inherit stale state.
//
// Save the value of each touched field on first use and restore it when the guard is
// destroyed. Repeated calls to the same setter only change the live value — the original
Expand All @@ -107,7 +111,7 @@ namespace mambatests
// mambatests::ScopedContextChange context_change{ ctx };
// context_change.set_channels({ "conda-forge" }).set_offline(false);
//
// context_change.preserve(&mamba::Context::use_sharded_repodata);
// context_change.preserve(ctx.use_sharded_repodata);
// ctx.use_sharded_repodata = false; // restored to the pre-preserve value at scope end
class ScopedContextChange
{
Expand All @@ -120,73 +124,69 @@ namespace mambatests

~ScopedContextChange()
{
for (auto it = m_restorers.rbegin(); it != m_restorers.rend(); ++it)
for (auto& restorer : std::ranges::reverse_view(m_restorers))
{
(*it)();
[[maybe_unused]] auto result = mamba::safe_invoke(restorer);
Comment thread
jjerphan marked this conversation as resolved.
Outdated
}
}

ScopedContextChange& set_target_prefix(const mamba::fs::u8path& prefix)
{
touch(
&mamba::Context::prefix_params,
[&](auto& params) { params.target_prefix = prefix; }
);
touch(m_ctx.prefix_params, [&](auto& params) { params.target_prefix = prefix; });
return *this;
}

ScopedContextChange& set_root_prefix(const mamba::fs::u8path& prefix)
{
touch(&mamba::Context::prefix_params, [&](auto& params) { params.root_prefix = prefix; });
touch(m_ctx.prefix_params, [&](auto& params) { params.root_prefix = prefix; });
return *this;
}

ScopedContextChange& set_envs_dirs(std::vector<mamba::fs::u8path> dirs)
{
touch(&mamba::Context::envs_dirs, [&](auto& field) { field = std::move(dirs); });
touch(m_ctx.envs_dirs, [&](auto& field) { field = std::move(dirs); });
return *this;
}

ScopedContextChange& set_pkgs_dirs(std::vector<mamba::fs::u8path> dirs)
{
touch(&mamba::Context::pkgs_dirs, [&](auto& field) { field = std::move(dirs); });
touch(m_ctx.pkgs_dirs, [&](auto& field) { field = std::move(dirs); });
return *this;
}

ScopedContextChange& set_prefix_data_interoperability(bool value)
{
touch(&mamba::Context::prefix_data_interoperability, [&](auto& field) { field = value; });
touch(m_ctx.prefix_data_interoperability, [&](auto& field) { field = value; });
return *this;
}

ScopedContextChange& set_channels(std::vector<std::string> channels)
{
touch(&mamba::Context::channels, [&](auto& field) { field = std::move(channels); });
touch(m_ctx.channels, [&](auto& field) { field = std::move(channels); });
return *this;
}

ScopedContextChange& set_use_sharded_repodata(bool value)
{
touch(&mamba::Context::use_sharded_repodata, [&](auto& field) { field = value; });
touch(m_ctx.use_sharded_repodata, [&](auto& field) { field = value; });
return *this;
}

ScopedContextChange& set_offline(bool value)
{
touch(&mamba::Context::offline, [&](auto& field) { field = value; });
touch(m_ctx.offline, [&](auto& field) { field = value; });
return *this;
}

ScopedContextChange& set_platform(std::string platform)
{
touch(&mamba::Context::platform, [&](auto& field) { field = std::move(platform); });
touch(m_ctx.platform, [&](auto& field) { field = std::move(platform); });
return *this;
}

// Snapshot member for restoration without assigning a new value. The member pointer
// syntax (e.g. &mamba::Context::platform) selects which Context field to guard.
// Snapshot member for restoration without assigning a new value.
template <typename T>
ScopedContextChange& preserve(T mamba::Context::* member)
ScopedContextChange& preserve(T& member)
{
touch(member, [](auto&) {});
return *this;
Expand All @@ -200,15 +200,14 @@ namespace mambatests
private:

template <typename T, typename F>
void touch(T mamba::Context::* member, F&& mutator)
void touch(T& member, F&& mutator)
{
auto& field = m_ctx.*member;
if (m_saved_fields.insert(static_cast<const void*>(&field)).second)
if (m_saved_fields.insert(static_cast<const void*>(&member)).second)
{
m_restorers.push_back([&field, initial = field]() mutable
{ field = std::move(initial); });
m_restorers.push_back([&member, initial = member]() mutable
{ member = std::move(initial); });
}
mutator(field);
std::invoke(std::forward<F>(mutator), member);
}

mamba::Context& m_ctx;
Expand Down
12 changes: 6 additions & 6 deletions libmamba/tests/src/core/test_channel_loader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -162,12 +162,12 @@ TEST_CASE("load_channels", "[mamba::api][channel_loader]")
// Use test singletons so Console/progress bar are initialized (avoids SIGABRT)
Context& ctx = mambatests::context();
mambatests::ScopedContextChange context_change{ ctx };
context_change.preserve(&mamba::Context::channels)
.preserve(&mamba::Context::mirrored_channels)
.preserve(&mamba::Context::pkgs_dirs)
.preserve(&mamba::Context::offline)
.preserve(&mamba::Context::remote_fetch_params)
.preserve(&mamba::Context::channel_alias);
context_change.preserve(ctx.channels)
.preserve(ctx.mirrored_channels)
.preserve(ctx.pkgs_dirs)
.preserve(ctx.offline)
.preserve(ctx.remote_fetch_params)
.preserve(ctx.channel_alias);

ctx.channels = {};
ctx.mirrored_channels = {};
Expand Down
2 changes: 1 addition & 1 deletion libmamba/tests/src/core/test_channels_hook.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ namespace mamba::testing

ChannelsHookFixture()
{
m_context_change.preserve(&mamba::Context::channel_alias).preserve(&mamba::Context::channels);
m_context_change.preserve(ctx.channel_alias).preserve(ctx.channels);
}

~ChannelsHookFixture()
Expand Down
5 changes: 2 additions & 3 deletions libmamba/tests/src/core/test_configuration.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,7 @@ namespace mamba

Configuration()
{
m_context_change.preserve(&mamba::Context::channel_alias)
.preserve(&mamba::Context::remote_fetch_params);
m_context_change.preserve(ctx.channel_alias).preserve(ctx.remote_fetch_params);
}

~Configuration()
Expand Down Expand Up @@ -865,7 +864,7 @@ namespace mamba
TEST_CASE_METHOD(Configuration, "platform")
{
mambatests::ScopedContextChange context_change{ ctx };
context_change.preserve(&mamba::Context::platform);
context_change.preserve(ctx.platform);

REQUIRE(ctx.platform == ctx.host_platform);

Expand Down
2 changes: 1 addition & 1 deletion libmamba/tests/src/core/test_output.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ namespace mamba
{
auto& ctx = mambatests::context();
mambatests::ScopedContextChange context_change{ ctx };
context_change.preserve(&mamba::Context::graphics_params);
context_change.preserve(ctx.graphics_params);

ctx.graphics_params.no_progress_bars = true;
auto proxy = Console::instance().add_progress_bar("conda-forge");
Expand Down
6 changes: 2 additions & 4 deletions libmamba/tests/src/core/test_sharded_repodata_integration.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1290,8 +1290,7 @@ TEST_CASE("Sharded repodata - update scenarios", "[mamba::core][sharded][.integr

// For update, we need to create prefix data and use Update request
mambatests::ScopedContextChange update_context_change{ ctx };
update_context_change.preserve(&mamba::Context::use_sharded_repodata)
.preserve(&mamba::Context::validation_params);
update_context_change.preserve(ctx.use_sharded_repodata).preserve(ctx.validation_params);

// Test traditional update
ctx.use_sharded_repodata = false;
Expand Down Expand Up @@ -1615,8 +1614,7 @@ TEST_CASE("Sharded repodata - remove scenarios", "[mamba::core][sharded][.integr

// For remove, we need to create prefix data and use Remove request
mambatests::ScopedContextChange remove_context_change{ ctx };
remove_context_change.preserve(&mamba::Context::use_sharded_repodata)
.preserve(&mamba::Context::validation_params);
remove_context_change.preserve(ctx.use_sharded_repodata).preserve(ctx.validation_params);

// Test traditional remove
ctx.use_sharded_repodata = false;
Expand Down
2 changes: 1 addition & 1 deletion libmamba/tests/src/core/test_virtual_packages.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ namespace mamba

auto& ctx = mambatests::context();
mambatests::ScopedContextChange context_change{ ctx };
context_change.preserve(&mamba::Context::platform);
context_change.preserve(ctx.platform);

auto pkgs = detail::dist_packages(ctx.platform);

Expand Down
Loading