147 lines
6.2 KiB
C++
147 lines
6.2 KiB
C++
// Step 452: Concurrency Model Translation Tests (12 tests)
|
|
|
|
#include "ConcurrencyTranslator.h"
|
|
|
|
#include <iostream>
|
|
|
|
static int passed = 0, failed = 0;
|
|
#define TEST(name) { std::cout << " " << #name << "... "; }
|
|
#define PASS() { std::cout << "PASS\n"; ++passed; }
|
|
#define FAIL(msg) { std::cout << "FAIL: " << msg << "\n"; ++failed; }
|
|
#define CHECK(cond, msg) if (!(cond)) { FAIL(msg); return; } else {}
|
|
|
|
void test_async_python_to_rust_needs_runtime_review() {
|
|
TEST(async_python_to_rust_needs_runtime_review);
|
|
auto r = ConcurrencyTranslator::analyze("async def f(): await g()", "python", "rust");
|
|
CHECK(r.hasPattern("async/await"), "expected async pattern");
|
|
CHECK(r.countNeedsReview() >= 1, "rust async runtime should require review");
|
|
CHECK(r.translations[0].annotation.find("tokio") != std::string::npos,
|
|
"expected tokio runtime annotation");
|
|
PASS();
|
|
}
|
|
|
|
void test_async_to_c_is_unsafe() {
|
|
TEST(async_to_c_is_unsafe);
|
|
auto r = ConcurrencyTranslator::analyze("async def f(): await g()", "python", "c");
|
|
CHECK(r.hasPattern("async/await"), "expected async pattern");
|
|
CHECK(r.translations[0].safety == ConcurrencySafety::Unsafe, "async->C should be unsafe");
|
|
CHECK(r.translations[0].annotation.find("@Risk(high)") != std::string::npos,
|
|
"expected high risk annotation");
|
|
PASS();
|
|
}
|
|
|
|
void test_thread_java_to_go_maps_to_goroutine() {
|
|
TEST(thread_java_to_go_maps_to_goroutine);
|
|
auto r = ConcurrencyTranslator::analyze("new Thread(() -> {}).start();", "java", "go");
|
|
CHECK(r.hasPattern("thread_spawn"), "expected thread spawn pattern");
|
|
CHECK(r.translations[0].targetCode.find("go func") != std::string::npos,
|
|
"expected goroutine mapping");
|
|
CHECK(r.translations[0].safety == ConcurrencySafety::Safe, "expected safe mapping");
|
|
PASS();
|
|
}
|
|
|
|
void test_thread_to_python_marks_gil_review() {
|
|
TEST(thread_to_python_marks_gil_review);
|
|
auto r = ConcurrencyTranslator::analyze("std::thread t(f);", "cpp", "python");
|
|
CHECK(r.hasPattern("thread_spawn"), "expected thread spawn pattern");
|
|
CHECK(r.translations[0].safety == ConcurrencySafety::NeedsReview, "expected review");
|
|
CHECK(r.translations[0].annotation.find("GIL") != std::string::npos, "expected GIL annotation");
|
|
PASS();
|
|
}
|
|
|
|
void test_channels_go_to_rust_mpsc() {
|
|
TEST(channels_go_to_rust_mpsc);
|
|
auto r = ConcurrencyTranslator::analyze("ch := make(chan int); ch <- 1", "go", "rust");
|
|
CHECK(r.hasPattern("channels"), "expected channels pattern");
|
|
CHECK(r.translations[0].targetCode.find("mpsc::channel") != std::string::npos,
|
|
"expected rust mpsc mapping");
|
|
PASS();
|
|
}
|
|
|
|
void test_mutex_java_to_c_requires_review() {
|
|
TEST(mutex_java_to_c_requires_review);
|
|
auto r = ConcurrencyTranslator::analyze("synchronized(lock) { x++; }", "java", "c");
|
|
CHECK(r.hasPattern("mutex"), "expected mutex pattern");
|
|
CHECK(r.translations[0].safety == ConcurrencySafety::NeedsReview, "expected review in C");
|
|
CHECK(r.translations[0].targetCode.find("pthread_mutex_lock") != std::string::npos,
|
|
"expected pthread mutex mapping");
|
|
PASS();
|
|
}
|
|
|
|
void test_source_model_prefers_async_when_present() {
|
|
TEST(source_model_prefers_async_when_present);
|
|
auto r = ConcurrencyTranslator::analyze(
|
|
"async def f(): await g()\nthreading.Thread(target=h).start()",
|
|
"python",
|
|
"rust");
|
|
CHECK(r.sourceModel == ConcurrencyModel::AsyncAwait, "async should win source model detection");
|
|
PASS();
|
|
}
|
|
|
|
void test_target_model_defaults_for_javascript() {
|
|
TEST(target_model_defaults_for_javascript);
|
|
auto r = ConcurrencyTranslator::analyze("value = 1;", "python", "javascript");
|
|
CHECK(r.targetModel == ConcurrencyModel::EventLoop, "javascript target should default to event loop");
|
|
PASS();
|
|
}
|
|
|
|
void test_no_patterns_on_plain_code() {
|
|
TEST(no_patterns_on_plain_code);
|
|
auto r = ConcurrencyTranslator::analyze("x = a + b;", "python", "rust");
|
|
CHECK(r.translations.empty(), "plain code should not emit translations");
|
|
CHECK(!r.hasPattern("async/await"), "should not detect async pattern");
|
|
PASS();
|
|
}
|
|
|
|
void test_multiple_patterns_detected() {
|
|
TEST(multiple_patterns_detected);
|
|
auto r = ConcurrencyTranslator::analyze(
|
|
"async def f(): await g()\nmutex.lock()\nmutex.unlock()",
|
|
"python",
|
|
"rust");
|
|
CHECK(r.hasPattern("async/await"), "expected async");
|
|
CHECK(r.hasPattern("mutex"), "expected mutex");
|
|
CHECK(r.translations.size() >= 2, "expected multiple translations");
|
|
PASS();
|
|
}
|
|
|
|
void test_async_python_to_python_stays_safe() {
|
|
TEST(async_python_to_python_stays_safe);
|
|
auto r = ConcurrencyTranslator::analyze("async def f(): await g()", "python", "python");
|
|
CHECK(r.hasPattern("async/await"), "expected async pattern");
|
|
CHECK(r.translations[0].safety == ConcurrencySafety::Safe, "python async should stay safe");
|
|
PASS();
|
|
}
|
|
|
|
void test_review_count_aggregates_multiple_translations() {
|
|
TEST(review_count_aggregates_multiple_translations);
|
|
auto r = ConcurrencyTranslator::analyze(
|
|
"async def f(): await g()\nnew Thread(() -> {}).start();",
|
|
"python",
|
|
"java");
|
|
CHECK(r.translations.size() >= 2, "expected async + thread translations");
|
|
CHECK(r.countNeedsReview() >= 1, "expected review-required mappings");
|
|
PASS();
|
|
}
|
|
|
|
int main() {
|
|
std::cout << "Step 452: Concurrency Model Translation Tests\n";
|
|
|
|
test_async_python_to_rust_needs_runtime_review(); // 1
|
|
test_async_to_c_is_unsafe(); // 2
|
|
test_thread_java_to_go_maps_to_goroutine(); // 3
|
|
test_thread_to_python_marks_gil_review(); // 4
|
|
test_channels_go_to_rust_mpsc(); // 5
|
|
test_mutex_java_to_c_requires_review(); // 6
|
|
test_source_model_prefers_async_when_present(); // 7
|
|
test_target_model_defaults_for_javascript(); // 8
|
|
test_no_patterns_on_plain_code(); // 9
|
|
test_multiple_patterns_detected(); // 10
|
|
test_async_python_to_python_stays_safe(); // 11
|
|
test_review_count_aggregates_multiple_translations(); // 12
|
|
|
|
std::cout << "\nResults: " << passed << "/" << (passed + failed)
|
|
<< " passed\n";
|
|
return failed == 0 ? 0 : 1;
|
|
}
|