Merge from goog/master.
The following CLs are included in this merge:
dc873fa Fix test_http_server location.
f285857 Implement suspend, resume and cancel the download.
14dbd33 Mount the new system as 'postinstall_file' in postinstall.
390efed Parse postinstall parameters from the payload metadata.
14fd1ec Allow to Suspend/Resume the ActionProcessor.
f25eb49 Fix resuming canceled updates.
4eccae2 Fix unittest compile
63bdd87 Don't rebuild .img files on incremental builds.
c90be63 Fix Ext2FilesystemTest unittests on Brillo.
bffa060 Fix *ExtentWriterTest unittest.
279bbab Fix Subprocess unittests.
5fe0c4e Fix unittest build in x86_64.
80f70ff Build unittests in Brillo.
b3f699a Add .clang-format symlink to Brillo's clang-format.
0cd976d Disable ChromeBrowserProxyResolver behind a flag.
71102a2 Fix unittest build.
a96ddc1 Define libupdate_engine_client before using it.
2997173 Add a feature to get the last UpdateAttempt ErrorCode from update_engine
While unittests changes are not compiled in nyc-dev, this helps
cherry-pick of CLs that modify the code and the unittests in the
future without extra risk for nyc-dev.
Bug: 24277309
Bug: 25598547
Bug: 26955860
Bug: 27047026
Bug: 27121653
Bug: 27177071
TEST=`make dist` in nyc-dev
Change-Id: I023f35d4187650ce6cd1e9e3acbdda74ef8a36ea
diff --git a/.clang-format b/.clang-format
new file mode 120000
index 0000000..f412743
--- /dev/null
+++ b/.clang-format
@@ -0,0 +1 @@
+../../build/tools/brillo-clang-format
\ No newline at end of file
diff --git a/Android.mk b/Android.mk
index 0b30720..d529f70 100644
--- a/Android.mk
+++ b/Android.mk
@@ -23,6 +23,9 @@
local_use_dbus := $(if $(BRILLO_USE_DBUS),$(BRILLO_USE_DBUS),0)
local_use_hwid_override := \
$(if $(BRILLO_USE_HWID_OVERRIDE),$(BRILLO_USE_HWID_OVERRIDE),0)
+# "libcros" gates the LibCrosService exposed by the Chrome OS' chrome browser to
+# the system layer.
+local_use_libcros := $(if $(BRILLO_USE_LIBCROS),$(BRILLO_USE_LIBCROS),0)
local_use_mtd := $(if $(BRILLO_USE_MTD),$(BRILLO_USE_MTD),0)
local_use_power_management := \
$(if $(BRILLO_USE_POWER_MANAGEMENT),$(BRILLO_USE_POWER_MANAGEMENT),0)
@@ -32,6 +35,7 @@
-DUSE_BINDER=$(local_use_binder) \
-DUSE_DBUS=$(local_use_dbus) \
-DUSE_HWID_OVERRIDE=$(local_use_hwid_override) \
+ -DUSE_LIBCROS=$(local_use_libcros) \
-DUSE_MTD=$(local_use_mtd) \
-DUSE_POWER_MANAGEMENT=$(local_use_power_management) \
-DUSE_WEAVE=$(local_use_weave) \
@@ -299,7 +303,6 @@
$(ue_update_metadata_protos_exported_shared_libraries)
LOCAL_SRC_FILES := \
boot_control_android.cc \
- chrome_browser_proxy_resolver.cc \
common_service.cc \
connection_manager.cc \
daemon.cc \
@@ -346,6 +349,10 @@
LOCAL_SRC_FILES += \
weave_service.cc
endif # local_use_weave == 1
+ifeq ($(local_use_libcros),1)
+LOCAL_SRC_FILES += \
+ chrome_browser_proxy_resolver.cc
+endif # local_use_libcros == 1
include $(BUILD_STATIC_LIBRARY)
else # !defined(BRILLO)
@@ -448,6 +455,57 @@
LOCAL_INIT_RC := update_engine.rc
include $(BUILD_EXECUTABLE)
+# libupdate_engine_client (type: shared_library)
+# ========================================================
+include $(CLEAR_VARS)
+LOCAL_MODULE := libupdate_engine_client
+LOCAL_CFLAGS := \
+ -Wall \
+ -Werror \
+ -Wno-unused-parameter \
+ -DUSE_DBUS=$(local_use_dbus) \
+ -DUSE_BINDER=$(local_use_binder)
+LOCAL_CLANG := true
+LOCAL_CPP_EXTENSION := .cc
+# TODO(deymo): Remove "external/cros/system_api/dbus" when dbus is not used.
+LOCAL_C_INCLUDES := \
+ $(LOCAL_PATH)/client_library/include \
+ external/cros/system_api/dbus \
+ system \
+ external/gtest/include
+LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/client_library/include
+LOCAL_SHARED_LIBRARIES := \
+ libchrome \
+ libbrillo
+LOCAL_SRC_FILES := \
+ client_library/client.cc \
+ update_status_utils.cc
+
+# We can only compile support for one IPC mechanism. If both "binder" and "dbus"
+# are defined, we prefer binder.
+ifeq ($(local_use_binder),1)
+LOCAL_AIDL_INCLUDES := $(LOCAL_PATH)/binder_bindings
+LOCAL_SHARED_LIBRARIES += \
+ libbinder \
+ libbrillo-binder \
+ libutils
+LOCAL_SRC_FILES += \
+ binder_bindings/android/brillo/IUpdateEngine.aidl \
+ binder_bindings/android/brillo/IUpdateEngineStatusCallback.aidl \
+ client_library/client_binder.cc \
+ parcelable_update_engine_status.cc
+else # local_use_binder != 1
+LOCAL_STATIC_LIBRARIES := \
+ update_engine_client-dbus-proxies
+LOCAL_SHARED_LIBRARIES += \
+ libchrome-dbus \
+ libbrillo-dbus
+LOCAL_SRC_FILES += \
+ client_library/client_dbus.cc
+endif # local_use_binder == 1
+
+include $(BUILD_SHARED_LIBRARY)
+
# update_engine_client (type: executable)
# ========================================================
# update_engine console client.
@@ -465,7 +523,8 @@
LOCAL_SHARED_LIBRARIES += \
libupdate_engine_client
LOCAL_SRC_FILES := \
- update_engine_client.cc
+ update_engine_client.cc \
+ common/error_code_utils.cc
else # !defined(BRILLO)
#TODO(deymo): Remove external/cros/system_api/dbus once the strings are moved
# out of the DBus interface.
@@ -623,56 +682,171 @@
LOCAL_SRC_FILES := $(ue_delta_generator_src_files)
include $(BUILD_EXECUTABLE)
-# libupdate_engine_client
+# TODO(deymo): Enable the unittest binaries in non-Brillo builds once the DBus
+# dependencies are removed or placed behind the USE_DBUS flag.
+ifdef BRILLO
+
+# Sample images for unittests.
# ========================================================
+# Generate a prebuilt module that installs a sample image from the compressed
+# sample_images.tar.bz2 file used by the unittests.
+#
+# $(1): The filename in the sample_images.tar.bz2
+define ue-unittest-sample-image
+ $(eval include $(CLEAR_VARS)) \
+ $(eval LOCAL_MODULE := ue_unittest_$(1)) \
+ $(eval LOCAL_MODULE_CLASS := EXECUTABLES) \
+ $(eval $(ifeq $(BRILLO), 1, LOCAL_MODULE_TAGS := eng)) \
+ $(eval LOCAL_MODULE_PATH := \
+ $(TARGET_OUT_DATA_NATIVE_TESTS)/update_engine_unittests/gen) \
+ $(eval LOCAL_MODULE_STEM := $(1)) \
+ $(eval my_gen := $(call local-intermediates-dir)/gen/$(1)) \
+ $(eval $(my_gen) : PRIVATE_CUSTOM_TOOL = \
+ tar -jxf $$< -C $$(dir $$@) $$(notdir $$@) && touch $$@) \
+ $(eval $(my_gen) : $(LOCAL_PATH)/sample_images/sample_images.tar.bz2 ; \
+ $$(transform-generated-source)) \
+ $(eval LOCAL_PREBUILT_MODULE_FILE := $(my_gen)) \
+ $(eval include $(BUILD_PREBUILT))
+endef
+
+$(call ue-unittest-sample-image,disk_ext2_1k.img)
+$(call ue-unittest-sample-image,disk_ext2_4k.img)
+$(call ue-unittest-sample-image,disk_ext2_4k_empty.img)
+$(call ue-unittest-sample-image,disk_ext2_ue_settings.img)
+
+# test_http_server (type: executable)
+# ========================================================
+# Test HTTP Server.
include $(CLEAR_VARS)
-LOCAL_MODULE := libupdate_engine_client
-LOCAL_CFLAGS := \
- -Wall \
- -Werror \
- -Wno-unused-parameter \
- -DUSE_DBUS=$(local_use_dbus) \
- -DUSE_BINDER=$(local_use_binder)
-LOCAL_CLANG := true
+LOCAL_MODULE := test_http_server
+ifdef BRILLO
+ LOCAL_MODULE_TAGS := eng
+endif
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_NATIVE_TESTS)/update_engine_unittests
+LOCAL_MODULE_CLASS := EXECUTABLES
LOCAL_CPP_EXTENSION := .cc
-# TODO(deymo): Remove "external/cros/system_api/dbus" when dbus is not used.
-LOCAL_C_INCLUDES := \
- $(LOCAL_PATH)/client_library/include \
- external/cros/system_api/dbus \
- system \
- external/gtest/include
-LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/client_library/include
-LOCAL_SHARED_LIBRARIES := \
- libchrome \
- libbrillo
+LOCAL_CLANG := true
+LOCAL_CFLAGS := $(ue_common_cflags)
+LOCAL_CPPFLAGS := $(ue_common_cppflags)
+LOCAL_LDFLAGS := $(ue_common_ldflags)
+LOCAL_C_INCLUDES := $(ue_common_c_includes)
+LOCAL_SHARED_LIBRARIES := $(ue_common_shared_libraries)
LOCAL_SRC_FILES := \
- client_library/client.cc \
- update_status_utils.cc
+ common/http_common.cc \
+ test_http_server.cc
+include $(BUILD_EXECUTABLE)
-# We can only compile support for one IPC mechanism. If both "binder" and "dbus"
-# are defined, we prefer binder.
-ifeq ($(local_use_binder),1)
-LOCAL_AIDL_INCLUDES := $(LOCAL_PATH)/binder_bindings
-LOCAL_SHARED_LIBRARIES += \
- libbinder \
- libbrillo-binder \
- libutils
-LOCAL_SRC_FILES += \
- binder_bindings/android/brillo/IUpdateEngine.aidl \
- binder_bindings/android/brillo/IUpdateEngineStatusCallback.aidl \
- client_library/client_binder.cc \
- parcelable_update_engine_status.cc
-else # local_use_binder != 1
+# update_engine_unittests (type: executable)
+# ========================================================
+# Main unittest file.
+include $(CLEAR_VARS)
+LOCAL_MODULE := update_engine_unittests
+ifdef BRILLO
+ LOCAL_MODULE_TAGS := eng
+endif
+LOCAL_REQUIRED_MODULES := \
+ ue_unittest_disk_ext2_1k.img \
+ ue_unittest_disk_ext2_4k.img \
+ ue_unittest_disk_ext2_4k_empty.img \
+ ue_unittest_disk_ext2_ue_settings.img
+LOCAL_MODULE_CLASS := EXECUTABLES
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_CLANG := true
+LOCAL_CFLAGS := $(ue_common_cflags)
+LOCAL_CPPFLAGS := $(ue_common_cppflags)
+LOCAL_LDFLAGS := $(ue_common_ldflags)
+LOCAL_C_INCLUDES := \
+ $(ue_common_c_includes) \
+ $(ue_libupdate_engine_exported_c_includes)
LOCAL_STATIC_LIBRARIES := \
- update_engine_client-dbus-proxies
-LOCAL_SHARED_LIBRARIES += \
- libchrome-dbus \
- libbrillo-dbus
+ libupdate_engine \
+ libpayload_generator \
+ libbrillo-test-helpers \
+ libgmock \
+ libgtest \
+ libchrome_test_helpers \
+ $(ue_libupdate_engine_exported_static_libraries:-host=) \
+ $(ue_libpayload_generator_exported_static_libraries:-host=)
+LOCAL_SHARED_LIBRARIES := \
+ $(ue_common_shared_libraries) \
+ $(ue_libupdate_engine_exported_shared_libraries:-host=) \
+ $(ue_libpayload_generator_exported_shared_libraries:-host=)
+LOCAL_SRC_FILES := \
+ common/action_pipe_unittest.cc \
+ common/action_processor_unittest.cc \
+ common/action_unittest.cc \
+ common/certificate_checker_unittest.cc \
+ common/cpu_limiter_unittest.cc \
+ common/fake_prefs.cc \
+ common/hash_calculator_unittest.cc \
+ common/http_fetcher_unittest.cc \
+ common/hwid_override_unittest.cc \
+ common/mock_http_fetcher.cc \
+ common/prefs_unittest.cc \
+ common/subprocess_unittest.cc \
+ common/terminator_unittest.cc \
+ common/test_utils.cc \
+ common/utils_unittest.cc \
+ common_service_unittest.cc \
+ connection_manager_unittest.cc \
+ fake_shill_proxy.cc \
+ fake_system_state.cc \
+ metrics_utils_unittest.cc \
+ omaha_request_action_unittest.cc \
+ omaha_request_params_unittest.cc \
+ omaha_response_handler_action_unittest.cc \
+ p2p_manager_unittest.cc \
+ payload_consumer/bzip_extent_writer_unittest.cc \
+ payload_consumer/delta_performer_integration_test.cc \
+ payload_consumer/delta_performer_unittest.cc \
+ payload_consumer/download_action_unittest.cc \
+ payload_consumer/extent_writer_unittest.cc \
+ payload_consumer/file_writer_unittest.cc \
+ payload_consumer/filesystem_verifier_action_unittest.cc \
+ payload_consumer/postinstall_runner_action_unittest.cc \
+ payload_consumer/xz_extent_writer_unittest.cc \
+ payload_generator/ab_generator_unittest.cc \
+ payload_generator/blob_file_writer_unittest.cc \
+ payload_generator/block_mapping_unittest.cc \
+ payload_generator/cycle_breaker_unittest.cc \
+ payload_generator/delta_diff_utils_unittest.cc \
+ payload_generator/ext2_filesystem_unittest.cc \
+ payload_generator/extent_ranges_unittest.cc \
+ payload_generator/extent_utils_unittest.cc \
+ payload_generator/fake_filesystem.cc \
+ payload_generator/full_update_generator_unittest.cc \
+ payload_generator/graph_utils_unittest.cc \
+ payload_generator/inplace_generator_unittest.cc \
+ payload_generator/payload_file_unittest.cc \
+ payload_generator/payload_generation_config_unittest.cc \
+ payload_generator/payload_signer_unittest.cc \
+ payload_generator/tarjan_unittest.cc \
+ payload_generator/topological_sort_unittest.cc \
+ payload_generator/zip_unittest.cc \
+ payload_state_unittest.cc \
+ update_attempter_unittest.cc \
+ update_manager/boxed_value_unittest.cc \
+ update_manager/chromeos_policy_unittest.cc \
+ update_manager/evaluation_context_unittest.cc \
+ update_manager/generic_variables_unittest.cc \
+ update_manager/prng_unittest.cc \
+ update_manager/real_config_provider_unittest.cc \
+ update_manager/real_device_policy_provider_unittest.cc \
+ update_manager/real_random_provider_unittest.cc \
+ update_manager/real_shill_provider_unittest.cc \
+ update_manager/real_system_provider_unittest.cc \
+ update_manager/real_time_provider_unittest.cc \
+ update_manager/real_updater_provider_unittest.cc \
+ update_manager/umtest_utils.cc \
+ update_manager/update_manager_unittest.cc \
+ update_manager/variable_unittest.cc \
+ testrunner.cc
+ifeq ($(local_use_libcros),1)
LOCAL_SRC_FILES += \
- client_library/client_dbus.cc
-endif # local_use_binder == 1
-
-include $(BUILD_SHARED_LIBRARY)
+ chrome_browser_proxy_resolver_unittest.cc
+endif # local_use_libcros == 1
+include $(BUILD_NATIVE_TEST)
+endif # BRILLO
# Weave schema files
# ========================================================
diff --git a/UpdateEngine.conf b/UpdateEngine.conf
index 8a91607..9cf6042 100644
--- a/UpdateEngine.conf
+++ b/UpdateEngine.conf
@@ -54,6 +54,9 @@
<allow send_destination="org.chromium.UpdateEngine"
send_interface="org.chromium.UpdateEngineInterface"
send_member="GetPrevVersion"/>
+ <allow send_destination="org.chromium.UpdateEngine"
+ send_interface="org.chromium.UpdateEngineInterface"
+ send_member="GetLastAttemptError"/>
<allow send_interface="org.chromium.UpdateEngineLibcrosProxyResolvedInterface" />
</policy>
<policy user="power">
diff --git a/binder_bindings/android/brillo/IUpdateEngine.aidl b/binder_bindings/android/brillo/IUpdateEngine.aidl
index 9399ce3..1c0a3e5 100644
--- a/binder_bindings/android/brillo/IUpdateEngine.aidl
+++ b/binder_bindings/android/brillo/IUpdateEngine.aidl
@@ -36,4 +36,5 @@
String GetPrevVersion();
String GetRollbackPartition();
void RegisterStatusCallback(in IUpdateEngineStatusCallback callback);
+ int GetLastAttemptError();
}
diff --git a/binder_service_brillo.cc b/binder_service_brillo.cc
index 45ac343..6a6a16e 100644
--- a/binder_service_brillo.cc
+++ b/binder_service_brillo.cc
@@ -186,6 +186,12 @@
return Status::ok();
}
+Status BinderUpdateEngineBrilloService::GetLastAttemptError(
+ int* out_last_attempt_error) {
+ return CallCommonHandler(&UpdateEngineService::GetLastAttemptError,
+ out_last_attempt_error);
+}
+
void BinderUpdateEngineBrilloService::UnregisterStatusCallback(
IUpdateEngineStatusCallback* callback) {
auto it = callbacks_.begin();
diff --git a/binder_service_brillo.h b/binder_service_brillo.h
index 178305b..497b1b0 100644
--- a/binder_service_brillo.h
+++ b/binder_service_brillo.h
@@ -84,6 +84,8 @@
android::binder::Status RegisterStatusCallback(
const android::sp<android::brillo::IUpdateEngineStatusCallback>& callback)
override;
+ android::binder::Status GetLastAttemptError(
+ int* out_last_attempt_error) override;
private:
// Generic function for dispatching to the common service.
diff --git a/chrome_browser_proxy_resolver_unittest.cc b/chrome_browser_proxy_resolver_unittest.cc
index 7a4de3d..bb5193e 100644
--- a/chrome_browser_proxy_resolver_unittest.cc
+++ b/chrome_browser_proxy_resolver_unittest.cc
@@ -109,14 +109,14 @@
namespace {
void CheckResponseResolved(const deque<string>& proxies,
void* /* pirv_data */) {
- EXPECT_EQ(2, proxies.size());
+ EXPECT_EQ(2U, proxies.size());
EXPECT_EQ("socks5://192.168.52.83:5555", proxies[0]);
EXPECT_EQ(kNoProxy, proxies[1]);
MessageLoop::current()->BreakLoop();
}
void CheckResponseNoReply(const deque<string>& proxies, void* /* pirv_data */) {
- EXPECT_EQ(1, proxies.size());
+ EXPECT_EQ(1U, proxies.size());
EXPECT_EQ(kNoProxy, proxies[0]);
MessageLoop::current()->BreakLoop();
}
diff --git a/client_library/client_binder.cc b/client_library/client_binder.cc
index 6f9b7b6..321dfc4 100644
--- a/client_library/client_binder.cc
+++ b/client_library/client_binder.cc
@@ -215,5 +215,16 @@
return true;
}
+bool BinderUpdateEngineClient::GetLastAttemptError(
+ int32_t* last_attempt_error) const {
+ int out_as_int;
+
+ if (!service_->GetLastAttemptError(&out_as_int).isOk())
+ return false;
+
+ *last_attempt_error = out_as_int;
+ return true;
+}
+
} // namespace internal
} // namespace update_engine
diff --git a/client_library/client_binder.h b/client_library/client_binder.h
index 562cee4..72f80dd 100644
--- a/client_library/client_binder.h
+++ b/client_library/client_binder.h
@@ -80,6 +80,8 @@
bool RegisterStatusUpdateHandler(StatusUpdateHandler* handler) override;
bool UnregisterStatusUpdateHandler(StatusUpdateHandler* handler) override;
+ bool GetLastAttemptError(int32_t* last_attempt_error) const override;
+
private:
class StatusUpdateCallback :
public android::brillo::BnUpdateEngineStatusCallback {
diff --git a/client_library/client_dbus.cc b/client_library/client_dbus.cc
index 270a987..0d6b783 100644
--- a/client_library/client_dbus.cc
+++ b/client_library/client_dbus.cc
@@ -225,5 +225,10 @@
nullptr);
}
+bool DBusUpdateEngineClient::GetLastAttemptError(
+ int32_t* last_attempt_error) const {
+ return proxy_->GetLastAttemptError(last_attempt_error, nullptr);
+}
+
} // namespace internal
} // namespace update_engine
diff --git a/client_library/client_dbus.h b/client_library/client_dbus.h
index 507fb5c..02a7e84 100644
--- a/client_library/client_dbus.h
+++ b/client_library/client_dbus.h
@@ -73,6 +73,8 @@
bool RegisterStatusUpdateHandler(StatusUpdateHandler* handler) override;
bool UnregisterStatusUpdateHandler(StatusUpdateHandler* handler) override;
+ bool GetLastAttemptError(int32_t* last_attempt_error) const override;
+
private:
void DBusStatusHandlersRegistered(const std::string& interface,
const std::string& signal_name,
diff --git a/client_library/include/update_engine/client.h b/client_library/include/update_engine/client.h
index dc0fb8c..62ac5fb 100644
--- a/client_library/include/update_engine/client.h
+++ b/client_library/include/update_engine/client.h
@@ -112,6 +112,9 @@
// Unregister a status update handler
virtual bool UnregisterStatusUpdateHandler(StatusUpdateHandler* handler) = 0;
+ // Get the last UpdateAttempt error code.
+ virtual bool GetLastAttemptError(int32_t* last_attempt_error) const = 0;
+
protected:
// Use CreateInstance().
UpdateEngineClient() = default;
diff --git a/common/action.h b/common/action.h
index d8049ac..6c88216 100644
--- a/common/action.h
+++ b/common/action.h
@@ -124,6 +124,15 @@
// Only the ActionProcessor should call this.
virtual void TerminateProcessing() {}
+ // Called on asynchronous actions if the processing is suspended and resumed,
+ // respectively. These methods are called by the ActionProcessor and should
+ // not be explicitly called.
+ // The action may still call ActionCompleted() once the action is completed
+ // while the processing is suspended, for example if suspend/resume is not
+ // implemented for the given action.
+ virtual void SuspendAction() {}
+ virtual void ResumeAction() {}
+
// These methods are useful for debugging. TODO(adlr): consider using
// std::type_info for this?
// Type() returns a string of the Action type. I.e., for DownloadAction,
diff --git a/common/action_processor.cc b/common/action_processor.cc
index 7ccdfbd..3549e08 100644
--- a/common/action_processor.cc
+++ b/common/action_processor.cc
@@ -21,14 +21,12 @@
#include <base/logging.h>
#include "update_engine/common/action.h"
+#include "update_engine/common/error_code_utils.h"
using std::string;
namespace chromeos_update_engine {
-ActionProcessor::ActionProcessor()
- : current_action_(nullptr), delegate_(nullptr) {}
-
ActionProcessor::~ActionProcessor() {
if (IsRunning())
StopProcessing();
@@ -45,8 +43,7 @@
CHECK(!IsRunning());
if (!actions_.empty()) {
current_action_ = actions_.front();
- LOG(INFO) << "ActionProcessor::StartProcessing: "
- << current_action_->Type();
+ LOG(INFO) << "ActionProcessor: starting " << current_action_->Type();
actions_.pop_front();
current_action_->PerformAction();
}
@@ -54,17 +51,59 @@
void ActionProcessor::StopProcessing() {
CHECK(IsRunning());
- CHECK(current_action_);
- current_action_->TerminateProcessing();
- CHECK(current_action_);
- current_action_->SetProcessor(nullptr);
- LOG(INFO) << "ActionProcessor::StopProcessing: aborted "
- << current_action_->Type();
+ if (current_action_) {
+ current_action_->TerminateProcessing();
+ current_action_->SetProcessor(nullptr);
+ }
+ LOG(INFO) << "ActionProcessor: aborted "
+ << (current_action_ ? current_action_->Type() : "")
+ << (suspended_ ? " while suspended" : "");
current_action_ = nullptr;
+ suspended_ = false;
+ // Delete all the actions before calling the delegate.
+ for (auto action : actions_)
+ action->SetProcessor(nullptr);
+ actions_.clear();
if (delegate_)
delegate_->ProcessingStopped(this);
}
+void ActionProcessor::SuspendProcessing() {
+ // No current_action_ when not suspended means that the action processor was
+ // never started or already finished.
+ if (suspended_ || !current_action_) {
+ LOG(WARNING) << "Called SuspendProcessing while not processing.";
+ return;
+ }
+ suspended_ = true;
+
+ // If there's a current action we should notify it that it should suspend, but
+ // the action can ignore that and terminate at any point.
+ LOG(INFO) << "ActionProcessor: suspending " << current_action_->Type();
+ current_action_->SuspendAction();
+}
+
+void ActionProcessor::ResumeProcessing() {
+ if (!suspended_) {
+ LOG(WARNING) << "Called ResumeProcessing while not suspended.";
+ return;
+ }
+ suspended_ = false;
+ if (current_action_) {
+ // The current_action_ did not call ActionComplete while suspended, so we
+ // should notify it of the resume operation.
+ LOG(INFO) << "ActionProcessor: resuming " << current_action_->Type();
+ current_action_->ResumeAction();
+ } else {
+ // The last action called ActionComplete while suspended, so there is
+ // already a log message with the type of the finished action. We simply
+ // state that we are resuming processing and the next function will log the
+ // start of the next action or processing completion.
+ LOG(INFO) << "ActionProcessor: resuming processing";
+ StartNextActionOrFinish(suspended_error_code_);
+ }
+}
+
void ActionProcessor::ActionComplete(AbstractAction* actionptr,
ErrorCode code) {
CHECK_EQ(actionptr, current_action_);
@@ -74,17 +113,26 @@
current_action_->ActionCompleted(code);
current_action_->SetProcessor(nullptr);
current_action_ = nullptr;
- if (actions_.empty()) {
- LOG(INFO) << "ActionProcessor::ActionComplete: finished last action of"
- " type " << old_type;
- } else if (code != ErrorCode::kSuccess) {
- LOG(INFO) << "ActionProcessor::ActionComplete: " << old_type
- << " action failed. Aborting processing.";
+ LOG(INFO) << "ActionProcessor: finished "
+ << (actions_.empty() ? "last action " : "") << old_type
+ << (suspended_ ? " while suspended" : "")
+ << " with code " << utils::ErrorCodeToString(code);
+ if (!actions_.empty() && code != ErrorCode::kSuccess) {
+ LOG(INFO) << "ActionProcessor: Aborting processing due to failure.";
actions_.clear();
}
+ if (suspended_) {
+ // If an action finished while suspended we don't start the next action (or
+ // terminate the processing) until the processor is resumed. This condition
+ // will be flagged by a nullptr current_action_ while suspended_ is true.
+ suspended_error_code_ = code;
+ return;
+ }
+ StartNextActionOrFinish(code);
+}
+
+void ActionProcessor::StartNextActionOrFinish(ErrorCode code) {
if (actions_.empty()) {
- LOG(INFO) << "ActionProcessor::ActionComplete: finished last action of"
- " type " << old_type;
if (delegate_) {
delegate_->ProcessingDone(this, code);
}
@@ -92,8 +140,7 @@
}
current_action_ = actions_.front();
actions_.pop_front();
- LOG(INFO) << "ActionProcessor::ActionComplete: finished " << old_type
- << ", starting " << current_action_->Type();
+ LOG(INFO) << "ActionProcessor: starting " << current_action_->Type();
current_action_->PerformAction();
}
diff --git a/common/action_processor.h b/common/action_processor.h
index d61e12d..c9c179e 100644
--- a/common/action_processor.h
+++ b/common/action_processor.h
@@ -20,6 +20,7 @@
#include <deque>
#include <base/macros.h>
+#include <brillo/errors/error.h>
#include "update_engine/common/error_code.h"
@@ -40,7 +41,7 @@
class ActionProcessor {
public:
- ActionProcessor();
+ ActionProcessor() = default;
virtual ~ActionProcessor();
@@ -50,12 +51,25 @@
virtual void StartProcessing();
// Aborts processing. If an Action is running, it will have
- // TerminateProcessing() called on it. The Action that was running
- // will be lost and must be re-enqueued if this Processor is to use it.
+ // TerminateProcessing() called on it. The Action that was running and all the
+ // remaining actions will be lost and must be re-enqueued if this Processor is
+ // to use it.
void StopProcessing();
- // Returns true iff an Action is currently processing.
- bool IsRunning() const { return nullptr != current_action_; }
+ // Suspend the processing. If an Action is running, it will have the
+ // SuspendProcessing() called on it, and it should suspend operations until
+ // ResumeProcessing() is called on this class to continue. While suspended,
+ // no new actions will be started. Calling SuspendProcessing while the
+ // processing is suspended or not running this method performs no action.
+ void SuspendProcessing();
+
+ // Resume the suspended processing. If the ActionProcessor is not suspended
+ // or not running in the first place this method performs no action.
+ void ResumeProcessing();
+
+ // Returns true iff the processing was started but not yet completed nor
+ // stopped.
+ bool IsRunning() const { return current_action_ != nullptr || suspended_; }
// Adds another Action to the end of the queue.
virtual void EnqueueAction(AbstractAction* action);
@@ -75,15 +89,29 @@
void ActionComplete(AbstractAction* actionptr, ErrorCode code);
private:
+ // Continue processing actions (if any) after the last action terminated with
+ // the passed error code. If there are no more actions to process, the
+ // processing will terminate.
+ void StartNextActionOrFinish(ErrorCode code);
+
// Actions that have not yet begun processing, in the order in which
// they'll be processed.
std::deque<AbstractAction*> actions_;
// A pointer to the currently processing Action, if any.
- AbstractAction* current_action_;
+ AbstractAction* current_action_{nullptr};
+
+ // The ErrorCode reported by an action that was suspended but finished while
+ // being suspended. This error code is stored here to be reported back to the
+ // delegate once the processor is resumed.
+ ErrorCode suspended_error_code_{ErrorCode::kSuccess};
+
+ // Whether the action processor is or should be suspended.
+ bool suspended_{false};
// A pointer to the delegate, or null if none.
- ActionProcessorDelegate *delegate_;
+ ActionProcessorDelegate* delegate_{nullptr};
+
DISALLOW_COPY_AND_ASSIGN(ActionProcessor);
};
diff --git a/common/action_processor_unittest.cc b/common/action_processor_unittest.cc
index 8285470..631e42d 100644
--- a/common/action_processor_unittest.cc
+++ b/common/action_processor_unittest.cc
@@ -16,9 +16,12 @@
#include "update_engine/common/action_processor.h"
-#include <gtest/gtest.h>
#include <string>
+
+#include <gtest/gtest.h>
+
#include "update_engine/common/action.h"
+#include "update_engine/common/mock_action.h"
using std::string;
@@ -51,26 +54,6 @@
string Type() const { return "ActionProcessorTestAction"; }
};
-class ActionProcessorTest : public ::testing::Test { };
-
-// This test creates two simple Actions and sends a message via an ActionPipe
-// from one to the other.
-TEST(ActionProcessorTest, SimpleTest) {
- ActionProcessorTestAction action;
- ActionProcessor action_processor;
- EXPECT_FALSE(action_processor.IsRunning());
- action_processor.EnqueueAction(&action);
- EXPECT_FALSE(action_processor.IsRunning());
- EXPECT_FALSE(action.IsRunning());
- action_processor.StartProcessing();
- EXPECT_TRUE(action_processor.IsRunning());
- EXPECT_TRUE(action.IsRunning());
- EXPECT_EQ(action_processor.current_action(), &action);
- action.CompleteAction();
- EXPECT_FALSE(action_processor.IsRunning());
- EXPECT_FALSE(action.IsRunning());
-}
-
namespace {
class MyActionProcessorDelegate : public ActionProcessorDelegate {
public:
@@ -109,53 +92,79 @@
};
} // namespace
-TEST(ActionProcessorTest, DelegateTest) {
- ActionProcessorTestAction action;
- ActionProcessor action_processor;
- MyActionProcessorDelegate delegate(&action_processor);
- action_processor.set_delegate(&delegate);
+class ActionProcessorTest : public ::testing::Test {
+ void SetUp() override {
+ action_processor_.set_delegate(&delegate_);
+ // Silence Type() calls used for logging.
+ EXPECT_CALL(mock_action_, Type()).Times(testing::AnyNumber());
+ }
- action_processor.EnqueueAction(&action);
- action_processor.StartProcessing();
- action.CompleteAction();
- action_processor.set_delegate(nullptr);
- EXPECT_TRUE(delegate.processing_done_called_);
- EXPECT_TRUE(delegate.action_completed_called_);
+ void TearDown() override {
+ action_processor_.set_delegate(nullptr);
+ }
+
+ protected:
+ // The ActionProcessor under test.
+ ActionProcessor action_processor_;
+
+ MyActionProcessorDelegate delegate_{&action_processor_};
+
+ // Common actions used during most tests.
+ testing::StrictMock<MockAction> mock_action_;
+ ActionProcessorTestAction action_;
+};
+
+TEST_F(ActionProcessorTest, SimpleTest) {
+ EXPECT_FALSE(action_processor_.IsRunning());
+ action_processor_.EnqueueAction(&action_);
+ EXPECT_FALSE(action_processor_.IsRunning());
+ EXPECT_FALSE(action_.IsRunning());
+ action_processor_.StartProcessing();
+ EXPECT_TRUE(action_processor_.IsRunning());
+ EXPECT_TRUE(action_.IsRunning());
+ EXPECT_EQ(action_processor_.current_action(), &action_);
+ action_.CompleteAction();
+ EXPECT_FALSE(action_processor_.IsRunning());
+ EXPECT_FALSE(action_.IsRunning());
}
-TEST(ActionProcessorTest, StopProcessingTest) {
- ActionProcessorTestAction action;
- ActionProcessor action_processor;
- MyActionProcessorDelegate delegate(&action_processor);
- action_processor.set_delegate(&delegate);
-
- action_processor.EnqueueAction(&action);
- action_processor.StartProcessing();
- action_processor.StopProcessing();
- action_processor.set_delegate(nullptr);
- EXPECT_TRUE(delegate.processing_stopped_called_);
- EXPECT_FALSE(delegate.action_completed_called_);
- EXPECT_FALSE(action_processor.IsRunning());
- EXPECT_EQ(nullptr, action_processor.current_action());
+TEST_F(ActionProcessorTest, DelegateTest) {
+ action_processor_.EnqueueAction(&action_);
+ action_processor_.StartProcessing();
+ action_.CompleteAction();
+ EXPECT_TRUE(delegate_.processing_done_called_);
+ EXPECT_TRUE(delegate_.action_completed_called_);
}
-TEST(ActionProcessorTest, ChainActionsTest) {
+TEST_F(ActionProcessorTest, StopProcessingTest) {
+ action_processor_.EnqueueAction(&action_);
+ action_processor_.StartProcessing();
+ action_processor_.StopProcessing();
+ EXPECT_TRUE(delegate_.processing_stopped_called_);
+ EXPECT_FALSE(delegate_.action_completed_called_);
+ EXPECT_FALSE(action_processor_.IsRunning());
+ EXPECT_EQ(nullptr, action_processor_.current_action());
+}
+
+TEST_F(ActionProcessorTest, ChainActionsTest) {
+ // This test doesn't use a delegate since it terminates several actions.
+ action_processor_.set_delegate(nullptr);
+
ActionProcessorTestAction action1, action2;
- ActionProcessor action_processor;
- action_processor.EnqueueAction(&action1);
- action_processor.EnqueueAction(&action2);
- action_processor.StartProcessing();
- EXPECT_EQ(&action1, action_processor.current_action());
- EXPECT_TRUE(action_processor.IsRunning());
+ action_processor_.EnqueueAction(&action1);
+ action_processor_.EnqueueAction(&action2);
+ action_processor_.StartProcessing();
+ EXPECT_EQ(&action1, action_processor_.current_action());
+ EXPECT_TRUE(action_processor_.IsRunning());
action1.CompleteAction();
- EXPECT_EQ(&action2, action_processor.current_action());
- EXPECT_TRUE(action_processor.IsRunning());
+ EXPECT_EQ(&action2, action_processor_.current_action());
+ EXPECT_TRUE(action_processor_.IsRunning());
action2.CompleteAction();
- EXPECT_EQ(nullptr, action_processor.current_action());
- EXPECT_FALSE(action_processor.IsRunning());
+ EXPECT_EQ(nullptr, action_processor_.current_action());
+ EXPECT_FALSE(action_processor_.IsRunning());
}
-TEST(ActionProcessorTest, DtorTest) {
+TEST_F(ActionProcessorTest, DtorTest) {
ActionProcessorTestAction action1, action2;
{
ActionProcessor action_processor;
@@ -169,22 +178,87 @@
EXPECT_FALSE(action2.IsRunning());
}
-TEST(ActionProcessorTest, DefaultDelegateTest) {
+TEST_F(ActionProcessorTest, DefaultDelegateTest) {
// Just make sure it doesn't crash
- ActionProcessorTestAction action;
- ActionProcessor action_processor;
- ActionProcessorDelegate delegate;
- action_processor.set_delegate(&delegate);
+ action_processor_.EnqueueAction(&action_);
+ action_processor_.StartProcessing();
+ action_.CompleteAction();
- action_processor.EnqueueAction(&action);
- action_processor.StartProcessing();
- action.CompleteAction();
+ action_processor_.EnqueueAction(&action_);
+ action_processor_.StartProcessing();
+ action_processor_.StopProcessing();
+}
- action_processor.EnqueueAction(&action);
- action_processor.StartProcessing();
- action_processor.StopProcessing();
+// This test suspends and resume the action processor while running one action_.
+TEST_F(ActionProcessorTest, SuspendResumeTest) {
+ action_processor_.EnqueueAction(&mock_action_);
- action_processor.set_delegate(nullptr);
+ testing::InSequence s;
+ EXPECT_CALL(mock_action_, PerformAction());
+ action_processor_.StartProcessing();
+
+ EXPECT_CALL(mock_action_, SuspendAction());
+ action_processor_.SuspendProcessing();
+ // Suspending the processor twice should not suspend the action twice.
+ action_processor_.SuspendProcessing();
+
+ // IsRunning should return whether there's is an action doing some work, even
+ // if it is suspended.
+ EXPECT_TRUE(action_processor_.IsRunning());
+ EXPECT_EQ(&mock_action_, action_processor_.current_action());
+
+ EXPECT_CALL(mock_action_, ResumeAction());
+ action_processor_.ResumeProcessing();
+
+ // Calling ResumeProcessing twice should not affect the action_.
+ action_processor_.ResumeProcessing();
+
+ action_processor_.ActionComplete(&mock_action_, ErrorCode::kSuccess);
+}
+
+// This test suspends an action that presumably doesn't support suspend/resume
+// and it finished before being resumed.
+TEST_F(ActionProcessorTest, ActionCompletedWhileSuspendedTest) {
+ action_processor_.EnqueueAction(&mock_action_);
+
+ testing::InSequence s;
+ EXPECT_CALL(mock_action_, PerformAction());
+ action_processor_.StartProcessing();
+
+ EXPECT_CALL(mock_action_, SuspendAction());
+ action_processor_.SuspendProcessing();
+
+ // Simulate the action completion while suspended. No other call to
+ // |mock_action_| is expected at this point.
+ action_processor_.ActionComplete(&mock_action_, ErrorCode::kSuccess);
+
+ // The processing should not be done since the ActionProcessor is suspended
+ // and the processing is considered to be still running until resumed.
+ EXPECT_FALSE(delegate_.processing_done_called_);
+ EXPECT_TRUE(action_processor_.IsRunning());
+
+ action_processor_.ResumeProcessing();
+ EXPECT_TRUE(delegate_.processing_done_called_);
+ EXPECT_FALSE(delegate_.processing_stopped_called_);
+}
+
+TEST_F(ActionProcessorTest, StoppedWhileSuspendedTest) {
+ action_processor_.EnqueueAction(&mock_action_);
+
+ testing::InSequence s;
+ EXPECT_CALL(mock_action_, PerformAction());
+ action_processor_.StartProcessing();
+ EXPECT_CALL(mock_action_, SuspendAction());
+ action_processor_.SuspendProcessing();
+
+ EXPECT_CALL(mock_action_, TerminateProcessing());
+ action_processor_.StopProcessing();
+ // Stopping the processing should abort the current execution no matter what.
+ EXPECT_TRUE(delegate_.processing_stopped_called_);
+ EXPECT_FALSE(delegate_.processing_done_called_);
+ EXPECT_FALSE(delegate_.action_completed_called_);
+ EXPECT_FALSE(action_processor_.IsRunning());
+ EXPECT_EQ(nullptr, action_processor_.current_action());
}
} // namespace chromeos_update_engine
diff --git a/common/constants.cc b/common/constants.cc
index b15c3f4..fc6df37 100644
--- a/common/constants.cc
+++ b/common/constants.cc
@@ -29,6 +29,8 @@
const char kStatefulPartition[] = "/mnt/stateful_partition";
+const char kPostinstallDefaultScript[] = "postinst";
+
// Constants defining keys for the persisted state of update engine.
const char kPrefsAttemptInProgress[] = "attempt-in-progress";
const char kPrefsBackoffExpiryTime[] = "backoff-expiry-time";
@@ -45,6 +47,7 @@
const char kPrefsLastActivePingDay[] = "last-active-ping-day";
const char kPrefsLastRollCallPingDay[] = "last-roll-call-ping-day";
const char kPrefsManifestMetadataSize[] = "manifest-metadata-size";
+const char kPrefsManifestSignatureSize[] = "manifest-signature-size";
const char kPrefsMetricsAttemptLastReportingTime[] =
"metrics-attempt-last-reporting-time";
const char kPrefsMetricsCheckLastReportingTime[] =
diff --git a/common/constants.h b/common/constants.h
index 62f61ce..25d587b 100644
--- a/common/constants.h
+++ b/common/constants.h
@@ -32,6 +32,9 @@
// The location where we store the AU preferences (state etc).
extern const char kPrefsSubDirectory[];
+// Path to the post install command, relative to the partition.
+extern const char kPostinstallDefaultScript[];
+
// Path to the stateful partition on the root filesystem.
extern const char kStatefulPartition[];
@@ -50,6 +53,7 @@
extern const char kPrefsLastActivePingDay[];
extern const char kPrefsLastRollCallPingDay[];
extern const char kPrefsManifestMetadataSize[];
+extern const char kPrefsManifestSignatureSize[];
extern const char kPrefsMetricsAttemptLastReportingTime[];
extern const char kPrefsMetricsCheckLastReportingTime[];
extern const char kPrefsNumReboots[];
diff --git a/common/http_common.cc b/common/http_common.cc
index 7d98889..d07ced3 100644
--- a/common/http_common.cc
+++ b/common/http_common.cc
@@ -18,6 +18,8 @@
#include "update_engine/common/http_common.h"
+#include <cstdlib>
+
#include <base/macros.h>
namespace chromeos_update_engine {
diff --git a/common/http_common.h b/common/http_common.h
index 041cad5..6d444ed 100644
--- a/common/http_common.h
+++ b/common/http_common.h
@@ -20,8 +20,6 @@
#ifndef UPDATE_ENGINE_COMMON_HTTP_COMMON_H_
#define UPDATE_ENGINE_COMMON_HTTP_COMMON_H_
-#include <cstdlib>
-
namespace chromeos_update_engine {
// Enumeration type for HTTP response codes.
diff --git a/common/http_fetcher_unittest.cc b/common/http_fetcher_unittest.cc
index 17e360e..5450958 100644
--- a/common/http_fetcher_unittest.cc
+++ b/common/http_fetcher_unittest.cc
@@ -48,6 +48,7 @@
#include "update_engine/common/multi_range_http_fetcher.h"
#include "update_engine/common/test_utils.h"
#include "update_engine/common/utils.h"
+#include "update_engine/mock_proxy_resolver.h"
#include "update_engine/proxy_resolver.h"
using brillo::MessageLoop;
@@ -56,6 +57,10 @@
using std::string;
using std::unique_ptr;
using std::vector;
+using testing::DoAll;
+using testing::Return;
+using testing::SaveArg;
+using testing::_;
namespace {
@@ -193,14 +198,19 @@
AnyHttpFetcherTest() {}
virtual ~AnyHttpFetcherTest() {}
- virtual HttpFetcher* NewLargeFetcher(size_t num_proxies) = 0;
+ virtual HttpFetcher* NewLargeFetcher(ProxyResolver* proxy_resolver) = 0;
+ HttpFetcher* NewLargeFetcher(size_t num_proxies) {
+ proxy_resolver_.set_num_proxies(num_proxies);
+ return NewLargeFetcher(&proxy_resolver_);
+ }
HttpFetcher* NewLargeFetcher() {
return NewLargeFetcher(1);
}
- virtual HttpFetcher* NewSmallFetcher(size_t num_proxies) = 0;
+ virtual HttpFetcher* NewSmallFetcher(ProxyResolver* proxy_resolver) = 0;
HttpFetcher* NewSmallFetcher() {
- return NewSmallFetcher(1);
+ proxy_resolver_.set_num_proxies(1);
+ return NewSmallFetcher(&proxy_resolver_);
}
virtual string BigUrl(in_port_t port) const { return kUnusedUrl; }
@@ -227,25 +237,16 @@
public:
// Necessary to unhide the definition in the base class.
using AnyHttpFetcherTest::NewLargeFetcher;
- HttpFetcher* NewLargeFetcher(size_t num_proxies) override {
+ HttpFetcher* NewLargeFetcher(ProxyResolver* proxy_resolver) override {
brillo::Blob big_data(1000000);
- CHECK_GT(num_proxies, 0u);
- proxy_resolver_.set_num_proxies(num_proxies);
return new MockHttpFetcher(
- big_data.data(),
- big_data.size(),
- reinterpret_cast<ProxyResolver*>(&proxy_resolver_));
+ big_data.data(), big_data.size(), proxy_resolver);
}
// Necessary to unhide the definition in the base class.
using AnyHttpFetcherTest::NewSmallFetcher;
- HttpFetcher* NewSmallFetcher(size_t num_proxies) override {
- CHECK_GT(num_proxies, 0u);
- proxy_resolver_.set_num_proxies(num_proxies);
- return new MockHttpFetcher(
- "x",
- 1,
- reinterpret_cast<ProxyResolver*>(&proxy_resolver_));
+ HttpFetcher* NewSmallFetcher(ProxyResolver* proxy_resolver) override {
+ return new MockHttpFetcher("x", 1, proxy_resolver);
}
bool IsMock() const override { return true; }
@@ -260,12 +261,9 @@
public:
// Necessary to unhide the definition in the base class.
using AnyHttpFetcherTest::NewLargeFetcher;
- HttpFetcher* NewLargeFetcher(size_t num_proxies) override {
- CHECK_GT(num_proxies, 0u);
- proxy_resolver_.set_num_proxies(num_proxies);
- LibcurlHttpFetcher *ret = new
- LibcurlHttpFetcher(reinterpret_cast<ProxyResolver*>(&proxy_resolver_),
- &fake_hardware_);
+ HttpFetcher* NewLargeFetcher(ProxyResolver* proxy_resolver) override {
+ LibcurlHttpFetcher* ret =
+ new LibcurlHttpFetcher(proxy_resolver, &fake_hardware_);
// Speed up test execution.
ret->set_idle_seconds(1);
ret->set_retry_seconds(1);
@@ -275,8 +273,8 @@
// Necessary to unhide the definition in the base class.
using AnyHttpFetcherTest::NewSmallFetcher;
- HttpFetcher* NewSmallFetcher(size_t num_proxies) override {
- return NewLargeFetcher(num_proxies);
+ HttpFetcher* NewSmallFetcher(ProxyResolver* proxy_resolver) override {
+ return NewLargeFetcher(proxy_resolver);
}
string BigUrl(in_port_t port) const override {
@@ -307,14 +305,9 @@
public:
// Necessary to unhide the definition in the base class.
using AnyHttpFetcherTest::NewLargeFetcher;
- HttpFetcher* NewLargeFetcher(size_t num_proxies) override {
- CHECK_GT(num_proxies, 0u);
- proxy_resolver_.set_num_proxies(num_proxies);
- ProxyResolver* resolver =
- reinterpret_cast<ProxyResolver*>(&proxy_resolver_);
- MultiRangeHttpFetcher *ret =
- new MultiRangeHttpFetcher(
- new LibcurlHttpFetcher(resolver, &fake_hardware_));
+ HttpFetcher* NewLargeFetcher(ProxyResolver* proxy_resolver) override {
+ MultiRangeHttpFetcher* ret = new MultiRangeHttpFetcher(
+ new LibcurlHttpFetcher(proxy_resolver, &fake_hardware_));
ret->ClearRanges();
ret->AddRange(0);
// Speed up test execution.
@@ -326,8 +319,8 @@
// Necessary to unhide the definition in the base class.
using AnyHttpFetcherTest::NewSmallFetcher;
- HttpFetcher* NewSmallFetcher(size_t num_proxies) override {
- return NewLargeFetcher(num_proxies);
+ HttpFetcher* NewSmallFetcher(ProxyResolver* proxy_resolver) override {
+ return NewLargeFetcher(proxy_resolver);
}
bool IsMulti() const override { return true; }
@@ -517,26 +510,51 @@
} // namespace
TYPED_TEST(HttpFetcherTest, PauseTest) {
- {
- PausingHttpFetcherTestDelegate delegate;
- unique_ptr<HttpFetcher> fetcher(this->test_.NewLargeFetcher());
- delegate.paused_ = false;
- delegate.fetcher_ = fetcher.get();
- fetcher->set_delegate(&delegate);
+ PausingHttpFetcherTestDelegate delegate;
+ unique_ptr<HttpFetcher> fetcher(this->test_.NewLargeFetcher());
+ delegate.paused_ = false;
+ delegate.fetcher_ = fetcher.get();
+ fetcher->set_delegate(&delegate);
- unique_ptr<HttpServer> server(this->test_.CreateServer());
- ASSERT_TRUE(server->started_);
+ unique_ptr<HttpServer> server(this->test_.CreateServer());
+ ASSERT_TRUE(server->started_);
- MessageLoop::TaskId callback_id;
- callback_id = this->loop_.PostDelayedTask(
- FROM_HERE,
- base::Bind(&UnpausingTimeoutCallback, &delegate, &callback_id),
- base::TimeDelta::FromMilliseconds(200));
- fetcher->BeginTransfer(this->test_.BigUrl(server->GetPort()));
+ MessageLoop::TaskId callback_id;
+ callback_id = this->loop_.PostDelayedTask(
+ FROM_HERE,
+ base::Bind(&UnpausingTimeoutCallback, &delegate, &callback_id),
+ base::TimeDelta::FromMilliseconds(200));
+ fetcher->BeginTransfer(this->test_.BigUrl(server->GetPort()));
- this->loop_.Run();
- EXPECT_TRUE(this->loop_.CancelTask(callback_id));
- }
+ this->loop_.Run();
+ EXPECT_TRUE(this->loop_.CancelTask(callback_id));
+}
+
+// This test will pause the fetcher while the download is not yet started
+// because it is waiting for the proxy to be resolved.
+TYPED_TEST(HttpFetcherTest, PauseWhileResolvingProxyTest) {
+ if (this->test_.IsMock())
+ return;
+ MockProxyResolver mock_resolver;
+ unique_ptr<HttpFetcher> fetcher(this->test_.NewLargeFetcher(&mock_resolver));
+
+ // Saved arguments from the proxy call.
+ ProxiesResolvedFn proxy_callback = nullptr;
+ void* proxy_data = nullptr;
+
+ EXPECT_CALL(mock_resolver, GetProxiesForUrl("http://fake_url", _, _))
+ .WillOnce(DoAll(
+ SaveArg<1>(&proxy_callback), SaveArg<2>(&proxy_data), Return(true)));
+ fetcher->BeginTransfer("http://fake_url");
+ testing::Mock::VerifyAndClearExpectations(&mock_resolver);
+
+ // Pausing and unpausing while resolving the proxy should not affect anything.
+ fetcher->Pause();
+ fetcher->Unpause();
+ fetcher->Pause();
+ // Proxy resolver comes back after we paused the fetcher.
+ ASSERT_TRUE(proxy_callback);
+ (*proxy_callback)({1, kNoProxy}, proxy_data);
}
namespace {
@@ -650,7 +668,7 @@
this->loop_.Run();
// verify the data we get back
- ASSERT_EQ(kBigLength, delegate.data.size());
+ ASSERT_EQ(kBigLength, static_cast<int>(delegate.data.size()));
for (int i = 0; i < kBigLength; i += 10) {
// Assert so that we don't flood the screen w/ EXPECT errors on failure.
ASSERT_EQ(delegate.data.substr(i, 10), "abcdefghij");
@@ -831,7 +849,7 @@
MessageLoop::current()->Run();
if (expected_successful) {
// verify the data we get back
- ASSERT_EQ(kMediumLength, delegate.data.size());
+ ASSERT_EQ(static_cast<size_t>(kMediumLength), delegate.data.size());
for (int i = 0; i < kMediumLength; i += 10) {
// Assert so that we don't flood the screen w/ EXPECT errors on failure.
ASSERT_EQ(delegate.data.substr(i, 10), "abcdefghij");
@@ -923,13 +941,13 @@
const string& url,
const vector<pair<off_t, off_t>>& ranges,
const string& expected_prefix,
- off_t expected_size,
+ size_t expected_size,
HttpResponseCode expected_response_code) {
MultiHttpFetcherTestDelegate delegate(expected_response_code);
delegate.fetcher_.reset(fetcher_in);
MultiRangeHttpFetcher* multi_fetcher =
- dynamic_cast<MultiRangeHttpFetcher*>(fetcher_in);
+ static_cast<MultiRangeHttpFetcher*>(fetcher_in);
ASSERT_TRUE(multi_fetcher);
multi_fetcher->ClearRanges();
for (vector<pair<off_t, off_t>>::const_iterator it = ranges.begin(),
diff --git a/common/hwid_override_unittest.cc b/common/hwid_override_unittest.cc
index fff64bc..26ef30a 100644
--- a/common/hwid_override_unittest.cc
+++ b/common/hwid_override_unittest.cc
@@ -48,7 +48,7 @@
keyval += ("=" + expected_hwid);
ASSERT_EQ(base::WriteFile(tempdir_.path().Append("etc/lsb-release"),
keyval.c_str(), keyval.length()),
- keyval.length());
+ static_cast<int>(keyval.length()));
EXPECT_EQ(expected_hwid, HwidOverride::Read(tempdir_.path()));
}
@@ -56,7 +56,7 @@
std::string keyval("SOMETHING_ELSE=UNINTERESTING");
ASSERT_EQ(base::WriteFile(tempdir_.path().Append("etc/lsb-release"),
keyval.c_str(), keyval.length()),
- keyval.length());
+ static_cast<int>(keyval.length()));
EXPECT_EQ(std::string(), HwidOverride::Read(tempdir_.path()));
}
diff --git a/common/libcurl_http_fetcher.cc b/common/libcurl_http_fetcher.cc
index 761b74e..789f46e 100644
--- a/common/libcurl_http_fetcher.cc
+++ b/common/libcurl_http_fetcher.cc
@@ -99,6 +99,7 @@
curl_handle_ = curl_easy_init();
CHECK(curl_handle_);
+ ignore_failure_ = false;
CHECK(HasProxy());
bool is_direct = (GetCurrentProxy() == kNoProxy);
@@ -291,6 +292,12 @@
http_response_code_ = 0;
terminate_requested_ = false;
sent_byte_ = false;
+
+ // If we are paused, we delay these two operations until Unpause is called.
+ if (transfer_paused_) {
+ restart_transfer_on_unpause_ = true;
+ return;
+ }
ResumeTransfer(url_);
CurlPerformOnce();
}
@@ -325,96 +332,110 @@
return;
}
}
- if (0 == running_handles) {
- GetHttpResponseCode();
- if (http_response_code_) {
- LOG(INFO) << "HTTP response code: " << http_response_code_;
- no_network_retry_count_ = 0;
+
+ // If the transfer completes while paused, we should ignore the failure once
+ // the fetcher is unpaused.
+ if (running_handles == 0 && transfer_paused_ && !ignore_failure_) {
+ LOG(INFO) << "Connection closed while paused, ignoring failure.";
+ ignore_failure_ = true;
+ }
+
+ if (running_handles != 0 || transfer_paused_) {
+ // There's either more work to do or we are paused, so we just keep the
+ // file descriptors to watch up to date and exit, until we are done with the
+ // work and we are not paused.
+ SetupMessageLoopSources();
+ return;
+ }
+
+ // At this point, the transfer was completed in some way (error, connection
+ // closed or download finished).
+
+ GetHttpResponseCode();
+ if (http_response_code_) {
+ LOG(INFO) << "HTTP response code: " << http_response_code_;
+ no_network_retry_count_ = 0;
+ } else {
+ LOG(ERROR) << "Unable to get http response code.";
+ }
+
+ // we're done!
+ CleanUp();
+
+ // TODO(petkov): This temporary code tries to deal with the case where the
+ // update engine performs an update check while the network is not ready
+ // (e.g., right after resume). Longer term, we should check if the network
+ // is online/offline and return an appropriate error code.
+ if (!sent_byte_ &&
+ http_response_code_ == 0 &&
+ no_network_retry_count_ < no_network_max_retries_) {
+ no_network_retry_count_++;
+ MessageLoop::current()->PostDelayedTask(
+ FROM_HERE,
+ base::Bind(&LibcurlHttpFetcher::RetryTimeoutCallback,
+ base::Unretained(this)),
+ TimeDelta::FromSeconds(kNoNetworkRetrySeconds));
+ LOG(INFO) << "No HTTP response, retry " << no_network_retry_count_;
+ } else if ((!sent_byte_ && !IsHttpResponseSuccess()) ||
+ IsHttpResponseError()) {
+ // The transfer completed w/ error and we didn't get any bytes.
+ // If we have another proxy to try, try that.
+ //
+ // TODO(garnold) in fact there are two separate cases here: one case is an
+ // other-than-success return code (including no return code) and no
+ // received bytes, which is necessary due to the way callbacks are
+ // currently processing error conditions; the second is an explicit HTTP
+ // error code, where some data may have been received (as in the case of a
+ // semi-successful multi-chunk fetch). This is a confusing behavior and
+ // should be unified into a complete, coherent interface.
+ LOG(INFO) << "Transfer resulted in an error (" << http_response_code_
+ << "), " << bytes_downloaded_ << " bytes downloaded";
+
+ PopProxy(); // Delete the proxy we just gave up on.
+
+ if (HasProxy()) {
+ // We have another proxy. Retry immediately.
+ LOG(INFO) << "Retrying with next proxy setting";
+ MessageLoop::current()->PostTask(
+ FROM_HERE,
+ base::Bind(&LibcurlHttpFetcher::RetryTimeoutCallback,
+ base::Unretained(this)));
} else {
- LOG(ERROR) << "Unable to get http response code.";
+ // Out of proxies. Give up.
+ LOG(INFO) << "No further proxies, indicating transfer complete";
+ if (delegate_)
+ delegate_->TransferComplete(this, false); // signal fail
}
+ } else if ((transfer_size_ >= 0) && (bytes_downloaded_ < transfer_size_)) {
+ if (!ignore_failure_)
+ retry_count_++;
+ LOG(INFO) << "Transfer interrupted after downloading "
+ << bytes_downloaded_ << " of " << transfer_size_ << " bytes. "
+ << transfer_size_ - bytes_downloaded_ << " bytes remaining "
+ << "after " << retry_count_ << " attempt(s)";
- // we're done!
- CleanUp();
-
- // TODO(petkov): This temporary code tries to deal with the case where the
- // update engine performs an update check while the network is not ready
- // (e.g., right after resume). Longer term, we should check if the network
- // is online/offline and return an appropriate error code.
- if (!sent_byte_ &&
- http_response_code_ == 0 &&
- no_network_retry_count_ < no_network_max_retries_) {
- no_network_retry_count_++;
+ if (retry_count_ > max_retry_count_) {
+ LOG(INFO) << "Reached max attempts (" << retry_count_ << ")";
+ if (delegate_)
+ delegate_->TransferComplete(this, false); // signal fail
+ } else {
+ // Need to restart transfer
+ LOG(INFO) << "Restarting transfer to download the remaining bytes";
MessageLoop::current()->PostDelayedTask(
FROM_HERE,
base::Bind(&LibcurlHttpFetcher::RetryTimeoutCallback,
base::Unretained(this)),
- TimeDelta::FromSeconds(kNoNetworkRetrySeconds));
- LOG(INFO) << "No HTTP response, retry " << no_network_retry_count_;
- return;
- }
-
- if ((!sent_byte_ && !IsHttpResponseSuccess()) || IsHttpResponseError()) {
- // The transfer completed w/ error and we didn't get any bytes.
- // If we have another proxy to try, try that.
- //
- // TODO(garnold) in fact there are two separate cases here: one case is an
- // other-than-success return code (including no return code) and no
- // received bytes, which is necessary due to the way callbacks are
- // currently processing error conditions; the second is an explicit HTTP
- // error code, where some data may have been received (as in the case of a
- // semi-successful multi-chunk fetch). This is a confusing behavior and
- // should be unified into a complete, coherent interface.
- LOG(INFO) << "Transfer resulted in an error (" << http_response_code_
- << "), " << bytes_downloaded_ << " bytes downloaded";
-
- PopProxy(); // Delete the proxy we just gave up on.
-
- if (HasProxy()) {
- // We have another proxy. Retry immediately.
- LOG(INFO) << "Retrying with next proxy setting";
- MessageLoop::current()->PostTask(
- FROM_HERE,
- base::Bind(&LibcurlHttpFetcher::RetryTimeoutCallback,
- base::Unretained(this)));
- } else {
- // Out of proxies. Give up.
- LOG(INFO) << "No further proxies, indicating transfer complete";
- if (delegate_)
- delegate_->TransferComplete(this, false); // signal fail
- }
- } else if ((transfer_size_ >= 0) && (bytes_downloaded_ < transfer_size_)) {
- retry_count_++;
- LOG(INFO) << "Transfer interrupted after downloading "
- << bytes_downloaded_ << " of " << transfer_size_ << " bytes. "
- << transfer_size_ - bytes_downloaded_ << " bytes remaining "
- << "after " << retry_count_ << " attempt(s)";
-
- if (retry_count_ > max_retry_count_) {
- LOG(INFO) << "Reached max attempts (" << retry_count_ << ")";
- if (delegate_)
- delegate_->TransferComplete(this, false); // signal fail
- } else {
- // Need to restart transfer
- LOG(INFO) << "Restarting transfer to download the remaining bytes";
- MessageLoop::current()->PostDelayedTask(
- FROM_HERE,
- base::Bind(&LibcurlHttpFetcher::RetryTimeoutCallback,
- base::Unretained(this)),
- TimeDelta::FromSeconds(retry_seconds_));
- }
- } else {
- LOG(INFO) << "Transfer completed (" << http_response_code_
- << "), " << bytes_downloaded_ << " bytes downloaded";
- if (delegate_) {
- bool success = IsHttpResponseSuccess();
- delegate_->TransferComplete(this, success);
- }
+ TimeDelta::FromSeconds(retry_seconds_));
}
} else {
- // set up callback
- SetupMessageLoopSources();
+ LOG(INFO) << "Transfer completed (" << http_response_code_
+ << "), " << bytes_downloaded_ << " bytes downloaded";
+ if (delegate_) {
+ bool success = IsHttpResponseSuccess();
+ delegate_->TransferComplete(this, success);
+ }
}
+ ignore_failure_ = false;
}
size_t LibcurlHttpFetcher::LibcurlWrite(void *ptr, size_t size, size_t nmemb) {
@@ -449,15 +470,43 @@
}
void LibcurlHttpFetcher::Pause() {
+ if (transfer_paused_) {
+ LOG(ERROR) << "Fetcher already paused.";
+ return;
+ }
+ transfer_paused_ = true;
+ if (!transfer_in_progress_) {
+ // If pause before we started a connection, we don't need to notify curl
+ // about that, we will simply not start the connection later.
+ return;
+ }
CHECK(curl_handle_);
- CHECK(transfer_in_progress_);
CHECK_EQ(curl_easy_pause(curl_handle_, CURLPAUSE_ALL), CURLE_OK);
}
void LibcurlHttpFetcher::Unpause() {
+ if (!transfer_paused_) {
+ LOG(ERROR) << "Resume attempted when fetcher not paused.";
+ return;
+ }
+ transfer_paused_ = false;
+ if (restart_transfer_on_unpause_) {
+ restart_transfer_on_unpause_ = false;
+ ResumeTransfer(url_);
+ CurlPerformOnce();
+ return;
+ }
+ if (!transfer_in_progress_) {
+ // If resumed before starting the connection, there's no need to notify
+ // anybody. We will simply start the connection once it is time.
+ return;
+ }
CHECK(curl_handle_);
- CHECK(transfer_in_progress_);
CHECK_EQ(curl_easy_pause(curl_handle_, CURLPAUSE_CONT), CURLE_OK);
+ // Since the transfer is in progress, we need to dispatch a CurlPerformOnce()
+ // now to let the connection continue, otherwise it would be called by the
+ // TimeoutCallback but with a delay.
+ CurlPerformOnce();
}
// This method sets up callbacks with the MessageLoop.
@@ -537,7 +586,7 @@
// Set up a timeout callback for libcurl.
if (timeout_id_ == MessageLoop::kTaskIdNull) {
- LOG(INFO) << "Setting up timeout source: " << idle_seconds_ << " seconds.";
+ VLOG(1) << "Setting up timeout source: " << idle_seconds_ << " seconds.";
timeout_id_ = MessageLoop::current()->PostDelayedTask(
FROM_HERE,
base::Bind(&LibcurlHttpFetcher::TimeoutCallback,
@@ -547,6 +596,10 @@
}
void LibcurlHttpFetcher::RetryTimeoutCallback() {
+ if (transfer_paused_) {
+ restart_transfer_on_unpause_ = true;
+ return;
+ }
ResumeTransfer(url_);
CurlPerformOnce();
}
@@ -599,6 +652,8 @@
curl_multi_handle_ = nullptr;
}
transfer_in_progress_ = false;
+ transfer_paused_ = false;
+ restart_transfer_on_unpause_ = false;
}
void LibcurlHttpFetcher::GetHttpResponseCode() {
diff --git a/common/libcurl_http_fetcher.h b/common/libcurl_http_fetcher.h
index 66dbb18..218e6cb 100644
--- a/common/libcurl_http_fetcher.h
+++ b/common/libcurl_http_fetcher.h
@@ -132,9 +132,9 @@
// Calls into curl_multi_perform to let libcurl do its work. Returns after
// curl_multi_perform is finished, which may actually be after more than
// one call to curl_multi_perform. This method will set up the message
- // loop with sources for future work that libcurl will do.
+ // loop with sources for future work that libcurl will do, if any, or complete
+ // the transfer and finish the action if no work left to do.
// This method will not block.
- // Returns true if we should resume immediately after this call.
void CurlPerformOnce();
// Sets up message loop sources as needed by libcurl. This is generally
@@ -192,6 +192,16 @@
brillo::MessageLoop::TaskId timeout_id_{brillo::MessageLoop::kTaskIdNull};
bool transfer_in_progress_{false};
+ bool transfer_paused_{false};
+
+ // Whether it should ignore transfer failures for the purpose of retrying the
+ // connection.
+ bool ignore_failure_{false};
+
+ // Whether we should restart the transfer once Unpause() is called. This can
+ // be caused because either the connection dropped while pause or the proxy
+ // was resolved and we never started the transfer in the first place.
+ bool restart_transfer_on_unpause_{false};
// The transfer size. -1 if not known.
off_t transfer_size_{0};
diff --git a/mock_action.h b/common/mock_action.h
similarity index 74%
rename from mock_action.h
rename to common/mock_action.h
index 0ba796d..06acad1 100644
--- a/mock_action.h
+++ b/common/mock_action.h
@@ -14,8 +14,8 @@
// limitations under the License.
//
-#ifndef UPDATE_ENGINE_MOCK_ACTION_H_
-#define UPDATE_ENGINE_MOCK_ACTION_H_
+#ifndef UPDATE_ENGINE_COMMON_MOCK_ACTION_H_
+#define UPDATE_ENGINE_COMMON_MOCK_ACTION_H_
#include <string>
@@ -27,7 +27,7 @@
class MockAction;
-template<>
+template <>
class ActionTraits<MockAction> {
public:
typedef NoneType OutputObjectType;
@@ -36,10 +36,17 @@
class MockAction : public Action<MockAction> {
public:
+ MockAction() {
+ ON_CALL(*this, Type()).WillByDefault(testing::Return("MockAction"));
+ }
+
MOCK_METHOD0(PerformAction, void());
+ MOCK_METHOD0(TerminateProcessing, void());
+ MOCK_METHOD0(SuspendAction, void());
+ MOCK_METHOD0(ResumeAction, void());
MOCK_CONST_METHOD0(Type, std::string());
};
} // namespace chromeos_update_engine
-#endif // UPDATE_ENGINE_MOCK_ACTION_H_
+#endif // UPDATE_ENGINE_COMMON_MOCK_ACTION_H_
diff --git a/mock_action_processor.h b/common/mock_action_processor.h
similarity index 84%
rename from mock_action_processor.h
rename to common/mock_action_processor.h
index c98ff3c..04275c1 100644
--- a/mock_action_processor.h
+++ b/common/mock_action_processor.h
@@ -14,8 +14,8 @@
// limitations under the License.
//
-#ifndef UPDATE_ENGINE_MOCK_ACTION_PROCESSOR_H_
-#define UPDATE_ENGINE_MOCK_ACTION_PROCESSOR_H_
+#ifndef UPDATE_ENGINE_COMMON_MOCK_ACTION_PROCESSOR_H_
+#define UPDATE_ENGINE_COMMON_MOCK_ACTION_PROCESSOR_H_
#include <gmock/gmock.h>
@@ -31,4 +31,4 @@
} // namespace chromeos_update_engine
-#endif // UPDATE_ENGINE_MOCK_ACTION_PROCESSOR_H_
+#endif // UPDATE_ENGINE_COMMON_MOCK_ACTION_PROCESSOR_H_
diff --git a/common/platform_constants.h b/common/platform_constants.h
index d1786ff..6eaa940 100644
--- a/common/platform_constants.h
+++ b/common/platform_constants.h
@@ -50,6 +50,10 @@
// The stateful directory used by update_engine.
extern const char kNonVolatileDirectory[];
+// Options passed to the filesystem when mounting the new partition during
+// postinstall.
+extern const char kPostinstallMountOptions[];
+
} // namespace constants
} // namespace chromeos_update_engine
diff --git a/common/platform_constants_android.cc b/common/platform_constants_android.cc
index 4f55106..371fe26 100644
--- a/common/platform_constants_android.cc
+++ b/common/platform_constants_android.cc
@@ -31,6 +31,8 @@
// No deadline file API support on Android.
const char kOmahaResponseDeadlineFile[] = "";
const char kNonVolatileDirectory[] = "/data/misc/update_engine";
+const char kPostinstallMountOptions[] =
+ "context=u:object_r:postinstall_file:s0";
} // namespace constants
} // namespace chromeos_update_engine
diff --git a/common/platform_constants_chromeos.cc b/common/platform_constants_chromeos.cc
index d8587ca..7c1d627 100644
--- a/common/platform_constants_chromeos.cc
+++ b/common/platform_constants_chromeos.cc
@@ -32,6 +32,7 @@
"/tmp/update-check-response-deadline";
// This directory is wiped during powerwash.
const char kNonVolatileDirectory[] = "/var/lib/update_engine";
+const char kPostinstallMountOptions[] = nullptr;
} // namespace constants
} // namespace chromeos_update_engine
diff --git a/common/prefs_unittest.cc b/common/prefs_unittest.cc
index 967c411..d94623a 100644
--- a/common/prefs_unittest.cc
+++ b/common/prefs_unittest.cc
@@ -144,18 +144,18 @@
TEST_F(PrefsTest, GetInt64Max) {
ASSERT_TRUE(SetValue(kKey, base::StringPrintf(
- "%" PRIi64, std::numeric_limits<uint64_t>::max())));
+ "%" PRIi64, std::numeric_limits<int64_t>::max())));
int64_t value;
EXPECT_TRUE(prefs_.GetInt64(kKey, &value));
- EXPECT_EQ(std::numeric_limits<uint64_t>::max(), value);
+ EXPECT_EQ(std::numeric_limits<int64_t>::max(), value);
}
TEST_F(PrefsTest, GetInt64Min) {
ASSERT_TRUE(SetValue(kKey, base::StringPrintf(
- "%" PRIi64, std::numeric_limits<uint64_t>::min())));
+ "%" PRIi64, std::numeric_limits<int64_t>::min())));
int64_t value;
EXPECT_TRUE(prefs_.GetInt64(kKey, &value));
- EXPECT_EQ(std::numeric_limits<uint64_t>::min(), value);
+ EXPECT_EQ(std::numeric_limits<int64_t>::min(), value);
}
TEST_F(PrefsTest, GetInt64Negative) {
diff --git a/common/subprocess_unittest.cc b/common/subprocess_unittest.cc
index b37dc91..c6cbab0 100644
--- a/common/subprocess_unittest.cc
+++ b/common/subprocess_unittest.cc
@@ -17,11 +17,7 @@
#include "update_engine/common/subprocess.h"
#include <fcntl.h>
-#include <netinet/in.h>
-#include <netinet/ip.h>
#include <poll.h>
-#include <sys/socket.h>
-#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
@@ -30,6 +26,7 @@
#include <vector>
#include <base/bind.h>
+#include <base/files/scoped_temp_dir.h>
#include <base/location.h>
#include <base/message_loop/message_loop.h>
#include <base/strings/string_util.h>
@@ -50,6 +47,18 @@
using std::string;
using std::vector;
+namespace {
+
+#ifdef __ANDROID__
+#define kBinPath "/system/bin"
+#define kUsrBinPath "/system/bin"
+#else
+#define kBinPath "/bin"
+#define kUsrBinPath "/usr/bin"
+#endif // __ANDROID__
+
+} // namespace
+
namespace chromeos_update_engine {
class SubprocessTest : public ::testing::Test {
@@ -68,8 +77,6 @@
namespace {
-int local_server_port = 0;
-
void ExpectedResults(int expected_return_code, const string& expected_output,
int return_code, const string& output) {
EXPECT_EQ(expected_return_code, return_code);
@@ -102,28 +109,29 @@
}
TEST_F(SubprocessTest, SimpleTest) {
- EXPECT_TRUE(subprocess_.Exec({"/bin/false"},
+ EXPECT_TRUE(subprocess_.Exec({kBinPath "/false"},
base::Bind(&ExpectedResults, 1, "")));
loop_.Run();
}
TEST_F(SubprocessTest, EchoTest) {
EXPECT_TRUE(subprocess_.Exec(
- {"/bin/sh", "-c", "echo this is stdout; echo this is stderr >&2"},
+ {kBinPath "/sh", "-c", "echo this is stdout; echo this is stderr >&2"},
base::Bind(&ExpectedResults, 0, "this is stdout\nthis is stderr\n")));
loop_.Run();
}
TEST_F(SubprocessTest, StderrNotIncludedInOutputTest) {
EXPECT_TRUE(subprocess_.ExecFlags(
- {"/bin/sh", "-c", "echo on stdout; echo on stderr >&2"},
+ {kBinPath "/sh", "-c", "echo on stdout; echo on stderr >&2"},
0,
base::Bind(&ExpectedResults, 0, "on stdout\n")));
loop_.Run();
}
TEST_F(SubprocessTest, EnvVarsAreFiltered) {
- EXPECT_TRUE(subprocess_.Exec({"/usr/bin/env"}, base::Bind(&ExpectedEnvVars)));
+ EXPECT_TRUE(
+ subprocess_.Exec({kUsrBinPath "/env"}, base::Bind(&ExpectedEnvVars)));
loop_.Run();
}
@@ -136,9 +144,9 @@
TEST_F(SubprocessTest, SynchronousEchoTest) {
vector<string> cmd = {
- "/bin/sh",
- "-c",
- "echo -n stdout-here; echo -n stderr-there > /dev/stderr"};
+ kBinPath "/sh",
+ "-c",
+ "echo -n stdout-here; echo -n stderr-there >&2"};
int rc = -1;
string stdout;
ASSERT_TRUE(Subprocess::SynchronousExec(cmd, &rc, &stdout));
@@ -149,8 +157,7 @@
TEST_F(SubprocessTest, SynchronousEchoNoOutputTest) {
int rc = -1;
ASSERT_TRUE(Subprocess::SynchronousExec(
- {"/bin/sh", "-c", "echo test"},
- &rc, nullptr));
+ {kBinPath "/sh", "-c", "echo test"}, &rc, nullptr));
EXPECT_EQ(0, rc);
}
@@ -158,106 +165,55 @@
void CallbackBad(int return_code, const string& output) {
ADD_FAILURE() << "should never be called.";
}
-
-// TODO(garnold) this test method uses test_http_server as a representative for
-// interactive processes that can be spawned/terminated at will. This causes us
-// to go through hoops when spawning this process (e.g. obtaining the port
-// number it uses so we can control it with wget). It would have been much
-// preferred to use something else and thus simplify both test_http_server
-// (doesn't have to be able to communicate through a temp file) and the test
-// code below; for example, it sounds like a brain dead sleep loop with proper
-// signal handlers could be used instead.
-void StartAndCancelInRunLoop(bool* spawned) {
- // Create a temp file for test_http_server to communicate its port number.
- char temp_file_name[] = "/tmp/subprocess_unittest-test_http_server-XXXXXX";
- int temp_fd = mkstemp(temp_file_name);
- CHECK_GE(temp_fd, 0);
- int temp_flags = fcntl(temp_fd, F_GETFL, 0) | O_NONBLOCK;
- CHECK_EQ(fcntl(temp_fd, F_SETFL, temp_flags), 0);
-
- vector<string> cmd;
- cmd.push_back("./test_http_server");
- cmd.push_back(temp_file_name);
- uint32_t tag = Subprocess::Get().Exec(cmd, base::Bind(&CallbackBad));
- EXPECT_NE(0, tag);
- *spawned = true;
- printf("test http server spawned\n");
- // Wait for server to be up and running
- TimeDelta total_wait_time;
- const TimeDelta kSleepTime = TimeDelta::FromMilliseconds(100);
- const TimeDelta kMaxWaitTime = TimeDelta::FromSeconds(3);
- local_server_port = 0;
- static const char* kServerListeningMsgPrefix = "listening on port ";
- while (total_wait_time.InMicroseconds() < kMaxWaitTime.InMicroseconds()) {
- char line[80];
- int line_len = read(temp_fd, line, sizeof(line) - 1);
- if (line_len > 0) {
- line[line_len] = '\0';
- CHECK_EQ(strstr(line, kServerListeningMsgPrefix), line);
- const char* listening_port_str =
- line + strlen(kServerListeningMsgPrefix);
- char* end_ptr;
- long raw_port = strtol(listening_port_str, // NOLINT(runtime/int)
- &end_ptr, 10);
- CHECK(!*end_ptr || *end_ptr == '\n');
- local_server_port = static_cast<in_port_t>(raw_port);
- break;
- } else if (line_len < 0 && errno != EAGAIN) {
- LOG(INFO) << "error reading from " << temp_file_name << ": "
- << strerror(errno);
- break;
- }
- usleep(kSleepTime.InMicroseconds());
- total_wait_time += kSleepTime;
- }
- close(temp_fd);
- remove(temp_file_name);
- CHECK_GT(local_server_port, 0);
- LOG(INFO) << "server listening on port " << local_server_port;
- Subprocess::Get().KillExec(tag);
-}
-
-void ExitWhenDone(bool* spawned) {
- if (*spawned && !Subprocess::Get().SubprocessInFlight()) {
- // tear down the sub process
- printf("tear down time\n");
- int status = test_utils::System(
- base::StringPrintf("wget -O /dev/null http://127.0.0.1:%d/quitquitquit",
- local_server_port));
- EXPECT_NE(-1, status) << "system() failed";
- EXPECT_TRUE(WIFEXITED(status))
- << "command failed to run or died abnormally";
- MessageLoop::current()->BreakLoop();
- } else {
- // Re-run this callback again in 10 ms.
- MessageLoop::current()->PostDelayedTask(
- FROM_HERE,
- base::Bind(&ExitWhenDone, spawned),
- TimeDelta::FromMilliseconds(10));
- }
-}
-
} // namespace
+// Test that you can cancel a program that's already running.
TEST_F(SubprocessTest, CancelTest) {
- bool spawned = false;
- loop_.PostDelayedTask(
- FROM_HERE,
- base::Bind(&StartAndCancelInRunLoop, &spawned),
- TimeDelta::FromMilliseconds(100));
- loop_.PostDelayedTask(
- FROM_HERE,
- base::Bind(&ExitWhenDone, &spawned),
- TimeDelta::FromMilliseconds(10));
- loop_.Run();
+ base::ScopedTempDir tempdir;
+ ASSERT_TRUE(tempdir.CreateUniqueTempDir());
+ string fifo_path = tempdir.path().Append("fifo").value();
+ EXPECT_EQ(0, mkfifo(fifo_path.c_str(), 0666));
+
+ // Start a process, make sure it is running and try to cancel it. We write
+ // two bytes to the fifo, the first one marks that the program is running and
+ // the second one marks that the process waited for a timeout and was not
+ // killed. We should read the first byte but not the second one.
+ vector<string> cmd = {
+ kBinPath "/sh",
+ "-c",
+ base::StringPrintf(
+ "echo -n X >\"%s\"; sleep 60; echo -n Y >\"%s\"; exit 1",
+ fifo_path.c_str(),
+ fifo_path.c_str())};
+ uint32_t tag = Subprocess::Get().Exec(cmd, base::Bind(&CallbackBad));
+ EXPECT_NE(0U, tag);
+
+ int fifo_fd = HANDLE_EINTR(open(fifo_path.c_str(), O_RDONLY));
+ EXPECT_GE(fifo_fd, 0);
+
+ loop_.WatchFileDescriptor(FROM_HERE,
+ fifo_fd,
+ MessageLoop::WatchMode::kWatchRead,
+ false,
+ base::Bind([fifo_fd, tag] {
+ char c;
+ EXPECT_EQ(1, HANDLE_EINTR(read(fifo_fd, &c, 1)));
+ EXPECT_EQ('X', c);
+ LOG(INFO) << "Killing tag " << tag;
+ Subprocess::Get().KillExec(tag);
+ }));
+
// This test would leak a callback that runs when the child process exits
// unless we wait for it to run.
brillo::MessageLoopRunUntil(
&loop_,
- TimeDelta::FromSeconds(10),
- base::Bind([] {
- return Subprocess::Get().subprocess_records_.empty();
- }));
+ TimeDelta::FromSeconds(120),
+ base::Bind([] { return Subprocess::Get().subprocess_records_.empty(); }));
+ EXPECT_TRUE(Subprocess::Get().subprocess_records_.empty());
+ // Check that there isn't anything else to read from the pipe.
+ char c;
+ EXPECT_EQ(0, HANDLE_EINTR(read(fifo_fd, &c, 1)));
+ IGNORE_EINTR(close(fifo_fd));
}
} // namespace chromeos_update_engine
diff --git a/common/test_utils.cc b/common/test_utils.cc
index c09096b..77a9141 100644
--- a/common/test_utils.cc
+++ b/common/test_utils.cc
@@ -260,7 +260,7 @@
string loop_dev;
loop_binder_.reset(new ScopedLoopbackDeviceBinder(file_path, &loop_dev));
- EXPECT_TRUE(utils::MountFilesystem(loop_dev, *mnt_path, flags));
+ EXPECT_TRUE(utils::MountFilesystem(loop_dev, *mnt_path, flags, "", nullptr));
unmounter_.reset(new ScopedFilesystemUnmounter(*mnt_path));
}
diff --git a/common/test_utils.h b/common/test_utils.h
index b5151f2..7be027a 100644
--- a/common/test_utils.h
+++ b/common/test_utils.h
@@ -162,13 +162,15 @@
class ScopedTempFile {
public:
- ScopedTempFile() {
- EXPECT_TRUE(utils::MakeTempFile("update_engine_test_temp_file.XXXXXX",
- &path_,
- nullptr));
+ ScopedTempFile() : ScopedTempFile("update_engine_test_temp_file.XXXXXX") {}
+
+ explicit ScopedTempFile(const std::string& pattern) {
+ EXPECT_TRUE(utils::MakeTempFile(pattern, &path_, nullptr));
unlinker_.reset(new ScopedPathUnlinker(path_));
}
- const std::string& GetPath() { return path_; }
+
+ const std::string& path() { return path_; }
+
private:
std::string path_;
std::unique_ptr<ScopedPathUnlinker> unlinker_;
diff --git a/common/utils.cc b/common/utils.cc
index 91dcfc8..912bc96 100644
--- a/common/utils.cc
+++ b/common/utils.cc
@@ -613,19 +613,27 @@
bool MountFilesystem(const string& device,
const string& mountpoint,
- unsigned long mountflags) { // NOLINT(runtime/int)
- // TODO(sosa): Remove "ext3" once crbug.com/208022 is resolved.
- const vector<const char*> fstypes{"ext2", "ext3", "ext4", "squashfs"};
+ unsigned long mountflags, // NOLINT(runtime/int)
+ const string& type,
+ const string& fs_mount_options) {
+ vector<const char*> fstypes;
+ if (type.empty()) {
+ fstypes = {"ext2", "ext3", "ext4", "squashfs"};
+ } else {
+ fstypes = {type.c_str()};
+ }
for (const char* fstype : fstypes) {
int rc = mount(device.c_str(), mountpoint.c_str(), fstype, mountflags,
- nullptr);
+ fs_mount_options.c_str());
if (rc == 0)
return true;
PLOG(WARNING) << "Unable to mount destination device " << device
<< " on " << mountpoint << " as " << fstype;
}
- LOG(ERROR) << "Unable to mount " << device << " with any supported type";
+ if (!type.empty()) {
+ LOG(ERROR) << "Unable to mount " << device << " with any supported type";
+ }
return false;
}
diff --git a/common/utils.h b/common/utils.h
index 5bf1422..df06ef1 100644
--- a/common/utils.h
+++ b/common/utils.h
@@ -171,10 +171,14 @@
std::string MakePartitionNameForMount(const std::string& part_name);
// Synchronously mount or unmount a filesystem. Return true on success.
-// When mounting, it will attempt to mount the the device as "ext3", "ext2" and
-// "squashfs", with the passed |flags| options.
-bool MountFilesystem(const std::string& device, const std::string& mountpoint,
- unsigned long flags); // NOLINT(runtime/int)
+// When mounting, it will attempt to mount the device as the passed filesystem
+// type |type|, with the passed |flags| options. If |type| is empty, "ext2",
+// "ext3", "ext4" and "squashfs" will be tried.
+bool MountFilesystem(const std::string& device,
+ const std::string& mountpoint,
+ unsigned long flags, // NOLINT(runtime/int)
+ const std::string& type,
+ const std::string& fs_mount_options);
bool UnmountFilesystem(const std::string& mountpoint);
// Returns the block count and the block byte size of the file system on
diff --git a/common/utils_unittest.cc b/common/utils_unittest.cc
index fde89e8..f840a75 100644
--- a/common/utils_unittest.cc
+++ b/common/utils_unittest.cc
@@ -181,11 +181,11 @@
}
TEST(UtilsTest, FuzzIntTest) {
- static const unsigned int kRanges[] = { 0, 1, 2, 20 };
- for (unsigned int range : kRanges) {
+ static const uint32_t kRanges[] = { 0, 1, 2, 20 };
+ for (uint32_t range : kRanges) {
const int kValue = 50;
for (int tries = 0; tries < 100; ++tries) {
- int value = utils::FuzzInt(kValue, range);
+ uint32_t value = utils::FuzzInt(kValue, range);
EXPECT_GE(value, kValue - range / 2);
EXPECT_LE(value, kValue + range - range / 2);
}
@@ -280,10 +280,10 @@
void GetFileFormatTester(const string& expected,
const vector<uint8_t>& contents) {
test_utils::ScopedTempFile file;
- ASSERT_TRUE(utils::WriteFile(file.GetPath().c_str(),
+ ASSERT_TRUE(utils::WriteFile(file.path().c_str(),
reinterpret_cast<const char*>(contents.data()),
contents.size()));
- EXPECT_EQ(expected, utils::GetFileFormat(file.GetPath()));
+ EXPECT_EQ(expected, utils::GetFileFormat(file.path()));
}
} // namespace
@@ -413,7 +413,8 @@
string contents;
EXPECT_TRUE(utils::ReadFile(path.value(), &contents));
EXPECT_EQ(contents, expected_contents);
- EXPECT_EQ(utils::FileSize(path.value()), expected_contents.size());
+ EXPECT_EQ(static_cast<off_t>(expected_contents.size()),
+ utils::FileSize(path.value()));
}
TEST(UtilsTest, ConvertToOmahaInstallDate) {
@@ -493,7 +494,7 @@
EXPECT_TRUE(store.LoadFromString("PAYLOAD_MINOR_VERSION=123\n"));
EXPECT_TRUE(utils::GetMinorVersion(store, &minor_version));
- EXPECT_EQ(minor_version, 123);
+ EXPECT_EQ(123U, minor_version);
}
static bool BoolMacroTestHelper() {
diff --git a/common_service.cc b/common_service.cc
index 3c77c93..f0b818f 100644
--- a/common_service.cc
+++ b/common_service.cc
@@ -35,6 +35,7 @@
#include "update_engine/omaha_request_params.h"
#include "update_engine/p2p_manager.h"
#include "update_engine/update_attempter.h"
+#include "update_engine/payload_state_interface.h"
using base::StringPrintf;
using brillo::ErrorPtr;
@@ -318,4 +319,10 @@
return true;
}
+bool UpdateEngineService::GetLastAttemptError(ErrorPtr* /* error */,
+ int32_t* out_last_attempt_error) {
+ ErrorCode error_code = system_state_->payload_state()->GetAttemptErrorCode();
+ *out_last_attempt_error = static_cast<int>(error_code);
+ return true;
+}
} // namespace chromeos_update_engine
diff --git a/common_service.h b/common_service.h
index e08b4fd..4ad8862 100644
--- a/common_service.h
+++ b/common_service.h
@@ -127,6 +127,10 @@
bool GetRollbackPartition(brillo::ErrorPtr* error,
std::string* out_rollback_partition_name);
+ // Returns the last UpdateAttempt error.
+ bool GetLastAttemptError(brillo::ErrorPtr* error,
+ int32_t* out_last_attempt_error);
+
private:
SystemState* system_state_;
};
diff --git a/dbus_bindings/org.chromium.UpdateEngineInterface.dbus-xml b/dbus_bindings/org.chromium.UpdateEngineInterface.dbus-xml
index bc4ec36..02287de 100644
--- a/dbus_bindings/org.chromium.UpdateEngineInterface.dbus-xml
+++ b/dbus_bindings/org.chromium.UpdateEngineInterface.dbus-xml
@@ -80,5 +80,8 @@
<method name="GetRollbackPartition">
<arg type="s" name="rollback_partition_name" direction="out" />
</method>
+ <method name="GetLastAttemptError">
+ <arg type="i" name="last_attempt_error" direction="out" />
+ </method>
</interface>
</node>
diff --git a/dbus_service.cc b/dbus_service.cc
index 0ab0ac0..392555f 100644
--- a/dbus_service.cc
+++ b/dbus_service.cc
@@ -132,6 +132,11 @@
return common_->GetRollbackPartition(error, out_rollback_partition_name);
}
+bool DBusUpdateEngineService::GetLastAttemptError(
+ ErrorPtr* error, int32_t* out_last_attempt_error){
+ return common_->GetLastAttemptError(error, out_last_attempt_error);
+}
+
UpdateEngineAdaptor::UpdateEngineAdaptor(SystemState* system_state,
const scoped_refptr<dbus::Bus>& bus)
: org::chromium::UpdateEngineInterfaceAdaptor(&dbus_service_),
diff --git a/dbus_service.h b/dbus_service.h
index b0c68e5..1486e3c 100644
--- a/dbus_service.h
+++ b/dbus_service.h
@@ -129,6 +129,10 @@
bool GetRollbackPartition(brillo::ErrorPtr* error,
std::string* out_rollback_partition_name) override;
+ // Returns the last UpdateAttempt error. If not updated yet, default success
+ // ErrorCode will be returned.
+ bool GetLastAttemptError(brillo::ErrorPtr* error,
+ int32_t* out_last_attempt_error) override;
private:
std::unique_ptr<UpdateEngineService> common_;
};
diff --git a/include/debugd/dbus-constants.h b/include/debugd/dbus-constants.h
deleted file mode 100644
index 3427a99..0000000
--- a/include/debugd/dbus-constants.h
+++ /dev/null
@@ -1,56 +0,0 @@
-// Copyright 2015 The Chromium OS Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef SYSTEM_API_DBUS_DEBUGD_DBUS_CONSTANTS_H_
-#define SYSTEM_API_DBUS_DEBUGD_DBUS_CONSTANTS_H_
-
-namespace debugd {
-const char kDebugdInterface[] = "org.chromium.debugd";
-const char kDebugdServicePath[] = "/org/chromium/debugd";
-const char kDebugdServiceName[] = "org.chromium.debugd";
-
-// Methods.
-const char kDumpDebugLogs[] = "DumpDebugLogs";
-const char kGetDebugLogs[] = "GetDebugLogs";
-const char kGetInterfaces[] = "GetInterfaces";
-const char kGetModemStatus[] = "GetModemStatus";
-const char kGetNetworkStatus[] = "GetNetworkStatus";
-const char kGetPerfOutput[] = "GetPerfOutput";
-const char kGetRandomPerfOutput[] = "GetRandomPerfOutput";
-const char kGetRichPerfData[] = "GetRichPerfData";
-const char kGetRoutes[] = "GetRoutes";
-const char kGetWiMaxStatus[] = "GetWiMaxStatus";
-const char kSetDebugMode[] = "SetDebugMode";
-const char kSystraceStart[] = "SystraceStart";
-const char kSystraceStop[] = "SystraceStop";
-const char kSystraceStatus[] = "SystraceStatus";
-const char kGetLog[] = "GetLog";
-const char kGetAllLogs[] = "GetAllLogs";
-const char kGetUserLogFiles[] = "GetUserLogFiles";
-const char kGetFeedbackLogs[] = "GetFeedbackLogs";
-const char kTestICMP[] = "TestICMP";
-const char kTestICMPWithOptions[] = "TestICMPWithOptions";
-const char kLogKernelTaskStates[] = "LogKernelTaskStates";
-const char kUploadCrashes[] = "UploadCrashes";
-const char kRemoveRootfsVerification[] = "RemoveRootfsVerification";
-const char kEnableChromeRemoteDebugging[] = "EnableChromeRemoteDebugging";
-const char kEnableBootFromUsb[] = "EnableBootFromUsb";
-const char kConfigureSshServer[] = "ConfigureSshServer";
-const char kSetUserPassword[] = "SetUserPassword";
-const char kEnableChromeDevFeatures[] = "EnableChromeDevFeatures";
-const char kQueryDevFeatures[] = "QueryDevFeatures";
-
-// Values.
-enum DevFeatureFlag {
- DEV_FEATURES_DISABLED = 1 << 0,
- DEV_FEATURE_ROOTFS_VERIFICATION_REMOVED = 1 << 1,
- DEV_FEATURE_BOOT_FROM_USB_ENABLED = 1 << 2,
- DEV_FEATURE_SSH_SERVER_CONFIGURED = 1 << 3,
- DEV_FEATURE_DEV_MODE_ROOT_PASSWORD_SET = 1 << 4,
- DEV_FEATURE_SYSTEM_ROOT_PASSWORD_SET = 1 << 5,
- DEV_FEATURE_CHROME_REMOTE_DEBUGGING_ENABLED = 1 << 6,
-};
-} // namespace debugd
-
-#endif // SYSTEM_API_DBUS_DEBUGD_DBUS_CONSTANTS_H_
diff --git a/include/libcros/dbus-proxy-mocks.h b/include/libcros/dbus-proxy-mocks.h
new file mode 100644
index 0000000..97f614f
--- /dev/null
+++ b/include/libcros/dbus-proxy-mocks.h
@@ -0,0 +1,69 @@
+// Automatic generation of D-Bus interface mock proxies for:
+// - org.chromium.LibCrosServiceInterface
+// - org.chromium.UpdateEngineLibcrosProxyResolvedInterface
+#ifndef ____CHROMEOS_DBUS_BINDING___UPDATE_ENGINE_INCLUDE_LIBCROS_DBUS_PROXY_MOCKS_H
+#define ____CHROMEOS_DBUS_BINDING___UPDATE_ENGINE_INCLUDE_LIBCROS_DBUS_PROXY_MOCKS_H
+#include <string>
+#include <vector>
+
+#include <base/callback_forward.h>
+#include <base/logging.h>
+#include <base/macros.h>
+#include <brillo/any.h>
+#include <brillo/errors/error.h>
+#include <brillo/variant_dictionary.h>
+#include <gmock/gmock.h>
+
+#include "libcros/dbus-proxies.h"
+
+namespace org {
+namespace chromium {
+
+// Mock object for LibCrosServiceInterfaceProxyInterface.
+class LibCrosServiceInterfaceProxyMock : public LibCrosServiceInterfaceProxyInterface {
+ public:
+ LibCrosServiceInterfaceProxyMock() = default;
+
+ MOCK_METHOD5(ResolveNetworkProxy,
+ bool(const std::string& /*in_source_url*/,
+ const std::string& /*in_signal_interface*/,
+ const std::string& /*in_signal_name*/,
+ brillo::ErrorPtr* /*error*/,
+ int /*timeout_ms*/));
+ MOCK_METHOD6(ResolveNetworkProxyAsync,
+ void(const std::string& /*in_source_url*/,
+ const std::string& /*in_signal_interface*/,
+ const std::string& /*in_signal_name*/,
+ const base::Callback<void()>& /*success_callback*/,
+ const base::Callback<void(brillo::Error*)>& /*error_callback*/,
+ int /*timeout_ms*/));
+ MOCK_CONST_METHOD0(GetObjectPath, const dbus::ObjectPath&());
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(LibCrosServiceInterfaceProxyMock);
+};
+} // namespace chromium
+} // namespace org
+
+namespace org {
+namespace chromium {
+
+// Mock object for UpdateEngineLibcrosProxyResolvedInterfaceProxyInterface.
+class UpdateEngineLibcrosProxyResolvedInterfaceProxyMock : public UpdateEngineLibcrosProxyResolvedInterfaceProxyInterface {
+ public:
+ UpdateEngineLibcrosProxyResolvedInterfaceProxyMock() = default;
+
+ MOCK_METHOD2(RegisterProxyResolvedSignalHandler,
+ void(const base::Callback<void(const std::string&,
+ const std::string&,
+ const std::string&)>& /*signal_callback*/,
+ dbus::ObjectProxy::OnConnectedCallback /*on_connected_callback*/));
+ MOCK_CONST_METHOD0(GetObjectPath, const dbus::ObjectPath&());
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(UpdateEngineLibcrosProxyResolvedInterfaceProxyMock);
+};
+} // namespace chromium
+} // namespace org
+
+#endif // ____CHROMEOS_DBUS_BINDING___UPDATE_ENGINE_INCLUDE_LIBCROS_DBUS_PROXY_MOCKS_H
diff --git a/include/power_manager/dbus-constants.h b/include/power_manager/dbus-constants.h
deleted file mode 100644
index fa42cb1..0000000
--- a/include/power_manager/dbus-constants.h
+++ /dev/null
@@ -1,66 +0,0 @@
-// Copyright 2015 The Chromium OS Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef SYSTEM_API_DBUS_POWER_MANAGER_DBUS_CONSTANTS_H_
-#define SYSTEM_API_DBUS_POWER_MANAGER_DBUS_CONSTANTS_H_
-
-namespace power_manager {
-// powerd
-const char kPowerManagerInterface[] = "org.chromium.PowerManager";
-const char kPowerManagerServicePath[] = "/org/chromium/PowerManager";
-const char kPowerManagerServiceName[] = "org.chromium.PowerManager";
-// Methods exposed by powerd.
-const char kDecreaseScreenBrightnessMethod[] = "DecreaseScreenBrightness";
-const char kIncreaseScreenBrightnessMethod[] = "IncreaseScreenBrightness";
-const char kGetScreenBrightnessPercentMethod[] = "GetScreenBrightnessPercent";
-const char kSetScreenBrightnessPercentMethod[] = "SetScreenBrightnessPercent";
-const char kDecreaseKeyboardBrightnessMethod[] = "DecreaseKeyboardBrightness";
-const char kIncreaseKeyboardBrightnessMethod[] = "IncreaseKeyboardBrightness";
-const char kRequestRestartMethod[] = "RequestRestart";
-const char kRequestShutdownMethod[] = "RequestShutdown";
-const char kRequestSuspendMethod[] = "RequestSuspend";
-const char kGetPowerSupplyPropertiesMethod[] = "GetPowerSupplyProperties";
-const char kHandleUserActivityMethod[] = "HandleUserActivity";
-const char kHandleVideoActivityMethod[] = "HandleVideoActivity";
-const char kSetIsProjectingMethod[] = "SetIsProjecting";
-const char kSetPolicyMethod[] = "SetPolicy";
-const char kSetPowerSourceMethod[] = "SetPowerSource";
-const char kRegisterSuspendDelayMethod[] = "RegisterSuspendDelay";
-const char kUnregisterSuspendDelayMethod[] = "UnregisterSuspendDelay";
-const char kHandleSuspendReadinessMethod[] = "HandleSuspendReadiness";
-const char kRegisterDarkSuspendDelayMethod[] = "RegisterDarkSuspendDelay";
-const char kUnregisterDarkSuspendDelayMethod[] = "UnregisterDarkSuspendDelay";
-const char kHandleDarkSuspendReadinessMethod[] = "HandleDarkSuspendReadiness";
-const char kHandlePowerButtonAcknowledgmentMethod[] =
- "HandlePowerButtonAcknowledgment";
-const char kRecordDarkResumeWakeReasonMethod[] = "RecordDarkResumeWakeReason";
-// Signals emitted by powerd.
-const char kBrightnessChangedSignal[] = "BrightnessChanged";
-const char kKeyboardBrightnessChangedSignal[] = "KeyboardBrightnessChanged";
-const char kPeripheralBatteryStatusSignal[] = "PeripheralBatteryStatus";
-const char kPowerSupplyPollSignal[] = "PowerSupplyPoll";
-const char kSuspendImminentSignal[] = "SuspendImminent";
-const char kDarkSuspendImminentSignal[] = "DarkSuspendImminent";
-const char kSuspendDoneSignal[] = "SuspendDone";
-const char kInputEventSignal[] = "InputEvent";
-const char kIdleActionImminentSignal[] = "IdleActionImminent";
-const char kIdleActionDeferredSignal[] = "IdleActionDeferred";
-// Values
-const int kBrightnessTransitionGradual = 1;
-const int kBrightnessTransitionInstant = 2;
-enum UserActivityType {
- USER_ACTIVITY_OTHER = 0,
- USER_ACTIVITY_BRIGHTNESS_UP_KEY_PRESS = 1,
- USER_ACTIVITY_BRIGHTNESS_DOWN_KEY_PRESS = 2,
- USER_ACTIVITY_VOLUME_UP_KEY_PRESS = 3,
- USER_ACTIVITY_VOLUME_DOWN_KEY_PRESS = 4,
- USER_ACTIVITY_VOLUME_MUTE_KEY_PRESS = 5,
-};
-enum RequestRestartReason {
- REQUEST_RESTART_FOR_USER = 0,
- REQUEST_RESTART_FOR_UPDATE = 1,
-};
-} // namespace power_manager
-
-#endif // SYSTEM_API_DBUS_POWER_MANAGER_DBUS_CONSTANTS_H_
diff --git a/include/shill/dbus-proxy-mocks.h b/include/shill/dbus-proxy-mocks.h
new file mode 100644
index 0000000..e5d52f7
--- /dev/null
+++ b/include/shill/dbus-proxy-mocks.h
@@ -0,0 +1,549 @@
+// Automatic generation of D-Bus interface mock proxies for:
+// - org.chromium.flimflam.Manager
+// - org.chromium.flimflam.Service
+#ifndef ____CHROMEOS_DBUS_BINDING___UPDATE_ENGINE_INCLUDE_SHILL_DBUS_PROXY_MOCKS_H
+#define ____CHROMEOS_DBUS_BINDING___UPDATE_ENGINE_INCLUDE_SHILL_DBUS_PROXY_MOCKS_H
+#include <string>
+#include <vector>
+
+#include <base/callback_forward.h>
+#include <base/logging.h>
+#include <base/macros.h>
+#include <brillo/any.h>
+#include <brillo/errors/error.h>
+#include <brillo/variant_dictionary.h>
+#include <gmock/gmock.h>
+
+#include "shill/dbus-proxies.h"
+
+namespace org {
+namespace chromium {
+namespace flimflam {
+
+// Mock object for ManagerProxyInterface.
+class ManagerProxyMock : public ManagerProxyInterface {
+ public:
+ ManagerProxyMock() = default;
+
+ MOCK_METHOD3(GetProperties,
+ bool(brillo::VariantDictionary*,
+ brillo::ErrorPtr* /*error*/,
+ int /*timeout_ms*/));
+ MOCK_METHOD3(GetPropertiesAsync,
+ void(const base::Callback<void(const brillo::VariantDictionary&)>& /*success_callback*/,
+ const base::Callback<void(brillo::Error*)>& /*error_callback*/,
+ int /*timeout_ms*/));
+ MOCK_METHOD4(SetProperty,
+ bool(const std::string&,
+ const brillo::Any&,
+ brillo::ErrorPtr* /*error*/,
+ int /*timeout_ms*/));
+ MOCK_METHOD5(SetPropertyAsync,
+ void(const std::string&,
+ const brillo::Any&,
+ const base::Callback<void()>& /*success_callback*/,
+ const base::Callback<void(brillo::Error*)>& /*error_callback*/,
+ int /*timeout_ms*/));
+ MOCK_METHOD3(GetState,
+ bool(std::string*,
+ brillo::ErrorPtr* /*error*/,
+ int /*timeout_ms*/));
+ MOCK_METHOD3(GetStateAsync,
+ void(const base::Callback<void(const std::string&)>& /*success_callback*/,
+ const base::Callback<void(brillo::Error*)>& /*error_callback*/,
+ int /*timeout_ms*/));
+ MOCK_METHOD4(CreateProfile,
+ bool(const std::string&,
+ dbus::ObjectPath*,
+ brillo::ErrorPtr* /*error*/,
+ int /*timeout_ms*/));
+ MOCK_METHOD4(CreateProfileAsync,
+ void(const std::string&,
+ const base::Callback<void(const dbus::ObjectPath&)>& /*success_callback*/,
+ const base::Callback<void(brillo::Error*)>& /*error_callback*/,
+ int /*timeout_ms*/));
+ MOCK_METHOD3(RemoveProfile,
+ bool(const std::string&,
+ brillo::ErrorPtr* /*error*/,
+ int /*timeout_ms*/));
+ MOCK_METHOD4(RemoveProfileAsync,
+ void(const std::string&,
+ const base::Callback<void()>& /*success_callback*/,
+ const base::Callback<void(brillo::Error*)>& /*error_callback*/,
+ int /*timeout_ms*/));
+ MOCK_METHOD4(PushProfile,
+ bool(const std::string&,
+ dbus::ObjectPath*,
+ brillo::ErrorPtr* /*error*/,
+ int /*timeout_ms*/));
+ MOCK_METHOD4(PushProfileAsync,
+ void(const std::string&,
+ const base::Callback<void(const dbus::ObjectPath&)>& /*success_callback*/,
+ const base::Callback<void(brillo::Error*)>& /*error_callback*/,
+ int /*timeout_ms*/));
+ MOCK_METHOD5(InsertUserProfile,
+ bool(const std::string&,
+ const std::string&,
+ dbus::ObjectPath*,
+ brillo::ErrorPtr* /*error*/,
+ int /*timeout_ms*/));
+ MOCK_METHOD5(InsertUserProfileAsync,
+ void(const std::string&,
+ const std::string&,
+ const base::Callback<void(const dbus::ObjectPath&)>& /*success_callback*/,
+ const base::Callback<void(brillo::Error*)>& /*error_callback*/,
+ int /*timeout_ms*/));
+ MOCK_METHOD3(PopProfile,
+ bool(const std::string&,
+ brillo::ErrorPtr* /*error*/,
+ int /*timeout_ms*/));
+ MOCK_METHOD4(PopProfileAsync,
+ void(const std::string&,
+ const base::Callback<void()>& /*success_callback*/,
+ const base::Callback<void(brillo::Error*)>& /*error_callback*/,
+ int /*timeout_ms*/));
+ MOCK_METHOD2(PopAnyProfile,
+ bool(brillo::ErrorPtr* /*error*/,
+ int /*timeout_ms*/));
+ MOCK_METHOD3(PopAnyProfileAsync,
+ void(const base::Callback<void()>& /*success_callback*/,
+ const base::Callback<void(brillo::Error*)>& /*error_callback*/,
+ int /*timeout_ms*/));
+ MOCK_METHOD2(PopAllUserProfiles,
+ bool(brillo::ErrorPtr* /*error*/,
+ int /*timeout_ms*/));
+ MOCK_METHOD3(PopAllUserProfilesAsync,
+ void(const base::Callback<void()>& /*success_callback*/,
+ const base::Callback<void(brillo::Error*)>& /*error_callback*/,
+ int /*timeout_ms*/));
+ MOCK_METHOD2(RecheckPortal,
+ bool(brillo::ErrorPtr* /*error*/,
+ int /*timeout_ms*/));
+ MOCK_METHOD3(RecheckPortalAsync,
+ void(const base::Callback<void()>& /*success_callback*/,
+ const base::Callback<void(brillo::Error*)>& /*error_callback*/,
+ int /*timeout_ms*/));
+ MOCK_METHOD3(RequestScan,
+ bool(const std::string&,
+ brillo::ErrorPtr* /*error*/,
+ int /*timeout_ms*/));
+ MOCK_METHOD4(RequestScanAsync,
+ void(const std::string&,
+ const base::Callback<void()>& /*success_callback*/,
+ const base::Callback<void(brillo::Error*)>& /*error_callback*/,
+ int /*timeout_ms*/));
+ MOCK_METHOD3(EnableTechnology,
+ bool(const std::string&,
+ brillo::ErrorPtr* /*error*/,
+ int /*timeout_ms*/));
+ MOCK_METHOD4(EnableTechnologyAsync,
+ void(const std::string&,
+ const base::Callback<void()>& /*success_callback*/,
+ const base::Callback<void(brillo::Error*)>& /*error_callback*/,
+ int /*timeout_ms*/));
+ MOCK_METHOD3(DisableTechnology,
+ bool(const std::string&,
+ brillo::ErrorPtr* /*error*/,
+ int /*timeout_ms*/));
+ MOCK_METHOD4(DisableTechnologyAsync,
+ void(const std::string&,
+ const base::Callback<void()>& /*success_callback*/,
+ const base::Callback<void(brillo::Error*)>& /*error_callback*/,
+ int /*timeout_ms*/));
+ MOCK_METHOD4(GetService,
+ bool(const brillo::VariantDictionary&,
+ dbus::ObjectPath*,
+ brillo::ErrorPtr* /*error*/,
+ int /*timeout_ms*/));
+ MOCK_METHOD4(GetServiceAsync,
+ void(const brillo::VariantDictionary&,
+ const base::Callback<void(const dbus::ObjectPath&)>& /*success_callback*/,
+ const base::Callback<void(brillo::Error*)>& /*error_callback*/,
+ int /*timeout_ms*/));
+ MOCK_METHOD4(GetWifiService,
+ bool(const brillo::VariantDictionary&,
+ dbus::ObjectPath*,
+ brillo::ErrorPtr* /*error*/,
+ int /*timeout_ms*/));
+ MOCK_METHOD4(GetWifiServiceAsync,
+ void(const brillo::VariantDictionary&,
+ const base::Callback<void(const dbus::ObjectPath&)>& /*success_callback*/,
+ const base::Callback<void(brillo::Error*)>& /*error_callback*/,
+ int /*timeout_ms*/));
+ MOCK_METHOD4(ConfigureService,
+ bool(const brillo::VariantDictionary&,
+ dbus::ObjectPath*,
+ brillo::ErrorPtr* /*error*/,
+ int /*timeout_ms*/));
+ MOCK_METHOD4(ConfigureServiceAsync,
+ void(const brillo::VariantDictionary&,
+ const base::Callback<void(const dbus::ObjectPath&)>& /*success_callback*/,
+ const base::Callback<void(brillo::Error*)>& /*error_callback*/,
+ int /*timeout_ms*/));
+ MOCK_METHOD5(ConfigureServiceForProfile,
+ bool(const dbus::ObjectPath&,
+ const brillo::VariantDictionary&,
+ dbus::ObjectPath*,
+ brillo::ErrorPtr* /*error*/,
+ int /*timeout_ms*/));
+ MOCK_METHOD5(ConfigureServiceForProfileAsync,
+ void(const dbus::ObjectPath&,
+ const brillo::VariantDictionary&,
+ const base::Callback<void(const dbus::ObjectPath&)>& /*success_callback*/,
+ const base::Callback<void(brillo::Error*)>& /*error_callback*/,
+ int /*timeout_ms*/));
+ MOCK_METHOD4(FindMatchingService,
+ bool(const brillo::VariantDictionary&,
+ dbus::ObjectPath*,
+ brillo::ErrorPtr* /*error*/,
+ int /*timeout_ms*/));
+ MOCK_METHOD4(FindMatchingServiceAsync,
+ void(const brillo::VariantDictionary&,
+ const base::Callback<void(const dbus::ObjectPath&)>& /*success_callback*/,
+ const base::Callback<void(brillo::Error*)>& /*error_callback*/,
+ int /*timeout_ms*/));
+ MOCK_METHOD4(GetVPNService,
+ bool(const brillo::VariantDictionary&,
+ dbus::ObjectPath*,
+ brillo::ErrorPtr* /*error*/,
+ int /*timeout_ms*/));
+ MOCK_METHOD4(GetVPNServiceAsync,
+ void(const brillo::VariantDictionary&,
+ const base::Callback<void(const dbus::ObjectPath&)>& /*success_callback*/,
+ const base::Callback<void(brillo::Error*)>& /*error_callback*/,
+ int /*timeout_ms*/));
+ MOCK_METHOD3(GetDebugLevel,
+ bool(int32_t*,
+ brillo::ErrorPtr* /*error*/,
+ int /*timeout_ms*/));
+ MOCK_METHOD3(GetDebugLevelAsync,
+ void(const base::Callback<void(int32_t)>& /*success_callback*/,
+ const base::Callback<void(brillo::Error*)>& /*error_callback*/,
+ int /*timeout_ms*/));
+ MOCK_METHOD3(SetDebugLevel,
+ bool(int32_t,
+ brillo::ErrorPtr* /*error*/,
+ int /*timeout_ms*/));
+ MOCK_METHOD4(SetDebugLevelAsync,
+ void(int32_t,
+ const base::Callback<void()>& /*success_callback*/,
+ const base::Callback<void(brillo::Error*)>& /*error_callback*/,
+ int /*timeout_ms*/));
+ MOCK_METHOD3(GetServiceOrder,
+ bool(std::string*,
+ brillo::ErrorPtr* /*error*/,
+ int /*timeout_ms*/));
+ MOCK_METHOD3(GetServiceOrderAsync,
+ void(const base::Callback<void(const std::string&)>& /*success_callback*/,
+ const base::Callback<void(brillo::Error*)>& /*error_callback*/,
+ int /*timeout_ms*/));
+ MOCK_METHOD3(SetServiceOrder,
+ bool(const std::string&,
+ brillo::ErrorPtr* /*error*/,
+ int /*timeout_ms*/));
+ MOCK_METHOD4(SetServiceOrderAsync,
+ void(const std::string&,
+ const base::Callback<void()>& /*success_callback*/,
+ const base::Callback<void(brillo::Error*)>& /*error_callback*/,
+ int /*timeout_ms*/));
+ MOCK_METHOD3(GetDebugTags,
+ bool(std::string*,
+ brillo::ErrorPtr* /*error*/,
+ int /*timeout_ms*/));
+ MOCK_METHOD3(GetDebugTagsAsync,
+ void(const base::Callback<void(const std::string&)>& /*success_callback*/,
+ const base::Callback<void(brillo::Error*)>& /*error_callback*/,
+ int /*timeout_ms*/));
+ MOCK_METHOD3(SetDebugTags,
+ bool(const std::string&,
+ brillo::ErrorPtr* /*error*/,
+ int /*timeout_ms*/));
+ MOCK_METHOD4(SetDebugTagsAsync,
+ void(const std::string&,
+ const base::Callback<void()>& /*success_callback*/,
+ const base::Callback<void(brillo::Error*)>& /*error_callback*/,
+ int /*timeout_ms*/));
+ MOCK_METHOD3(ListDebugTags,
+ bool(std::string*,
+ brillo::ErrorPtr* /*error*/,
+ int /*timeout_ms*/));
+ MOCK_METHOD3(ListDebugTagsAsync,
+ void(const base::Callback<void(const std::string&)>& /*success_callback*/,
+ const base::Callback<void(brillo::Error*)>& /*error_callback*/,
+ int /*timeout_ms*/));
+ MOCK_METHOD3(GetNetworksForGeolocation,
+ bool(brillo::VariantDictionary*,
+ brillo::ErrorPtr* /*error*/,
+ int /*timeout_ms*/));
+ MOCK_METHOD3(GetNetworksForGeolocationAsync,
+ void(const base::Callback<void(const brillo::VariantDictionary&)>& /*success_callback*/,
+ const base::Callback<void(brillo::Error*)>& /*error_callback*/,
+ int /*timeout_ms*/));
+ MOCK_METHOD10(VerifyDestination,
+ bool(const std::string& /*in_certificate*/,
+ const std::string& /*in_public_key*/,
+ const std::string& /*in_nonce*/,
+ const std::string& /*in_signed_data*/,
+ const std::string& /*in_destination_udn*/,
+ const std::string& /*in_hotspot_ssid*/,
+ const std::string& /*in_hotspot_bssid*/,
+ bool*,
+ brillo::ErrorPtr* /*error*/,
+ int /*timeout_ms*/));
+ MOCK_METHOD10(VerifyDestinationAsync,
+ void(const std::string& /*in_certificate*/,
+ const std::string& /*in_public_key*/,
+ const std::string& /*in_nonce*/,
+ const std::string& /*in_signed_data*/,
+ const std::string& /*in_destination_udn*/,
+ const std::string& /*in_hotspot_ssid*/,
+ const std::string& /*in_hotspot_bssid*/,
+ const base::Callback<void(bool)>& /*success_callback*/,
+ const base::Callback<void(brillo::Error*)>& /*error_callback*/,
+ int /*timeout_ms*/));
+ bool VerifyAndEncryptCredentials(const std::string& /*in_certificate*/,
+ const std::string& /*in_public_key*/,
+ const std::string& /*in_nonce*/,
+ const std::string& /*in_signed_data*/,
+ const std::string& /*in_destination_udn*/,
+ const std::string& /*in_hotspot_ssid*/,
+ const std::string& /*in_hotspot_bssid*/,
+ const dbus::ObjectPath& /*in_network*/,
+ std::string*,
+ brillo::ErrorPtr* /*error*/,
+ int /*timeout_ms*/) override {
+ LOG(WARNING) << "VerifyAndEncryptCredentials(): gmock can't handle methods with 11 arguments. You can override this method in a subclass if you need to.";
+ return false;
+ }
+ void VerifyAndEncryptCredentialsAsync(const std::string& /*in_certificate*/,
+ const std::string& /*in_public_key*/,
+ const std::string& /*in_nonce*/,
+ const std::string& /*in_signed_data*/,
+ const std::string& /*in_destination_udn*/,
+ const std::string& /*in_hotspot_ssid*/,
+ const std::string& /*in_hotspot_bssid*/,
+ const dbus::ObjectPath& /*in_network*/,
+ const base::Callback<void(const std::string&)>& /*success_callback*/,
+ const base::Callback<void(brillo::Error*)>& /*error_callback*/,
+ int /*timeout_ms*/) override {
+ LOG(WARNING) << "VerifyAndEncryptCredentialsAsync(): gmock can't handle methods with 11 arguments. You can override this method in a subclass if you need to.";
+ }
+ bool VerifyAndEncryptData(const std::string& /*in_certificate*/,
+ const std::string& /*in_public_key*/,
+ const std::string& /*in_nonce*/,
+ const std::string& /*in_signed_data*/,
+ const std::string& /*in_destination_udn*/,
+ const std::string& /*in_hotspot_ssid*/,
+ const std::string& /*in_hotspot_bssid*/,
+ const std::string& /*in_data*/,
+ std::string*,
+ brillo::ErrorPtr* /*error*/,
+ int /*timeout_ms*/) override {
+ LOG(WARNING) << "VerifyAndEncryptData(): gmock can't handle methods with 11 arguments. You can override this method in a subclass if you need to.";
+ return false;
+ }
+ void VerifyAndEncryptDataAsync(const std::string& /*in_certificate*/,
+ const std::string& /*in_public_key*/,
+ const std::string& /*in_nonce*/,
+ const std::string& /*in_signed_data*/,
+ const std::string& /*in_destination_udn*/,
+ const std::string& /*in_hotspot_ssid*/,
+ const std::string& /*in_hotspot_bssid*/,
+ const std::string& /*in_data*/,
+ const base::Callback<void(const std::string&)>& /*success_callback*/,
+ const base::Callback<void(brillo::Error*)>& /*error_callback*/,
+ int /*timeout_ms*/) override {
+ LOG(WARNING) << "VerifyAndEncryptDataAsync(): gmock can't handle methods with 11 arguments. You can override this method in a subclass if you need to.";
+ }
+ MOCK_METHOD2(ConnectToBestServices,
+ bool(brillo::ErrorPtr* /*error*/,
+ int /*timeout_ms*/));
+ MOCK_METHOD3(ConnectToBestServicesAsync,
+ void(const base::Callback<void()>& /*success_callback*/,
+ const base::Callback<void(brillo::Error*)>& /*error_callback*/,
+ int /*timeout_ms*/));
+ MOCK_METHOD2(CreateConnectivityReport,
+ bool(brillo::ErrorPtr* /*error*/,
+ int /*timeout_ms*/));
+ MOCK_METHOD3(CreateConnectivityReportAsync,
+ void(const base::Callback<void()>& /*success_callback*/,
+ const base::Callback<void(brillo::Error*)>& /*error_callback*/,
+ int /*timeout_ms*/));
+ MOCK_METHOD4(ClaimInterface,
+ bool(const std::string& /*in_claimer_name*/,
+ const std::string& /*in_interface_name*/,
+ brillo::ErrorPtr* /*error*/,
+ int /*timeout_ms*/));
+ MOCK_METHOD5(ClaimInterfaceAsync,
+ void(const std::string& /*in_claimer_name*/,
+ const std::string& /*in_interface_name*/,
+ const base::Callback<void()>& /*success_callback*/,
+ const base::Callback<void(brillo::Error*)>& /*error_callback*/,
+ int /*timeout_ms*/));
+ MOCK_METHOD4(ReleaseInterface,
+ bool(const std::string& /*in_claimer_name*/,
+ const std::string& /*in_interface_name*/,
+ brillo::ErrorPtr* /*error*/,
+ int /*timeout_ms*/));
+ MOCK_METHOD5(ReleaseInterfaceAsync,
+ void(const std::string& /*in_claimer_name*/,
+ const std::string& /*in_interface_name*/,
+ const base::Callback<void()>& /*success_callback*/,
+ const base::Callback<void(brillo::Error*)>& /*error_callback*/,
+ int /*timeout_ms*/));
+ MOCK_METHOD3(SetSchedScan,
+ bool(bool,
+ brillo::ErrorPtr* /*error*/,
+ int /*timeout_ms*/));
+ MOCK_METHOD4(SetSchedScanAsync,
+ void(bool,
+ const base::Callback<void()>& /*success_callback*/,
+ const base::Callback<void(brillo::Error*)>& /*error_callback*/,
+ int /*timeout_ms*/));
+ MOCK_METHOD3(SetupApModeInterface,
+ bool(std::string* /*out_interface_name*/,
+ brillo::ErrorPtr* /*error*/,
+ int /*timeout_ms*/));
+ MOCK_METHOD3(SetupApModeInterfaceAsync,
+ void(const base::Callback<void(const std::string& /*interface_name*/)>& /*success_callback*/,
+ const base::Callback<void(brillo::Error*)>& /*error_callback*/,
+ int /*timeout_ms*/));
+ MOCK_METHOD3(SetupStationModeInterface,
+ bool(std::string* /*out_interface_name*/,
+ brillo::ErrorPtr* /*error*/,
+ int /*timeout_ms*/));
+ MOCK_METHOD3(SetupStationModeInterfaceAsync,
+ void(const base::Callback<void(const std::string& /*interface_name*/)>& /*success_callback*/,
+ const base::Callback<void(brillo::Error*)>& /*error_callback*/,
+ int /*timeout_ms*/));
+ MOCK_METHOD2(RegisterPropertyChangedSignalHandler,
+ void(const base::Callback<void(const std::string&,
+ const brillo::Any&)>& /*signal_callback*/,
+ dbus::ObjectProxy::OnConnectedCallback /*on_connected_callback*/));
+ MOCK_METHOD2(RegisterStateChangedSignalHandler,
+ void(const base::Callback<void(const std::string&)>& /*signal_callback*/,
+ dbus::ObjectProxy::OnConnectedCallback /*on_connected_callback*/));
+ MOCK_CONST_METHOD0(GetObjectPath, const dbus::ObjectPath&());
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(ManagerProxyMock);
+};
+} // namespace flimflam
+} // namespace chromium
+} // namespace org
+
+namespace org {
+namespace chromium {
+namespace flimflam {
+
+// Mock object for ServiceProxyInterface.
+class ServiceProxyMock : public ServiceProxyInterface {
+ public:
+ ServiceProxyMock() = default;
+
+ MOCK_METHOD3(GetProperties,
+ bool(brillo::VariantDictionary*,
+ brillo::ErrorPtr* /*error*/,
+ int /*timeout_ms*/));
+ MOCK_METHOD3(GetPropertiesAsync,
+ void(const base::Callback<void(const brillo::VariantDictionary&)>& /*success_callback*/,
+ const base::Callback<void(brillo::Error*)>& /*error_callback*/,
+ int /*timeout_ms*/));
+ MOCK_METHOD4(SetProperty,
+ bool(const std::string&,
+ const brillo::Any&,
+ brillo::ErrorPtr* /*error*/,
+ int /*timeout_ms*/));
+ MOCK_METHOD5(SetPropertyAsync,
+ void(const std::string&,
+ const brillo::Any&,
+ const base::Callback<void()>& /*success_callback*/,
+ const base::Callback<void(brillo::Error*)>& /*error_callback*/,
+ int /*timeout_ms*/));
+ MOCK_METHOD3(SetProperties,
+ bool(const brillo::VariantDictionary&,
+ brillo::ErrorPtr* /*error*/,
+ int /*timeout_ms*/));
+ MOCK_METHOD4(SetPropertiesAsync,
+ void(const brillo::VariantDictionary&,
+ const base::Callback<void()>& /*success_callback*/,
+ const base::Callback<void(brillo::Error*)>& /*error_callback*/,
+ int /*timeout_ms*/));
+ MOCK_METHOD3(ClearProperty,
+ bool(const std::string&,
+ brillo::ErrorPtr* /*error*/,
+ int /*timeout_ms*/));
+ MOCK_METHOD4(ClearPropertyAsync,
+ void(const std::string&,
+ const base::Callback<void()>& /*success_callback*/,
+ const base::Callback<void(brillo::Error*)>& /*error_callback*/,
+ int /*timeout_ms*/));
+ MOCK_METHOD4(ClearProperties,
+ bool(const std::vector<std::string>&,
+ std::vector<bool>*,
+ brillo::ErrorPtr* /*error*/,
+ int /*timeout_ms*/));
+ MOCK_METHOD4(ClearPropertiesAsync,
+ void(const std::vector<std::string>&,
+ const base::Callback<void(const std::vector<bool>&)>& /*success_callback*/,
+ const base::Callback<void(brillo::Error*)>& /*error_callback*/,
+ int /*timeout_ms*/));
+ MOCK_METHOD2(Connect,
+ bool(brillo::ErrorPtr* /*error*/,
+ int /*timeout_ms*/));
+ MOCK_METHOD3(ConnectAsync,
+ void(const base::Callback<void()>& /*success_callback*/,
+ const base::Callback<void(brillo::Error*)>& /*error_callback*/,
+ int /*timeout_ms*/));
+ MOCK_METHOD2(Disconnect,
+ bool(brillo::ErrorPtr* /*error*/,
+ int /*timeout_ms*/));
+ MOCK_METHOD3(DisconnectAsync,
+ void(const base::Callback<void()>& /*success_callback*/,
+ const base::Callback<void(brillo::Error*)>& /*error_callback*/,
+ int /*timeout_ms*/));
+ MOCK_METHOD2(Remove,
+ bool(brillo::ErrorPtr* /*error*/,
+ int /*timeout_ms*/));
+ MOCK_METHOD3(RemoveAsync,
+ void(const base::Callback<void()>& /*success_callback*/,
+ const base::Callback<void(brillo::Error*)>& /*error_callback*/,
+ int /*timeout_ms*/));
+ MOCK_METHOD3(ActivateCellularModem,
+ bool(const std::string&,
+ brillo::ErrorPtr* /*error*/,
+ int /*timeout_ms*/));
+ MOCK_METHOD4(ActivateCellularModemAsync,
+ void(const std::string&,
+ const base::Callback<void()>& /*success_callback*/,
+ const base::Callback<void(brillo::Error*)>& /*error_callback*/,
+ int /*timeout_ms*/));
+ MOCK_METHOD2(CompleteCellularActivation,
+ bool(brillo::ErrorPtr* /*error*/,
+ int /*timeout_ms*/));
+ MOCK_METHOD3(CompleteCellularActivationAsync,
+ void(const base::Callback<void()>& /*success_callback*/,
+ const base::Callback<void(brillo::Error*)>& /*error_callback*/,
+ int /*timeout_ms*/));
+ MOCK_METHOD3(GetLoadableProfileEntries,
+ bool(std::map<dbus::ObjectPath, std::string>*,
+ brillo::ErrorPtr* /*error*/,
+ int /*timeout_ms*/));
+ MOCK_METHOD3(GetLoadableProfileEntriesAsync,
+ void(const base::Callback<void(const std::map<dbus::ObjectPath, std::string>&)>& /*success_callback*/,
+ const base::Callback<void(brillo::Error*)>& /*error_callback*/,
+ int /*timeout_ms*/));
+ MOCK_METHOD2(RegisterPropertyChangedSignalHandler,
+ void(const base::Callback<void(const std::string&,
+ const brillo::Any&)>& /*signal_callback*/,
+ dbus::ObjectProxy::OnConnectedCallback /*on_connected_callback*/));
+ MOCK_CONST_METHOD0(GetObjectPath, const dbus::ObjectPath&());
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(ServiceProxyMock);
+};
+} // namespace flimflam
+} // namespace chromium
+} // namespace org
+
+#endif // ____CHROMEOS_DBUS_BINDING___UPDATE_ENGINE_INCLUDE_SHILL_DBUS_PROXY_MOCKS_H
diff --git a/include/update_engine/dbus-constants.h b/include/update_engine/dbus-constants.h
deleted file mode 100644
index 94e35f1..0000000
--- a/include/update_engine/dbus-constants.h
+++ /dev/null
@@ -1,51 +0,0 @@
-// Copyright 2015 The Chromium OS Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef SYSTEM_API_DBUS_UPDATE_ENGINE_DBUS_CONSTANTS_H_
-#define SYSTEM_API_DBUS_UPDATE_ENGINE_DBUS_CONSTANTS_H_
-
-namespace update_engine {
-const char kUpdateEngineInterface[] = "org.chromium.UpdateEngineInterface";
-const char kUpdateEngineServicePath[] = "/org/chromium/UpdateEngine";
-const char kUpdateEngineServiceName[] = "org.chromium.UpdateEngine";
-
-// Generic UpdateEngine D-Bus error.
-static const char* const kUpdateEngineServiceErrorFailed =
- "org.chromium.UpdateEngine.Error.Failed";
-
-// Methods.
-const char kAttemptUpdate[] = "AttemptUpdate";
-const char kGetStatus[] = "GetStatus";
-const char kRebootIfNeeded[] = "RebootIfNeeded";
-const char kSetChannel[] = "SetChannel";
-const char kGetChannel[] = "GetChannel";
-const char kAttemptRollback[] = "AttemptRollback";
-const char kCanRollback[] = "CanRollback";
-
-// Signals.
-const char kStatusUpdate[] = "StatusUpdate";
-
-// Flags used in the AttemptUpdateWithFlags() D-Bus method.
-typedef enum {
- kAttemptUpdateFlagNonInteractive = (1<<0)
-} AttemptUpdateFlags;
-
-// Operations contained in StatusUpdate signals.
-const char kUpdateStatusIdle[] = "UPDATE_STATUS_IDLE";
-const char kUpdateStatusCheckingForUpdate[] =
- "UPDATE_STATUS_CHECKING_FOR_UPDATE";
-const char kUpdateStatusUpdateAvailable[] = "UPDATE_STATUS_UPDATE_AVAILABLE";
-const char kUpdateStatusDownloading[] = "UPDATE_STATUS_DOWNLOADING";
-const char kUpdateStatusVerifying[] = "UPDATE_STATUS_VERIFYING";
-const char kUpdateStatusFinalizing[] = "UPDATE_STATUS_FINALIZING";
-const char kUpdateStatusUpdatedNeedReboot[] =
- "UPDATE_STATUS_UPDATED_NEED_REBOOT";
-const char kUpdateStatusReportingErrorEvent[] =
- "UPDATE_STATUS_REPORTING_ERROR_EVENT";
-const char kUpdateStatusAttemptingRollback[] =
- "UPDATE_STATUS_ATTEMPTING_ROLLBACK";
-const char kUpdateStatusDisabled[] = "UPDATE_STATUS_DISABLED";
-} // namespace update_engine
-
-#endif // SYSTEM_API_DBUS_UPDATE_ENGINE_DBUS_CONSTANTS_H_
diff --git a/include/update_includes.sh b/include/update_includes.sh
new file mode 100755
index 0000000..6008d59
--- /dev/null
+++ b/include/update_includes.sh
@@ -0,0 +1,79 @@
+#!/bin/bash
+
+#
+# Copyright (C) 2016 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+DBUS_GENERATOR=$(which dbus-binding-generator)
+MY_DIR=$(dirname "$0")
+
+if [[ -z "${ANDROID_HOST_OUT}" ]]; then
+ echo "You must run envsetup.sh and lunch first." >&2
+ exit 1
+fi
+
+if [[ -z "${DBUS_GENERATOR}" ]]; then
+ echo "DBus bindings generator not found." >&2
+ exit 1
+fi
+
+set -e
+
+# generate <kind> <dir> <xml> [xml ...]
+# Generate a DBus proxy and/or proxy mock in the passed |dir| for the provided
+# |xml| service files.
+# The parameter |kind| determines whether it should generate the mock only
+# (mock), the proxy only (proxy) or both (both).
+generate() {
+ local kind="$1"
+ local dir="$2"
+ local xmls=("${@:3}")
+
+ mkdir -p "${MY_DIR}/${dir}"
+ local outdir=$(realpath "${MY_DIR}/${dir}")
+ local proxyh="${outdir}/dbus-proxies.h"
+ local mockh="${outdir}/dbus-proxy-mocks.h"
+
+ ${DBUS_GENERATOR} "${xmls[@]}" --mock="${mockh}" --proxy="${proxyh}"
+
+ # Fix the include path to the dbus-proxies.h to include ${dir}.
+ sed "s,include \"dbus-proxies.h\",include \"${dir}/dbus-proxies.h\"," \
+ -i "${mockh}"
+
+ # Fix the header guards to be independent from the checkout location.
+ local guard=$(realpath "${MY_DIR}/../.." | tr '[:lower:]/ ' '[:upper:]__')
+ for header in "${mockh}" "${proxyh}"; do
+ sed "s,___CHROMEOS_DBUS_BINDING__${guard},___CHROMEOS_DBUS_BINDING__," \
+ -i "${header}"
+ done
+
+ # Remove the files not requested.
+ if [[ "${kind}" == "mock" ]]; then
+ rm -f "${proxyh}"
+ elif [[ "${kind}" == "proxy" ]]; then
+ rm -f "${mockh}"
+ fi
+}
+
+UE_DIR=$(realpath "${MY_DIR}/..")
+SHILL_DIR=$(realpath "${UE_DIR}/../connectivity/shill")
+
+generate mock "libcros" \
+ "${UE_DIR}/dbus_bindings/org.chromium.LibCrosService.dbus-xml"
+
+generate mock "shill" \
+ "${SHILL_DIR}"/dbus_bindings/org.chromium.flimflam.{Manager,Service}.dbus-xml
+
+echo "Done."
diff --git a/mock_payload_state.h b/mock_payload_state.h
index 728f274..2f654c7 100644
--- a/mock_payload_state.h
+++ b/mock_payload_state.h
@@ -74,6 +74,7 @@
MOCK_CONST_METHOD0(GetUsingP2PForSharing, bool());
MOCK_METHOD0(GetScatteringWaitPeriod, base::TimeDelta());
MOCK_CONST_METHOD0(GetP2PUrl, std::string());
+ MOCK_CONST_METHOD0(GetAttemptErrorCode, ErrorCode());
};
} // namespace chromeos_update_engine
diff --git a/mock_proxy_resolver.h b/mock_proxy_resolver.h
new file mode 100644
index 0000000..0595f5a
--- /dev/null
+++ b/mock_proxy_resolver.h
@@ -0,0 +1,38 @@
+//
+// Copyright (C) 2016 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+#ifndef UPDATE_ENGINE_MOCK_PROXY_RESOLVER_H_
+#define UPDATE_ENGINE_MOCK_PROXY_RESOLVER_H_
+
+#include <string>
+
+#include <gmock/gmock.h>
+
+#include "update_engine/proxy_resolver.h"
+
+namespace chromeos_update_engine {
+
+class MockProxyResolver : public ProxyResolver {
+ public:
+ MOCK_METHOD3(GetProxiesForUrl,
+ bool(const std::string& url,
+ ProxiesResolvedFn callback,
+ void* data));
+};
+
+} // namespace chromeos_update_engine
+
+#endif // UPDATE_ENGINE_MOCK_PROXY_RESOLVER_H_
diff --git a/omaha_request_action.cc b/omaha_request_action.cc
index 1b0c2fe..bc84c9f 100644
--- a/omaha_request_action.cc
+++ b/omaha_request_action.cc
@@ -1074,18 +1074,23 @@
// safe-guards). See http://crbug.com/297170 for an example)
size_t minimum_size = 0;
int64_t manifest_metadata_size = 0;
+ int64_t manifest_signature_size = 0;
int64_t next_data_offset = 0;
int64_t next_data_length = 0;
if (system_state_ &&
system_state_->prefs()->GetInt64(kPrefsManifestMetadataSize,
&manifest_metadata_size) &&
manifest_metadata_size != -1 &&
+ system_state_->prefs()->GetInt64(kPrefsManifestSignatureSize,
+ &manifest_signature_size) &&
+ manifest_signature_size != -1 &&
system_state_->prefs()->GetInt64(kPrefsUpdateStateNextDataOffset,
&next_data_offset) &&
next_data_offset != -1 &&
system_state_->prefs()->GetInt64(kPrefsUpdateStateNextDataLength,
&next_data_length)) {
- minimum_size = manifest_metadata_size + next_data_offset + next_data_length;
+ minimum_size = manifest_metadata_size + manifest_signature_size +
+ next_data_offset + next_data_length;
}
string file_id = utils::CalculateP2PFileId(response.hash, response.size);
diff --git a/omaha_request_action_unittest.cc b/omaha_request_action_unittest.cc
index 81a7378..3f455f3 100644
--- a/omaha_request_action_unittest.cc
+++ b/omaha_request_action_unittest.cc
@@ -1524,7 +1524,7 @@
metrics::DownloadErrorCode::kUnset,
nullptr,
&post_data));
- EXPECT_EQ(post_data.size(), 0);
+ EXPECT_EQ(0U, post_data.size());
}
TEST_F(OmahaRequestActionTest, BackInTimePingTest) {
diff --git a/omaha_response_handler_action_unittest.cc b/omaha_response_handler_action_unittest.cc
index b996d38..4917162 100644
--- a/omaha_response_handler_action_unittest.cc
+++ b/omaha_response_handler_action_unittest.cc
@@ -154,14 +154,15 @@
EXPECT_TRUE(DoTest(in, test_deadline_file, &install_plan));
EXPECT_EQ(in.payload_urls[0], install_plan.download_url);
EXPECT_EQ(in.hash, install_plan.payload_hash);
- EXPECT_EQ(1, install_plan.target_slot);
+ EXPECT_EQ(1U, install_plan.target_slot);
string deadline;
EXPECT_TRUE(utils::ReadFile(test_deadline_file, &deadline));
EXPECT_EQ("20101020", deadline);
struct stat deadline_stat;
EXPECT_EQ(0, stat(test_deadline_file.c_str(), &deadline_stat));
- EXPECT_EQ(S_IFREG | S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH,
- deadline_stat.st_mode);
+ EXPECT_EQ(
+ static_cast<mode_t>(S_IFREG | S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH),
+ deadline_stat.st_mode);
EXPECT_EQ(in.version, install_plan.version);
}
{
@@ -179,7 +180,7 @@
EXPECT_TRUE(DoTest(in, test_deadline_file, &install_plan));
EXPECT_EQ(in.payload_urls[0], install_plan.download_url);
EXPECT_EQ(in.hash, install_plan.payload_hash);
- EXPECT_EQ(0, install_plan.target_slot);
+ EXPECT_EQ(0U, install_plan.target_slot);
string deadline;
EXPECT_TRUE(utils::ReadFile(test_deadline_file, &deadline) &&
deadline.empty());
@@ -200,7 +201,7 @@
EXPECT_TRUE(DoTest(in, test_deadline_file, &install_plan));
EXPECT_EQ(in.payload_urls[0], install_plan.download_url);
EXPECT_EQ(in.hash, install_plan.payload_hash);
- EXPECT_EQ(1, install_plan.target_slot);
+ EXPECT_EQ(1U, install_plan.target_slot);
string deadline;
EXPECT_TRUE(utils::ReadFile(test_deadline_file, &deadline));
EXPECT_EQ("some-deadline", deadline);
diff --git a/payload_consumer/bzip_extent_writer_unittest.cc b/payload_consumer/bzip_extent_writer_unittest.cc
index a52a286..8ac3e59 100644
--- a/payload_consumer/bzip_extent_writer_unittest.cc
+++ b/payload_consumer/bzip_extent_writer_unittest.cc
@@ -17,9 +17,6 @@
#include "update_engine/payload_consumer/bzip_extent_writer.h"
#include <fcntl.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <unistd.h>
#include <algorithm>
#include <string>
@@ -38,28 +35,23 @@
namespace chromeos_update_engine {
namespace {
-const char kPathTemplate[] = "./BzipExtentWriterTest-file.XXXXXX";
const uint32_t kBlockSize = 4096;
}
class BzipExtentWriterTest : public ::testing::Test {
protected:
void SetUp() override {
- memcpy(path_, kPathTemplate, sizeof(kPathTemplate));
fd_.reset(new EintrSafeFileDescriptor);
- int fd = mkstemp(path_);
- ASSERT_TRUE(fd_->Open(path_, O_RDWR, 0600));
- close(fd);
+ ASSERT_TRUE(fd_->Open(temp_file_.path().c_str(), O_RDWR, 0600));
}
void TearDown() override {
fd_->Close();
- unlink(path_);
}
void WriteAlignedExtents(size_t chunk_size, size_t first_chunk_size);
void TestZeroPad(bool aligned_size);
FileDescriptorPtr fd_;
- char path_[sizeof(kPathTemplate)];
+ test_utils::ScopedTempFile temp_file_{"BzipExtentWriterTest-file.XXXXXX"};
};
TEST_F(BzipExtentWriterTest, SimpleTest) {
@@ -85,39 +77,37 @@
EXPECT_TRUE(bzip_writer.End());
brillo::Blob buf;
- EXPECT_TRUE(utils::ReadFile(path_, &buf));
+ EXPECT_TRUE(utils::ReadFile(temp_file_.path(), &buf));
EXPECT_EQ(strlen(test_uncompressed), buf.size());
EXPECT_EQ(string(buf.begin(), buf.end()), string(test_uncompressed));
}
TEST_F(BzipExtentWriterTest, ChunkedTest) {
- const brillo::Blob::size_type kDecompressedLength = 2048 * 1024; // 2 MiB
- string decompressed_path;
- ASSERT_TRUE(utils::MakeTempFile("BzipExtentWriterTest-decompressed-XXXXXX",
- &decompressed_path, nullptr));
- string compressed_path;
- ASSERT_TRUE(utils::MakeTempFile("BzipExtentWriterTest-compressed-XXXXXX",
- &compressed_path, nullptr));
+ // Generated with:
+ // yes "ABC" | head -c 819200 | bzip2 -9 |
+ // hexdump -v -e '" " 11/1 "0x%02x, " "\n"'
+ static const uint8_t kCompressedData[] = {
+ 0x42, 0x5a, 0x68, 0x39, 0x31, 0x41, 0x59, 0x26, 0x53, 0x59, 0xbe,
+ 0x1c, 0xda, 0xee, 0x03, 0x1f, 0xff, 0xc4, 0x00, 0x00, 0x10, 0x38,
+ 0x00, 0x20, 0x00, 0x50, 0x66, 0x9a, 0x05, 0x28, 0x38, 0x00, 0x11,
+ 0x60, 0x00, 0x22, 0xd0, 0x00, 0x45, 0xc0, 0x00, 0x8b, 0xc5, 0xdc,
+ 0x91, 0x4e, 0x14, 0x24, 0x2f, 0x87, 0x36, 0xbb, 0x80};
+ brillo::Blob compressed_data(std::begin(kCompressedData),
+ std::end(kCompressedData));
+
+ const brillo::Blob::size_type kDecompressedLength = 800 * 1024; // 800 KiB
const size_t kChunkSize = 3;
+ brillo::Blob decompressed_data(kDecompressedLength);
+ for (size_t i = 0; i < decompressed_data.size(); ++i)
+ decompressed_data[i] = static_cast<uint8_t>("ABC\n"[i % 4]);
+
vector<Extent> extents;
Extent extent;
extent.set_start_block(0);
- extent.set_num_blocks(kDecompressedLength / kBlockSize + 1);
+ extent.set_num_blocks((kDecompressedLength + kBlockSize - 1) / kBlockSize);
extents.push_back(extent);
- brillo::Blob decompressed_data(kDecompressedLength);
- test_utils::FillWithData(&decompressed_data);
-
- EXPECT_TRUE(test_utils::WriteFileVector(
- decompressed_path, decompressed_data));
-
- EXPECT_EQ(0, test_utils::System(
- string("cat ") + decompressed_path + "|bzip2>" + compressed_path));
-
- brillo::Blob compressed_data;
- EXPECT_TRUE(utils::ReadFile(compressed_path, &compressed_data));
-
BzipExtentWriter bzip_writer(
brillo::make_unique_ptr(new DirectExtentWriter()));
EXPECT_TRUE(bzip_writer.Init(fd_, extents, kBlockSize));
@@ -134,12 +124,9 @@
test_utils::ExpectVectorsEq(original_compressed_data, compressed_data);
brillo::Blob output;
- EXPECT_TRUE(utils::ReadFile(path_, &output));
+ EXPECT_TRUE(utils::ReadFile(temp_file_.path(), &output));
EXPECT_EQ(kDecompressedLength, output.size());
test_utils::ExpectVectorsEq(decompressed_data, output);
-
- unlink(decompressed_path.c_str());
- unlink(compressed_path.c_str());
}
} // namespace chromeos_update_engine
diff --git a/payload_consumer/delta_performer.cc b/payload_consumer/delta_performer.cc
index cb3cdb5..f490c08 100644
--- a/payload_consumer/delta_performer.cc
+++ b/payload_consumer/delta_performer.cc
@@ -578,6 +578,9 @@
LOG_IF(WARNING, !prefs_->SetInt64(kPrefsManifestMetadataSize,
metadata_size_))
<< "Unable to save the manifest metadata size.";
+ LOG_IF(WARNING, !prefs_->SetInt64(kPrefsManifestSignatureSize,
+ metadata_signature_size_))
+ << "Unable to save the manifest signature size.";
if (!PrimeUpdateState()) {
*error = ErrorCode::kDownloadStateInitializationError;
@@ -686,8 +689,10 @@
}
// In major version 2, we don't add dummy operation to the payload.
+ // If we already extracted the signature we should skip this step.
if (major_payload_version_ == kBrilloMajorPayloadVersion &&
- manifest_.has_signatures_offset() && manifest_.has_signatures_size()) {
+ manifest_.has_signatures_offset() && manifest_.has_signatures_size() &&
+ signatures_message_data_.empty()) {
if (manifest_.signatures_offset() != buffer_offset_) {
LOG(ERROR) << "Payload signatures offset points to blob offset "
<< manifest_.signatures_offset()
@@ -706,6 +711,10 @@
return false;
}
DiscardBuffer(true, 0);
+ // Since we extracted the SignatureMessage we need to advance the
+ // checkpoint, otherwise we would reload the signature and try to extract
+ // it again.
+ CheckpointUpdateProgress();
}
return true;
@@ -781,6 +790,12 @@
install_part.name = partition.partition_name();
install_part.run_postinstall =
partition.has_run_postinstall() && partition.run_postinstall();
+ if (install_part.run_postinstall) {
+ install_part.postinstall_path =
+ (partition.has_postinstall_path() ? partition.postinstall_path()
+ : kPostinstallDefaultScript);
+ install_part.filesystem_type = partition.filesystem_type();
+ }
if (partition.has_old_partition_info()) {
const PartitionInfo& info = partition.old_partition_info();
@@ -1666,8 +1681,10 @@
return false;
int64_t resumed_update_failures;
- if (!(prefs->GetInt64(kPrefsResumedUpdateFailures, &resumed_update_failures)
- && resumed_update_failures > kMaxResumedUpdateFailures))
+ // Note that storing this value is optional, but if it is there it should not
+ // be more than the limit.
+ if (prefs->GetInt64(kPrefsResumedUpdateFailures, &resumed_update_failures) &&
+ resumed_update_failures > kMaxResumedUpdateFailures)
return false;
// Sanity check the rest.
@@ -1686,6 +1703,12 @@
manifest_metadata_size > 0))
return false;
+ int64_t manifest_signature_size = 0;
+ if (!(prefs->GetInt64(kPrefsManifestSignatureSize,
+ &manifest_signature_size) &&
+ manifest_signature_size >= 0))
+ return false;
+
return true;
}
@@ -1700,6 +1723,7 @@
prefs->SetString(kPrefsUpdateStateSignedSHA256Context, "");
prefs->SetString(kPrefsUpdateStateSignatureBlob, "");
prefs->SetInt64(kPrefsManifestMetadataSize, -1);
+ prefs->SetInt64(kPrefsManifestSignatureSize, -1);
prefs->SetInt64(kPrefsResumedUpdateFailures, 0);
}
return true;
@@ -1786,6 +1810,12 @@
manifest_metadata_size > 0);
metadata_size_ = manifest_metadata_size;
+ int64_t manifest_signature_size = 0;
+ TEST_AND_RETURN_FALSE(
+ prefs_->GetInt64(kPrefsManifestSignatureSize, &manifest_signature_size) &&
+ manifest_signature_size >= 0);
+ metadata_signature_size_ = manifest_signature_size;
+
// Advance the download progress to reflect what doesn't need to be
// re-downloaded.
total_bytes_received_ += buffer_offset_;
diff --git a/payload_consumer/delta_performer_integration_test.cc b/payload_consumer/delta_performer_integration_test.cc
index 9b7854b..3d7f8fa 100644
--- a/payload_consumer/delta_performer_integration_test.cc
+++ b/payload_consumer/delta_performer_integration_test.cc
@@ -58,7 +58,7 @@
extern const char* kUnittestPrivateKey2Path;
extern const char* kUnittestPublicKey2Path;
-static const int kDefaultKernelSize = 4096; // Something small for a test
+static const uint32_t kDefaultKernelSize = 4096; // Something small for a test
static const uint8_t kNewData[] = {'T', 'h', 'i', 's', ' ', 'i', 's', ' ',
'n', 'e', 'w', ' ', 'd', 'a', 't', 'a', '.'};
@@ -124,7 +124,7 @@
static void CompareFilesByBlock(const string& a_file, const string& b_file,
size_t image_size) {
- EXPECT_EQ(0, image_size % kBlockSize);
+ EXPECT_EQ(0U, image_size % kBlockSize);
brillo::Blob a_data, b_data;
EXPECT_TRUE(utils::ReadFile(a_file, &a_data)) << "file failed: " << a_file;
@@ -133,7 +133,7 @@
EXPECT_GE(a_data.size(), image_size);
EXPECT_GE(b_data.size(), image_size);
for (size_t i = 0; i < image_size; i += kBlockSize) {
- EXPECT_EQ(0, i % kBlockSize);
+ EXPECT_EQ(0U, i % kBlockSize);
brillo::Blob a_sub(&a_data[i], &a_data[i + kBlockSize]);
brillo::Blob b_sub(&b_data[i], &b_data[i + kBlockSize]);
EXPECT_TRUE(a_sub == b_sub) << "Block " << (i/kBlockSize) << " differs";
@@ -350,7 +350,7 @@
hardtocompress.size()));
brillo::Blob zeros(16 * 1024, 0);
- EXPECT_EQ(zeros.size(),
+ EXPECT_EQ(static_cast<int>(zeros.size()),
base::WriteFile(base::FilePath(base::StringPrintf(
"%s/move-to-sparse", a_mnt.c_str())),
reinterpret_cast<const char*>(zeros.data()),
@@ -416,7 +416,7 @@
16 * 1024));
brillo::Blob zeros(16 * 1024, 0);
- EXPECT_EQ(zeros.size(),
+ EXPECT_EQ(static_cast<int>(zeros.size()),
base::WriteFile(base::FilePath(base::StringPrintf(
"%s/move-from-sparse", b_mnt.c_str())),
reinterpret_cast<const char*>(zeros.data()),
@@ -543,10 +543,12 @@
// Extend the "partitions" holding the file system a bit.
EXPECT_EQ(0, HANDLE_EINTR(truncate(state->a_img.c_str(),
state->image_size + 1024 * 1024)));
- EXPECT_EQ(state->image_size + 1024 * 1024, utils::FileSize(state->a_img));
+ EXPECT_EQ(static_cast<off_t>(state->image_size + 1024 * 1024),
+ utils::FileSize(state->a_img));
EXPECT_EQ(0, HANDLE_EINTR(truncate(state->b_img.c_str(),
state->image_size + 1024 * 1024)));
- EXPECT_EQ(state->image_size + 1024 * 1024, utils::FileSize(state->b_img));
+ EXPECT_EQ(static_cast<off_t>(state->image_size + 1024 * 1024),
+ utils::FileSize(state->b_img));
if (signature_test == kSignatureGeneratedPlaceholder ||
signature_test == kSignatureGeneratedPlaceholderMismatch) {
@@ -614,7 +616,7 @@
else
EXPECT_EQ(1, sigs_message.signatures_size());
const Signatures_Signature& signature = sigs_message.signatures(0);
- EXPECT_EQ(1, signature.version());
+ EXPECT_EQ(1U, signature.version());
uint64_t expected_sig_data_length = 0;
vector<string> key_paths{kUnittestPrivateKeyPath};
@@ -691,6 +693,8 @@
MockPrefs prefs;
EXPECT_CALL(prefs, SetInt64(kPrefsManifestMetadataSize,
state->metadata_size)).WillOnce(Return(true));
+ EXPECT_CALL(prefs, SetInt64(kPrefsManifestSignatureSize, 0))
+ .WillOnce(Return(true));
EXPECT_CALL(prefs, SetInt64(kPrefsUpdateStateNextOperation, _))
.WillRepeatedly(Return(true));
EXPECT_CALL(prefs, GetInt64(kPrefsUpdateStateNextOperation, _))
@@ -745,7 +749,7 @@
(*performer)->set_public_key_path(kUnittestPublicKeyPath);
DeltaPerformerIntegrationTest::SetSupportedVersion(*performer, minor_version);
- EXPECT_EQ(state->image_size,
+ EXPECT_EQ(static_cast<off_t>(state->image_size),
HashCalculator::RawHashOfFile(
state->a_img,
state->image_size,
@@ -880,7 +884,7 @@
updated_kernel_partition.begin()));
const auto& partitions = state->install_plan.partitions;
- EXPECT_EQ(2, partitions.size());
+ EXPECT_EQ(2U, partitions.size());
EXPECT_EQ(kLegacyPartitionNameRoot, partitions[0].name);
EXPECT_EQ(kLegacyPartitionNameKernel, partitions[1].name);
@@ -892,7 +896,7 @@
EXPECT_EQ(state->image_size, partitions[0].target_size);
brillo::Blob expected_new_rootfs_hash;
- EXPECT_EQ(state->image_size,
+ EXPECT_EQ(static_cast<off_t>(state->image_size),
HashCalculator::RawHashOfFile(state->b_img,
state->image_size,
&expected_new_rootfs_hash));
diff --git a/payload_consumer/delta_performer_unittest.cc b/payload_consumer/delta_performer_unittest.cc
index dabe138..98a378b 100644
--- a/payload_consumer/delta_performer_unittest.cc
+++ b/payload_consumer/delta_performer_unittest.cc
@@ -16,6 +16,7 @@
#include "update_engine/payload_consumer/delta_performer.h"
+#include <endian.h>
#include <inttypes.h>
#include <string>
@@ -649,7 +650,7 @@
EXPECT_EQ(kBrilloMajorPayloadVersion, performer_.GetMajorVersion());
uint64_t manifest_offset;
EXPECT_TRUE(performer_.GetManifestOffset(&manifest_offset));
- EXPECT_EQ(24, manifest_offset); // 4 + 8 + 8 + 4
+ EXPECT_EQ(24U, manifest_offset); // 4 + 8 + 8 + 4
EXPECT_EQ(manifest_offset + manifest_size, performer_.GetMetadataSize());
EXPECT_EQ(metadata_signature_size, performer_.metadata_signature_size_);
}
diff --git a/payload_consumer/download_action.cc b/payload_consumer/download_action.cc
index 6a71fdb..fdbbd72 100644
--- a/payload_consumer/download_action.cc
+++ b/payload_consumer/download_action.cc
@@ -232,6 +232,14 @@
http_fetcher_->BeginTransfer(install_plan_.download_url);
}
+void DownloadAction::SuspendAction() {
+ http_fetcher_->Pause();
+}
+
+void DownloadAction::ResumeAction() {
+ http_fetcher_->Unpause();
+}
+
void DownloadAction::TerminateProcessing() {
if (writer_) {
writer_->Close();
diff --git a/payload_consumer/download_action.h b/payload_consumer/download_action.h
index d000c67..fc32068 100644
--- a/payload_consumer/download_action.h
+++ b/payload_consumer/download_action.h
@@ -68,6 +68,9 @@
class DownloadAction : public InstallPlanAction,
public HttpFetcherDelegate {
public:
+ // Debugging/logging
+ static std::string StaticType() { return "DownloadAction"; }
+
// Takes ownership of the passed in HttpFetcher. Useful for testing.
// A good calling pattern is:
// DownloadAction(prefs, boot_contol, hardware, system_state,
@@ -78,8 +81,13 @@
SystemState* system_state,
HttpFetcher* http_fetcher);
~DownloadAction() override;
+
+ // InstallPlanAction overrides.
void PerformAction() override;
+ void SuspendAction() override;
+ void ResumeAction() override;
void TerminateProcessing() override;
+ std::string Type() const override { return StaticType(); }
// Testing
void SetTestFileWriter(FileWriter* writer) {
@@ -88,10 +96,6 @@
int GetHTTPResponseCode() { return http_fetcher_->http_response_code(); }
- // Debugging/logging
- static std::string StaticType() { return "DownloadAction"; }
- std::string Type() const override { return StaticType(); }
-
// HttpFetcherDelegate methods (see http_fetcher.h)
void ReceivedBytes(HttpFetcher* fetcher,
const void* bytes, size_t length) override;
diff --git a/payload_consumer/download_action_unittest.cc b/payload_consumer/download_action_unittest.cc
index 979776f..4ffd35c 100644
--- a/payload_consumer/download_action_unittest.cc
+++ b/payload_consumer/download_action_unittest.cc
@@ -135,9 +135,8 @@
// TODO(adlr): see if we need a different file for build bots
ScopedTempFile output_temp_file;
TestDirectFileWriter writer;
- EXPECT_EQ(0, writer.Open(output_temp_file.GetPath().c_str(),
- O_WRONLY | O_CREAT,
- 0));
+ EXPECT_EQ(
+ 0, writer.Open(output_temp_file.path().c_str(), O_WRONLY | O_CREAT, 0));
writer.set_fail_write(fail_write);
// We pull off the first byte from data and seek past it.
@@ -183,7 +182,7 @@
expected_code = ErrorCode::kDownloadWriteError;
DownloadActionTestProcessorDelegate delegate(expected_code);
delegate.expected_data_ = brillo::Blob(data.begin() + 1, data.end());
- delegate.path_ = output_temp_file.GetPath();
+ delegate.path_ = output_temp_file.path();
ActionProcessor processor;
processor.set_delegate(&delegate);
processor.EnqueueAction(&feeder_action);
@@ -268,9 +267,7 @@
ScopedTempFile temp_file;
{
DirectFileWriter writer;
- EXPECT_EQ(0, writer.Open(temp_file.GetPath().c_str(),
- O_WRONLY | O_CREAT,
- 0));
+ EXPECT_EQ(0, writer.Open(temp_file.path().c_str(), O_WRONLY | O_CREAT, 0));
// takes ownership of passed in HttpFetcher
ObjectFeederAction<InstallPlan> feeder_action;
@@ -304,10 +301,11 @@
}
// 1 or 0 chunks should have come through
- const off_t resulting_file_size(utils::FileSize(temp_file.GetPath()));
+ const off_t resulting_file_size(utils::FileSize(temp_file.path()));
EXPECT_GE(resulting_file_size, 0);
if (resulting_file_size != 0)
- EXPECT_EQ(kMockHttpFetcherChunkSize, resulting_file_size);
+ EXPECT_EQ(kMockHttpFetcherChunkSize,
+ static_cast<size_t>(resulting_file_size));
}
} // namespace
@@ -451,9 +449,8 @@
ScopedTempFile output_temp_file;
TestDirectFileWriter writer;
- EXPECT_EQ(0, writer.Open(output_temp_file.GetPath().c_str(),
- O_WRONLY | O_CREAT,
- 0));
+ EXPECT_EQ(
+ 0, writer.Open(output_temp_file.path().c_str(), O_WRONLY | O_CREAT, 0));
InstallPlan install_plan;
install_plan.payload_size = data_.length();
install_plan.payload_hash = "1234hash";
@@ -474,7 +471,7 @@
DownloadActionTestProcessorDelegate delegate(ErrorCode::kSuccess);
delegate.expected_data_ = brillo::Blob(data_.begin() + start_at_offset_,
data_.end());
- delegate.path_ = output_temp_file.GetPath();
+ delegate.path_ = output_temp_file.path();
processor_.set_delegate(&delegate);
processor_.EnqueueAction(&feeder_action);
processor_.EnqueueAction(download_action_.get());
@@ -532,8 +529,10 @@
// Check the p2p file and its content matches what was sent.
string file_id = download_action_->p2p_file_id();
EXPECT_NE("", file_id);
- EXPECT_EQ(data_.length(), p2p_manager_->FileGetSize(file_id));
- EXPECT_EQ(data_.length(), p2p_manager_->FileGetExpectedSize(file_id));
+ EXPECT_EQ(static_cast<int>(data_.length()),
+ p2p_manager_->FileGetSize(file_id));
+ EXPECT_EQ(static_cast<int>(data_.length()),
+ p2p_manager_->FileGetExpectedSize(file_id));
string p2p_file_contents;
EXPECT_TRUE(ReadFileToString(p2p_manager_->FileGetPath(file_id),
&p2p_file_contents));
@@ -580,8 +579,10 @@
// DownloadAction should convey the same file_id and the file should
// have the expected size.
EXPECT_EQ(download_action_->p2p_file_id(), file_id);
- EXPECT_EQ(p2p_manager_->FileGetSize(file_id), data_.length());
- EXPECT_EQ(p2p_manager_->FileGetExpectedSize(file_id), data_.length());
+ EXPECT_EQ(static_cast<ssize_t>(data_.length()),
+ p2p_manager_->FileGetSize(file_id));
+ EXPECT_EQ(static_cast<ssize_t>(data_.length()),
+ p2p_manager_->FileGetExpectedSize(file_id));
string p2p_file_contents;
// Check that the first 1000 bytes wasn't touched and that we
// appended the remaining as appropriate.
@@ -611,14 +612,14 @@
1000), 1000);
// Check that the file is there.
- EXPECT_EQ(p2p_manager_->FileGetSize(file_id), 1000);
- EXPECT_EQ(p2p_manager_->CountSharedFiles(), 1);
+ EXPECT_EQ(1000, p2p_manager_->FileGetSize(file_id));
+ EXPECT_EQ(1, p2p_manager_->CountSharedFiles());
StartDownload(false); // use_p2p_to_share
// DownloadAction should have deleted the p2p file. Check that it's gone.
- EXPECT_EQ(p2p_manager_->FileGetSize(file_id), -1);
- EXPECT_EQ(p2p_manager_->CountSharedFiles(), 0);
+ EXPECT_EQ(-1, p2p_manager_->FileGetSize(file_id));
+ EXPECT_EQ(0, p2p_manager_->CountSharedFiles());
}
} // namespace chromeos_update_engine
diff --git a/payload_consumer/extent_writer_unittest.cc b/payload_consumer/extent_writer_unittest.cc
index efeab09..24d238e 100644
--- a/payload_consumer/extent_writer_unittest.cc
+++ b/payload_consumer/extent_writer_unittest.cc
@@ -17,9 +17,6 @@
#include "update_engine/payload_consumer/extent_writer.h"
#include <fcntl.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <unistd.h>
#include <algorithm>
#include <string>
@@ -43,22 +40,17 @@
static_assert(sizeof(off_t) == 8, "off_t not 64 bit");
namespace {
-const char kPathTemplate[] = "./ExtentWriterTest-file.XXXXXX";
const size_t kBlockSize = 4096;
}
class ExtentWriterTest : public ::testing::Test {
protected:
void SetUp() override {
- memcpy(path_, kPathTemplate, sizeof(kPathTemplate));
fd_.reset(new EintrSafeFileDescriptor);
- int fd = mkstemp(path_);
- ASSERT_TRUE(fd_->Open(path_, O_RDWR, 0600));
- close(fd);
+ ASSERT_TRUE(fd_->Open(temp_file_.path().c_str(), O_RDWR, 0600));
}
void TearDown() override {
fd_->Close();
- unlink(path_);
}
// Writes data to an extent writer in 'chunk_size' chunks with
@@ -69,7 +61,7 @@
void TestZeroPad(bool aligned_size);
FileDescriptorPtr fd_;
- char path_[sizeof(kPathTemplate)];
+ test_utils::ScopedTempFile temp_file_{"ExtentWriterTest-file.XXXXXX"};
};
TEST_F(ExtentWriterTest, SimpleTest) {
@@ -86,10 +78,11 @@
EXPECT_TRUE(direct_writer.Write(bytes.data(), bytes.size()));
EXPECT_TRUE(direct_writer.End());
- EXPECT_EQ(kBlockSize + bytes.size(), utils::FileSize(path_));
+ EXPECT_EQ(static_cast<off_t>(kBlockSize + bytes.size()),
+ utils::FileSize(temp_file_.path()));
brillo::Blob result_file;
- EXPECT_TRUE(utils::ReadFile(path_, &result_file));
+ EXPECT_TRUE(utils::ReadFile(temp_file_.path(), &result_file));
brillo::Blob expected_file(kBlockSize);
expected_file.insert(expected_file.end(),
@@ -153,10 +146,11 @@
}
EXPECT_TRUE(direct_writer.End());
- EXPECT_EQ(data.size(), utils::FileSize(path_));
+ EXPECT_EQ(static_cast<off_t>(data.size()),
+ utils::FileSize(temp_file_.path()));
brillo::Blob result_file;
- EXPECT_TRUE(utils::ReadFile(path_, &result_file));
+ EXPECT_TRUE(utils::ReadFile(temp_file_.path(), &result_file));
brillo::Blob expected_file;
expected_file.insert(expected_file.end(),
@@ -202,10 +196,11 @@
ASSERT_TRUE(zero_pad_writer.Write(data.data(), bytes_to_write));
EXPECT_TRUE(zero_pad_writer.End());
- EXPECT_EQ(data.size(), utils::FileSize(path_));
+ EXPECT_EQ(static_cast<off_t>(data.size()),
+ utils::FileSize(temp_file_.path()));
brillo::Blob result_file;
- EXPECT_TRUE(utils::ReadFile(path_, &result_file));
+ EXPECT_TRUE(utils::ReadFile(temp_file_.path(), &result_file));
brillo::Blob expected_file;
expected_file.insert(expected_file.end(),
@@ -251,10 +246,11 @@
EXPECT_TRUE(direct_writer.End());
// check file size, then data inside
- ASSERT_EQ(2 * kBlockSize, utils::FileSize(path_));
+ ASSERT_EQ(static_cast<off_t>(2 * kBlockSize),
+ utils::FileSize(temp_file_.path()));
brillo::Blob resultant_data;
- EXPECT_TRUE(utils::ReadFile(path_, &resultant_data));
+ EXPECT_TRUE(utils::ReadFile(temp_file_.path(), &resultant_data));
// Create expected data
brillo::Blob expected_data(on_disk_count * kBlockSize);
diff --git a/payload_consumer/filesystem_verifier_action_unittest.cc b/payload_consumer/filesystem_verifier_action_unittest.cc
index 10daaa8..cdf7fc0 100644
--- a/payload_consumer/filesystem_verifier_action_unittest.cc
+++ b/payload_consumer/filesystem_verifier_action_unittest.cc
@@ -120,7 +120,7 @@
// failures and whether or not they are due to the test setup or an inherent
// issue with the chroot environment, library versions we use, etc.
TEST_F(FilesystemVerifierActionTest, DISABLED_RunAsRootSimpleTest) {
- ASSERT_EQ(0, getuid());
+ ASSERT_EQ(0U, getuid());
bool test = DoTest(false, false, VerifierMode::kComputeSourceHash);
EXPECT_TRUE(test);
if (!test)
@@ -309,18 +309,18 @@
}
TEST_F(FilesystemVerifierActionTest, RunAsRootVerifyHashTest) {
- ASSERT_EQ(0, getuid());
+ ASSERT_EQ(0U, getuid());
EXPECT_TRUE(DoTest(false, false, VerifierMode::kVerifyTargetHash));
EXPECT_TRUE(DoTest(false, false, VerifierMode::kComputeSourceHash));
}
TEST_F(FilesystemVerifierActionTest, RunAsRootVerifyHashFailTest) {
- ASSERT_EQ(0, getuid());
+ ASSERT_EQ(0U, getuid());
EXPECT_TRUE(DoTest(false, true, VerifierMode::kVerifyTargetHash));
}
TEST_F(FilesystemVerifierActionTest, RunAsRootTerminateEarlyTest) {
- ASSERT_EQ(0, getuid());
+ ASSERT_EQ(0U, getuid());
EXPECT_TRUE(DoTest(true, false, VerifierMode::kVerifyTargetHash));
// TerminateEarlyTest may leak some null callbacks from the Stream class.
while (loop_.RunOnce(false)) {}
@@ -366,13 +366,13 @@
loop_.Run();
install_plan = collector_action.object();
- ASSERT_EQ(2, install_plan.partitions.size());
+ ASSERT_EQ(2U, install_plan.partitions.size());
// When computing the size of the rootfs on legacy delta updates we use the
// size of the filesystem, but when updating the kernel we use the whole
// partition.
- EXPECT_EQ(10 * 1024 * 1024, install_plan.partitions[0].source_size);
+ EXPECT_EQ(10U << 20, install_plan.partitions[0].source_size);
EXPECT_EQ(kLegacyPartitionNameRoot, install_plan.partitions[0].name);
- EXPECT_EQ(20 * 1024 * 1024, install_plan.partitions[1].source_size);
+ EXPECT_EQ(20U << 20, install_plan.partitions[1].source_size);
EXPECT_EQ(kLegacyPartitionNameKernel, install_plan.partitions[1].name);
}
diff --git a/payload_consumer/install_plan.cc b/payload_consumer/install_plan.cc
index 572ff41..51e85b3 100644
--- a/payload_consumer/install_plan.cc
+++ b/payload_consumer/install_plan.cc
@@ -59,9 +59,13 @@
void InstallPlan::Dump() const {
string partitions_str;
for (const auto& partition : partitions) {
- partitions_str += base::StringPrintf(
- ", part: %s (source_size: %" PRIu64 ", target_size %" PRIu64 ")",
- partition.name.c_str(), partition.source_size, partition.target_size);
+ partitions_str +=
+ base::StringPrintf(", part: %s (source_size: %" PRIu64
+ ", target_size %" PRIu64 ", postinst:%s)",
+ partition.name.c_str(),
+ partition.source_size,
+ partition.target_size,
+ utils::ToString(partition.run_postinstall).c_str());
}
LOG(INFO) << "InstallPlan: "
@@ -109,7 +113,9 @@
target_path == that.target_path &&
target_size == that.target_size &&
target_hash == that.target_hash &&
- run_postinstall == that.run_postinstall);
+ run_postinstall == that.run_postinstall &&
+ postinstall_path == that.postinstall_path &&
+ filesystem_type == that.filesystem_type);
}
} // namespace chromeos_update_engine
diff --git a/payload_consumer/install_plan.h b/payload_consumer/install_plan.h
index d2f15fa..454dd78 100644
--- a/payload_consumer/install_plan.h
+++ b/payload_consumer/install_plan.h
@@ -90,8 +90,11 @@
uint64_t target_size{0};
brillo::Blob target_hash;
- // Whether we should run the postinstall script from this partition.
+ // Whether we should run the postinstall script from this partition and the
+ // postinstall parameters.
bool run_postinstall{false};
+ std::string postinstall_path;
+ std::string filesystem_type;
};
std::vector<Partition> partitions;
diff --git a/payload_consumer/postinstall_runner_action.cc b/payload_consumer/postinstall_runner_action.cc
index 84ca398..d57ef4e 100644
--- a/payload_consumer/postinstall_runner_action.cc
+++ b/payload_consumer/postinstall_runner_action.cc
@@ -23,9 +23,11 @@
#include <base/bind.h>
#include <base/files/file_path.h>
#include <base/files/file_util.h>
+#include <base/strings/string_util.h>
#include "update_engine/common/action_processor.h"
#include "update_engine/common/boot_control_interface.h"
+#include "update_engine/common/platform_constants.h"
#include "update_engine/common/subprocess.h"
#include "update_engine/common/utils.h"
@@ -34,16 +36,6 @@
using std::string;
using std::vector;
-namespace {
-// The absolute path to the post install command.
-const char kPostinstallScript[] = "/postinst";
-
-// Path to the binary file used by kPostinstallScript. Used to get and log the
-// file format of the binary to debug issues when the ELF format on the update
-// doesn't match the one on the current system. This path is not executed.
-const char kDebugPostinstallBinaryPath[] = "/usr/bin/cros_installer";
-}
-
void PostinstallRunnerAction::PerformAction() {
CHECK(HasInputObject());
install_plan_ = GetInputObject();
@@ -60,6 +52,11 @@
}
void PostinstallRunnerAction::PerformPartitionPostinstall() {
+ if (install_plan_.download_url.empty()) {
+ LOG(INFO) << "Skipping post-install during rollback";
+ return CompletePostinstall(ErrorCode::kSuccess);
+ }
+
// Skip all the partitions that don't have a post-install step.
while (current_partition_ < install_plan_.partitions.size() &&
!install_plan_.partitions[current_partition_].run_postinstall) {
@@ -83,38 +80,45 @@
// Perform post-install for the current_partition_ partition. At this point we
// need to call CompletePartitionPostinstall to complete the operation and
// cleanup.
+#ifdef __ANDROID__
+ fs_mount_dir_ = "/postinstall";
+#else // __ANDROID__
TEST_AND_RETURN(
- utils::MakeTempDirectory("au_postint_mount.XXXXXX", &temp_rootfs_dir_));
+ utils::MakeTempDirectory("au_postint_mount.XXXXXX", &fs_mount_dir_));
+#endif // __ANDROID__
- if (!utils::MountFilesystem(mountable_device, temp_rootfs_dir_, MS_RDONLY)) {
+ string abs_path = base::FilePath(fs_mount_dir_)
+ .AppendASCII(partition.postinstall_path)
+ .value();
+ if (!base::StartsWith(
+ abs_path, fs_mount_dir_, base::CompareCase::SENSITIVE)) {
+ LOG(ERROR) << "Invalid relative postinstall path: "
+ << partition.postinstall_path;
+ return CompletePostinstall(ErrorCode::kPostinstallRunnerError);
+ }
+
+ if (!utils::MountFilesystem(mountable_device,
+ fs_mount_dir_,
+ MS_RDONLY,
+ partition.filesystem_type,
+ constants::kPostinstallMountOptions)) {
return CompletePartitionPostinstall(
1, "Error mounting the device " + mountable_device);
}
- LOG(INFO) << "Performing postinst (" << kPostinstallScript
- << ") installed on device " << partition.target_path
+ LOG(INFO) << "Performing postinst (" << partition.postinstall_path << " at "
+ << abs_path << ") installed on device " << partition.target_path
<< " and mountable device " << mountable_device;
// Logs the file format of the postinstall script we are about to run. This
// will help debug when the postinstall script doesn't match the architecture
// of our build.
- LOG(INFO) << "Format file for new " << kPostinstallScript << " is: "
- << utils::GetFileFormat(temp_rootfs_dir_ + kPostinstallScript);
- LOG(INFO) << "Format file for new " << kDebugPostinstallBinaryPath << " is: "
- << utils::GetFileFormat(
- temp_rootfs_dir_ + kDebugPostinstallBinaryPath);
+ LOG(INFO) << "Format file for new " << partition.postinstall_path
+ << " is: " << utils::GetFileFormat(abs_path);
// Runs the postinstall script asynchronously to free up the main loop while
// it's running.
- vector<string> command;
- if (!install_plan_.download_url.empty()) {
- command.push_back(temp_rootfs_dir_ + kPostinstallScript);
- } else {
- // TODO(sosa): crbug.com/366207.
- // If we're doing a rollback, just run our own postinstall.
- command.push_back(kPostinstallScript);
- }
- command.push_back(partition.target_path);
+ vector<string> command = {abs_path, partition.target_path};
if (!Subprocess::Get().Exec(
command,
base::Bind(
@@ -127,11 +131,13 @@
void PostinstallRunnerAction::CompletePartitionPostinstall(
int return_code,
const string& output) {
- utils::UnmountFilesystem(temp_rootfs_dir_);
- if (!base::DeleteFile(base::FilePath(temp_rootfs_dir_), false)) {
- PLOG(WARNING) << "Not removing mountpoint " << temp_rootfs_dir_;
+ utils::UnmountFilesystem(fs_mount_dir_);
+#ifndef ANDROID
+ if (!base::DeleteFile(base::FilePath(fs_mount_dir_), false)) {
+ PLOG(WARNING) << "Not removing temporary mountpoint " << fs_mount_dir_;
}
- temp_rootfs_dir_.clear();
+#endif // !ANDROID
+ fs_mount_dir_.clear();
if (return_code != 0) {
LOG(ERROR) << "Postinst command failed with code: " << return_code;
diff --git a/payload_consumer/postinstall_runner_action.h b/payload_consumer/postinstall_runner_action.h
index ab267b8..b4defae 100644
--- a/payload_consumer/postinstall_runner_action.h
+++ b/payload_consumer/postinstall_runner_action.h
@@ -63,7 +63,9 @@
void CompletePostinstall(ErrorCode error_code);
InstallPlan install_plan_;
- std::string temp_rootfs_dir_;
+
+ // The path where the filesystem will be mounted during post-install.
+ std::string fs_mount_dir_;
// The partition being processed on the list of partitions specified in the
// InstallPlan.
diff --git a/payload_consumer/postinstall_runner_action_unittest.cc b/payload_consumer/postinstall_runner_action_unittest.cc
index beed4f1..85535d7 100644
--- a/payload_consumer/postinstall_runner_action_unittest.cc
+++ b/payload_consumer/postinstall_runner_action_unittest.cc
@@ -121,8 +121,8 @@
bool do_losetup,
int err_code,
bool powerwash_required) {
- ASSERT_EQ(0, getuid()) << "Run me as root. Ideally don't run other tests "
- << "as root, tho.";
+ ASSERT_EQ(0U, getuid()) << "Run me as root. Ideally don't run other tests "
+ << "as root, tho.";
// True if the post-install action is expected to succeed.
bool should_succeed = do_losetup && !err_code;
@@ -191,6 +191,7 @@
part.name = "part";
part.target_path = dev;
part.run_postinstall = true;
+ part.postinstall_path = kPostinstallDefaultScript;
InstallPlan install_plan;
install_plan.partitions = {part};
install_plan.download_url = "http://devserver:8080/update";
@@ -215,7 +216,7 @@
EXPECT_TRUE(delegate.code_set_);
EXPECT_EQ(should_succeed, delegate.code_ == ErrorCode::kSuccess);
if (should_succeed)
- EXPECT_TRUE(install_plan == collector_action.object());
+ EXPECT_EQ(install_plan, collector_action.object());
const base::FilePath kPowerwashMarkerPath(powerwash_marker_file);
string actual_cmd;
@@ -251,7 +252,7 @@
// Death tests don't seem to be working on Hardy
TEST_F(PostinstallRunnerActionTest, DISABLED_RunAsRootDeathTest) {
- ASSERT_EQ(0, getuid());
+ ASSERT_EQ(0U, getuid());
PostinstallRunnerAction runner_action(&fake_boot_control_);
ASSERT_DEATH({ runner_action.TerminateProcessing(); },
"postinstall_runner_action.h:.*] Check failed");
diff --git a/payload_generator/ab_generator_unittest.cc b/payload_generator/ab_generator_unittest.cc
index 632fc64..60bdf26 100644
--- a/payload_generator/ab_generator_unittest.cc
+++ b/payload_generator/ab_generator_unittest.cc
@@ -21,6 +21,7 @@
#include <sys/types.h>
#include <string>
+#include <random>
#include <vector>
#include <gtest/gtest.h>
@@ -128,7 +129,7 @@
InstallOperation_Type expected_type =
compressible ? InstallOperation::REPLACE_BZ : InstallOperation::REPLACE;
- ASSERT_EQ(2, result_ops.size());
+ ASSERT_EQ(2U, result_ops.size());
EXPECT_EQ("SplitTestOp:0", result_ops[0].name);
InstallOperation first_op = result_ops[0].op;
@@ -156,7 +157,7 @@
first_op.data_length(),
first_op.data_offset(),
&bytes_read));
- ASSERT_EQ(bytes_read, first_op.data_length());
+ ASSERT_EQ(bytes_read, static_cast<ssize_t>(first_op.data_length()));
EXPECT_EQ(first_expected_blob, first_data_blob);
EXPECT_EQ("SplitTestOp:1", result_ops[1].name);
@@ -184,7 +185,7 @@
second_op.data_length(),
second_op.data_offset(),
&bytes_read));
- ASSERT_EQ(bytes_read, second_op.data_length());
+ ASSERT_EQ(bytes_read, static_cast<ssize_t>(second_op.data_length()));
EXPECT_EQ(second_expected_blob, second_data_blob);
// Check relative layout of data blobs.
@@ -193,7 +194,7 @@
EXPECT_EQ(second_op.data_offset() + second_op.data_length(), data_file_size);
// If we split a REPLACE into multiple ones, ensure reuse of preexisting blob.
if (!compressible && orig_type == InstallOperation::REPLACE) {
- EXPECT_EQ(0, first_op.data_offset());
+ EXPECT_EQ(0U, first_op.data_offset());
}
}
@@ -293,7 +294,7 @@
// Check the result.
InstallOperation_Type expected_op_type =
compressible ? InstallOperation::REPLACE_BZ : InstallOperation::REPLACE;
- EXPECT_EQ(1, aops.size());
+ EXPECT_EQ(1U, aops.size());
InstallOperation new_op = aops[0].op;
EXPECT_EQ(expected_op_type, new_op.type());
EXPECT_FALSE(new_op.has_src_length());
@@ -312,7 +313,8 @@
expected_blob = expected_data;
}
ASSERT_EQ(expected_blob.size(), new_op.data_length());
- ASSERT_EQ(blob_data.size() + expected_blob.size(), data_file_size);
+ ASSERT_EQ(blob_data.size() + expected_blob.size(),
+ static_cast<size_t>(data_file_size));
brillo::Blob new_op_blob(new_op.data_length());
ssize_t bytes_read;
ASSERT_TRUE(utils::PReadAll(data_fd,
@@ -320,7 +322,7 @@
new_op.data_length(),
new_op.data_offset(),
&bytes_read));
- ASSERT_EQ(new_op.data_length(), bytes_read);
+ ASSERT_EQ(static_cast<ssize_t>(new_op.data_length()), bytes_read);
EXPECT_EQ(expected_blob, new_op_blob);
}
@@ -343,47 +345,47 @@
aop.name = "SplitSourceCopyTestOp";
vector<AnnotatedOperation> result_ops;
EXPECT_TRUE(ABGenerator::SplitSourceCopy(aop, &result_ops));
- EXPECT_EQ(result_ops.size(), 3);
+ EXPECT_EQ(3U, result_ops.size());
EXPECT_EQ("SplitSourceCopyTestOp:0", result_ops[0].name);
InstallOperation first_op = result_ops[0].op;
EXPECT_EQ(InstallOperation::SOURCE_COPY, first_op.type());
EXPECT_EQ(kBlockSize * 2, first_op.src_length());
EXPECT_EQ(1, first_op.src_extents().size());
- EXPECT_EQ(2, first_op.src_extents(0).start_block());
- EXPECT_EQ(2, first_op.src_extents(0).num_blocks());
+ EXPECT_EQ(2U, first_op.src_extents(0).start_block());
+ EXPECT_EQ(2U, first_op.src_extents(0).num_blocks());
EXPECT_EQ(kBlockSize * 2, first_op.dst_length());
EXPECT_EQ(1, first_op.dst_extents().size());
- EXPECT_EQ(10, first_op.dst_extents(0).start_block());
- EXPECT_EQ(2, first_op.dst_extents(0).num_blocks());
+ EXPECT_EQ(10U, first_op.dst_extents(0).start_block());
+ EXPECT_EQ(2U, first_op.dst_extents(0).num_blocks());
EXPECT_EQ("SplitSourceCopyTestOp:1", result_ops[1].name);
InstallOperation second_op = result_ops[1].op;
EXPECT_EQ(InstallOperation::SOURCE_COPY, second_op.type());
EXPECT_EQ(kBlockSize * 3, second_op.src_length());
EXPECT_EQ(3, second_op.src_extents().size());
- EXPECT_EQ(4, second_op.src_extents(0).start_block());
- EXPECT_EQ(1, second_op.src_extents(0).num_blocks());
- EXPECT_EQ(6, second_op.src_extents(1).start_block());
- EXPECT_EQ(1, second_op.src_extents(1).num_blocks());
- EXPECT_EQ(8, second_op.src_extents(2).start_block());
- EXPECT_EQ(1, second_op.src_extents(2).num_blocks());
+ EXPECT_EQ(4U, second_op.src_extents(0).start_block());
+ EXPECT_EQ(1U, second_op.src_extents(0).num_blocks());
+ EXPECT_EQ(6U, second_op.src_extents(1).start_block());
+ EXPECT_EQ(1U, second_op.src_extents(1).num_blocks());
+ EXPECT_EQ(8U, second_op.src_extents(2).start_block());
+ EXPECT_EQ(1U, second_op.src_extents(2).num_blocks());
EXPECT_EQ(kBlockSize * 3, second_op.dst_length());
EXPECT_EQ(1, second_op.dst_extents().size());
- EXPECT_EQ(14, second_op.dst_extents(0).start_block());
- EXPECT_EQ(3, second_op.dst_extents(0).num_blocks());
+ EXPECT_EQ(14U, second_op.dst_extents(0).start_block());
+ EXPECT_EQ(3U, second_op.dst_extents(0).num_blocks());
EXPECT_EQ("SplitSourceCopyTestOp:2", result_ops[2].name);
InstallOperation third_op = result_ops[2].op;
EXPECT_EQ(InstallOperation::SOURCE_COPY, third_op.type());
EXPECT_EQ(kBlockSize * 3, third_op.src_length());
EXPECT_EQ(1, third_op.src_extents().size());
- EXPECT_EQ(9, third_op.src_extents(0).start_block());
- EXPECT_EQ(3, third_op.src_extents(0).num_blocks());
+ EXPECT_EQ(9U, third_op.src_extents(0).start_block());
+ EXPECT_EQ(3U, third_op.src_extents(0).num_blocks());
EXPECT_EQ(kBlockSize * 3, third_op.dst_length());
EXPECT_EQ(1, third_op.dst_extents().size());
- EXPECT_EQ(18, third_op.dst_extents(0).start_block());
- EXPECT_EQ(3, third_op.dst_extents(0).num_blocks());
+ EXPECT_EQ(18U, third_op.dst_extents(0).start_block());
+ EXPECT_EQ(3U, third_op.dst_extents(0).num_blocks());
}
TEST_F(ABGeneratorTest, SplitReplaceTest) {
@@ -429,7 +431,7 @@
aops.push_back(third_aop);
ABGenerator::SortOperationsByDestination(&aops);
- EXPECT_EQ(aops.size(), 3);
+ EXPECT_EQ(3U, aops.size());
EXPECT_EQ(third_aop.name, aops[0].name);
EXPECT_EQ(first_aop.name, aops[1].name);
EXPECT_EQ(second_aop.name, aops[2].name);
@@ -475,7 +477,7 @@
BlobFileWriter blob_file(0, nullptr);
EXPECT_TRUE(ABGenerator::MergeOperations(&aops, 5, "", &blob_file));
- EXPECT_EQ(aops.size(), 1);
+ EXPECT_EQ(1U, aops.size());
InstallOperation first_result_op = aops[0].op;
EXPECT_EQ(InstallOperation::SOURCE_COPY, first_result_op.type());
EXPECT_EQ(kBlockSize * 5, first_result_op.src_length());
@@ -548,7 +550,7 @@
EXPECT_TRUE(ABGenerator::MergeOperations(&aops, 4, "", &blob_file));
// No operations were merged, the number of ops is the same.
- EXPECT_EQ(aops.size(), 4);
+ EXPECT_EQ(4U, aops.size());
}
TEST_F(ABGeneratorTest, AddSourceHashTest) {
diff --git a/payload_generator/block_mapping_unittest.cc b/payload_generator/block_mapping_unittest.cc
index 18e48c4..4d09710 100644
--- a/payload_generator/block_mapping_unittest.cc
+++ b/payload_generator/block_mapping_unittest.cc
@@ -97,7 +97,7 @@
EXPECT_FALSE(ublock.block_data.empty());
// The block was loaded from disk only 4 times, and after that the counter
// is not updated anymore.
- EXPECT_EQ(4, ublock.times_read);
+ EXPECT_EQ(4U, ublock.times_read);
}
}
}
diff --git a/payload_generator/cycle_breaker_unittest.cc b/payload_generator/cycle_breaker_unittest.cc
index 4053cf3..e92bc30 100644
--- a/payload_generator/cycle_breaker_unittest.cc
+++ b/payload_generator/cycle_breaker_unittest.cc
@@ -91,7 +91,7 @@
utils::SetContainsKey(broken_edges, make_pair(n_e, n_c)));
EXPECT_TRUE(utils::SetContainsKey(broken_edges, make_pair(n_g, n_h)) ||
utils::SetContainsKey(broken_edges, make_pair(n_h, n_g)));
- EXPECT_EQ(3, broken_edges.size());
+ EXPECT_EQ(3U, broken_edges.size());
}
namespace {
@@ -127,7 +127,7 @@
// the algorithm to cut cycles (t) instead, since they are closer to the
// root, and that can massively speed up cycle cutting.
TEST(CycleBreakerTest, AggressiveCutTest) {
- int counter = 0;
+ size_t counter = 0;
const int kNodesPerGroup = 4;
const int kGroups = 33;
@@ -176,7 +176,7 @@
}
TEST(CycleBreakerTest, WeightTest) {
- int counter = 0;
+ size_t counter = 0;
const Vertex::Index n_a = counter++;
const Vertex::Index n_b = counter++;
const Vertex::Index n_c = counter++;
@@ -225,7 +225,7 @@
}
TEST(CycleBreakerTest, UnblockGraphTest) {
- int counter = 0;
+ size_t counter = 0;
const Vertex::Index n_a = counter++;
const Vertex::Index n_b = counter++;
const Vertex::Index n_c = counter++;
@@ -253,7 +253,7 @@
}
TEST(CycleBreakerTest, SkipOpsTest) {
- int counter = 0;
+ size_t counter = 0;
const Vertex::Index n_a = counter++;
const Vertex::Index n_b = counter++;
const Vertex::Index n_c = counter++;
@@ -272,7 +272,7 @@
set<Edge> broken_edges;
breaker.BreakCycles(graph, &broken_edges);
- EXPECT_EQ(2, breaker.skipped_ops());
+ EXPECT_EQ(2U, breaker.skipped_ops());
}
} // namespace chromeos_update_engine
diff --git a/payload_generator/delta_diff_utils_unittest.cc b/payload_generator/delta_diff_utils_unittest.cc
index 4dc5981..72349d8 100644
--- a/payload_generator/delta_diff_utils_unittest.cc
+++ b/payload_generator/delta_diff_utils_unittest.cc
@@ -17,6 +17,7 @@
#include "update_engine/payload_generator/delta_diff_utils.h"
#include <algorithm>
+#include <random>
#include <string>
#include <vector>
@@ -193,7 +194,7 @@
EXPECT_EQ(kBlockSize, op.dst_length());
EXPECT_EQ(BlocksInExtents(op.src_extents()),
BlocksInExtents(op.dst_extents()));
- EXPECT_EQ(1, BlocksInExtents(op.dst_extents()));
+ EXPECT_EQ(1U, BlocksInExtents(op.dst_extents()));
}
TEST_F(DeltaDiffUtilsTest, MoveWithSameBlock) {
@@ -263,7 +264,7 @@
EXPECT_EQ(num_blocks * kBlockSize, op.src_length());
EXPECT_EQ(num_blocks * kBlockSize, op.dst_length());
- EXPECT_EQ(old_extents.size(), op.src_extents_size());
+ EXPECT_EQ(old_extents.size(), static_cast<size_t>(op.src_extents_size()));
for (int i = 0; i < op.src_extents_size(); i++) {
EXPECT_EQ(old_extents[i].start_block(), op.src_extents(i).start_block())
<< "i == " << i;
@@ -271,7 +272,7 @@
<< "i == " << i;
}
- EXPECT_EQ(new_extents.size(), op.dst_extents_size());
+ EXPECT_EQ(new_extents.size(), static_cast<size_t>(op.dst_extents_size()));
for (int i = 0; i < op.dst_extents_size(); i++) {
EXPECT_EQ(new_extents[i].start_block(), op.dst_extents(i).start_block())
<< "i == " << i;
@@ -318,7 +319,7 @@
EXPECT_EQ(kBlockSize, op.dst_length());
EXPECT_EQ(BlocksInExtents(op.src_extents()),
BlocksInExtents(op.dst_extents()));
- EXPECT_EQ(1, BlocksInExtents(op.dst_extents()));
+ EXPECT_EQ(1U, BlocksInExtents(op.dst_extents()));
}
TEST_F(DeltaDiffUtilsTest, BsdiffNotAllowedTest) {
@@ -432,7 +433,7 @@
EXPECT_FALSE(op.has_src_length());
EXPECT_EQ(1, op.dst_extents_size());
EXPECT_EQ(data_to_test.size(), op.dst_length());
- EXPECT_EQ(1, BlocksInExtents(op.dst_extents()));
+ EXPECT_EQ(1U, BlocksInExtents(op.dst_extents()));
}
}
@@ -552,8 +553,8 @@
EXPECT_TRUE(RunDeltaMovedAndZeroBlocks(-1, // chunk_blocks
false)); // src_ops_allowed
- EXPECT_EQ(0, old_visited_blocks_.blocks());
- EXPECT_EQ(0, new_visited_blocks_.blocks());
+ EXPECT_EQ(0U, old_visited_blocks_.blocks());
+ EXPECT_EQ(0U, new_visited_blocks_.blocks());
EXPECT_EQ(0, blob_size_);
EXPECT_TRUE(aops_.empty());
}
@@ -662,7 +663,7 @@
// source extents should cover only the first copy of the source file since
// we prefer to re-read files (maybe cached) instead of continue reading the
// rest of the partition.
- EXPECT_EQ(1, aops_.size());
+ EXPECT_EQ(1U, aops_.size());
const AnnotatedOperation& aop = aops_[0];
EXPECT_EQ(InstallOperation::SOURCE_COPY, aop.op.type());
EXPECT_EQ(5, aop.op.src_extents_size());
@@ -759,7 +760,7 @@
EXPECT_EQ(permutation.size(), new_visited_blocks_.blocks());
// There should be only one SOURCE_COPY, with a complicate list of extents.
- EXPECT_EQ(1, aops_.size());
+ EXPECT_EQ(1U, aops_.size());
const AnnotatedOperation& aop = aops_[0];
EXPECT_EQ(InstallOperation::SOURCE_COPY, aop.op.type());
vector<Extent> aop_src_extents;
diff --git a/payload_generator/ext2_filesystem_unittest.cc b/payload_generator/ext2_filesystem_unittest.cc
index df8b98f..f7d25da 100644
--- a/payload_generator/ext2_filesystem_unittest.cc
+++ b/payload_generator/ext2_filesystem_unittest.cc
@@ -34,7 +34,6 @@
#include "update_engine/common/utils.h"
#include "update_engine/payload_generator/extent_utils.h"
-using chromeos_update_engine::test_utils::System;
using std::map;
using std::set;
using std::string;
@@ -52,31 +51,20 @@
// Checks that all the blocks in |extents| are in the range [0, total_blocks).
void ExpectBlocksInRange(const vector<Extent>& extents, uint64_t total_blocks) {
for (const Extent& extent : extents) {
- EXPECT_LE(0, extent.start_block());
+ EXPECT_LE(0U, extent.start_block());
EXPECT_LE(extent.start_block() + extent.num_blocks(), total_blocks);
}
}
} // namespace
-
-class Ext2FilesystemTest : public ::testing::Test {
- protected:
- void SetUp() override {
- ASSERT_TRUE(utils::MakeTempFile("Ext2FilesystemTest-XXXXXX",
- &fs_filename_, nullptr));
- ASSERT_EQ(0, truncate(fs_filename_.c_str(), kDefaultFilesystemSize));
- }
-
- void TearDown() override {
- unlink(fs_filename_.c_str());
- }
-
- string fs_filename_;
-};
+class Ext2FilesystemTest : public ::testing::Test {};
TEST_F(Ext2FilesystemTest, InvalidFilesystem) {
- unique_ptr<Ext2Filesystem> fs = Ext2Filesystem::CreateFromFile(fs_filename_);
+ test_utils::ScopedTempFile fs_filename_{"Ext2FilesystemTest-XXXXXX"};
+ ASSERT_EQ(0, truncate(fs_filename_.path().c_str(), kDefaultFilesystemSize));
+ unique_ptr<Ext2Filesystem> fs =
+ Ext2Filesystem::CreateFromFile(fs_filename_.path());
ASSERT_EQ(nullptr, fs.get());
fs = Ext2Filesystem::CreateFromFile("/path/to/invalid/file");
@@ -84,10 +72,9 @@
}
TEST_F(Ext2FilesystemTest, EmptyFilesystem) {
- EXPECT_EQ(0, System(base::StringPrintf(
- "/sbin/mkfs.ext2 -q -b %" PRIuS " -F %s",
- kDefaultFilesystemBlockSize, fs_filename_.c_str())));
- unique_ptr<Ext2Filesystem> fs = Ext2Filesystem::CreateFromFile(fs_filename_);
+ base::FilePath path =
+ test_utils::GetBuildArtifactsPath().Append("gen/disk_ext2_4k_empty.img");
+ unique_ptr<Ext2Filesystem> fs = Ext2Filesystem::CreateFromFile(path.value());
ASSERT_NE(nullptr, fs.get());
EXPECT_EQ(kDefaultFilesystemBlockCount, fs->GetBlockCount());
@@ -103,7 +90,7 @@
map_files[file.name] = file;
ExpectBlocksInRange(file.extents, fs->GetBlockCount());
}
- EXPECT_EQ(2, map_files["/"].file_stat.st_ino);
+ EXPECT_EQ(2U, map_files["/"].file_stat.st_ino);
EXPECT_FALSE(map_files["<free-space>"].extents.empty());
}
@@ -169,7 +156,7 @@
// Small symlinks don't actually have data blocks.
EXPECT_TRUE(map_files["/link-short_symlink"].extents.empty());
- EXPECT_EQ(1, BlocksInExtents(map_files["/link-long_symlink"].extents));
+ EXPECT_EQ(1U, BlocksInExtents(map_files["/link-long_symlink"].extents));
// Hard-links report the same list of blocks.
EXPECT_EQ(map_files["/link-hard-regular-16k"].extents,
@@ -179,13 +166,14 @@
// The number of blocks in these files doesn't depend on the
// block size.
EXPECT_TRUE(map_files["/empty-file"].extents.empty());
- EXPECT_EQ(1, BlocksInExtents(map_files["/regular-small"].extents));
- EXPECT_EQ(1, BlocksInExtents(map_files["/regular-with_net_cap"].extents));
+ EXPECT_EQ(1U, BlocksInExtents(map_files["/regular-small"].extents));
+ EXPECT_EQ(1U, BlocksInExtents(map_files["/regular-with_net_cap"].extents));
EXPECT_TRUE(map_files["/sparse_empty-10k"].extents.empty());
EXPECT_TRUE(map_files["/sparse_empty-2blocks"].extents.empty());
- EXPECT_EQ(1, BlocksInExtents(map_files["/sparse-16k-last_block"].extents));
- EXPECT_EQ(1, BlocksInExtents(map_files["/sparse-16k-first_block"].extents));
- EXPECT_EQ(2, BlocksInExtents(map_files["/sparse-16k-holes"].extents));
+ EXPECT_EQ(1U, BlocksInExtents(map_files["/sparse-16k-last_block"].extents));
+ EXPECT_EQ(1U,
+ BlocksInExtents(map_files["/sparse-16k-first_block"].extents));
+ EXPECT_EQ(2U, BlocksInExtents(map_files["/sparse-16k-holes"].extents));
}
}
@@ -193,6 +181,7 @@
base::FilePath path = test_utils::GetBuildArtifactsPath().Append(
"gen/disk_ext2_1k.img");
unique_ptr<Ext2Filesystem> fs = Ext2Filesystem::CreateFromFile(path.value());
+ ASSERT_NE(nullptr, fs.get());
brillo::KeyValueStore store;
// disk_ext2_1k.img doesn't have the /etc/update_engine.conf file.
@@ -203,6 +192,7 @@
base::FilePath path = test_utils::GetBuildArtifactsPath().Append(
"gen/disk_ext2_ue_settings.img");
unique_ptr<Ext2Filesystem> fs = Ext2Filesystem::CreateFromFile(path.value());
+ ASSERT_NE(nullptr, fs.get());
brillo::KeyValueStore store;
EXPECT_TRUE(fs->LoadSettings(&store));
diff --git a/payload_generator/extent_ranges_unittest.cc b/payload_generator/extent_ranges_unittest.cc
index 8b39040..3705bac 100644
--- a/payload_generator/extent_ranges_unittest.cc
+++ b/payload_generator/extent_ranges_unittest.cc
@@ -250,7 +250,7 @@
ranges.SubtractExtents(vector<Extent>(1, ExtentForRange(20, 10)));
*rep_field.Mutable(0) = ExtentForRange(50, 10);
ranges.SubtractRepeatedExtents(rep_field);
- EXPECT_EQ(40, ranges.blocks());
+ EXPECT_EQ(40U, ranges.blocks());
for (int i = 0; i < 2; i++) {
vector<Extent> expected(2);
diff --git a/payload_generator/extent_utils_unittest.cc b/payload_generator/extent_utils_unittest.cc
index 62c8ff1..d470e7b 100644
--- a/payload_generator/extent_utils_unittest.cc
+++ b/payload_generator/extent_utils_unittest.cc
@@ -34,43 +34,43 @@
TEST(ExtentUtilsTest, AppendSparseToExtentsTest) {
vector<Extent> extents;
- EXPECT_EQ(0, extents.size());
+ EXPECT_EQ(0U, extents.size());
AppendBlockToExtents(&extents, kSparseHole);
- EXPECT_EQ(1, extents.size());
+ EXPECT_EQ(1U, extents.size());
AppendBlockToExtents(&extents, 0);
- EXPECT_EQ(2, extents.size());
+ EXPECT_EQ(2U, extents.size());
AppendBlockToExtents(&extents, kSparseHole);
AppendBlockToExtents(&extents, kSparseHole);
- ASSERT_EQ(3, extents.size());
+ ASSERT_EQ(3U, extents.size());
EXPECT_EQ(kSparseHole, extents[0].start_block());
- EXPECT_EQ(1, extents[0].num_blocks());
- EXPECT_EQ(0, extents[1].start_block());
- EXPECT_EQ(1, extents[1].num_blocks());
+ EXPECT_EQ(1U, extents[0].num_blocks());
+ EXPECT_EQ(0U, extents[1].start_block());
+ EXPECT_EQ(1U, extents[1].num_blocks());
EXPECT_EQ(kSparseHole, extents[2].start_block());
- EXPECT_EQ(2, extents[2].num_blocks());
+ EXPECT_EQ(2U, extents[2].num_blocks());
}
TEST(ExtentUtilsTest, BlocksInExtentsTest) {
{
vector<Extent> extents;
- EXPECT_EQ(0, BlocksInExtents(extents));
+ EXPECT_EQ(0U, BlocksInExtents(extents));
extents.push_back(ExtentForRange(0, 1));
- EXPECT_EQ(1, BlocksInExtents(extents));
+ EXPECT_EQ(1U, BlocksInExtents(extents));
extents.push_back(ExtentForRange(23, 55));
- EXPECT_EQ(56, BlocksInExtents(extents));
+ EXPECT_EQ(56U, BlocksInExtents(extents));
extents.push_back(ExtentForRange(1, 2));
- EXPECT_EQ(58, BlocksInExtents(extents));
+ EXPECT_EQ(58U, BlocksInExtents(extents));
}
{
google::protobuf::RepeatedPtrField<Extent> extents;
- EXPECT_EQ(0, BlocksInExtents(extents));
+ EXPECT_EQ(0U, BlocksInExtents(extents));
*extents.Add() = ExtentForRange(0, 1);
- EXPECT_EQ(1, BlocksInExtents(extents));
+ EXPECT_EQ(1U, BlocksInExtents(extents));
*extents.Add() = ExtentForRange(23, 55);
- EXPECT_EQ(56, BlocksInExtents(extents));
+ EXPECT_EQ(56U, BlocksInExtents(extents));
*extents.Add() = ExtentForRange(1, 2);
- EXPECT_EQ(58, BlocksInExtents(extents));
+ EXPECT_EQ(58U, BlocksInExtents(extents));
}
}
@@ -96,11 +96,11 @@
// Make sure it works when there's just one extent.
vector<Extent> extents;
NormalizeExtents(&extents);
- EXPECT_EQ(0, extents.size());
+ EXPECT_EQ(0U, extents.size());
extents = { ExtentForRange(0, 3) };
NormalizeExtents(&extents);
- EXPECT_EQ(1, extents.size());
+ EXPECT_EQ(1U, extents.size());
EXPECT_EQ(ExtentForRange(0, 3), extents[0]);
}
@@ -114,7 +114,7 @@
ExtentForRange(14, 2)
};
NormalizeExtents(&extents);
- EXPECT_EQ(3, extents.size());
+ EXPECT_EQ(3U, extents.size());
EXPECT_EQ(ExtentForRange(0, 6), extents[0]);
EXPECT_EQ(ExtentForRange(8, 4), extents[1]);
EXPECT_EQ(ExtentForRange(13, 3), extents[2]);
diff --git a/payload_generator/fake_filesystem.cc b/payload_generator/fake_filesystem.cc
index 3a6458d..c765286 100644
--- a/payload_generator/fake_filesystem.cc
+++ b/payload_generator/fake_filesystem.cc
@@ -44,7 +44,7 @@
file.name = filename;
file.extents = extents;
for (const Extent& extent : extents) {
- EXPECT_LE(0, extent.start_block());
+ EXPECT_LE(0U, extent.start_block());
EXPECT_LE(extent.start_block() + extent.num_blocks(), block_count_);
}
files_.push_back(file);
diff --git a/payload_generator/full_update_generator_unittest.cc b/payload_generator/full_update_generator_unittest.cc
index d46346d..d5af9d0 100644
--- a/payload_generator/full_update_generator_unittest.cc
+++ b/payload_generator/full_update_generator_unittest.cc
@@ -83,10 +83,10 @@
blob_file_.get(),
&aops));
int64_t new_part_chunks = new_part_conf.size / config_.hard_chunk_size;
- EXPECT_EQ(new_part_chunks, aops.size());
+ EXPECT_EQ(new_part_chunks, static_cast<int64_t>(aops.size()));
for (off_t i = 0; i < new_part_chunks; ++i) {
EXPECT_EQ(1, aops[i].op.dst_extents_size());
- EXPECT_EQ(i * config_.hard_chunk_size / config_.block_size,
+ EXPECT_EQ(static_cast<uint64_t>(i * config_.hard_chunk_size / config_.block_size),
aops[i].op.dst_extents(0).start_block()) << "i = " << i;
EXPECT_EQ(config_.hard_chunk_size / config_.block_size,
aops[i].op.dst_extents(0).num_blocks());
@@ -112,7 +112,7 @@
blob_file_.get(),
&aops));
// new_part has one chunk and a half.
- EXPECT_EQ(2, aops.size());
+ EXPECT_EQ(2U, aops.size());
EXPECT_EQ(config_.hard_chunk_size / config_.block_size,
BlocksInExtents(aops[0].op.dst_extents()));
EXPECT_EQ((new_part.size() - config_.hard_chunk_size) / config_.block_size,
@@ -134,7 +134,7 @@
&aops));
// new_part has less than one chunk.
- EXPECT_EQ(1, aops.size());
+ EXPECT_EQ(1U, aops.size());
EXPECT_EQ(new_part.size() / config_.block_size,
BlocksInExtents(aops[0].op.dst_extents()));
}
diff --git a/payload_generator/graph_utils_unittest.cc b/payload_generator/graph_utils_unittest.cc
index 7d3dbe3..dddf815 100644
--- a/payload_generator/graph_utils_unittest.cc
+++ b/payload_generator/graph_utils_unittest.cc
@@ -39,21 +39,21 @@
vector<Extent>& extents = graph[0].out_edges[1].extents;
- EXPECT_EQ(0, extents.size());
+ EXPECT_EQ(0U, extents.size());
AppendBlockToExtents(&extents, 0);
- EXPECT_EQ(1, extents.size());
+ EXPECT_EQ(1U, extents.size());
AppendBlockToExtents(&extents, 1);
AppendBlockToExtents(&extents, 2);
- EXPECT_EQ(1, extents.size());
+ EXPECT_EQ(1U, extents.size());
AppendBlockToExtents(&extents, 4);
- EXPECT_EQ(2, extents.size());
- EXPECT_EQ(0, extents[0].start_block());
- EXPECT_EQ(3, extents[0].num_blocks());
- EXPECT_EQ(4, extents[1].start_block());
- EXPECT_EQ(1, extents[1].num_blocks());
+ EXPECT_EQ(2U, extents.size());
+ EXPECT_EQ(0U, extents[0].start_block());
+ EXPECT_EQ(3U, extents[0].num_blocks());
+ EXPECT_EQ(4U, extents[1].start_block());
+ EXPECT_EQ(1U, extents[1].num_blocks());
- EXPECT_EQ(4, graph_utils::EdgeWeight(graph, make_pair(0, 1)));
+ EXPECT_EQ(4U, graph_utils::EdgeWeight(graph, make_pair(0, 1)));
}
@@ -61,35 +61,35 @@
Graph graph(3);
graph_utils::AddReadBeforeDep(&graph[0], 1, 3);
- EXPECT_EQ(1, graph[0].out_edges.size());
+ EXPECT_EQ(1U, graph[0].out_edges.size());
{
Extent& extent = graph[0].out_edges[1].extents[0];
- EXPECT_EQ(3, extent.start_block());
- EXPECT_EQ(1, extent.num_blocks());
+ EXPECT_EQ(3U, extent.start_block());
+ EXPECT_EQ(1U, extent.num_blocks());
}
graph_utils::AddReadBeforeDep(&graph[0], 1, 4);
- EXPECT_EQ(1, graph[0].out_edges.size());
+ EXPECT_EQ(1U, graph[0].out_edges.size());
{
Extent& extent = graph[0].out_edges[1].extents[0];
- EXPECT_EQ(3, extent.start_block());
- EXPECT_EQ(2, extent.num_blocks());
+ EXPECT_EQ(3U, extent.start_block());
+ EXPECT_EQ(2U, extent.num_blocks());
}
graph_utils::AddReadBeforeDepExtents(&graph[2], 1,
vector<Extent>(1, ExtentForRange(5, 2)));
- EXPECT_EQ(1, graph[2].out_edges.size());
+ EXPECT_EQ(1U, graph[2].out_edges.size());
{
Extent& extent = graph[2].out_edges[1].extents[0];
- EXPECT_EQ(5, extent.start_block());
- EXPECT_EQ(2, extent.num_blocks());
+ EXPECT_EQ(5U, extent.start_block());
+ EXPECT_EQ(2U, extent.num_blocks());
}
// Change most recent edge from read-before to write-before
graph[2].out_edges[1].write_extents.swap(graph[2].out_edges[1].extents);
graph_utils::DropWriteBeforeDeps(&graph[2].out_edges);
- EXPECT_EQ(0, graph[2].out_edges.size());
+ EXPECT_EQ(0U, graph[2].out_edges.size());
- EXPECT_EQ(1, graph[0].out_edges.size());
+ EXPECT_EQ(1U, graph[0].out_edges.size());
graph_utils::DropIncomingEdgesTo(&graph, 1);
- EXPECT_EQ(0, graph[0].out_edges.size());
+ EXPECT_EQ(0U, graph[0].out_edges.size());
}
} // namespace chromeos_update_engine
diff --git a/payload_generator/inplace_generator_unittest.cc b/payload_generator/inplace_generator_unittest.cc
index 9932ef9..cde4bfc 100644
--- a/payload_generator/inplace_generator_unittest.cc
+++ b/payload_generator/inplace_generator_unittest.cc
@@ -153,20 +153,20 @@
InplaceGenerator::SubstituteBlocks(&vertex, remove_blocks, replace_blocks);
EXPECT_EQ(7, op.src_extents_size());
- EXPECT_EQ(11, op.src_extents(0).start_block());
- EXPECT_EQ(1, op.src_extents(0).num_blocks());
- EXPECT_EQ(13, op.src_extents(1).start_block());
- EXPECT_EQ(1, op.src_extents(1).num_blocks());
- EXPECT_EQ(6, op.src_extents(2).start_block());
- EXPECT_EQ(1, op.src_extents(2).num_blocks());
+ EXPECT_EQ(11U, op.src_extents(0).start_block());
+ EXPECT_EQ(1U, op.src_extents(0).num_blocks());
+ EXPECT_EQ(13U, op.src_extents(1).start_block());
+ EXPECT_EQ(1U, op.src_extents(1).num_blocks());
+ EXPECT_EQ(6U, op.src_extents(2).start_block());
+ EXPECT_EQ(1U, op.src_extents(2).num_blocks());
EXPECT_EQ(kSparseHole, op.src_extents(3).start_block());
- EXPECT_EQ(4, op.src_extents(3).num_blocks());
- EXPECT_EQ(10, op.src_extents(4).start_block());
- EXPECT_EQ(1, op.src_extents(4).num_blocks());
- EXPECT_EQ(14, op.src_extents(5).start_block());
- EXPECT_EQ(1, op.src_extents(5).num_blocks());
- EXPECT_EQ(8, op.src_extents(6).start_block());
- EXPECT_EQ(2, op.src_extents(6).num_blocks());
+ EXPECT_EQ(4U, op.src_extents(3).num_blocks());
+ EXPECT_EQ(10U, op.src_extents(4).start_block());
+ EXPECT_EQ(1U, op.src_extents(4).num_blocks());
+ EXPECT_EQ(14U, op.src_extents(5).start_block());
+ EXPECT_EQ(1U, op.src_extents(5).num_blocks());
+ EXPECT_EQ(8U, op.src_extents(6).start_block());
+ EXPECT_EQ(2U, op.src_extents(6).num_blocks());
}
TEST_F(InplaceGeneratorTest, CutEdgesTest) {
@@ -229,58 +229,58 @@
set<Edge> cut_edges;
cycle_breaker.BreakCycles(graph, &cut_edges);
- EXPECT_EQ(1, cut_edges.size());
+ EXPECT_EQ(1U, cut_edges.size());
EXPECT_TRUE(cut_edges.end() != cut_edges.find(
std::pair<Vertex::Index, Vertex::Index>(1, 0)));
vector<CutEdgeVertexes> cuts;
EXPECT_TRUE(InplaceGenerator::CutEdges(&graph, cut_edges, &cuts));
- EXPECT_EQ(3, graph.size());
+ EXPECT_EQ(3U, graph.size());
// Check new node in graph:
EXPECT_EQ(InstallOperation::MOVE, graph.back().aop.op.type());
EXPECT_EQ(2, graph.back().aop.op.src_extents_size());
EXPECT_EQ(1, graph.back().aop.op.dst_extents_size());
EXPECT_EQ(kTempBlockStart, graph.back().aop.op.dst_extents(0).start_block());
- EXPECT_EQ(2, graph.back().aop.op.dst_extents(0).num_blocks());
+ EXPECT_EQ(2U, graph.back().aop.op.dst_extents(0).num_blocks());
EXPECT_TRUE(graph.back().out_edges.empty());
// Check that old node reads from new blocks
EXPECT_EQ(2, graph[0].aop.op.src_extents_size());
EXPECT_EQ(kTempBlockStart, graph[0].aop.op.src_extents(0).start_block());
- EXPECT_EQ(2, graph[0].aop.op.src_extents(0).num_blocks());
- EXPECT_EQ(7, graph[0].aop.op.src_extents(1).start_block());
- EXPECT_EQ(1, graph[0].aop.op.src_extents(1).num_blocks());
+ EXPECT_EQ(2U, graph[0].aop.op.src_extents(0).num_blocks());
+ EXPECT_EQ(7U, graph[0].aop.op.src_extents(1).start_block());
+ EXPECT_EQ(1U, graph[0].aop.op.src_extents(1).num_blocks());
// And that the old dst extents haven't changed
EXPECT_EQ(2, graph[0].aop.op.dst_extents_size());
- EXPECT_EQ(1, graph[0].aop.op.dst_extents(0).start_block());
- EXPECT_EQ(2, graph[0].aop.op.dst_extents(0).num_blocks());
- EXPECT_EQ(4, graph[0].aop.op.dst_extents(1).start_block());
- EXPECT_EQ(1, graph[0].aop.op.dst_extents(1).num_blocks());
+ EXPECT_EQ(1U, graph[0].aop.op.dst_extents(0).start_block());
+ EXPECT_EQ(2U, graph[0].aop.op.dst_extents(0).num_blocks());
+ EXPECT_EQ(4U, graph[0].aop.op.dst_extents(1).start_block());
+ EXPECT_EQ(1U, graph[0].aop.op.dst_extents(1).num_blocks());
// Ensure it only depends on the next node and the new temp node
- EXPECT_EQ(2, graph[0].out_edges.size());
+ EXPECT_EQ(2U, graph[0].out_edges.size());
EXPECT_TRUE(graph[0].out_edges.end() != graph[0].out_edges.find(1));
EXPECT_TRUE(graph[0].out_edges.end() != graph[0].out_edges.find(graph.size() -
1));
// Check second node has unchanged extents
EXPECT_EQ(2, graph[1].aop.op.src_extents_size());
- EXPECT_EQ(1, graph[1].aop.op.src_extents(0).start_block());
- EXPECT_EQ(2, graph[1].aop.op.src_extents(0).num_blocks());
- EXPECT_EQ(4, graph[1].aop.op.src_extents(1).start_block());
- EXPECT_EQ(1, graph[1].aop.op.src_extents(1).num_blocks());
+ EXPECT_EQ(1U, graph[1].aop.op.src_extents(0).start_block());
+ EXPECT_EQ(2U, graph[1].aop.op.src_extents(0).num_blocks());
+ EXPECT_EQ(4U, graph[1].aop.op.src_extents(1).start_block());
+ EXPECT_EQ(1U, graph[1].aop.op.src_extents(1).num_blocks());
EXPECT_EQ(2, graph[1].aop.op.dst_extents_size());
- EXPECT_EQ(3, graph[1].aop.op.dst_extents(0).start_block());
- EXPECT_EQ(1, graph[1].aop.op.dst_extents(0).num_blocks());
- EXPECT_EQ(5, graph[1].aop.op.dst_extents(1).start_block());
- EXPECT_EQ(2, graph[1].aop.op.dst_extents(1).num_blocks());
+ EXPECT_EQ(3U, graph[1].aop.op.dst_extents(0).start_block());
+ EXPECT_EQ(1U, graph[1].aop.op.dst_extents(0).num_blocks());
+ EXPECT_EQ(5U, graph[1].aop.op.dst_extents(1).start_block());
+ EXPECT_EQ(2U, graph[1].aop.op.dst_extents(1).num_blocks());
// Ensure it only depends on the next node
- EXPECT_EQ(1, graph[1].out_edges.size());
+ EXPECT_EQ(1U, graph[1].out_edges.size());
EXPECT_TRUE(graph[1].out_edges.end() != graph[1].out_edges.find(2));
}
@@ -384,8 +384,8 @@
EXPECT_FALSE(graph[6].valid);
EXPECT_FALSE(graph[7].valid);
EXPECT_EQ(1, graph[1].aop.op.src_extents_size());
- EXPECT_EQ(2, graph[1].aop.op.src_extents(0).start_block());
- EXPECT_EQ(1, graph[1].aop.op.src_extents(0).num_blocks());
+ EXPECT_EQ(2U, graph[1].aop.op.src_extents(0).start_block());
+ EXPECT_EQ(1U, graph[1].aop.op.src_extents(0).num_blocks());
EXPECT_EQ(InstallOperation::REPLACE_BZ, graph[5].aop.op.type());
}
@@ -547,7 +547,7 @@
InstallOperation::MOVE);
expected_graph[10].out_edges[4] = EdgeWithReadDep(VectOfExt(60, 9));
- EXPECT_EQ(12, graph.size());
+ EXPECT_EQ(12U, graph.size());
EXPECT_FALSE(graph.back().valid);
for (Graph::size_type i = 0; i < graph.size() - 1; i++) {
EXPECT_TRUE(graph[i].out_edges == expected_graph[i].out_edges);
@@ -563,11 +563,11 @@
Vertex vertex;
InplaceGenerator::CreateScratchNode(12, 34, &vertex);
EXPECT_EQ(InstallOperation::REPLACE_BZ, vertex.aop.op.type());
- EXPECT_EQ(0, vertex.aop.op.data_offset());
- EXPECT_EQ(0, vertex.aop.op.data_length());
+ EXPECT_EQ(0U, vertex.aop.op.data_offset());
+ EXPECT_EQ(0U, vertex.aop.op.data_length());
EXPECT_EQ(1, vertex.aop.op.dst_extents_size());
- EXPECT_EQ(12, vertex.aop.op.dst_extents(0).start_block());
- EXPECT_EQ(34, vertex.aop.op.dst_extents(0).num_blocks());
+ EXPECT_EQ(12U, vertex.aop.op.dst_extents(0).start_block());
+ EXPECT_EQ(34U, vertex.aop.op.dst_extents(0).num_blocks());
}
TEST_F(InplaceGeneratorTest, ApplyMapTest) {
@@ -635,16 +635,18 @@
if (aop.op.type() != InstallOperation::MOVE)
continue;
for (const Extent& extent : aop.op.src_extents()) {
- EXPECT_NE(0, extent.start_block()) << "On src extents for aop: " << aop;
+ EXPECT_NE(0U, extent.start_block())
+ << "On src extents for aop: " << aop;
}
for (const Extent& extent : aop.op.dst_extents()) {
- EXPECT_NE(0, extent.start_block()) << "On dst extents for aop: " << aop;
+ EXPECT_NE(0U, extent.start_block())
+ << "On dst extents for aop: " << aop;
}
}
// If there's extra space in the partition, it should not use a new full
// operation for it.
- EXPECT_EQ(part_blocks == num_blocks ? 2 : 1, full_ops);
+ EXPECT_EQ(part_blocks == num_blocks ? 2U : 1U, full_ops);
if (HasNonfatalFailure()) {
LOG(INFO) << "Result operation list:";
diff --git a/payload_generator/payload_file_unittest.cc b/payload_generator/payload_file_unittest.cc
index 4d18adf..e8e7e14 100644
--- a/payload_generator/payload_file_unittest.cc
+++ b/payload_generator/payload_file_unittest.cc
@@ -80,15 +80,15 @@
// Kernel blobs should appear at the end.
EXPECT_EQ("bcdakernel", new_data);
- EXPECT_EQ(2, part0_aops.size());
- EXPECT_EQ(0, part0_aops[0].op.data_offset());
- EXPECT_EQ(3, part0_aops[0].op.data_length());
- EXPECT_EQ(3, part0_aops[1].op.data_offset());
- EXPECT_EQ(1, part0_aops[1].op.data_length());
+ EXPECT_EQ(2U, part0_aops.size());
+ EXPECT_EQ(0U, part0_aops[0].op.data_offset());
+ EXPECT_EQ(3U, part0_aops[0].op.data_length());
+ EXPECT_EQ(3U, part0_aops[1].op.data_offset());
+ EXPECT_EQ(1U, part0_aops[1].op.data_length());
- EXPECT_EQ(1, part1_aops.size());
- EXPECT_EQ(4, part1_aops[0].op.data_offset());
- EXPECT_EQ(6, part1_aops[0].op.data_length());
+ EXPECT_EQ(1U, part1_aops.size());
+ EXPECT_EQ(4U, part1_aops[0].op.data_offset());
+ EXPECT_EQ(6U, part1_aops[0].op.data_length());
}
} // namespace chromeos_update_engine
diff --git a/payload_generator/payload_signer_unittest.cc b/payload_generator/payload_signer_unittest.cc
index eadbc59..ebdd280 100644
--- a/payload_generator/payload_signer_unittest.cc
+++ b/payload_generator/payload_signer_unittest.cc
@@ -103,7 +103,7 @@
std::begin(kDataToSign) + strlen(kDataToSign));
uint64_t length = 0;
EXPECT_TRUE(PayloadSigner::SignatureBlobLength(private_keys, &length));
- EXPECT_GT(length, 0);
+ EXPECT_GT(length, 0U);
brillo::Blob hash_blob;
EXPECT_TRUE(HashCalculator::RawHashOfBytes(data_blob.data(),
data_blob.size(),
@@ -170,7 +170,7 @@
signature_blob.size()));
EXPECT_EQ(1, signatures.signatures_size());
const Signatures_Signature& signature = signatures.signatures(0);
- EXPECT_EQ(1, signature.version());
+ EXPECT_EQ(1U, signature.version());
const string sig_data = signature.data();
ASSERT_EQ(arraysize(kDataSignature), sig_data.size());
for (size_t i = 0; i < arraysize(kDataSignature); i++) {
diff --git a/payload_generator/tarjan_unittest.cc b/payload_generator/tarjan_unittest.cc
index e40a7ff..c29cbdc 100644
--- a/payload_generator/tarjan_unittest.cc
+++ b/payload_generator/tarjan_unittest.cc
@@ -65,7 +65,7 @@
vector<Vertex::Index> vertex_indexes;
tarjan.Execute(i, &graph, &vertex_indexes);
- EXPECT_EQ(5, vertex_indexes.size());
+ EXPECT_EQ(5U, vertex_indexes.size());
EXPECT_TRUE(utils::VectorContainsValue(vertex_indexes, n_a));
EXPECT_TRUE(utils::VectorContainsValue(vertex_indexes, n_b));
EXPECT_TRUE(utils::VectorContainsValue(vertex_indexes, n_c));
@@ -77,7 +77,7 @@
vector<Vertex::Index> vertex_indexes;
tarjan.Execute(n_f, &graph, &vertex_indexes);
- EXPECT_EQ(1, vertex_indexes.size());
+ EXPECT_EQ(1U, vertex_indexes.size());
EXPECT_TRUE(utils::VectorContainsValue(vertex_indexes, n_f));
}
@@ -85,7 +85,7 @@
vector<Vertex::Index> vertex_indexes;
tarjan.Execute(i, &graph, &vertex_indexes);
- EXPECT_EQ(2, vertex_indexes.size());
+ EXPECT_EQ(2U, vertex_indexes.size());
EXPECT_TRUE(utils::VectorContainsValue(vertex_indexes, n_g));
EXPECT_TRUE(utils::VectorContainsValue(vertex_indexes, n_h));
}
diff --git a/payload_generator/zip_unittest.cc b/payload_generator/zip_unittest.cc
index 49b08b0..0c95a8f 100644
--- a/payload_generator/zip_unittest.cc
+++ b/payload_generator/zip_unittest.cc
@@ -74,7 +74,7 @@
brillo::Blob out;
EXPECT_TRUE(this->ZipCompressString(in, &out));
EXPECT_LT(out.size(), in.size());
- EXPECT_GT(out.size(), 0);
+ EXPECT_GT(out.size(), 0U);
brillo::Blob decompressed;
EXPECT_TRUE(this->ZipDecompress(out, &decompressed));
EXPECT_EQ(in.size(), decompressed.size());
@@ -105,10 +105,10 @@
string in;
brillo::Blob out;
EXPECT_TRUE(this->ZipDecompressString(in, &out));
- EXPECT_EQ(0, out.size());
+ EXPECT_EQ(0U, out.size());
EXPECT_TRUE(this->ZipCompressString(in, &out));
- EXPECT_EQ(0, out.size());
+ EXPECT_EQ(0U, out.size());
}
} // namespace chromeos_update_engine
diff --git a/payload_state.cc b/payload_state.cc
index 4b5b5fd..04b6579 100644
--- a/payload_state.cc
+++ b/payload_state.cc
@@ -62,6 +62,7 @@
url_switch_count_(0),
attempt_num_bytes_downloaded_(0),
attempt_connection_type_(metrics::ConnectionType::kUnknown),
+ attempt_error_code_(ErrorCode::kSuccess),
attempt_type_(AttemptType::kUpdate) {
for (int i = 0; i <= kNumDownloadSources; i++)
total_bytes_downloaded_[i] = current_bytes_downloaded_[i] = 0;
@@ -232,6 +233,7 @@
metrics::RollbackResult::kSuccess);
break;
}
+ attempt_error_code_ = ErrorCode::kSuccess;
// Reset the number of responses seen since it counts from the last
// successful update, e.g. now.
@@ -265,6 +267,8 @@
break;
}
+ attempt_error_code_ = base_error;
+
switch (base_error) {
// Errors which are good indicators of a problem with a particular URL or
// the protocol used in the URL or entities in the communication channel
diff --git a/payload_state.h b/payload_state.h
index bec5823..46711b6 100644
--- a/payload_state.h
+++ b/payload_state.h
@@ -147,6 +147,10 @@
return p2p_url_;
}
+ inline ErrorCode GetAttemptErrorCode() const override {
+ return attempt_error_code_;
+ }
+
private:
enum class AttemptType {
kUpdate,
@@ -559,6 +563,9 @@
// The connection type when the attempt started.
metrics::ConnectionType attempt_connection_type_;
+ // The attempt error code when the attempt finished.
+ ErrorCode attempt_error_code_;
+
// Whether we're currently rolling back.
AttemptType attempt_type_;
diff --git a/payload_state_interface.h b/payload_state_interface.h
index 40a13dd..68798ee 100644
--- a/payload_state_interface.h
+++ b/payload_state_interface.h
@@ -192,6 +192,7 @@
// Sets/gets the P2P download URL, if one is to be used.
virtual void SetP2PUrl(const std::string& url) = 0;
virtual std::string GetP2PUrl() const = 0;
+ virtual ErrorCode GetAttemptErrorCode() const = 0;
};
} // namespace chromeos_update_engine
diff --git a/payload_state_unittest.cc b/payload_state_unittest.cc
index 4490637..b671722 100644
--- a/payload_state_unittest.cc
+++ b/payload_state_unittest.cc
@@ -139,8 +139,8 @@
"Disable Payload Backoff = 0\n";
EXPECT_EQ(expected_response_sign, stored_response_sign);
EXPECT_EQ("", payload_state.GetCurrentUrl());
- EXPECT_EQ(0, payload_state.GetUrlFailureCount());
- EXPECT_EQ(0, payload_state.GetUrlSwitchCount());
+ EXPECT_EQ(0U, payload_state.GetUrlFailureCount());
+ EXPECT_EQ(0U, payload_state.GetUrlSwitchCount());
EXPECT_EQ(1, payload_state.GetNumResponsesSeen());
}
@@ -191,8 +191,8 @@
"Disable Payload Backoff = 0\n";
EXPECT_EQ(expected_response_sign, stored_response_sign);
EXPECT_EQ("https://single.url.test", payload_state.GetCurrentUrl());
- EXPECT_EQ(0, payload_state.GetUrlFailureCount());
- EXPECT_EQ(0, payload_state.GetUrlSwitchCount());
+ EXPECT_EQ(0U, payload_state.GetUrlFailureCount());
+ EXPECT_EQ(0U, payload_state.GetUrlSwitchCount());
EXPECT_EQ(1, payload_state.GetNumResponsesSeen());
}
@@ -242,8 +242,8 @@
"Disable Payload Backoff = 0\n";
EXPECT_EQ(expected_response_sign, stored_response_sign);
EXPECT_EQ("http://multiple.url.test", payload_state.GetCurrentUrl());
- EXPECT_EQ(0, payload_state.GetUrlFailureCount());
- EXPECT_EQ(0, payload_state.GetUrlSwitchCount());
+ EXPECT_EQ(0U, payload_state.GetUrlFailureCount());
+ EXPECT_EQ(0U, payload_state.GetUrlSwitchCount());
EXPECT_EQ(1, payload_state.GetNumResponsesSeen());
}
@@ -298,7 +298,7 @@
EXPECT_EQ("https://test", payload_state.GetCurrentUrl());
// Verify that we switched URLs three times
- EXPECT_EQ(3, payload_state.GetUrlSwitchCount());
+ EXPECT_EQ(3U, payload_state.GetUrlSwitchCount());
}
TEST(PayloadStateTest, NewResponseResetsPayloadState) {
@@ -321,7 +321,7 @@
ErrorCode error = ErrorCode::kDownloadMetadataSignatureMismatch;
payload_state.UpdateFailed(error);
EXPECT_EQ("https://test", payload_state.GetCurrentUrl());
- EXPECT_EQ(1, payload_state.GetUrlSwitchCount());
+ EXPECT_EQ(1U, payload_state.GetUrlSwitchCount());
// Now, slightly change the response and set it again.
SetupPayloadStateWith2Urls("Hash8225", true, &payload_state, &response);
@@ -330,7 +330,7 @@
// Fake an error again.
payload_state.UpdateFailed(error);
EXPECT_EQ("https://test", payload_state.GetCurrentUrl());
- EXPECT_EQ(1, payload_state.GetUrlSwitchCount());
+ EXPECT_EQ(1U, payload_state.GetUrlSwitchCount());
// Return a third different response.
SetupPayloadStateWith2Urls("Hash9999", true, &payload_state, &response);
@@ -338,15 +338,15 @@
// Make sure the url index was reset to 0 because of the new response.
EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
- EXPECT_EQ(0, payload_state.GetUrlFailureCount());
- EXPECT_EQ(0, payload_state.GetUrlSwitchCount());
- EXPECT_EQ(0,
+ EXPECT_EQ(0U, payload_state.GetUrlFailureCount());
+ EXPECT_EQ(0U, payload_state.GetUrlSwitchCount());
+ EXPECT_EQ(0U,
payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpServer));
- EXPECT_EQ(0,
+ EXPECT_EQ(0U,
payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpServer));
- EXPECT_EQ(0, payload_state.GetCurrentBytesDownloaded(
- kDownloadSourceHttpsServer));
- EXPECT_EQ(0,
+ EXPECT_EQ(
+ 0U, payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpsServer));
+ EXPECT_EQ(0U,
payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpsServer));
}
@@ -412,24 +412,24 @@
EXPECT_EQ(0, payload_state.GetPayloadAttemptNumber());
EXPECT_EQ(0, payload_state.GetFullPayloadAttemptNumber());
EXPECT_EQ("https://test", payload_state.GetCurrentUrl());
- EXPECT_EQ(0, payload_state.GetUrlFailureCount());
- EXPECT_EQ(1, payload_state.GetUrlSwitchCount());
+ EXPECT_EQ(0U, payload_state.GetUrlFailureCount());
+ EXPECT_EQ(1U, payload_state.GetUrlSwitchCount());
// This should advance the failure count only.
payload_state.UpdateFailed(ErrorCode::kDownloadTransferError);
EXPECT_EQ(0, payload_state.GetPayloadAttemptNumber());
EXPECT_EQ(0, payload_state.GetFullPayloadAttemptNumber());
EXPECT_EQ("https://test", payload_state.GetCurrentUrl());
- EXPECT_EQ(1, payload_state.GetUrlFailureCount());
- EXPECT_EQ(1, payload_state.GetUrlSwitchCount());
+ EXPECT_EQ(1U, payload_state.GetUrlFailureCount());
+ EXPECT_EQ(1U, payload_state.GetUrlSwitchCount());
// This should advance the failure count only.
payload_state.UpdateFailed(ErrorCode::kDownloadTransferError);
EXPECT_EQ(0, payload_state.GetPayloadAttemptNumber());
EXPECT_EQ(0, payload_state.GetFullPayloadAttemptNumber());
EXPECT_EQ("https://test", payload_state.GetCurrentUrl());
- EXPECT_EQ(2, payload_state.GetUrlFailureCount());
- EXPECT_EQ(1, payload_state.GetUrlSwitchCount());
+ EXPECT_EQ(2U, payload_state.GetUrlFailureCount());
+ EXPECT_EQ(1U, payload_state.GetUrlSwitchCount());
// This should advance the URL index as we've reached the
// max failure count and reset the failure count for the new URL index.
@@ -439,8 +439,8 @@
EXPECT_EQ(1, payload_state.GetPayloadAttemptNumber());
EXPECT_EQ(1, payload_state.GetFullPayloadAttemptNumber());
EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
- EXPECT_EQ(0, payload_state.GetUrlFailureCount());
- EXPECT_EQ(2, payload_state.GetUrlSwitchCount());
+ EXPECT_EQ(0U, payload_state.GetUrlFailureCount());
+ EXPECT_EQ(2U, payload_state.GetUrlSwitchCount());
EXPECT_TRUE(payload_state.ShouldBackoffDownload());
// This should advance the URL index.
@@ -448,8 +448,8 @@
EXPECT_EQ(1, payload_state.GetPayloadAttemptNumber());
EXPECT_EQ(1, payload_state.GetFullPayloadAttemptNumber());
EXPECT_EQ("https://test", payload_state.GetCurrentUrl());
- EXPECT_EQ(0, payload_state.GetUrlFailureCount());
- EXPECT_EQ(3, payload_state.GetUrlSwitchCount());
+ EXPECT_EQ(0U, payload_state.GetUrlFailureCount());
+ EXPECT_EQ(3U, payload_state.GetUrlSwitchCount());
EXPECT_TRUE(payload_state.ShouldBackoffDownload());
// This should advance the URL index and payload attempt number due to
@@ -458,8 +458,8 @@
EXPECT_EQ(2, payload_state.GetPayloadAttemptNumber());
EXPECT_EQ(2, payload_state.GetFullPayloadAttemptNumber());
EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
- EXPECT_EQ(0, payload_state.GetUrlFailureCount());
- EXPECT_EQ(4, payload_state.GetUrlSwitchCount());
+ EXPECT_EQ(0U, payload_state.GetUrlFailureCount());
+ EXPECT_EQ(4U, payload_state.GetUrlSwitchCount());
EXPECT_TRUE(payload_state.ShouldBackoffDownload());
// This HTTP error code should only increase the failure count.
@@ -468,8 +468,8 @@
EXPECT_EQ(2, payload_state.GetPayloadAttemptNumber());
EXPECT_EQ(2, payload_state.GetFullPayloadAttemptNumber());
EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
- EXPECT_EQ(1, payload_state.GetUrlFailureCount());
- EXPECT_EQ(4, payload_state.GetUrlSwitchCount());
+ EXPECT_EQ(1U, payload_state.GetUrlFailureCount());
+ EXPECT_EQ(4U, payload_state.GetUrlSwitchCount());
EXPECT_TRUE(payload_state.ShouldBackoffDownload());
// And that failure count should be reset when we download some bytes
@@ -478,8 +478,8 @@
EXPECT_EQ(2, payload_state.GetPayloadAttemptNumber());
EXPECT_EQ(2, payload_state.GetFullPayloadAttemptNumber());
EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
- EXPECT_EQ(0, payload_state.GetUrlFailureCount());
- EXPECT_EQ(4, payload_state.GetUrlSwitchCount());
+ EXPECT_EQ(0U, payload_state.GetUrlFailureCount());
+ EXPECT_EQ(4U, payload_state.GetUrlSwitchCount());
EXPECT_TRUE(payload_state.ShouldBackoffDownload());
// Now, slightly change the response and set it again.
@@ -490,8 +490,8 @@
EXPECT_EQ(0, payload_state.GetPayloadAttemptNumber());
EXPECT_EQ(0, payload_state.GetFullPayloadAttemptNumber());
EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
- EXPECT_EQ(0, payload_state.GetUrlFailureCount());
- EXPECT_EQ(0, payload_state.GetUrlSwitchCount());
+ EXPECT_EQ(0U, payload_state.GetUrlFailureCount());
+ EXPECT_EQ(0U, payload_state.GetUrlSwitchCount());
EXPECT_FALSE(payload_state.ShouldBackoffDownload());
}
@@ -532,8 +532,8 @@
EXPECT_EQ(1, payload_state.GetPayloadAttemptNumber());
EXPECT_EQ(1, payload_state.GetFullPayloadAttemptNumber());
EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
- EXPECT_EQ(0, payload_state.GetUrlFailureCount());
- EXPECT_EQ(0, payload_state.GetUrlSwitchCount());
+ EXPECT_EQ(0U, payload_state.GetUrlFailureCount());
+ EXPECT_EQ(0U, payload_state.GetUrlSwitchCount());
}
TEST(PayloadStateTest, PayloadAttemptNumberIncreasesOnSuccessfulDeltaDownload) {
@@ -572,8 +572,8 @@
EXPECT_EQ(1, payload_state.GetPayloadAttemptNumber());
EXPECT_EQ(0, payload_state.GetFullPayloadAttemptNumber());
EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
- EXPECT_EQ(0, payload_state.GetUrlFailureCount());
- EXPECT_EQ(0, payload_state.GetUrlSwitchCount());
+ EXPECT_EQ(0U, payload_state.GetUrlFailureCount());
+ EXPECT_EQ(0U, payload_state.GetUrlSwitchCount());
}
TEST(PayloadStateTest, SetResponseResetsInvalidUrlIndex) {
@@ -592,8 +592,8 @@
EXPECT_EQ(1, payload_state.GetPayloadAttemptNumber());
EXPECT_EQ(1, payload_state.GetFullPayloadAttemptNumber());
EXPECT_EQ("https://test", payload_state.GetCurrentUrl());
- EXPECT_EQ(1, payload_state.GetUrlFailureCount());
- EXPECT_EQ(1, payload_state.GetUrlSwitchCount());
+ EXPECT_EQ(1U, payload_state.GetUrlFailureCount());
+ EXPECT_EQ(1U, payload_state.GetUrlSwitchCount());
// Now, simulate a corrupted url index on persisted store which gets
// loaded when update_engine restarts. Using a different prefs object
@@ -625,8 +625,8 @@
EXPECT_EQ(0, payload_state.GetPayloadAttemptNumber());
EXPECT_EQ(0, payload_state.GetFullPayloadAttemptNumber());
EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
- EXPECT_EQ(0, payload_state.GetUrlFailureCount());
- EXPECT_EQ(0, payload_state.GetUrlSwitchCount());
+ EXPECT_EQ(0U, payload_state.GetUrlFailureCount());
+ EXPECT_EQ(0U, payload_state.GetUrlSwitchCount());
}
TEST(PayloadStateTest, NoBackoffInteractiveChecks) {
@@ -780,8 +780,8 @@
response.disable_payload_backoff = true;
PayloadState payload_state;
FakeSystemState fake_system_state;
- int https_total = 0;
- int http_total = 0;
+ uint64_t https_total = 0;
+ uint64_t http_total = 0;
EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
SetupPayloadStateWith2Urls("Hash3286", true, &payload_state, &response);
@@ -789,7 +789,7 @@
// Simulate a previous attempt with in order to set an initial non-zero value
// for the total bytes downloaded for HTTP.
- int prev_chunk = 323456789;
+ uint64_t prev_chunk = 323456789;
http_total += prev_chunk;
payload_state.DownloadProgress(prev_chunk);
@@ -805,7 +805,7 @@
EXPECT_EQ(2, payload_state.GetNumResponsesSeen());
// First, simulate successful download of a few bytes over HTTP.
- int first_chunk = 5000000;
+ uint64_t first_chunk = 5000000;
http_total += first_chunk;
payload_state.DownloadProgress(first_chunk);
// Test that first all progress is made on HTTP and none on HTTPS.
@@ -813,7 +813,7 @@
payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpServer));
EXPECT_EQ(http_total,
payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpServer));
- EXPECT_EQ(0, payload_state.GetCurrentBytesDownloaded(
+ EXPECT_EQ(0U, payload_state.GetCurrentBytesDownloaded(
kDownloadSourceHttpsServer));
EXPECT_EQ(https_total,
payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpsServer));
@@ -823,7 +823,7 @@
payload_state.UpdateFailed(error);
// Test that no new progress is made on HTTP and new progress is on HTTPS.
- int second_chunk = 23456789;
+ uint64_t second_chunk = 23456789;
https_total += second_chunk;
payload_state.DownloadProgress(second_chunk);
EXPECT_EQ(first_chunk,
@@ -837,8 +837,8 @@
// Simulate error to go back to http.
payload_state.UpdateFailed(error);
- int third_chunk = 32345678;
- int http_chunk = first_chunk + third_chunk;
+ uint64_t third_chunk = 32345678;
+ uint64_t http_chunk = first_chunk + third_chunk;
http_total += third_chunk;
payload_state.DownloadProgress(third_chunk);
@@ -856,7 +856,7 @@
// then do 42MB worth of progress
payload_state.UpdateFailed(error);
payload_state.SetUsingP2PForDownloading(true);
- int p2p_total = 42 * 1000 * 1000;
+ uint64_t p2p_total = 42 * 1000 * 1000;
payload_state.DownloadProgress(p2p_total);
EXPECT_EQ(p2p_total,
@@ -886,13 +886,13 @@
payload_state.UpdateSucceeded();
// Make sure the metrics are reset after a successful update.
- EXPECT_EQ(0,
+ EXPECT_EQ(0U,
payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpServer));
- EXPECT_EQ(0,
+ EXPECT_EQ(0U,
payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpServer));
- EXPECT_EQ(0, payload_state.GetCurrentBytesDownloaded(
+ EXPECT_EQ(0U, payload_state.GetCurrentBytesDownloaded(
kDownloadSourceHttpsServer));
- EXPECT_EQ(0,
+ EXPECT_EQ(0U,
payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpsServer));
EXPECT_EQ(0, payload_state.GetNumResponsesSeen());
}
@@ -906,7 +906,7 @@
SetupPayloadStateWith2Urls("Hash3286", true, &payload_state, &response);
// Simulate progress in order to mark HTTP as one of the sources used.
- int num_bytes = 42 * 1000 * 1000;
+ uint64_t num_bytes = 42 * 1000 * 1000;
payload_state.DownloadProgress(num_bytes);
// Check that this was done via HTTP.
@@ -936,20 +936,20 @@
// Set the first response.
SetupPayloadStateWith2Urls("Hash5823", true, &payload_state, &response);
- int num_bytes = 10000;
+ uint64_t num_bytes = 10000;
payload_state.DownloadProgress(num_bytes);
EXPECT_EQ(num_bytes,
payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpServer));
EXPECT_EQ(num_bytes,
payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpServer));
- EXPECT_EQ(0, payload_state.GetCurrentBytesDownloaded(
+ EXPECT_EQ(0U, payload_state.GetCurrentBytesDownloaded(
kDownloadSourceHttpsServer));
- EXPECT_EQ(0,
+ EXPECT_EQ(0U,
payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpsServer));
payload_state.UpdateRestarted();
// Make sure the current bytes downloaded is reset, but not the total bytes.
- EXPECT_EQ(0,
+ EXPECT_EQ(0U,
payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpServer));
EXPECT_EQ(num_bytes,
payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpServer));
@@ -966,21 +966,21 @@
EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
payload_state.UpdateRestarted();
- EXPECT_EQ(0, payload_state.GetNumReboots());
+ EXPECT_EQ(0U, payload_state.GetNumReboots());
fake_system_state.set_system_rebooted(true);
payload_state.UpdateResumed();
// Num reboots should be incremented because system rebooted detected.
- EXPECT_EQ(1, payload_state.GetNumReboots());
+ EXPECT_EQ(1U, payload_state.GetNumReboots());
fake_system_state.set_system_rebooted(false);
payload_state.UpdateResumed();
// Num reboots should now be 1 as reboot was not detected.
- EXPECT_EQ(1, payload_state.GetNumReboots());
+ EXPECT_EQ(1U, payload_state.GetNumReboots());
// Restart the update again to verify we set the num of reboots back to 0.
payload_state.UpdateRestarted();
- EXPECT_EQ(0, payload_state.GetNumReboots());
+ EXPECT_EQ(0U, payload_state.GetNumReboots());
}
TEST(PayloadStateTest, RollbackVersion) {
@@ -1267,7 +1267,7 @@
// Check that we still skip the HTTP URL and use only the HTTPS url.
EXPECT_EQ("https://test", payload_state.GetCurrentUrl());
- EXPECT_EQ(0, payload_state.GetUrlSwitchCount());
+ EXPECT_EQ(0U, payload_state.GetUrlSwitchCount());
// Now, slightly change the response and set it again.
SetupPayloadStateWith2Urls("Hash2399", false, &payload_state, &response);
@@ -1290,14 +1290,14 @@
// Check that we use the HTTP URL now and the failure count is reset.
EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
- EXPECT_EQ(0, payload_state.GetUrlFailureCount());
+ EXPECT_EQ(0U, payload_state.GetUrlFailureCount());
// Fake a failure and see if we're moving over to the HTTPS url and update
// the URL switch count properly.
payload_state.UpdateFailed(error);
EXPECT_EQ("https://test", payload_state.GetCurrentUrl());
- EXPECT_EQ(1, payload_state.GetUrlSwitchCount());
- EXPECT_EQ(0, payload_state.GetUrlFailureCount());
+ EXPECT_EQ(1U, payload_state.GetUrlSwitchCount());
+ EXPECT_EQ(0U, payload_state.GetUrlFailureCount());
}
TEST(PayloadStateTest, PayloadTypeMetricWhenTypeIsDelta) {
diff --git a/sample_images/generate_images.sh b/sample_images/generate_images.sh
index 70fc14b..1c2a83c 100755
--- a/sample_images/generate_images.sh
+++ b/sample_images/generate_images.sh
@@ -156,6 +156,8 @@
default)
add_files_default "${mntdir}" "${block_size}"
;;
+ empty)
+ ;;
esac
cleanup "${mntdir}"
@@ -176,6 +178,7 @@
# Add more sample images here.
generate_image disk_ext2_1k default 16777216 1024
generate_image disk_ext2_4k default 16777216 4096
+ generate_image disk_ext2_4k_empty empty $((1024 * 4096)) 4096
generate_image disk_ext2_ue_settings ue_settings 16777216 4096
# Generate the tarball and delete temporary images.
diff --git a/sample_images/sample_images.tar.bz2 b/sample_images/sample_images.tar.bz2
index 0982271..83141ab 100644
--- a/sample_images/sample_images.tar.bz2
+++ b/sample_images/sample_images.tar.bz2
Binary files differ
diff --git a/update_attempter.cc b/update_attempter.cc
index aeb433b..cfd2425 100644
--- a/update_attempter.cc
+++ b/update_attempter.cc
@@ -125,7 +125,9 @@
: processor_(new ActionProcessor()),
system_state_(system_state),
cert_checker_(cert_checker),
+#if USE_LIBCROS
chrome_proxy_resolver_(libcros_proxy),
+#endif // USE_LIBCROS
debugd_proxy_(debugd_proxy) {
}
@@ -155,7 +157,9 @@
else
status_ = UpdateStatus::IDLE;
+#if USE_LIBCROS
chrome_proxy_resolver_.Init();
+#endif // USE_LIBCROS
}
void UpdateAttempter::ScheduleUpdates() {
@@ -1376,14 +1380,17 @@
if (response_handler_action_->install_plan().is_resume) {
// Resuming an update so fetch the update manifest metadata first.
int64_t manifest_metadata_size = 0;
+ int64_t manifest_signature_size = 0;
prefs_->GetInt64(kPrefsManifestMetadataSize, &manifest_metadata_size);
- fetcher->AddRange(0, manifest_metadata_size);
+ prefs_->GetInt64(kPrefsManifestSignatureSize, &manifest_signature_size);
+ fetcher->AddRange(0, manifest_metadata_size + manifest_signature_size);
// If there're remaining unprocessed data blobs, fetch them. Be careful not
// to request data beyond the end of the payload to avoid 416 HTTP response
// error codes.
int64_t next_data_offset = 0;
prefs_->GetInt64(kPrefsUpdateStateNextDataOffset, &next_data_offset);
- uint64_t resume_offset = manifest_metadata_size + next_data_offset;
+ uint64_t resume_offset =
+ manifest_metadata_size + manifest_signature_size + next_data_offset;
if (resume_offset < response_handler_action_->install_plan().payload_size) {
fetcher->AddRange(resume_offset);
}
diff --git a/update_attempter.h b/update_attempter.h
index 8f6fd18..bbc4b4e 100644
--- a/update_attempter.h
+++ b/update_attempter.h
@@ -306,9 +306,13 @@
void MarkDeltaUpdateFailure();
ProxyResolver* GetProxyResolver() {
+#if USE_LIBCROS
return obeying_proxies_ ?
reinterpret_cast<ProxyResolver*>(&chrome_proxy_resolver_) :
reinterpret_cast<ProxyResolver*>(&direct_proxy_resolver_);
+#else
+ return &direct_proxy_resolver_;
+#endif // USE_LIBCROS
}
// Sends a ping to Omaha.
@@ -454,7 +458,9 @@
// Our two proxy resolvers
DirectProxyResolver direct_proxy_resolver_;
+#if USE_LIBCROS
ChromeBrowserProxyResolver chrome_proxy_resolver_;
+#endif // USE_LIBCROS
// Originally, both of these flags are false. Once UpdateBootFlags is called,
// |update_boot_flags_running_| is set to true. As soon as UpdateBootFlags
diff --git a/update_attempter_android.cc b/update_attempter_android.cc
index cc478a4..6f88ee7 100644
--- a/update_attempter_android.cc
+++ b/update_attempter_android.cc
@@ -173,6 +173,7 @@
SetupDownload();
cpu_limiter_.StartLimiter();
SetStatusAndNotify(UpdateStatus::UPDATE_AVAILABLE);
+ ongoing_update_ = true;
// Just in case we didn't update boot flags yet, make sure they're updated
// before any update processing starts. This will start the update process.
@@ -181,23 +182,24 @@
}
bool UpdateAttempterAndroid::SuspendUpdate(brillo::ErrorPtr* error) {
- // TODO(deymo): Implement suspend/resume.
- return LogAndSetError(error, FROM_HERE, "Suspend/resume not implemented");
+ if (!ongoing_update_)
+ return LogAndSetError(error, FROM_HERE, "No ongoing update to suspend.");
+ processor_->SuspendProcessing();
+ return true;
}
bool UpdateAttempterAndroid::ResumeUpdate(brillo::ErrorPtr* error) {
- // TODO(deymo): Implement suspend/resume.
- return LogAndSetError(error, FROM_HERE, "Suspend/resume not implemented");
+ if (!ongoing_update_)
+ return LogAndSetError(error, FROM_HERE, "No ongoing update to resume.");
+ processor_->ResumeProcessing();
+ return true;
}
bool UpdateAttempterAndroid::CancelUpdate(brillo::ErrorPtr* error) {
- if (status_ == UpdateStatus::IDLE ||
- status_ == UpdateStatus::UPDATED_NEED_REBOOT) {
+ if (!ongoing_update_)
return LogAndSetError(error, FROM_HERE, "No ongoing update to cancel.");
- }
-
- // TODO(deymo): Implement cancel.
- return LogAndSetError(error, FROM_HERE, "Cancel not implemented");
+ processor_->StopProcessing();
+ return true;
}
bool UpdateAttempterAndroid::ResetStatus(brillo::ErrorPtr* error) {
@@ -412,14 +414,18 @@
if (install_plan_.is_resume) {
// Resuming an update so fetch the update manifest metadata first.
int64_t manifest_metadata_size = 0;
+ int64_t manifest_signature_size = 0;
prefs_->GetInt64(kPrefsManifestMetadataSize, &manifest_metadata_size);
- fetcher->AddRange(base_offset_, manifest_metadata_size);
+ prefs_->GetInt64(kPrefsManifestSignatureSize, &manifest_signature_size);
+ fetcher->AddRange(base_offset_,
+ manifest_metadata_size + manifest_signature_size);
// If there're remaining unprocessed data blobs, fetch them. Be careful not
// to request data beyond the end of the payload to avoid 416 HTTP response
// error codes.
int64_t next_data_offset = 0;
prefs_->GetInt64(kPrefsUpdateStateNextDataOffset, &next_data_offset);
- uint64_t resume_offset = manifest_metadata_size + next_data_offset;
+ uint64_t resume_offset =
+ manifest_metadata_size + manifest_signature_size + next_data_offset;
if (!install_plan_.payload_size) {
fetcher->AddRange(base_offset_ + resume_offset);
} else if (resume_offset < install_plan_.payload_size) {
diff --git a/update_attempter_unittest.cc b/update_attempter_unittest.cc
index e77b571..35bd206 100644
--- a/update_attempter_unittest.cc
+++ b/update_attempter_unittest.cc
@@ -38,6 +38,8 @@
#include "libcros/dbus-proxy-mocks.h"
#include "update_engine/common/fake_clock.h"
#include "update_engine/common/fake_prefs.h"
+#include "update_engine/common/mock_action.h"
+#include "update_engine/common/mock_action_processor.h"
#include "update_engine/common/mock_http_fetcher.h"
#include "update_engine/common/mock_prefs.h"
#include "update_engine/common/platform_constants.h"
@@ -45,8 +47,6 @@
#include "update_engine/common/test_utils.h"
#include "update_engine/common/utils.h"
#include "update_engine/fake_system_state.h"
-#include "update_engine/mock_action.h"
-#include "update_engine/mock_action_processor.h"
#include "update_engine/mock_p2p_manager.h"
#include "update_engine/mock_payload_state.h"
#include "update_engine/payload_consumer/filesystem_verifier_action.h"
@@ -254,7 +254,7 @@
attempter_.ActionCompleted(nullptr, &action, ErrorCode::kSuccess);
EXPECT_EQ(500, attempter_.http_response_code());
EXPECT_EQ(UpdateStatus::IDLE, attempter_.status());
- EXPECT_EQ(234, attempter_.server_dictated_poll_interval_);
+ EXPECT_EQ(234U, attempter_.server_dictated_poll_interval_);
ASSERT_TRUE(attempter_.error_event_.get() == nullptr);
}
@@ -429,9 +429,10 @@
}
EXPECT_EQ(attempter_.response_handler_action_.get(),
attempter_.actions_[1].get());
- DownloadAction* download_action =
- dynamic_cast<DownloadAction*>(attempter_.actions_[4].get());
- ASSERT_NE(nullptr, download_action);
+ AbstractAction* action_4 = attempter_.actions_[4].get();
+ ASSERT_NE(nullptr, action_4);
+ ASSERT_EQ(DownloadAction::StaticType(), action_4->Type());
+ DownloadAction* download_action = static_cast<DownloadAction*>(action_4);
EXPECT_EQ(&attempter_, download_action->delegate());
EXPECT_EQ(UpdateStatus::CHECKING_FOR_UPDATE, attempter_.status());
loop_.BreakLoop();
@@ -501,10 +502,13 @@
EXPECT_EQ(kRollbackActionTypes[i], attempter_.actions_[i]->Type());
}
EXPECT_EQ(UpdateStatus::ATTEMPTING_ROLLBACK, attempter_.status());
+ AbstractAction* action_0 = attempter_.actions_[0].get();
+ ASSERT_NE(nullptr, action_0);
+ ASSERT_EQ(InstallPlanAction::StaticType(), action_0->Type());
InstallPlanAction* install_plan_action =
- dynamic_cast<InstallPlanAction*>(attempter_.actions_[0].get());
+ static_cast<InstallPlanAction*>(action_0);
InstallPlan* install_plan = install_plan_action->install_plan();
- EXPECT_EQ(0, install_plan->partitions.size());
+ EXPECT_EQ(0U, install_plan->partitions.size());
EXPECT_EQ(install_plan->powerwash_required, true);
loop_.BreakLoop();
}
diff --git a/update_engine.gyp b/update_engine.gyp
index ab20243..07e6f6c 100644
--- a/update_engine.gyp
+++ b/update_engine.gyp
@@ -26,6 +26,7 @@
'USE_binder%': '0',
'USE_dbus%': '1',
'USE_hwid_override%': '0',
+ 'USE_libcros%': '1',
'USE_mtd%': '0',
'USE_power_management%': '0',
'USE_buffet%': '0',
@@ -52,6 +53,7 @@
'USE_BINDER=<(USE_binder)',
'USE_DBUS=<(USE_dbus)',
'USE_HWID_OVERRIDE=<(USE_hwid_override)',
+ 'USE_LIBCROS=<(USE_libcros)',
'USE_MTD=<(USE_mtd)',
'USE_POWER_MANAGEMENT=<(USE_power_management)',
'USE_WEAVE=<(USE_buffet)',
@@ -246,7 +248,6 @@
},
'sources': [
'boot_control_chromeos.cc',
- 'chrome_browser_proxy_resolver.cc',
'common_service.cc',
'connection_manager.cc',
'daemon.cc',
@@ -293,6 +294,14 @@
],
},
}],
+ ['USE_libcros == 1', {
+ 'dependencies': [
+ 'update_engine-other-dbus-proxies',
+ ],
+ 'sources': [
+ 'chrome_browser_proxy_resolver.cc',
+ ],
+ }],
],
},
# update_engine daemon.
@@ -333,8 +342,9 @@
'libupdate_engine_client',
],
'sources': [
+ 'common/error_code_utils.cc',
'update_engine_client.cc',
- ],
+ ],
},
# server-side code. This is used for delta_generator and unittests but not
# for any client code.
@@ -440,8 +450,8 @@
{
'target_name': 'test_http_server',
'type': 'executable',
- 'dependencies': ['libupdate_engine'],
'sources': [
+ 'common/http_common.cc',
'test_http_server.cc',
],
},
@@ -467,7 +477,6 @@
'includes': ['../../../platform2/common-mk/common_test.gypi'],
'sources': [
'boot_control_chromeos_unittest.cc',
- 'chrome_browser_proxy_resolver_unittest.cc',
'common/action_pipe_unittest.cc',
'common/action_processor_unittest.cc',
'common/action_unittest.cc',
@@ -539,6 +548,13 @@
# Main entry point for runnning tests.
'testrunner.cc',
],
+ 'conditions': [
+ ['USE_libcros == 1', {
+ 'sources': [
+ 'chrome_browser_proxy_resolver_unittest.cc',
+ ],
+ }],
+ ],
},
],
}],
diff --git a/update_engine_client.cc b/update_engine_client.cc
index eabc546..22fe6a6 100644
--- a/update_engine_client.cc
+++ b/update_engine_client.cc
@@ -29,12 +29,15 @@
#include <brillo/daemons/daemon.h>
#include <brillo/flag_helper.h>
+#include "update_engine/common/error_code.h"
+#include "update_engine/common/error_code_utils.h"
#include "update_engine/client.h"
#include "update_engine/status_update_handler.h"
#include "update_engine/update_status.h"
#include "update_engine/update_status_utils.h"
using chromeos_update_engine::UpdateStatusToString;
+using chromeos_update_engine::ErrorCode;
using std::string;
using std::unique_ptr;
using std::vector;
@@ -262,6 +265,7 @@
"Listen for status updates and print them to the screen.");
DEFINE_bool(prev_version, false,
"Show the previous OS version used before the update reboot.");
+ DEFINE_bool(last_attempt_error, false, "Show the last attempt error.");
// Boilerplate init commands.
base::CommandLine::Init(argc_, argv_);
@@ -509,6 +513,19 @@
return kContinueRunning;
}
+ if (FLAGS_last_attempt_error) {
+ int last_attempt_error;
+ if (!client_->GetLastAttemptError(&last_attempt_error)) {
+ LOG(ERROR) << "Error getting last attempt error.";
+ } else {
+ ErrorCode code = static_cast<ErrorCode>(last_attempt_error);
+ string error_msg = chromeos_update_engine::utils::ErrorCodeToString(code);
+ printf("ERROR_CODE=%i\n"
+ "ERROR_MESSAGE=%s\n",
+ last_attempt_error, error_msg.c_str());
+ }
+ }
+
return 0;
}
diff --git a/update_manager/update_manager_unittest.cc b/update_manager/update_manager_unittest.cc
index 4cc738d..03f1610 100644
--- a/update_manager/update_manager_unittest.cc
+++ b/update_manager/update_manager_unittest.cc
@@ -253,9 +253,9 @@
umut_->AsyncPolicyRequest(callback, &Policy::UpdateCheckAllowed);
// The callback should wait until we run the main loop for it to be executed.
- EXPECT_EQ(0, calls.size());
+ EXPECT_EQ(0U, calls.size());
MessageLoopRunMaxIterations(MessageLoop::current(), 100);
- EXPECT_EQ(1, calls.size());
+ EXPECT_EQ(1U, calls.size());
}
TEST_F(UmUpdateManagerTest, AsyncPolicyRequestTimeoutDoesNotFire) {
@@ -273,14 +273,14 @@
// to the default.
MessageLoopRunMaxIterations(MessageLoop::current(), 100);
EXPECT_EQ(1, num_called);
- ASSERT_EQ(1, calls.size());
+ ASSERT_EQ(1U, calls.size());
EXPECT_EQ(EvalStatus::kSucceeded, calls[0].first);
// Wait for the timeout to expire, run the main loop again, ensure that
// nothing happened.
test_clock_.Advance(TimeDelta::FromSeconds(2));
MessageLoopRunMaxIterations(MessageLoop::current(), 10);
EXPECT_EQ(1, num_called);
- EXPECT_EQ(1, calls.size());
+ EXPECT_EQ(1U, calls.size());
}
TEST_F(UmUpdateManagerTest, AsyncPolicyRequestTimesOut) {
@@ -301,7 +301,7 @@
// was not invoked.
MessageLoopRunMaxIterations(MessageLoop::current(), 100);
EXPECT_EQ(1, num_called);
- EXPECT_EQ(0, calls.size());
+ EXPECT_EQ(0U, calls.size());
// Wait for the expiration timeout to expire, run the main loop again,
// ensure that reevaluation occurred but callback was not invoked (i.e.
// default policy was not consulted).
@@ -310,7 +310,7 @@
TimeDelta::FromSeconds(2));
MessageLoopRunMaxIterations(MessageLoop::current(), 10);
EXPECT_EQ(2, num_called);
- EXPECT_EQ(0, calls.size());
+ EXPECT_EQ(0U, calls.size());
// Wait for reevaluation due to delay to happen, ensure that it occurs and
// that the callback is invoked.
test_clock_.Advance(TimeDelta::FromSeconds(2));
@@ -318,7 +318,7 @@
TimeDelta::FromSeconds(2));
MessageLoopRunMaxIterations(MessageLoop::current(), 10);
EXPECT_EQ(3, num_called);
- ASSERT_EQ(1, calls.size());
+ ASSERT_EQ(1U, calls.size());
EXPECT_EQ(EvalStatus::kSucceeded, calls[0].first);
}
diff --git a/update_manager/variable_unittest.cc b/update_manager/variable_unittest.cc
index 13cceb1..144002a 100644
--- a/update_manager/variable_unittest.cc
+++ b/update_manager/variable_unittest.cc
@@ -99,13 +99,13 @@
DefaultVariable<int> var("var", kVariableModeAsync);
BaseVariableObserver observer;
var.AddObserver(&observer);
- EXPECT_EQ(var.observer_list_.size(), 1);
+ EXPECT_EQ(1U, var.observer_list_.size());
var.AddObserver(&observer);
- EXPECT_EQ(var.observer_list_.size(), 1);
+ EXPECT_EQ(1U, var.observer_list_.size());
var.RemoveObserver(&observer);
- EXPECT_EQ(var.observer_list_.size(), 0);
+ EXPECT_EQ(0U, var.observer_list_.size());
var.RemoveObserver(&observer);
- EXPECT_EQ(var.observer_list_.size(), 0);
+ EXPECT_EQ(0U, var.observer_list_.size());
}
TEST_F(UmBaseVariableTest, NotifyValueChangedTest) {
@@ -114,10 +114,10 @@
var.AddObserver(&observer1);
// Simulate a value change on the variable's implementation.
var.NotifyValueChanged();
- ASSERT_EQ(0, observer1.calls_.size());
+ ASSERT_EQ(0U, observer1.calls_.size());
MessageLoopRunMaxIterations(MessageLoop::current(), 100);
- ASSERT_EQ(1, observer1.calls_.size());
+ ASSERT_EQ(1U, observer1.calls_.size());
// Check that the observer is called with the right argument.
EXPECT_EQ(&var, observer1.calls_[0]);
@@ -127,8 +127,8 @@
MessageLoopRunMaxIterations(MessageLoop::current(), 100);
// Check that all the observers are called.
- EXPECT_EQ(2, observer1.calls_.size());
- EXPECT_EQ(1, observer2.calls_.size());
+ EXPECT_EQ(2U, observer1.calls_.size());
+ EXPECT_EQ(1U, observer2.calls_.size());
var.RemoveObserver(&observer1);
var.RemoveObserver(&observer2);