android/filesystems/partition_types.h: new header
This patch introduces a new header to handle several types of
partition images through a simple common interface. This will be
used in a future patch to rework the way these images are setup
in vl-android.c
+ Move test support stuff to android/filesystems/testing/
+ Add unit tests.
Change-Id: Icc1c32258e37731283079adf0e5407fa2e48f661
diff --git a/Makefile.common b/Makefile.common
index 3dec971..17f886e 100644
--- a/Makefile.common
+++ b/Makefile.common
@@ -123,6 +123,7 @@
android/base/StringView.cpp \
android/emulation/CpuAccelerator.cpp \
android/filesystems/ext4_utils.cpp \
+ android/filesystems/partition_types.cpp \
android/kernel/kernel_utils.cpp \
android/utils/assert.c \
android/utils/bufprint.c \
diff --git a/Makefile.tests b/Makefile.tests
index 04373e6..b9a5a28 100644
--- a/Makefile.tests
+++ b/Makefile.tests
@@ -23,6 +23,8 @@
android/base/StringView_unittest.cpp \
android/emulation/CpuAccelerator_unittest.cpp \
android/filesystems/ext4_utils_unittest.cpp \
+ android/filesystems/partition_types_unittest.cpp \
+ android/filesystems/testing/TestSupport.cpp \
android/kernel/kernel_utils_unittest.cpp \
ifeq (windows,$(HOST_OS))
diff --git a/android/filesystems/ext4_utils_unittest.cpp b/android/filesystems/ext4_utils_unittest.cpp
index 646c93d..66cc4a7 100644
--- a/android/filesystems/ext4_utils_unittest.cpp
+++ b/android/filesystems/ext4_utils_unittest.cpp
@@ -14,6 +14,8 @@
#include "android/base/EintrWrapper.h"
#include "android/base/Log.h"
#include "android/base/files/ScopedStdioFile.h"
+#include "android/filesystems/testing/TestExt4ImageHeader.h"
+#include "android/filesystems/testing/TestSupport.h"
#include <gtest/gtest.h>
@@ -28,144 +30,13 @@
#endif
using android::base::ScopedStdioFile;
-
-// These are the first 1082 bytes of an EXT4 system.img file
-// It was generated with:
-//
-// dd -if=$SDK/system-images/android-19/armeabi-v7a/system.img
-// -of=/tmp/ext4-system.img
-// -bs=1082 -count=1
-//
-// xxd -i /tmp/ext4-system.img
-//
-// The two last bytes must be 0x53 / 0xef, i.e. the EXT4 magic bytes.
-//
-static const unsigned char kExt4SystemImage[] = {
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x80, 0x89, 0x00, 0x00, 0x00, 0x26, 0x02, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x15, 0x19, 0x01, 0x00, 0xd6, 0x85, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
- 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x80, 0x1b, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
- 0x53, 0xef
-};
-
-static const size_t kExt4SystemImageSize = sizeof(kExt4SystemImage);
-
-
-// TODO(digit): Move that to a test-support class.
-static std::string createTempFilePath() {
-#ifdef _WIN32
- char tempDir[MAX_PATH];
- DWORD ret = GetTempPath(MAX_PATH, tempDir);
- CHECK(ret > 0 && ret < MAX_PATH)
- << "Could not get temporary directory path";
-
- std::string result;
- result.resize(MAX_PATH);
- UINT ret2 = GetTempFileName(tempDir, "emulator-test-", 0, &result[0]);
- CHECK(ret2 != ERROR_BUFFER_OVERFLOW) << "Could not create temporary file name";
- result.resize(::strlen(result.c_str()));
- return result;
-#else
- std::string result("/tmp/emulator-test.XXXXXX");
- int ret = HANDLE_EINTR(mkstemp(&result[0]));
- PCHECK(ret >= 0) << "Could not create temporary filepath";
- ::close(ret);
- return result;
-#endif
-}
-
+using android::testing::CreateTempFilePath;
class Ext4UtilsTest : public ::testing::Test {
public:
Ext4UtilsTest() : mTempFilePath() {
::memset(mImage, 0, sizeof mImage);
- ::memcpy(mImage, kExt4SystemImage, kExt4SystemImageSize);
+ ::memcpy(mImage, kTestExt4ImageHeader, kTestExt4ImageHeaderSize);
}
~Ext4UtilsTest() {
@@ -181,7 +52,7 @@
const char* createTempFile(size_t maxBytes) {
CHECK(maxBytes <= sizeof mImage);
// TODO(digit): Replace with something else.
- mTempFilePath = createTempFilePath();
+ mTempFilePath = CreateTempFilePath();
ScopedStdioFile file(fopen(mTempFilePath.c_str(), "wb"));
PCHECK(file.get()) << "Could not create temporary file!";
PCHECK(::fwrite(mImage, maxBytes, 1, file.get()) == 1)
@@ -194,21 +65,21 @@
// Create the path of a temporary file, but do not create or
// populate it. The file is removed in the destructor.
const char* createTempPath() {
- mTempFilePath = createTempFilePath();
+ mTempFilePath = CreateTempFilePath();
return mTempFilePath.c_str();
}
std::string mTempFilePath;
- char mImage[kExt4SystemImageSize * 2U];
+ char mImage[kTestExt4ImageHeaderSize * 2U];
};
TEST_F(Ext4UtilsTest, android_pathIsExt4PartitionImage) {
- const char* path = createTempFile(kExt4SystemImageSize);
+ const char* path = createTempFile(kTestExt4ImageHeaderSize);
EXPECT_TRUE(android_pathIsExt4PartitionImage(path));
}
TEST_F(Ext4UtilsTest, android_pathIsExt4PartitionImageTruncated) {
- const char* path = createTempFile(kExt4SystemImageSize - 2U);
+ const char* path = createTempFile(kTestExt4ImageHeaderSize - 2U);
EXPECT_FALSE(android_pathIsExt4PartitionImage(path));
}
@@ -219,13 +90,13 @@
}
TEST_F(Ext4UtilsTest, android_pathIsExt4PartitionImageBadMagic1) {
- mImage[kExt4SystemImageSize - 1] = 0;
+ mImage[kTestExt4ImageHeaderSize - 1] = 0;
const char* path = createTempFile(sizeof mImage);
EXPECT_FALSE(android_pathIsExt4PartitionImage(path));
}
TEST_F(Ext4UtilsTest, android_pathIsExt4PartitionImageBadMagic2) {
- mImage[kExt4SystemImageSize - 2] = 0;
+ mImage[kTestExt4ImageHeaderSize - 2] = 0;
const char* path = createTempFile(sizeof mImage);
EXPECT_FALSE(android_pathIsExt4PartitionImage(path));
}
diff --git a/android/filesystems/partition_types.cpp b/android/filesystems/partition_types.cpp
new file mode 100644
index 0000000..f0dfba7
--- /dev/null
+++ b/android/filesystems/partition_types.cpp
@@ -0,0 +1,65 @@
+// Copyright 2014 The Android Open Source Project
+//
+// This software is licensed under the terms of the GNU General Public
+// License version 2, as published by the Free Software Foundation, and
+// may be copied, distributed, and modified under those terms.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+#include "android/filesystems/partition_types.h"
+
+#include "android/filesystems/ext4_utils.h"
+#include "android/utils/panic.h"
+#include "android/utils/path.h"
+
+#include <errno.h>
+
+const char* androidPartitionType_toString(AndroidPartitionType part_type) {
+ switch (part_type) {
+ case ANDROID_PARTITION_TYPE_UNKNOWN:
+ return "unknown";
+ case ANDROID_PARTITION_TYPE_YAFFS2:
+ return "yaffs2";
+ case ANDROID_PARTITION_TYPE_EXT4:
+ return "ext4";
+ default:
+ APANIC("Invalid partition type value %d", part_type);
+ }
+}
+
+
+AndroidPartitionType androidPartitionType_probeFile(const char* image_file) {
+ if (!path_exists(image_file)) {
+ return ANDROID_PARTITION_TYPE_UNKNOWN;
+ }
+ if (android_pathIsExt4PartitionImage(image_file)) {
+ return ANDROID_PARTITION_TYPE_EXT4;
+ }
+ // Assume YAFFS2, since there is little way to be sure for now.
+ // NOTE: An empty file is a valid Yaffs2 file!
+ return ANDROID_PARTITION_TYPE_YAFFS2;
+}
+
+
+int androidPartitionType_makeEmptyFile(AndroidPartitionType part_type,
+ uint64_t part_size,
+ const char* part_file) {
+ switch (part_type) {
+ case ANDROID_PARTITION_TYPE_YAFFS2:
+ // Any empty file is a valid YAFFS2 partition, |part_size|
+ // can be ignored here.
+ if (path_empty_file(part_file) < 0) {
+ return -errno;
+ }
+ return 0;
+
+ case ANDROID_PARTITION_TYPE_EXT4:
+ return android_createEmptyExt4Image(part_file, part_size, NULL);
+
+ default:
+ return -EINVAL;
+ }
+}
diff --git a/android/filesystems/partition_types.h b/android/filesystems/partition_types.h
new file mode 100644
index 0000000..9bbdcf4
--- /dev/null
+++ b/android/filesystems/partition_types.h
@@ -0,0 +1,46 @@
+// Copyright 2014 The Android Open Source Project
+//
+// This software is licensed under the terms of the GNU General Public
+// License version 2, as published by the Free Software Foundation, and
+// may be copied, distributed, and modified under those terms.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+#ifndef ANDROID_FILESYSTEMS_PARTITION_TYPES_H
+#define ANDROID_FILESYSTEMS_PARTITION_TYPES_H
+
+#include "android/utils/compiler.h"
+
+#include <inttypes.h>
+
+ANDROID_BEGIN_HEADER
+
+// List of supported Android partition image types.
+typedef enum {
+ ANDROID_PARTITION_TYPE_UNKNOWN = 0,
+ ANDROID_PARTITION_TYPE_YAFFS2 = 1,
+ ANDROID_PARTITION_TYPE_EXT4 = 2,
+} AndroidPartitionType;
+
+// Return a string describing the partition type to the caller.
+// Note: this will panic if |part_type| is an invalid value.
+const char* androidPartitionType_toString(AndroidPartitionType part_type);
+
+// Probe a given image file and return its partition image type.
+// Note: this returns ANDROID_PARTITION_TYPE_UNKNOWN if the file does
+// not exist or cannot be read.
+AndroidPartitionType androidPartitionType_probeFile(const char* image_file);
+
+// Create or reset the file at |image_file| to be an empty partition of type
+// |part_type| and size |part_size|. Returns 0 on success, or -errno on
+// failure.
+int androidPartitionType_makeEmptyFile(AndroidPartitionType part_type,
+ uint64_t part_size,
+ const char* image_file);
+
+ANDROID_END_HEADER
+
+#endif // ANDROID_FILESYSTEMS_PARTITION_TYPES_H
diff --git a/android/filesystems/partition_types_unittest.cpp b/android/filesystems/partition_types_unittest.cpp
new file mode 100644
index 0000000..5bdddd9
--- /dev/null
+++ b/android/filesystems/partition_types_unittest.cpp
@@ -0,0 +1,102 @@
+// Copyright 2014 The Android Open Source Project
+//
+// This software is licensed under the terms of the GNU General Public
+// License version 2, as published by the Free Software Foundation, and
+// may be copied, distributed, and modified under those terms.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+#include "android/filesystems/partition_types.h"
+
+#include "android/base/EintrWrapper.h"
+#include "android/base/files/ScopedStdioFile.h"
+#include "android/filesystems/ext4_utils.h"
+#include "android/filesystems/testing/TestExt4ImageHeader.h"
+#include "android/filesystems/testing/TestSupport.h"
+
+#include "android/utils/path.h"
+
+#include <gtest/gtest.h>
+
+#include <stdio.h>
+#include <string>
+#include <unistd.h>
+
+namespace {
+
+using android::base::ScopedStdioFile;
+
+class TempPartition {
+public:
+ TempPartition() {
+ mPath = android::testing::CreateTempFilePath();
+ }
+
+ ~TempPartition() {
+ if (!mPath.empty()) {
+ HANDLE_EINTR(::unlink(mPath.c_str()));
+ }
+ }
+
+ const char* GetPath() const {
+ return mPath.c_str();
+ }
+
+protected:
+ std::string mPath;
+};
+
+} // namespace
+
+TEST(AndroidPartitionType, ToString) {
+ EXPECT_STREQ("unknown", androidPartitionType_toString(ANDROID_PARTITION_TYPE_UNKNOWN));
+ EXPECT_STREQ("yaffs2", androidPartitionType_toString(ANDROID_PARTITION_TYPE_YAFFS2));
+ EXPECT_STREQ("ext4", androidPartitionType_toString(ANDROID_PARTITION_TYPE_EXT4));
+}
+
+TEST(AndroidPartitionType, ProbeFileYaffs2) {
+ TempPartition part;
+
+ // An empty partition is a valid YAFFS2 one.
+ ::path_empty_file(part.GetPath());
+
+ EXPECT_EQ(ANDROID_PARTITION_TYPE_YAFFS2,
+ androidPartitionType_probeFile(part.GetPath()));
+}
+
+
+TEST(AndroidPartitionType, ProbeFileExt4) {
+ TempPartition part;
+
+ android_createEmptyExt4Image(part.GetPath(), 16*1024*1024, "cache");
+
+ EXPECT_EQ(ANDROID_PARTITION_TYPE_EXT4,
+ androidPartitionType_probeFile(part.GetPath()));
+}
+
+TEST(AndroidPartitionType, MakeEmptyFileYaffs2) {
+ TempPartition part;
+
+ EXPECT_EQ(0, androidPartitionType_makeEmptyFile(
+ ANDROID_PARTITION_TYPE_YAFFS2,
+ 8 * 1024 * 1024,
+ part.GetPath())) << "Could not create Yaffs2 partition image";
+
+ EXPECT_EQ(ANDROID_PARTITION_TYPE_YAFFS2,
+ androidPartitionType_probeFile(part.GetPath()));
+}
+
+TEST(AndroidPartitionType, MakeEmptyFileExt4) {
+ TempPartition part;
+
+ EXPECT_EQ(0, androidPartitionType_makeEmptyFile(
+ ANDROID_PARTITION_TYPE_EXT4,
+ 8 * 1024 * 1024,
+ part.GetPath())) << "Could not create EXT4 partition image";
+
+ EXPECT_EQ(ANDROID_PARTITION_TYPE_EXT4,
+ androidPartitionType_probeFile(part.GetPath()));
+}
diff --git a/android/filesystems/testing/TestExt4ImageHeader.h b/android/filesystems/testing/TestExt4ImageHeader.h
new file mode 100644
index 0000000..13d41e2
--- /dev/null
+++ b/android/filesystems/testing/TestExt4ImageHeader.h
@@ -0,0 +1,122 @@
+// Copyright 2014 The Android Open Source Project
+//
+// This software is licensed under the terms of the GNU General Public
+// License version 2, as published by the Free Software Foundation, and
+// may be copied, distributed, and modified under those terms.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+#ifndef ANDROID_FILESYSTEMS_TESTING_TEST_EXT4_IMAGE_HEADER_H
+#define ANDROID_FILESYSTEMS_TESTING_TEST_EXT4_IMAGE_HEADER_H
+
+// These are the first 1082 bytes of an EXT4 system.img file
+// It was generated with:
+//
+// dd -if=$SDK/system-images/android-19/armeabi-v7a/system.img
+// -of=/tmp/ext4-system.img
+// -bs=1082 -count=1
+//
+// xxd -i /tmp/ext4-system.img
+//
+// The two last bytes must be 0x53 / 0xef, i.e. the EXT4 magic bytes.
+//
+static const unsigned char kTestExt4ImageHeader[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x80, 0x89, 0x00, 0x00, 0x00, 0x26, 0x02, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x15, 0x19, 0x01, 0x00, 0xd6, 0x85, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x80, 0x1b, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
+ 0x53, 0xef
+};
+
+static const size_t kTestExt4ImageHeaderSize = sizeof(kTestExt4ImageHeader);
+
+#endif // ANDROID_FILESYSTEMS_TESTING_TEST_EXT4_IMAGE_HEADER_H
diff --git a/android/filesystems/testing/TestSupport.cpp b/android/filesystems/testing/TestSupport.cpp
new file mode 100644
index 0000000..f084306
--- /dev/null
+++ b/android/filesystems/testing/TestSupport.cpp
@@ -0,0 +1,49 @@
+// Copyright 2014 The Android Open Source Project
+//
+// This software is licensed under the terms of the GNU General Public
+// License version 2, as published by the Free Software Foundation, and
+// may be copied, distributed, and modified under those terms.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+#include "android/filesystems/testing/TestSupport.h"
+
+#include "android/base/EintrWrapper.h"
+#include "android/base/Log.h"
+
+#include <stdlib.h>
+
+#ifdef _WIN32
+#include <windows.h>
+#endif
+
+namespace android {
+namespace testing {
+
+std::string CreateTempFilePath() {
+#ifdef _WIN32
+ char tempDir[MAX_PATH];
+ DWORD ret = GetTempPath(MAX_PATH, tempDir);
+ CHECK(ret > 0 && ret < MAX_PATH)
+ << "Could not get temporary directory path";
+
+ std::string result;
+ result.resize(MAX_PATH);
+ UINT ret2 = GetTempFileName(tempDir, "emulator-test-", 0, &result[0]);
+ CHECK(ret2 != ERROR_BUFFER_OVERFLOW) << "Could not create temporary file name";
+ result.resize(::strlen(result.c_str()));
+ return result;
+#else
+ std::string result("/tmp/emulator-test.XXXXXX");
+ int ret = HANDLE_EINTR(mkstemp(&result[0]));
+ PCHECK(ret >= 0) << "Could not create temporary filepath";
+ ::close(ret);
+ return result;
+#endif
+}
+
+} // namespace testing
+} // namespace android
diff --git a/android/filesystems/testing/TestSupport.h b/android/filesystems/testing/TestSupport.h
new file mode 100644
index 0000000..b2285b5
--- /dev/null
+++ b/android/filesystems/testing/TestSupport.h
@@ -0,0 +1,25 @@
+// Copyright 2014 The Android Open Source Project
+//
+// This software is licensed under the terms of the GNU General Public
+// License version 2, as published by the Free Software Foundation, and
+// may be copied, distributed, and modified under those terms.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+#ifndef ANDROID_FILESYSTEMS_TESTING_TEST_SUPPORT_H
+#define ANDROID_FILESYSTEMS_TESTING_TEST_SUPPORT_H
+
+#include <string>
+
+namespace android {
+namespace testing {
+
+std::string CreateTempFilePath();
+
+} // namespace testing
+} // namespace android
+
+#endif // ANDROID_FILESYSTEMS_TESTING_TEST_SUPPORT_H