graphictest

Signed-off-by: 王德海 <wangdehai2@huawei.com>
Change-Id: Ie52e62a3c59b2cde075ed0f4f63eb4054cd1be3b
This commit is contained in:
王德海 2024-08-06 14:32:29 +08:00
parent bf21fcc49c
commit cc3ef44056
9 changed files with 225 additions and 22 deletions

View File

@ -107,7 +107,7 @@ ohos_shared_library("rs_graphic_test") {
subsystem_name = "graphic"
}
ohos_shared_library("rs_graphic_test_main") {
ohos_static_library("rs_graphic_test_main") {
branch_protector_ret = "pac_ret"
sanitize = {
cfi = true

View File

@ -33,7 +33,6 @@ public:
void SetSurfaceBounds(const Vector4f& bounds);
void SetSurfaceColor(const RSColor& color);
void RegisterNode(std::shared_ptr<RSNode> node);
void SetImageSavePath(const std::string path);
// overrides gtest functions
static void SetUpTestCase();
@ -46,6 +45,8 @@ public:
virtual void AfterEach() {};
private:
std::string GetImageSavePath(const std::string path);
bool shouldRunTest_ = true;
Vector4f surfaceBounds_;
std::vector<std::shared_ptr<RSNode>> nodes_;

View File

@ -24,6 +24,7 @@
namespace OHOS {
namespace Rosen {
class VSyncWaiter;
class RSGraphicTestDirector {
public:
~RSGraphicTestDirector();
@ -31,6 +32,7 @@ public:
void Run();
void FlushMessage();
std::shared_ptr<Media::PixelMap> TakeScreenCaptureAndWait(int ms);
void WaitForVSync(size_t count = 1);
void ResetImagePath();
std::shared_ptr<RSGraphicRootNode> GetRootNode() const;
@ -48,6 +50,7 @@ private:
std::shared_ptr<OHOS::AppExecFwk::EventRunner> runner_;
std::shared_ptr<OHOS::AppExecFwk::EventHandler> handler_;
std::shared_ptr<VSyncWaiter> vsyncWaiter_;
friend class RSGraphicTest;
};

View File

@ -45,6 +45,7 @@ struct TestDefInfo {
std::string testName;
RSGraphicTestType testType;
RSGraphicTestMode testMode;
std::string filePath;
};
class TestDefManager {
@ -54,7 +55,8 @@ private:
public:
static TestDefManager& Instance();
bool Regist(const char* testCaseName, const char* testName, RSGraphicTestType type, RSGraphicTestMode mode);
bool Regist(const char* testCaseName, const char* testName, RSGraphicTestType type, RSGraphicTestMode mode,
const char* filePath);
const TestDefInfo* GetTestInfo(const char* testCaseName, const char* testName) const;
std::vector<const TestDefInfo*> GetTestInfosByType(RSGraphicTestType type) const;
};
@ -63,7 +65,7 @@ public:
#define GRAPHIC_TEST_PARAMS(test_case_name, test_name, test_type, test_mode) \
bool GTEST_TEST_UNIQUE_ID_(test_case_name, test_name, __LINE__) = \
OHOS::Rosen::TestDefManager::Instance().Regist(#test_case_name, #test_name, test_type, test_mode); \
OHOS::Rosen::TestDefManager::Instance().Regist(#test_case_name, #test_name, test_type, test_mode, __FILE__); \
TEST_F(test_case_name, test_name)
#define GRAPHIC_TEST_2(test_type, test_name) \

View File

@ -30,12 +30,13 @@ public:
static const RSParameterParse& Instance();
static void Parse(int argc, char **argv);
std::string imageSavePath = "/data/local/rs_graphic_tests/";
std::string imageSavePath = "/data/local/graphic_test/";
int testCaseWaitTime = 1000; //ms
int surfaceCaptureWaitTime = 1000; //ms
int manualTestWaitTime = 1500; //ms
std::unordered_set<RSGraphicTestType> filterTestTypes = {};
RSGraphicTestMode runTestMode = RSGraphicTestMode::ALL;
int32_t vsynRate = 1;
};
} // namespace Rosen

View File

@ -20,9 +20,10 @@
#include "ui/rs_root_node.h"
#include "ui/rs_surface_node.h"
#include <thread>
#include <chrono>
#include <filesystem>
#include <iostream>
#include <thread>
namespace OHOS {
namespace Rosen {
@ -92,7 +93,7 @@ void RSGraphicTest::TearDown()
}
RSGraphicTestDirector::Instance().FlushMessage();
WaitTimeout(RSParameterParse::Instance().testCaseWaitTime);
RSGraphicTestDirector::Instance().WaitForVSync();
const ::testing::TestInfo* const testInfo =
::testing::UnitTest::GetInstance()->current_test_info();
@ -111,10 +112,7 @@ void RSGraphicTest::TearDown()
auto pixelMap = RSGraphicTestDirector::Instance().TakeScreenCaptureAndWait(
RSParameterParse::Instance().surfaceCaptureWaitTime);
if (pixelMap) {
std::string filename = RSParameterParse::Instance().imageSavePath;
if (imageSavePath_ != "") {
filename = imageSavePath_;
}
std::string filename = GetImageSavePath(extInfo->filePath);
filename += testInfo->test_case_name() + std::string("_");
filename += testInfo->name() + std::string(".png");
if (std::filesystem::exists(filename)) {
@ -131,7 +129,7 @@ void RSGraphicTest::TearDown()
GetRootNode()->ResetTestSurface();
RSGraphicTestDirector::Instance().FlushMessage();
WaitTimeout(RSParameterParse::Instance().testCaseWaitTime);
RSGraphicTestDirector::Instance().WaitForVSync();
++imageWriteId_;
}
@ -161,20 +159,26 @@ void RSGraphicTest::SetSurfaceColor(const RSColor& color)
RSGraphicTestDirector::Instance().SetSurfaceColor(color);
}
void RSGraphicTest::SetImageSavePath(const std::string path)
std::string RSGraphicTest::GetImageSavePath(const std::string path)
{
std::string imagePath = "/data/local/";
size_t posCnt = path.rfind("/") + 1;
std::string subPath = path.substr(0, posCnt);
imagePath.append(subPath);
namespace fs = std::filesystem;
if (!fs::exists(path)) {
if (!fs::create_directories(path)) {
if (!fs::exists(imagePath)) {
if (!fs::create_directories(imagePath)) {
LOGE("RSGraphicTestDirector create dir failed");
}
} else {
if (!fs::is_directory(path)) {
if (!fs::is_directory(imagePath)) {
LOGE("RSGraphicTestDirector path is not dir");
return;
}
}
imageSavePath_ = path;
retrun imagePath;
}
} // namespace Rosen

View File

@ -61,6 +61,43 @@ public:
};
}
class VSyncWaiter {
public:
VSyncWaiter(std::shared_ptr<OHOS::AppExecFwk::EventHandler> handler, int32_t rate)
{
frameCallback_ = {
.userData_ = this,
.callback_ = std::bind(&VSyncWaiter::OnVSync, this);
};
vsyncReceiver_ = RSInterfaces::GetInstance().CreateVSyncReceiver("RSGraphicTest", handler);
vsyncReceiver_->Init();
vsyncReceiver_->SetVSyncRate(frameCallback_, rate);
}
void OnVSync()
{
{
std::unique_lock lock(mutex_);
++counts_;
}
cv_.notify_all();
}
void WaitForVSync(size_t count)
{
std::unique_lock lock(mutex_);
count += counts_;
cv_.wait(lock, [this, count] { return counts_ >= count; });
}
private:
std::mutex mutex_;
std::condition_variable cv_;
size_t counts_ = 0;
std::shared_ptr<OHOS::Rosen::VSyncReceiver> vsyncReceiver_;
Rosen::VSyncReceiver::FrameCallback frameCallback_;
}
RSGraphicTestDirector& RSGraphicTestDirector::Instance()
{
static RSGraphicTestDirector instance;
@ -71,7 +108,7 @@ RSGraphicTestDirector::~RSGraphicTestDirector()
{
rootNode_->screenSurfaceNode_->RemoveFromTree();
rsUiDirector_->SendMessages();
sleep(1);
vsyncWaiter_ = nullptr;
}
void RSGraphicTestDirector::Run()
@ -85,6 +122,7 @@ void RSGraphicTestDirector::Run()
[handler](const std::function<void()>& task, uint32_t delay) { handler->PostTask(task); });
runner->Run();
vsyncWaiter_ = std::make_shared<VSyncWaiter>(handler_, RSParameterParse::Instance().vsyncRate);
screenId_ = RSInterfaces::GetInstance().GetDefaultScreenId();
auto defaultDisplay = DisplayManager::GetInstance().GetDefaultDisplay();
@ -100,7 +138,7 @@ void RSGraphicTestDirector::Run()
rsUiDirector_->SetRSSurfaceNode(rootNode_->screenSurfaceNode_);
rsUiDirector_->SendMessages();
sleep(1);
WaitForVSync();
ResetImagePath();
}
@ -160,5 +198,11 @@ void RSGraphicTestDirector::SetSurfaceColor(const RSColor& color)
}
}
void RSGraphicTestDirector::WaitForVSync(size_t count)
{
if (vsyncWaiter_) {
vsyncWaiter_->WaitForVSync(count);
}
}
} // namespace Rosen
} // namespace OHOS

View File

@ -31,7 +31,7 @@ TestDefManager& TestDefManager::Instance()
}
bool TestDefManager::Regist(const char* testCaseName, const char* testName,
RSGraphicTestType type, RSGraphicTestMode mode)
RSGraphicTestType type, RSGraphicTestMode mode, const char* filePath)
{
const auto& name = GetTestName(testCaseName, testName);
if (testInfos_.find(name) != testInfos_.end()) {
@ -39,7 +39,15 @@ bool TestDefManager::Regist(const char* testCaseName, const char* testName,
return false;
}
testInfos_.emplace(name, TestDefInfo {testCaseName, testName, type, mode});
std::string startPath = "graphic_test/";
size_t startPos = std::string(filePath).find(startPath) + startPath.length();
if (startPos == std::string::npos) {
LOGE("TestDefManager::Regist fail filePath %{public}s", filePath.c_str());
return false;
}
std::string savePath = std::string(filePath).substr(startPos);
testInfos_.emplace(name, TestDefInfo {testCaseName, testName, type, mode, savePath});
return true;
}
@ -65,5 +73,21 @@ std::vector<const TestDefInfo*> TestDefManager::GetTestInfosByType(RSGraphicTest
return infos;
}
static inline bool Cmp(const TestDefInfo* info1, const TestDefInfo* info2)
{
retrun info1->filePath < info2->filePath;
}
std::vector<const TestDefInfo*> TestDefManager::GetAllTestInfos() const
{
std::vector<const TestDefInfo*> infos;
for (const auto& it: testInfos_) {
infos.push_back(&it.second);
}
sort(infos.begin(), infos.end(), Cmp);
return infos;
}
} // namespace Rosen
} // namespace OHOS

View File

@ -16,13 +16,137 @@
#include "rs_graphic_test.h"
#include "rs_graphic_test_director.h"
#include "rs_parameter_parse.h"
#include "rs_graphic_test_ext.h"
#include <iostream>
#include <string>
using namespace OHOS;
using namespace OHOS::Rosen;
using namespace std;
typedef int (*ProcFunc)(int argc, char **argv);
typedef struct {
string oid;
ProcFunc procFunc;
} GraphicTestCommandTb;
static void SplitString(const string& str, vector<string>& vec, const string& pattern)
{
string::size_type pos1 = 0;
string::size_type pos2 = str.find(pattern);
while (pos2 != string::npos) {
vec.push_back(str.substr(pos1, pos2 - pos1));
pos1 = pos2 + pattern.size();
pos2 = str.find(pattern, pos1);
}
if (pos1 != str.length()) {
vec.push_back(str.substr(pos1));
}
}
static void DisplayCaseLayer(vector<string>& curlayerInfo, vector<string>& layerInfo)
{
for (uint32_t loop = 0; loop < curlayerInfo.size(); loop++) {
if (loop >= layerInfo.size()) {
layerInfo.push_back(curlayerInfo[loop]);
} else if (curlayerInfo[loop] == layerInfo[loop]) {
continue;
} else {
layerInfo[loop] = curlayerInfo[loop];
}
string out {};
for (uint32_t idx = 0; idx < loop; idx++) {
out.append("| ");
}
out.append("|--").append(curlayerInfo[loop]);
cout << out << endl;
}
}
static int DisplayAllCaseInfo(int argc, char **argv)
{
vector<const TestDefInfo*> info = ::OHOS::Rosen::TestDefManager::Instance().GetAllTestInfos();
vector<string> layerInfo {};
vector<string> curlayerInfo {};
string findPath = "graphic_test";
if (argc == 3) {
findPath = string(argv[2]);
}
cout << findPath << endl;
findPath.append("/");
for (uint32_t loop = 0; loop < info.size(); loop++) {
string filePath = info[loop]->filePath;
if (filePath.find(findPath) == string::npos) {
continue;
}
size_t startPos = filePath.find(findPath) + findPath.length();
if (filePath.rfind("/") > startPos) {
string subPath = filePath.substr(startPos, filePath.rfind("/") - startPos);
SplitString(subPath, curlayerInfo, "/");
}
curlayerInfo.push_back(info[loop]->testCaseName);
DisplayCaseLayer(curlayerInfo, layerInfo);
string out {};
for (uint32_t idx = 0; idx < curlayerInfo.size() - 1; idx++) {
out.append("| ");
}
out.append(" |--").append(info[loop]->testName);
cout << out << endl;
curlayerInfo.clear();
}
return 0;
}
static int FilterTestUnit(int argc, char **argv)
{
string unitName;
string caseName = "*";
switch (argc) {
case 3:
unitName = argv[2];
break;
case 4:
unitName = argv[2];
caseName = argv[3];
break;
default:
cout << "format fail [-unit unitName [caseName]]" << endl;
return 0;
}
int argcTemp = 2;
string filter = "--gtest_filter=";
filter.append(unitName).append(".").append(caseName);
argv[1] = (char*)filter.c_str();
RSGraphicTestDirector::Instance().Run();
testing::InitGoogleTest(&argcTemp, argv);
return RUN_ALL_TESTS();
}
int main(int argc, char **argv)
{
RSParameterParse::Parse(argc, argv);
GraphicTestCommandTb funcTbl[] = {
{ "-list", DisplayAllCaseInfo },
{ "-unit", FilterTestUnit }
};
if (argc >= 2) {
size_t tblCnt = sizeof(funcTbl) / sizeof(funcTbl[0]);
for (uint32_t paraNo = 0; paraNo < tblCnt; paraNo++) {
if (funcTbl[paraNo].oid == string(argv[1])) {
return funcTbl[paraNo].procFunc(argc, argv);
}
}
}
RSGraphicTestDirector::Instance().Run();
testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();