AU: Implement exponential back off for 500 and 503 HTTP response codes.
Also refactors the automatic update checks into a separate
scheduler class and adds unit tests for them.
update_check_scheduler.cc 59 / 59: 100.0%
update_check_scheduler.h 1 / 1: 100.0%
Note: because the unit tests for this CL use the
UpdateAttempter class, the CL brings in several untested
modules into the test report reducing the overall test
coverage to ~82%.
BUG=2394
TEST=unit tests, gmerged on device and inspected logs
Change-Id: I078b1727b5338f6fc34e51f5e04a375518d63cef
Review URL: http://codereview.chromium.org/3215006
diff --git a/update_attempter.cc b/update_attempter.cc
index b0c470b..3614cad 100644
--- a/update_attempter.cc
+++ b/update_attempter.cc
@@ -15,8 +15,8 @@
#include <vector>
#include <glib.h>
+#include <metrics/metrics_library.h>
-#include "metrics/metrics_library.h"
#include "update_engine/dbus_service.h"
#include "update_engine/download_action.h"
#include "update_engine/filesystem_copier_action.h"
@@ -26,6 +26,7 @@
#include "update_engine/omaha_response_handler_action.h"
#include "update_engine/postinstall_runner_action.h"
#include "update_engine/set_bootable_flag_action.h"
+#include "update_engine/update_check_scheduler.h"
using base::TimeDelta;
using base::TimeTicks;
@@ -35,21 +36,6 @@
namespace chromeos_update_engine {
-namespace {
-
-const int kTimeoutOnce = 7 * 60; // at 7 minutes
-const int kTimeoutPeriodic = 45 * 60; // every 45 minutes
-const int kTimeoutFuzz = 10 * 60; // +/- 5 minutes
-
-gboolean CheckForUpdatePeriodically(void* arg) {
- UpdateAttempter* update_attempter = reinterpret_cast<UpdateAttempter*>(arg);
- update_attempter->Update("", "");
- update_attempter->SchedulePeriodicUpdateCheck(kTimeoutPeriodic);
- return FALSE; // Don't run again.
-}
-
-} // namespace {}
-
const char* kUpdateCompletedMarker = "/tmp/update_engine_autoupdate_completed";
const char* UpdateStatusToString(UpdateStatus status) {
@@ -104,6 +90,8 @@
: dbus_service_(NULL),
prefs_(prefs),
metrics_lib_(metrics_lib),
+ update_check_scheduler_(NULL),
+ http_response_code_(0),
priority_(utils::kProcessPriorityNormal),
manage_priority_source_(NULL),
download_active_(false),
@@ -131,6 +119,7 @@
// Update in progress. Do nothing
return;
}
+ http_response_code_ = 0;
if (!omaha_request_params_.Init(app_version, omaha_url)) {
LOG(ERROR) << "Unable to initialize Omaha request device params.";
return;
@@ -271,9 +260,10 @@
return;
}
- LOG(INFO) << "Update failed.";
- if (ScheduleErrorEventAction())
+ if (ScheduleErrorEventAction()) {
return;
+ }
+ LOG(INFO) << "No update.";
SetStatusAndNotify(UPDATE_STATUS_IDLE);
}
@@ -291,11 +281,23 @@
void UpdateAttempter::ActionCompleted(ActionProcessor* processor,
AbstractAction* action,
ActionExitCode code) {
- // Reset download progress regardless of whether or not the download action
- // succeeded.
+ // Reset download progress regardless of whether or not the download
+ // action succeeded. Also, get the response code from HTTP request
+ // actions (update download as well as the initial update check
+ // actions).
const string type = action->Type();
- if (type == DownloadAction::StaticType())
+ if (type == DownloadAction::StaticType()) {
download_progress_ = 0.0;
+ DownloadAction* download_action = dynamic_cast<DownloadAction*>(action);
+ http_response_code_ = download_action->GetHTTPResponseCode();
+ } else if (type == OmahaRequestAction::StaticType()) {
+ OmahaRequestAction* omaha_request_action =
+ dynamic_cast<OmahaRequestAction*>(action);
+ // If the request is not an event, then it's the update-check.
+ if (!omaha_request_action->IsEvent()) {
+ http_response_code_ = omaha_request_action->GetHTTPResponseCode();
+ }
+ }
if (code != kActionCodeSuccess) {
// On failure, schedule an error event to be sent to Omaha.
CreatePendingErrorEvent(action, code);
@@ -374,6 +376,9 @@
void UpdateAttempter::SetStatusAndNotify(UpdateStatus status) {
status_ = status;
+ if (update_check_scheduler_) {
+ update_check_scheduler_->SetUpdateStatus(status_);
+ }
if (!dbus_service_)
return;
last_notify_time_ = TimeTicks::Now();
@@ -414,6 +419,7 @@
if (error_event_.get() == NULL)
return false;
+ LOG(INFO) << "Update failed -- reporting the error event.";
shared_ptr<OmahaRequestAction> error_event_action(
new OmahaRequestAction(prefs_,
omaha_request_params_,
@@ -426,27 +432,6 @@
return true;
}
-void UpdateAttempter::InitiatePeriodicUpdateChecks() {
- if (!utils::IsOfficialBuild()) {
- LOG(WARNING) << "Non-official build: periodic update checks disabled.";
- return;
- }
- if (utils::IsRemovableDevice(utils::RootDevice(utils::BootDevice()))) {
- LOG(WARNING) << "Removable device boot: periodic update checks disabled.";
- return;
- }
- // Kick off periodic update checks. The first check is scheduled
- // |kTimeoutOnce| seconds from now. Subsequent checks are scheduled
- // at |kTimeoutPeriodic|-second intervals.
- SchedulePeriodicUpdateCheck(kTimeoutOnce);
-}
-
-void UpdateAttempter::SchedulePeriodicUpdateCheck(int seconds) {
- seconds = utils::FuzzInt(seconds, kTimeoutFuzz);
- g_timeout_add_seconds(seconds, CheckForUpdatePeriodically, this);
- LOG(INFO) << "Next update check in " << seconds << " seconds.";
-}
-
void UpdateAttempter::SetPriority(utils::ProcessPriority priority) {
if (priority_ == priority) {
return;