#include "sys_io.hh" #include using ::testing::_; using ::testing::MockFunction; using ::testing::Return; namespace k { extern "C" { #include "uart.h" #include "uart_16550.h" } } // namespace k class Uart16550 : public ::testing::Test { protected: void SetUp() { ASSERT_FALSE(mockPort); mockPort.reset(new MockPort); } void TearDown() { ASSERT_TRUE(mockPort); mockPort.reset(); } }; TEST_F(Uart16550, uart_thre) { // set up expectations EXPECT_CALL(*mockPort, inb(k::COM1 + k::LineStatus)).Times(1).WillOnce(Return(k::THRE)); const auto result = uart_thre(k::COM1); EXPECT_TRUE(result); } TEST_F(Uart16550, uart_putc) { k::FILE f{k::COM1, nullptr, nullptr, nullptr}; // set up expectations EXPECT_CALL(*mockPort, inb(k::COM1 + k::LineStatus)).Times(1).WillRepeatedly(Return(k::THRE)); EXPECT_CALL(*mockPort, outb('a', k::COM1)).Times(1); uart_putc(&f, 'a'); } TEST_F(Uart16550, uart_putc_newline) { k::FILE f{k::COM1, nullptr, nullptr, nullptr}; // set up expectations EXPECT_CALL(*mockPort, inb(k::COM1 + k::LineStatus)).Times(2).WillRepeatedly(Return(k::THRE)); EXPECT_CALL(*mockPort, outb('\n', k::COM1)).Times(1); EXPECT_CALL(*mockPort, outb('\r', k::COM1)).Times(1); uart_putc(&f, '\n'); } TEST_F(Uart16550, uart_puts) { k::FILE f{k::COM1, nullptr, nullptr, nullptr}; const char *string{"This is a test string to write over uart"}; const int length = (int)strlen(string); // set up expectations EXPECT_CALL(*mockPort, inb(k::COM1 + k::LineStatus)).Times(length).WillRepeatedly(Return(k::THRE)); EXPECT_CALL(*mockPort, outb(_, k::COM1)).Times(length); const auto result = uart_puts(&f, string, length); ASSERT_EQ(result, length); } TEST_F(Uart16550, uart_puts_WithUnknownLength) { k::FILE f{k::COM1, nullptr, nullptr, nullptr}; const char *string{"This is a test string to write over uart"}; const int length = (int)strlen(string); // set up expectations EXPECT_CALL(*mockPort, inb(k::COM1 + k::LineStatus)).Times(length).WillRepeatedly(Return(k::THRE)); EXPECT_CALL(*mockPort, outb(_, k::COM1)).Times(length); const auto result = uart_puts(&f, string, -1); ASSERT_EQ(result, length); } TEST_F(Uart16550, uart_puts_WithPartialLength) { k::FILE f{k::COM1, nullptr, nullptr, nullptr}; const char *string{"This is a test string to write over uart"}; const int length = (int)strlen(string); const int partial = 10; ASSERT_LT(partial, length); // set up expectations EXPECT_CALL(*mockPort, inb(k::COM1 + k::LineStatus)).Times(partial).WillRepeatedly(Return(k::THRE)); EXPECT_CALL(*mockPort, outb(_, k::COM1)).Times(partial); const auto result = uart_puts(&f, string, partial); ASSERT_EQ(result, partial); } TEST_F(Uart16550, uart_flush) { k::FILE f{k::COM1, nullptr, nullptr, nullptr}; // set up expectations // no mock calls are expected uart_flush(&f); }