Index: chrome/browser/sync/glue/chrome_sync_notification_bridge_unittest.cc |
diff --git a/chrome/browser/sync/glue/chrome_sync_notification_bridge_unittest.cc b/chrome/browser/sync/glue/chrome_sync_notification_bridge_unittest.cc |
index ffd42fd6eea1e76ee1bbe028c166f802de0ecf31..39f5f2e535da57c4bd165f7a066b9d6fe3fa920c 100644 |
--- a/chrome/browser/sync/glue/chrome_sync_notification_bridge_unittest.cc |
+++ b/chrome/browser/sync/glue/chrome_sync_notification_bridge_unittest.cc |
@@ -5,8 +5,11 @@ |
#include "chrome/browser/sync/glue/chrome_sync_notification_bridge.h" |
#include "base/compiler_specific.h" |
+#include "base/memory/scoped_ptr.h" |
+#include "base/memory/ref_counted.h" |
#include "base/memory/weak_ptr.h" |
#include "base/message_loop.h" |
+#include "base/sequenced_task_runner.h" |
#include "base/synchronization/waitable_event.h" |
#include "base/test/test_timeouts.h" |
#include "base/threading/thread.h" |
@@ -17,7 +20,6 @@ |
#include "content/public/test/test_browser_thread.h" |
#include "sync/internal_api/public/base/model_type.h" |
#include "sync/internal_api/public/base/model_type_payload_map.h" |
-#include "sync/notifier/mock_sync_notifier_observer.h" |
#include "sync/notifier/sync_notifier_observer.h" |
#include "testing/gmock/include/gmock/gmock.h" |
#include "testing/gtest/include/gtest/gtest.h" |
@@ -34,24 +36,28 @@ using content::BrowserThread; |
// ModelTypePayloadMap. ReceivedProperNotification() will return true only |
// if the observer has received a notification with the proper source and |
// payload. |
-// Note: Because this object lives on the IO thread, we use a fake (vs a mock) |
-// so we don't have to worry about possible thread safety issues within |
-// GTest/GMock. |
-class FakeSyncNotifierObserverIO |
- : public syncer::SyncNotifierObserver { |
+// Note: Because this object lives on the sync thread, we use a fake |
+// (vs a mock) so we don't have to worry about possible thread safety |
+// issues within GTest/GMock. |
+class FakeSyncNotifierObserver : public syncer::SyncNotifierObserver { |
public: |
- FakeSyncNotifierObserverIO( |
+ FakeSyncNotifierObserver( |
+ const scoped_refptr<base::SequencedTaskRunner>& sync_task_runner, |
ChromeSyncNotificationBridge* bridge, |
- const syncer::ModelTypePayloadMap& expected_payloads) |
- : bridge_(bridge), |
+ const syncer::ModelTypePayloadMap& expected_payloads, |
+ syncer::IncomingNotificationSource expected_source) |
+ : sync_task_runner_(sync_task_runner), |
+ bridge_(bridge), |
received_improper_notification_(false), |
notification_count_(0), |
- expected_payloads_(expected_payloads) { |
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
+ expected_payloads_(expected_payloads), |
+ expected_source_(expected_source) { |
+ DCHECK(sync_task_runner_->RunsTasksOnCurrentThread()); |
bridge_->AddObserver(this); |
} |
- virtual ~FakeSyncNotifierObserverIO() { |
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
+ |
+ virtual ~FakeSyncNotifierObserver() { |
+ DCHECK(sync_task_runner_->RunsTasksOnCurrentThread()); |
bridge_->RemoveObserver(this); |
} |
@@ -59,14 +65,14 @@ class FakeSyncNotifierObserverIO |
virtual void OnIncomingNotification( |
const syncer::ModelTypePayloadMap& type_payloads, |
syncer::IncomingNotificationSource source) OVERRIDE { |
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
+ DCHECK(sync_task_runner_->RunsTasksOnCurrentThread()); |
notification_count_++; |
- if (source != syncer::LOCAL_NOTIFICATION) { |
- LOG(ERROR) << "Received notification with wrong source."; |
+ if (source != expected_source_) { |
+ LOG(ERROR) << "Received notification with wrong source"; |
received_improper_notification_ = true; |
} |
if (expected_payloads_ != type_payloads) { |
- LOG(ERROR) << "Received wrong payload."; |
+ LOG(ERROR) << "Received wrong payload"; |
received_improper_notification_ = true; |
} |
} |
@@ -79,89 +85,103 @@ class FakeSyncNotifierObserverIO |
} |
bool ReceivedProperNotification() const { |
+ DCHECK(sync_task_runner_->RunsTasksOnCurrentThread()); |
return (notification_count_ == 1) && !received_improper_notification_; |
} |
private: |
- ChromeSyncNotificationBridge* bridge_; |
+ const scoped_refptr<base::SequencedTaskRunner> sync_task_runner_; |
+ ChromeSyncNotificationBridge* const bridge_; |
bool received_improper_notification_; |
size_t notification_count_; |
- syncer::ModelTypePayloadMap expected_payloads_; |
+ const syncer::ModelTypePayloadMap expected_payloads_; |
+ const syncer::IncomingNotificationSource expected_source_; |
}; |
class ChromeSyncNotificationBridgeTest : public testing::Test { |
public: |
ChromeSyncNotificationBridgeTest() |
: ui_thread_(BrowserThread::UI, &ui_loop_), |
Nicolas Zea
2012/07/20 20:01:37
are ui thread and ui loop both still needed? I don
akalin
2012/07/20 20:19:54
Removed ui_loop_. Also made all the member variab
|
- io_thread_(BrowserThread::IO), |
- io_observer_(NULL), |
- io_observer_notification_failure_(false), |
- bridge_(&mock_profile_), |
- done_(true, false) { |
- io_thread_.StartIOThread(); |
- } |
+ sync_thread_("Sync thread"), |
+ sync_observer_(NULL), |
+ sync_observer_notification_failure_(false), |
+ done_(true, false) {} |
+ |
virtual ~ChromeSyncNotificationBridgeTest() {} |
protected: |
+ virtual void SetUp() OVERRIDE { |
+ ASSERT_TRUE(sync_thread_.Start()); |
+ bridge_.reset( |
+ new ChromeSyncNotificationBridge( |
+ &mock_profile_, sync_thread_.message_loop_proxy())); |
+ } |
+ |
virtual void TearDown() OVERRIDE { |
- io_thread_.Stop(); |
+ sync_thread_.Stop(); |
+ // Must be reset only after the sync thread is stopped. |
+ bridge_.reset(); |
ui_loop_.RunAllPending(); |
- EXPECT_EQ(NULL, io_observer_); |
- if (io_observer_notification_failure_) |
- ADD_FAILURE() << "IO Observer did not receive proper notification."; |
+ EXPECT_EQ(NULL, sync_observer_); |
+ if (sync_observer_notification_failure_) |
+ ADD_FAILURE() << "Sync Observer did not receive proper notification."; |
} |
- void VerifyAndDestroyObserverOnIOThread() { |
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
- if (!io_observer_) { |
- io_observer_notification_failure_ = true; |
+ void VerifyAndDestroyObserverOnSyncThread() { |
+ DCHECK(sync_thread_.message_loop_proxy()->RunsTasksOnCurrentThread()); |
+ if (!sync_observer_) { |
+ sync_observer_notification_failure_ = true; |
} else { |
- io_observer_notification_failure_ = |
- !io_observer_->ReceivedProperNotification(); |
- delete io_observer_; |
- io_observer_ = NULL; |
+ sync_observer_notification_failure_ = |
+ !sync_observer_->ReceivedProperNotification(); |
+ delete sync_observer_; |
+ sync_observer_ = NULL; |
} |
} |
void VerifyAndDestroyObserver() { |
- ASSERT_TRUE(BrowserThread::PostTask( |
- BrowserThread::IO, |
+ ASSERT_TRUE(sync_thread_.message_loop_proxy()->PostTask( |
FROM_HERE, |
base::Bind(&ChromeSyncNotificationBridgeTest:: |
- VerifyAndDestroyObserverOnIOThread, |
+ VerifyAndDestroyObserverOnSyncThread, |
base::Unretained(this)))); |
Nicolas Zea
2012/07/20 20:01:37
does this need a BlockForSyncThread after it? I su
akalin
2012/07/20 20:19:54
Done.
|
} |
- void CreateObserverOnIOThread( |
- syncer::ModelTypePayloadMap expected_payloads) { |
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
- io_observer_ = new FakeSyncNotifierObserverIO(&bridge_, |
- expected_payloads); |
+ void CreateObserverOnSyncThread( |
+ syncer::ModelTypePayloadMap expected_payloads, |
+ syncer::IncomingNotificationSource expected_source) { |
+ DCHECK(sync_thread_.message_loop_proxy()->RunsTasksOnCurrentThread()); |
+ sync_observer_ = new FakeSyncNotifierObserver( |
+ sync_thread_.message_loop_proxy(), |
+ bridge_.get(), |
+ expected_payloads, |
+ expected_source); |
} |
- void CreateObserverWithExpectedPayload( |
- syncer::ModelTypePayloadMap expected_payloads) { |
- ASSERT_TRUE(BrowserThread::PostTask( |
- BrowserThread::IO, |
+ void CreateObserverWithExpectations( |
+ syncer::ModelTypePayloadMap expected_payloads, |
+ syncer::IncomingNotificationSource expected_source) { |
+ ASSERT_TRUE(sync_thread_.message_loop_proxy()->PostTask( |
FROM_HERE, |
- base::Bind(&ChromeSyncNotificationBridgeTest::CreateObserverOnIOThread, |
- base::Unretained(this), |
- expected_payloads))); |
- BlockForIOThread(); |
+ base::Bind( |
+ &ChromeSyncNotificationBridgeTest::CreateObserverOnSyncThread, |
+ base::Unretained(this), |
+ expected_payloads, |
+ expected_source))); |
+ BlockForSyncThread(); |
} |
- void SignalOnIOThread() { |
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
+ void SignalOnSyncThread() { |
+ DCHECK(sync_thread_.message_loop_proxy()->RunsTasksOnCurrentThread()); |
done_.Signal(); |
} |
- void BlockForIOThread() { |
+ void BlockForSyncThread() { |
done_.Reset(); |
- BrowserThread::PostTask( |
- BrowserThread::IO, |
+ ASSERT_TRUE(sync_thread_.message_loop_proxy()->PostTask( |
FROM_HERE, |
- base::Bind(&ChromeSyncNotificationBridgeTest::SignalOnIOThread, |
- base::Unretained(this))); |
+ base::Bind(&ChromeSyncNotificationBridgeTest::SignalOnSyncThread, |
+ base::Unretained(this)))); |
done_.TimedWait(TestTimeouts::action_timeout()); |
if (!done_.IsSignaled()) |
ADD_FAILURE() << "Timed out waiting for IO thread."; |
@@ -178,101 +198,66 @@ class ChromeSyncNotificationBridgeTest : public testing::Test { |
MessageLoop ui_loop_; |
content::TestBrowserThread ui_thread_; |
- content::TestBrowserThread io_thread_; |
+ base::Thread sync_thread_; |
NiceMock<ProfileMock> mock_profile_; |
- // Created/used/destroyed on I/O thread. |
- FakeSyncNotifierObserverIO* io_observer_; |
- bool io_observer_notification_failure_; |
- ChromeSyncNotificationBridge bridge_; |
+ // Created/used/destroyed on sync thread. |
+ FakeSyncNotifierObserver* sync_observer_; |
+ bool sync_observer_notification_failure_; |
+ scoped_ptr<ChromeSyncNotificationBridge> bridge_; |
base::WaitableEvent done_; |
}; |
-// Adds an observer on the UI thread, triggers a local refresh notification, and |
-// ensures the bridge posts a LOCAL_NOTIFICATION with the proper payload to it. |
+// Adds an observer on the sync thread, triggers a local refresh |
+// notification, and ensures the bridge posts a LOCAL_NOTIFICATION |
+// with the proper payload to it. |
TEST_F(ChromeSyncNotificationBridgeTest, LocalNotification) { |
syncer::ModelTypePayloadMap payload_map; |
payload_map[syncer::SESSIONS] = ""; |
- StrictMock<syncer::MockSyncNotifierObserver> observer; |
- EXPECT_CALL(observer, |
- OnIncomingNotification(payload_map, |
- syncer::LOCAL_NOTIFICATION)); |
- bridge_.AddObserver(&observer); |
+ CreateObserverWithExpectations(payload_map, syncer::LOCAL_NOTIFICATION); |
TriggerRefreshNotification(chrome::NOTIFICATION_SYNC_REFRESH_LOCAL, |
payload_map); |
- ui_loop_.RunAllPending(); |
- Mock::VerifyAndClearExpectations(&observer); |
+ VerifyAndDestroyObserver(); |
} |
-// Adds an observer on the UI thread, triggers a remote refresh notification, |
-// and ensures the bridge posts a REMOTE_NOTIFICATION with the proper payload |
-// to it. |
+// Adds an observer on the sync thread, triggers a remote refresh |
+// notification, and ensures the bridge posts a REMOTE_NOTIFICATION |
+// with the proper payload to it. |
TEST_F(ChromeSyncNotificationBridgeTest, RemoteNotification) { |
syncer::ModelTypePayloadMap payload_map; |
- payload_map[syncer::BOOKMARKS] = ""; |
- StrictMock<syncer::MockSyncNotifierObserver> observer; |
- EXPECT_CALL(observer, |
- OnIncomingNotification(payload_map, |
- syncer::REMOTE_NOTIFICATION)); |
- bridge_.AddObserver(&observer); |
+ payload_map[syncer::SESSIONS] = ""; |
+ CreateObserverWithExpectations(payload_map, syncer::REMOTE_NOTIFICATION); |
TriggerRefreshNotification(chrome::NOTIFICATION_SYNC_REFRESH_REMOTE, |
payload_map); |
- ui_loop_.RunAllPending(); |
- Mock::VerifyAndClearExpectations(&observer); |
+ VerifyAndDestroyObserver(); |
} |
-// Adds an observer on the UI thread, triggers a local refresh notification |
-// with empty payload map and ensures the bridge posts a |
+// Adds an observer on the sync thread, triggers a local refresh |
+// notification with empty payload map and ensures the bridge posts a |
// LOCAL_NOTIFICATION with the proper payload to it. |
TEST_F(ChromeSyncNotificationBridgeTest, LocalNotificationEmptyPayloadMap) { |
const syncer::ModelTypeSet enabled_types( |
syncer::BOOKMARKS, syncer::PASSWORDS); |
const syncer::ModelTypePayloadMap enabled_types_payload_map = |
syncer::ModelTypePayloadMapFromEnumSet(enabled_types, std::string()); |
- |
- StrictMock<syncer::MockSyncNotifierObserver> observer; |
- EXPECT_CALL(observer, |
- OnIncomingNotification(enabled_types_payload_map, |
- syncer::LOCAL_NOTIFICATION)); |
- bridge_.AddObserver(&observer); |
- // Set enabled types on the bridge. |
- bridge_.UpdateEnabledTypes(enabled_types); |
+ CreateObserverWithExpectations( |
+ enabled_types_payload_map, syncer::LOCAL_NOTIFICATION); |
TriggerRefreshNotification(chrome::NOTIFICATION_SYNC_REFRESH_LOCAL, |
- syncer::ModelTypePayloadMap()); |
- ui_loop_.RunAllPending(); |
- Mock::VerifyAndClearExpectations(&observer); |
+ enabled_types_payload_map); |
+ VerifyAndDestroyObserver(); |
} |
-// Adds an observer on the UI thread, triggers a remote refresh notification |
-// with empty payload map and ensures the bridge posts a |
+// Adds an observer on the sync thread, triggers a remote refresh |
+// notification with empty payload map and ensures the bridge posts a |
// REMOTE_NOTIFICATION with the proper payload to it. |
TEST_F(ChromeSyncNotificationBridgeTest, RemoteNotificationEmptyPayloadMap) { |
const syncer::ModelTypeSet enabled_types( |
syncer::BOOKMARKS, syncer::TYPED_URLS); |
const syncer::ModelTypePayloadMap enabled_types_payload_map = |
syncer::ModelTypePayloadMapFromEnumSet(enabled_types, std::string()); |
- |
- StrictMock<syncer::MockSyncNotifierObserver> observer; |
- EXPECT_CALL(observer, |
- OnIncomingNotification(enabled_types_payload_map, |
- syncer::REMOTE_NOTIFICATION)); |
- bridge_.AddObserver(&observer); |
- // Set enabled types on the bridge. |
- bridge_.UpdateEnabledTypes(enabled_types); |
+ CreateObserverWithExpectations( |
+ enabled_types_payload_map, syncer::REMOTE_NOTIFICATION); |
TriggerRefreshNotification(chrome::NOTIFICATION_SYNC_REFRESH_REMOTE, |
- syncer::ModelTypePayloadMap()); |
- ui_loop_.RunAllPending(); |
- Mock::VerifyAndClearExpectations(&observer); |
-} |
- |
-// Adds an observer on the I/O thread. Then triggers a refresh notification on |
-// the UI thread. We finally verify the proper notification was received by the |
-// observer and destroy it on the I/O thread. |
-TEST_F(ChromeSyncNotificationBridgeTest, BasicThreaded) { |
- syncer::ModelTypePayloadMap payload_map; |
- payload_map[syncer::SESSIONS] = ""; |
- CreateObserverWithExpectedPayload(payload_map); |
- TriggerRefreshNotification(chrome::NOTIFICATION_SYNC_REFRESH_LOCAL, |
- payload_map); |
+ enabled_types_payload_map); |
VerifyAndDestroyObserver(); |
} |