Refactor libupdater into a seperate module.
So that we can write native tests for updater functions. This CL adds a
testcase for getprop() function.
Test: mmma bootable/recovery; Run recovery_component_test on device.
Change-Id: Iff4c1ff63c5c71aded2f9686fed6b71cc298c228
diff --git a/tests/Android.mk b/tests/Android.mk
index 19cb809..ef822d1 100644
--- a/tests/Android.mk
+++ b/tests/Android.mk
@@ -41,25 +41,41 @@
LOCAL_MODULE := recovery_component_test
LOCAL_C_INCLUDES := bootable/recovery
LOCAL_SRC_FILES := \
+ component/applypatch_test.cpp \
component/edify_test.cpp \
- component/verifier_test.cpp \
- component/applypatch_test.cpp
+ component/updater_test.cpp \
+ component/verifier_test.cpp
LOCAL_FORCE_STATIC_EXECUTABLE := true
+
+tune2fs_static_libraries := \
+ libext2_com_err \
+ libext2_blkid \
+ libext2_quota \
+ libext2_uuid_static \
+ libext2_e2p \
+ libext2fs
+
LOCAL_STATIC_LIBRARIES := \
libapplypatch \
libedify \
libotafault \
+ libupdater \
libverifier \
- libcrypto_utils \
- libcrypto \
libminui \
libminzip \
+ libmounts \
+ liblog \
+ libselinux \
+ libext4_utils_static \
+ libsparse_static \
+ libcrypto_utils \
+ libcrypto \
libcutils \
libbz \
libz \
- libc \
libbase \
- liblog
+ libtune2fs \
+ $(tune2fs_static_libraries)
testdata_out_path := $(TARGET_OUT_DATA_NATIVE_TESTS)/recovery
testdata_files := $(call find-subdir-files, testdata/*)
diff --git a/tests/component/updater_test.cpp b/tests/component/updater_test.cpp
new file mode 100644
index 0000000..ec9c290
--- /dev/null
+++ b/tests/component/updater_test.cpp
@@ -0,0 +1,71 @@
+/*
+ * 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.
+ */
+
+#include <string>
+
+#include <android-base/properties.h>
+#include <gtest/gtest.h>
+
+#include "edify/expr.h"
+#include "error_code.h"
+#include "updater/install.h"
+
+struct selabel_handle *sehandle = nullptr;
+
+static void expect(const char* expected, const char* expr_str,
+ ErrorCode error_code, CauseCode cause_code) {
+ Expr* e;
+ int error_count;
+ EXPECT_EQ(parse_string(expr_str, &e, &error_count), 0);
+
+ State state(expr_str, nullptr);
+
+ char* result = Evaluate(&state, e);
+
+ if (expected == nullptr) {
+ EXPECT_EQ(nullptr, result);
+ } else {
+ EXPECT_STREQ(expected, result);
+ }
+
+ EXPECT_EQ(error_code, state.error_code);
+ EXPECT_EQ(cause_code, state.cause_code);
+
+ free(result);
+}
+
+class UpdaterTest : public ::testing::Test {
+ protected:
+ virtual void SetUp() {
+ RegisterBuiltins();
+ RegisterInstallFunctions();
+ FinishRegistration();
+ }
+};
+
+TEST_F(UpdaterTest, getprop) {
+ expect(android::base::GetProperty("ro.product.device", "").c_str(),
+ "getprop(\"ro.product.device\")",
+ kNoError, kNoCause);
+
+ expect(android::base::GetProperty("ro.build.fingerprint", "").c_str(),
+ "getprop(\"ro.build.fingerprint\")",
+ kNoError, kNoCause);
+
+ // getprop() accepts only one parameter.
+ expect(nullptr, "getprop()", kNoError, kArgsParsingFailure);
+ expect(nullptr, "getprop(\"arg1\", \"arg2\")", kNoError, kArgsParsingFailure);
+}
diff --git a/updater/Android.mk b/updater/Android.mk
index d9fc72c..33e9738 100644
--- a/updater/Android.mk
+++ b/updater/Android.mk
@@ -14,41 +14,6 @@
LOCAL_PATH := $(call my-dir)
-# updater (static executable)
-# ===============================
-# Build a statically-linked binary to include in OTA packages.
-include $(CLEAR_VARS)
-
-updater_src_files := \
- install.cpp \
- blockimg.cpp \
- updater.cpp
-
-LOCAL_CLANG := true
-LOCAL_SRC_FILES := $(updater_src_files)
-
-LOCAL_STATIC_LIBRARIES += \
- $(TARGET_RECOVERY_UPDATER_LIBS) \
- $(TARGET_RECOVERY_UPDATER_EXTRA_LIBS) \
- libfec \
- libfec_rs \
- libext4_utils_static \
- libsquashfs_utils \
- libcrypto_utils \
- libcrypto \
- libapplypatch \
- libotafault \
- libedify \
- libminzip \
- libmounts \
- libz \
- libbz \
- libcutils \
- liblog \
- libselinux \
- libbase \
- liblog
-
tune2fs_static_libraries := \
libext2_com_err \
libext2_blkid \
@@ -57,17 +22,77 @@
libext2_e2p \
libext2fs
-LOCAL_STATIC_LIBRARIES += \
+updater_common_static_libraries := \
+ libapplypatch \
+ libedify \
+ libminzip \
+ libmounts \
+ libotafault \
+ libext4_utils_static \
+ libfec \
+ libfec_rs \
+ liblog \
+ libselinux \
+ libsparse_static \
+ libsquashfs_utils \
+ libbz \
+ libz \
+ libbase \
+ libcrypto \
+ libcrypto_utils \
+ libcutils \
libtune2fs \
$(tune2fs_static_libraries)
-LOCAL_CFLAGS += -Wno-unused-parameter -Werror
-LOCAL_STATIC_LIBRARIES += \
- libsparse_static \
- libz
+# libupdater (static library)
+# ===============================
+include $(CLEAR_VARS)
-LOCAL_C_INCLUDES += external/e2fsprogs/misc
-LOCAL_C_INCLUDES += $(LOCAL_PATH)/..
+LOCAL_MODULE := libupdater
+
+LOCAL_SRC_FILES := \
+ install.cpp \
+ blockimg.cpp
+
+LOCAL_C_INCLUDES := \
+ $(LOCAL_PATH)/.. \
+ $(LOCAL_PATH)/include \
+ external/e2fsprogs/misc
+
+LOCAL_CFLAGS := \
+ -Wno-unused-parameter \
+ -Werror
+
+LOCAL_EXPORT_C_INCLUDE_DIRS := \
+ $(LOCAL_PATH)/include
+
+LOCAL_STATIC_LIBRARIES := \
+ $(updater_common_static_libraries)
+
+include $(BUILD_STATIC_LIBRARY)
+
+# updater (static executable)
+# ===============================
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := updater
+
+LOCAL_SRC_FILES := \
+ updater.cpp
+
+LOCAL_C_INCLUDES := \
+ $(LOCAL_PATH)/.. \
+ $(LOCAL_PATH)/include
+
+LOCAL_CFLAGS := \
+ -Wno-unused-parameter \
+ -Werror
+
+LOCAL_STATIC_LIBRARIES := \
+ libupdater \
+ $(TARGET_RECOVERY_UPDATER_LIBS) \
+ $(TARGET_RECOVERY_UPDATER_EXTRA_LIBS) \
+ $(updater_common_static_libraries)
# Each library in TARGET_RECOVERY_UPDATER_LIBS should have a function
# named "Register_<libname>()". Here we emit a little C function that
@@ -108,8 +133,6 @@
inc :=
inc_dep_file :=
-LOCAL_MODULE := updater
-
LOCAL_FORCE_STATIC_EXECUTABLE := true
include $(BUILD_EXECUTABLE)
diff --git a/updater/blockimg.cpp b/updater/blockimg.cpp
index 0caa1ac..433d980 100644
--- a/updater/blockimg.cpp
+++ b/updater/blockimg.cpp
@@ -45,12 +45,12 @@
#include "applypatch/applypatch.h"
#include "edify/expr.h"
#include "error_code.h"
-#include "install.h"
+#include "updater/install.h"
#include "openssl/sha.h"
#include "minzip/Hash.h"
#include "ota_io.h"
#include "print_sha1.h"
-#include "updater.h"
+#include "updater/updater.h"
#define BLOCKSIZE 4096
diff --git a/updater/blockimg.h b/updater/include/updater/blockimg.h
similarity index 100%
rename from updater/blockimg.h
rename to updater/include/updater/blockimg.h
diff --git a/updater/install.h b/updater/include/updater/install.h
similarity index 89%
rename from updater/install.h
rename to updater/include/updater/install.h
index b3b8a4d..8d6ca47 100644
--- a/updater/install.h
+++ b/updater/include/updater/install.h
@@ -17,11 +17,12 @@
#ifndef _UPDATER_INSTALL_H_
#define _UPDATER_INSTALL_H_
+struct State;
+
void RegisterInstallFunctions();
// uiPrintf function prints msg to screen as well as logs
-void uiPrintf(State* _Nonnull state, const char* _Nonnull format, ...) __attribute__((__format__(printf, 2, 3)));
-
-static int make_parents(char* _Nonnull name);
+void uiPrintf(State* _Nonnull state, const char* _Nonnull format, ...)
+ __attribute__((__format__(printf, 2, 3)));
#endif
diff --git a/updater/updater.h b/updater/include/updater/updater.h
similarity index 100%
rename from updater/updater.h
rename to updater/include/updater/updater.h
diff --git a/updater/install.cpp b/updater/install.cpp
index 24e35cf..86cdd5d 100644
--- a/updater/install.cpp
+++ b/updater/install.cpp
@@ -14,6 +14,8 @@
* limitations under the License.
*/
+#include "updater/install.h"
+
#include <ctype.h>
#include <errno.h>
#include <stdarg.h>
@@ -40,24 +42,22 @@
#include <android-base/properties.h>
#include <android-base/strings.h>
#include <android-base/stringprintf.h>
+#include <cutils/android_reboot.h>
#include <ext4_utils/make_ext4fs.h>
#include <ext4_utils/wipe.h>
#include <selinux/label.h>
#include <selinux/selinux.h>
-#include "bootloader.h"
#include "applypatch/applypatch.h"
-#include "cutils/android_reboot.h"
-#include "cutils/misc.h"
+#include "bootloader.h"
#include "edify/expr.h"
#include "error_code.h"
#include "minzip/DirUtil.h"
#include "mounts.h"
#include "openssl/sha.h"
#include "ota_io.h"
-#include "updater.h"
-#include "install.h"
#include "tune2fs.h"
+#include "updater/updater.h"
// Send over the buffer to recovery though the command pipe.
static void uiPrint(State* state, const std::string& buffer) {
@@ -90,6 +90,27 @@
uiPrint(state, error_msg);
}
+// Create all parent directories of name, if necessary.
+static int make_parents(char* name) {
+ char* p;
+ for (p = name + (strlen(name)-1); p > name; --p) {
+ if (*p != '/') continue;
+ *p = '\0';
+ if (make_parents(name) < 0) return -1;
+ int result = mkdir(name, 0700);
+ if (result == 0) printf("created [%s]\n", name);
+ *p = '/';
+ if (result == 0 || errno == EEXIST) {
+ // successfully created or already existed; we're done
+ return 0;
+ } else {
+ printf("failed to mkdir %s: %s\n", name, strerror(errno));
+ return -1;
+ }
+ }
+ return 0;
+}
+
// Take a sha-1 digest and return it as a newly-allocated hex string.
char* PrintSha1(const uint8_t* digest) {
char* buffer = reinterpret_cast<char*>(malloc(SHA_DIGEST_LENGTH*2 + 1));
@@ -569,27 +590,6 @@
}
}
-// Create all parent directories of name, if necessary.
-static int make_parents(char* name) {
- char* p;
- for (p = name + (strlen(name)-1); p > name; --p) {
- if (*p != '/') continue;
- *p = '\0';
- if (make_parents(name) < 0) return -1;
- int result = mkdir(name, 0700);
- if (result == 0) printf("created [%s]\n", name);
- *p = '/';
- if (result == 0 || errno == EEXIST) {
- // successfully created or already existed; we're done
- return 0;
- } else {
- printf("failed to mkdir %s: %s\n", name, strerror(errno));
- return -1;
- }
- }
- return 0;
-}
-
// symlink target src1 src2 ...
// unlinks any previously existing src1, src2, etc before creating symlinks.
Value* SymlinkFn(const char* name, State* state, int argc, Expr* argv[]) {
diff --git a/updater/updater.cpp b/updater/updater.cpp
index 74a4048..45e31e0 100644
--- a/updater/updater.cpp
+++ b/updater/updater.cpp
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-#include "updater.h"
+#include "updater/updater.h"
#include <stdio.h>
#include <unistd.h>
@@ -27,10 +27,10 @@
#include "config.h"
#include "edify/expr.h"
-#include "blockimg.h"
-#include "install.h"
-#include "minzip/Zip.h"
#include "minzip/SysUtil.h"
+#include "minzip/Zip.h"
+#include "updater/blockimg.h"
+#include "updater/install.h"
// Generated by the makefile, this function defines the
// RegisterDeviceExtensions() function, which calls all the