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 32using android::base::ScopedStdioFile; 33using android::testing::CreateTempFilePath; 34 35class Ext4UtilsTest : public ::testing::Test { 36public: 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 48protected: 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 76TEST_F(Ext4UtilsTest, android_pathIsExt4PartitionImage) { 77 const char* path = createTempFile(kTestExt4ImageHeaderSize); 78 EXPECT_TRUE(android_pathIsExt4PartitionImage(path)); 79} 80 81TEST_F(Ext4UtilsTest, android_pathIsExt4PartitionImageTruncated) { 82 const char* path = createTempFile(kTestExt4ImageHeaderSize - 2U); 83 EXPECT_FALSE(android_pathIsExt4PartitionImage(path)); 84} 85 86TEST_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 92TEST_F(Ext4UtilsTest, android_pathIsExt4PartitionImageBadMagic1) { 93 mImage[kTestExt4ImageHeaderSize - 1] = 0; 94 const char* path = createTempFile(sizeof mImage); 95 EXPECT_FALSE(android_pathIsExt4PartitionImage(path)); 96} 97 98TEST_F(Ext4UtilsTest, android_pathIsExt4PartitionImageBadMagic2) { 99 mImage[kTestExt4ImageHeaderSize - 2] = 0; 100 const char* path = createTempFile(sizeof mImage); 101 EXPECT_FALSE(android_pathIsExt4PartitionImage(path)); 102} 103 104TEST_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