OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "tools/battor_agent/battor_connection.h" | |
6 | |
7 #include "base/bind.h" | |
8 #include "base/bind_helpers.h" | |
9 #include "device/serial/serial.mojom.h" | |
10 #include "device/serial/test_serial_io_handler.h" | |
11 #include "testing/gtest/include/gtest/gtest.h" | |
12 #include "tools/battor_agent/battor_protocol_types.h" | |
13 | |
14 namespace { | |
15 | |
16 void NullWriteCallback(int, device::serial::SendError) {} | |
17 void NullReadCallback(int, device::serial::ReceiveError) {} | |
18 | |
19 } // namespace | |
20 | |
21 namespace battor { | |
22 | |
23 // TestableBattOrConnection uses a fake serial connection be testable. | |
24 class TestableBattOrConnection : public BattOrConnection { | |
25 public: | |
26 TestableBattOrConnection() : BattOrConnection(nullptr, nullptr) {} | |
27 scoped_refptr<device::SerialIoHandler> CreateIoHandler() override { | |
28 return device::TestSerialIoHandler::Create(); | |
29 } | |
30 | |
31 scoped_refptr<device::SerialIoHandler> GetIoHandler() { return io_handler_; } | |
32 }; | |
33 | |
34 // BattOrConnectionTest provides a BattOrConnection that captures the | |
35 // results of its commands. | |
36 class BattOrConnectionTest : public testing::Test { | |
37 protected: | |
38 scoped_ptr<TestableBattOrConnection> connection; | |
39 | |
40 void SetUp() override { | |
41 connection.reset(new TestableBattOrConnection()); | |
42 } | |
43 | |
44 void Connect() { | |
45 connection->Connect( | |
46 "/dev/test", base::Bind(&BattOrConnectionTest::CaptureConnectResult, | |
47 base::Unretained(this))); | |
48 } | |
49 | |
50 void CaptureConnectResult(bool success) { connect_success = success; } | |
51 | |
52 void SendControlMessage(BattOrControlMessageType type, | |
53 uint16_t param1, | |
54 uint16_t param2) { | |
55 BattOrControlMessage msg{type, param1, param2}; | |
56 connection->SendBytes( | |
57 base::Bind(&BattOrConnectionTest::CaptureSendBytesResults, | |
58 base::Unretained(this)), | |
59 BATTOR_MESSAGE_TYPE_CONTROL, reinterpret_cast<char*>(&msg), | |
60 sizeof(msg)); | |
61 } | |
62 | |
63 // Writes the specified bytes directly to the serial connectino. | |
64 void SendBytesRaw(const char* data, uint16_t bytes_to_send) { | |
65 std::vector<char> data_vector(data, data + bytes_to_send); | |
66 connection->GetIoHandler()->Write(make_scoped_ptr( | |
67 new device::SendBuffer(data_vector, base::Bind(&NullWriteCallback)))); | |
68 } | |
69 | |
70 void CaptureSendBytesResults(bool success) { send_success = success; } | |
71 | |
72 void ReadBytes(uint16_t bytes_to_read) { | |
73 connection->ReadBytes( | |
74 base::Bind(&BattOrConnectionTest::CaptureReadBytesResults, | |
75 base::Unretained(this)), | |
76 bytes_to_read); | |
77 } | |
78 | |
79 // Reads the specified number of bytes directly from the serial connection. | |
80 scoped_refptr<net::IOBuffer> ReadBytesRaw(int bytes_to_read) { | |
81 scoped_refptr<net::IOBuffer> buffer( | |
82 new net::IOBuffer((size_t)bytes_to_read)); | |
83 | |
84 connection->GetIoHandler()->Read( | |
85 make_scoped_ptr(new device::ReceiveBuffer( | |
86 buffer, bytes_to_read, base::Bind(&NullReadCallback)))); | |
87 | |
88 return buffer; | |
89 } | |
90 | |
91 void CaptureReadBytesResults(bool success, | |
92 BattOrMessageType type, | |
93 scoped_ptr<std::vector<char>> bytes) { | |
94 read_success = success; | |
95 read_type = type; | |
96 read_bytes = bytes.Pass(); | |
97 } | |
98 | |
99 // Result from the last connect command. | |
100 bool connect_success; | |
Zhen Wang
2015/12/14 23:39:47
I think the practice is to make variables private
charliea (OOO until 10-5)
2015/12/15 23:50:04
Done.
I wasn't sure if this was the case in unit
| |
101 // Result from the last send command. | |
102 bool send_success; | |
103 // Results from the last read command. | |
104 bool read_success; | |
105 BattOrMessageType read_type; | |
106 scoped_ptr<std::vector<char>> read_bytes; | |
107 }; | |
108 | |
109 TEST_F(BattOrConnectionTest, InitSendsCorrectBytes) { | |
110 Connect(); | |
111 ASSERT_TRUE(connect_success); | |
112 | |
113 SendControlMessage(BATTOR_CONTROL_MESSAGE_TYPE_INIT, 0, 0); | |
114 | |
115 const char expected_data[] = { | |
116 BATTOR_SPECIAL_BYTE_START, BATTOR_MESSAGE_TYPE_CONTROL, | |
117 BATTOR_SPECIAL_BYTE_ESCAPE, BATTOR_CONTROL_MESSAGE_TYPE_INIT, | |
118 BATTOR_SPECIAL_BYTE_ESCAPE, 0x00, | |
119 BATTOR_SPECIAL_BYTE_ESCAPE, 0x00, | |
120 BATTOR_SPECIAL_BYTE_ESCAPE, 0x00, | |
121 BATTOR_SPECIAL_BYTE_ESCAPE, 0x00, | |
122 BATTOR_SPECIAL_BYTE_END, | |
123 }; | |
124 | |
125 ASSERT_TRUE(send_success); | |
126 ASSERT_EQ(0, std::memcmp(ReadBytesRaw(13)->data(), expected_data, 13)); | |
127 } | |
128 | |
129 TEST_F(BattOrConnectionTest, ResetSendsCorrectBytes) { | |
130 Connect(); | |
131 ASSERT_TRUE(connect_success); | |
132 | |
133 SendControlMessage(BATTOR_CONTROL_MESSAGE_TYPE_RESET, 0, 0); | |
134 | |
135 const char expected_data[] = { | |
136 BATTOR_SPECIAL_BYTE_START, | |
137 BATTOR_MESSAGE_TYPE_CONTROL, | |
138 BATTOR_CONTROL_MESSAGE_TYPE_RESET, | |
139 BATTOR_SPECIAL_BYTE_ESCAPE, | |
140 0x00, | |
141 BATTOR_SPECIAL_BYTE_ESCAPE, | |
142 0x00, | |
143 BATTOR_SPECIAL_BYTE_ESCAPE, | |
144 0x00, | |
145 BATTOR_SPECIAL_BYTE_ESCAPE, | |
146 0x00, | |
147 BATTOR_SPECIAL_BYTE_END, | |
148 }; | |
149 | |
150 ASSERT_TRUE(send_success); | |
151 ASSERT_EQ(0, std::memcmp(ReadBytesRaw(12)->data(), expected_data, 12)); | |
152 } | |
153 | |
154 TEST_F(BattOrConnectionTest, ReadBytesControlMessage) { | |
155 Connect(); | |
156 ASSERT_TRUE(connect_success); | |
157 | |
158 const char data[] = { | |
159 BATTOR_SPECIAL_BYTE_START, | |
160 BATTOR_MESSAGE_TYPE_CONTROL, | |
161 BATTOR_CONTROL_MESSAGE_TYPE_RESET, | |
162 0x04, | |
163 0x04, | |
164 0x04, | |
165 0x04, | |
166 BATTOR_SPECIAL_BYTE_END, | |
167 }; | |
168 SendBytesRaw(data, 8); | |
169 | |
170 ReadBytes(5); | |
171 | |
172 const char expected[] = {BATTOR_CONTROL_MESSAGE_TYPE_RESET, 0x04, 0x04, 0x04, | |
173 0x04}; | |
174 | |
175 ASSERT_TRUE(read_success); | |
176 ASSERT_EQ(BATTOR_MESSAGE_TYPE_CONTROL, read_type); | |
177 ASSERT_EQ(0, std::memcmp(read_bytes->data(), expected, 5)); | |
178 } | |
179 | |
180 TEST_F(BattOrConnectionTest, ReadBytesEmptyStream) { | |
181 Connect(); | |
182 ASSERT_TRUE(connect_success); | |
183 | |
184 ReadBytes(1); | |
185 | |
186 ASSERT_FALSE(read_success); | |
187 } | |
188 | |
189 TEST_F(BattOrConnectionTest, ReadBytesWithEscapeCharacters) { | |
190 Connect(); | |
191 ASSERT_TRUE(connect_success); | |
192 | |
193 const char data[] = { | |
194 BATTOR_SPECIAL_BYTE_START, | |
195 BATTOR_MESSAGE_TYPE_CONTROL_ACK, | |
196 BATTOR_CONTROL_MESSAGE_TYPE_RESET, | |
197 BATTOR_SPECIAL_BYTE_ESCAPE, | |
198 0x00, | |
199 BATTOR_SPECIAL_BYTE_END, | |
200 }; | |
201 SendBytesRaw(data, 6); | |
202 | |
203 ReadBytes(2); | |
204 | |
205 const char expected[] = {BATTOR_CONTROL_MESSAGE_TYPE_RESET, 0x00}; | |
206 | |
207 ASSERT_TRUE(read_success); | |
208 ASSERT_EQ(BATTOR_MESSAGE_TYPE_CONTROL_ACK, read_type); | |
209 ASSERT_EQ(0, std::memcmp(read_bytes->data(), expected, 2)); | |
210 } | |
211 | |
212 TEST_F(BattOrConnectionTest, ReadBytesWithEscapeCharactersInSubsequentReads) { | |
213 Connect(); | |
214 ASSERT_TRUE(connect_success); | |
215 | |
216 // The first read should request 7 bytes. Of those 7 bytes, though, 2 of them | |
217 // are escape bytes, so we'll then do a second read of 2 bytes. In that second | |
218 // read, we'll see another escape byte, so we'll have to do a third read of 1 | |
219 // byte. That third read should complete the message. | |
220 const char data[] = { | |
221 // These bytes make up the first read. | |
222 BATTOR_SPECIAL_BYTE_START, BATTOR_MESSAGE_TYPE_CONTROL_ACK, | |
223 BATTOR_CONTROL_MESSAGE_TYPE_RESET, BATTOR_SPECIAL_BYTE_ESCAPE, 0x00, | |
224 BATTOR_SPECIAL_BYTE_ESCAPE, 0x00, | |
225 // These bytes make up the second read. | |
226 BATTOR_SPECIAL_BYTE_ESCAPE, 0x00, | |
227 // This byte makes up the third read. | |
228 BATTOR_SPECIAL_BYTE_END, | |
229 }; | |
230 SendBytesRaw(data, 10); | |
231 | |
232 ReadBytes(4); | |
233 | |
234 const char expected[] = {BATTOR_CONTROL_MESSAGE_TYPE_RESET, 0x00, 0x00, 0x00}; | |
235 | |
236 ASSERT_TRUE(read_success); | |
237 ASSERT_EQ(BATTOR_MESSAGE_TYPE_CONTROL_ACK, read_type); | |
238 ASSERT_EQ(0, std::memcmp(read_bytes->data(), expected, 4)); | |
239 } | |
240 | |
241 TEST_F(BattOrConnectionTest, ReadControlMessage) { | |
242 Connect(); | |
243 ASSERT_TRUE(connect_success); | |
244 | |
245 SendControlMessage(BATTOR_CONTROL_MESSAGE_TYPE_RESET, 4, 7); | |
246 ReadBytes(sizeof(BattOrControlMessage)); | |
247 | |
248 ASSERT_TRUE(read_success); | |
249 ASSERT_EQ(BATTOR_MESSAGE_TYPE_CONTROL, read_type); | |
250 | |
251 BattOrControlMessage* msg = | |
252 reinterpret_cast<BattOrControlMessage*>(read_bytes->data()); | |
253 | |
254 ASSERT_EQ(BATTOR_CONTROL_MESSAGE_TYPE_RESET, msg->type); | |
255 ASSERT_EQ(4, msg->param1); | |
256 ASSERT_EQ(7, msg->param2); | |
257 } | |
258 | |
259 } // namespace battor | |
OLD | NEW |