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/memory/ref_counted.h"
9 #include "base/memory/scoped_ptr.h"
10 #include "base/message_loop/message_loop.h"
11 #include "base/synchronization/waitable_event.h"
12 #include "base/threading/thread.h"
13 #include "chrome/browser/sync/glue/ui_model_worker.h"
14 #include "content/public/test/test_browser_thread.h"
15 #include "testing/gtest/include/gtest/gtest.h"
17 using browser_sync::UIModelWorker
;
18 using syncer::SyncerError
;
19 using content::BrowserThread
;
21 class UIModelWorkerVisitor
{
23 UIModelWorkerVisitor(base::WaitableEvent
* was_run
,
25 : quit_loop_when_run_(quit_loop
),
27 virtual ~UIModelWorkerVisitor() { }
29 virtual syncer::SyncerError
DoWork() {
30 EXPECT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::UI
));
32 if (quit_loop_when_run_
)
33 base::MessageLoop::current()->Quit();
34 return syncer::SYNCER_OK
;
38 bool quit_loop_when_run_
;
39 base::WaitableEvent
* was_run_
;
40 DISALLOW_COPY_AND_ASSIGN(UIModelWorkerVisitor
);
43 // A faux-syncer that only interacts with its model safe worker.
46 explicit Syncer(UIModelWorker
* worker
) : worker_(worker
) {}
49 void SyncShare(UIModelWorkerVisitor
* visitor
) {
50 // We wait until the callback is executed. So it is safe to use Unretained.
51 syncer::WorkCallback c
= base::Bind(&UIModelWorkerVisitor::DoWork
,
52 base::Unretained(visitor
));
53 worker_
->DoWorkAndWaitUntilDone(c
);
56 scoped_refptr
<UIModelWorker
> worker_
;
57 DISALLOW_COPY_AND_ASSIGN(Syncer
);
60 class SyncUIModelWorkerTest
: public testing::Test
{
62 SyncUIModelWorkerTest() : faux_syncer_thread_("FauxSyncerThread"),
63 faux_core_thread_("FauxCoreThread") { }
65 virtual void SetUp() {
66 faux_syncer_thread_
.Start();
67 ui_thread_
.reset(new content::TestBrowserThread(BrowserThread::UI
,
69 bmw_
= new UIModelWorker(NULL
);
70 syncer_
.reset(new Syncer(bmw_
.get()));
73 Syncer
* syncer() { return syncer_
.get(); }
74 UIModelWorker
* bmw() { return bmw_
.get(); }
75 base::Thread
* core_thread() { return &faux_core_thread_
; }
76 base::Thread
* syncer_thread() { return &faux_syncer_thread_
; }
78 base::MessageLoop faux_ui_loop_
;
79 scoped_ptr
<content::TestBrowserThread
> ui_thread_
;
80 base::Thread faux_syncer_thread_
;
81 base::Thread faux_core_thread_
;
82 scoped_refptr
<UIModelWorker
> bmw_
;
83 scoped_ptr
<Syncer
> syncer_
;
86 TEST_F(SyncUIModelWorkerTest
, ScheduledWorkRunsOnUILoop
) {
87 base::WaitableEvent
v_was_run(false, false);
88 scoped_ptr
<UIModelWorkerVisitor
> v(
89 new UIModelWorkerVisitor(&v_was_run
, true));
91 syncer_thread()->message_loop()->PostTask(FROM_HERE
,
92 base::Bind(&Syncer::SyncShare
, base::Unretained(syncer()), v
.get()));
94 // We are on the UI thread, so run our loop to process the
95 // (hopefully) scheduled task from a SyncShare invocation.
96 base::MessageLoop::current()->Run();
97 syncer_thread()->Stop();