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
3 // found in the LICENSE file.
6 #include "base/bind_helpers.h"
7 #include "base/callback.h"
8 #include "base/location.h"
9 #include "base/memory/ref_counted.h"
10 #include "base/memory/scoped_ptr.h"
11 #include "base/single_thread_task_runner.h"
12 #include "base/synchronization/waitable_event.h"
13 #include "base/threading/thread.h"
14 #include "components/sync_driver/glue/ui_model_worker.h"
15 #include "content/public/test/test_browser_thread.h"
16 #include "testing/gtest/include/gtest/gtest.h"
18 using browser_sync::UIModelWorker
;
19 using syncer::SyncerError
;
20 using content::BrowserThread
;
22 class UIModelWorkerVisitor
{
24 UIModelWorkerVisitor(base::WaitableEvent
* was_run
,
26 : quit_loop_when_run_(quit_loop
),
28 virtual ~UIModelWorkerVisitor() { }
30 virtual syncer::SyncerError
DoWork() {
31 EXPECT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::UI
));
33 if (quit_loop_when_run_
)
34 base::MessageLoop::current()->Quit();
35 return syncer::SYNCER_OK
;
39 bool quit_loop_when_run_
;
40 base::WaitableEvent
* was_run_
;
41 DISALLOW_COPY_AND_ASSIGN(UIModelWorkerVisitor
);
44 // A faux-syncer that only interacts with its model safe worker.
47 explicit Syncer(UIModelWorker
* worker
) : worker_(worker
) {}
50 void SyncShare(UIModelWorkerVisitor
* visitor
) {
51 // We wait until the callback is executed. So it is safe to use Unretained.
52 syncer::WorkCallback c
= base::Bind(&UIModelWorkerVisitor::DoWork
,
53 base::Unretained(visitor
));
54 worker_
->DoWorkAndWaitUntilDone(c
);
57 scoped_refptr
<UIModelWorker
> worker_
;
58 DISALLOW_COPY_AND_ASSIGN(Syncer
);
61 class SyncUIModelWorkerTest
: public testing::Test
{
63 SyncUIModelWorkerTest() : faux_syncer_thread_("FauxSyncerThread"),
64 faux_core_thread_("FauxCoreThread") { }
66 void SetUp() override
{
67 faux_syncer_thread_
.Start();
68 ui_thread_
.reset(new content::TestBrowserThread(BrowserThread::UI
,
70 bmw_
= new UIModelWorker(
71 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI
),
73 syncer_
.reset(new Syncer(bmw_
.get()));
76 Syncer
* syncer() { return syncer_
.get(); }
77 UIModelWorker
* bmw() { return bmw_
.get(); }
78 base::Thread
* core_thread() { return &faux_core_thread_
; }
79 base::Thread
* syncer_thread() { return &faux_syncer_thread_
; }
81 base::MessageLoop faux_ui_loop_
;
82 scoped_ptr
<content::TestBrowserThread
> ui_thread_
;
83 base::Thread faux_syncer_thread_
;
84 base::Thread faux_core_thread_
;
85 scoped_refptr
<UIModelWorker
> bmw_
;
86 scoped_ptr
<Syncer
> syncer_
;
89 TEST_F(SyncUIModelWorkerTest
, ScheduledWorkRunsOnUILoop
) {
90 base::WaitableEvent
v_was_run(false, false);
91 scoped_ptr
<UIModelWorkerVisitor
> v(
92 new UIModelWorkerVisitor(&v_was_run
, true));
94 syncer_thread()->task_runner()->PostTask(
96 base::Bind(&Syncer::SyncShare
, base::Unretained(syncer()), v
.get()));
98 // We are on the UI thread, so run our loop to process the
99 // (hopefully) scheduled task from a SyncShare invocation.
100 base::MessageLoop::current()->Run();
101 syncer_thread()->Stop();