OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 // Unit test for SyncChannel. | 5 // Unit test for SyncChannel. |
6 | 6 |
7 #include "ipc/ipc_sync_channel.h" | 7 #include "ipc/ipc_sync_channel.h" |
8 | 8 |
9 #include <string> | 9 #include <string> |
10 #include <vector> | 10 #include <vector> |
(...skipping 1239 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1250 int* success) | 1250 int* success) |
1251 : Worker("restricted_channel", Channel::MODE_CLIENT), | 1251 : Worker("restricted_channel", Channel::MODE_CLIENT), |
1252 ping_(0), | 1252 ping_(0), |
1253 server_(server), | 1253 server_(server), |
1254 success_(success), | 1254 success_(success), |
1255 sent_ping_event_(sent_ping_event) {} | 1255 sent_ping_event_(sent_ping_event) {} |
1256 | 1256 |
1257 void Run() { | 1257 void Run() { |
1258 // Incoming messages from our channel should only be dispatched when we | 1258 // Incoming messages from our channel should only be dispatched when we |
1259 // send a message on that same channel. | 1259 // send a message on that same channel. |
1260 channel()->SetRestrictDispatchToSameChannel(true); | 1260 channel()->SetRestrictDispatchChannelGroup(1); |
1261 | 1261 |
1262 server_->ListenerThread()->message_loop()->PostTask( | 1262 server_->ListenerThread()->message_loop()->PostTask( |
1263 FROM_HERE, base::Bind(&RestrictedDispatchServer::OnDoPing, server_, 1)); | 1263 FROM_HERE, base::Bind(&RestrictedDispatchServer::OnDoPing, server_, 1)); |
1264 sent_ping_event_->Wait(); | 1264 sent_ping_event_->Wait(); |
1265 Send(new SyncChannelTestMsg_NoArgs); | 1265 Send(new SyncChannelTestMsg_NoArgs); |
1266 if (ping_ == 1) | 1266 if (ping_ == 1) |
1267 ++*success_; | 1267 ++*success_; |
1268 else | 1268 else |
1269 LOG(ERROR) << "Send failed to dispatch incoming message on same channel"; | 1269 LOG(ERROR) << "Send failed to dispatch incoming message on same channel"; |
1270 | 1270 |
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1381 client_kicked_(false) { } | 1381 client_kicked_(false) { } |
1382 | 1382 |
1383 void OnDoServerTask() { | 1383 void OnDoServerTask() { |
1384 events_[3]->Signal(); | 1384 events_[3]->Signal(); |
1385 events_[2]->Wait(); | 1385 events_[2]->Wait(); |
1386 events_[0]->Signal(); | 1386 events_[0]->Signal(); |
1387 SendMessageToClient(); | 1387 SendMessageToClient(); |
1388 } | 1388 } |
1389 | 1389 |
1390 void Run() { | 1390 void Run() { |
1391 channel()->SetRestrictDispatchToSameChannel(true); | 1391 channel()->SetRestrictDispatchChannelGroup(true); |
Josh Horwich
2012/03/29 18:29:22
Shouldn't this be 1 rather than true now?
| |
1392 server_ready_event_->Signal(); | 1392 server_ready_event_->Signal(); |
1393 } | 1393 } |
1394 | 1394 |
1395 base::Thread* ListenerThread() { return Worker::ListenerThread(); } | 1395 base::Thread* ListenerThread() { return Worker::ListenerThread(); } |
1396 | 1396 |
1397 private: | 1397 private: |
1398 bool OnMessageReceived(const Message& message) { | 1398 bool OnMessageReceived(const Message& message) { |
1399 IPC_BEGIN_MESSAGE_MAP(RestrictedDispatchDeadlockServer, message) | 1399 IPC_BEGIN_MESSAGE_MAP(RestrictedDispatchDeadlockServer, message) |
1400 IPC_MESSAGE_HANDLER(SyncChannelTestMsg_NoArgs, OnNoArgs) | 1400 IPC_MESSAGE_HANDLER(SyncChannelTestMsg_NoArgs, OnNoArgs) |
1401 IPC_MESSAGE_HANDLER(SyncChannelTestMsg_Done, Done) | 1401 IPC_MESSAGE_HANDLER(SyncChannelTestMsg_Done, Done) |
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1589 | 1589 |
1590 client1 = new RestrictedDispatchDeadlockClient1(server1, client2, | 1590 client1 = new RestrictedDispatchDeadlockClient1(server1, client2, |
1591 &server1_ready, events); | 1591 &server1_ready, events); |
1592 workers.push_back(client1); | 1592 workers.push_back(client1); |
1593 | 1593 |
1594 RunTest(workers); | 1594 RunTest(workers); |
1595 } | 1595 } |
1596 | 1596 |
1597 //----------------------------------------------------------------------------- | 1597 //----------------------------------------------------------------------------- |
1598 | 1598 |
1599 // This test case inspired by crbug.com/120530 | |
1600 // We create 4 workers that pipe to each other W1->W2->W3->W4->W1 then we send a | |
1601 // message that recurses through 3, 4 or 5 steps to make sure, say, W1 can | |
1602 // re-enter when called from W4 while it's sending a message to W2. | |
1603 // The first worker drives the whole test so it mus be treated specially. | |
Josh Horwich
2012/03/29 18:29:22
Nit: typo (mus -> must)
| |
1604 namespace { | |
1605 | |
1606 class RestrictedDispatchPipeWorker : public Worker { | |
1607 public: | |
1608 RestrictedDispatchPipeWorker( | |
1609 const std::string &channel1, | |
1610 WaitableEvent* event1, | |
1611 const std::string &channel2, | |
1612 WaitableEvent* event2, | |
1613 int group, | |
1614 int* success) | |
1615 : Worker(channel1, Channel::MODE_SERVER), | |
1616 event1_(event1), | |
1617 event2_(event2), | |
1618 other_channel_name_(channel2), | |
1619 group_(group), | |
1620 success_(success) { | |
1621 } | |
1622 | |
1623 void OnPingTTL(int ping, int* ret) { | |
1624 *ret = 0; | |
1625 if (!ping) | |
1626 return; | |
1627 other_channel_->Send(new SyncChannelTestMsg_PingTTL(ping - 1, ret)); | |
1628 ++*ret; | |
1629 } | |
1630 | |
1631 void OnDone() { | |
1632 if (is_first()) | |
1633 return; | |
1634 other_channel_->Send(new SyncChannelTestMsg_Done); | |
1635 other_channel_.reset(); | |
1636 Done(); | |
1637 } | |
1638 | |
1639 void Run() { | |
1640 channel()->SetRestrictDispatchChannelGroup(group_); | |
1641 if (is_first()) | |
1642 event1_->Signal(); | |
1643 event2_->Wait(); | |
1644 other_channel_.reset(new SyncChannel( | |
1645 other_channel_name_, Channel::MODE_CLIENT, this, | |
1646 ipc_thread().message_loop_proxy(), true, shutdown_event())); | |
1647 other_channel_->SetRestrictDispatchChannelGroup(group_); | |
1648 if (!is_first()) { | |
1649 event1_->Signal(); | |
1650 return; | |
1651 } | |
1652 *success_ = 0; | |
1653 int value = 0; | |
1654 OnPingTTL(3, &value); | |
1655 *success_ += (value == 3); | |
1656 OnPingTTL(4, &value); | |
1657 *success_ += (value == 4); | |
1658 OnPingTTL(5, &value); | |
1659 *success_ += (value == 5); | |
1660 other_channel_->Send(new SyncChannelTestMsg_Done); | |
1661 other_channel_.reset(); | |
1662 Done(); | |
1663 } | |
1664 | |
1665 bool is_first() { return !!success_; } | |
1666 | |
1667 private: | |
1668 bool OnMessageReceived(const Message& message) { | |
1669 IPC_BEGIN_MESSAGE_MAP(RestrictedDispatchPipeWorker, message) | |
1670 IPC_MESSAGE_HANDLER(SyncChannelTestMsg_PingTTL, OnPingTTL) | |
1671 IPC_MESSAGE_HANDLER(SyncChannelTestMsg_Done, OnDone) | |
1672 IPC_END_MESSAGE_MAP() | |
1673 return true; | |
1674 } | |
1675 | |
1676 scoped_ptr<SyncChannel> other_channel_; | |
1677 WaitableEvent* event1_; | |
1678 WaitableEvent* event2_; | |
1679 std::string other_channel_name_; | |
1680 int group_; | |
1681 int* success_; | |
1682 }; | |
1683 | |
1684 } // namespace | |
1685 | |
1686 TEST_F(IPCSyncChannelTest, RestrictedDispatch4WayDeadlock) { | |
1687 int success = 0; | |
1688 std::vector<Worker*> workers; | |
1689 WaitableEvent event0(true, false); | |
1690 WaitableEvent event1(true, false); | |
1691 WaitableEvent event2(true, false); | |
1692 WaitableEvent event3(true, false); | |
1693 workers.push_back(new RestrictedDispatchPipeWorker( | |
1694 "channel0", &event0, "channel1", &event1, 1, &success)); | |
1695 workers.push_back(new RestrictedDispatchPipeWorker( | |
1696 "channel1", &event1, "channel2", &event2, 2, NULL)); | |
1697 workers.push_back(new RestrictedDispatchPipeWorker( | |
1698 "channel2", &event2, "channel3", &event3, 3, NULL)); | |
1699 workers.push_back(new RestrictedDispatchPipeWorker( | |
1700 "channel3", &event3, "channel0", &event0, 4, NULL)); | |
1701 RunTest(workers); | |
1702 EXPECT_EQ(3, success); | |
1703 } | |
1704 | |
1705 //----------------------------------------------------------------------------- | |
1706 | |
1599 // Generate a validated channel ID using Channel::GenerateVerifiedChannelID(). | 1707 // Generate a validated channel ID using Channel::GenerateVerifiedChannelID(). |
1600 namespace { | 1708 namespace { |
1601 | 1709 |
1602 class VerifiedServer : public Worker { | 1710 class VerifiedServer : public Worker { |
1603 public: | 1711 public: |
1604 VerifiedServer(base::Thread* listener_thread, | 1712 VerifiedServer(base::Thread* listener_thread, |
1605 const std::string& channel_name, | 1713 const std::string& channel_name, |
1606 const std::string& reply_text) | 1714 const std::string& reply_text) |
1607 : Worker(channel_name, Channel::MODE_SERVER), | 1715 : Worker(channel_name, Channel::MODE_SERVER), |
1608 reply_text_(reply_text) { | 1716 reply_text_(reply_text) { |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1677 | 1785 |
1678 } // namespace | 1786 } // namespace |
1679 | 1787 |
1680 // Windows needs to send an out-of-band secret to verify the client end of the | 1788 // Windows needs to send an out-of-band secret to verify the client end of the |
1681 // channel. Test that we still connect correctly in that case. | 1789 // channel. Test that we still connect correctly in that case. |
1682 TEST_F(IPCSyncChannelTest, Verified) { | 1790 TEST_F(IPCSyncChannelTest, Verified) { |
1683 Verified(); | 1791 Verified(); |
1684 } | 1792 } |
1685 | 1793 |
1686 } // namespace IPC | 1794 } // namespace IPC |
OLD | NEW |