Chromium Code Reviews| 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/remote_security_key_message_reader.h" | |
| 6 | |
| 7 #include <cstdint> | |
| 8 #include <string> | |
| 9 #include <utility> | |
| 10 | |
| 11 #include "base/bind.h" | |
| 12 #include "base/memory/scoped_ptr.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::RemoteSecurityKeyMessageType kTestMessageType = | |
| 21 remoting::RemoteSecurityKeyMessageType::CONNECT; | |
| 22 const uint32_t kMaxSecurityKeyMessageByteCount = 256 * 1024; | |
| 23 } // namespace | |
| 24 | |
| 25 namespace remoting { | |
| 26 | |
| 27 class RemoteSecurityKeyMessageReaderTest : public testing::Test { | |
| 28 public: | |
| 29 RemoteSecurityKeyMessageReaderTest(); | |
| 30 ~RemoteSecurityKeyMessageReaderTest() override; | |
| 31 | |
| 32 // SecurityKeyMessageCallback passed to the Reader. Stores |message| so it can | |
| 33 // be verified by tests. | |
| 34 void OnMessage(scoped_ptr<SecurityKeyMessage> message); | |
| 35 | |
| 36 protected: | |
| 37 // testing::Test interface. | |
| 38 void SetUp() override; | |
| 39 | |
| 40 // Runs the MessageLoop until the reader has completed and called back. | |
| 41 void Run(); | |
| 42 | |
| 43 // Writes a message (header+code+body) to the write-end of the pipe. | |
| 44 void WriteMessage(RemoteSecurityKeyMessageType message_type, | |
| 45 const std::string& message_payload); | |
| 46 | |
| 47 // Writes some data to the write-end of the pipe. | |
| 48 void WriteData(const char* data, int length); | |
| 49 | |
| 50 scoped_ptr<RemoteSecurityKeyMessageReader> reader_; | |
| 51 base::File read_file_; | |
| 52 base::File write_file_; | |
| 53 | |
| 54 std::vector<scoped_ptr<SecurityKeyMessage>> messages_received_; | |
| 55 | |
| 56 private: | |
| 57 base::MessageLoopForIO message_loop_; | |
| 58 base::RunLoop run_loop_; | |
| 59 | |
| 60 DISALLOW_COPY_AND_ASSIGN(RemoteSecurityKeyMessageReaderTest); | |
| 61 }; | |
| 62 | |
| 63 RemoteSecurityKeyMessageReaderTest::RemoteSecurityKeyMessageReaderTest() {} | |
| 64 | |
| 65 RemoteSecurityKeyMessageReaderTest::~RemoteSecurityKeyMessageReaderTest() {} | |
| 66 | |
| 67 void RemoteSecurityKeyMessageReaderTest::SetUp() { | |
| 68 ASSERT_TRUE(MakePipe(&read_file_, &write_file_)); | |
| 69 reader_.reset(new RemoteSecurityKeyMessageReader(std::move(read_file_))); | |
| 70 | |
| 71 // base::Unretained is safe since no further tasks can run after | |
| 72 // RunLoop::Run() returns. | |
| 73 reader_->Start(base::Bind(&RemoteSecurityKeyMessageReaderTest::OnMessage, | |
| 74 base::Unretained(this)), | |
| 75 run_loop_.QuitClosure()); | |
| 76 } | |
| 77 | |
| 78 void RemoteSecurityKeyMessageReaderTest::Run() { | |
| 79 // Close the write-end, so the reader doesn't block waiting for more data. | |
| 80 write_file_.Close(); | |
| 81 run_loop_.Run(); | |
| 82 } | |
| 83 | |
| 84 void RemoteSecurityKeyMessageReaderTest::OnMessage( | |
| 85 scoped_ptr<SecurityKeyMessage> message) { | |
| 86 messages_received_.push_back(std::move(message)); | |
| 87 } | |
| 88 | |
| 89 void RemoteSecurityKeyMessageReaderTest::WriteMessage( | |
| 90 RemoteSecurityKeyMessageType message_type, | |
| 91 const std::string& message_payload) { | |
| 92 uint32_t length = | |
| 93 SecurityKeyMessage::kMessageTypeSizeBytes + message_payload.size(); | |
| 94 WriteData(reinterpret_cast<char*>(&length), | |
| 95 SecurityKeyMessage::kHeaderSizeBytes); | |
| 96 WriteData(reinterpret_cast<char*>(&message_type), | |
| 97 SecurityKeyMessage::kMessageTypeSizeBytes); | |
| 98 if (!message_payload.empty()) { | |
| 99 WriteData(message_payload.data(), message_payload.size()); | |
| 100 } | |
| 101 } | |
| 102 | |
| 103 void RemoteSecurityKeyMessageReaderTest::WriteData(const char* data, | |
| 104 int length) { | |
| 105 int written = write_file_.WriteAtCurrentPos(data, length); | |
| 106 ASSERT_EQ(length, written); | |
| 107 } | |
| 108 | |
| 109 TEST_F(RemoteSecurityKeyMessageReaderTest, EnsureReaderTornDownCleanly) { | |
| 110 // This test is different from the others as the files used for reading and | |
| 111 // writing are still open when the reader instance is destroyed. This test is | |
| 112 // meant to ensure that no asserts/exceptions/hangs occur during shutdown. | |
| 113 WriteMessage(kTestMessageType, std::string()); | |
| 114 reader_.reset(); | |
| 115 } | |
| 116 | |
| 117 TEST_F(RemoteSecurityKeyMessageReaderTest, SingleMessageWithNoPayload) { | |
| 118 WriteMessage(kTestMessageType, std::string()); | |
| 119 Run(); | |
| 120 ASSERT_EQ(1u, messages_received_.size()); | |
| 121 ASSERT_EQ(kTestMessageType, messages_received_[0]->type()); | |
| 122 ASSERT_EQ("", messages_received_[0]->payload()); | |
| 123 } | |
| 124 | |
| 125 TEST_F(RemoteSecurityKeyMessageReaderTest, SingleMessageWithPayload) { | |
| 126 std::string payload("I AM A VALID MESSAGE PAYLOAD!!!!!!!!!!!!!!!!!!!!!!"); | |
| 127 WriteMessage(kTestMessageType, payload); | |
| 128 Run(); | |
| 129 ASSERT_EQ(1u, messages_received_.size()); | |
| 130 ASSERT_EQ(kTestMessageType, messages_received_[0]->type()); | |
| 131 ASSERT_EQ(payload, messages_received_[0]->payload()); | |
| 132 } | |
| 133 | |
| 134 TEST_F(RemoteSecurityKeyMessageReaderTest, SingleMessageWithLargePayload) { | |
| 135 std::string payload(kMaxSecurityKeyMessageByteCount - | |
| 136 SecurityKeyMessage::kMessageTypeSizeBytes, | |
| 137 'Y'); | |
| 138 WriteMessage(kTestMessageType, payload); | |
| 139 Run(); | |
| 140 ASSERT_EQ(1u, messages_received_.size()); | |
| 141 ASSERT_EQ(kTestMessageType, messages_received_[0]->type()); | |
| 142 ASSERT_EQ(payload, messages_received_[0]->payload()); | |
| 143 } | |
| 144 | |
| 145 TEST_F(RemoteSecurityKeyMessageReaderTest, EmptyFile) { | |
| 146 Run(); | |
| 147 ASSERT_EQ(0u, messages_received_.size()); | |
| 148 } | |
| 149 | |
| 150 TEST_F(RemoteSecurityKeyMessageReaderTest, InvalidMessageLength) { | |
| 151 uint32_t length = kMaxSecurityKeyMessageByteCount + 1; | |
| 152 ASSERT_FALSE(SecurityKeyMessage::IsValidMessageSize(length)); | |
| 153 WriteData(reinterpret_cast<char*>(&length), sizeof(length)); | |
| 154 Run(); | |
| 155 ASSERT_EQ(0u, messages_received_.size()); | |
| 156 } | |
| 157 | |
| 158 TEST_F(RemoteSecurityKeyMessageReaderTest, ShortHeader) { | |
| 159 // Write only 3 bytes - the message length header is supposed to be 4 bytes. | |
| 160 WriteData("xxx", SecurityKeyMessage::kHeaderSizeBytes - 1); | |
| 161 Run(); | |
| 162 ASSERT_EQ(0u, messages_received_.size()); | |
| 163 } | |
| 164 | |
| 165 TEST_F(RemoteSecurityKeyMessageReaderTest, ZeroLengthMessage) { | |
| 166 uint32_t length = 0; | |
| 167 WriteData(reinterpret_cast<char*>(&length), sizeof(length)); | |
| 168 Run(); | |
| 169 ASSERT_EQ(0u, messages_received_.size()); | |
| 170 } | |
| 171 | |
| 172 TEST_F(RemoteSecurityKeyMessageReaderTest, MissingControlCode) { | |
| 173 uint32_t length = 1; | |
| 174 WriteData(reinterpret_cast<char*>(&length), sizeof(length)); | |
| 175 Run(); | |
| 176 ASSERT_EQ(0u, messages_received_.size()); | |
| 177 } | |
| 178 | |
| 179 TEST_F(RemoteSecurityKeyMessageReaderTest, MissingPayload) { | |
| 180 uint32_t length = 2; | |
| 181 WriteData(reinterpret_cast<char*>(&length), sizeof(length)); | |
| 182 | |
| 183 char test_control_code = static_cast<char>(kTestMessageType); | |
| 184 WriteData(&test_control_code, sizeof(test_control_code)); | |
| 185 Run(); | |
| 186 ASSERT_EQ(0u, messages_received_.size()); | |
| 187 } | |
| 188 | |
| 189 TEST_F(RemoteSecurityKeyMessageReaderTest, MultipleMessages) { | |
| 190 std::vector<std::string> payloads({"", "S", // Really short | |
| 191 "", "Short", "", "Medium Length", "", | |
| 192 "Longer than medium, but not super long", | |
| 193 "", std::string(2048, 'Y'), ""}); | |
| 194 | |
| 195 for (size_t i = 0; i < payloads.size(); i++) { | |
|
Sergey Ulanov
2016/03/30 21:34:28
for (auto& payload : payloads)
joedow
2016/03/31 01:45:12
Done.
| |
| 196 WriteMessage(kTestMessageType, payloads[i]); | |
| 197 } | |
| 198 | |
| 199 Run(); | |
| 200 ASSERT_EQ(payloads.size(), messages_received_.size()); | |
| 201 | |
| 202 for (size_t i = 0; i < payloads.size(); i++) { | |
| 203 ASSERT_EQ(kTestMessageType, messages_received_[i]->type()); | |
| 204 ASSERT_EQ(payloads[i], messages_received_[i]->payload()); | |
| 205 } | |
| 206 } | |
| 207 | |
| 208 } // namespace remoting | |
| OLD | NEW |