synth/arm/uart_test.cc
Paul Mathieu f274749050 arm: add host uart driver tests
All host tests currently pass
Some async refactors may not work well on device, will try later
2023-06-02 23:33:01 -07:00

95 lines
2.3 KiB
C++

#include "uart.h"
#include "uart_async.h"
#include "fake_uart.h"
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <atomic>
#include <chrono>
#include <semaphore>
#include <thread>
using namespace ::testing;
namespace {
std::atomic<bool> 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<char*>(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<uint8_t> reader = UartReadLoop();
async::gimme<std::span<const std::byte>> 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();
}