10f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved. 20f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 30f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)// found in the LICENSE file. 40f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 5f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "mojo/common/handle_watcher.h" 60f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 75d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include <string> 85d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 9f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "base/at_exit.h" 100f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#include "base/auto_reset.h" 110f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#include "base/bind.h" 125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "base/memory/scoped_vector.h" 130f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#include "base/run_loop.h" 140f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#include "base/test/simple_test_tick_clock.h" 155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "base/threading/thread.h" 161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "mojo/common/message_pump_mojo.h" 17a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "mojo/common/time_helper.h" 18effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "mojo/public/cpp/system/core.h" 19e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#include "mojo/public/cpp/test_support/test_utils.h" 200f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h" 210f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 220f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)namespace mojo { 23f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)namespace common { 240f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)namespace test { 250f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccienum MessageLoopConfig { 271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci MESSAGE_LOOP_CONFIG_DEFAULT = 0, 281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci MESSAGE_LOOP_CONFIG_MOJO = 1 291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}; 301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 31cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void ObserveCallback(bool* was_signaled, 32cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) MojoResult* result_observed, 33cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) MojoResult result) { 34cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) *was_signaled = true; 35cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) *result_observed = result; 36cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 37cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 380f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)void RunUntilIdle() { 390f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) base::RunLoop run_loop; 400f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) run_loop.RunUntilIdle(); 410f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)} 420f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 43f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void DeleteWatcherAndForwardResult( 44f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) HandleWatcher* watcher, 45f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) base::Callback<void(MojoResult)> next_callback, 46f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) MojoResult result) { 47f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) delete watcher; 48f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) next_callback.Run(result); 49f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 50f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciscoped_ptr<base::MessageLoop> CreateMessageLoop(MessageLoopConfig config) { 521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_ptr<base::MessageLoop> loop; 531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (config == MESSAGE_LOOP_CONFIG_DEFAULT) 541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci loop.reset(new base::MessageLoop()); 551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci else 561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci loop.reset(new base::MessageLoop(MessagePumpMojo::Create())); 571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return loop.Pass(); 581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 600f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)// Helper class to manage the callback and running the message loop waiting for 610f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)// message to be received. Typical usage is something like: 620f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)// Schedule callback returned from GetCallback(). 630f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)// RunUntilGotCallback(); 640f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)// EXPECT_TRUE(got_callback()); 650f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)// clear_callback(); 660f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)class CallbackHelper { 670f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) public: 680f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) CallbackHelper() 690f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) : got_callback_(false), 700f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) run_loop_(NULL), 710f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) weak_factory_(this) {} 720f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) ~CallbackHelper() {} 730f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 740f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) // See description above |got_callback_|. 750f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) bool got_callback() const { return got_callback_; } 760f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) void clear_callback() { got_callback_ = false; } 770f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 780f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) // Runs the current MessageLoop until the callback returned from GetCallback() 790f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) // is notified. 800f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) void RunUntilGotCallback() { 810f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) ASSERT_TRUE(run_loop_ == NULL); 820f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) base::RunLoop run_loop; 830f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) base::AutoReset<base::RunLoop*> reseter(&run_loop_, &run_loop); 840f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) run_loop.Run(); 850f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) } 860f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 87f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) base::Callback<void(MojoResult)> GetCallback() { 880f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) return base::Bind(&CallbackHelper::OnCallback, weak_factory_.GetWeakPtr()); 890f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) } 900f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 91f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) void Start(HandleWatcher* watcher, const MessagePipeHandle& handle) { 92f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) StartWithCallback(watcher, handle, GetCallback()); 93f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 94f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 95f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) void StartWithCallback(HandleWatcher* watcher, 96f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const MessagePipeHandle& handle, 97f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const base::Callback<void(MojoResult)>& callback) { 98f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) watcher->Start(handle, MOJO_HANDLE_SIGNAL_READABLE, 99f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) MOJO_DEADLINE_INDEFINITE, callback); 1000f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) } 1010f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 1020f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) private: 103f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) void OnCallback(MojoResult result) { 1040f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) got_callback_ = true; 1050f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) if (run_loop_) 1060f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) run_loop_->Quit(); 1070f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) } 1080f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 1090f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) // Set to true when the callback is called. 1100f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) bool got_callback_; 1110f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 1120f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) // If non-NULL we're in RunUntilGotCallback(). 1130f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) base::RunLoop* run_loop_; 1140f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 1150f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) base::WeakPtrFactory<CallbackHelper> weak_factory_; 1160f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 1170f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) private: 1180f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(CallbackHelper); 1190f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)}; 1200f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 1211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciclass HandleWatcherTest : public testing::TestWithParam<MessageLoopConfig> { 1220f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) public: 1231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci HandleWatcherTest() : message_loop_(CreateMessageLoop(GetParam())) {} 1240f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) virtual ~HandleWatcherTest() { 125a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) test::SetTickClockForTest(NULL); 1260f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) } 1270f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 1280f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) protected: 1291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci void TearDownMessageLoop() { 1301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci message_loop_.reset(); 1311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 1321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1330f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) void InstallTickClock() { 134a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) test::SetTickClockForTest(&tick_clock_); 1350f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) } 1360f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 1370f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) base::SimpleTestTickClock tick_clock_; 1380f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 1390f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) private: 140f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) base::ShadowingAtExitManager at_exit_; 1411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_ptr<base::MessageLoop> message_loop_; 142f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 1430f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(HandleWatcherTest); 1440f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)}; 1450f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 1461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciINSTANTIATE_TEST_CASE_P( 1471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci MultipleMessageLoopConfigs, HandleWatcherTest, 1481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci testing::Values(MESSAGE_LOOP_CONFIG_DEFAULT, MESSAGE_LOOP_CONFIG_MOJO)); 1491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1500f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)// Trivial test case with a single handle to watch. 1511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST_P(HandleWatcherTest, SingleHandler) { 1525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) MessagePipe test_pipe; 1535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ASSERT_TRUE(test_pipe.handle0.is_valid()); 1540f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) CallbackHelper callback_helper; 1550f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) HandleWatcher watcher; 1565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) callback_helper.Start(&watcher, test_pipe.handle0.get()); 1570f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) RunUntilIdle(); 1580f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) EXPECT_FALSE(callback_helper.got_callback()); 1595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_TRUE(mojo::test::WriteTextMessage(test_pipe.handle1.get(), 1605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::string())); 1610f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) callback_helper.RunUntilGotCallback(); 1620f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) EXPECT_TRUE(callback_helper.got_callback()); 1630f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)} 1640f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 1650f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)// Creates three handles and notfies them in reverse order ensuring each one is 1660f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)// notified appropriately. 1671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST_P(HandleWatcherTest, ThreeHandles) { 1685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) MessagePipe test_pipe1; 1695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) MessagePipe test_pipe2; 1705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) MessagePipe test_pipe3; 1710f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) CallbackHelper callback_helper1; 1720f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) CallbackHelper callback_helper2; 1730f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) CallbackHelper callback_helper3; 1745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ASSERT_TRUE(test_pipe1.handle0.is_valid()); 1755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ASSERT_TRUE(test_pipe2.handle0.is_valid()); 1765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ASSERT_TRUE(test_pipe3.handle0.is_valid()); 1770f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 1780f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) HandleWatcher watcher1; 1795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) callback_helper1.Start(&watcher1, test_pipe1.handle0.get()); 1800f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) RunUntilIdle(); 1810f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) EXPECT_FALSE(callback_helper1.got_callback()); 1820f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) EXPECT_FALSE(callback_helper2.got_callback()); 1830f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) EXPECT_FALSE(callback_helper3.got_callback()); 1840f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 1850f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) HandleWatcher watcher2; 1865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) callback_helper2.Start(&watcher2, test_pipe2.handle0.get()); 1870f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) RunUntilIdle(); 1880f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) EXPECT_FALSE(callback_helper1.got_callback()); 1890f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) EXPECT_FALSE(callback_helper2.got_callback()); 1900f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) EXPECT_FALSE(callback_helper3.got_callback()); 1910f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 1920f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) HandleWatcher watcher3; 1935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) callback_helper3.Start(&watcher3, test_pipe3.handle0.get()); 1940f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) RunUntilIdle(); 1950f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) EXPECT_FALSE(callback_helper1.got_callback()); 1960f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) EXPECT_FALSE(callback_helper2.got_callback()); 1970f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) EXPECT_FALSE(callback_helper3.got_callback()); 1980f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 1990f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) // Write to 3 and make sure it's notified. 2005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_TRUE(mojo::test::WriteTextMessage(test_pipe3.handle1.get(), 2015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::string())); 2020f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) callback_helper3.RunUntilGotCallback(); 2030f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) EXPECT_FALSE(callback_helper1.got_callback()); 2040f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) EXPECT_FALSE(callback_helper2.got_callback()); 2050f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) EXPECT_TRUE(callback_helper3.got_callback()); 2060f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) callback_helper3.clear_callback(); 2070f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 2080f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) // Write to 1 and 3. Only 1 should be notified since 3 was is no longer 2090f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) // running. 2105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_TRUE(mojo::test::WriteTextMessage(test_pipe1.handle1.get(), 2115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::string())); 2125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_TRUE(mojo::test::WriteTextMessage(test_pipe3.handle1.get(), 2135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::string())); 2140f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) callback_helper1.RunUntilGotCallback(); 2150f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) EXPECT_TRUE(callback_helper1.got_callback()); 2160f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) EXPECT_FALSE(callback_helper2.got_callback()); 2170f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) EXPECT_FALSE(callback_helper3.got_callback()); 2180f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) callback_helper1.clear_callback(); 2190f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 2200f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) // Write to 1 and 2. Only 2 should be notified (since 1 was already notified). 2215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_TRUE(mojo::test::WriteTextMessage(test_pipe1.handle1.get(), 2225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::string())); 2235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_TRUE(mojo::test::WriteTextMessage(test_pipe2.handle1.get(), 2245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::string())); 2250f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) callback_helper2.RunUntilGotCallback(); 2260f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) EXPECT_FALSE(callback_helper1.got_callback()); 2270f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) EXPECT_TRUE(callback_helper2.got_callback()); 2280f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) EXPECT_FALSE(callback_helper3.got_callback()); 2290f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)} 2300f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 2310f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)// Verifies Start() invoked a second time works. 2321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST_P(HandleWatcherTest, Restart) { 2335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) MessagePipe test_pipe1; 2345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) MessagePipe test_pipe2; 2350f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) CallbackHelper callback_helper1; 2360f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) CallbackHelper callback_helper2; 2375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ASSERT_TRUE(test_pipe1.handle0.is_valid()); 2385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ASSERT_TRUE(test_pipe2.handle0.is_valid()); 2390f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 2400f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) HandleWatcher watcher1; 2415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) callback_helper1.Start(&watcher1, test_pipe1.handle0.get()); 2420f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) RunUntilIdle(); 2430f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) EXPECT_FALSE(callback_helper1.got_callback()); 2440f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) EXPECT_FALSE(callback_helper2.got_callback()); 2450f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 2460f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) HandleWatcher watcher2; 2475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) callback_helper2.Start(&watcher2, test_pipe2.handle0.get()); 2480f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) RunUntilIdle(); 2490f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) EXPECT_FALSE(callback_helper1.got_callback()); 2500f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) EXPECT_FALSE(callback_helper2.got_callback()); 2510f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 2520f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) // Write to 1 and make sure it's notified. 2535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_TRUE(mojo::test::WriteTextMessage(test_pipe1.handle1.get(), 2545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::string())); 2550f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) callback_helper1.RunUntilGotCallback(); 2560f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) EXPECT_TRUE(callback_helper1.got_callback()); 2570f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) EXPECT_FALSE(callback_helper2.got_callback()); 2580f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) callback_helper1.clear_callback(); 2595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_TRUE(mojo::test::DiscardMessage(test_pipe1.handle0.get())); 2600f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 2610f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) // Write to 2 and make sure it's notified. 2625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_TRUE(mojo::test::WriteTextMessage(test_pipe2.handle1.get(), 2635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::string())); 2640f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) callback_helper2.RunUntilGotCallback(); 2650f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) EXPECT_FALSE(callback_helper1.got_callback()); 2660f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) EXPECT_TRUE(callback_helper2.got_callback()); 2670f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) callback_helper2.clear_callback(); 2680f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 2690f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) // Listen on 1 again. 2705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) callback_helper1.Start(&watcher1, test_pipe1.handle0.get()); 2710f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) RunUntilIdle(); 2720f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) EXPECT_FALSE(callback_helper1.got_callback()); 2730f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) EXPECT_FALSE(callback_helper2.got_callback()); 2740f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 2750f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) // Write to 1 and make sure it's notified. 2765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_TRUE(mojo::test::WriteTextMessage(test_pipe1.handle1.get(), 2775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::string())); 2780f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) callback_helper1.RunUntilGotCallback(); 2790f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) EXPECT_TRUE(callback_helper1.got_callback()); 2800f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) EXPECT_FALSE(callback_helper2.got_callback()); 2810f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)} 2820f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 2830f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)// Verifies deadline is honored. 2841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST_P(HandleWatcherTest, Deadline) { 2850f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) InstallTickClock(); 2860f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 2875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) MessagePipe test_pipe1; 2885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) MessagePipe test_pipe2; 2895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) MessagePipe test_pipe3; 2900f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) CallbackHelper callback_helper1; 2910f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) CallbackHelper callback_helper2; 2920f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) CallbackHelper callback_helper3; 2935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ASSERT_TRUE(test_pipe1.handle0.is_valid()); 2945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ASSERT_TRUE(test_pipe2.handle0.is_valid()); 2955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ASSERT_TRUE(test_pipe3.handle0.is_valid()); 2960f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 2970f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) // Add a watcher with an infinite timeout. 2980f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) HandleWatcher watcher1; 2995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) callback_helper1.Start(&watcher1, test_pipe1.handle0.get()); 3000f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) RunUntilIdle(); 3010f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) EXPECT_FALSE(callback_helper1.got_callback()); 3020f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) EXPECT_FALSE(callback_helper2.got_callback()); 3030f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) EXPECT_FALSE(callback_helper3.got_callback()); 3040f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 3050f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) // Add another watcher wth a timeout of 500 microseconds. 3060f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) HandleWatcher watcher2; 307f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) watcher2.Start(test_pipe2.handle0.get(), MOJO_HANDLE_SIGNAL_READABLE, 500, 3080f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) callback_helper2.GetCallback()); 3090f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) RunUntilIdle(); 3100f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) EXPECT_FALSE(callback_helper1.got_callback()); 3110f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) EXPECT_FALSE(callback_helper2.got_callback()); 3120f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) EXPECT_FALSE(callback_helper3.got_callback()); 3130f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 3140f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) // Advance the clock passed the deadline. We also have to start another 3150f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) // watcher to wake up the background thread. 3160f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) tick_clock_.Advance(base::TimeDelta::FromMicroseconds(501)); 3170f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 3180f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) HandleWatcher watcher3; 3195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) callback_helper3.Start(&watcher3, test_pipe3.handle0.get()); 3200f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 3210f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) callback_helper2.RunUntilGotCallback(); 3220f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) EXPECT_FALSE(callback_helper1.got_callback()); 3230f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) EXPECT_TRUE(callback_helper2.got_callback()); 3240f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) EXPECT_FALSE(callback_helper3.got_callback()); 3250f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)} 3260f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 3271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST_P(HandleWatcherTest, DeleteInCallback) { 3285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) MessagePipe test_pipe; 329f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) CallbackHelper callback_helper; 330f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 331f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) HandleWatcher* watcher = new HandleWatcher(); 3325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) callback_helper.StartWithCallback(watcher, test_pipe.handle1.get(), 333f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) base::Bind(&DeleteWatcherAndForwardResult, 334f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) watcher, 335f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) callback_helper.GetCallback())); 3365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_TRUE(mojo::test::WriteTextMessage(test_pipe.handle0.get(), 3375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::string())); 338f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) callback_helper.RunUntilGotCallback(); 339f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) EXPECT_TRUE(callback_helper.got_callback()); 340f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 341f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 3421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST_P(HandleWatcherTest, AbortedOnMessageLoopDestruction) { 343cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) bool was_signaled = false; 344cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) MojoResult result = MOJO_RESULT_OK; 345cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 346cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) MessagePipe pipe; 347cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) HandleWatcher watcher; 3481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci watcher.Start(pipe.handle0.get(), 3491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci MOJO_HANDLE_SIGNAL_READABLE, 3501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci MOJO_DEADLINE_INDEFINITE, 3511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::Bind(&ObserveCallback, &was_signaled, &result)); 352cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 3531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Now, let the MessageLoop get torn down. We expect our callback to run. 3541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci TearDownMessageLoop(); 355cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 356cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EXPECT_TRUE(was_signaled); 357cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EXPECT_EQ(MOJO_RESULT_ABORTED, result); 358cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 359cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 3605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void NeverReached(MojoResult result) { 3615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) FAIL() << "Callback should never be invoked " << result; 3625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 3635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 3645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// Called on the main thread when a thread is done. Decrements |active_count| 3655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// and if |active_count| is zero quits |run_loop|. 3665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void StressThreadDone(base::RunLoop* run_loop, int* active_count) { 3675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) (*active_count)--; 3685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) EXPECT_GE(*active_count, 0); 3695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (*active_count == 0) 3705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) run_loop->Quit(); 3715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 3725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 3735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// See description of StressTest. This is called on the background thread. 3745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// |count| is the number of HandleWatchers to create. |active_count| is the 3755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// number of outstanding threads, |task_runner| the task runner for the main 3765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// thread and |run_loop| the run loop that should be quit when there are no more 3775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// threads running. When done StressThreadDone() is invoked on the main thread. 3785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// |active_count| and |run_loop| should only be used on the main thread. 3795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void RunStressTest(int count, 3805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) scoped_refptr<base::TaskRunner> task_runner, 3815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base::RunLoop* run_loop, 3825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) int* active_count) { 3835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) struct TestData { 3845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) MessagePipe pipe; 3855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) HandleWatcher watcher; 3865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) }; 3875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ScopedVector<TestData> data_vector; 3885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for (int i = 0; i < count; ++i) { 3895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (i % 20 == 0) { 3905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // Every so often we wait. This results in some level of thread balancing 3915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // as well as making sure HandleWatcher has time to actually start some 3925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // watches. 3935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) MessagePipe test_pipe; 3945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ASSERT_TRUE(test_pipe.handle0.is_valid()); 3955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) CallbackHelper callback_helper; 3965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) HandleWatcher watcher; 3975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) callback_helper.Start(&watcher, test_pipe.handle0.get()); 3985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) RunUntilIdle(); 3995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) EXPECT_FALSE(callback_helper.got_callback()); 4005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) EXPECT_TRUE(mojo::test::WriteTextMessage(test_pipe.handle1.get(), 4015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) std::string())); 4025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base::MessageLoop::ScopedNestableTaskAllower scoper( 4035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base::MessageLoop::current()); 4045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) callback_helper.RunUntilGotCallback(); 4055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) EXPECT_TRUE(callback_helper.got_callback()); 4065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } else { 4075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) scoped_ptr<TestData> test_data(new TestData); 4085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ASSERT_TRUE(test_data->pipe.handle0.is_valid()); 4095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) test_data->watcher.Start(test_data->pipe.handle0.get(), 4105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) MOJO_HANDLE_SIGNAL_READABLE, 4115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) MOJO_DEADLINE_INDEFINITE, 4125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base::Bind(&NeverReached)); 4135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) data_vector.push_back(test_data.release()); 4145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 4155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (i % 15 == 0) 4165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) data_vector.clear(); 4175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 4185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) task_runner->PostTask(FROM_HERE, 4195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base::Bind(&StressThreadDone, run_loop, 4205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) active_count)); 4215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 4225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 4235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// This test is meant to stress HandleWatcher. It uses from various threads 4245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// repeatedly starting and stopping watches. It spins up kThreadCount 4255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// threads. Each thread creates kWatchCount watches. Every so often each thread 4265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// writes to a pipe and waits for the response. 4275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)TEST(HandleWatcherCleanEnvironmentTest, StressTest) { 4285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#if defined(NDEBUG) 4295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const int kThreadCount = 15; 4305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const int kWatchCount = 400; 4315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#else 4325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const int kThreadCount = 10; 4335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const int kWatchCount = 250; 4345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#endif 4355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 4365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base::ShadowingAtExitManager at_exit; 4375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base::MessageLoop message_loop; 4385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base::RunLoop run_loop; 4395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ScopedVector<base::Thread> threads; 4405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) int threads_active_counter = kThreadCount; 4415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // Starts the threads first and then post the task in hopes of having more 4425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // threads running at once. 4435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for (int i = 0; i < kThreadCount; ++i) { 4445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) scoped_ptr<base::Thread> thread(new base::Thread("test thread")); 4451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (i % 2) { 4461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::Thread::Options thread_options; 4471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci thread_options.message_pump_factory = 4481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::Bind(&MessagePumpMojo::Create); 4491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci thread->StartWithOptions(thread_options); 4501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } else { 4511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci thread->Start(); 4521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 4535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) threads.push_back(thread.release()); 4545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 4555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for (int i = 0; i < kThreadCount; ++i) { 4565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) threads[i]->task_runner()->PostTask( 4575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) FROM_HERE, base::Bind(&RunStressTest, kWatchCount, 4585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) message_loop.task_runner(), 4595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) &run_loop, &threads_active_counter)); 4605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 4615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) run_loop.Run(); 4625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ASSERT_EQ(0, threads_active_counter); 4635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 4645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 4650f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)} // namespace test 466f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} // namespace common 4670f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)} // namespace mojo 468