11e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
21e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
31e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// found in the LICENSE file.
41e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
51e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "mojo/system/test_utils.h"
61e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
71e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "base/bind.h"
81e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "base/callback.h"
91e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "base/synchronization/waitable_event.h"
10cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/test/test_timeouts.h"
11cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "build/build_config.h"
121e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
131e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)namespace mojo {
141e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)namespace system {
151e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)namespace test {
161e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
171e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)namespace {
181e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
191e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void PostTaskAndWaitHelper(base::WaitableEvent* event,
201e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                           const base::Closure& task) {
211e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  task.Run();
221e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  event->Signal();
231e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
241e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
251e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}  // namespace
261e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
271e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void PostTaskAndWait(scoped_refptr<base::TaskRunner> task_runner,
281e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                     const tracked_objects::Location& from_here,
291e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                     const base::Closure& task) {
301e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  base::WaitableEvent event(false, false);
311e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  task_runner->PostTask(from_here,
321e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                        base::Bind(&PostTaskAndWaitHelper, &event, task));
331e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  event.Wait();
341e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
351e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
36cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)base::TimeDelta EpsilonTimeout() {
37cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Originally, our epsilon timeout was 10 ms, which was mostly fine but flaky
38cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // on some Windows bots. I don't recall ever seeing flakes on other bots. At
39cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // 30 ms tests seem reliable on Windows bots, but not at 25 ms. We'd like this
40cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // timeout to be as small as possible (see the description in the .h file).
41cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  //
42cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Currently, |tiny_timeout()| is usually 100 ms (possibly scaled under ASAN,
43cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // etc.). Based on this, set it to (usually be) 30 ms on Windows and 20 ms
44cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // elsewhere.
45cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#if defined(OS_WIN)
46cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return (TestTimeouts::tiny_timeout() * 3) / 10;
47cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#else
48cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return (TestTimeouts::tiny_timeout() * 2) / 10;
49cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#endif
50cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
51cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
52a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// TestIOThread ----------------------------------------------------------------
535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
54a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)TestIOThread::TestIOThread(Mode mode)
55a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    : io_thread_("test_io_thread"),
56a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      io_thread_started_(false) {
57a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  switch (mode) {
58a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    case kAutoStart:
59a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      Start();
60a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      return;
61a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    case kManualStart:
62a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      return;
63a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
64a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  CHECK(false) << "Invalid mode";
655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
67a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)TestIOThread::~TestIOThread() {
68a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  Stop();
695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
71a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void TestIOThread::Start() {
72a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  CHECK(!io_thread_started_);
73a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  io_thread_started_ = true;
74a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  CHECK(io_thread_.StartWithOptions(
75a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::Thread::Options(base::MessageLoop::TYPE_IO, 0)));
765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
78a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void TestIOThread::Stop() {
79a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Note: It's okay to call |Stop()| even if the thread isn't running.
805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  io_thread_.Stop();
81a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  io_thread_started_ = false;
82a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
83a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
84a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void TestIOThread::PostTask(const tracked_objects::Location& from_here,
85a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                            const base::Closure& task) {
86a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  task_runner()->PostTask(from_here, task);
87a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
88a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
89a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void TestIOThread::PostTaskAndWait(const tracked_objects::Location& from_here,
90a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                   const base::Closure& task) {
91a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ::mojo::system::test::PostTaskAndWait(task_runner(), from_here, task);
925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
941e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}  // namespace test
951e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}  // namespace system
961e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}  // namespace mojo
97