syncer_proto_util_unittest.cc 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  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.
  4. #include "components/sync/engine/syncer_proto_util.h"
  5. #include <memory>
  6. #include <vector>
  7. #include "base/compiler_specific.h"
  8. #include "base/test/metrics/histogram_tester.h"
  9. #include "components/sync/base/model_type_test_util.h"
  10. #include "components/sync/engine/cycle/sync_cycle_context.h"
  11. #include "components/sync/protocol/bookmark_specifics.pb.h"
  12. #include "components/sync/protocol/password_specifics.pb.h"
  13. #include "components/sync/protocol/sync.pb.h"
  14. #include "components/sync/protocol/sync_enums.pb.h"
  15. #include "components/sync/test/mock_connection_manager.h"
  16. #include "testing/gtest/include/gtest/gtest.h"
  17. using ::testing::_;
  18. using sync_pb::ClientToServerMessage;
  19. using sync_pb::CommitResponse_EntryResponse;
  20. namespace syncer {
  21. // Builds a ClientToServerResponse with some data type ids, including
  22. // invalid ones. GetTypesToMigrate() should return only the valid
  23. // model types.
  24. TEST(SyncerProtoUtil, GetTypesToMigrate) {
  25. sync_pb::ClientToServerResponse response;
  26. response.add_migrated_data_type_id(
  27. GetSpecificsFieldNumberFromModelType(BOOKMARKS));
  28. response.add_migrated_data_type_id(
  29. GetSpecificsFieldNumberFromModelType(HISTORY_DELETE_DIRECTIVES));
  30. response.add_migrated_data_type_id(-1);
  31. EXPECT_EQ(ModelTypeSet(BOOKMARKS, HISTORY_DELETE_DIRECTIVES),
  32. GetTypesToMigrate(response));
  33. }
  34. // Builds a ClientToServerResponse_Error with some error data type
  35. // ids, including invalid ones. ConvertErrorPBToSyncProtocolError() should
  36. // return a SyncProtocolError with only the valid model types.
  37. TEST(SyncerProtoUtil, ConvertErrorPBToSyncProtocolError) {
  38. sync_pb::ClientToServerResponse_Error error_pb;
  39. error_pb.set_error_type(sync_pb::SyncEnums::THROTTLED);
  40. error_pb.add_error_data_type_ids(
  41. GetSpecificsFieldNumberFromModelType(BOOKMARKS));
  42. error_pb.add_error_data_type_ids(
  43. GetSpecificsFieldNumberFromModelType(HISTORY_DELETE_DIRECTIVES));
  44. error_pb.add_error_data_type_ids(-1);
  45. SyncProtocolError error = ConvertErrorPBToSyncProtocolError(error_pb);
  46. EXPECT_EQ(ModelTypeSet(BOOKMARKS, HISTORY_DELETE_DIRECTIVES),
  47. error.error_data_types);
  48. }
  49. class SyncerProtoUtilTest : public testing::Test {
  50. public:
  51. void SetUp() override {
  52. context_ = std::make_unique<SyncCycleContext>(
  53. /*connection_manager=*/nullptr,
  54. /*extensions_activity=*/nullptr,
  55. /*listeners=*/std::vector<SyncEngineEventListener*>(),
  56. /*debug_info_getter=*/nullptr,
  57. /*model_type_registry=*/nullptr,
  58. /*invalidator_client_id=*/"",
  59. /*cache_guid=*/"",
  60. /*birthday=*/"",
  61. /*bag_of_chips=*/"",
  62. /*poll_internal=*/base::Seconds(1));
  63. }
  64. SyncCycleContext* context() { return context_.get(); }
  65. // Helper function to call GetProtocolErrorFromResponse. Allows not adding
  66. // individual tests as friends to SyncerProtoUtil.
  67. static SyncProtocolError CallGetProtocolErrorFromResponse(
  68. const sync_pb::ClientToServerResponse& response,
  69. SyncCycleContext* context) {
  70. return SyncerProtoUtil::GetProtocolErrorFromResponse(response, context);
  71. }
  72. protected:
  73. std::unique_ptr<SyncCycleContext> context_;
  74. };
  75. TEST_F(SyncerProtoUtilTest, VerifyResponseBirthday) {
  76. // Both sides empty
  77. ASSERT_TRUE(context()->birthday().empty());
  78. sync_pb::ClientToServerResponse response;
  79. SyncProtocolError sync_protocol_error;
  80. response.set_error_code(sync_pb::SyncEnums::SUCCESS);
  81. sync_protocol_error = CallGetProtocolErrorFromResponse(response, context());
  82. EXPECT_EQ(NOT_MY_BIRTHDAY, sync_protocol_error.error_type);
  83. EXPECT_EQ(DISABLE_SYNC_ON_CLIENT, sync_protocol_error.action);
  84. // Remote set, local empty
  85. response.set_store_birthday("flan");
  86. sync_protocol_error = CallGetProtocolErrorFromResponse(response, context());
  87. EXPECT_EQ(SYNC_SUCCESS, sync_protocol_error.error_type);
  88. EXPECT_EQ(UNKNOWN_ACTION, sync_protocol_error.action);
  89. EXPECT_EQ(context()->birthday(), "flan");
  90. // Remote empty, local set.
  91. response.clear_store_birthday();
  92. sync_protocol_error = CallGetProtocolErrorFromResponse(response, context());
  93. EXPECT_EQ(SYNC_SUCCESS, sync_protocol_error.error_type);
  94. EXPECT_EQ(UNKNOWN_ACTION, sync_protocol_error.action);
  95. EXPECT_EQ(context()->birthday(), "flan");
  96. // Doesn't match
  97. response.set_store_birthday("meat");
  98. response.set_error_code(sync_pb::SyncEnums::NOT_MY_BIRTHDAY);
  99. sync_protocol_error = CallGetProtocolErrorFromResponse(response, context());
  100. EXPECT_EQ(NOT_MY_BIRTHDAY, sync_protocol_error.error_type);
  101. EXPECT_EQ(DISABLE_SYNC_ON_CLIENT, sync_protocol_error.action);
  102. // Doesn't match. CLIENT_DATA_OBSOLETE error is set.
  103. response.set_error_code(sync_pb::SyncEnums::CLIENT_DATA_OBSOLETE);
  104. sync_protocol_error = CallGetProtocolErrorFromResponse(response, context());
  105. EXPECT_EQ(CLIENT_DATA_OBSOLETE, sync_protocol_error.error_type);
  106. EXPECT_EQ(RESET_LOCAL_SYNC_DATA, sync_protocol_error.action);
  107. }
  108. TEST_F(SyncerProtoUtilTest, VerifyDisabledByAdmin) {
  109. // No error code
  110. sync_pb::ClientToServerResponse response;
  111. SyncProtocolError sync_protocol_error;
  112. context()->set_birthday("flan");
  113. response.set_error_code(sync_pb::SyncEnums::SUCCESS);
  114. sync_protocol_error = CallGetProtocolErrorFromResponse(response, context());
  115. ASSERT_EQ(SYNC_SUCCESS, sync_protocol_error.error_type);
  116. ASSERT_EQ(UNKNOWN_ACTION, sync_protocol_error.action);
  117. // Has error code, but not disabled
  118. response.set_error_code(sync_pb::SyncEnums::NOT_MY_BIRTHDAY);
  119. sync_protocol_error = CallGetProtocolErrorFromResponse(response, context());
  120. EXPECT_EQ(NOT_MY_BIRTHDAY, sync_protocol_error.error_type);
  121. EXPECT_NE(UNKNOWN_ACTION, sync_protocol_error.action);
  122. // Has error code, and is disabled by admin
  123. response.set_error_code(sync_pb::SyncEnums::DISABLED_BY_ADMIN);
  124. sync_protocol_error = CallGetProtocolErrorFromResponse(response, context());
  125. EXPECT_EQ(DISABLED_BY_ADMIN, sync_protocol_error.error_type);
  126. EXPECT_EQ(STOP_SYNC_FOR_DISABLED_ACCOUNT, sync_protocol_error.action);
  127. }
  128. TEST_F(SyncerProtoUtilTest, VerifyUpgradeClient) {
  129. ASSERT_TRUE(context()->birthday().empty());
  130. sync_pb::ClientToServerResponse response;
  131. response.set_error_code(sync_pb::SyncEnums::SUCCESS);
  132. response.mutable_error()->set_error_type(sync_pb::SyncEnums::THROTTLED);
  133. response.mutable_error()->set_action(sync_pb::SyncEnums::UPGRADE_CLIENT);
  134. response.mutable_error()->set_error_description(
  135. "Legacy client needs to be upgraded.");
  136. SyncProtocolError sync_protocol_error =
  137. CallGetProtocolErrorFromResponse(response, context());
  138. EXPECT_EQ(THROTTLED, sync_protocol_error.error_type);
  139. EXPECT_EQ(UPGRADE_CLIENT, sync_protocol_error.action);
  140. }
  141. TEST_F(SyncerProtoUtilTest, VerifyEncryptionObsolete) {
  142. sync_pb::ClientToServerResponse response;
  143. response.set_error_code(sync_pb::SyncEnums::ENCRYPTION_OBSOLETE);
  144. response.set_store_birthday("flan");
  145. SyncProtocolError sync_protocol_error =
  146. CallGetProtocolErrorFromResponse(response, context());
  147. EXPECT_EQ(ENCRYPTION_OBSOLETE, sync_protocol_error.error_type);
  148. EXPECT_EQ(DISABLE_SYNC_ON_CLIENT, sync_protocol_error.action);
  149. }
  150. class DummyConnectionManager : public ServerConnectionManager {
  151. public:
  152. DummyConnectionManager() = default;
  153. HttpResponse PostBuffer(const std::string& buffer_in,
  154. const std::string& access_token,
  155. bool allow_batching,
  156. std::string* buffer_out) override {
  157. if (send_error_) {
  158. return HttpResponse::ForIoError();
  159. }
  160. sync_pb::ClientToServerResponse client_to_server_response;
  161. client_to_server_response.SerializeToString(buffer_out);
  162. return HttpResponse::ForSuccess();
  163. }
  164. void set_send_error(bool send) { send_error_ = send; }
  165. private:
  166. bool send_error_ = false;
  167. };
  168. TEST_F(SyncerProtoUtilTest, PostAndProcessHeaders) {
  169. DummyConnectionManager dcm;
  170. ClientToServerMessage msg;
  171. SyncerProtoUtil::SetProtocolVersion(&msg);
  172. msg.set_share("required");
  173. msg.set_message_contents(ClientToServerMessage::GET_UPDATES);
  174. sync_pb::ClientToServerResponse response;
  175. base::HistogramTester histogram_tester;
  176. dcm.set_send_error(true);
  177. EXPECT_FALSE(SyncerProtoUtil::PostAndProcessHeaders(&dcm, msg, &response));
  178. EXPECT_EQ(1, histogram_tester.GetBucketCount(
  179. "Sync.PostedClientToServerMessage",
  180. /*sample=*/ClientToServerMessage::GET_UPDATES));
  181. dcm.set_send_error(false);
  182. EXPECT_TRUE(SyncerProtoUtil::PostAndProcessHeaders(&dcm, msg, &response));
  183. EXPECT_EQ(2, histogram_tester.GetBucketCount(
  184. "Sync.PostedClientToServerMessage",
  185. /*sample=*/ClientToServerMessage::GET_UPDATES));
  186. }
  187. } // namespace syncer