aboutsummaryrefslogtreecommitdiff
path: root/devices/uart/unittest_uart_16550.cc
blob: f8124bb69c4c06666077b718d4d8a7d2fac2952b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
#include "sys_io.hh"
#include <gtest/gtest.h>

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);
}