Merge impl branch

This commit is contained in:
Lam Wei Lun
2026-09-24 14:46:30 +08:00
1163 changed files with 28054 additions and 6833 deletions
+13 -5
View File
@@ -1,6 +1,7 @@
#include <catch2/catch_test_macros.hpp>
#include <nlohmann/json.hpp>
#include <slic3r/Utils/AmsPayload.hpp>
#include <slic3r/Utils/IPrinterAgent.hpp>
#include <slic3r/Utils/OrcaCloudServiceAgent.hpp>
#include <slic3r/Utils/OrcaPrinterAgent.hpp>
@@ -95,7 +96,10 @@ TEST_CASE("OrcaPrinterAgent::make_lan_client_id is stable and prefixed", "[OrcaP
TEST_CASE("connect_printer wires up a LAN Config", "[OrcaPrinterAgent][.integration]") {
Probe agent("/tmp");
const int rc = agent.connect_printer("dev-1", "10.255.255.1", "orcasonar", "code", false);
Slic3r::PrinterConnectionParams params{
"dev-1", "10.255.255.1", "", "orcasonar", "code", false, ""
};
const int rc = agent.connect_printer(params);
CHECK(rc == BAMBU_NETWORK_SUCCESS);
CHECK(agent.lan_connection_target() == "ws://10.255.255.1:8280/mqtt");
CHECK(agent.get_user_selected_machine().empty()); // LAN path must not touch the cloud selection
@@ -111,7 +115,9 @@ TEST_CASE("filament sync follows the printer's AMS capability", "[OrcaPrinterAge
Probe agent("/tmp");
CHECK(agent.get_filament_sync_mode() == Slic3r::FilamentSyncMode::none);
REQUIRE(agent.connect_printer("dev-ams-1", "10.255.255.1", "orcasonar", "code", false) == BAMBU_NETWORK_SUCCESS);
REQUIRE(agent.connect_printer(Slic3r::PrinterConnectionParams{
"dev-ams-1", "10.255.255.1", "", "orcasonar", "code", false, ""
}) == BAMBU_NETWORK_SUCCESS);
// Connected, but no capability reply yet: still none.
CHECK(agent.get_filament_sync_mode() == Slic3r::FilamentSyncMode::none);
@@ -270,7 +276,7 @@ TEST_CASE("send_message_to_printer publishes on the LAN connection", "[OrcaPrint
orca_mqtt_test::MockBroker broker;
OrcaPrinterAgent agent("/tmp");
const auto ep = broker.host_port();
agent.connect_printer("dev-1", ep.first + ":" + ep.second, "orcasonar", "code", false);
agent.connect_printer(Slic3r::PrinterConnectionParams{"dev-1", ep.first + ":" + ep.second, "", "orcasonar", "code", false, ""});
for (int i = 0; i < 150 && broker.connect_count() == 0; ++i)
std::this_thread::sleep_for(std::chrono::milliseconds(20));
@@ -293,7 +299,7 @@ TEST_CASE("send_message_to_printer publishes on the LAN connection", "[OrcaPrint
TEST_CASE("destroying an agent mid-connect does not hang or crash", "[OrcaPrinterAgent]") {
for (int i = 0; i < 20; ++i) {
auto agent = std::make_unique<OrcaPrinterAgent>("/tmp");
agent->connect_printer("dev-1", "127.0.0.1:1", "orcasonar", "code", false); // nothing listening: instant ECONNREFUSED
agent->connect_printer(Slic3r::PrinterConnectionParams{"dev-1", "127.0.0.1:1", "", "orcasonar", "code", false, ""}); // nothing listening: instant ECONNREFUSED
agent.reset(); // ~OrcaPrinterAgent must stop the conn, join the thread, and not hang/crash
}
SUCCEED();
@@ -515,7 +521,9 @@ TEST_CASE("deselecting a cloud device keeps a live LAN declaration", "[OrcaPrint
Slic3r::register_ams_ops("dev-lan-keep", {"change_filament"});
Slic3r::register_filament_slots("dev-lan-keep", true);
REQUIRE(agent.connect_printer("dev-lan-keep", "10.255.255.1", "orcasonar", "code", false) == BAMBU_NETWORK_SUCCESS);
REQUIRE(agent.connect_printer(Slic3r::PrinterConnectionParams{
"dev-lan-keep", "10.255.255.1", "", "orcasonar", "code", false, ""
}) == BAMBU_NETWORK_SUCCESS);
agent.set_user_selected_machine("dev-lan-keep");
agent.set_user_selected_machine("");
@@ -1,5 +1,6 @@
#include <catch2/catch_all.hpp>
#include <libslic3r/LifecycleEvents.hpp>
#include <libslic3r/Utils.hpp>
#include <slic3r/Utils/NetworkAgentFactory.hpp>
#include <slic3r/plugin/PluginDescriptor.hpp>
@@ -13,8 +14,11 @@
#include <algorithm>
#include <chrono>
#include <condition_variable>
#include <fstream>
#include <mutex>
#include <string>
#include <thread>
#include <vector>
using namespace Slic3r;
@@ -205,6 +209,72 @@ PluginDescriptor descriptor_of(PluginManager& manager, const std::string& plugin
} // namespace
TEST_CASE("Lifecycle hook shutdown drains concurrent dispatch", "[PluginLifecycle][LifecycleEvents]")
{
std::mutex mutex;
std::condition_variable cv;
bool callback_entered = false;
bool release_callback = false;
bool shutdown_started = false;
bool shutdown_finished = false;
set_lifecycle_hook_fn([&](LifecycleEvent, const LifecycleEventContext&) {
std::unique_lock<std::mutex> lock(mutex);
callback_entered = true;
cv.notify_all();
cv.wait(lock, [&] { return release_callback; });
});
std::thread dispatch_thread([] {
LifecycleEventContext ctx;
fire_lifecycle_event(LifecycleEvent::ProjectOpened, ctx);
});
bool callback_was_entered = false;
{
std::unique_lock<std::mutex> lock(mutex);
callback_was_entered = cv.wait_for(lock, std::chrono::seconds(5), [&] { return callback_entered; });
}
if (!callback_was_entered) {
{
std::lock_guard<std::mutex> lock(mutex);
release_callback = true;
cv.notify_all();
}
dispatch_thread.join();
set_lifecycle_hook_fn(nullptr);
FAIL("Lifecycle callback did not start");
}
std::thread shutdown_thread([&] {
{
std::lock_guard<std::mutex> lock(mutex);
shutdown_started = true;
cv.notify_all();
}
set_lifecycle_hook_fn(nullptr);
std::lock_guard<std::mutex> lock(mutex);
shutdown_finished = true;
cv.notify_all();
});
bool shutdown_was_started = false;
{
std::unique_lock<std::mutex> lock(mutex);
shutdown_was_started = cv.wait_for(lock, std::chrono::seconds(5), [&] { return shutdown_started; });
if (shutdown_was_started)
CHECK_FALSE(cv.wait_for(lock, std::chrono::milliseconds(100), [&] { return shutdown_finished; }));
release_callback = true;
cv.notify_all();
}
dispatch_thread.join();
shutdown_thread.join();
if (!shutdown_was_started)
FAIL("Lifecycle hook shutdown did not start");
CHECK(shutdown_finished);
}
TEST_CASE("A discovered script plugin loads and materializes its capability", "[PluginLifecycle][Python]")
{
ScopedPluginManager plugin_system;
@@ -128,7 +128,7 @@ TEST_CASE("A printer agent uses IPrinterAgent defaults for omitted commands", "[
CHECK(agent->command_xyz_abs("dev", 1, false) == 7);
CHECK(agent->command_set_nozzle("dev", 200, 2, true) == 8);
CHECK(agent->command_ams_refresh_rfid("dev", "tray", 3, false) == ORCA_NETWORK_ERR_CMD_NOT_SUPPORTED);
CHECK(agent->command_ams_refresh_rfid("dev", -1, 0, 3, false) == ORCA_NETWORK_ERR_CMD_NOT_SUPPORTED);
}
TEST_CASE("A printer agent operation returning the wrong type answers like a missing agent", "[PluginPrinterAgent][Python]")