| OLD | NEW |
| (Empty) |
| 1 // Copyright 2016 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 "remoting/host/security_key/security_key_message_reader_impl.h" | |
| 6 | |
| 7 #include <cstdint> | |
| 8 #include <memory> | |
| 9 #include <string> | |
| 10 #include <utility> | |
| 11 | |
| 12 #include "base/bind.h" | |
| 13 #include "base/message_loop/message_loop.h" | |
| 14 #include "base/run_loop.h" | |
| 15 #include "remoting/host/security_key/security_key_message.h" | |
| 16 #include "remoting/host/setup/test_util.h" | |
| 17 #include "testing/gtest/include/gtest/gtest.h" | |
| 18 | |
| 19 namespace { | |
| 20 const remoting::SecurityKeyMessageType kTestMessageType = | |
| 21 remoting::SecurityKeyMessageType::CONNECT; | |
| 22 const uint32_t kMaxSecurityKeyMessageByteCount = 256 * 1024; | |
| 23 } // namespace | |
| 24 | |
| 25 namespace remoting { | |
| 26 | |
| 27 class SecurityKeyMessageReaderImplTest : public testing::Test { | |
| 28 public: | |
| 29 SecurityKeyMessageReaderImplTest(); | |
| 30 ~SecurityKeyMessageReaderImplTest() override; | |
| 31 | |
| 32 // SecurityKeyMessageCallback passed to the Reader. Stores |message| so it can | |
| 33 // be verified by tests. | |
| 34 void OnMessage(std::unique_ptr<SecurityKeyMessage> message); | |
| 35 | |
| 36 // Used as a callback to signal completion. | |
| 37 void OperationComplete(); | |
| 38 | |
| 39 protected: | |
| 40 // testing::Test interface. | |
| 41 void SetUp() override; | |
| 42 | |
| 43 // Runs the MessageLoop until the reader has completed and called back. | |
| 44 void RunLoop(); | |
| 45 | |
| 46 // Closes |write_file_| and runs the MessageLoop until the reader has | |
| 47 // completed and called back. | |
| 48 void CloseWriteFileAndRunLoop(); | |
| 49 | |
| 50 // Writes a message (header+code+body) to the write-end of the pipe. | |
| 51 void WriteMessage(SecurityKeyMessageType message_type, | |
| 52 const std::string& message_payload); | |
| 53 | |
| 54 // Writes some data to the write-end of the pipe. | |
| 55 void WriteData(const char* data, int length); | |
| 56 | |
| 57 std::unique_ptr<SecurityKeyMessageReader> reader_; | |
| 58 base::File read_file_; | |
| 59 base::File write_file_; | |
| 60 | |
| 61 std::vector<std::unique_ptr<SecurityKeyMessage>> messages_received_; | |
| 62 | |
| 63 private: | |
| 64 base::MessageLoopForIO message_loop_; | |
| 65 std::unique_ptr<base::RunLoop> run_loop_; | |
| 66 | |
| 67 DISALLOW_COPY_AND_ASSIGN(SecurityKeyMessageReaderImplTest); | |
| 68 }; | |
| 69 | |
| 70 SecurityKeyMessageReaderImplTest::SecurityKeyMessageReaderImplTest() | |
| 71 : run_loop_(new base::RunLoop()) {} | |
| 72 | |
| 73 SecurityKeyMessageReaderImplTest::~SecurityKeyMessageReaderImplTest() {} | |
| 74 | |
| 75 void SecurityKeyMessageReaderImplTest::SetUp() { | |
| 76 ASSERT_TRUE(MakePipe(&read_file_, &write_file_)); | |
| 77 reader_.reset(new SecurityKeyMessageReaderImpl(std::move(read_file_))); | |
| 78 | |
| 79 // base::Unretained is safe since no further tasks can run after | |
| 80 // RunLoop::Run() returns. | |
| 81 reader_->Start( | |
| 82 base::Bind(&SecurityKeyMessageReaderImplTest::OnMessage, | |
| 83 base::Unretained(this)), | |
| 84 base::Bind(&SecurityKeyMessageReaderImplTest::OperationComplete, | |
| 85 base::Unretained(this))); | |
| 86 } | |
| 87 | |
| 88 void SecurityKeyMessageReaderImplTest::RunLoop() { | |
| 89 run_loop_->Run(); | |
| 90 run_loop_.reset(new base::RunLoop()); | |
| 91 } | |
| 92 | |
| 93 void SecurityKeyMessageReaderImplTest::CloseWriteFileAndRunLoop() { | |
| 94 write_file_.Close(); | |
| 95 run_loop_->Run(); | |
| 96 run_loop_.reset(new base::RunLoop()); | |
| 97 } | |
| 98 | |
| 99 void SecurityKeyMessageReaderImplTest::OnMessage( | |
| 100 std::unique_ptr<SecurityKeyMessage> message) { | |
| 101 messages_received_.push_back(std::move(message)); | |
| 102 OperationComplete(); | |
| 103 } | |
| 104 | |
| 105 void SecurityKeyMessageReaderImplTest::OperationComplete() { | |
| 106 run_loop_->Quit(); | |
| 107 } | |
| 108 | |
| 109 void SecurityKeyMessageReaderImplTest::WriteMessage( | |
| 110 SecurityKeyMessageType message_type, | |
| 111 const std::string& message_payload) { | |
| 112 uint32_t length = | |
| 113 SecurityKeyMessage::kMessageTypeSizeBytes + message_payload.size(); | |
| 114 WriteData(reinterpret_cast<char*>(&length), | |
| 115 SecurityKeyMessage::kHeaderSizeBytes); | |
| 116 WriteData(reinterpret_cast<char*>(&message_type), | |
| 117 SecurityKeyMessage::kMessageTypeSizeBytes); | |
| 118 if (!message_payload.empty()) { | |
| 119 WriteData(message_payload.data(), message_payload.size()); | |
| 120 } | |
| 121 } | |
| 122 | |
| 123 void SecurityKeyMessageReaderImplTest::WriteData(const char* data, int length) { | |
| 124 int written = write_file_.WriteAtCurrentPos(data, length); | |
| 125 ASSERT_EQ(length, written); | |
| 126 } | |
| 127 | |
| 128 TEST_F(SecurityKeyMessageReaderImplTest, SingleMessageWithNoPayload) { | |
| 129 WriteMessage(kTestMessageType, std::string()); | |
| 130 RunLoop(); | |
| 131 ASSERT_EQ(1u, messages_received_.size()); | |
| 132 ASSERT_EQ(kTestMessageType, messages_received_[0]->type()); | |
| 133 ASSERT_EQ("", messages_received_[0]->payload()); | |
| 134 | |
| 135 CloseWriteFileAndRunLoop(); | |
| 136 } | |
| 137 | |
| 138 TEST_F(SecurityKeyMessageReaderImplTest, SingleMessageWithPayload) { | |
| 139 std::string payload("I AM A VALID MESSAGE PAYLOAD!!!!!!!!!!!!!!!!!!!!!!"); | |
| 140 WriteMessage(kTestMessageType, payload); | |
| 141 RunLoop(); | |
| 142 ASSERT_EQ(1u, messages_received_.size()); | |
| 143 ASSERT_EQ(kTestMessageType, messages_received_[0]->type()); | |
| 144 ASSERT_EQ(payload, messages_received_[0]->payload()); | |
| 145 | |
| 146 CloseWriteFileAndRunLoop(); | |
| 147 } | |
| 148 | |
| 149 TEST_F(SecurityKeyMessageReaderImplTest, SingleMessageViaSingleWrite) { | |
| 150 // All other tests write in 2-3 chunks, this writes the message in one shot. | |
| 151 std::string payload("LLLLTI am the best payload in the history of testing."); | |
| 152 // Overwite the 'L' values with the actual length. | |
| 153 uint8_t length = payload.size() - SecurityKeyMessage::kHeaderSizeBytes; | |
| 154 payload[0] = static_cast<char>(length); | |
| 155 payload[1] = 0; | |
| 156 payload[2] = 0; | |
| 157 payload[3] = 0; | |
| 158 // Overwite the 'T' value with the actual type. | |
| 159 payload[4] = static_cast<char>(kTestMessageType); | |
| 160 WriteData(payload.data(), payload.size()); | |
| 161 RunLoop(); | |
| 162 ASSERT_EQ(1u, messages_received_.size()); | |
| 163 ASSERT_EQ(kTestMessageType, messages_received_[0]->type()); | |
| 164 ASSERT_EQ(payload.substr(5), messages_received_[0]->payload()); | |
| 165 | |
| 166 CloseWriteFileAndRunLoop(); | |
| 167 } | |
| 168 | |
| 169 TEST_F(SecurityKeyMessageReaderImplTest, SingleMessageViaMultipleWrites) { | |
| 170 // All other tests write in 2-3 chunks, this writes the message byte by byte. | |
| 171 std::string payload("LLLLTI am the worst payload in the history of testing."); | |
| 172 // Overwite the 'L' values with the actual length. | |
| 173 uint8_t length = payload.size() - SecurityKeyMessage::kHeaderSizeBytes; | |
| 174 payload[0] = static_cast<char>(length); | |
| 175 payload[1] = 0; | |
| 176 payload[2] = 0; | |
| 177 payload[3] = 0; | |
| 178 // Overwite the 'T' value with the actual type. | |
| 179 payload[4] = static_cast<char>(kTestMessageType); | |
| 180 | |
| 181 for (uint32_t i = 0; i < payload.size(); i++) { | |
| 182 WriteData(&payload[i], 1); | |
| 183 } | |
| 184 RunLoop(); | |
| 185 ASSERT_EQ(1u, messages_received_.size()); | |
| 186 ASSERT_EQ(kTestMessageType, messages_received_[0]->type()); | |
| 187 ASSERT_EQ(payload.substr(5), messages_received_[0]->payload()); | |
| 188 | |
| 189 CloseWriteFileAndRunLoop(); | |
| 190 } | |
| 191 | |
| 192 TEST_F(SecurityKeyMessageReaderImplTest, SingleMessageWithLargePayload) { | |
| 193 std::string payload(kMaxSecurityKeyMessageByteCount - | |
| 194 SecurityKeyMessage::kMessageTypeSizeBytes, | |
| 195 'Y'); | |
| 196 WriteMessage(kTestMessageType, payload); | |
| 197 RunLoop(); | |
| 198 ASSERT_EQ(1u, messages_received_.size()); | |
| 199 ASSERT_EQ(kTestMessageType, messages_received_[0]->type()); | |
| 200 ASSERT_EQ(payload, messages_received_[0]->payload()); | |
| 201 | |
| 202 CloseWriteFileAndRunLoop(); | |
| 203 } | |
| 204 | |
| 205 TEST_F(SecurityKeyMessageReaderImplTest, EmptyFile) { | |
| 206 CloseWriteFileAndRunLoop(); | |
| 207 ASSERT_EQ(0u, messages_received_.size()); | |
| 208 } | |
| 209 | |
| 210 TEST_F(SecurityKeyMessageReaderImplTest, InvalidMessageLength) { | |
| 211 uint32_t length = kMaxSecurityKeyMessageByteCount + 1; | |
| 212 ASSERT_FALSE(SecurityKeyMessage::IsValidMessageSize(length)); | |
| 213 WriteData(reinterpret_cast<char*>(&length), sizeof(length)); | |
| 214 CloseWriteFileAndRunLoop(); | |
| 215 ASSERT_EQ(0u, messages_received_.size()); | |
| 216 } | |
| 217 | |
| 218 TEST_F(SecurityKeyMessageReaderImplTest, ShortHeader) { | |
| 219 // Write only 3 bytes - the message length header is supposed to be 4 bytes. | |
| 220 WriteData("xxx", SecurityKeyMessage::kHeaderSizeBytes - 1); | |
| 221 CloseWriteFileAndRunLoop(); | |
| 222 ASSERT_EQ(0u, messages_received_.size()); | |
| 223 } | |
| 224 | |
| 225 TEST_F(SecurityKeyMessageReaderImplTest, ZeroLengthMessage) { | |
| 226 uint32_t length = 0; | |
| 227 WriteData(reinterpret_cast<char*>(&length), sizeof(length)); | |
| 228 CloseWriteFileAndRunLoop(); | |
| 229 ASSERT_EQ(0u, messages_received_.size()); | |
| 230 } | |
| 231 | |
| 232 TEST_F(SecurityKeyMessageReaderImplTest, MissingControlCode) { | |
| 233 uint32_t length = 1; | |
| 234 WriteData(reinterpret_cast<char*>(&length), sizeof(length)); | |
| 235 CloseWriteFileAndRunLoop(); | |
| 236 ASSERT_EQ(0u, messages_received_.size()); | |
| 237 } | |
| 238 | |
| 239 TEST_F(SecurityKeyMessageReaderImplTest, MissingPayload) { | |
| 240 uint32_t length = 2; | |
| 241 WriteData(reinterpret_cast<char*>(&length), sizeof(length)); | |
| 242 | |
| 243 char test_control_code = static_cast<char>(kTestMessageType); | |
| 244 WriteData(&test_control_code, sizeof(test_control_code)); | |
| 245 CloseWriteFileAndRunLoop(); | |
| 246 ASSERT_EQ(0u, messages_received_.size()); | |
| 247 } | |
| 248 | |
| 249 TEST_F(SecurityKeyMessageReaderImplTest, MultipleMessages) { | |
| 250 std::vector<std::string> payloads({"", "S", // Really short | |
| 251 "", "Short", "", "Medium Length", "", | |
| 252 "Longer than medium, but not super long", | |
| 253 "", std::string(2048, 'Y'), ""}); | |
| 254 for (size_t i = 0; i < payloads.size(); i++) { | |
| 255 WriteMessage(kTestMessageType, payloads[i]); | |
| 256 RunLoop(); | |
| 257 ASSERT_EQ(i + 1, messages_received_.size()); | |
| 258 } | |
| 259 CloseWriteFileAndRunLoop(); | |
| 260 | |
| 261 for (size_t i = 0; i < payloads.size(); i++) { | |
| 262 ASSERT_EQ(kTestMessageType, messages_received_[i]->type()); | |
| 263 ASSERT_EQ(payloads[i], messages_received_[i]->payload()); | |
| 264 } | |
| 265 } | |
| 266 | |
| 267 } // namespace remoting | |
| OLD | NEW |