From a84c12d530d9ae03ef49c5ffd1e4a5ce8e51dfc8 Mon Sep 17 00:00:00 2001 From: Dmitrii Date: Sun, 2 Feb 2025 11:19:25 +0300 Subject: [PATCH 1/6] SENJUN-24: add cpp practice processing --- src/core/service.cpp | 4 +++- tests/data/config.json | 6 +++++- tests/data/practice/cpp_run.json | 7 +++++++ tests/data/practice/cpp_test.json | 7 +++++++ tests/service/common.hpp | 3 +++ tests/service/courses_tests.cpp | 2 +- tests/service/practice_tests.cpp | 14 +++++++++++++- third_party/senjun-images | 2 +- 8 files changed, 40 insertions(+), 5 deletions(-) create mode 100644 tests/data/practice/cpp_run.json create mode 100644 tests/data/practice/cpp_test.json diff --git a/src/core/service.cpp b/src/core/service.cpp index f721d8c..dfce18a 100644 --- a/src/core/service.cpp +++ b/src/core/service.cpp @@ -51,6 +51,9 @@ std::vector getPracticeDockerArgs(RunPracticeParams const & params) runArgs.emplace_back(cmd); runArgs.emplace_back(script); + runArgs.emplace_back(fmt::format("-f {}", params.practice.project.name)); + + // TODO check -f parameter. It's absent for C++ practice. Do we need it? // see run.sh for python pracitce auto runAction = [&runArgs, ¶ms]() { runArgs.emplace_back( @@ -60,7 +63,6 @@ std::vector getPracticeDockerArgs(RunPracticeParams const & params) }; auto testAction = [&runArgs, ¶ms]() { - runArgs.emplace_back(fmt::format("-f {}", params.practice.project.name)); runArgs.emplace_back(fmt::format("-t")); }; diff --git a/tests/data/config.json b/tests/data/config.json index a11894f..569706a 100644 --- a/tests/data/config.json +++ b/tests/data/config.json @@ -49,6 +49,10 @@ "python": { "image-name": "senjun_python", "launched": 1 + }, + "cpp": { + "image-name": "senjun_cpp", + "launched": 1 } } -} +} \ No newline at end of file diff --git a/tests/data/practice/cpp_run.json b/tests/data/practice/cpp_run.json new file mode 100644 index 0000000..1a500a2 --- /dev/null +++ b/tests/data/practice/cpp_run.json @@ -0,0 +1,7 @@ +{ + "project_contents": "{\"name\":\"project\",\"children\":[{\"name\":\"CMakeLists.txt\",\"contents\":\"cmake_minimum_required(VERSION 3.30.0 FATAL_ERROR)\\n\\n# Включаем флаг для возможности `import std`.\\n# Эта строка должна идти ДО объявления, что проект на C++ (значение CXX).\\nset(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD\\n \\\"0e5b6991-d74f-4b3d-a41c-cf096e0b2508\\\")\\n\\n# Для всех целей сборки устанавливаем возможность импорта std в 1.\\nset(CMAKE_CXX_MODULE_STD 1)\\n\\nSET(CMAKE_CXX_FLAGS \\\"${CMAKE_CXX_FLAGS} -stdlib=libc++ -Werror -Wall -O2\\\")\\n\\nproject(div_without_div LANGUAGES CXX)\\n\\nadd_executable(main)\\n\\ntarget_sources(main\\n PRIVATE\\n main.cpp)\\n\\ntarget_compile_features(main\\n PRIVATE cxx_std_23\\n INTERFACE cxx_std_23)\\n\\nadd_executable(tests)\\n\\ntarget_sources(tests\\nPRIVATE\\n tests.cpp)\\n\\ntarget_compile_features(tests\\nPRIVATE cxx_std_23\\nINTERFACE cxx_std_23)\\n\\n# Чтобы собрать проект локально, выполните:\\n# mkdir build \u0026\u0026 cd build\\n# cmake -Wno-dev -GNinja ..\\n# ninja\\n\",\"id\":2},{\"name\":\"div.h\",\"contents\":\"#pragma once\\n\\ninline int divide(int a, int b) {\\n // Ваше решение\\nreturn 0;}\\n\",\"id\":3},{\"name\":\"main.cpp\",\"contents\":\"#include \\\"div.h\\\"\\n\\n#include \u003cprint\u003e\\n\\nint main() {\\n std::println(\\\"{}\\\", divide(11, 5)); // 2\\n std::println(\\\"{}\\\", divide(5, 11)); // 0\\n}\",\"is_main_file\":true,\"id\":4},{\"name\":\"tests.cpp\",\"contents\":\"#include \\\"ut.hpp\\\" // Библиотка для юнит-тестов\\n\\n#include \\\"div.h\\\"\\n\\n// Юнит-тесты\\nint main() {\\n using namespace boost::ut;\\n\\n \\\"Simple cases\\\"_test = [] {\\n expect(divide(1, 1) == 1);\\n expect(divide(1, 2) == 0);\\n expect(divide(2, 1) == 2);\\n expect(divide(3, 2) == 1);\\n expect(divide(10, 2) == 5);\\n expect(divide(11, 2) == 5);\\n };\\n}\",\"id\":5}],\"id\":1}", + "project_id": "cpp_div_without_div", + "course_id": "cpp", + "user_cmd_line_args": "", + "action": "run" +} \ No newline at end of file diff --git a/tests/data/practice/cpp_test.json b/tests/data/practice/cpp_test.json new file mode 100644 index 0000000..7fabd1e --- /dev/null +++ b/tests/data/practice/cpp_test.json @@ -0,0 +1,7 @@ +{ + "project_contents": "{\"name\":\"project\",\"children\":[{\"name\":\"CMakeLists.txt\",\"contents\":\"cmake_minimum_required(VERSION 3.30.0 FATAL_ERROR)\\n\\n# Включаем флаг для возможности `import std`.\\n# Эта строка должна идти ДО объявления, что проект на C++ (значение CXX).\\nset(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD\\n \\\"0e5b6991-d74f-4b3d-a41c-cf096e0b2508\\\")\\n\\n# Для всех целей сборки устанавливаем возможность импорта std в 1.\\nset(CMAKE_CXX_MODULE_STD 1)\\n\\nSET(CMAKE_CXX_FLAGS \\\"${CMAKE_CXX_FLAGS} -stdlib=libc++ -Werror -Wall -O2\\\")\\n\\nproject(div_without_div LANGUAGES CXX)\\n\\nadd_executable(main)\\n\\ntarget_sources(main\\n PRIVATE\\n main.cpp)\\n\\ntarget_compile_features(main\\n PRIVATE cxx_std_23\\n INTERFACE cxx_std_23)\\n\\nadd_executable(tests)\\n\\ntarget_sources(tests\\nPRIVATE\\n tests.cpp)\\n\\ntarget_compile_features(tests\\nPRIVATE cxx_std_23\\nINTERFACE cxx_std_23)\\n\\n# Чтобы собрать проект локально, выполните:\\n# mkdir build \u0026\u0026 cd build\\n# cmake -Wno-dev -GNinja ..\\n# ninja\\n\",\"id\":2},{\"name\":\"div.h\",\"contents\":\"#pragma once\\n\\ninline int divide(int a, int b) {\\n // Ваше решение\\nreturn 0;}\\n\",\"id\":3},{\"name\":\"main.cpp\",\"contents\":\"#include \\\"div.h\\\"\\n\\n#include \u003cprint\u003e\\n\\nint main() {\\n std::println(\\\"{}\\\", divide(11, 5)); // 2\\n std::println(\\\"{}\\\", divide(5, 11)); // 0\\n}\",\"is_main_file\":true,\"id\":4},{\"name\":\"tests.cpp\",\"contents\":\"#include \\\"ut.hpp\\\" // Библиотка для юнит-тестов\\n\\n#include \\\"div.h\\\"\\n\\n// Юнит-тесты\\nint main() {\\n using namespace boost::ut;\\n\\n \\\"Simple cases\\\"_test = [] {\\n expect(divide(1, 1) == 1);\\n expect(divide(1, 2) == 0);\\n expect(divide(2, 1) == 2);\\n expect(divide(3, 2) == 1);\\n expect(divide(10, 2) == 5);\\n expect(divide(11, 2) == 5);\\n };\\n}\",\"id\":5}],\"id\":1}", + "project_id": "cpp_div_without_div", + "course_id": "cpp", + "user_cmd_line_args": "", + "action": "test" +} \ No newline at end of file diff --git a/tests/service/common.hpp b/tests/service/common.hpp index b2ba00b..2f76250 100644 --- a/tests/service/common.hpp +++ b/tests/service/common.hpp @@ -41,3 +41,6 @@ std::string const kHaskellProject = "haskell_playground.json"; std::string const kPythonPracticeRun = "practice/python_run.json"; std::string const kPythonPracticeTest = "practice/python_test.json"; + +std::string const kCppPracticeRun = "practice/cpp_run.json"; +std::string const kCppPracticeTest = "practice/cpp_test.json"; diff --git a/tests/service/courses_tests.cpp b/tests/service/courses_tests.cpp index a446410..3d74277 100644 --- a/tests/service/courses_tests.cpp +++ b/tests/service/courses_tests.cpp @@ -51,7 +51,7 @@ TEST(Courses, Rust) { std::string testingCode = "/* You can edit and run this code. */\n\nfn main() {\n println!(\"Hello world!\");\n}\n"; watchman::ChapterTaskParams const params{ - {watchman::Language::RUST}, std::move(sourceCode), std::move(testingCode)}; + {watchman::Language::RUST, {}}, std::move(sourceCode), std::move(testingCode)}; watchman::Response response = service.runChapter(params); ASSERT_EQ(response.sourceCode, 0); ASSERT_EQ(response.output, "Hello world!\r\n"); diff --git a/tests/service/practice_tests.cpp b/tests/service/practice_tests.cpp index 63ae93f..e9b1704 100644 --- a/tests/service/practice_tests.cpp +++ b/tests/service/practice_tests.cpp @@ -6,7 +6,8 @@ TEST(Practice, RunTest) { watchman::Service service(watchman::readConfig(kParams.config)); - watchman::RunPracticeParams params = watchman::parsePractice(getFileContent(kPythonPracticeRun)); + watchman::RunPracticeParams params = + watchman::parsePractice(getFileContent(kPythonPracticeRun)); auto response = service.runPractice(params); ASSERT_TRUE(response.sourceCode == watchman::kSuccessCode); @@ -14,3 +15,14 @@ TEST(Practice, RunTest) { response = service.runPractice(params); ASSERT_TRUE(response.sourceCode == watchman::kTestsError); } + +TEST(Practice, RunCpp) { + watchman::Service service(watchman::readConfig(kParams.config)); + watchman::RunPracticeParams params = watchman::parsePractice(getFileContent(kCppPracticeRun)); + auto response = service.runPractice(params); + ASSERT_TRUE(response.sourceCode == watchman::kSuccessCode); + + params = watchman::parsePractice(getFileContent((kCppPracticeTest))); + response = service.runPractice(params); + ASSERT_TRUE(response.sourceCode == watchman::kTestsError); +} diff --git a/third_party/senjun-images b/third_party/senjun-images index 3389c1a..e0bcf8a 160000 --- a/third_party/senjun-images +++ b/third_party/senjun-images @@ -1 +1 @@ -Subproject commit 3389c1a94f8a501bad66804ec4e3ee63a288b3cc +Subproject commit e0bcf8a9aa4de6519755ca832d116f4b8756808a From d11bc5b12af84632bb55f011e7279c3afbf73d3e Mon Sep 17 00:00:00 2001 From: Dmitrii Date: Sun, 2 Feb 2025 16:24:06 +0300 Subject: [PATCH 2/6] SENJUN-24: update cpp image --- third_party/senjun-images | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/third_party/senjun-images b/third_party/senjun-images index e0bcf8a..49c54e0 160000 --- a/third_party/senjun-images +++ b/third_party/senjun-images @@ -1 +1 @@ -Subproject commit e0bcf8a9aa4de6519755ca832d116f4b8756808a +Subproject commit 49c54e049381d5313dc05533741986d065d7200c From eda09347391d5b862d3d3adaf693d30e10bafc75 Mon Sep 17 00:00:00 2001 From: Dmitrii Date: Mon, 3 Feb 2025 20:28:22 +0300 Subject: [PATCH 3/6] SENJUN-24: fix wrong -o parameter usage --- src/core/service.cpp | 8 ++++---- tests/data/practice/cpp_test.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/core/service.cpp b/src/core/service.cpp index dfce18a..3c32f88 100644 --- a/src/core/service.cpp +++ b/src/core/service.cpp @@ -58,13 +58,13 @@ std::vector getPracticeDockerArgs(RunPracticeParams const & params) auto runAction = [&runArgs, ¶ms]() { runArgs.emplace_back( fmt::format("-p practice/{}", params.pathToMainFile)); // TODO remove this properly - runArgs.emplace_back(fmt::format("-o {}", params.userCmdLineArgs)); + if (!params.userCmdLineArgs.empty()) { + runArgs.emplace_back(fmt::format("-o {}", params.userCmdLineArgs)); + } runArgs.emplace_back(fmt::format("-r")); }; - auto testAction = [&runArgs, ¶ms]() { - runArgs.emplace_back(fmt::format("-t")); - }; + auto testAction = [&runArgs, ¶ms]() { runArgs.emplace_back(fmt::format("-t")); }; switch (params.practice.action) { case PracticeAction::Run: runAction(); break; diff --git a/tests/data/practice/cpp_test.json b/tests/data/practice/cpp_test.json index 7fabd1e..dc4b08f 100644 --- a/tests/data/practice/cpp_test.json +++ b/tests/data/practice/cpp_test.json @@ -1,5 +1,5 @@ { - "project_contents": "{\"name\":\"project\",\"children\":[{\"name\":\"CMakeLists.txt\",\"contents\":\"cmake_minimum_required(VERSION 3.30.0 FATAL_ERROR)\\n\\n# Включаем флаг для возможности `import std`.\\n# Эта строка должна идти ДО объявления, что проект на C++ (значение CXX).\\nset(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD\\n \\\"0e5b6991-d74f-4b3d-a41c-cf096e0b2508\\\")\\n\\n# Для всех целей сборки устанавливаем возможность импорта std в 1.\\nset(CMAKE_CXX_MODULE_STD 1)\\n\\nSET(CMAKE_CXX_FLAGS \\\"${CMAKE_CXX_FLAGS} -stdlib=libc++ -Werror -Wall -O2\\\")\\n\\nproject(div_without_div LANGUAGES CXX)\\n\\nadd_executable(main)\\n\\ntarget_sources(main\\n PRIVATE\\n main.cpp)\\n\\ntarget_compile_features(main\\n PRIVATE cxx_std_23\\n INTERFACE cxx_std_23)\\n\\nadd_executable(tests)\\n\\ntarget_sources(tests\\nPRIVATE\\n tests.cpp)\\n\\ntarget_compile_features(tests\\nPRIVATE cxx_std_23\\nINTERFACE cxx_std_23)\\n\\n# Чтобы собрать проект локально, выполните:\\n# mkdir build \u0026\u0026 cd build\\n# cmake -Wno-dev -GNinja ..\\n# ninja\\n\",\"id\":2},{\"name\":\"div.h\",\"contents\":\"#pragma once\\n\\ninline int divide(int a, int b) {\\n // Ваше решение\\nreturn 0;}\\n\",\"id\":3},{\"name\":\"main.cpp\",\"contents\":\"#include \\\"div.h\\\"\\n\\n#include \u003cprint\u003e\\n\\nint main() {\\n std::println(\\\"{}\\\", divide(11, 5)); // 2\\n std::println(\\\"{}\\\", divide(5, 11)); // 0\\n}\",\"is_main_file\":true,\"id\":4},{\"name\":\"tests.cpp\",\"contents\":\"#include \\\"ut.hpp\\\" // Библиотка для юнит-тестов\\n\\n#include \\\"div.h\\\"\\n\\n// Юнит-тесты\\nint main() {\\n using namespace boost::ut;\\n\\n \\\"Simple cases\\\"_test = [] {\\n expect(divide(1, 1) == 1);\\n expect(divide(1, 2) == 0);\\n expect(divide(2, 1) == 2);\\n expect(divide(3, 2) == 1);\\n expect(divide(10, 2) == 5);\\n expect(divide(11, 2) == 5);\\n };\\n}\",\"id\":5}],\"id\":1}", + "project_contents": "{\"name\":\"project\",\"children\":[{\"name\":\"CMakeLists.txt\",\"contents\":\"cmake_minimum_required(VERSION 3.30.0 FATAL_ERROR)\\n\\n# Включаем флаг для возможности `import std`.\\n# Эта строка должна идти ДО объявления, что проект на C++ (значение CXX).\\nset(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD\\n \\\"0e5b6991-d74f-4b3d-a41c-cf096e0b2508\\\")\\n\\n# Для всех целей сборки устанавливаем возможность импорта std в 1.\\nset(CMAKE_CXX_MODULE_STD 1)\\n\\nSET(CMAKE_CXX_FLAGS \\\"${CMAKE_CXX_FLAGS} -stdlib=libc++ -Werror -Wall -O2\\\")\\n\\nproject(div_without_div LANGUAGES CXX)\\n\\nadd_executable(main)\\n\\ntarget_sources(main\\n PRIVATE\\n main.cpp)\\n\\ntarget_compile_features(main\\n PRIVATE cxx_std_23\\n INTERFACE cxx_std_23)\\n\\nadd_executable(tests)\\n\\ntarget_sources(tests\\nPRIVATE\\n tests.cpp)\\n\\ntarget_compile_features(tests\\nPRIVATE cxx_std_23\\nINTERFACE cxx_std_23)\\n\\n# Чтобы собрать проект локально, выполните:\\n# mkdir build \u0026\u0026 cd build\\n# cmake -Wno-dev -GNinja ..\\n# ninja\\n\",\"id\":2},{\"name\":\"div.h\",\"contents\":\"#pragma once\\n\\ninline int divide(int a, int b) {\\n while(true);// Ваше решение\\nreturn 0;}\\n\",\"id\":3},{\"name\":\"main.cpp\",\"contents\":\"#include \\\"div.h\\\"\\n\\n#include \u003cprint\u003e\\n\\nint main() {\\n std::println(\\\"{}\\\", divide(11, 5)); // 2\\n std::println(\\\"{}\\\", divide(5, 11)); // 0\\n}\",\"is_main_file\":true,\"id\":4},{\"name\":\"tests.cpp\",\"contents\":\"#include \\\"ut.hpp\\\" // Библиотка для юнит-тестов\\n\\n#include \\\"div.h\\\"\\n\\n// Юнит-тесты\\nint main() {\\n using namespace boost::ut;\\n\\n \\\"Simple cases\\\"_test = [] {\\n expect(divide(1, 1) == 1);\\n expect(divide(1, 2) == 0);\\n expect(divide(2, 1) == 2);\\n expect(divide(3, 2) == 1);\\n expect(divide(10, 2) == 5);\\n expect(divide(11, 2) == 5);\\n };\\n}\",\"id\":5}],\"id\":1}", "project_id": "cpp_div_without_div", "course_id": "cpp", "user_cmd_line_args": "", From a1b983694f12c07acd70d3b46e3c063f9dde9641 Mon Sep 17 00:00:00 2001 From: Dmitrii Date: Mon, 3 Feb 2025 20:28:50 +0300 Subject: [PATCH 4/6] SENJUN-24: update senjun-images --- third_party/senjun-images | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/third_party/senjun-images b/third_party/senjun-images index 49c54e0..4275a6a 160000 --- a/third_party/senjun-images +++ b/third_party/senjun-images @@ -1 +1 @@ -Subproject commit 49c54e049381d5313dc05533741986d065d7200c +Subproject commit 4275a6a18ff10ed03ce88d11915932cf99123176 From 485fe022dead174add44cec2817389a4af6e88e2 Mon Sep 17 00:00:00 2001 From: Dmitrii Date: Sun, 6 Apr 2025 18:35:49 +0300 Subject: [PATCH 5/6] SENJUN-24: update submodule --- third_party/senjun-images | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/third_party/senjun-images b/third_party/senjun-images index 4275a6a..3389c1a 160000 --- a/third_party/senjun-images +++ b/third_party/senjun-images @@ -1 +1 @@ -Subproject commit 4275a6a18ff10ed03ce88d11915932cf99123176 +Subproject commit 3389c1a94f8a501bad66804ec4e3ee63a288b3cc From 72bba3845a2f256da91d8b78a51247fbc2c49df5 Mon Sep 17 00:00:00 2001 From: Dmitrii Date: Sun, 6 Apr 2025 19:07:45 +0300 Subject: [PATCH 6/6] SENJUN-24: update senjun-images --- third_party/senjun-images | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/third_party/senjun-images b/third_party/senjun-images index 3389c1a..c66d1e6 160000 --- a/third_party/senjun-images +++ b/third_party/senjun-images @@ -1 +1 @@ -Subproject commit 3389c1a94f8a501bad66804ec4e3ee63a288b3cc +Subproject commit c66d1e65b3795f8126ad1135f3028f7cae21c8ec