mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-09-09 10:16:50 +00:00
Merge branch 'main' into feat/plugin-auditing
This commit is contained in:
@@ -6,6 +6,8 @@
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "test_utils.hpp"
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
// Point data_dir() at a throwaway directory for the lifetime of a test and
|
||||
@@ -13,24 +15,20 @@ namespace Slic3r {
|
||||
// disposable tree and tests don't leak state into each other.
|
||||
struct ScopedDataDir
|
||||
{
|
||||
ScopedTemporaryDir tmp; // owns the temp dir (create + recursive remove)
|
||||
boost::filesystem::path dir; // = tmp.path(); kept as a member for callers
|
||||
std::string previous;
|
||||
boost::filesystem::path dir;
|
||||
|
||||
explicit ScopedDataDir(const std::string& tag)
|
||||
: tmp("orca-" + tag), dir(tmp.path()), previous(data_dir())
|
||||
{
|
||||
namespace fs = boost::filesystem;
|
||||
previous = data_dir();
|
||||
dir = fs::temp_directory_path() / fs::unique_path("orca-" + tag + "-%%%%-%%%%");
|
||||
fs::create_directories(dir);
|
||||
set_data_dir(dir.string());
|
||||
}
|
||||
|
||||
~ScopedDataDir()
|
||||
{
|
||||
set_data_dir(previous);
|
||||
boost::system::error_code ec;
|
||||
boost::filesystem::remove_all(dir, ec);
|
||||
}
|
||||
~ScopedDataDir() { set_data_dir(previous); } // tmp removes the directory
|
||||
|
||||
// The plugin manager scans {data_dir}/orca_plugins.
|
||||
boost::filesystem::path plugins_dir() const { return dir / "orca_plugins"; }
|
||||
|
||||
ScopedDataDir(const ScopedDataDir&) = delete;
|
||||
ScopedDataDir& operator=(const ScopedDataDir&) = delete;
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
#include "libslic3r/Utils.hpp"
|
||||
#include "slic3r/Utils/bambu_networking.hpp"
|
||||
|
||||
#include "plugin_test_utils.hpp"
|
||||
|
||||
using namespace Slic3r;
|
||||
namespace fs = boost::filesystem;
|
||||
|
||||
@@ -25,27 +27,16 @@ static const char* PLUGIN_EXT = ".so";
|
||||
|
||||
struct PluginFolderFixture
|
||||
{
|
||||
fs::path root;
|
||||
std::string previous_data_dir;
|
||||
ScopedDataDir data{"netver"};
|
||||
|
||||
PluginFolderFixture()
|
||||
{
|
||||
previous_data_dir = data_dir();
|
||||
root = fs::temp_directory_path() / fs::unique_path("orca-netver-%%%%%%%%");
|
||||
fs::create_directories(root / "plugins");
|
||||
set_data_dir(root.string());
|
||||
}
|
||||
|
||||
~PluginFolderFixture()
|
||||
{
|
||||
set_data_dir(previous_data_dir);
|
||||
boost::system::error_code ec;
|
||||
fs::remove_all(root, ec);
|
||||
fs::create_directories(data.dir / "plugins");
|
||||
}
|
||||
|
||||
void add_plugin(const std::string& version)
|
||||
{
|
||||
boost::nowide::ofstream f((root / "plugins" / (PLUGIN_PREFIX + version + PLUGIN_EXT)).string());
|
||||
boost::nowide::ofstream f((data.dir / "plugins" / (PLUGIN_PREFIX + version + PLUGIN_EXT)).string());
|
||||
f << "stub";
|
||||
}
|
||||
};
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
#include <chrono>
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
|
||||
@@ -48,6 +49,18 @@ const char* const CLOUD_PLUGIN_SOURCE = R"PY(# /// script
|
||||
# version = "1.0"
|
||||
# ///
|
||||
print('ok')
|
||||
|
||||
import orca
|
||||
class stubscript(orca.script.ScriptPluginCapabilityBase):
|
||||
def get_name(self):
|
||||
return "stubscript"
|
||||
def execute(self):
|
||||
return orca.ExecutionResult.success("Stub orca script.")
|
||||
|
||||
@orca.plugin
|
||||
class stubpackage(orca.base):
|
||||
def register_capabilities(self):
|
||||
orca.register_capability(stubscript)
|
||||
)PY";
|
||||
|
||||
} // namespace
|
||||
@@ -152,4 +165,31 @@ TEST_CASE("cloud metadata refresh preserves a plugin's stored config", "[PluginC
|
||||
reloaded.load();
|
||||
REQUIRE(reloaded.has_config(id));
|
||||
CHECK(reloaded.get_config(id)->config == configured);
|
||||
|
||||
// A local package can remain after the cloud subscription disappears. The cloud identity is
|
||||
// retained for diagnosis, but the orphaned state must suppress update availability until the
|
||||
// plugin is returned by a later cloud refresh.
|
||||
PluginDescriptor orphaned_record = cloud_record;
|
||||
orphaned_record.cloud->orphaned = true;
|
||||
orphaned_record.cloud->update_available = true;
|
||||
manager.update_cloud_metadata({orphaned_record});
|
||||
|
||||
const PluginDescriptor orphaned = find_by_uuid();
|
||||
REQUIRE(orphaned.cloud.has_value());
|
||||
CHECK(orphaned.cloud->orphaned);
|
||||
CHECK_FALSE(orphaned.has_error());
|
||||
CHECK(orphaned.get_update_status() == PluginUpdateStatus::Normal);
|
||||
|
||||
// Orphaned is informational only: the local package must remain loadable and usable.
|
||||
std::string load_error;
|
||||
manager.load_plugin(uuid, /*skip_deps=*/true);
|
||||
REQUIRE(manager.wait_for_plugin_load(uuid, std::chrono::seconds(120), load_error));
|
||||
INFO("load error: " << load_error);
|
||||
CHECK(load_error.empty());
|
||||
CHECK(manager.is_plugin_loaded(uuid));
|
||||
CHECK(manager.unload_plugin(uuid));
|
||||
|
||||
// Seeing the plugin in a subsequent cloud response clears the orphaned marker.
|
||||
manager.update_cloud_metadata({cloud_record});
|
||||
CHECK_FALSE(find_by_uuid().cloud->orphaned);
|
||||
}
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
#include <slic3r/plugin/PluginFsUtils.hpp>
|
||||
#include <slic3r/plugin/PythonInterpreter.hpp>
|
||||
|
||||
#include "plugin_test_utils.hpp"
|
||||
|
||||
#include <boost/filesystem.hpp>
|
||||
|
||||
#include <algorithm>
|
||||
@@ -25,32 +27,6 @@ namespace fs = boost::filesystem;
|
||||
|
||||
namespace {
|
||||
|
||||
// Point data_dir() at a throwaway directory for the lifetime of a test and restore the previous
|
||||
// value afterwards, so discovery scans a disposable {data_dir}/orca_plugins tree and tests don't
|
||||
// leak state into each other.
|
||||
struct ScopedDataDir
|
||||
{
|
||||
std::string previous;
|
||||
fs::path dir;
|
||||
|
||||
explicit ScopedDataDir(const std::string& tag)
|
||||
{
|
||||
previous = data_dir();
|
||||
dir = fs::temp_directory_path() / fs::unique_path("orca-" + tag + "-%%%%-%%%%");
|
||||
fs::create_directories(dir);
|
||||
set_data_dir(dir.string());
|
||||
}
|
||||
|
||||
~ScopedDataDir()
|
||||
{
|
||||
set_data_dir(previous);
|
||||
boost::system::error_code ec;
|
||||
fs::remove_all(dir, ec);
|
||||
}
|
||||
|
||||
fs::path plugins_dir() const { return dir / "orca_plugins"; }
|
||||
};
|
||||
|
||||
// Brings the plugin system up, and tears it down explicitly at the end of the test.
|
||||
//
|
||||
// Shutting the interpreter down here, rather than leaving it to PythonInterpreter's static
|
||||
|
||||
@@ -16,6 +16,8 @@ TEST_CASE("SlicingPipeline capability-type string maps round-trip", "[slicing_pi
|
||||
#include "libslic3r/Point.hpp"
|
||||
#include "libslic3r/ExPolygon.hpp"
|
||||
#include "libslic3r/Surface.hpp"
|
||||
|
||||
#include "test_utils.hpp"
|
||||
#include "libslic3r/Layer.hpp"
|
||||
#include "libslic3r/ExtrusionEntity.hpp"
|
||||
#include "libslic3r/ExtrusionEntityCollection.hpp"
|
||||
@@ -142,7 +144,7 @@ TEST_CASE("orca.slicing psGCodePostProcess context: file edit in place + config
|
||||
import_orca_module();
|
||||
py::gil_scoped_acquire gil;
|
||||
|
||||
const fs::path gpath = fs::temp_directory_path() / fs::unique_path("orca_pp_%%%%-%%%%.gcode");
|
||||
ScopedTemporaryFile gpath(".gcode");
|
||||
{
|
||||
boost::nowide::ofstream ofs(gpath.string());
|
||||
ofs << "; header\nG1 X0 Y0\n";
|
||||
@@ -196,9 +198,7 @@ _pp_result = Stamp().execute(_pp_ctx)
|
||||
boost::nowide::ifstream ifs(gpath.string());
|
||||
std::stringstream ss; ss << ifs.rdbuf(); contents = ss.str();
|
||||
}
|
||||
CHECK(contents.find("; stamped by File") != std::string::npos);
|
||||
fs::remove(gpath);
|
||||
}
|
||||
CHECK(contents.find("; stamped by File") != std::string::npos);}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Toolpath helpers for the raw-graph tests.
|
||||
|
||||
Reference in New Issue
Block a user