Add a device-side unittest target

This change also adds two static libs, libbspatch and libbsdiff,
which encapsulate the dependencies of both the binaries and the
unit tests.

TEST=`mma external/bsdiff` and ran unittests on host and bullhead:NRC47C

Bug: 26971929
Change-Id: Ica0b17fa60f3ddf86d03ae12e6c099efbdd1296b
diff --git a/Android.mk b/Android.mk
index b22e62d..2591267 100644
--- a/Android.mk
+++ b/Android.mk
@@ -25,16 +25,11 @@
 bsdiff_common_static_libs := \
     libbz
 
-bsdiff_common_unittests := \
-    bsdiff_unittest.cc \
-    extents_file_unittest.cc \
-    extents_unittest.cc \
-    test_utils.cc
-
 # "bsdiff" program.
-bsdiff_shared_libs := \
+bsdiff_static_libs := \
     libdivsufsort64 \
-    libdivsufsort
+    libdivsufsort \
+    $(bsdiff_common_static_libs)
 
 bsdiff_src_files := \
     bsdiff.cc
@@ -46,59 +41,96 @@
     extents_file.cc \
     file.cc
 
+# Unit test files.
+bsdiff_common_unittests := \
+    bsdiff_unittest.cc \
+    extents_file_unittest.cc \
+    extents_unittest.cc \
+    test_utils.cc
+
+# Target static libraries.
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := libbspatch
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_SRC_FILES := $(bspatch_src_files)
+LOCAL_CFLAGS := $(bsdiff_common_cflags)
+LOCAL_STATIC_LIBRARIES := $(bsdiff_common_static_libs)
+include $(BUILD_STATIC_LIBRARY)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := libbsdiff
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_SRC_FILES := $(bsdiff_src_files)
+LOCAL_CFLAGS := $(bsdiff_common_cflags)
+LOCAL_STATIC_LIBRARIES := $(bsdiff_static_libs)
+include $(BUILD_STATIC_LIBRARY)
+
+# Host static libraries.
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := libbspatch
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_SRC_FILES := $(bspatch_src_files)
+LOCAL_CFLAGS := $(bsdiff_common_cflags)
+LOCAL_STATIC_LIBRARIES := $(bsdiff_common_static_libs)
+include $(BUILD_HOST_STATIC_LIBRARY)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := libbsdiff
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_SRC_FILES := $(bsdiff_src_files)
+LOCAL_CFLAGS := $(bsdiff_common_cflags)
+LOCAL_STATIC_LIBRARIES := $(bsdiff_static_libs)
+include $(BUILD_HOST_STATIC_LIBRARY)
+
 # Target executables.
 
 include $(CLEAR_VARS)
 LOCAL_MODULE := bspatch
 LOCAL_CPP_EXTENSION := .cc
-LOCAL_SRC_FILES := \
-    $(bspatch_src_files) \
-    bspatch_main.cc
+LOCAL_SRC_FILES := bspatch_main.cc
 LOCAL_CFLAGS := $(bsdiff_common_cflags)
-LOCAL_C_INCLUDES += external/bzip2
-LOCAL_STATIC_LIBRARIES := $(bsdiff_common_static_libs)
+LOCAL_STATIC_LIBRARIES := \
+    libbspatch \
+    $(bsdiff_common_static_libs)
 include $(BUILD_EXECUTABLE)
 
-
 # Host executables.
 
 include $(CLEAR_VARS)
 LOCAL_MODULE := bsdiff
 LOCAL_CPP_EXTENSION := .cc
-LOCAL_SRC_FILES := \
-    $(bsdiff_src_files) \
-    bsdiff_main.cc
+LOCAL_SRC_FILES := bsdiff_main.cc
 LOCAL_CFLAGS := $(bsdiff_common_cflags)
-LOCAL_C_INCLUDES += external/bzip2
-LOCAL_STATIC_LIBRARIES := $(bsdiff_common_static_libs)
-LOCAL_SHARED_LIBRARIES := $(bsdiff_shared_libs)
+LOCAL_STATIC_LIBRARIES := \
+    libbsdiff \
+    $(bsdiff_static_libs)
 include $(BUILD_HOST_EXECUTABLE)
 
 include $(CLEAR_VARS)
 LOCAL_MODULE := bspatch
 LOCAL_CPP_EXTENSION := .cc
-LOCAL_SRC_FILES := \
-    $(bspatch_src_files) \
-    bspatch_main.cc
+LOCAL_SRC_FILES := bspatch_main.cc
 LOCAL_CFLAGS := $(bsdiff_common_cflags)
-LOCAL_C_INCLUDES += external/bzip2
-LOCAL_STATIC_LIBRARIES := $(bsdiff_common_static_libs)
+LOCAL_STATIC_LIBRARIES := \
+    libbspatch \
+    $(bsdiff_common_static_libs)
 include $(BUILD_HOST_EXECUTABLE)
 
+# Unit tests.
+
 include $(CLEAR_VARS)
 LOCAL_MODULE := bsdiff_unittest
 LOCAL_MODULE_TAGS := debug tests
 LOCAL_CPP_EXTENSION := .cc
-LOCAL_SRC_FILES := \
-    $(bsdiff_src_files) \
-    $(bspatch_src_files) \
-    $(bsdiff_common_unittests) \
+LOCAL_SRC_FILES := $(bsdiff_common_unittests) \
     testrunner.cc
-LOCAL_CFLAGS := $(bsdiff_common_cflags)
-LOCAL_C_INCLUDES += external/bzip2
+LOCAL_CFLAGS := $(bsdiff_common_cflags) \
+    -DBSDIFF_TARGET_UNITTEST
 LOCAL_STATIC_LIBRARIES := \
-    $(bsdiff_common_static_libs) \
-    libgtest_host \
-    libgmock_host
-LOCAL_SHARED_LIBRARIES := $(bsdiff_shared_libs)
-include $(BUILD_HOST_EXECUTABLE)
+    libbsdiff \
+    libbspatch \
+    libgmock \
+    $(bsdiff_static_libs)
+include $(BUILD_NATIVE_TEST)
diff --git a/test_utils.cc b/test_utils.cc
index 2ad8fc8..f369f80 100644
--- a/test_utils.cc
+++ b/test_utils.cc
@@ -7,6 +7,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <sys/stat.h>
 #include <unistd.h>
 
 #include <gtest/gtest.h>
@@ -51,6 +52,16 @@
 
 namespace test_utils {
 
+void BsdiffTestEnvironment::SetUp() {
+#ifdef BSDIFF_TARGET_UNITTEST
+#define BSDIFF_TARGET_TMP_BASE "/data/tmp"
+      if (access(BSDIFF_TARGET_TMP_BASE, F_OK) == -1) {
+        mkdir(BSDIFF_TARGET_TMP_BASE, S_IRWXU | S_IRWXG | S_IROTH | S_IWOTH);
+      }
+      setenv("TMPDIR", BSDIFF_TARGET_TMP_BASE, 1);
+#endif // defined (BSDIFF_TARGET_UNITTEST)
+}
+
 bool ReadFile(const string& path, vector<uint8_t>* out) {
   FILE* fp = fopen(path.c_str(), "r");
   if (!fp)
@@ -101,13 +112,15 @@
   memcpy(&diff_len, contents.data() + 16, sizeof(diff_len));
   memcpy(&new_file_len, contents.data() + 24, sizeof(new_file_len));
 
-  TEST_AND_RETURN_FALSE(file_size >= kHeaderSize + ctrl_len + diff_len);
-  extra_len = file_size - kHeaderSize - ctrl_len - diff_len;
-
   // Sanity check before we attempt to parse the bz2 streams.
   TEST_AND_RETURN_FALSE(ctrl_len >= 0);
   TEST_AND_RETURN_FALSE(diff_len >= 0);
 
+  // The cast is safe since ctrl_len and diff_len are both positive.
+  TEST_AND_RETURN_FALSE(file_size >=
+        static_cast<uint64_t>(kHeaderSize + ctrl_len + diff_len));
+  extra_len = file_size - kHeaderSize - ctrl_len - diff_len;
+
   uint8_t* ptr = contents.data() + kHeaderSize;
   bz2_ctrl = vector<uint8_t>(ptr, ptr + ctrl_len);
   ptr += ctrl_len;
diff --git a/test_utils.h b/test_utils.h
index 186d9e6..7132fe5 100644
--- a/test_utils.h
+++ b/test_utils.h
@@ -5,6 +5,7 @@
 #ifndef _BSDIFF_TEST_UTILS_H_
 #define _BSDIFF_TEST_UTILS_H_
 
+#include <gtest/gtest.h>
 #include <string>
 #include <vector>
 
@@ -18,6 +19,11 @@
 
 namespace test_utils {
 
+class BsdiffTestEnvironment : public ::testing::Environment {
+  public:
+    virtual void SetUp();
+};
+
 // Reads all the contents of the file |path| into |out|. Returns whether it
 // read up to the end of file.
 bool ReadFile(const std::string& path, std::vector<uint8_t>* out);
diff --git a/testrunner.cc b/testrunner.cc
index 44f0b5e..8b598e2 100644
--- a/testrunner.cc
+++ b/testrunner.cc
@@ -2,9 +2,12 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include "test_utils.h"
+
 #include <gtest/gtest.h>
 
 int main(int argc, char** argv) {
   ::testing::InitGoogleTest(&argc, argv);
+  ::testing::AddGlobalTestEnvironment(new test_utils::BsdiffTestEnvironment);
   return RUN_ALL_TESTS();
 }