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: 37 Ext4UtilsTest() : mTempFilePath() { 38 ::memset(mImage, 0, sizeof mImage); 39 ::memcpy(mImage, kTestExt4ImageHeader, kTestExt4ImageHeaderSize); 40 } 41 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. 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. 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 76 TEST_F(Ext4UtilsTest, android_pathIsExt4PartitionImage) { 77 const char* path = createTempFile(kTestExt4ImageHeaderSize); 78 EXPECT_TRUE(android_pathIsExt4PartitionImage(path)); 79 } 80 81 TEST_F(Ext4UtilsTest, android_pathIsExt4PartitionImageTruncated) { 82 const char* path = createTempFile(kTestExt4ImageHeaderSize - 2U); 83 EXPECT_FALSE(android_pathIsExt4PartitionImage(path)); 84 } 85 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 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 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 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