Commit 37b0119b authored by Josh Nohle's avatar Josh Nohle Committed by Commit Bot

[DeviceSync v2] Schedule a first-time v2 DeviceSync

If a v2 DeviceSync has never successfully completed and there are no
pending failure retries, schedule a first-time initialization sync.
Previously, we were waiting for an InvokeNext instruction after a v2
Enrollment or a GCM notification before scheduling the first v2
DeviceSync.

This change ensures that Chrome OS starts using v2 DeviceSync as soon as
the flag is enabled.

Bug: 951969
Change-Id: I6ed5330029f943d3cf1ae07eefa9d88f965689f8
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2116227
Auto-Submit: Josh Nohle <nohle@chromium.org>
Commit-Queue: James Vecore <vecore@google.com>
Reviewed-by: default avatarJames Vecore <vecore@google.com>
Cr-Commit-Position: refs/heads/master@{#753265}
parent 5a515f97
...@@ -510,7 +510,18 @@ void CryptAuthSchedulerImpl::ScheduleNextRequest(RequestType request_type) { ...@@ -510,7 +510,18 @@ void CryptAuthSchedulerImpl::ScheduleNextRequest(RequestType request_type) {
base::nullopt /* session_id */); base::nullopt /* session_id */);
} }
// Schedule a first-time DeviceSync if one has never successfully completed.
// However, unlike Enrollment, there are no periodic DeviceSyncs.
if (request_type == RequestType::kDeviceSync &&
!pending_requests_[request_type] && !GetLastSuccessTime(request_type)) {
pending_requests_[request_type] = BuildClientMetadata(
0 /* retry_count */, cryptauthv2::ClientMetadata::INITIALIZATION,
base::nullopt /* session_id */);
}
if (!pending_requests_[request_type]) { if (!pending_requests_[request_type]) {
// By this point, only DeviceSync can have no requests pending because it
// does not schedule periodic syncs.
DCHECK_EQ(RequestType::kDeviceSync, request_type); DCHECK_EQ(RequestType::kDeviceSync, request_type);
pref_service_->SetString(GetPendingRequestPrefName(request_type), pref_service_->SetString(GetPendingRequestPrefName(request_type),
kNoClientMetadata); kNoClientMetadata);
......
...@@ -41,7 +41,8 @@ namespace device_sync { ...@@ -41,7 +41,8 @@ namespace device_sync {
// is made immediately on startup. After a successful Enrollment, periodic // is made immediately on startup. After a successful Enrollment, periodic
// Enrollment requests are made at time intervals provided by the CryptAuth // Enrollment requests are made at time intervals provided by the CryptAuth
// server in the ClientDirective proto. Note that there is no periodic // server in the ClientDirective proto. Note that there is no periodic
// scheduling for DeviceSync, per se. // scheduling for DeviceSync, per se; however, an initialization request will be
// made.
// //
// ClientDirectives received from CryptAuth may contain an InvokeNext field // ClientDirectives received from CryptAuth may contain an InvokeNext field
// specifying that an Enrollment and/or DeviceSync request should be made // specifying that an Enrollment and/or DeviceSync request should be made
......
...@@ -445,6 +445,62 @@ TEST_F(DeviceSyncCryptAuthSchedulerImplTest, ...@@ -445,6 +445,62 @@ TEST_F(DeviceSyncCryptAuthSchedulerImplTest,
VerifyClientDirective(cryptauthv2::GetClientDirectiveForTest()); VerifyClientDirective(cryptauthv2::GetClientDirectiveForTest());
} }
TEST_F(DeviceSyncCryptAuthSchedulerImplTest,
SuccessfulInitializationDeviceSync) {
AddDisconnectedWifiNetwork();
SetWifiNetworkStatus(NetworkConnectionStatus::kConnected);
const base::Time kStartTime = base::Time::FromDoubleT(1600600000);
const base::Time kInitializationFinishTime =
kStartTime + base::TimeDelta::FromSeconds(5);
clock()->SetNow(kStartTime);
CreateScheduler(base::nullopt /* persisted_client_directive */,
base::nullopt /* persisted_enrollment_client_metadata */,
base::nullopt /* persisted_last_enrollment_attempt_time */,
base::nullopt /* persisted_last_successful_enrollment_time */,
base::nullopt /* persisted_device_sync_client_metadata */,
base::nullopt /* persisted_last_device_sync_attempt_time */,
base::nullopt /* persisted_last_successful_device_sync_time */
);
// No DeviceSync has been scheduled yet.
EXPECT_FALSE(device_sync_timer()->IsRunning());
EXPECT_EQ(base::nullopt, scheduler()->GetTimeToNextDeviceSyncRequest());
EXPECT_FALSE(scheduler()->HasDeviceSyncSchedulingStarted());
scheduler()->StartDeviceSyncScheduling(fake_device_sync_delegate());
EXPECT_TRUE(scheduler()->HasDeviceSyncSchedulingStarted());
// No successful DeviceSync has ever occurred; attempt immediately.
cryptauthv2::ClientMetadata expected_scheduled_device_sync_request =
cryptauthv2::BuildClientMetadata(
0 /* retry_count */, cryptauthv2::ClientMetadata::INITIALIZATION,
base::nullopt /* session_id */);
VerifyScheduledDeviceSync(expected_scheduled_device_sync_request,
kZeroTimeDelta /* expected_delay */);
device_sync_timer()->Fire();
EXPECT_TRUE(scheduler()->IsWaitingForDeviceSyncResult());
VerifyLastClientMetadataReceivedByDeviceSyncDelegate(
1 /* total_received */, expected_scheduled_device_sync_request);
clock()->SetNow(kInitializationFinishTime);
scheduler()->HandleDeviceSyncResult(
CryptAuthDeviceSyncResult(CryptAuthDeviceSyncResult::ResultCode::kSuccess,
true /* did_device_registry_change */,
cryptauthv2::GetClientDirectiveForTest()));
VerifyLastDeviceSyncAttemptTime(kInitializationFinishTime);
VerifyLastSuccessfulDeviceSyncTime(kInitializationFinishTime);
VerifyClientDirective(cryptauthv2::GetClientDirectiveForTest());
// No periodic DeviceSyncs are scheduled.
EXPECT_FALSE(device_sync_timer()->IsRunning());
EXPECT_EQ(base::nullopt, scheduler()->GetTimeToNextDeviceSyncRequest());
}
TEST_F(DeviceSyncCryptAuthSchedulerImplTest, FailedRequests) { TEST_F(DeviceSyncCryptAuthSchedulerImplTest, FailedRequests) {
AddDisconnectedWifiNetwork(); AddDisconnectedWifiNetwork();
SetWifiNetworkStatus(NetworkConnectionStatus::kConnected); SetWifiNetworkStatus(NetworkConnectionStatus::kConnected);
...@@ -698,13 +754,20 @@ TEST_F(DeviceSyncCryptAuthSchedulerImplTest, HandleInvokeNext) { ...@@ -698,13 +754,20 @@ TEST_F(DeviceSyncCryptAuthSchedulerImplTest, HandleInvokeNext) {
AddDisconnectedWifiNetwork(); AddDisconnectedWifiNetwork();
SetWifiNetworkStatus(NetworkConnectionStatus::kConnected); SetWifiNetworkStatus(NetworkConnectionStatus::kConnected);
CreateScheduler(base::nullopt /* persisted_client_directive */, const base::Time kLastSuccessTime = base::Time::FromDoubleT(1600600000);
base::nullopt /* persisted_enrollment_client_metadata */, const base::Time kLastAttemptTime =
base::nullopt /* persisted_last_enrollment_attempt_time */, kLastSuccessTime + base::TimeDelta::FromDays(30);
base::nullopt /* persisted_last_successful_enrollment_time */, const base::Time kStartTime = kLastAttemptTime + (kImmediateRetryDelay / 2);
base::nullopt /* persisted_device_sync_client_metadata */, clock()->SetNow(kStartTime);
base::nullopt /* persisted_last_device_sync_attempt_time */,
base::nullopt /* persisted_last_successful_device_sync_time */ CreateScheduler(
cryptauthv2::GetClientDirectiveForTest() /* persisted_client_directive */,
base::nullopt /* persisted_enrollment_client_metadata */,
kLastAttemptTime /* persisted_last_enrollment_attempt_time */,
kLastSuccessTime /* persisted_last_successful_enrollment_time */,
base::nullopt /* persisted_device_sync_client_metadata */,
kLastAttemptTime /* persisted_last_device_sync_attempt_time */,
kLastSuccessTime /* persisted_last_successful_device_sync_time */
); );
scheduler()->StartEnrollmentScheduling(fake_enrollment_delegate()); scheduler()->StartEnrollmentScheduling(fake_enrollment_delegate());
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment