15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/worker_thread_ticker.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
79ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include "base/message_loop/message_loop.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/threading/platform_thread.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class TestCallback : public WorkerThreadTicker::Callback {
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
15a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  TestCallback() : counter_(0), message_loop_(base::MessageLoop::current()) {}
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnTick() OVERRIDE {
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    counter_++;
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Finish the test faster.
21a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    message_loop_->PostTask(FROM_HERE, base::MessageLoop::QuitClosure());
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int counter() const { return counter_; }
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int counter_;
28a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  base::MessageLoop* message_loop_;
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class LongCallback : public WorkerThreadTicker::Callback {
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnTick() OVERRIDE {
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(1500));
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RunMessageLoopForAWhile() {
39a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  base::MessageLoop::current()->PostDelayedTask(
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      FROM_HERE,
41a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      base::MessageLoop::QuitClosure(),
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::TimeDelta::FromMilliseconds(500));
43a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  base::MessageLoop::current()->Run();
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(WorkerThreadTickerTest, Basic) {
49a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  base::MessageLoop loop;
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCallback callback;
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WorkerThreadTicker ticker(50);
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(ticker.IsRunning());
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(ticker.RegisterTickHandler(&callback));
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(ticker.UnregisterTickHandler(&callback));
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(ticker.Start());
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(ticker.RegisterTickHandler(&callback));
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(ticker.UnregisterTickHandler(&callback));
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(ticker.IsRunning());
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(ticker.Start());  // Can't start when it is running.
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(ticker.Stop());
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(ticker.IsRunning());
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(ticker.Stop());  // Can't stop when it isn't running.
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(WorkerThreadTickerTest, Callback) {
67a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  base::MessageLoop loop;
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCallback callback;
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WorkerThreadTicker ticker(50);
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(ticker.RegisterTickHandler(&callback));
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(ticker.Start());
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunMessageLoopForAWhile();
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(callback.counter() > 0);
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(ticker.Stop());
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int counter_value = callback.counter();
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunMessageLoopForAWhile();
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(counter_value, callback.counter());
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(WorkerThreadTickerTest, OutOfScope) {
84a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  base::MessageLoop loop;
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCallback callback;
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WorkerThreadTicker ticker(50);
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(ticker.RegisterTickHandler(&callback));
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(ticker.Start());
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RunMessageLoopForAWhile();
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(callback.counter() > 0);
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int counter_value = callback.counter();
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunMessageLoopForAWhile();
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(counter_value, callback.counter());
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(WorkerThreadTickerTest, LongCallback) {
101a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  base::MessageLoop loop;
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LongCallback callback;
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WorkerThreadTicker ticker(50);
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(ticker.RegisterTickHandler(&callback));
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(ticker.Start());
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunMessageLoopForAWhile();
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
110