Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(410)

Side by Side Diff: remoting/host/native_messaging/native_messaging_reader_unittest.cc

Issue 2207153004: Fixing a hang in the native messaging hosts on Windows (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Adding a comment describing why we need to cancel the pending read operation on Windows. Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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/native_messaging/native_messaging_reader.h" 5 #include "remoting/host/native_messaging/native_messaging_reader.h"
6 6
7 #include <stdint.h> 7 #include <cstdint>
8
9 #include <memory> 8 #include <memory>
10 #include <utility> 9 #include <utility>
11 10
12 #include "base/bind.h" 11 #include "base/bind.h"
13 #include "base/message_loop/message_loop.h" 12 #include "base/message_loop/message_loop.h"
14 #include "base/run_loop.h" 13 #include "base/run_loop.h"
15 #include "base/values.h" 14 #include "base/values.h"
16 #include "remoting/host/setup/test_util.h" 15 #include "remoting/host/setup/test_util.h"
17 #include "testing/gtest/include/gtest/gtest.h" 16 #include "testing/gtest/include/gtest/gtest.h"
18 17
19 namespace remoting { 18 namespace remoting {
20 19
21 class NativeMessagingReaderTest : public testing::Test { 20 class NativeMessagingReaderTest : public testing::Test {
22 public: 21 public:
23 NativeMessagingReaderTest(); 22 NativeMessagingReaderTest();
24 ~NativeMessagingReaderTest() override; 23 ~NativeMessagingReaderTest() override;
25 24
26 void SetUp() override; 25 void SetUp() override;
27 26
28 // Starts the reader and runs the MessageLoop to completion. 27 // Runs the MessageLoop to completion.
29 void Run(); 28 void RunAndWaitForOperationComplete();
30 29
31 // MessageCallback passed to the Reader. Stores |message| so it can be 30 // MessageCallback passed to the Reader. Stores |message| so it can be
32 // verified by tests. 31 // verified by tests.
33 void OnMessage(std::unique_ptr<base::Value> message); 32 void OnMessage(std::unique_ptr<base::Value> message);
34 33
34 // Closure passed to the Reader, called back when the reader detects an error.
35 void OnError();
36
35 // Writes a message (header+body) to the write-end of the pipe. 37 // Writes a message (header+body) to the write-end of the pipe.
36 void WriteMessage(const std::string& message); 38 void WriteMessage(const std::string& message);
37 39
38 // Writes some data to the write-end of the pipe. 40 // Writes some data to the write-end of the pipe.
39 void WriteData(const char* data, int length); 41 void WriteData(const char* data, int length);
40 42
41 protected: 43 protected:
42 std::unique_ptr<NativeMessagingReader> reader_; 44 std::unique_ptr<NativeMessagingReader> reader_;
43 base::File read_file_; 45 base::File read_file_;
44 base::File write_file_; 46 base::File write_file_;
47 bool on_error_signaled_ = false;
45 std::unique_ptr<base::Value> message_; 48 std::unique_ptr<base::Value> message_;
46 49
47 private: 50 private:
48 // MessageLoop declared here, since the NativeMessageReader ctor requires a 51 // MessageLoop declared here, since the NativeMessageReader ctor requires a
49 // MessageLoop to have been created. 52 // MessageLoop to have been created.
50 base::MessageLoopForIO message_loop_; 53 base::MessageLoopForIO message_loop_;
51 base::RunLoop run_loop_; 54 std::unique_ptr<base::RunLoop> run_loop_;
52 }; 55 };
53 56
54 NativeMessagingReaderTest::NativeMessagingReaderTest() {} 57 NativeMessagingReaderTest::NativeMessagingReaderTest() {}
58
55 NativeMessagingReaderTest::~NativeMessagingReaderTest() {} 59 NativeMessagingReaderTest::~NativeMessagingReaderTest() {}
56 60
57 void NativeMessagingReaderTest::SetUp() { 61 void NativeMessagingReaderTest::SetUp() {
58 ASSERT_TRUE(MakePipe(&read_file_, &write_file_)); 62 ASSERT_TRUE(MakePipe(&read_file_, &write_file_));
59 reader_.reset(new NativeMessagingReader(std::move(read_file_))); 63 reader_.reset(new NativeMessagingReader(std::move(read_file_)));
60 } 64 run_loop_.reset(new base::RunLoop());
61
62 void NativeMessagingReaderTest::Run() {
63 // Close the write-end, so the reader doesn't block waiting for more data.
64 write_file_.Close();
65 65
66 // base::Unretained is safe since no further tasks can run after 66 // base::Unretained is safe since no further tasks can run after
67 // RunLoop::Run() returns. 67 // RunLoop::Run() returns.
68 reader_->Start( 68 reader_->Start(
69 base::Bind(&NativeMessagingReaderTest::OnMessage, base::Unretained(this)), 69 base::Bind(&NativeMessagingReaderTest::OnMessage, base::Unretained(this)),
70 run_loop_.QuitClosure()); 70 base::Bind(&NativeMessagingReaderTest::OnError, base::Unretained(this)));
71 run_loop_.Run(); 71 }
72
73 void NativeMessagingReaderTest::RunAndWaitForOperationComplete() {
74 run_loop_->Run();
75 run_loop_.reset(new base::RunLoop());
72 } 76 }
73 77
74 void NativeMessagingReaderTest::OnMessage( 78 void NativeMessagingReaderTest::OnMessage(
75 std::unique_ptr<base::Value> message) { 79 std::unique_ptr<base::Value> message) {
76 message_ = std::move(message); 80 message_ = std::move(message);
81 run_loop_->Quit();
82 }
83
84 void NativeMessagingReaderTest::OnError() {
85 on_error_signaled_ = true;
86 run_loop_->Quit();
77 } 87 }
78 88
79 void NativeMessagingReaderTest::WriteMessage(const std::string& message) { 89 void NativeMessagingReaderTest::WriteMessage(const std::string& message) {
80 uint32_t length = message.length(); 90 uint32_t length = message.length();
81 WriteData(reinterpret_cast<char*>(&length), 4); 91 WriteData(reinterpret_cast<char*>(&length), 4);
82 WriteData(message.data(), length); 92 WriteData(message.data(), length);
83 } 93 }
84 94
85 void NativeMessagingReaderTest::WriteData(const char* data, int length) { 95 void NativeMessagingReaderTest::WriteData(const char* data, int length) {
86 int written = write_file_.WriteAtCurrentPos(data, length); 96 int written = write_file_.WriteAtCurrentPos(data, length);
87 ASSERT_EQ(length, written); 97 ASSERT_EQ(length, written);
88 } 98 }
89 99
90 TEST_F(NativeMessagingReaderTest, GoodMessage) { 100 TEST_F(NativeMessagingReaderTest, ReaderDestroyedByClosingPipe) {
91 WriteMessage("{\"foo\": 42}"); 101 WriteMessage("{\"foo\": 42}");
92 Run(); 102 RunAndWaitForOperationComplete();
93 EXPECT_TRUE(message_); 103 ASSERT_FALSE(on_error_signaled_);
104
105 // Close the write end of the pipe while the reader is waiting for more data.
106 write_file_.Close();
107 RunAndWaitForOperationComplete();
108 ASSERT_TRUE(on_error_signaled_);
109 }
110
111 #if defined(OS_WIN)
112 // This scenario is only a problem on Windows as closing the write pipe there
113 // does not trigger the parent process to close the read pipe.
114 TEST_F(NativeMessagingReaderTest, ReaderDestroyedByOwner) {
115 WriteMessage("{\"foo\": 42}");
116 RunAndWaitForOperationComplete();
117 ASSERT_FALSE(on_error_signaled_);
118
119 // Destroy the reader while it is waiting for more data.
120 reader_.reset();
121 ASSERT_FALSE(on_error_signaled_);
122 }
123 #endif // defined(OS_WIN)
124
125 TEST_F(NativeMessagingReaderTest, SingleGoodMessage) {
126 WriteMessage("{\"foo\": 42}");
127 RunAndWaitForOperationComplete();
128 ASSERT_FALSE(on_error_signaled_);
129 ASSERT_TRUE(message_);
94 base::DictionaryValue* message_dict; 130 base::DictionaryValue* message_dict;
95 EXPECT_TRUE(message_->GetAsDictionary(&message_dict)); 131 ASSERT_TRUE(message_->GetAsDictionary(&message_dict));
96 int result; 132 int result;
97 EXPECT_TRUE(message_dict->GetInteger("foo", &result)); 133 ASSERT_TRUE(message_dict->GetInteger("foo", &result));
98 EXPECT_EQ(42, result); 134 ASSERT_EQ(42, result);
135 }
136
137 TEST_F(NativeMessagingReaderTest, MultipleGoodMessages) {
138 WriteMessage("{}");
139 RunAndWaitForOperationComplete();
140 ASSERT_FALSE(on_error_signaled_);
141 ASSERT_TRUE(message_);
142 base::DictionaryValue* message_dict;
143 ASSERT_TRUE(message_->GetAsDictionary(&message_dict));
144
145 int result;
146 WriteMessage("{\"foo\": 42}");
147 RunAndWaitForOperationComplete();
148 ASSERT_FALSE(on_error_signaled_);
149 ASSERT_TRUE(message_);
150 ASSERT_TRUE(message_->GetAsDictionary(&message_dict));
151 ASSERT_TRUE(message_dict->GetInteger("foo", &result));
152 ASSERT_EQ(42, result);
153
154 WriteMessage("{\"bar\": 43}");
155 RunAndWaitForOperationComplete();
156 ASSERT_FALSE(on_error_signaled_);
157 ASSERT_TRUE(message_);
158 ASSERT_TRUE(message_->GetAsDictionary(&message_dict));
159 ASSERT_TRUE(message_dict->GetInteger("bar", &result));
160 ASSERT_EQ(43, result);
161
162 WriteMessage("{\"baz\": 44}");
163 RunAndWaitForOperationComplete();
164 ASSERT_FALSE(on_error_signaled_);
165 ASSERT_TRUE(message_);
166 ASSERT_TRUE(message_->GetAsDictionary(&message_dict));
167 ASSERT_TRUE(message_dict->GetInteger("baz", &result));
168 ASSERT_EQ(44, result);
99 } 169 }
100 170
101 TEST_F(NativeMessagingReaderTest, InvalidLength) { 171 TEST_F(NativeMessagingReaderTest, InvalidLength) {
102 uint32_t length = 0xffffffff; 172 uint32_t length = 0xffffffff;
103 WriteData(reinterpret_cast<char*>(&length), 4); 173 WriteData(reinterpret_cast<char*>(&length), 4);
104 Run(); 174 RunAndWaitForOperationComplete();
105 EXPECT_FALSE(message_); 175 ASSERT_FALSE(message_);
176 ASSERT_TRUE(on_error_signaled_);
106 } 177 }
107 178
108 TEST_F(NativeMessagingReaderTest, EmptyFile) { 179 TEST_F(NativeMessagingReaderTest, EmptyFile) {
109 Run(); 180 write_file_.Close();
110 EXPECT_FALSE(message_); 181 RunAndWaitForOperationComplete();
182 ASSERT_FALSE(message_);
183 ASSERT_TRUE(on_error_signaled_);
111 } 184 }
112 185
113 TEST_F(NativeMessagingReaderTest, ShortHeader) { 186 TEST_F(NativeMessagingReaderTest, ShortHeader) {
114 // Write only 3 bytes - the message length header is supposed to be 4 bytes. 187 // Write only 3 bytes - the message length header is supposed to be 4 bytes.
115 WriteData("xxx", 3); 188 WriteData("xxx", 3);
116 Run(); 189 write_file_.Close();
117 EXPECT_FALSE(message_); 190 RunAndWaitForOperationComplete();
191 ASSERT_FALSE(message_);
192 ASSERT_TRUE(on_error_signaled_);
118 } 193 }
119 194
120 TEST_F(NativeMessagingReaderTest, EmptyBody) { 195 TEST_F(NativeMessagingReaderTest, EmptyBody) {
121 uint32_t length = 1; 196 uint32_t length = 1;
122 WriteData(reinterpret_cast<char*>(&length), 4); 197 WriteData(reinterpret_cast<char*>(&length), 4);
123 Run(); 198 write_file_.Close();
124 EXPECT_FALSE(message_); 199 RunAndWaitForOperationComplete();
200 ASSERT_FALSE(message_);
201 ASSERT_TRUE(on_error_signaled_);
125 } 202 }
126 203
127 TEST_F(NativeMessagingReaderTest, ShortBody) { 204 TEST_F(NativeMessagingReaderTest, ShortBody) {
128 uint32_t length = 2; 205 uint32_t length = 2;
129 WriteData(reinterpret_cast<char*>(&length), 4); 206 WriteData(reinterpret_cast<char*>(&length), 4);
130 207
131 // Only write 1 byte, where the header indicates there should be 2 bytes. 208 // Only write 1 byte, where the header indicates there should be 2 bytes.
132 WriteData("x", 1); 209 WriteData("x", 1);
133 Run(); 210 write_file_.Close();
134 EXPECT_FALSE(message_); 211 RunAndWaitForOperationComplete();
212 ASSERT_FALSE(message_);
213 ASSERT_TRUE(on_error_signaled_);
135 } 214 }
136 215
137 TEST_F(NativeMessagingReaderTest, InvalidJSON) { 216 TEST_F(NativeMessagingReaderTest, InvalidJSON) {
138 std::string text = "{"; 217 std::string text = "{";
139 WriteMessage(text); 218 WriteMessage(text);
140 Run(); 219 write_file_.Close();
141 EXPECT_FALSE(message_); 220 RunAndWaitForOperationComplete();
142 } 221 ASSERT_FALSE(message_);
143 222 ASSERT_TRUE(on_error_signaled_);
144 TEST_F(NativeMessagingReaderTest, SecondMessage) {
145 WriteMessage("{}");
146 WriteMessage("{\"foo\": 42}");
147 Run();
148 EXPECT_TRUE(message_);
149 base::DictionaryValue* message_dict;
150 EXPECT_TRUE(message_->GetAsDictionary(&message_dict));
151 int result;
152 EXPECT_TRUE(message_dict->GetInteger("foo", &result));
153 EXPECT_EQ(42, result);
154 } 223 }
155 224
156 } // namespace remoting 225 } // namespace remoting
OLDNEW
« no previous file with comments | « remoting/host/native_messaging/native_messaging_reader.cc ('k') | remoting/host/setup/me2me_native_messaging_host.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698