1/* 2 * Copyright (c) 2021 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15#include <gtest/gtest.h> 16 17#include <thread> 18#include <chrono> 19#include <unistd.h> 20#include <fstream> 21 22#include <buffer_utils.h> 23#include "surface_buffer_impl.h" 24#include "sandbox_utils.h" 25 26 27using namespace testing; 28using namespace testing::ext; 29 30namespace OHOS::Rosen { 31class BufferUtilsTest : public testing::Test { 32public: 33 static void SetUpTestCase(); 34 static void TearDownTestCase(); 35 36 static inline BufferRequestConfig requestConfig = { 37 .width = 0x100, 38 .height = 0x100, 39 .strideAlignment = 0x8, 40 .format = GRAPHIC_PIXEL_FMT_RGBA_8888, 41 .usage = BUFFER_USAGE_CPU_READ | BUFFER_USAGE_CPU_WRITE | BUFFER_USAGE_MEM_DMA, 42 .timeout = 0, 43 }; 44 45 static inline sptr<SurfaceBuffer> buffer = nullptr; 46 static inline std::string flagPath = "/data/bq_dump"; 47 static inline std::string name_ = "test"; 48}; 49 50namespace fs = std::filesystem; 51 52void BufferUtilsTest::SetUpTestCase() 53{ 54 buffer = nullptr; 55 56 // open dump flag 57 std::ofstream outfile(flagPath); 58 outfile << "touch" << std::endl; 59 outfile.close(); 60} 61 62void BufferUtilsTest::TearDownTestCase() 63{ 64 buffer = nullptr; 65 66 // delete dump flag 67 if (fs::exists(flagPath)) { 68 fs::remove(flagPath); 69 } 70} 71 72/* 73* Function: WriteToFile 74* Type: Function 75* Rank: Important(2) 76* EnvConditions: N/A 77* CaseDescription: 1. call DumpToFileAsync 78* 2. check ret 79 */ 80HWTEST_F(BufferUtilsTest, DumpToFileAsyncTest001, Function | MediumTest | Level2) 81{ 82 const pid_t pid = GetRealPid(); 83 84 // Alloc buffer 85 buffer = new SurfaceBufferImpl(); 86 buffer->Alloc(requestConfig); 87 88 // Call DumpToFileAsync 89 GSError ret = DumpToFileAsync(pid, name_, buffer); 90 ASSERT_EQ(ret, OHOS::GSERROR_OK); 91 92 // Expect Buffer Dump to be completed within 20ms. 93 std::chrono::milliseconds dura(20); 94 std::this_thread::sleep_for(dura); 95 96 const std::string directory = "/data"; 97 const std::string prefix = "bq_" + std::to_string(pid) + "_" + name_; 98 size_t dumpFileSize = 0; 99 // Traverse the directory and find the dump file. 100 for (const auto& entry : fs::recursive_directory_iterator(directory)) { 101 if (entry.is_regular_file() && entry.path().filename().string().find(prefix) == 0) { 102 // Open the file to create a stream 103 std::ifstream dumpFile(entry.path(), std::ios::binary); 104 std::vector<uint8_t> file_data((std::istreambuf_iterator<char>(dumpFile)), 105 std::istreambuf_iterator<char>()); 106 // Get fileSize from the file stream 107 dumpFileSize = file_data.size(); 108 dumpFile.close(); 109 fs::remove(entry.path()); 110 break; 111 } 112 } 113 114 ASSERT_EQ(dumpFileSize, buffer->GetSize()); 115} 116 117/* 118* Function: WriteToFile 119* Type: Function 120* Rank: Important(2) 121* EnvConditions: N/A 122* CaseDescription: 1. call DumpToFileAsync 123* 2. check ret 124 */ 125HWTEST_F(BufferUtilsTest, DumpToFileAsyncTest002, Function | MediumTest | Level2) 126{ 127 const pid_t pid = GetRealPid(); 128 129 // Alloc buffer 130 buffer = new SurfaceBufferImpl(); 131 buffer->Alloc(requestConfig); 132 133 // Call DumpToFileAsync 134 GSError ret = DumpToFileAsync(pid, name_, buffer); 135 ASSERT_EQ(ret, OHOS::GSERROR_OK); 136 137 // Expect Buffer Dump to be completed within 20ms. 138 std::chrono::milliseconds dura(20); 139 std::this_thread::sleep_for(dura); 140 141 const std::string directory = "/data/storage/el1/base"; 142 if (access(directory.c_str(), F_OK) == 0) { 143 const std::string prefix = "bq_" + std::to_string(pid) + "_" + name_; 144 size_t dumpFileSize = 0; 145 // Traverse the directory and find the dump file. 146 for (const auto& entry : fs::recursive_directory_iterator(directory)) { 147 if (entry.is_regular_file() && entry.path().filename().string().find(prefix) == 0) { 148 // Open the file to create a stream 149 std::ifstream dumpFile(entry.path(), std::ios::binary); 150 std::vector<uint8_t> file_data((std::istreambuf_iterator<char>(dumpFile)), 151 std::istreambuf_iterator<char>()); 152 // Get fileSize from the file stream 153 dumpFileSize = file_data.size(); 154 dumpFile.close(); 155 fs::remove(entry.path()); 156 break; 157 } 158 } 159 160 ASSERT_EQ(dumpFileSize, buffer->GetSize()); 161 } 162} 163 164/* 165* Function: WriteToFile 166* Type: Function 167* Rank: Important(2) 168* EnvConditions: N/A 169* CaseDescription: 1. call DumpToFileAsync 170* 2. check ret 171 */ 172HWTEST_F(BufferUtilsTest, DumpToFileAsyncTest003, Function | MediumTest | Level2) 173{ 174 buffer = nullptr; 175 GSError ret = DumpToFileAsync(0, name_, buffer); 176 ASSERT_NE(ret, OHOS::GSERROR_OK); 177} 178 179/* 180* Function: SizeLimitTest 181* Type: Function 182* Rank: Important(2) 183* EnvConditions: N/A 184* CaseDescription: 1. make size bigger than SURFACE_PARCEL_SIZE_LIMIT and check the ret 185 */ 186HWTEST_F(BufferUtilsTest, SizeLimitTest001, Function | MediumTest | Level2) 187{ 188 MessageParcel parcel; 189 uint32_t size = SURFACE_PARCEL_SIZE_LIMIT + 1; 190 191 BufferFlushConfigWithDamages flushConfig = { 192 .damages = std::vector<Rect>(size), 193 }; 194 EXPECT_EQ(WriteFlushConfig(parcel, flushConfig), GSERROR_INVALID_ARGUMENTS); 195 EXPECT_TRUE(parcel.WriteUint32(size)); 196 EXPECT_EQ(ReadFlushConfig(parcel, flushConfig), GSERROR_BINDER); 197 198 auto infos = std::vector<BufferVerifyAllocInfo>(size); 199 EXPECT_EQ(WriteVerifyAllocInfo(parcel, infos), GSERROR_INVALID_ARGUMENTS); 200 EXPECT_TRUE(parcel.WriteUint32(size)); 201 ReadVerifyAllocInfo(parcel, infos); 202 203 auto metaData = std::vector<GraphicHDRMetaData>(size); 204 EXPECT_EQ(WriteHDRMetaData(parcel, metaData), GSERROR_INVALID_ARGUMENTS); 205 EXPECT_TRUE(parcel.WriteUint32(size)); 206 EXPECT_EQ(ReadHDRMetaData(parcel, metaData), GSERROR_BINDER); 207 208 auto metaDataSet = std::vector<uint8_t>(size); 209 EXPECT_EQ(WriteHDRMetaDataSet(parcel, metaDataSet), GSERROR_INVALID_ARGUMENTS); 210 EXPECT_TRUE(parcel.WriteUint32(size)); 211 EXPECT_EQ(ReadHDRMetaDataSet(parcel, metaDataSet), GSERROR_BINDER); 212 213 GraphicExtDataHandle *handle = static_cast<GraphicExtDataHandle *>( 214 malloc(sizeof(GraphicExtDataHandle) + sizeof(int32_t))); 215 handle->fd = -1; 216 handle->reserveInts = size; 217 handle->reserve[0] = 0; 218 sptr<SurfaceTunnelHandle> tunnelHandle = new SurfaceTunnelHandle(); 219 EXPECT_EQ(WriteExtDataHandle(parcel, handle), GSERROR_INVALID_ARGUMENTS); 220 EXPECT_TRUE(parcel.WriteUint32(size)); 221 EXPECT_EQ(ReadExtDataHandle(parcel, tunnelHandle), GSERROR_BINDER); 222} 223}