OLD | NEW |
1 /* | 1 /* |
2 * This file is part of Adblock Plus <https://adblockplus.org/>, | 2 * This file is part of Adblock Plus <https://adblockplus.org/>, |
3 * Copyright (C) 2006-2015 Eyeo GmbH | 3 * Copyright (C) 2006-2015 Eyeo GmbH |
4 * | 4 * |
5 * Adblock Plus is free software: you can redistribute it and/or modify | 5 * Adblock Plus is free software: you can redistribute it and/or modify |
6 * it under the terms of the GNU General Public License version 3 as | 6 * it under the terms of the GNU General Public License version 3 as |
7 * published by the Free Software Foundation. | 7 * published by the Free Software Foundation. |
8 * | 8 * |
9 * Adblock Plus is distributed in the hope that it will be useful, | 9 * Adblock Plus is distributed in the hope that it will be useful, |
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of | 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
12 * GNU General Public License for more details. | 12 * GNU General Public License for more details. |
13 * | 13 * |
14 * You should have received a copy of the GNU General Public License | 14 * You should have received a copy of the GNU General Public License |
15 * along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>. | 15 * along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>. |
16 */ | 16 */ |
17 | 17 |
18 #include <gtest/gtest.h> | 18 #include <gtest/gtest.h> |
19 | 19 |
| 20 #include <thread> |
| 21 #include <chrono> |
| 22 #include <memory> |
20 #include "../src/shared/AutoHandle.h" | 23 #include "../src/shared/AutoHandle.h" |
21 #include "../src/shared/Communication.h" | 24 #include "../src/shared/Communication.h" |
22 | 25 |
23 const std::wstring pipeName(L"\\\\.\\pipe\\adblockplustests"); | 26 const std::wstring pipeName(L"\\\\.\\pipe\\adblockplustests"); |
24 | 27 |
| 28 TEST(CommunicationTest, PipeConnect) |
| 29 { |
| 30 auto serverThread = std::thread([] |
| 31 { |
| 32 Communication::Pipe pipe(pipeName, Communication::Pipe::MODE_CREATE); |
| 33 }); |
| 34 std::this_thread::sleep_for(std::chrono::milliseconds(100)); |
| 35 ASSERT_NO_THROW(Communication::Pipe pipe(pipeName, Communication::Pipe::MODE_C
ONNECT)); |
| 36 serverThread.join(); |
| 37 } |
| 38 |
| 39 TEST(CommunicationTest, PipeSendReceive) |
| 40 { |
| 41 std::unique_ptr<Communication::Pipe> client; |
| 42 auto clientThread = std::thread([&client] |
| 43 { |
| 44 while(!client) |
| 45 { |
| 46 try |
| 47 { |
| 48 client.reset(new Communication::Pipe(pipeName, Communication::Pipe::MODE
_CONNECT)); |
| 49 } |
| 50 catch(...) |
| 51 { |
| 52 std::this_thread::yield(); |
| 53 } |
| 54 } |
| 55 }); |
| 56 Communication::Pipe server(pipeName, Communication::Pipe::MODE_CREATE); |
| 57 clientThread.join(); |
| 58 |
| 59 // send to the server |
| 60 { |
| 61 Communication::OutputBuffer message; |
| 62 message << Communication::ProcType::PROC_IS_WHITELISTED_URL |
| 63 << std::string("This is a test message") << 64ll << 32 << true << false; |
| 64 client->WriteMessage(message); |
| 65 } |
| 66 // receive on the server and send back |
| 67 { |
| 68 Communication::OutputBuffer response; |
| 69 Communication::InputBuffer message = server.ReadMessage(); |
| 70 Communication::ProcType proc; |
| 71 message >> proc; |
| 72 EXPECT_EQ(Communication::ProcType::PROC_IS_WHITELISTED_URL, proc); |
| 73 response << Communication::ProcType::PROC_IS_FIRST_RUN_ACTION_NEEDED; |
| 74 |
| 75 std::string text; |
| 76 message >> text; |
| 77 EXPECT_EQ("This is a test message", text); |
| 78 response << std::string("Response"); |
| 79 |
| 80 int64_t integer64; |
| 81 message >> integer64; |
| 82 EXPECT_EQ(64ll, integer64); |
| 83 response << 46ll; |
| 84 |
| 85 int32_t integer32; |
| 86 message >> integer32; |
| 87 EXPECT_EQ(32, integer32); |
| 88 response << 23; |
| 89 |
| 90 bool boolean; |
| 91 message >> boolean; |
| 92 EXPECT_TRUE(boolean); |
| 93 response << false; |
| 94 |
| 95 message >> boolean; |
| 96 EXPECT_FALSE(boolean); |
| 97 response << true; |
| 98 |
| 99 server.WriteMessage(response); |
| 100 } |
| 101 |
| 102 // receive on the client |
| 103 { |
| 104 Communication::InputBuffer message = client->ReadMessage(); |
| 105 Communication::ProcType proc; |
| 106 message >> proc; |
| 107 EXPECT_EQ(Communication::ProcType::PROC_IS_FIRST_RUN_ACTION_NEEDED, proc); |
| 108 |
| 109 std::string text; |
| 110 message >> text; |
| 111 EXPECT_EQ("Response", text); |
| 112 |
| 113 int64_t integer64; |
| 114 message >> integer64; |
| 115 EXPECT_EQ(46ll, integer64); |
| 116 |
| 117 int32_t integer32; |
| 118 message >> integer32; |
| 119 EXPECT_EQ(23, integer32); |
| 120 |
| 121 bool boolean; |
| 122 message >> boolean; |
| 123 EXPECT_FALSE(boolean); |
| 124 |
| 125 message >> boolean; |
| 126 EXPECT_TRUE(boolean); |
| 127 } |
| 128 } |
| 129 |
25 namespace | 130 namespace |
26 { | 131 { |
27 DWORD WINAPI CreatePipe(LPVOID param) | 132 template<typename TestedType, typename AnotherType> |
28 { | 133 void SendReceiveTypes(TestedType value, AnotherType anotherTypeValue) |
29 Communication::Pipe pipe(pipeName, Communication::Pipe::MODE_CREATE); | 134 { |
30 return 0; | 135 Communication::OutputBuffer message; |
31 } | 136 message << anotherTypeValue << value; |
32 | 137 Communication::InputBuffer response(message.Get()); |
33 DWORD WINAPI ReceiveSend(LPVOID param) | 138 TestedType received; |
34 { | 139 ASSERT_ANY_THROW(response >> received); |
35 Communication::Pipe pipe(pipeName, Communication::Pipe::MODE_CREATE); | 140 AnotherType anotherTypeValueReceived; |
36 | 141 response >> anotherTypeValueReceived; |
37 Communication::InputBuffer message = pipe.ReadMessage(); | 142 response >> received; |
38 | 143 EXPECT_EQ(value, received); |
39 std::string stringValue; | 144 } |
40 std::wstring wstringValue; | 145 } |
41 int64_t int64Value; | 146 |
42 int32_t int32Value; | 147 TEST(CommunicationTest, TypeProc) |
43 bool boolValue; | 148 { |
44 message >> stringValue >> wstringValue >> int64Value >> int32Value >> boolVa
lue; | 149 SendReceiveTypes(Communication::ProcType::PROC_GET_ELEMHIDE_SELECTORS, std::st
ring("non-ProcType")); |
45 | 150 } |
46 stringValue += " Received"; | 151 |
47 wstringValue += L" \u043f\u0440\u0438\u043d\u044f\u0442\u043e"; | 152 TEST(CommunicationTest, TypeString) |
48 int64Value += 1; | 153 { |
49 int32Value += 2; | 154 int32_t nonStringTypeValue = 10; |
50 boolValue = !boolValue; | 155 SendReceiveTypes(std::string("stringValue"), nonStringTypeValue); |
51 | 156 } |
52 Communication::OutputBuffer response; | 157 |
53 response << stringValue << wstringValue << int64Value << int32Value << boolV
alue; | 158 TEST(CommunicationTest, SendReceiveEmptyString) |
54 pipe.WriteMessage(response); | 159 { |
55 | 160 Communication::OutputBuffer message; |
56 return 0; | 161 message << std::string(); |
57 } | 162 Communication::InputBuffer response(message.Get()); |
58 } | 163 std::string received = "clean me"; |
59 | 164 response >> received; |
60 TEST(CommunicationTest, ConnectPipe) | 165 EXPECT_EQ("", received); |
61 { | 166 } |
62 AutoHandle thread(CreateThread(0, 0, CreatePipe, 0, 0, 0)); | 167 |
63 | 168 TEST(CommunicationTest, TypeStringSendWideReceiveWide) |
64 Sleep(100); | 169 { |
65 | 170 int32_t nonStringTypeValue = 10; |
66 ASSERT_NO_THROW(Communication::Pipe pipe(pipeName, Communication::Pipe::MODE_C
ONNECT)); | 171 SendReceiveTypes(std::wstring(L"stringValue"), nonStringTypeValue); |
67 } | 172 } |
68 | 173 |
69 TEST(CommunicationTest, SendReceive) | 174 TEST(CommunicationTest, SendString_ReceiveWString) |
70 { | 175 { |
71 AutoHandle thread(CreateThread(0, 0, ReceiveSend, 0, 0, 0)); | 176 Communication::OutputBuffer message; |
72 | 177 message << std::string("test"); |
73 Sleep(100); | 178 Communication::InputBuffer response(message.Get()); |
74 | 179 std::wstring received; |
75 Communication::Pipe pipe(pipeName, Communication::Pipe::MODE_CONNECT); | 180 response >> received; |
76 | 181 EXPECT_EQ(L"test", received); |
77 Communication::OutputBuffer message; | 182 } |
78 message << std::string("Foo") << std::wstring(L"Bar") << int64_t(9876543210L)
<< int32_t(5) << true; | 183 |
79 pipe.WriteMessage(message); | 184 TEST(CommunicationTest, SendWString_ReceiveString) |
80 | 185 { |
81 Communication::InputBuffer response = pipe.ReadMessage(); | 186 Communication::OutputBuffer message; |
82 | 187 message << std::wstring(L"test"); |
83 std::string stringValue; | 188 Communication::InputBuffer response(message.Get()); |
84 std::wstring wstringValue; | 189 std::string received; |
85 int64_t int64Value; | 190 response >> received; |
86 int32_t int32Value; | 191 EXPECT_EQ("test", received); |
87 bool boolValue; | 192 } |
88 | 193 |
89 ASSERT_ANY_THROW(response >> wstringValue); | 194 TEST(CommunicationTest, SendStrings_ReceiveWStrings) |
90 ASSERT_ANY_THROW(response >> int64Value); | 195 { |
91 ASSERT_ANY_THROW(response >> int32Value); | 196 Communication::OutputBuffer message; |
92 ASSERT_ANY_THROW(response >> boolValue); | 197 std::vector<std::string> strings; |
93 | 198 strings.emplace_back("test0"); |
94 response >> stringValue >> wstringValue; | 199 strings.emplace_back("test1"); |
95 | 200 message << strings; |
96 ASSERT_ANY_THROW(response >> stringValue); | 201 Communication::InputBuffer response(message.Get()); |
97 ASSERT_ANY_THROW(response >> wstringValue); | 202 std::vector<std::wstring> received; |
98 ASSERT_ANY_THROW(response >> int32Value); | 203 response >> received; |
99 ASSERT_ANY_THROW(response >> boolValue); | 204 ASSERT_EQ(2u, received.size()); |
100 | 205 EXPECT_EQ(L"test0", received[0]); |
101 response >> int64Value >> int32Value >> boolValue; | 206 EXPECT_EQ(L"test1", received[1]); |
102 | 207 } |
103 ASSERT_ANY_THROW(response >> stringValue); | 208 |
104 ASSERT_ANY_THROW(response >> wstringValue); | 209 TEST(CommunicationTest, TypeInt64) |
105 ASSERT_ANY_THROW(response >> int64Value); | 210 { |
106 ASSERT_ANY_THROW(response >> int32Value); | 211 SendReceiveTypes<int64_t>(10, std::string("non-ProcType")); |
107 ASSERT_ANY_THROW(response >> boolValue); | 212 } |
108 | 213 |
109 ASSERT_EQ("Foo Received", stringValue); | 214 TEST(CommunicationTest, TypeInt32) |
110 ASSERT_EQ(L"Bar \u043f\u0440\u0438\u043d\u044f\u0442\u043e", wstringValue); | 215 { |
111 ASSERT_EQ(9876543211L, int64Value); | 216 SendReceiveTypes<int32_t>(10, std::string("non-ProcType")); |
112 ASSERT_EQ(7, int32Value); | 217 } |
113 ASSERT_FALSE(boolValue); | 218 |
114 } | 219 TEST(CommunicationTest, TypeBool) |
115 | 220 { |
116 void SendReceiveStrings(const std::vector<std::string>& src) | 221 SendReceiveTypes<bool>(true, std::string("non-ProcType")); |
117 { | 222 SendReceiveTypes<bool>(false, std::string("non-ProcType")); |
118 Communication::OutputBuffer outputBuffer; | 223 } |
119 outputBuffer << src; | 224 |
120 Communication::InputBuffer inputBuffer(outputBuffer.Get()); | 225 namespace |
121 std::vector<std::string> dst; | 226 { |
122 inputBuffer >> dst; | 227 void SendReceiveStrings(const std::vector<std::string>& src) |
123 auto dstSize = dst.size(); | 228 { |
124 ASSERT_EQ(dstSize, src.size()); | 229 Communication::OutputBuffer outputBuffer; |
125 for (auto i = 0; i < dstSize; ++i) | 230 outputBuffer << src; |
126 { | 231 Communication::InputBuffer inputBuffer(outputBuffer.Get()); |
127 EXPECT_EQ(dst[i], src[i]); | 232 std::vector<std::string> dst; |
128 } | 233 inputBuffer >> dst; |
129 } | 234 auto dstSize = dst.size(); |
130 | 235 ASSERT_EQ(src.size(), dstSize); |
131 TEST(InputOutputBuffersTests, EmptyStrings) | 236 for (auto i = 0u; i < dstSize; ++i) |
| 237 { |
| 238 EXPECT_EQ(src[i], dst[i]); |
| 239 } |
| 240 } |
| 241 |
| 242 std::vector<std::wstring> SendReceiveStringsToWStrings(const std::vector<std::
string>& src) |
| 243 { |
| 244 Communication::OutputBuffer outputBuffer; |
| 245 outputBuffer << src; |
| 246 Communication::InputBuffer inputBuffer(outputBuffer.Get()); |
| 247 std::vector<std::wstring> dst; |
| 248 inputBuffer >> dst; |
| 249 return dst; |
| 250 } |
| 251 } |
| 252 |
| 253 TEST(InputOutputBuffersTests, InputOutputBufferEmptyStrings) |
132 { | 254 { |
133 SendReceiveStrings(std::vector<std::string>()); | 255 SendReceiveStrings(std::vector<std::string>()); |
134 } | 256 } |
135 | 257 |
136 TEST(InputOutputBuffersTests, StringsWithOneValue) | 258 TEST(InputOutputBuffersTests, InputOutputBufferEmptyStringsToWideStrings) |
| 259 { |
| 260 EXPECT_EQ(0u, SendReceiveStringsToWStrings(std::vector<std::string>()).size())
; |
| 261 } |
| 262 |
| 263 TEST(InputOutputBuffersTests, InputOutputBufferStringsWithOneValue) |
137 { | 264 { |
138 std::vector<std::string> src; | 265 std::vector<std::string> src; |
139 src.emplace_back("string1"); | 266 src.emplace_back("string1"); |
140 SendReceiveStrings(src); | 267 SendReceiveStrings(src); |
141 } | 268 } |
142 | 269 |
143 TEST(InputOutputBuffersTests, MultivalueStrings) | 270 TEST(InputOutputBuffersTests, InputOutputBufferStringsWithOneValueToWStrings) |
| 271 { |
| 272 std::vector<std::string> src; |
| 273 src.emplace_back("string1"); |
| 274 auto dst = SendReceiveStringsToWStrings(src); |
| 275 ASSERT_EQ(1u, dst.size()); |
| 276 EXPECT_EQ(L"string1", dst[0]); |
| 277 } |
| 278 |
| 279 TEST(InputOutputBuffersTests, InputOutputBufferWithMultivalueStrings) |
144 { | 280 { |
145 std::vector<std::string> src; | 281 std::vector<std::string> src; |
146 src.emplace_back("string1"); | 282 src.emplace_back("string1"); |
147 src.emplace_back("str2"); | 283 src.emplace_back("str2"); |
148 src.emplace_back("value"); | 284 src.emplace_back("value"); |
149 SendReceiveStrings(src); | 285 SendReceiveStrings(src); |
| 286 } |
| 287 |
| 288 TEST(InputOutputBuffersTests, InputOutputBufferWithMultivalueStringsToWStrings) |
| 289 { |
| 290 std::vector<std::string> src; |
| 291 src.emplace_back("string1"); |
| 292 src.emplace_back("str2"); |
| 293 src.emplace_back("value"); |
| 294 auto dst = SendReceiveStringsToWStrings(src); |
| 295 ASSERT_EQ(3u, dst.size()); |
| 296 EXPECT_EQ(L"string1", dst[0]); |
| 297 EXPECT_EQ(L"str2", dst[1]); |
| 298 EXPECT_EQ(L"value", dst[2]); |
150 } | 299 } |
OLD | NEW |