Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright 2015 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/test/host_list_fetcher.h" | |
| 6 | |
| 7 #include "base/bind.h" | |
| 8 #include "base/message_loop/message_loop.h" | |
| 9 #include "base/run_loop.h" | |
| 10 #include "base/strings/stringprintf.h" | |
| 11 #include "net/url_request/test_url_fetcher_factory.h" | |
| 12 #include "remoting/test/host_info.h" | |
| 13 #include "testing/gtest/include/gtest/gtest.h" | |
| 14 | |
| 15 namespace { | |
| 16 // Used as a HostListCallback for testing. | |
|
Sergey Ulanov
2015/07/09 01:25:29
nit: empty line above this one.
tonychun
2015/07/09 03:02:46
Done.
| |
| 17 void OnHostlistRetrieved( | |
| 18 base::Closure done_closure, | |
| 19 std::vector<remoting::test::HostInfo>* hostlist, | |
| 20 const std::vector<remoting::test::HostInfo>& retrieved_hostlist) { | |
| 21 *hostlist = retrieved_hostlist; | |
| 22 | |
| 23 done_closure.Run(); | |
| 24 } | |
| 25 | |
| 26 const char kAccessTokenValue[] = "test_access_token_value"; | |
| 27 const char kHostListReadyResponse[] = | |
| 28 "{" | |
| 29 " \"data\":{" | |
| 30 " \"kind\":\"chromoting#hostList\"," | |
| 31 " \"items\":[" | |
| 32 " {" | |
| 33 " \"tokenUrlPatterns\":[" | |
| 34 " \"tokenUrlPattern_1A\"," | |
| 35 " \"tokenUrlPattern_1B\"," | |
| 36 " \"tokenUrlPattern_1C\"" | |
| 37 " ]," | |
| 38 " \"kind\":\"chromoting#host\"," | |
| 39 " \"hostId\":\"test_host_id_1\"," | |
| 40 " \"hostName\":\"test_host_name_1\"," | |
| 41 " \"publicKey\":\"test_public_key_1\"," | |
| 42 " \"jabberId\":\"test_jabber_id_1\"," | |
| 43 " \"createdTime\":\"test_created_time_1\"," | |
| 44 " \"updatedTime\":\"test_updated_time_1\"," | |
| 45 " \"status\":\"ONLINE\"," | |
| 46 " \"hostOfflineReason\":\"\"," | |
| 47 " \"hostVersion\":\"test_host_version_1\"" | |
| 48 " }," | |
| 49 " {" | |
| 50 " \"kind\":\"chromoting#host\"," | |
| 51 " \"hostId\":\"test_host_id_2\"," | |
| 52 " \"hostName\":\"test_host_name_2\"," | |
| 53 " \"publicKey\":\"test_public_key_2\"," | |
| 54 " \"jabberId\":\"test_jabber_id_2\"," | |
| 55 " \"createdTime\":\"test_created_time_2\"," | |
| 56 " \"updatedTime\":\"test_updated_time_2\"," | |
| 57 " \"status\":\"OFFLINE\"," | |
| 58 " \"hostOfflineReason\":\"test_host_offline_reason_2\"," | |
| 59 " \"hostVersion\":\"test_host_version_2\"" | |
| 60 " }" | |
| 61 " ]" | |
| 62 " }" | |
| 63 "}"; | |
| 64 const char kHostListMissingParametersResponse[] = | |
| 65 "{" | |
| 66 " \"data\":{" | |
| 67 " \"kind\":\"chromoting#hostList\"," | |
| 68 " \"items\":[" | |
| 69 " {" | |
| 70 " \"tokenUrlPatterns\":[" | |
| 71 " \"tokenUrlPattern_1A\"," | |
| 72 " \"tokenUrlPattern_1B\"," | |
| 73 " \"tokenUrlPattern_1C\"" | |
| 74 " ]," | |
| 75 " \"kind\":\"chromoting#host\"," | |
| 76 " \"hostId\":\"test_host_id_1\"," | |
| 77 " \"hostName\":\"test_host_name_1\"," | |
| 78 " \"publicKey\":\"test_public_key_1\"," | |
| 79 " \"createdTime\":\"test_created_time_1\"," | |
| 80 " \"updatedTime\":\"test_updated_time_1\"," | |
| 81 " \"status\":\"OFFLINE\"," | |
| 82 " \"hostOfflineReason\":\"\"," | |
| 83 " \"hostVersion\":\"test_host_version_1\"" | |
| 84 " }," | |
| 85 " {" | |
| 86 " \"kind\":\"chromoting#host\"," | |
| 87 " \"hostName\":\"test_host_name_2\"," | |
| 88 " \"publicKey\":\"test_public_key_2\"," | |
| 89 " \"jabberId\":\"test_jabber_id_2\"," | |
| 90 " \"createdTime\":\"test_created_time_2\"," | |
| 91 " \"updatedTime\":\"test_updated_time_2\"," | |
| 92 " \"status\":\"ONLINE\"," | |
| 93 " \"hostOfflineReason\":\"\"," | |
| 94 " \"hostVersion\":\"test_host_version_2\"" | |
| 95 " }," | |
| 96 " {" | |
| 97 " \"kind\":\"chromoting#host\"," | |
| 98 " \"hostId\":\"test_host_id_3\"," | |
| 99 " \"publicKey\":\"test_public_key_3\"," | |
| 100 " \"jabberId\":\"test_jabber_id_3\"," | |
| 101 " \"createdTime\":\"test_created_time_3\"," | |
| 102 " \"updatedTime\":\"test_updated_time_3\"," | |
| 103 " \"status\":\"ONLINE\"," | |
| 104 " \"hostOfflineReason\":\"\"," | |
| 105 " \"hostVersion\":\"test_host_version_3\"" | |
| 106 " }," | |
| 107 " {" | |
| 108 " \"kind\":\"chromoting#host\"," | |
| 109 " \"hostId\":\"test_host_id_4\"," | |
| 110 " \"hostName\":\"test_host_name_4\"," | |
| 111 " \"jabberId\":\"test_jabber_id_4\"," | |
| 112 " \"createdTime\":\"test_created_time_4\"," | |
| 113 " \"updatedTime\":\"test_updated_time_4\"," | |
| 114 " \"status\":\"ONLINE\"," | |
| 115 " \"hostOfflineReason\":\"\"," | |
| 116 " \"hostVersion\":\"test_host_version_4\"" | |
| 117 " }," | |
| 118 " {" | |
| 119 " \"kind\":\"chromoting#host\"," | |
| 120 " \"hostId\":\"test_host_id_5\"," | |
| 121 " \"hostName\":\"test_host_name_5\"," | |
| 122 " \"publicKey\":\"test_public_key_5\"," | |
| 123 " \"jabberId\":\"test_jabber_id_5\"," | |
| 124 " \"createdTime\":\"test_created_time_5\"," | |
| 125 " \"updatedTime\":\"test_updated_time_5\"," | |
| 126 " \"status\":\"OFFLINE\"," | |
| 127 " \"hostVersion\":\"test_host_version_5\"" | |
| 128 " }" | |
| 129 " ]" | |
| 130 " }" | |
| 131 "}"; | |
| 132 const char kHostListEmptyTokenUrlPatternsResponse[] = | |
| 133 "{" | |
| 134 " \"data\":{" | |
| 135 " \"kind\":\"chromoting#hostList\"," | |
| 136 " \"items\":[" | |
| 137 " {" | |
| 138 " \"tokenUrlPatterns\":[" | |
| 139 " ]," | |
| 140 " \"kind\":\"chromoting#host\"," | |
| 141 " \"hostId\":\"test_host_id_1\"," | |
| 142 " \"hostName\":\"test_host_name_1\"," | |
| 143 " \"publicKey\":\"test_public_key_1\"," | |
| 144 " \"jabberId\":\"test_jabber_id_1\"," | |
| 145 " \"createdTime\":\"test_created_time_1\"," | |
| 146 " \"updatedTime\":\"test_updated_time_1\"," | |
| 147 " \"status\":\"ONLINE\"," | |
| 148 " \"hostOfflineReason\":\"\"," | |
| 149 " \"hostVersion\":\"test_host_version_1\"" | |
| 150 " }" | |
| 151 " ]" | |
| 152 " }" | |
| 153 "}"; | |
| 154 const char kHostListEmptyItemsResponse[] = | |
| 155 "{" | |
| 156 " \"data\":{" | |
| 157 " \"kind\":\"chromoting#hostList\"," | |
| 158 " \"items\":[" | |
| 159 " ]" | |
| 160 " }" | |
| 161 "}"; | |
| 162 const char kHostListEmptyResponse[] = "{}"; | |
| 163 } // namespace | |
| 164 | |
| 165 namespace remoting { | |
| 166 namespace test { | |
| 167 | |
| 168 // Provides base functionality for the HostListFetcher Tests below. | |
| 169 // The FakeURLFetcherFactory allows us to override the response data and payload | |
| 170 // for specified URLs. We use this to stub out network calls made by the | |
| 171 // HostListFetcher. This fixture also creates an IO MessageLoop | |
| 172 // for use by the HostListFetcher. | |
| 173 class HostListFetcherTest : public ::testing::Test { | |
| 174 public: | |
| 175 HostListFetcherTest() : url_fetcher_factory_(nullptr) {} | |
| 176 ~HostListFetcherTest() override {} | |
| 177 | |
| 178 protected: | |
| 179 // testing::Test interface. | |
| 180 void SetUp() override; | |
| 181 | |
| 182 // Sets the HTTP status and data returned for a specified URL. | |
| 183 void SetFakeResponse(const GURL& url, | |
| 184 const std::string& data, | |
| 185 net::HttpStatusCode code, | |
| 186 net::URLRequestStatus::Status status); | |
| 187 | |
| 188 private: | |
| 189 net::FakeURLFetcherFactory url_fetcher_factory_; | |
| 190 scoped_ptr<base::MessageLoopForIO> message_loop_; | |
| 191 | |
| 192 DISALLOW_COPY_AND_ASSIGN(HostListFetcherTest); | |
| 193 }; | |
| 194 | |
| 195 void HostListFetcherTest::SetUp() { | |
| 196 DCHECK(!message_loop_); | |
| 197 message_loop_.reset(new base::MessageLoopForIO); | |
| 198 | |
| 199 SetFakeResponse(GURL(kHostListProdRequestUrl), | |
| 200 kHostListEmptyResponse, net::HTTP_NOT_FOUND, | |
| 201 net::URLRequestStatus::FAILED); | |
| 202 } | |
| 203 | |
| 204 void HostListFetcherTest::SetFakeResponse( | |
| 205 const GURL& url, | |
| 206 const std::string& data, | |
| 207 net::HttpStatusCode code, | |
| 208 net::URLRequestStatus::Status status) { | |
| 209 url_fetcher_factory_.SetFakeResponse(url, data, code, status); | |
| 210 } | |
| 211 | |
| 212 TEST_F(HostListFetcherTest, RetrieveHostListFromProd) { | |
| 213 SetFakeResponse(GURL(kHostListProdRequestUrl), | |
| 214 kHostListReadyResponse, net::HTTP_OK, | |
| 215 net::URLRequestStatus::SUCCESS); | |
| 216 | |
| 217 std::vector<HostInfo> hostlist; | |
| 218 | |
| 219 base::RunLoop run_loop; | |
| 220 HostListFetcher::HostlistCallback host_list_callback = | |
| 221 base::Bind(&OnHostlistRetrieved, run_loop.QuitClosure(), &hostlist); | |
| 222 | |
| 223 HostListFetcher host_list_fetcher; | |
| 224 host_list_fetcher.RetrieveHostlist(kAccessTokenValue, host_list_callback); | |
| 225 | |
| 226 run_loop.Run(); | |
| 227 | |
| 228 const unsigned int expected_host_list_size = 2; | |
| 229 EXPECT_EQ(hostlist.size(), expected_host_list_size); | |
| 230 | |
| 231 HostInfo online_host_info = hostlist.at(0); | |
| 232 const unsigned int expected_patterns_size = 3; | |
| 233 EXPECT_EQ(online_host_info.token_url_patterns.size(), expected_patterns_size); | |
| 234 EXPECT_FALSE(online_host_info.host_id.empty()); | |
| 235 EXPECT_FALSE(online_host_info.host_jid.empty()); | |
| 236 EXPECT_FALSE(online_host_info.host_name.empty()); | |
| 237 EXPECT_EQ(online_host_info.status, HostStatus::kHostStatusOnline); | |
| 238 EXPECT_TRUE(online_host_info.offline_reason.empty()); | |
| 239 EXPECT_FALSE(online_host_info.public_key.empty()); | |
| 240 | |
| 241 HostInfo offline_host_info = hostlist.at(1); | |
| 242 EXPECT_TRUE(offline_host_info.token_url_patterns.empty()); | |
| 243 EXPECT_FALSE(offline_host_info.host_id.empty()); | |
| 244 EXPECT_FALSE(offline_host_info.host_jid.empty()); | |
| 245 EXPECT_FALSE(offline_host_info.host_name.empty()); | |
| 246 EXPECT_EQ(offline_host_info.status, HostStatus::kHostStatusOffline); | |
| 247 EXPECT_FALSE(offline_host_info.offline_reason.empty()); | |
| 248 EXPECT_FALSE(offline_host_info.public_key.empty()); | |
| 249 } | |
| 250 | |
| 251 TEST_F(HostListFetcherTest, RetrieveHostListWithEmptyPatterns) { | |
| 252 SetFakeResponse(GURL(kHostListProdRequestUrl), | |
| 253 kHostListEmptyTokenUrlPatternsResponse, net::HTTP_OK, | |
| 254 net::URLRequestStatus::SUCCESS); | |
| 255 | |
| 256 std::vector<HostInfo> hostlist; | |
| 257 | |
| 258 base::RunLoop run_loop; | |
| 259 HostListFetcher::HostlistCallback host_list_callback = | |
| 260 base::Bind(&OnHostlistRetrieved, run_loop.QuitClosure(), &hostlist); | |
| 261 | |
| 262 HostListFetcher host_list_fetcher; | |
| 263 host_list_fetcher.RetrieveHostlist(kAccessTokenValue, host_list_callback); | |
| 264 | |
| 265 run_loop.Run(); | |
| 266 | |
| 267 const unsigned int expected_host_list_size = 1; | |
| 268 EXPECT_EQ(hostlist.size(), expected_host_list_size); | |
| 269 | |
| 270 // While this is unlikely to happen, empty token url patterns are handled. | |
| 271 HostInfo online_host_info = hostlist.at(0); | |
| 272 EXPECT_TRUE(online_host_info.token_url_patterns.empty()); | |
| 273 EXPECT_FALSE(online_host_info.host_id.empty()); | |
| 274 EXPECT_FALSE(online_host_info.host_jid.empty()); | |
| 275 EXPECT_FALSE(online_host_info.host_name.empty()); | |
| 276 EXPECT_EQ(online_host_info.status, HostStatus::kHostStatusOnline); | |
| 277 EXPECT_TRUE(online_host_info.offline_reason.empty()); | |
| 278 EXPECT_FALSE(online_host_info.public_key.empty()); | |
| 279 } | |
| 280 | |
| 281 TEST_F(HostListFetcherTest, | |
| 282 RetrieveHostListMissingParametersResponse) { | |
| 283 SetFakeResponse(GURL(kHostListProdRequestUrl), | |
| 284 kHostListMissingParametersResponse, net::HTTP_OK, | |
| 285 net::URLRequestStatus::SUCCESS); | |
| 286 | |
| 287 std::vector<HostInfo> hostlist; | |
| 288 | |
| 289 base::RunLoop run_loop; | |
| 290 HostListFetcher::HostlistCallback host_list_callback = | |
| 291 base::Bind(&OnHostlistRetrieved, run_loop.QuitClosure(), &hostlist); | |
| 292 | |
| 293 HostListFetcher host_list_fetcher; | |
| 294 host_list_fetcher.RetrieveHostlist(kAccessTokenValue, host_list_callback); | |
| 295 run_loop.Run(); | |
| 296 | |
| 297 const unsigned int expected_host_list_size = 2; | |
| 298 EXPECT_EQ(hostlist.size(), expected_host_list_size); | |
| 299 | |
| 300 HostInfo no_jabber_id_host_info = hostlist.at(0); | |
| 301 const unsigned int expected_patterns_size = 3; | |
|
joedow
2015/07/09 02:41:18
This should be a const in the file scoped namespac
tonychun
2015/07/09 03:02:46
Done.
| |
| 302 EXPECT_EQ(no_jabber_id_host_info.token_url_patterns.size(), | |
| 303 expected_patterns_size); | |
| 304 EXPECT_FALSE(no_jabber_id_host_info.host_id.empty()); | |
| 305 EXPECT_TRUE(no_jabber_id_host_info.host_jid.empty()); | |
| 306 EXPECT_FALSE(no_jabber_id_host_info.host_name.empty()); | |
| 307 EXPECT_EQ(no_jabber_id_host_info.status, HostStatus::kHostStatusOffline); | |
| 308 EXPECT_TRUE(no_jabber_id_host_info.offline_reason.empty()); | |
| 309 EXPECT_FALSE(no_jabber_id_host_info.public_key.empty()); | |
| 310 | |
| 311 HostInfo no_offline_reason_host_info = hostlist.at(1); | |
| 312 EXPECT_TRUE(no_offline_reason_host_info.token_url_patterns.empty()); | |
| 313 EXPECT_FALSE(no_offline_reason_host_info.host_id.empty()); | |
| 314 EXPECT_FALSE(no_offline_reason_host_info.host_jid.empty()); | |
| 315 EXPECT_FALSE(no_offline_reason_host_info.host_name.empty()); | |
| 316 EXPECT_EQ(no_offline_reason_host_info.status, HostStatus::kHostStatusOffline); | |
| 317 EXPECT_TRUE(no_offline_reason_host_info.offline_reason.empty()); | |
| 318 EXPECT_FALSE(no_offline_reason_host_info.public_key.empty()); | |
| 319 } | |
| 320 | |
| 321 | |
| 322 TEST_F(HostListFetcherTest, RetrieveHostListNetworkError) { | |
| 323 base::RunLoop run_loop; | |
| 324 | |
| 325 std::vector<HostInfo> hostlist; | |
| 326 | |
| 327 HostListFetcher::HostlistCallback host_list_callback = | |
| 328 base::Bind(&OnHostlistRetrieved, run_loop.QuitClosure(), &hostlist); | |
| 329 | |
| 330 HostListFetcher host_list_fetcher; | |
| 331 host_list_fetcher.RetrieveHostlist(kAccessTokenValue, host_list_callback); | |
| 332 run_loop.Run(); | |
| 333 | |
| 334 // If there was a network error retrieving the host list, then the host list | |
| 335 // should be empty. | |
| 336 EXPECT_TRUE(hostlist.empty()); | |
| 337 } | |
| 338 | |
| 339 TEST_F(HostListFetcherTest, RetrieveHostListEmptyItemsResponse) { | |
| 340 SetFakeResponse(GURL(kHostListProdRequestUrl), | |
| 341 kHostListEmptyItemsResponse, net::HTTP_OK, | |
| 342 net::URLRequestStatus::SUCCESS); | |
| 343 | |
| 344 base::RunLoop run_loop; | |
| 345 | |
| 346 std::vector<HostInfo> hostlist; | |
| 347 | |
| 348 HostListFetcher::HostlistCallback host_list_callback = | |
| 349 base::Bind(&OnHostlistRetrieved, run_loop.QuitClosure(), &hostlist); | |
| 350 | |
| 351 HostListFetcher host_list_fetcher; | |
| 352 host_list_fetcher.RetrieveHostlist(kAccessTokenValue, host_list_callback); | |
| 353 run_loop.Run(); | |
| 354 | |
| 355 // If we received an empty items response, then host list should be empty. | |
| 356 EXPECT_TRUE(hostlist.empty()); | |
| 357 } | |
| 358 | |
| 359 TEST_F(HostListFetcherTest, RetrieveHostListEmptyResponse) { | |
| 360 SetFakeResponse(GURL(kHostListProdRequestUrl), | |
| 361 kHostListEmptyResponse, net::HTTP_OK, | |
| 362 net::URLRequestStatus::SUCCESS); | |
| 363 | |
| 364 base::RunLoop run_loop; | |
| 365 | |
| 366 std::vector<HostInfo> hostlist; | |
| 367 | |
| 368 HostListFetcher::HostlistCallback host_list_callback = | |
| 369 base::Bind(&OnHostlistRetrieved, run_loop.QuitClosure(), &hostlist); | |
| 370 | |
| 371 HostListFetcher host_list_fetcher; | |
| 372 host_list_fetcher.RetrieveHostlist(kAccessTokenValue, host_list_callback); | |
| 373 run_loop.Run(); | |
| 374 | |
| 375 // If we received an empty response, then host list should be empty. | |
| 376 EXPECT_TRUE(hostlist.empty()); | |
| 377 } | |
| 378 | |
| 379 TEST_F(HostListFetcherTest, MultipleRetrieveHostListRequests) { | |
| 380 // First, we will retrieve a valid response from the directory service. | |
| 381 SetFakeResponse(GURL(kHostListProdRequestUrl), | |
| 382 kHostListReadyResponse, net::HTTP_OK, | |
| 383 net::URLRequestStatus::SUCCESS); | |
| 384 | |
| 385 std::vector<HostInfo> ready_hostlist; | |
| 386 | |
| 387 base::RunLoop ready_run_loop; | |
| 388 HostListFetcher::HostlistCallback ready_host_list_callback = | |
| 389 base::Bind(&OnHostlistRetrieved, | |
| 390 ready_run_loop.QuitClosure(), | |
| 391 &ready_hostlist); | |
| 392 | |
| 393 HostListFetcher host_list_fetcher; | |
| 394 host_list_fetcher.RetrieveHostlist(kAccessTokenValue, | |
| 395 ready_host_list_callback); | |
| 396 | |
| 397 ready_run_loop.Run(); | |
| 398 | |
| 399 const unsigned int expected_host_list_size = 2; | |
| 400 EXPECT_EQ(ready_hostlist.size(), expected_host_list_size); | |
| 401 | |
| 402 HostInfo online_host_info = ready_hostlist.at(0); | |
| 403 const unsigned int expected_patterns_size = 3; | |
| 404 EXPECT_EQ(online_host_info.token_url_patterns.size(), expected_patterns_size); | |
| 405 EXPECT_FALSE(online_host_info.host_id.empty()); | |
| 406 EXPECT_FALSE(online_host_info.host_jid.empty()); | |
| 407 EXPECT_FALSE(online_host_info.host_name.empty()); | |
| 408 EXPECT_EQ(online_host_info.status, HostStatus::kHostStatusOnline); | |
| 409 EXPECT_TRUE(online_host_info.offline_reason.empty()); | |
| 410 EXPECT_FALSE(online_host_info.public_key.empty()); | |
| 411 | |
| 412 HostInfo offline_host_info = ready_hostlist.at(1); | |
| 413 EXPECT_TRUE(offline_host_info.token_url_patterns.empty()); | |
| 414 EXPECT_FALSE(offline_host_info.host_id.empty()); | |
| 415 EXPECT_FALSE(offline_host_info.host_jid.empty()); | |
| 416 EXPECT_FALSE(offline_host_info.host_name.empty()); | |
| 417 EXPECT_EQ(offline_host_info.status, HostStatus::kHostStatusOffline); | |
| 418 EXPECT_FALSE(offline_host_info.offline_reason.empty()); | |
| 419 EXPECT_FALSE(offline_host_info.public_key.empty()); | |
| 420 | |
| 421 // Next, we will retrieve an empty items response from the directory service. | |
| 422 SetFakeResponse(GURL(kHostListProdRequestUrl), | |
| 423 kHostListEmptyItemsResponse, net::HTTP_OK, | |
| 424 net::URLRequestStatus::SUCCESS); | |
| 425 | |
| 426 std::vector<HostInfo> empty_items_hostlist; | |
| 427 | |
| 428 base::RunLoop empty_items_run_loop; | |
| 429 | |
| 430 HostListFetcher::HostlistCallback empty_host_list_callback = | |
| 431 base::Bind(&OnHostlistRetrieved, | |
| 432 empty_items_run_loop.QuitClosure(), | |
| 433 &empty_items_hostlist); | |
| 434 | |
| 435 // Re-use the same host_list_fetcher. | |
| 436 host_list_fetcher.RetrieveHostlist(kAccessTokenValue, | |
| 437 empty_host_list_callback); | |
| 438 | |
| 439 empty_items_run_loop.Run(); | |
| 440 // If we received an empty items response, then host list should be empty. | |
| 441 EXPECT_TRUE(empty_items_hostlist.empty()); | |
| 442 } | |
| 443 | |
| 444 } // namespace test | |
| 445 } // namespace remoting | |
| OLD | NEW |