132a6e48fSopenharmony_ci/* 232a6e48fSopenharmony_ci * Copyright (c) 2021 Huawei Device Co., Ltd. 332a6e48fSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 432a6e48fSopenharmony_ci * you may not use this file except in compliance with the License. 532a6e48fSopenharmony_ci * You may obtain a copy of the License at 632a6e48fSopenharmony_ci * 732a6e48fSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 832a6e48fSopenharmony_ci * 932a6e48fSopenharmony_ci * Unless required by applicable law or agreed to in writing, software 1032a6e48fSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 1132a6e48fSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1232a6e48fSopenharmony_ci * See the License for the specific language governing permissions and 1332a6e48fSopenharmony_ci * limitations under the License. 1432a6e48fSopenharmony_ci */ 1532a6e48fSopenharmony_ci#include <gtest/gtest.h> 1632a6e48fSopenharmony_ci 1732a6e48fSopenharmony_ci#include <thread> 1832a6e48fSopenharmony_ci#include <chrono> 1932a6e48fSopenharmony_ci#include <unistd.h> 2032a6e48fSopenharmony_ci#include <fstream> 2132a6e48fSopenharmony_ci 2232a6e48fSopenharmony_ci#include <buffer_utils.h> 2332a6e48fSopenharmony_ci#include "surface_buffer_impl.h" 2432a6e48fSopenharmony_ci#include "sandbox_utils.h" 2532a6e48fSopenharmony_ci 2632a6e48fSopenharmony_ci 2732a6e48fSopenharmony_ciusing namespace testing; 2832a6e48fSopenharmony_ciusing namespace testing::ext; 2932a6e48fSopenharmony_ci 3032a6e48fSopenharmony_cinamespace OHOS::Rosen { 3132a6e48fSopenharmony_ciclass BufferUtilsTest : public testing::Test { 3232a6e48fSopenharmony_cipublic: 3332a6e48fSopenharmony_ci static void SetUpTestCase(); 3432a6e48fSopenharmony_ci static void TearDownTestCase(); 3532a6e48fSopenharmony_ci 3632a6e48fSopenharmony_ci static inline BufferRequestConfig requestConfig = { 3732a6e48fSopenharmony_ci .width = 0x100, 3832a6e48fSopenharmony_ci .height = 0x100, 3932a6e48fSopenharmony_ci .strideAlignment = 0x8, 4032a6e48fSopenharmony_ci .format = GRAPHIC_PIXEL_FMT_RGBA_8888, 4132a6e48fSopenharmony_ci .usage = BUFFER_USAGE_CPU_READ | BUFFER_USAGE_CPU_WRITE | BUFFER_USAGE_MEM_DMA, 4232a6e48fSopenharmony_ci .timeout = 0, 4332a6e48fSopenharmony_ci }; 4432a6e48fSopenharmony_ci 4532a6e48fSopenharmony_ci static inline sptr<SurfaceBuffer> buffer = nullptr; 4632a6e48fSopenharmony_ci static inline std::string flagPath = "/data/bq_dump"; 4732a6e48fSopenharmony_ci static inline std::string name_ = "test"; 4832a6e48fSopenharmony_ci}; 4932a6e48fSopenharmony_ci 5032a6e48fSopenharmony_cinamespace fs = std::filesystem; 5132a6e48fSopenharmony_ci 5232a6e48fSopenharmony_civoid BufferUtilsTest::SetUpTestCase() 5332a6e48fSopenharmony_ci{ 5432a6e48fSopenharmony_ci buffer = nullptr; 5532a6e48fSopenharmony_ci 5632a6e48fSopenharmony_ci // open dump flag 5732a6e48fSopenharmony_ci std::ofstream outfile(flagPath); 5832a6e48fSopenharmony_ci outfile << "touch" << std::endl; 5932a6e48fSopenharmony_ci outfile.close(); 6032a6e48fSopenharmony_ci} 6132a6e48fSopenharmony_ci 6232a6e48fSopenharmony_civoid BufferUtilsTest::TearDownTestCase() 6332a6e48fSopenharmony_ci{ 6432a6e48fSopenharmony_ci buffer = nullptr; 6532a6e48fSopenharmony_ci 6632a6e48fSopenharmony_ci // delete dump flag 6732a6e48fSopenharmony_ci if (fs::exists(flagPath)) { 6832a6e48fSopenharmony_ci fs::remove(flagPath); 6932a6e48fSopenharmony_ci } 7032a6e48fSopenharmony_ci} 7132a6e48fSopenharmony_ci 7232a6e48fSopenharmony_ci/* 7332a6e48fSopenharmony_ci* Function: WriteToFile 7432a6e48fSopenharmony_ci* Type: Function 7532a6e48fSopenharmony_ci* Rank: Important(2) 7632a6e48fSopenharmony_ci* EnvConditions: N/A 7732a6e48fSopenharmony_ci* CaseDescription: 1. call DumpToFileAsync 7832a6e48fSopenharmony_ci* 2. check ret 7932a6e48fSopenharmony_ci */ 8032a6e48fSopenharmony_ciHWTEST_F(BufferUtilsTest, DumpToFileAsyncTest001, Function | MediumTest | Level2) 8132a6e48fSopenharmony_ci{ 8232a6e48fSopenharmony_ci const pid_t pid = GetRealPid(); 8332a6e48fSopenharmony_ci 8432a6e48fSopenharmony_ci // Alloc buffer 8532a6e48fSopenharmony_ci buffer = new SurfaceBufferImpl(); 8632a6e48fSopenharmony_ci buffer->Alloc(requestConfig); 8732a6e48fSopenharmony_ci 8832a6e48fSopenharmony_ci // Call DumpToFileAsync 8932a6e48fSopenharmony_ci GSError ret = DumpToFileAsync(pid, name_, buffer); 9032a6e48fSopenharmony_ci ASSERT_EQ(ret, OHOS::GSERROR_OK); 9132a6e48fSopenharmony_ci 9232a6e48fSopenharmony_ci // Expect Buffer Dump to be completed within 20ms. 9332a6e48fSopenharmony_ci std::chrono::milliseconds dura(20); 9432a6e48fSopenharmony_ci std::this_thread::sleep_for(dura); 9532a6e48fSopenharmony_ci 9632a6e48fSopenharmony_ci const std::string directory = "/data"; 9732a6e48fSopenharmony_ci const std::string prefix = "bq_" + std::to_string(pid) + "_" + name_; 9832a6e48fSopenharmony_ci size_t dumpFileSize = 0; 9932a6e48fSopenharmony_ci // Traverse the directory and find the dump file. 10032a6e48fSopenharmony_ci for (const auto& entry : fs::recursive_directory_iterator(directory)) { 10132a6e48fSopenharmony_ci if (entry.is_regular_file() && entry.path().filename().string().find(prefix) == 0) { 10232a6e48fSopenharmony_ci // Open the file to create a stream 10332a6e48fSopenharmony_ci std::ifstream dumpFile(entry.path(), std::ios::binary); 10432a6e48fSopenharmony_ci std::vector<uint8_t> file_data((std::istreambuf_iterator<char>(dumpFile)), 10532a6e48fSopenharmony_ci std::istreambuf_iterator<char>()); 10632a6e48fSopenharmony_ci // Get fileSize from the file stream 10732a6e48fSopenharmony_ci dumpFileSize = file_data.size(); 10832a6e48fSopenharmony_ci dumpFile.close(); 10932a6e48fSopenharmony_ci fs::remove(entry.path()); 11032a6e48fSopenharmony_ci break; 11132a6e48fSopenharmony_ci } 11232a6e48fSopenharmony_ci } 11332a6e48fSopenharmony_ci 11432a6e48fSopenharmony_ci ASSERT_EQ(dumpFileSize, buffer->GetSize()); 11532a6e48fSopenharmony_ci} 11632a6e48fSopenharmony_ci 11732a6e48fSopenharmony_ci/* 11832a6e48fSopenharmony_ci* Function: WriteToFile 11932a6e48fSopenharmony_ci* Type: Function 12032a6e48fSopenharmony_ci* Rank: Important(2) 12132a6e48fSopenharmony_ci* EnvConditions: N/A 12232a6e48fSopenharmony_ci* CaseDescription: 1. call DumpToFileAsync 12332a6e48fSopenharmony_ci* 2. check ret 12432a6e48fSopenharmony_ci */ 12532a6e48fSopenharmony_ciHWTEST_F(BufferUtilsTest, DumpToFileAsyncTest002, Function | MediumTest | Level2) 12632a6e48fSopenharmony_ci{ 12732a6e48fSopenharmony_ci const pid_t pid = GetRealPid(); 12832a6e48fSopenharmony_ci 12932a6e48fSopenharmony_ci // Alloc buffer 13032a6e48fSopenharmony_ci buffer = new SurfaceBufferImpl(); 13132a6e48fSopenharmony_ci buffer->Alloc(requestConfig); 13232a6e48fSopenharmony_ci 13332a6e48fSopenharmony_ci // Call DumpToFileAsync 13432a6e48fSopenharmony_ci GSError ret = DumpToFileAsync(pid, name_, buffer); 13532a6e48fSopenharmony_ci ASSERT_EQ(ret, OHOS::GSERROR_OK); 13632a6e48fSopenharmony_ci 13732a6e48fSopenharmony_ci // Expect Buffer Dump to be completed within 20ms. 13832a6e48fSopenharmony_ci std::chrono::milliseconds dura(20); 13932a6e48fSopenharmony_ci std::this_thread::sleep_for(dura); 14032a6e48fSopenharmony_ci 14132a6e48fSopenharmony_ci const std::string directory = "/data/storage/el1/base"; 14232a6e48fSopenharmony_ci if (access(directory.c_str(), F_OK) == 0) { 14332a6e48fSopenharmony_ci const std::string prefix = "bq_" + std::to_string(pid) + "_" + name_; 14432a6e48fSopenharmony_ci size_t dumpFileSize = 0; 14532a6e48fSopenharmony_ci // Traverse the directory and find the dump file. 14632a6e48fSopenharmony_ci for (const auto& entry : fs::recursive_directory_iterator(directory)) { 14732a6e48fSopenharmony_ci if (entry.is_regular_file() && entry.path().filename().string().find(prefix) == 0) { 14832a6e48fSopenharmony_ci // Open the file to create a stream 14932a6e48fSopenharmony_ci std::ifstream dumpFile(entry.path(), std::ios::binary); 15032a6e48fSopenharmony_ci std::vector<uint8_t> file_data((std::istreambuf_iterator<char>(dumpFile)), 15132a6e48fSopenharmony_ci std::istreambuf_iterator<char>()); 15232a6e48fSopenharmony_ci // Get fileSize from the file stream 15332a6e48fSopenharmony_ci dumpFileSize = file_data.size(); 15432a6e48fSopenharmony_ci dumpFile.close(); 15532a6e48fSopenharmony_ci fs::remove(entry.path()); 15632a6e48fSopenharmony_ci break; 15732a6e48fSopenharmony_ci } 15832a6e48fSopenharmony_ci } 15932a6e48fSopenharmony_ci 16032a6e48fSopenharmony_ci ASSERT_EQ(dumpFileSize, buffer->GetSize()); 16132a6e48fSopenharmony_ci } 16232a6e48fSopenharmony_ci} 16332a6e48fSopenharmony_ci 16432a6e48fSopenharmony_ci/* 16532a6e48fSopenharmony_ci* Function: WriteToFile 16632a6e48fSopenharmony_ci* Type: Function 16732a6e48fSopenharmony_ci* Rank: Important(2) 16832a6e48fSopenharmony_ci* EnvConditions: N/A 16932a6e48fSopenharmony_ci* CaseDescription: 1. call DumpToFileAsync 17032a6e48fSopenharmony_ci* 2. check ret 17132a6e48fSopenharmony_ci */ 17232a6e48fSopenharmony_ciHWTEST_F(BufferUtilsTest, DumpToFileAsyncTest003, Function | MediumTest | Level2) 17332a6e48fSopenharmony_ci{ 17432a6e48fSopenharmony_ci buffer = nullptr; 17532a6e48fSopenharmony_ci GSError ret = DumpToFileAsync(0, name_, buffer); 17632a6e48fSopenharmony_ci ASSERT_NE(ret, OHOS::GSERROR_OK); 17732a6e48fSopenharmony_ci} 17832a6e48fSopenharmony_ci 17932a6e48fSopenharmony_ci/* 18032a6e48fSopenharmony_ci* Function: SizeLimitTest 18132a6e48fSopenharmony_ci* Type: Function 18232a6e48fSopenharmony_ci* Rank: Important(2) 18332a6e48fSopenharmony_ci* EnvConditions: N/A 18432a6e48fSopenharmony_ci* CaseDescription: 1. make size bigger than SURFACE_PARCEL_SIZE_LIMIT and check the ret 18532a6e48fSopenharmony_ci */ 18632a6e48fSopenharmony_ciHWTEST_F(BufferUtilsTest, SizeLimitTest001, Function | MediumTest | Level2) 18732a6e48fSopenharmony_ci{ 18832a6e48fSopenharmony_ci MessageParcel parcel; 18932a6e48fSopenharmony_ci uint32_t size = SURFACE_PARCEL_SIZE_LIMIT + 1; 19032a6e48fSopenharmony_ci 19132a6e48fSopenharmony_ci BufferFlushConfigWithDamages flushConfig = { 19232a6e48fSopenharmony_ci .damages = std::vector<Rect>(size), 19332a6e48fSopenharmony_ci }; 19432a6e48fSopenharmony_ci EXPECT_EQ(WriteFlushConfig(parcel, flushConfig), GSERROR_INVALID_ARGUMENTS); 19532a6e48fSopenharmony_ci EXPECT_TRUE(parcel.WriteUint32(size)); 19632a6e48fSopenharmony_ci EXPECT_EQ(ReadFlushConfig(parcel, flushConfig), GSERROR_BINDER); 19732a6e48fSopenharmony_ci 19832a6e48fSopenharmony_ci auto infos = std::vector<BufferVerifyAllocInfo>(size); 19932a6e48fSopenharmony_ci EXPECT_EQ(WriteVerifyAllocInfo(parcel, infos), GSERROR_INVALID_ARGUMENTS); 20032a6e48fSopenharmony_ci EXPECT_TRUE(parcel.WriteUint32(size)); 20132a6e48fSopenharmony_ci ReadVerifyAllocInfo(parcel, infos); 20232a6e48fSopenharmony_ci 20332a6e48fSopenharmony_ci auto metaData = std::vector<GraphicHDRMetaData>(size); 20432a6e48fSopenharmony_ci EXPECT_EQ(WriteHDRMetaData(parcel, metaData), GSERROR_INVALID_ARGUMENTS); 20532a6e48fSopenharmony_ci EXPECT_TRUE(parcel.WriteUint32(size)); 20632a6e48fSopenharmony_ci EXPECT_EQ(ReadHDRMetaData(parcel, metaData), GSERROR_BINDER); 20732a6e48fSopenharmony_ci 20832a6e48fSopenharmony_ci auto metaDataSet = std::vector<uint8_t>(size); 20932a6e48fSopenharmony_ci EXPECT_EQ(WriteHDRMetaDataSet(parcel, metaDataSet), GSERROR_INVALID_ARGUMENTS); 21032a6e48fSopenharmony_ci EXPECT_TRUE(parcel.WriteUint32(size)); 21132a6e48fSopenharmony_ci EXPECT_EQ(ReadHDRMetaDataSet(parcel, metaDataSet), GSERROR_BINDER); 21232a6e48fSopenharmony_ci 21332a6e48fSopenharmony_ci GraphicExtDataHandle *handle = static_cast<GraphicExtDataHandle *>( 21432a6e48fSopenharmony_ci malloc(sizeof(GraphicExtDataHandle) + sizeof(int32_t))); 21532a6e48fSopenharmony_ci handle->fd = -1; 21632a6e48fSopenharmony_ci handle->reserveInts = size; 21732a6e48fSopenharmony_ci handle->reserve[0] = 0; 21832a6e48fSopenharmony_ci sptr<SurfaceTunnelHandle> tunnelHandle = new SurfaceTunnelHandle(); 21932a6e48fSopenharmony_ci EXPECT_EQ(WriteExtDataHandle(parcel, handle), GSERROR_INVALID_ARGUMENTS); 22032a6e48fSopenharmony_ci EXPECT_TRUE(parcel.WriteUint32(size)); 22132a6e48fSopenharmony_ci EXPECT_EQ(ReadExtDataHandle(parcel, tunnelHandle), GSERROR_BINDER); 22232a6e48fSopenharmony_ci} 22332a6e48fSopenharmony_ci}