From e0ecabe4dce7d56d5f3f9262e98b7811c9e9bca3 Mon Sep 17 00:00:00 2001 From: vansangpfiev Date: Wed, 27 Nov 2024 10:42:46 +0700 Subject: [PATCH 01/21] fix: utf8 --- engine/CMakeLists.txt | 4 ++++ engine/cli/CMakeLists.txt | 4 ++++ engine/cli/commands/server_start_cmd.cc | 24 +++++++++++++----------- engine/services/hardware_service.cc | 5 +++-- engine/utils/system_info_utils.h | 4 ++-- 5 files changed, 26 insertions(+), 15 deletions(-) diff --git a/engine/CMakeLists.txt b/engine/CMakeLists.txt index bdbb67ed8..b53eb7fdf 100644 --- a/engine/CMakeLists.txt +++ b/engine/CMakeLists.txt @@ -28,6 +28,10 @@ if(MSVC) $<$:/MTd> #---|-- Statically link the runtime libraries $<$:/MT> #--| ) + + add_compile_options(/utf-8) + add_definitions(-DUNICODE -D_UNICODE) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /DUNICODE /D_UNICODE") endif() if(NOT DEFINED CORTEX_VARIANT) diff --git a/engine/cli/CMakeLists.txt b/engine/cli/CMakeLists.txt index ce6f254ca..c69e7e150 100644 --- a/engine/cli/CMakeLists.txt +++ b/engine/cli/CMakeLists.txt @@ -26,6 +26,10 @@ if(MSVC) $<$:/MTd> #---|-- Statically link the runtime libraries $<$:/MT> #--| ) + + add_compile_options(/utf-8) + add_definitions(-DUNICODE -D_UNICODE) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /DUNICODE /D_UNICODE") endif() if(NOT DEFINED CORTEX_VARIANT) diff --git a/engine/cli/commands/server_start_cmd.cc b/engine/cli/commands/server_start_cmd.cc index e039e5329..6f4c9627d 100644 --- a/engine/cli/commands/server_start_cmd.cc +++ b/engine/cli/commands/server_start_cmd.cc @@ -62,19 +62,20 @@ bool ServerStartCmd::Exec(const std::string& host, int port, params += " --data_folder_path " + get_data_folder_path(); params += " --loglevel " + log_level_; std::string cmds = cortex_utils::GetCurrentPath() + "/" + exe + " " + params; + std::wstring w = std::wstring(cmds.begin(), cmds.end()); // Create child process if (!CreateProcess( NULL, // No module name (use command line) - const_cast( - cmds.c_str()), // Command line (replace with your actual executable) - NULL, // Process handle not inheritable - NULL, // Thread handle not inheritable - FALSE, // Set handle inheritance to FALSE - 0, // No creation flags - NULL, // Use parent's environment block - NULL, // Use parent's starting directory - &si, // Pointer to STARTUPINFO structure - &pi)) // Pointer to PROCESS_INFORMATION structure + const_cast( + w.c_str()), // Command line (replace with your actual executable) + NULL, // Process handle not inheritable + NULL, // Thread handle not inheritable + TRUE, // Set handle inheritance + 0, // No creation flags + NULL, // Use parent's environment block + NULL, // Use parent's starting directory + &si, // Pointer to STARTUPINFO structure + &pi)) // Pointer to PROCESS_INFORMATION structure { std::cout << "Could not start server: " << GetLastError() << std::endl; return false; @@ -115,7 +116,8 @@ bool ServerStartCmd::Exec(const std::string& host, int port, std::string p = cortex_utils::GetCurrentPath() + "/" + exe; execl(p.c_str(), exe.c_str(), "--start-server", "--config_file_path", get_config_file_path().c_str(), "--data_folder_path", - get_data_folder_path().c_str(), "--loglevel", log_level_.c_str(), (char*)0); + get_data_folder_path().c_str(), "--loglevel", log_level_.c_str(), + (char*)0); } else { // Parent process if (!TryConnectToServer(host, port)) { diff --git a/engine/services/hardware_service.cc b/engine/services/hardware_service.cc index 02693a48d..72328f9b1 100644 --- a/engine/services/hardware_service.cc +++ b/engine/services/hardware_service.cc @@ -120,11 +120,12 @@ bool HardwareService::Restart(const std::string& host, int port) { params += " --data_folder_path " + get_data_folder_path(); params += " --loglevel " + luh::LogLevelStr(luh::global_log_level); std::string cmds = cortex_utils::GetCurrentPath() + "/" + exe + " " + params; + std::wstring w = std::wstring(cmds.begin(), cmds.end()); // Create child process if (!CreateProcess( NULL, // No module name (use command line) - const_cast( - cmds.c_str()), // Command line (replace with your actual executable) + const_cast( + w.c_str()), // Command line (replace with your actual executable) NULL, // Process handle not inheritable NULL, // Thread handle not inheritable TRUE, // Handle inheritance diff --git a/engine/utils/system_info_utils.h b/engine/utils/system_info_utils.h index 6183c3095..013069699 100644 --- a/engine/utils/system_info_utils.h +++ b/engine/utils/system_info_utils.h @@ -87,8 +87,8 @@ inline std::unique_ptr GetSystemInfo() { inline bool IsNvidiaSmiAvailable() { #ifdef _WIN32 // Check if nvidia-smi.exe exists in the PATH on Windows - char buffer[MAX_PATH]; - if (SearchPath(NULL, "nvidia-smi.exe", NULL, MAX_PATH, buffer, NULL) != 0) { + wchar_t buffer[MAX_PATH]; + if (SearchPath(NULL, L"nvidia-smi.exe", NULL, MAX_PATH, buffer, NULL) != 0) { return true; } else { return false; From 781236b02f1fc48f3d8b0ad2e982dee707ed53e0 Mon Sep 17 00:00:00 2001 From: vansangpfiev Date: Wed, 27 Nov 2024 12:14:44 +0700 Subject: [PATCH 02/21] fix: uft8 for cli --- engine/cli/commands/server_start_cmd.cc | 12 +++++++++--- engine/services/hardware_service.cc | 10 +++++++--- engine/utils/cortex_utils.h | 15 ++++++--------- 3 files changed, 22 insertions(+), 15 deletions(-) diff --git a/engine/cli/commands/server_start_cmd.cc b/engine/cli/commands/server_start_cmd.cc index 6f4c9627d..5eefcb4c7 100644 --- a/engine/cli/commands/server_start_cmd.cc +++ b/engine/cli/commands/server_start_cmd.cc @@ -3,6 +3,10 @@ #include "utils/cortex_utils.h" #include "utils/file_manager_utils.h" +#if defined(_WIN32) || defined(_WIN64) +#include +#include +#endif namespace commands { namespace { @@ -62,12 +66,14 @@ bool ServerStartCmd::Exec(const std::string& host, int port, params += " --data_folder_path " + get_data_folder_path(); params += " --loglevel " + log_level_; std::string cmds = cortex_utils::GetCurrentPath() + "/" + exe + " " + params; - std::wstring w = std::wstring(cmds.begin(), cmds.end()); + std::wstring_convert> converter; + std::wstring wcmds = converter.from_bytes(cmds); + std::vector mutable_cmds(wcmds.begin(), wcmds.end()); + mutable_cmds.push_back(L'\0'); // Create child process if (!CreateProcess( NULL, // No module name (use command line) - const_cast( - w.c_str()), // Command line (replace with your actual executable) + mutable_cmds.data(), // Command line (replace with your actual executable) NULL, // Process handle not inheritable NULL, // Thread handle not inheritable TRUE, // Set handle inheritance diff --git a/engine/services/hardware_service.cc b/engine/services/hardware_service.cc index 72328f9b1..843636c66 100644 --- a/engine/services/hardware_service.cc +++ b/engine/services/hardware_service.cc @@ -5,6 +5,8 @@ #if defined(_WIN32) || defined(_WIN64) #include #include +#include +#include #endif #include "cli/commands/cortex_upd_cmd.h" #include "database/hardware.h" @@ -120,12 +122,14 @@ bool HardwareService::Restart(const std::string& host, int port) { params += " --data_folder_path " + get_data_folder_path(); params += " --loglevel " + luh::LogLevelStr(luh::global_log_level); std::string cmds = cortex_utils::GetCurrentPath() + "/" + exe + " " + params; - std::wstring w = std::wstring(cmds.begin(), cmds.end()); + std::wstring_convert> converter; + std::wstring wcmds = converter.from_bytes(cmds); + std::vector mutable_cmds(wcmds.begin(), wcmds.end()); + mutable_cmds.push_back(L'\0'); // Create child process if (!CreateProcess( NULL, // No module name (use command line) - const_cast( - w.c_str()), // Command line (replace with your actual executable) + mutable_cmds.data(), // Command line (replace with your actual executable) NULL, // Process handle not inheritable NULL, // Thread handle not inheritable TRUE, // Handle inheritance diff --git a/engine/utils/cortex_utils.h b/engine/utils/cortex_utils.h index 50c927365..014dc6d9c 100644 --- a/engine/utils/cortex_utils.h +++ b/engine/utils/cortex_utils.h @@ -65,18 +65,15 @@ inline drogon::HttpResponsePtr CreateCortexStreamResponse( #if defined(_WIN32) inline std::string GetCurrentPath() { - wchar_t path[MAX_PATH]; - DWORD result = GetModuleFileNameW(NULL, path, MAX_PATH); + char path[MAX_PATH]; + DWORD result = GetModuleFileNameA(NULL, path, MAX_PATH); if (result == 0) { - std::wcerr << L"Error getting module file name." << std::endl; + std::cerr << "Error getting module file name." << std::endl; return ""; } - std::wstring::size_type pos = std::wstring(path).find_last_of(L"\\/"); - auto ws = std::wstring(path).substr(0, pos); - std::string res; - std::transform(ws.begin(), ws.end(), std::back_inserter(res), - [](wchar_t c) { return (char)c; }); - return res; + + std::string::size_type pos = std::string(path).find_last_of("\\/"); + return std::string(path).substr(0, pos); } #else inline std::string GetCurrentPath() { From b3d5fd0d77f7f35b0e753d5e4068ba7a6b016aa4 Mon Sep 17 00:00:00 2001 From: vansangpfiev Date: Wed, 27 Nov 2024 12:27:18 +0700 Subject: [PATCH 03/21] fix: codecvt_utf8_utf16 is deprecated --- engine/cli/commands/server_start_cmd.cc | 7 +------ engine/services/hardware_service.cc | 5 +---- engine/utils/cortex_utils.h | 26 ++++++++++++++++++++++++- 3 files changed, 27 insertions(+), 11 deletions(-) diff --git a/engine/cli/commands/server_start_cmd.cc b/engine/cli/commands/server_start_cmd.cc index 5eefcb4c7..dac29b8dc 100644 --- a/engine/cli/commands/server_start_cmd.cc +++ b/engine/cli/commands/server_start_cmd.cc @@ -3,10 +3,6 @@ #include "utils/cortex_utils.h" #include "utils/file_manager_utils.h" -#if defined(_WIN32) || defined(_WIN64) -#include -#include -#endif namespace commands { namespace { @@ -66,8 +62,7 @@ bool ServerStartCmd::Exec(const std::string& host, int port, params += " --data_folder_path " + get_data_folder_path(); params += " --loglevel " + log_level_; std::string cmds = cortex_utils::GetCurrentPath() + "/" + exe + " " + params; - std::wstring_convert> converter; - std::wstring wcmds = converter.from_bytes(cmds); + std::wstring wcmds = cortex_utils::UTF8ToUTF16(cmds); std::vector mutable_cmds(wcmds.begin(), wcmds.end()); mutable_cmds.push_back(L'\0'); // Create child process diff --git a/engine/services/hardware_service.cc b/engine/services/hardware_service.cc index 843636c66..0c89698bc 100644 --- a/engine/services/hardware_service.cc +++ b/engine/services/hardware_service.cc @@ -5,8 +5,6 @@ #if defined(_WIN32) || defined(_WIN64) #include #include -#include -#include #endif #include "cli/commands/cortex_upd_cmd.h" #include "database/hardware.h" @@ -122,8 +120,7 @@ bool HardwareService::Restart(const std::string& host, int port) { params += " --data_folder_path " + get_data_folder_path(); params += " --loglevel " + luh::LogLevelStr(luh::global_log_level); std::string cmds = cortex_utils::GetCurrentPath() + "/" + exe + " " + params; - std::wstring_convert> converter; - std::wstring wcmds = converter.from_bytes(cmds); + std::wstring wcmds = cortex_utils::UTF8ToUTF16(cmds); std::vector mutable_cmds(wcmds.begin(), wcmds.end()); mutable_cmds.push_back(L'\0'); // Create child process diff --git a/engine/utils/cortex_utils.h b/engine/utils/cortex_utils.h index 014dc6d9c..31387c3fd 100644 --- a/engine/utils/cortex_utils.h +++ b/engine/utils/cortex_utils.h @@ -17,10 +17,14 @@ #include #endif -#if __APPLE__ +#if defined(__APPLE__) #include #endif +#if defined(_WIN32) +#include +#endif + namespace cortex_utils { inline std::string logs_folder = "./logs"; inline std::string logs_base_name = "./logs/cortex.log"; @@ -64,6 +68,26 @@ inline drogon::HttpResponsePtr CreateCortexStreamResponse( } #if defined(_WIN32) + +inline std::wstring UTF8ToUTF16(const std::string& utf8) { + if (utf8.empty()) { + return std::wstring(); + } + + // First, get the size of the output buffer + int size_needed = + MultiByteToWideChar(CP_UTF8, 0, &utf8[0], (int)utf8.size(), NULL, 0); + + // Allocate the output buffer + std::wstring utf16(size_needed, 0); + + // Do the actual conversion + MultiByteToWideChar(CP_UTF8, 0, &utf8[0], (int)utf8.size(), &utf16[0], + size_needed); + + return utf16; +} + inline std::string GetCurrentPath() { char path[MAX_PATH]; DWORD result = GetModuleFileNameA(NULL, path, MAX_PATH); From e57ec06197fc80cf9c526fcb3b36f21ba6ec8d0d Mon Sep 17 00:00:00 2001 From: vansangpfiev Date: Wed, 27 Nov 2024 14:25:47 +0700 Subject: [PATCH 04/21] fix: more --- engine/services/engine_service.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/engine/services/engine_service.cc b/engine/services/engine_service.cc index 40356f163..f129b1875 100644 --- a/engine/services/engine_service.cc +++ b/engine/services/engine_service.cc @@ -13,6 +13,7 @@ #include "utils/semantic_version_utils.h" #include "utils/system_info_utils.h" #include "utils/url_parser.h" +#include "utils/cortex_utils.h" namespace { std::string GetSuitableCudaVersion(const std::string& engine, @@ -702,7 +703,7 @@ cpp::result EngineService::LoadEngine( // 3. Add dll directory if met other conditions auto add_dll = [this](const std::string& e_type, const std::string& p) { - auto ws = std::wstring(p.begin(), p.end()); + auto ws = cortex_utils::UTF8ToUTF16(p); if (auto cookie = AddDllDirectory(ws.c_str()); cookie != 0) { CTL_DBG("Added dll directory: " << p); engines_[e_type].cookie = cookie; From 807db5786fdbf3cab95a908f82e6290b375391df Mon Sep 17 00:00:00 2001 From: vansangpfiev Date: Thu, 28 Nov 2024 09:11:10 +0700 Subject: [PATCH 05/21] feat: support wstring string conversion --- engine/cli/main.cc | 19 +++++-- engine/database/database.h | 2 +- engine/main.cc | 69 +++++++++++++++++++------- engine/migrations/migration_helper.cc | 10 ++-- engine/migrations/migration_helper.h | 7 ++- engine/migrations/migration_manager.cc | 12 ++--- engine/services/engine_service.cc | 9 ++-- engine/services/model_service.cc | 9 ++-- engine/utils/cortex_utils.h | 14 ++++++ engine/utils/file_manager_utils.h | 18 +++++-- 10 files changed, 119 insertions(+), 50 deletions(-) diff --git a/engine/cli/main.cc b/engine/cli/main.cc index 49cdf4be9..417d7b86f 100644 --- a/engine/cli/main.cc +++ b/engine/cli/main.cc @@ -25,6 +25,9 @@ #error "Unsupported platform!" #endif +#include +#include + void RemoveBinaryTempFileIfExists() { auto temp = file_manager_utils::GetExecutableFolderContainerPath() / "cortex_temp"; @@ -40,11 +43,20 @@ void RemoveBinaryTempFileIfExists() { void SetupLogger(trantor::FileLogger& async_logger, bool verbose) { if (!verbose) { auto config = file_manager_utils::GetCortexConfig(); + std::filesystem::create_directories( +#if defined(_WIN32) + std::filesystem::u8path(config.logFolderPath) / +#else std::filesystem::path(config.logFolderPath) / +#endif std::filesystem::path(cortex_utils::logs_folder)); - async_logger.setFileName(config.logFolderPath + "/" + - cortex_utils::logs_cli_base_name); + + // Do not need to use u8path here because trantor handles itself + async_logger.setFileName( + (std::filesystem::path(config.logFolderPath) / + std::filesystem::path(cortex_utils::logs_cli_base_name)) + .string()); async_logger.setMaxLines(config.maxLogLines); // Keep last 100000 lines async_logger.startLogging(); trantor::Logger::setOutputFunction( @@ -192,8 +204,7 @@ int main(int argc, char* argv[]) { // Check if server exists, if not notify to user to install server auto exe = commands::GetCortexServerBinary(); auto server_binary_path = - std::filesystem::path(cortex_utils::GetCurrentPath()) / - std::filesystem::path(exe); + std::filesystem::u8path(cortex_utils::GetCurrentPath()) / exe; if (!std::filesystem::exists(server_binary_path)) { std::cout << CORTEX_CPP_VERSION << " requires server binary, to install server, run: " diff --git a/engine/database/database.h b/engine/database/database.h index 27c75e923..dbe58cc4b 100644 --- a/engine/database/database.h +++ b/engine/database/database.h @@ -20,7 +20,7 @@ class Database { private: Database() - : db_(file_manager_utils::GetCortexDataPath().string() + "/cortex.db", + : db_(file_manager_utils::GetCortexDataPath() / "cortex.db", SQLite::OPEN_READWRITE | SQLite::OPEN_CREATE) {} SQLite::Database db_; }; diff --git a/engine/main.cc b/engine/main.cc index afce8f3d3..175ff0872 100644 --- a/engine/main.cc +++ b/engine/main.cc @@ -66,7 +66,11 @@ void RunServer(std::optional port, bool ignore_cout) { } // Create logs/ folder and setup log to file std::filesystem::create_directories( +#if defined(_WIN32) + std::filesystem::u8path(config.logFolderPath) / +#else std::filesystem::path(config.logFolderPath) / +#endif std::filesystem::path(cortex_utils::logs_folder)); static trantor::FileLogger asyncFileLogger; asyncFileLogger.setFileName( @@ -200,7 +204,11 @@ void RunServer(std::optional port, bool ignore_cout) { } } +#if defined(_WIN32) +int main(int argc, wchar_t* argv[]) { +#else int main(int argc, char* argv[]) { +#endif // Stop the program if the system is not supported auto system_info = system_info_utils::GetSystemInfo(); if (system_info->arch == system_info_utils::kUnsupported || @@ -224,6 +232,28 @@ int main(int argc, char* argv[]) { std::optional server_port; bool ignore_cout_log = false; +#if defined(_WIN32) + for (int i = 0; i < argc; i++) { + std::wstring command = argv[i]; + if (command == L"--config_file_path") { + std::wstring v = argv[i + 1]; + file_manager_utils::cortex_config_file_path = + cortex_utils::WstringToUtf8(v); + } else if (command == L"--data_folder_path") { + std::wstring v = argv[i + 1]; + file_manager_utils::cortex_data_folder_path = + cortex_utils::WstringToUtf8(v); + } else if (command == L"--port") { + server_port = std::stoi(argv[i + 1]); + } else if (command == L"--ignore_cout") { + ignore_cout_log = true; + } else if (command == L"--loglevel") { + std::wstring v = argv[i + 1]; + std::string log_level = cortex_utils::WstringToUtf8(v); + logging_utils_helper::SetLogLevel(log_level, ignore_cout_log); + } + } +#else for (int i = 0; i < argc; i++) { if (strcmp(argv[i], "--config_file_path") == 0) { file_manager_utils::cortex_config_file_path = argv[i + 1]; @@ -238,6 +268,7 @@ int main(int argc, char* argv[]) { logging_utils_helper::SetLogLevel(log_level, ignore_cout_log); } } +#endif { auto result = file_manager_utils::CreateConfigFileIfNotExist(); @@ -274,26 +305,26 @@ int main(int argc, char* argv[]) { } } - // Check if this process is for python execution - if (argc > 1) { - if (strcmp(argv[1], "--run_python_file") == 0) { - std::string py_home_path = (argc > 3) ? argv[3] : ""; - std::unique_ptr dl; - try { - std::string abs_path = - cortex_utils::GetCurrentPath() + kPythonRuntimeLibPath; - dl = std::make_unique(abs_path, "engine"); - } catch (const cortex_cpp::dylib::load_error& e) { - LOG_ERROR << "Could not load engine: " << e.what(); - return 1; - } + // // Check if this process is for python execution + // if (argc > 1) { + // if (strcmp(argv[1], "--run_python_file") == 0) { + // std::string py_home_path = (argc > 3) ? argv[3] : ""; + // std::unique_ptr dl; + // try { + // std::string abs_path = + // cortex_utils::GetCurrentPath() + kPythonRuntimeLibPath; + // dl = std::make_unique(abs_path, "engine"); + // } catch (const cortex_cpp::dylib::load_error& e) { + // LOG_ERROR << "Could not load engine: " << e.what(); + // return 1; + // } - auto func = dl->get_function("get_engine"); - auto e = func(); - e->ExecutePythonFile(argv[0], argv[2], py_home_path); - return 0; - } - } + // auto func = dl->get_function("get_engine"); + // auto e = func(); + // e->ExecutePythonFile(argv[0], argv[2], py_home_path); + // return 0; + // } + // } RunServer(server_port, ignore_cout_log); return 0; diff --git a/engine/migrations/migration_helper.cc b/engine/migrations/migration_helper.cc index afebae5aa..f2b39d77e 100644 --- a/engine/migrations/migration_helper.cc +++ b/engine/migrations/migration_helper.cc @@ -2,12 +2,13 @@ namespace cortex::migr { cpp::result MigrationHelper::BackupDatabase( - const std::string& src_db_path, const std::string& backup_db_path) { + const std::filesystem::path& src_db_path, + const std::string& backup_db_path) { try { SQLite::Database src_db(src_db_path, SQLite::OPEN_READONLY); sqlite3* backup_db; - if (sqlite3_open(backup_db_path.c_str(), &backup_db) != SQLITE_OK) { + if (sqlite3_open16(backup_db_path.c_str(), &backup_db) != SQLITE_OK) { throw std::runtime_error("Failed to open backup database"); } @@ -35,13 +36,14 @@ cpp::result MigrationHelper::BackupDatabase( } cpp::result MigrationHelper::RestoreDatabase( - const std::string& backup_db_path, const std::string& target_db_path) { + const std::string& backup_db_path, + const std::filesystem::path& target_db_path) { try { SQLite::Database target_db(target_db_path, SQLite::OPEN_READWRITE | SQLite::OPEN_CREATE); sqlite3* backup_db; - if (sqlite3_open(backup_db_path.c_str(), &backup_db) != SQLITE_OK) { + if (sqlite3_open16(backup_db_path.c_str(), &backup_db) != SQLITE_OK) { throw std::runtime_error("Failed to open backup database"); } diff --git a/engine/migrations/migration_helper.h b/engine/migrations/migration_helper.h index ff0ee5075..cdf7b8f55 100644 --- a/engine/migrations/migration_helper.h +++ b/engine/migrations/migration_helper.h @@ -2,6 +2,7 @@ #include #include +#include #include "utils/logging_utils.h" #include "utils/result.hpp" @@ -9,9 +10,11 @@ namespace cortex::migr { class MigrationHelper { public: cpp::result BackupDatabase( - const std::string& src_db_path, const std::string& backup_db_path); + const std::filesystem::path& src_db_path, + const std::string& backup_db_path); cpp::result RestoreDatabase( - const std::string& backup_db_path, const std::string& target_db_path); + const std::string& backup_db_path, + const std::filesystem::path& target_db_path); }; } // namespace cortex::migr diff --git a/engine/migrations/migration_manager.cc b/engine/migrations/migration_manager.cc index b2920722f..f4b4f8046 100644 --- a/engine/migrations/migration_manager.cc +++ b/engine/migrations/migration_manager.cc @@ -38,9 +38,9 @@ cpp::result MigrationManager::Migrate() { return true; // Back up all data before migrating if (std::filesystem::exists(fmu::GetCortexDataPath() / kCortexDb)) { - auto src_db_path = (fmu::GetCortexDataPath() / kCortexDb).string(); - auto backup_db_path = (fmu::GetCortexDataPath() / kCortexDbBackup).string(); - if (auto res = mgr_helper_.BackupDatabase(src_db_path, backup_db_path); + auto src_db_path = (fmu::GetCortexDataPath() / kCortexDb); + auto backup_db_path = (fmu::GetCortexDataPath() / kCortexDbBackup); + if (auto res = mgr_helper_.BackupDatabase(src_db_path, backup_db_path.string()); res.has_error()) { CTL_INF("Error: backup database failed!"); return res; @@ -60,9 +60,9 @@ cpp::result MigrationManager::Migrate() { }); auto restore_db = [this]() -> cpp::result { - auto src_db_path = (fmu::GetCortexDataPath() / kCortexDb).string(); - auto backup_db_path = (fmu::GetCortexDataPath() / kCortexDbBackup).string(); - return mgr_helper_.BackupDatabase(src_db_path, backup_db_path); + auto src_db_path = (fmu::GetCortexDataPath() / kCortexDb); + auto backup_db_path = (fmu::GetCortexDataPath() / kCortexDbBackup); + return mgr_helper_.BackupDatabase(src_db_path, backup_db_path.string()); }; // Backup folder structure diff --git a/engine/services/engine_service.cc b/engine/services/engine_service.cc index f129b1875..9f0f413db 100644 --- a/engine/services/engine_service.cc +++ b/engine/services/engine_service.cc @@ -702,9 +702,8 @@ cpp::result EngineService::LoadEngine( // Do nothing, llamacpp can re-use tensorrt-llm dependencies (need to be tested careful) // 3. Add dll directory if met other conditions - auto add_dll = [this](const std::string& e_type, const std::string& p) { - auto ws = cortex_utils::UTF8ToUTF16(p); - if (auto cookie = AddDllDirectory(ws.c_str()); cookie != 0) { + auto add_dll = [this](const std::string& e_type, const std::filesystem::path& p) { + if (auto cookie = AddDllDirectory(p.c_str()); cookie != 0) { CTL_DBG("Added dll directory: " << p); engines_[e_type].cookie = cookie; } else { @@ -737,11 +736,11 @@ cpp::result EngineService::LoadEngine( CTL_DBG("Removed cuda dll directory: " << kLlamaRepo); } - add_dll(ne, engine_dir_path.string()); + add_dll(ne, engine_dir_path); } else if (IsEngineLoaded(kTrtLlmRepo) && ne == kLlamaRepo) { // Do nothing } else { - add_dll(ne, engine_dir_path.string()); + add_dll(ne, engine_dir_path); } } #endif diff --git a/engine/services/model_service.cc b/engine/services/model_service.cc index d6e66a717..fdf4ad7e2 100644 --- a/engine/services/model_service.cc +++ b/engine/services/model_service.cc @@ -9,6 +9,7 @@ #include "hardware_service.h" #include "httplib.h" #include "utils/cli_selection_utils.h" +#include "utils/cortex_utils.h" #include "utils/engine_constants.h" #include "utils/file_manager_utils.h" #include "utils/huggingface_utils.h" @@ -458,7 +459,8 @@ ModelService::DownloadModelFromCortexsoAsync( return; } auto url_obj = url_parser::FromUrlString(model_yml_item->downloadUrl); - CTL_INF("Adding model to modellist with branch: " << branch); + CTL_INF("Adding model to modellist with branch: " + << branch << ", path: " << model_yml_item->localPath.string()); config::YamlHandler yaml_handler; yaml_handler.ModelConfigFromFile(model_yml_item->localPath.string()); auto mc = yaml_handler.GetModelConfig(); @@ -666,9 +668,8 @@ cpp::result ModelService::StartModel( json_data = mc.ToJson(); if (mc.files.size() > 0) { - // TODO(sang) support multiple files - json_data["model_path"] = - fmu::ToAbsoluteCortexDataPath(fs::path(mc.files[0])).string(); + json_data["model_path"] = cortex_utils::WstringToUtf8( + fmu::ToAbsoluteCortexDataPath(fs::path(mc.files[0])).wstring()); } else { LOG_WARN << "model_path is empty"; return StartModelResult{.success = false}; diff --git a/engine/utils/cortex_utils.h b/engine/utils/cortex_utils.h index 31387c3fd..2c2aa93f1 100644 --- a/engine/utils/cortex_utils.h +++ b/engine/utils/cortex_utils.h @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include @@ -23,6 +24,8 @@ #if defined(_WIN32) #include +#include +#include #endif namespace cortex_utils { @@ -67,7 +70,18 @@ inline drogon::HttpResponsePtr CreateCortexStreamResponse( return res; } + + #if defined(_WIN32) +inline std::string WstringToUtf8(const std::wstring& wstr) { + std::wstring_convert> converter; + return converter.to_bytes(wstr); +} + +inline std::wstring Utf8ToWstring(const std::string& str) { + std::wstring_convert> converter; + return converter.from_bytes(str); +} inline std::wstring UTF8ToUTF16(const std::string& utf8) { if (utf8.empty()) { diff --git a/engine/utils/file_manager_utils.h b/engine/utils/file_manager_utils.h index 399afcfa6..e0fb84a12 100644 --- a/engine/utils/file_manager_utils.h +++ b/engine/utils/file_manager_utils.h @@ -67,11 +67,11 @@ inline std::filesystem::path GetExecutableFolderContainerPath() { inline std::filesystem::path GetHomeDirectoryPath() { #ifdef _WIN32 - const char* homeDir = std::getenv("USERPROFILE"); + const wchar_t* homeDir = _wgetenv(L"USERPROFILE"); if (!homeDir) { // Fallback if USERPROFILE is not set - const char* homeDrive = std::getenv("HOMEDRIVE"); - const char* homePath = std::getenv("HOMEPATH"); + const wchar_t* homeDrive = _wgetenv(L"HOMEDRIVE"); + const wchar_t* homePath = _wgetenv(L"HOMEPATH"); if (homeDrive && homePath) { return std::filesystem::path(homeDrive) / std::filesystem::path(homePath); } else { @@ -103,8 +103,12 @@ inline std::filesystem::path GetConfigurationPath() { } if (config_file_path != kDefaultConfigurationPath) { - // CTL_INF("Config file path: " + config_file_path); +// CTL_INF("Config file path: " + config_file_path); +#if defined(_WIN32) + return std::filesystem::u8path(config_file_path); +#else return std::filesystem::path(config_file_path); +#endif } std::string variant{CORTEX_VARIANT}; @@ -220,7 +224,11 @@ inline std::filesystem::path GetCortexDataPath() { auto config = GetCortexConfig(); std::filesystem::path data_folder_path; if (!config.dataFolderPath.empty()) { +#if defined(_WIN32) + data_folder_path = std::filesystem::u8path(config.dataFolderPath); +#else data_folder_path = std::filesystem::path(config.dataFolderPath); +#endif } else { auto home_path = GetHomeDirectoryPath(); data_folder_path = home_path / kCortexFolderName; @@ -304,7 +312,7 @@ inline std::filesystem::path GetEnginesContainerPath() { if (!std::filesystem::exists(engines_container_path)) { CTL_INF("Engine container folder not found. Create one: " << engines_container_path.string()); - std::filesystem::create_directory(engines_container_path); + std::filesystem::create_directory(engines_container_path.string()); } return engines_container_path; From 0f26924b816225328fff0215bfe94b2a94fb6271 Mon Sep 17 00:00:00 2001 From: vansangpfiev Date: Thu, 28 Nov 2024 09:28:06 +0700 Subject: [PATCH 06/21] fix: build --- engine/services/model_service.cc | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/engine/services/model_service.cc b/engine/services/model_service.cc index fdf4ad7e2..e72e73948 100644 --- a/engine/services/model_service.cc +++ b/engine/services/model_service.cc @@ -668,8 +668,13 @@ cpp::result ModelService::StartModel( json_data = mc.ToJson(); if (mc.files.size() > 0) { +#if defined(_WIN32) json_data["model_path"] = cortex_utils::WstringToUtf8( fmu::ToAbsoluteCortexDataPath(fs::path(mc.files[0])).wstring()); +#else + json_data["model_path"] = + fmu::ToAbsoluteCortexDataPath(fs::path(mc.files[0])).string(); +#endif } else { LOG_WARN << "model_path is empty"; return StartModelResult{.success = false}; From ed659189d254443cb0421467028f38167aaa0a7a Mon Sep 17 00:00:00 2001 From: vansangpfiev Date: Thu, 28 Nov 2024 10:18:24 +0700 Subject: [PATCH 07/21] fix: engine path env --- engine/cli/commands/server_start_cmd.cc | 2 +- engine/services/engine_service.cc | 20 ++++++++++++++------ 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/engine/cli/commands/server_start_cmd.cc b/engine/cli/commands/server_start_cmd.cc index dac29b8dc..9f47fbb86 100644 --- a/engine/cli/commands/server_start_cmd.cc +++ b/engine/cli/commands/server_start_cmd.cc @@ -71,7 +71,7 @@ bool ServerStartCmd::Exec(const std::string& host, int port, mutable_cmds.data(), // Command line (replace with your actual executable) NULL, // Process handle not inheritable NULL, // Thread handle not inheritable - TRUE, // Set handle inheritance + FALSE, // Set handle inheritance 0, // No creation flags NULL, // Use parent's environment block NULL, // Use parent's starting directory diff --git a/engine/services/engine_service.cc b/engine/services/engine_service.cc index 9f0f413db..4eebff669 100644 --- a/engine/services/engine_service.cc +++ b/engine/services/engine_service.cc @@ -4,6 +4,7 @@ #include #include "algorithm" #include "utils/archive_utils.h" +#include "utils/cortex_utils.h" #include "utils/engine_constants.h" #include "utils/engine_matcher_utils.h" #include "utils/file_manager_utils.h" @@ -13,7 +14,6 @@ #include "utils/semantic_version_utils.h" #include "utils/system_info_utils.h" #include "utils/url_parser.h" -#include "utils/cortex_utils.h" namespace { std::string GetSuitableCudaVersion(const std::string& engine, @@ -665,14 +665,17 @@ cpp::result EngineService::LoadEngine( CTL_INF("Selected engine variant: " << json_helper::DumpJsonString(selected_engine_variant->ToJson())); - +#if defined(_WIN32) + auto user_defined_engine_path = _wgetenv(L"ENGINE_PATH"); +#else auto user_defined_engine_path = getenv("ENGINE_PATH"); +#endif + CTL_DBG("user defined engine path: " << user_defined_engine_path); const std::filesystem::path engine_dir_path = [&] { if (user_defined_engine_path != nullptr) { - return std::filesystem::path(user_defined_engine_path + - GetEnginePath(ne)) / - selected_engine_variant->variant / + return std::filesystem::path(user_defined_engine_path) / + GetEnginePath(ne) / selected_engine_variant->variant / selected_engine_variant->version; } else { return file_manager_utils::GetEnginesContainerPath() / ne / @@ -702,7 +705,8 @@ cpp::result EngineService::LoadEngine( // Do nothing, llamacpp can re-use tensorrt-llm dependencies (need to be tested careful) // 3. Add dll directory if met other conditions - auto add_dll = [this](const std::string& e_type, const std::filesystem::path& p) { + auto add_dll = [this](const std::string& e_type, + const std::filesystem::path& p) { if (auto cookie = AddDllDirectory(p.c_str()); cookie != 0) { CTL_DBG("Added dll directory: " << p); engines_[e_type].cookie = cookie; @@ -720,7 +724,11 @@ cpp::result EngineService::LoadEngine( } }; +#if defined(_WIN32) + if (bool should_use_dll_search_path = !(_wgetenv(L"ENGINE_PATH")); +#else if (bool should_use_dll_search_path = !(getenv("ENGINE_PATH")); +#endif should_use_dll_search_path) { if (IsEngineLoaded(kLlamaRepo) && ne == kTrtLlmRepo && should_use_dll_search_path) { From c3485816f2250de691c09c9b046676276a743eef Mon Sep 17 00:00:00 2001 From: vansangpfiev Date: Thu, 28 Nov 2024 11:58:21 +0700 Subject: [PATCH 08/21] fix: wstring --- engine/main.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/engine/main.cc b/engine/main.cc index 175ff0872..821257be4 100644 --- a/engine/main.cc +++ b/engine/main.cc @@ -205,7 +205,7 @@ void RunServer(std::optional port, bool ignore_cout) { } #if defined(_WIN32) -int main(int argc, wchar_t* argv[]) { +int wmain(int argc, wchar_t* argv[]) { #else int main(int argc, char* argv[]) { #endif From 140fb1abdd3f91a3043aad0bf3cc8ee086161e08 Mon Sep 17 00:00:00 2001 From: vansangpfiev Date: Thu, 28 Nov 2024 12:26:04 +0700 Subject: [PATCH 09/21] fix: cli start server --- engine/cli/commands/server_start_cmd.cc | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/engine/cli/commands/server_start_cmd.cc b/engine/cli/commands/server_start_cmd.cc index 9f47fbb86..574bb135c 100644 --- a/engine/cli/commands/server_start_cmd.cc +++ b/engine/cli/commands/server_start_cmd.cc @@ -57,12 +57,13 @@ bool ServerStartCmd::Exec(const std::string& host, int port, ZeroMemory(&si, sizeof(si)); si.cb = sizeof(si); ZeroMemory(&pi, sizeof(pi)); - std::string params = "--start-server"; - params += " --config_file_path " + get_config_file_path(); - params += " --data_folder_path " + get_data_folder_path(); - params += " --loglevel " + log_level_; - std::string cmds = cortex_utils::GetCurrentPath() + "/" + exe + " " + params; - std::wstring wcmds = cortex_utils::UTF8ToUTF16(cmds); + std::wstring params = L"--start-server"; + params += L" --config_file_path " + cortex_utils::UTF8ToUTF16(get_config_file_path()); + params += L" --data_folder_path " + file_manager_utils::GetCortexDataPath().wstring(); + params += L" --loglevel " + cortex_utils::UTF8ToUTF16(log_level_); + std::wstring exe_w = cortex_utils::UTF8ToUTF16(exe); + std::wstring current_path_w = cortex_utils::UTF8ToUTF16(cortex_utils::GetCurrentPath()); + std::wstring wcmds = current_path_w + L"/" + exe_w + L" " + params; std::vector mutable_cmds(wcmds.begin(), wcmds.end()); mutable_cmds.push_back(L'\0'); // Create child process From ee5ee3508b8e4ca66d93f3a9c5236105bcab2001 Mon Sep 17 00:00:00 2001 From: vansangpfiev Date: Thu, 28 Nov 2024 14:35:12 +0700 Subject: [PATCH 10/21] fix: utf8 file --- engine/cli/commands/server_start_cmd.cc | 29 +++++++++++-------- engine/cli/main.cc | 2 +- engine/services/hardware_service.cc | 37 +++++++++++++++---------- engine/utils/config_yaml_utils.h | 3 ++ engine/utils/file_manager_utils.h | 26 +++++++++++++++-- 5 files changed, 67 insertions(+), 30 deletions(-) diff --git a/engine/cli/commands/server_start_cmd.cc b/engine/cli/commands/server_start_cmd.cc index 574bb135c..0025e1edf 100644 --- a/engine/cli/commands/server_start_cmd.cc +++ b/engine/cli/commands/server_start_cmd.cc @@ -58,26 +58,31 @@ bool ServerStartCmd::Exec(const std::string& host, int port, si.cb = sizeof(si); ZeroMemory(&pi, sizeof(pi)); std::wstring params = L"--start-server"; - params += L" --config_file_path " + cortex_utils::UTF8ToUTF16(get_config_file_path()); - params += L" --data_folder_path " + file_manager_utils::GetCortexDataPath().wstring(); + params += L" --config_file_path " + + file_manager_utils::GetConfigurationPath().wstring(); + params += L" --data_folder_path " + + file_manager_utils::GetCortexDataPath().wstring(); params += L" --loglevel " + cortex_utils::UTF8ToUTF16(log_level_); std::wstring exe_w = cortex_utils::UTF8ToUTF16(exe); - std::wstring current_path_w = cortex_utils::UTF8ToUTF16(cortex_utils::GetCurrentPath()); + std::wstring current_path_w = + file_manager_utils::GetExecutableFolderContainerPath().wstring(); std::wstring wcmds = current_path_w + L"/" + exe_w + L" " + params; + CTL_DBG("wcmds: " << wcmds); std::vector mutable_cmds(wcmds.begin(), wcmds.end()); mutable_cmds.push_back(L'\0'); // Create child process if (!CreateProcess( NULL, // No module name (use command line) - mutable_cmds.data(), // Command line (replace with your actual executable) - NULL, // Process handle not inheritable - NULL, // Thread handle not inheritable - FALSE, // Set handle inheritance - 0, // No creation flags - NULL, // Use parent's environment block - NULL, // Use parent's starting directory - &si, // Pointer to STARTUPINFO structure - &pi)) // Pointer to PROCESS_INFORMATION structure + mutable_cmds + .data(), // Command line (replace with your actual executable) + NULL, // Process handle not inheritable + NULL, // Thread handle not inheritable + FALSE, // Set handle inheritance + 0, // No creation flags + NULL, // Use parent's environment block + NULL, // Use parent's starting directory + &si, // Pointer to STARTUPINFO structure + &pi)) // Pointer to PROCESS_INFORMATION structure { std::cout << "Could not start server: " << GetLastError() << std::endl; return false; diff --git a/engine/cli/main.cc b/engine/cli/main.cc index 417d7b86f..a03c5adf0 100644 --- a/engine/cli/main.cc +++ b/engine/cli/main.cc @@ -204,7 +204,7 @@ int main(int argc, char* argv[]) { // Check if server exists, if not notify to user to install server auto exe = commands::GetCortexServerBinary(); auto server_binary_path = - std::filesystem::u8path(cortex_utils::GetCurrentPath()) / exe; + file_manager_utils::GetExecutableFolderContainerPath() / exe; if (!std::filesystem::exists(server_binary_path)) { std::cout << CORTEX_CPP_VERSION << " requires server binary, to install server, run: " diff --git a/engine/services/hardware_service.cc b/engine/services/hardware_service.cc index 0c89698bc..9eaf580dc 100644 --- a/engine/services/hardware_service.cc +++ b/engine/services/hardware_service.cc @@ -115,26 +115,33 @@ bool HardwareService::Restart(const std::string& host, int port) { ZeroMemory(&si, sizeof(si)); si.cb = sizeof(si); ZeroMemory(&pi, sizeof(pi)); - std::string params = "--ignore_cout"; - params += " --config_file_path " + get_config_file_path(); - params += " --data_folder_path " + get_data_folder_path(); - params += " --loglevel " + luh::LogLevelStr(luh::global_log_level); - std::string cmds = cortex_utils::GetCurrentPath() + "/" + exe + " " + params; - std::wstring wcmds = cortex_utils::UTF8ToUTF16(cmds); + // TODO (sang) write a common function for this and server_start_cmd + std::wstring params = L"--ignore_cout"; + params += L" --config_file_path " + + file_manager_utils::GetConfigurationPath().wstring(); + params += L" --data_folder_path " + + file_manager_utils::GetCortexDataPath().wstring(); + params += L" --loglevel " + + cortex_utils::UTF8ToUTF16(luh::LogLevelStr(luh::global_log_level)); + std::wstring exe_w = cortex_utils::UTF8ToUTF16(exe); + std::wstring current_path_w = + file_manager_utils::GetExecutableFolderContainerPath().wstring(); + std::wstring wcmds = current_path_w + L"/" + exe_w + L" " + params; std::vector mutable_cmds(wcmds.begin(), wcmds.end()); mutable_cmds.push_back(L'\0'); // Create child process if (!CreateProcess( NULL, // No module name (use command line) - mutable_cmds.data(), // Command line (replace with your actual executable) - NULL, // Process handle not inheritable - NULL, // Thread handle not inheritable - TRUE, // Handle inheritance - 0, // No creation flags - NULL, // Use parent's environment block - NULL, // Use parent's starting directory - &si, // Pointer to STARTUPINFO structure - &pi)) // Pointer to PROCESS_INFORMATION structure + mutable_cmds + .data(), // Command line (replace with your actual executable) + NULL, // Process handle not inheritable + NULL, // Thread handle not inheritable + TRUE, // Handle inheritance + 0, // No creation flags + NULL, // Use parent's environment block + NULL, // Use parent's starting directory + &si, // Pointer to STARTUPINFO structure + &pi)) // Pointer to PROCESS_INFORMATION structure { std::cout << "Could not start server: " << GetLastError() << std::endl; return false; diff --git a/engine/utils/config_yaml_utils.h b/engine/utils/config_yaml_utils.h index 187e1b4ef..3176339a0 100644 --- a/engine/utils/config_yaml_utils.h +++ b/engine/utils/config_yaml_utils.h @@ -86,6 +86,9 @@ class CortexConfigMgr { if (!out_file) { throw std::runtime_error("Failed to open output file."); } + // Workaround to save file as utf8 BOM + const unsigned char utf8_bom[] = {0xEF, 0xBB, 0xBF}; + out_file.write(reinterpret_cast(utf8_bom), sizeof(utf8_bom)); YAML::Node node; node["logFolderPath"] = config.logFolderPath; node["logLlamaCppPath"] = config.logLlamaCppPath; diff --git a/engine/utils/file_manager_utils.h b/engine/utils/file_manager_utils.h index e0fb84a12..1c91487a0 100644 --- a/engine/utils/file_manager_utils.h +++ b/engine/utils/file_manager_utils.h @@ -14,6 +14,8 @@ #include #elif defined(_WIN32) #include +#include +#include #endif namespace file_manager_utils { @@ -55,8 +57,8 @@ inline std::filesystem::path GetExecutableFolderContainerPath() { return std::filesystem::current_path(); } #elif defined(_WIN32) - char buffer[MAX_PATH]; - GetModuleFileNameA(NULL, buffer, MAX_PATH); + wchar_t buffer[MAX_PATH]; + GetModuleFileNameW(NULL, buffer, MAX_PATH); // CTL_DBG("Executable path: " << buffer); return std::filesystem::path{buffer}.parent_path(); #else @@ -156,6 +158,18 @@ inline cpp::result UpdateCortexConfig( config, config_path.string()); } +#if defined(_WIN32) +inline std::string WstringToUtf8(const std::wstring& wstr) { + std::wstring_convert> converter; + return converter.to_bytes(wstr); +} + +inline std::wstring Utf8ToWstring(const std::string& str) { + std::wstring_convert> converter; + return converter.from_bytes(str); +} +#endif + inline config_yaml_utils::CortexConfig GetDefaultConfig() { auto config_path = GetConfigurationPath(); auto default_data_folder_name = GetDefaultDataFolderName(); @@ -166,11 +180,19 @@ inline config_yaml_utils::CortexConfig GetDefaultConfig() { : std::filesystem::path(cortex_data_folder_path); return config_yaml_utils::CortexConfig{ +#if defined(_WIN32) + .logFolderPath = WstringToUtf8(default_data_folder_path.wstring()), +#else .logFolderPath = default_data_folder_path.string(), +#endif .logLlamaCppPath = kLogsLlamacppBaseName, .logTensorrtLLMPath = kLogsTensorrtllmBaseName, .logOnnxPath = kLogsOnnxBaseName, +#if defined(_WIN32) + .dataFolderPath = WstringToUtf8(default_data_folder_path.wstring()), +#else .dataFolderPath = default_data_folder_path.string(), +#endif .maxLogLines = config_yaml_utils::kDefaultMaxLines, .apiServerHost = config_yaml_utils::kDefaultHost, .apiServerPort = config_yaml_utils::kDefaultPort, From 761f3c0df7202239fc9871380a1248dd1b126ff5 Mon Sep 17 00:00:00 2001 From: vansangpfiev Date: Thu, 28 Nov 2024 16:17:10 +0700 Subject: [PATCH 11/21] fix: get env --- engine/cli/commands/server_start_cmd.cc | 5 ++- engine/main.cc | 7 ++-- engine/services/hardware_service.cc | 5 ++- engine/services/model_service.cc | 3 +- engine/utils/cortex_utils.h | 29 --------------- engine/utils/engine_constants.h | 2 +- engine/utils/file_manager_utils.h | 19 +++------- engine/utils/widechar_conv.h | 49 +++++++++++++++++++++++++ 8 files changed, 67 insertions(+), 52 deletions(-) create mode 100644 engine/utils/widechar_conv.h diff --git a/engine/cli/commands/server_start_cmd.cc b/engine/cli/commands/server_start_cmd.cc index 0025e1edf..5ba972463 100644 --- a/engine/cli/commands/server_start_cmd.cc +++ b/engine/cli/commands/server_start_cmd.cc @@ -2,6 +2,7 @@ #include "commands/cortex_upd_cmd.h" #include "utils/cortex_utils.h" #include "utils/file_manager_utils.h" +#include "utils/widechar_conv.h" namespace commands { @@ -62,8 +63,8 @@ bool ServerStartCmd::Exec(const std::string& host, int port, file_manager_utils::GetConfigurationPath().wstring(); params += L" --data_folder_path " + file_manager_utils::GetCortexDataPath().wstring(); - params += L" --loglevel " + cortex_utils::UTF8ToUTF16(log_level_); - std::wstring exe_w = cortex_utils::UTF8ToUTF16(exe); + params += L" --loglevel " + cortex::wc::Utf8ToWstring(log_level_); + std::wstring exe_w = cortex::wc::Utf8ToWstring(exe); std::wstring current_path_w = file_manager_utils::GetExecutableFolderContainerPath().wstring(); std::wstring wcmds = current_path_w + L"/" + exe_w + L" " + params; diff --git a/engine/main.cc b/engine/main.cc index 821257be4..d653efda5 100644 --- a/engine/main.cc +++ b/engine/main.cc @@ -22,6 +22,7 @@ #include "utils/file_manager_utils.h" #include "utils/logging_utils.h" #include "utils/system_info_utils.h" +#include "utils/widechar_conv.h" #if defined(__APPLE__) && defined(__MACH__) #include // for dirname() @@ -238,18 +239,18 @@ int main(int argc, char* argv[]) { if (command == L"--config_file_path") { std::wstring v = argv[i + 1]; file_manager_utils::cortex_config_file_path = - cortex_utils::WstringToUtf8(v); + cortex::wc::WstringToUtf8(v); } else if (command == L"--data_folder_path") { std::wstring v = argv[i + 1]; file_manager_utils::cortex_data_folder_path = - cortex_utils::WstringToUtf8(v); + cortex::wc::WstringToUtf8(v); } else if (command == L"--port") { server_port = std::stoi(argv[i + 1]); } else if (command == L"--ignore_cout") { ignore_cout_log = true; } else if (command == L"--loglevel") { std::wstring v = argv[i + 1]; - std::string log_level = cortex_utils::WstringToUtf8(v); + std::string log_level = cortex::wc::WstringToUtf8(v); logging_utils_helper::SetLogLevel(log_level, ignore_cout_log); } } diff --git a/engine/services/hardware_service.cc b/engine/services/hardware_service.cc index 9eaf580dc..16ae234b4 100644 --- a/engine/services/hardware_service.cc +++ b/engine/services/hardware_service.cc @@ -10,6 +10,7 @@ #include "database/hardware.h" #include "services/engine_service.h" #include "utils/cortex_utils.h" +#include "utils/widechar_conv.h" namespace services { @@ -122,8 +123,8 @@ bool HardwareService::Restart(const std::string& host, int port) { params += L" --data_folder_path " + file_manager_utils::GetCortexDataPath().wstring(); params += L" --loglevel " + - cortex_utils::UTF8ToUTF16(luh::LogLevelStr(luh::global_log_level)); - std::wstring exe_w = cortex_utils::UTF8ToUTF16(exe); + cortex::wc::Utf8ToWstring(luh::LogLevelStr(luh::global_log_level)); + std::wstring exe_w = cortex::wc::Utf8ToWstring(exe); std::wstring current_path_w = file_manager_utils::GetExecutableFolderContainerPath().wstring(); std::wstring wcmds = current_path_w + L"/" + exe_w + L" " + params; diff --git a/engine/services/model_service.cc b/engine/services/model_service.cc index e72e73948..1ec1a68cf 100644 --- a/engine/services/model_service.cc +++ b/engine/services/model_service.cc @@ -16,6 +16,7 @@ #include "utils/logging_utils.h" #include "utils/result.hpp" #include "utils/string_utils.h" +#include "utils/widechar_conv.h" namespace { void ParseGguf(const DownloadItem& ggufDownloadItem, @@ -669,7 +670,7 @@ cpp::result ModelService::StartModel( json_data = mc.ToJson(); if (mc.files.size() > 0) { #if defined(_WIN32) - json_data["model_path"] = cortex_utils::WstringToUtf8( + json_data["model_path"] = cortex::wc::WstringToUtf8( fmu::ToAbsoluteCortexDataPath(fs::path(mc.files[0])).wstring()); #else json_data["model_path"] = diff --git a/engine/utils/cortex_utils.h b/engine/utils/cortex_utils.h index 2c2aa93f1..b2ac2a346 100644 --- a/engine/utils/cortex_utils.h +++ b/engine/utils/cortex_utils.h @@ -73,35 +73,6 @@ inline drogon::HttpResponsePtr CreateCortexStreamResponse( #if defined(_WIN32) -inline std::string WstringToUtf8(const std::wstring& wstr) { - std::wstring_convert> converter; - return converter.to_bytes(wstr); -} - -inline std::wstring Utf8ToWstring(const std::string& str) { - std::wstring_convert> converter; - return converter.from_bytes(str); -} - -inline std::wstring UTF8ToUTF16(const std::string& utf8) { - if (utf8.empty()) { - return std::wstring(); - } - - // First, get the size of the output buffer - int size_needed = - MultiByteToWideChar(CP_UTF8, 0, &utf8[0], (int)utf8.size(), NULL, 0); - - // Allocate the output buffer - std::wstring utf16(size_needed, 0); - - // Do the actual conversion - MultiByteToWideChar(CP_UTF8, 0, &utf8[0], (int)utf8.size(), &utf16[0], - size_needed); - - return utf16; -} - inline std::string GetCurrentPath() { char path[MAX_PATH]; DWORD result = GetModuleFileNameA(NULL, path, MAX_PATH); diff --git a/engine/utils/engine_constants.h b/engine/utils/engine_constants.h index c63a58ab9..5dab49936 100644 --- a/engine/utils/engine_constants.h +++ b/engine/utils/engine_constants.h @@ -9,7 +9,7 @@ constexpr const auto kLlamaRepo = "cortex.llamacpp"; constexpr const auto kTrtLlmRepo = "cortex.tensorrt-llm"; constexpr const auto kPythonRuntimeRepo = "cortex.python"; -constexpr const auto kLlamaLibPath = "/engines/cortex.llamacpp"; +constexpr const auto kLlamaLibPath = "./engines/cortex.llamacpp"; constexpr const auto kPythonRuntimeLibPath = "/engines/cortex.python"; constexpr const auto kOnnxLibPath = "/engines/cortex.onnx"; constexpr const auto kTensorrtLlmPath = "/engines/cortex.tensorrt-llm"; diff --git a/engine/utils/file_manager_utils.h b/engine/utils/file_manager_utils.h index 1c91487a0..554e225dc 100644 --- a/engine/utils/file_manager_utils.h +++ b/engine/utils/file_manager_utils.h @@ -7,6 +7,7 @@ #include "utils/config_yaml_utils.h" #include "utils/engine_constants.h" #include "utils/result.hpp" +#include "utils/widechar_conv.h" #if defined(__APPLE__) && defined(__MACH__) #include @@ -158,18 +159,6 @@ inline cpp::result UpdateCortexConfig( config, config_path.string()); } -#if defined(_WIN32) -inline std::string WstringToUtf8(const std::wstring& wstr) { - std::wstring_convert> converter; - return converter.to_bytes(wstr); -} - -inline std::wstring Utf8ToWstring(const std::string& str) { - std::wstring_convert> converter; - return converter.from_bytes(str); -} -#endif - inline config_yaml_utils::CortexConfig GetDefaultConfig() { auto config_path = GetConfigurationPath(); auto default_data_folder_name = GetDefaultDataFolderName(); @@ -181,7 +170,8 @@ inline config_yaml_utils::CortexConfig GetDefaultConfig() { return config_yaml_utils::CortexConfig{ #if defined(_WIN32) - .logFolderPath = WstringToUtf8(default_data_folder_path.wstring()), + .logFolderPath = + cortex::wc::WstringToUtf8(default_data_folder_path.wstring()), #else .logFolderPath = default_data_folder_path.string(), #endif @@ -189,7 +179,8 @@ inline config_yaml_utils::CortexConfig GetDefaultConfig() { .logTensorrtLLMPath = kLogsTensorrtllmBaseName, .logOnnxPath = kLogsOnnxBaseName, #if defined(_WIN32) - .dataFolderPath = WstringToUtf8(default_data_folder_path.wstring()), + .dataFolderPath = + cortex::wc::WstringToUtf8(default_data_folder_path.wstring()), #else .dataFolderPath = default_data_folder_path.string(), #endif diff --git a/engine/utils/widechar_conv.h b/engine/utils/widechar_conv.h new file mode 100644 index 000000000..e979be3c1 --- /dev/null +++ b/engine/utils/widechar_conv.h @@ -0,0 +1,49 @@ +#pragma once + +#if defined(_WIN32) +#include +#include + +namespace cortex::wc { + +inline std::string WstringToUtf8(const std::wstring& wstr) { + if (wstr.empty()) { + return std::string(); + } + + int size_needed = WideCharToMultiByte(CP_UTF8, 0, wstr.data(), (int)wstr.size(), NULL, 0, NULL, NULL); + if (size_needed <= 0) { + throw std::runtime_error("WideCharToMultiByte() failed: " + std::to_string(GetLastError())); + } + + std::string result(size_needed, 0); + int bytes_written = WideCharToMultiByte(CP_UTF8, 0, wstr.data(), (int)wstr.size(), &result[0], size_needed, NULL, NULL); + if (bytes_written <= 0) { + throw std::runtime_error("WideCharToMultiByte() failed: " + std::to_string(GetLastError())); + } + + return result; +} + +inline std::wstring Utf8ToWstring(const std::string& str) { + if (str.empty()) { + return std::wstring(); + } + + int size_needed = MultiByteToWideChar(CP_UTF8, 0, str.data(), (int)str.size(), NULL, 0); + if (size_needed <= 0) { + throw std::runtime_error("MultiByteToWideChar() failed: " + std::to_string(GetLastError())); + } + + std::wstring result(size_needed, 0); + int chars_written = MultiByteToWideChar(CP_UTF8, 0, str.data(), (int)str.size(), &result[0], size_needed); + if (chars_written <= 0) { + throw std::runtime_error("MultiByteToWideChar() failed: " + std::to_string(GetLastError())); + } + + return result; +} + +}; + +#endif \ No newline at end of file From 2dc510df60e366b5438b28096a77e357af706d4d Mon Sep 17 00:00:00 2001 From: vansangpfiev Date: Thu, 28 Nov 2024 16:40:17 +0700 Subject: [PATCH 12/21] fix: db --- engine/main.cc | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/engine/main.cc b/engine/main.cc index d653efda5..b39c4c6e2 100644 --- a/engine/main.cc +++ b/engine/main.cc @@ -222,15 +222,6 @@ int main(int argc, char* argv[]) { // avoid printing logs to terminal is_server = true; - // check if migration is needed - if (auto res = cortex::migr::MigrationManager( - cortex::db::Database::GetInstance().db()) - .Migrate(); - res.has_error()) { - CLI_LOG("Error: " << res.error()); - return 1; - } - std::optional server_port; bool ignore_cout_log = false; #if defined(_WIN32) @@ -295,6 +286,15 @@ int main(int argc, char* argv[]) { } } + // check if migration is needed + if (auto res = cortex::migr::MigrationManager( + cortex::db::Database::GetInstance().db()) + .Migrate(); + res.has_error()) { + CLI_LOG("Error: " << res.error()); + return 1; + } + // Delete temporary file if it exists auto temp = file_manager_utils::GetExecutableFolderContainerPath() / "cortex_temp"; From 4427b302526994c69a11ef621a087d465972f39c Mon Sep 17 00:00:00 2001 From: vansangpfiev Date: Thu, 28 Nov 2024 21:42:13 +0700 Subject: [PATCH 13/21] fix: e2e --- engine/e2e-test/test_api_model_start.py | 27 ++++++++++++++++--------- engine/e2e-test/test_api_model_stop.py | 12 ++++++++--- 2 files changed, 26 insertions(+), 13 deletions(-) diff --git a/engine/e2e-test/test_api_model_start.py b/engine/e2e-test/test_api_model_start.py index d6a98a78b..88979d490 100644 --- a/engine/e2e-test/test_api_model_start.py +++ b/engine/e2e-test/test_api_model_start.py @@ -1,8 +1,9 @@ import pytest import requests from test_runner import run, start_server, stop_server - - +from test_runner import ( + wait_for_websocket_download_success_event +) class TestApiModelStart: @pytest.fixture(autouse=True) @@ -12,20 +13,26 @@ def setup_and_teardown(self): success = start_server() if not success: raise Exception("Failed to start server") - run("Install engine", ["engines", "install", "llama-cpp"], 5 * 60) run("Delete model", ["models", "delete", "tinyllama:gguf"]) - run( - "Pull model", - ["pull", "tinyllama:gguf"], - timeout=None, - ) yield # Teardown stop_server() - - def test_models_start_should_be_successful(self): + + @pytest.mark.asyncio + async def test_models_start_should_be_successful(self): + response = requests.post("http://localhost:3928/v1/engines/llama-cpp/install") + assert response.status_code == 200 + await wait_for_websocket_download_success_event(timeout=None) + + json_body = { + "model": "tinyllama:gguf" + } + response = requests.post("http://localhost:3928/v1/models/pull", json=json_body) + assert response.status_code == 200, f"Failed to pull model: tinyllama:gguf" + await wait_for_websocket_download_success_event(timeout=None) + json_body = {"model": "tinyllama:gguf"} response = requests.post( "http://localhost:3928/v1/models/start", json=json_body diff --git a/engine/e2e-test/test_api_model_stop.py b/engine/e2e-test/test_api_model_stop.py index dc3b6b77b..4157fecbd 100644 --- a/engine/e2e-test/test_api_model_stop.py +++ b/engine/e2e-test/test_api_model_stop.py @@ -1,7 +1,9 @@ import pytest import requests from test_runner import run, start_server, stop_server - +from test_runner import ( + wait_for_websocket_download_success_event +) class TestApiModelStop: @@ -13,14 +15,18 @@ def setup_and_teardown(self): if not success: raise Exception("Failed to start server") - run("Install engine", ["engines", "install", "llama-cpp"], 5 * 60) yield run("Uninstall engine", ["engines", "uninstall", "llama-cpp"]) # Teardown stop_server() - def test_models_stop_should_be_successful(self): + @pytest.mark.asyncio + async def test_models_stop_should_be_successful(self): + response = requests.post("http://localhost:3928/v1/engines/llama-cpp/install") + assert response.status_code == 200 + await wait_for_websocket_download_success_event(timeout=None) + json_body = {"model": "tinyllama:gguf"} response = requests.post( "http://localhost:3928/v1/models/start", json=json_body From e7612675024d403e88356958b6206b0714901944 Mon Sep 17 00:00:00 2001 From: vansangpfiev Date: Thu, 28 Nov 2024 21:50:49 +0700 Subject: [PATCH 14/21] fix: e2e --- engine/e2e-test/test_cli_engine_uninstall.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/engine/e2e-test/test_cli_engine_uninstall.py b/engine/e2e-test/test_cli_engine_uninstall.py index ede5e9758..bbc135db6 100644 --- a/engine/e2e-test/test_cli_engine_uninstall.py +++ b/engine/e2e-test/test_cli_engine_uninstall.py @@ -25,7 +25,7 @@ def setup_and_teardown(self): @pytest.mark.asyncio async def test_engines_uninstall_llamacpp_should_be_successfully(self): requests.post("http://127.0.0.1:3928/v1/engines/llama-cpp/install") - await wait_for_websocket_download_success_event(timeout=120) + await wait_for_websocket_download_success_event(timeout=600) exit_code, output, error = run( "Uninstall engine", ["engines", "uninstall", "llama-cpp"] ) From f274ecc49e87eae572377b7e882fb091774c27c2 Mon Sep 17 00:00:00 2001 From: vansangpfiev Date: Thu, 28 Nov 2024 21:56:48 +0700 Subject: [PATCH 15/21] fix: cli delete --- engine/e2e-test/test_cli_engine_uninstall.py | 2 +- engine/e2e-test/test_cli_model_delete.py | 18 +++++++++++++----- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/engine/e2e-test/test_cli_engine_uninstall.py b/engine/e2e-test/test_cli_engine_uninstall.py index bbc135db6..fcc5f5c73 100644 --- a/engine/e2e-test/test_cli_engine_uninstall.py +++ b/engine/e2e-test/test_cli_engine_uninstall.py @@ -25,7 +25,7 @@ def setup_and_teardown(self): @pytest.mark.asyncio async def test_engines_uninstall_llamacpp_should_be_successfully(self): requests.post("http://127.0.0.1:3928/v1/engines/llama-cpp/install") - await wait_for_websocket_download_success_event(timeout=600) + await wait_for_websocket_download_success_event(timeout=None) exit_code, output, error = run( "Uninstall engine", ["engines", "uninstall", "llama-cpp"] ) diff --git a/engine/e2e-test/test_cli_model_delete.py b/engine/e2e-test/test_cli_model_delete.py index f7ab53058..d0ba43ec1 100644 --- a/engine/e2e-test/test_cli_model_delete.py +++ b/engine/e2e-test/test_cli_model_delete.py @@ -1,6 +1,10 @@ import pytest +import requests from test_runner import popen, run from test_runner import start_server, stop_server +from test_runner import ( + wait_for_websocket_download_success_event +) class TestCliModelDelete: @@ -11,10 +15,6 @@ def setup_and_teardown(self): if not success: raise Exception("Failed to start server") - # Pull model - - run("Pull model", ["pull", "tinyllama:gguf"], timeout=None,) - yield # Teardown @@ -22,7 +22,15 @@ def setup_and_teardown(self): run("Delete model", ["models", "delete", "tinyllama:gguf"]) stop_server() - def test_models_delete_should_be_successful(self): + @pytest.mark.asyncio + async def test_models_delete_should_be_successful(self): + json_body = { + "model": "tinyllama:gguf" + } + response = requests.post("http://localhost:3928/v1/models/pull", json=json_body) + assert response.status_code == 200, f"Failed to pull model: tinyllama:gguf" + await wait_for_websocket_download_success_event(timeout=None) + exit_code, output, error = run( "Delete model", ["models", "delete", "tinyllama:gguf"] ) From f455ce7b98afcdb9978794d3f3ffae22e9b28823 Mon Sep 17 00:00:00 2001 From: vansangpfiev Date: Thu, 28 Nov 2024 22:03:32 +0700 Subject: [PATCH 16/21] fix: comment --- engine/utils/file_manager_utils.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/engine/utils/file_manager_utils.h b/engine/utils/file_manager_utils.h index 554e225dc..72310385c 100644 --- a/engine/utils/file_manager_utils.h +++ b/engine/utils/file_manager_utils.h @@ -325,7 +325,7 @@ inline std::filesystem::path GetEnginesContainerPath() { if (!std::filesystem::exists(engines_container_path)) { CTL_INF("Engine container folder not found. Create one: " << engines_container_path.string()); - std::filesystem::create_directory(engines_container_path.string()); + std::filesystem::create_directory(engines_container_path); } return engines_container_path; From 225deddd19b724a7f11177d2060d2f875414293e Mon Sep 17 00:00:00 2001 From: vansangpfiev Date: Thu, 28 Nov 2024 22:16:51 +0700 Subject: [PATCH 17/21] fix: e2e windows --- engine/e2e-test/test_api_engine_uninstall.py | 29 ++++++++++---------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/engine/e2e-test/test_api_engine_uninstall.py b/engine/e2e-test/test_api_engine_uninstall.py index 06c3c241c..c77cb2cea 100644 --- a/engine/e2e-test/test_api_engine_uninstall.py +++ b/engine/e2e-test/test_api_engine_uninstall.py @@ -21,26 +21,25 @@ def setup_and_teardown(self): # Teardown stop_server() - - def test_engines_uninstall_llamacpp_should_be_successful(self): - # install first, using cli for synchronously - run( - "Install Engine", - ["engines", "install", "llama-cpp"], - timeout=120, - capture=False, - ) + + @pytest.mark.asyncio + async def test_engines_uninstall_llamacpp_should_be_successful(self): + response = requests.post("http://localhost:3928/v1/engines/llama-cpp/install") + assert response.status_code == 200 + await wait_for_websocket_download_success_event(timeout=None) + response = requests.delete("http://localhost:3928/v1/engines/llama-cpp/install") assert response.status_code == 200 - def test_engines_uninstall_llamacpp_with_only_version_should_be_failed(self): + @pytest.mark.asyncio + async def test_engines_uninstall_llamacpp_with_only_version_should_be_failed(self): # install first - run( - "Install Engine", - ["engines", "install", "llama-cpp", "-v", "v0.1.35"], - timeout=None, - capture=False, + data = {"variant": "mac-arm64"} + install_response = requests.post( + "http://127.0.0.1:3928/v1/engines/llama-cpp/install", json=data ) + await wait_for_websocket_download_success_event(timeout=120) + assert install_response.status_code == 200 data = {"version": "v0.1.35"} response = requests.delete( From 3f4977ca9ba2fa8dabdfe15909d9bf4b4658b82c Mon Sep 17 00:00:00 2001 From: vansangpfiev Date: Thu, 28 Nov 2024 22:26:38 +0700 Subject: [PATCH 18/21] fix: e2e windows continue --- engine/e2e-test/test_cli_engine_install.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/engine/e2e-test/test_cli_engine_install.py b/engine/e2e-test/test_cli_engine_install.py index 380334222..cfac706c5 100644 --- a/engine/e2e-test/test_cli_engine_install.py +++ b/engine/e2e-test/test_cli_engine_install.py @@ -19,6 +19,7 @@ def setup_and_teardown(self): # Teardown stop_server() + @pytest.mark.skipif(platform.system() == "Windows", reason="Progress bar log issue on Windows") def test_engines_install_llamacpp_should_be_successfully(self): exit_code, output, error = run( "Install Engine", @@ -46,6 +47,7 @@ def test_engines_install_onnx_on_tensorrt_should_be_failed(self): assert "is not supported on" in output, "Should display error message" assert exit_code == 0, f"Install engine failed with error: {error}" + @pytest.mark.skipif(platform.system() == "Windows", reason="Progress bar log issue on Windows") def test_engines_install_pre_release_llamacpp(self): engine_version = "v0.1.29" exit_code, output, error = run( From c20017ae2c6b0abcea5fb51b502e5a463eff4eeb Mon Sep 17 00:00:00 2001 From: vansangpfiev Date: Thu, 28 Nov 2024 22:32:07 +0700 Subject: [PATCH 19/21] fix: e2e windows skip because of progress bar log issue --- engine/e2e-test/test_cli_engine_install.py | 1 + 1 file changed, 1 insertion(+) diff --git a/engine/e2e-test/test_cli_engine_install.py b/engine/e2e-test/test_cli_engine_install.py index cfac706c5..a998f3183 100644 --- a/engine/e2e-test/test_cli_engine_install.py +++ b/engine/e2e-test/test_cli_engine_install.py @@ -69,6 +69,7 @@ def test_engines_install_pre_release_llamacpp(self): assert is_engine_version_exist, f"Engine version {engine_version} is not found" assert exit_code == 0, f"Install engine failed with error: {error}" + @pytest.mark.skipif(platform.system() == "Windows", reason="Progress bar log issue on Windows") def test_engines_should_fallback_to_download_llamacpp_engine_if_not_exists(self): exit_code, output, error = run( "Install Engine", From 6a552bbc7771bad8ebe771690279c9ac4cf30432 Mon Sep 17 00:00:00 2001 From: vansangpfiev Date: Thu, 28 Nov 2024 23:37:39 +0700 Subject: [PATCH 20/21] fix: add sleep in case of cuda for e2e --- engine/e2e-test/test_api_engine_uninstall.py | 2 ++ engine/e2e-test/test_api_model_start.py | 3 +++ engine/e2e-test/test_api_model_stop.py | 1 + 3 files changed, 6 insertions(+) diff --git a/engine/e2e-test/test_api_engine_uninstall.py b/engine/e2e-test/test_api_engine_uninstall.py index c77cb2cea..2a491d07a 100644 --- a/engine/e2e-test/test_api_engine_uninstall.py +++ b/engine/e2e-test/test_api_engine_uninstall.py @@ -1,4 +1,5 @@ import pytest +import time import requests from test_runner import ( run, @@ -27,6 +28,7 @@ async def test_engines_uninstall_llamacpp_should_be_successful(self): response = requests.post("http://localhost:3928/v1/engines/llama-cpp/install") assert response.status_code == 200 await wait_for_websocket_download_success_event(timeout=None) + time.sleep(30) response = requests.delete("http://localhost:3928/v1/engines/llama-cpp/install") assert response.status_code == 200 diff --git a/engine/e2e-test/test_api_model_start.py b/engine/e2e-test/test_api_model_start.py index 88979d490..b3e33d113 100644 --- a/engine/e2e-test/test_api_model_start.py +++ b/engine/e2e-test/test_api_model_start.py @@ -1,4 +1,5 @@ import pytest +import time import requests from test_runner import run, start_server, stop_server from test_runner import ( @@ -25,6 +26,8 @@ async def test_models_start_should_be_successful(self): response = requests.post("http://localhost:3928/v1/engines/llama-cpp/install") assert response.status_code == 200 await wait_for_websocket_download_success_event(timeout=None) + # TODO(sang) need to fix for cuda download + time.sleep(30) json_body = { "model": "tinyllama:gguf" diff --git a/engine/e2e-test/test_api_model_stop.py b/engine/e2e-test/test_api_model_stop.py index 4157fecbd..2a74a20c5 100644 --- a/engine/e2e-test/test_api_model_stop.py +++ b/engine/e2e-test/test_api_model_stop.py @@ -26,6 +26,7 @@ async def test_models_stop_should_be_successful(self): response = requests.post("http://localhost:3928/v1/engines/llama-cpp/install") assert response.status_code == 200 await wait_for_websocket_download_success_event(timeout=None) + time.sleep(30) json_body = {"model": "tinyllama:gguf"} response = requests.post( From 512feb33a13500008901f57613f6932fc33c949c Mon Sep 17 00:00:00 2001 From: vansangpfiev Date: Thu, 28 Nov 2024 23:41:42 +0700 Subject: [PATCH 21/21] fix: import --- engine/e2e-test/test_api_model_stop.py | 1 + 1 file changed, 1 insertion(+) diff --git a/engine/e2e-test/test_api_model_stop.py b/engine/e2e-test/test_api_model_stop.py index 2a74a20c5..4fc7a55e2 100644 --- a/engine/e2e-test/test_api_model_stop.py +++ b/engine/e2e-test/test_api_model_stop.py @@ -1,4 +1,5 @@ import pytest +import time import requests from test_runner import run, start_server, stop_server from test_runner import (