1 // Copyright 2014 The Android Open Source Project
2 //
3 // This software is licensed under the terms of the GNU General Public
4 // License version 2, as published by the Free Software Foundation, and
5 // may be copied, distributed, and modified under those terms.
6 //
7 // This program is distributed in the hope that it will be useful,
8 // but WITHOUT ANY WARRANTY; without even the implied warranty of
9 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 // GNU General Public License for more details.
11
12 #include "android/filesystems/ext4_utils.h"
13
14 #include "android/base/EintrWrapper.h"
15 #include "android/base/Log.h"
16 #include "android/base/files/ScopedStdioFile.h"
17 #include "android/filesystems/testing/TestExt4ImageHeader.h"
18 #include "android/filesystems/testing/TestSupport.h"
19
20 #include <gtest/gtest.h>
21
22 #include <string>
23
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27
28 #ifdef _WIN32
29 #include <windows.h>
30 #endif
31
32 using android::base::ScopedStdioFile;
33 using android::testing::CreateTempFilePath;
34
35 class Ext4UtilsTest : public ::testing::Test {
36 public:
Ext4UtilsTest()37 Ext4UtilsTest() : mTempFilePath() {
38 ::memset(mImage, 0, sizeof mImage);
39 ::memcpy(mImage, kTestExt4ImageHeader, kTestExt4ImageHeaderSize);
40 }
41
~Ext4UtilsTest()42 ~Ext4UtilsTest() {
43 if (!mTempFilePath.empty()) {
44 HANDLE_EINTR(unlink(mTempFilePath.c_str()));
45 }
46 }
47
48 protected:
49 // Create a temporary file with up to |maxBytes| bytes of |mImage|
50 // in it, and return its path. The file will be removed in the
51 // destructor.
createTempFile(size_t maxBytes)52 const char* createTempFile(size_t maxBytes) {
53 CHECK(maxBytes <= sizeof mImage);
54 // TODO(digit): Replace with something else.
55 mTempFilePath = CreateTempFilePath();
56 ScopedStdioFile file(fopen(mTempFilePath.c_str(), "wb"));
57 PCHECK(file.get()) << "Could not create temporary file!";
58 PCHECK(::fwrite(mImage, maxBytes, 1, file.get()) == 1)
59 << "Could not write " << maxBytes << " bytes to "
60 << "temporary file";
61 file.close();
62 return mTempFilePath.c_str();
63 }
64
65 // Create the path of a temporary file, but do not create or
66 // populate it. The file is removed in the destructor.
createTempPath()67 const char* createTempPath() {
68 mTempFilePath = CreateTempFilePath();
69 return mTempFilePath.c_str();
70 }
71
72 std::string mTempFilePath;
73 char mImage[kTestExt4ImageHeaderSize * 2U];
74 };
75
TEST_F(Ext4UtilsTest,android_pathIsExt4PartitionImage)76 TEST_F(Ext4UtilsTest, android_pathIsExt4PartitionImage) {
77 const char* path = createTempFile(kTestExt4ImageHeaderSize);
78 EXPECT_TRUE(android_pathIsExt4PartitionImage(path));
79 }
80
TEST_F(Ext4UtilsTest,android_pathIsExt4PartitionImageTruncated)81 TEST_F(Ext4UtilsTest, android_pathIsExt4PartitionImageTruncated) {
82 const char* path = createTempFile(kTestExt4ImageHeaderSize - 2U);
83 EXPECT_FALSE(android_pathIsExt4PartitionImage(path));
84 }
85
TEST_F(Ext4UtilsTest,android_pathIsExt4PartitionImageCorrupted)86 TEST_F(Ext4UtilsTest, android_pathIsExt4PartitionImageCorrupted) {
87 memset(mImage, 0x55, sizeof mImage);
88 const char* path = createTempFile(sizeof mImage);
89 EXPECT_FALSE(android_pathIsExt4PartitionImage(path));
90 }
91
TEST_F(Ext4UtilsTest,android_pathIsExt4PartitionImageBadMagic1)92 TEST_F(Ext4UtilsTest, android_pathIsExt4PartitionImageBadMagic1) {
93 mImage[kTestExt4ImageHeaderSize - 1] = 0;
94 const char* path = createTempFile(sizeof mImage);
95 EXPECT_FALSE(android_pathIsExt4PartitionImage(path));
96 }
97
TEST_F(Ext4UtilsTest,android_pathIsExt4PartitionImageBadMagic2)98 TEST_F(Ext4UtilsTest, android_pathIsExt4PartitionImageBadMagic2) {
99 mImage[kTestExt4ImageHeaderSize - 2] = 0;
100 const char* path = createTempFile(sizeof mImage);
101 EXPECT_FALSE(android_pathIsExt4PartitionImage(path));
102 }
103
TEST_F(Ext4UtilsTest,android_createEmptyExt4Partition)104 TEST_F(Ext4UtilsTest, android_createEmptyExt4Partition) {
105 const char* tempPath = createTempPath();
106 uint64_t kSize = 32 * 1024 * 1024;
107 int ret = android_createEmptyExt4Image(tempPath, kSize, "cache");
108 EXPECT_EQ(0, ret);
109 EXPECT_TRUE(android_pathIsExt4PartitionImage(tempPath));
110 }
111