#include "uart.h" #include "uart_async.h" #include "fake_uart.h" #include #include #include #include #include #include using namespace ::testing; namespace { std::atomic terminate; std::counting_semaphore<12345> got_stuff(0); buffer rx; using namespace std::literals::chrono_literals; } std::string drain_n(size_t n, std::chrono::system_clock::duration timeout) { std::string txtout; auto begin = std::chrono::system_clock::now(); while (std::chrono::system_clock::now() < begin + timeout) { auto out = FakeUart_Drain(n); if (out.data.empty()) { continue; } auto strout = std::string_view(reinterpret_cast(out.data.data()), out.data.size()); n -= out.data.size(); txtout.append(strout); if (n < 1) { return txtout; } } return ""; } TEST(Uart, BasicSend) { FakeUart_Reset(); terminate = false; constexpr std::string_view kTestData = "blarg"; auto buff = std::as_bytes(std::span{kTestData}); async::schedule(UartWrite(buff).h); std::thread t( []() { async::main_loop([]() -> bool { return terminate; }); }); std::string strout = drain_n(kTestData.size(), 1s); EXPECT_EQ(strout, kTestData); terminate = true; t.join(); } async::task<> test_echo() { async::task reader = UartReadLoop(); async::gimme> feeder; async::task<> writer = UartWriteLoop(feeder); writer.h.resume(); // advance to first yield while (1) { uint8_t c = co_await reader; feeder.feed(std::as_bytes(std::span{&c, 1})); got_stuff.release(); } } TEST(Uart, Echo) { FakeUart_Reset(); terminate = false; constexpr std::string_view kTestData = "blargblaektrkblalasrjkh1!!"; auto buff = std::as_bytes(std::span{kTestData}); async::schedule(test_echo().h); std::thread t( []() { async::main_loop([]() -> bool { return terminate; }); }); for (int j = 0; j < 100; j++) { FakeUart_Feed(buff); std::string txtout = drain_n(kTestData.size(), 1s); ASSERT_EQ(txtout, kTestData); } terminate = true; t.join(); }