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