Skip to content

Commit

Permalink
Added cpp tests to linter integration tests
Browse files Browse the repository at this point in the history
  • Loading branch information
stevenewald committed Oct 5, 2024
1 parent f27093f commit 917ada4
Show file tree
Hide file tree
Showing 17 changed files with 190 additions and 105 deletions.
1 change: 0 additions & 1 deletion .github/scripts/conan-profile.sh
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,5 @@ profile="$(conan profile path default)"

mv "$profile" "${profile}.bak"
sed -e 's/^\(compiler\.cppstd=\).\{1,\}$/\1'"$std/" \
-e 's/^\(compiler\.version=\).\{1,\}$/\1'"$version/" \
"${profile}.bak" > "$profile"
rm "${profile}.bak"
2 changes: 1 addition & 1 deletion .github/workflows/exchange-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -288,7 +288,7 @@ jobs:
LLVM_DIR: '/usr/lib/llvm-18/lib/cmake/llvm'
NUTC_WRAPPER_BINARY_PATH: ${{ github.workspace }}/exchange/build/WRAPPER
NUTC_CPP_TEMPLATE_PATH: ${{ github.workspace }}/exchange/template.cpp
NUTC_SPAWNER_BINARY_PATH: ${{ github.workspace }}/exchange/build/LINTER-spawner
NUTC_LINTER_SPAWNER_BINARY_PATH: ${{ github.workspace }}/exchange/build/LINTER-spawner

steps:
- uses: actions/checkout@v3
Expand Down
19 changes: 10 additions & 9 deletions exchange/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,7 @@ target_include_directories(
"$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/src>"
)

target_compile_features(LINTER_lib PUBLIC cxx_std_20)
target_compile_features(LINTER_lib PUBLIC cxx_std_23)

target_link_libraries(LINTER_lib PUBLIC fmt::fmt)
target_link_libraries(LINTER_lib PUBLIC quill::quill)
Expand All @@ -258,7 +258,6 @@ target_include_directories(
LINTER_spawner_lib ${warning_guard}
PUBLIC
"$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/src>"
"$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/>"
)

target_link_libraries(LINTER_spawner_lib PRIVATE quill::quill)
Expand All @@ -275,7 +274,7 @@ add_executable(LINTER::exe ALIAS LINTER_exe)

set_property(TARGET LINTER_exe PROPERTY OUTPUT_NAME LINTER)

target_compile_features(LINTER_exe PRIVATE cxx_std_20)
target_compile_features(LINTER_exe PRIVATE cxx_std_23)

target_link_libraries(LINTER_exe PRIVATE LINTER_lib)
target_link_libraries(LINTER_exe PRIVATE fmt::fmt)
Expand All @@ -295,7 +294,7 @@ add_executable(LINTER_spawner::exe ALIAS LINTER_spawner_exe)

set_property(TARGET LINTER_spawner_exe PROPERTY OUTPUT_NAME LINTER_spawner)

target_compile_features(LINTER_spawner_exe PRIVATE cxx_std_20)
target_compile_features(LINTER_spawner_exe PRIVATE cxx_std_23)

target_link_libraries(LINTER_spawner_exe PRIVATE LINTER_spawner_lib)
target_link_libraries(LINTER_spawner_exe PRIVATE CURL::libcurl)
Expand All @@ -307,8 +306,8 @@ target_link_libraries(LINTER_spawner_exe PRIVATE Python3::Python)
# ---- COMMON ----------

add_library(COMMON_lib OBJECT
src/common/file_operations/file_operations.cpp
src/common/firebase/firebase.cpp
src/common/file_operations/file_operations.cpp
src/common/util.cpp
src/common/types/decimal.cpp
src/common/types/algorithm/local_algorithm.cpp
Expand Down Expand Up @@ -336,11 +335,11 @@ target_link_libraries(COMMON_lib PRIVATE boost::boost)
target_link_libraries(EXCHANGE_lib PUBLIC COMMON_lib)
target_link_libraries(EXCHANGE_exe PRIVATE COMMON_lib)

target_link_libraries(LINTER_lib PRIVATE COMMON_lib)
target_link_libraries(LINTER_exe PUBLIC COMMON_lib)
target_link_libraries(LINTER_lib PUBLIC COMMON_lib)
target_link_libraries(LINTER_exe PRIVATE COMMON_lib)

target_link_libraries(LINTER_spawner_lib PRIVATE COMMON_lib)
target_link_libraries(LINTER_spawner_exe PUBLIC COMMON_lib)
target_link_libraries(LINTER_spawner_lib PUBLIC COMMON_lib)
target_link_libraries(LINTER_spawner_exe PRIVATE COMMON_lib)

target_link_libraries(WRAPPER_lib PUBLIC COMMON_lib)
target_link_libraries(WRAPPER_exe PRIVATE COMMON_lib)
Expand All @@ -358,6 +357,8 @@ if(lto_supported)
set_target_properties(COMMON_lib PROPERTIES INTERPROCEDURAL_OPTIMIZATION_RELEASE TRUE)
set_target_properties(LINTER_exe PROPERTIES INTERPROCEDURAL_OPTIMIZATION_RELEASE TRUE)
set_target_properties(LINTER_lib PROPERTIES INTERPROCEDURAL_OPTIMIZATION_RELEASE TRUE)
set_target_properties(LINTER_spawner_lib PROPERTIES INTERPROCEDURAL_OPTIMIZATION_RELEASE TRUE)
set_target_properties(LINTER_spawner_exe PROPERTIES INTERPROCEDURAL_OPTIMIZATION_RELEASE TRUE)
else()
message(WARNING "LTO is not supported: ${error}")
endif()
Expand Down
Binary file modified exchange/docker/dev/grafana_data/grafana.db
Binary file not shown.
32 changes: 27 additions & 5 deletions exchange/src/common/compilation/compile_cpp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

#include "common/file_operations/file_operations.hpp"

#include <optional>

namespace nutc::common {
namespace {
std::string
Expand All @@ -19,6 +21,25 @@ get_cpp_template_path()

return template_path_env;
}

std::optional<std::string>
exec_command(const std::string& command)
{
std::array<char, 128> buffer{};
std::string result;

FILE* pipe = popen((command + " 2>&1").c_str(), "r");
if (pipe == nullptr) {
throw std::runtime_error("popen() failed!");
}
while (fgets(buffer.data(), buffer.size(), pipe) != nullptr) {
result += buffer.data();
}
if (pclose(pipe) != 0) {
return result;
}
return std::nullopt;
}
} // namespace

std::string
Expand All @@ -33,12 +54,13 @@ compile_cpp(const std::filesystem::path& filepath)
filepath.string(), get_cpp_template_path()
);

int result = system(command.c_str());
std::optional<std::string> result = exec_command(command);

if (result != 0) {
throw std::runtime_error(
fmt::format("Compilation of {} failed", filepath.string())
);
if (result) {
throw std::runtime_error(fmt::format(
"Compilation of {} failed. Compiler output below:\n {}", filepath.string(),
result.value()
));
}
return binary_output;
}
Expand Down
52 changes: 10 additions & 42 deletions exchange/src/linter/runtime/cpp/cpp_runtime.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
#include "cpp_runtime.hpp"

#include "common/compilation/compile_cpp.hpp"
#include "common/file_operations/file_operations.hpp"

#include <dlfcn.h>
#include <fcntl.h>
Expand All @@ -13,42 +12,8 @@
#include <cerrno>
#include <cstdlib>

#include <filesystem>
#include <fstream>
#include <iostream>
#include <stdexcept>

namespace {
namespace fs = std::filesystem;

std::pair<int, std::filesystem::path>
get_temp_file()
{
#ifdef __APPLE__
std::string template_path = (fs::temp_directory_path() / "algoXXXXXX").string();
std::vector<char> writable_template_path(
template_path.begin(), template_path.end()
);
writable_template_path.push_back('\0');
int fd = mkstemp(writable_template_path.data());
if (fd == -1) {
throw std::runtime_error("Failed to get file descriptor for temporary file");
}

return {fd, writable_template_path.data()};

#else
int memfd = memfd_create("algo", MFD_CLOEXEC);
if (memfd == -1) {
throw std::runtime_error("Failed to create memfd");
}

return {memfd, "/proc/self/fd/" + std::to_string(memfd)};

#endif
}

} // namespace

namespace nutc::lint {

Expand All @@ -64,9 +29,9 @@ CppRuntime::CppRuntime(

CppRuntime::~CppRuntime()
{
// TODO: shoudl not do
dlclose(dl_handle_);
close(fd_);
if (dl_handle_ != nullptr) {
dlclose(dl_handle_);
}
}

std::optional<std::string>
Expand All @@ -80,12 +45,17 @@ CppRuntime::init()
algo_file << algo_ << std::flush;
algo_file.close();

std::string compiled_binary_path = common::compile_cpp(temp_file.string());
// TODO: improve
std::string compiled_binary_path;
try {
compiled_binary_path = common::compile_cpp(temp_file.string());
} catch (const std::exception& e) {
return fmt::format("[linter] failed to compile C++ code: {}", e.what());
}

dl_handle_ = dlopen(compiled_binary_path.c_str(), RTLD_NOW);
if (dl_handle_ == nullptr) {
std::string err = dlerror();
close(fd_);
return fmt::format("[linter] failed to dlopen: {}", err);
}

Expand All @@ -100,8 +70,6 @@ CppRuntime::init()

if (init_func == nullptr || on_trade_update_func_ == nullptr
|| on_orderbook_update_func_ == nullptr || on_account_update_func_ == nullptr) {
dlclose(dl_handle_);
close(fd_);
return fmt::format("[linter] failed to dynamically load functions");
}
strategy_object_ =
Expand Down
3 changes: 1 addition & 2 deletions exchange/src/linter/runtime/cpp/cpp_runtime.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,6 @@ class CppRuntime : public Runtime {
OnAccountUpdateFunc on_account_update_func_;

Strategy* strategy_object_;
void* dl_handle_;
int fd_;
void* dl_handle_{};
};
} // namespace nutc::lint
16 changes: 11 additions & 5 deletions exchange/src/linter/spawner/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,17 @@ mock_cancel_func(nutc::common::Ticker, std::int64_t)
}
} // namespace

void
send_response(const std::string& response)
{
std::cout << nutc::common::base64_encode(response) << std::endl;
}

int
main(int argc, char* argv[])
{
if (argc < 2) {
std::cout << "[linter] no language provided\n";
send_response("[linter] no language provided");
return 1;
}

Expand All @@ -65,18 +71,18 @@ main(int argc, char* argv[])
lint_result = nutc::lint::lint(runtime);
}
else {
std::cout << "[linter] no language provided\n";
send_response("[linter] no language provided");
return 1;
}

auto output = glz::write_json(lint_result);
if (output) {
std::cout << *output << std::endl;
send_response(output.value());
}
else {
std::cout << fmt::format(
send_response(fmt::format(
"[linter] ERROR WRITING LINT RESULT: {}", glz::format_error(output.error())
) << std::endl;
));
}

return 0;
Expand Down
13 changes: 9 additions & 4 deletions exchange/src/linter/spawning/spawning.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,14 @@ namespace spawning {
const std::filesystem::path&
LintProcessManager::spawner_binary_path()
{
static constexpr auto LINTER_SPAWNER_BINARY_ENV_VAR =
"NUTC_LINTER_SPAWNER_BINARY_PATH";
static const char* spawner_binary_location =
std::getenv("NUTC_LINTER_SPAWNER_BINARY_PATH"); // NOLINT
std::getenv(LINTER_SPAWNER_BINARY_ENV_VAR); // NOLINT
if (spawner_binary_location == nullptr) [[unlikely]] {
throw std::runtime_error("NUTC_SPAWNER_BINARY_PATH environment variable not set"
);
throw std::runtime_error(fmt::format(
"{} environment variable not set", LINTER_SPAWNER_BINARY_ENV_VAR
));
}

static const std::filesystem::path spawner_binary_path{spawner_binary_location};
Expand Down Expand Up @@ -96,8 +99,10 @@ LintProcessManager::spawn_client(const std::string& algo_code, AlgoLanguage lang
if (child->running()) {
child->terminate();
}
std::string decoded_message = common::base64_decode(message);

auto error = glz::read_json<nutc::lint::lint_result>(res, message);
auto error =
glz::read_json<nutc::lint::lint_result>(res, decoded_message);
if (error) {
res = {
false, "Internal server error. Reach out to "
Expand Down
2 changes: 2 additions & 0 deletions exchange/template.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
// #include "template.hpp"

#include <functional>
#include <string>
#include <cstdint>

using PlaceMarketOrder = std::function<bool(Side, Ticker, float)>;
using PlaceLimitOrder = std::function<std::int64_t(Side, Ticker, float, float, bool)>;
Expand Down
3 changes: 2 additions & 1 deletion exchange/test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ add_executable(NUTC_tests
src/unit/types/decimal.cpp

src/integration/tests/basic.cpp
src/integration/tests/linter_test.cpp
src/integration/tests/linter_py_test.cpp
src/integration/tests/linter_cpp_test.cpp
src/integration/tests/cancellation.cpp
)

Expand Down
Loading

0 comments on commit 917ada4

Please sign in to comment.