TDD_benchmarktest总结
简介
基准测试(benchmarking)是一种测量和评估软件性能指标的活动,可以在某个时候通过基准测试建立一个已知的性能水平(称为基准线),当系统的软硬件环境发生变化之后再进行一次基准测试以确定那些变化对性能的影响。这是基准测试最常见的用途,其他用途包括测定某种负载水平下的性能极限、管理系统或环境的变化、发现可能导致性能问题的条件等。
测试框架
benchmarktest
----xxx_test
--------xxx_test.cpp
--------BUILD.gn
----BUILD.gn
编写avsession_test.cpp
#include <benchmark/benchmark.h>
#include <unistd.h>
using namespace OHOS::XXX;
namespace {
const int32_t NUM_THREADS = 4;
static int32_t g_onCall = AVSESSION_ERROR;
static int32_t g_sessionId = AVSESSION_ERROR;
static char g_testSessionTag[] = "test";
static char g_testBundleName[] = "test.ohos.avsession";
static char g_testAbilityName[] = "test.ability";
class AVSessionTest : public benchmark::Fixture {
public:
AVSessionTest()
{
Iterations(iterations);
Repetitions(repetitions);
ReportAggregatesOnly();
}
~AVSessionTest() override = default;
void SetUp(const ::benchmark::State& state) override
{
OHOS::AppExecFwk::ElementName elementName;
elementName.SetBundleName(g_testBundleName);
elementName.SetAbilityName(g_testAbilityName);
avsession_ =
AVSessionManager::GetInstance().CreateSession(g_testSessionTag, AVSession::SESSION_TYPE_AUDIO, elementName);
if (avsession_ == nullptr) {
SLOGE("%{public}s error, failed to CreateSession, avsession_ nullptr.", __func__);
}
g_sessionId++;
AVSessionManager::GetInstance().CreateController(avsession_->GetSessionId(), controller_);
if (controller_ == nullptr) {
SLOGE("%{public}s error, failed to CreateController, controller_ nullptr.", __func__);
}
}
void TearDown(const ::benchmark::State& state) override
{
int32_t ret = AVSESSION_ERROR;
if (avsession_) {
ret = avsession_->Destroy();
avsession_ = nullptr;
}
if (controller_) {
ret = controller_->Destroy();
controller_ = nullptr;
}
g_onCall = AVSESSION_ERROR;
}
protected:
const int32_t repetitions = 3;
const int32_t iterations = 20;
static constexpr int SESSION_LEN = 64;
std::shared_ptr<AVSession> avsession_;
std::shared_ptr<AVSessionController> controller_;
};
class AVSessionCallbackImpl : public AVSessionCallback {
public:
void OnPlay() override;
void OnPause() override;
void OnStop() override;
void OnPlayNext() override;
void OnPlayPrevious() override;
void OnFastForward() override;
void OnRewind() override;
void OnSeek(int64_t time) override;
void OnSetSpeed(double speed) override;
void OnSetLoopMode(int32_t loopMode) override;
void OnToggleFavorite(const std::string& mediald) override;
void OnMediaKeyEvent(const OHOS::MMI::KeyEvent& keyEvent) override;
~AVSessionCallbackImpl() override;
};
void AVSessionCallbackImpl::OnPlay()
{
g_onCall = AVSESSION_SUCCESS;
SLOGI("OnPlay %{public}d", g_onCall);
}
void AVSessionCallbackImpl::OnPause()
{
g_onCall = AVSESSION_SUCCESS;
SLOGI("OnPause %{public}d", g_onCall);
}
void AVSessionCallbackImpl::OnStop()
{
g_onCall = AVSESSION_SUCCESS;
SLOGI("OnStop %{public}d", g_onCall);
}
void AVSessionCallbackImpl::OnPlayNext()
{
g_onCall = AVSESSION_SUCCESS;
SLOGI("OnPlayNext %{public}d", g_onCall);
}
void AVSessionCallbackImpl::OnPlayPrevious()
{
g_onCall = AVSESSION_SUCCESS;
SLOGI("OnPlayPrevious %{public}d", g_onCall);
}
void AVSessionCallbackImpl::OnFastForward()
{
g_onCall = AVSESSION_SUCCESS;
SLOGI("OnFastForward %{public}d", g_onCall);
}
void AVSessionCallbackImpl::OnRewind()
{
g_onCall = AVSESSION_SUCCESS;
SLOGI("OnRewind %{public}d", g_onCall);
}
void AVSessionCallbackImpl::OnSeek(int64_t time)
{
SLOGI("OnSeek %{public}" PRId64, time);
g_onCall = AVSESSION_SUCCESS;
}
void AVSessionCallbackImpl::OnSetSpeed(double speed)
{
SLOGI("OnSetSpeed %{public}f", speed);
g_onCall = AVSESSION_SUCCESS;
SLOGI("OnSetSpeed %{public}d", g_onCall);
}
void AVSessionCallbackImpl::OnSetLoopMode(int32_t loopMode)
{
SLOGI("OnSetLoopMode %{public}d", loopMode);
g_onCall = AVSESSION_SUCCESS;
SLOGI("OnSetLoopMode %{public}d", g_onCall);
}
void AVSessionCallbackImpl::OnToggleFavorite(const std::string& mediald)
{
SLOGI("OnToggleFavorite %{public}s", mediald.c_str());
g_onCall = AVSESSION_SUCCESS;
SLOGI("OnToggleFavorite %{public}d", g_onCall);
}
void AVSessionCallbackImpl::OnMediaKeyEvent(const OHOS::MMI::KeyEvent& keyEvent)
{
SLOGI("OnMediaKeyEvent");
g_onCall = AVSESSION_SUCCESS;
}
AVSessionCallbackImpl::~AVSessionCallbackImpl()
{
}
BENCHMARK_F(AVSessionTest, GetSessionIdTestCase)(benchmark::State& state)
{
while (state.KeepRunning()) {
auto sessionId = avsession_->GetSessionId();
if (sessionId.empty() || sessionId.length() != SESSION_LEN) {
state.SkipWithError("GetSessionIdTestCase failed, return error.");
}
}
}
BENCHMARK_F(AVSessionTest, SetAVMetaDataTestCase)(benchmark::State& state)
{
const int32_t iDuration = 40000;
AVMetaData metaData;
while (state.KeepRunning()) {
metaData.Reset();
metaData.SetAssetId("123");
metaData.SetTitle("Black Humor");
metaData.SetArtist("zhoujielun");
metaData.SetAuthor("zhoujielun");
metaData.SetAlbum("Jay");
metaData.SetWriter("zhoujielun");
metaData.SetComposer("zhoujielun");
metaData.SetDuration(iDuration);
metaData.SetMediaImageUri("https://baidu.yinyue.com");
metaData.SetSubTitle("fac");
metaData.SetDescription("for friends");
metaData.SetLyric("https://baidu.yinyue.com");
OHOS::ErrCode errCode = avsession_->SetAVMetaData(metaData);
if (errCode != OHOS::ERR_OK) {
state.SkipWithError("SetAVMetaDataTestCase failed, return error.");
}
}
}
BENCHMARK_F(AVSessionTest, GetAVMetaDataTestCase)(benchmark::State& state)
{
while (state.KeepRunning()) {
AVMetaData metaData;
metaData.Reset();
OHOS::ErrCode errCode = avsession_->GetAVMetaData(metaData);
if (errCode != OHOS::ERR_OK) {
state.SkipWithError("GetAVMetaDataTestCase failed, return error.");
}
}
}
BENCHMARK_F(AVSessionTest, SetAVPlaybackStateTestCase)(benchmark::State &state)
{
const int32_t iPosition = 80000;
const int32_t iBufferedTime = 700000;
AVPlaybackState playbackState;
playbackState.SetState(1);
playbackState.SetSpeed(1);
playbackState.SetPosition({iPosition, 0});
playbackState.SetBufferedTime(iBufferedTime);
playbackState.SetLoopMode(1);
playbackState.SetFavorite(true);
while (state.KeepRunning()) {
int32_t ret = avsession_->SetAVPlaybackState(playbackState);
if (ret != AVSESSION_SUCCESS) {
SLOGE("%{public}s error, failed to SetAVPlaybackStateTestCase", __func__);
state.SkipWithError("SetAVPlaybackStateTestCase failed, return error.");
}
}
}
BENCHMARK_F(AVSessionTest, GetAVPlaybackStateTestCase)(benchmark::State &state)
{
while (state.KeepRunning()) {
AVPlaybackState backState;
int32_t ret = avsession_->GetAVPlaybackState(backState);
if (ret != AVSESSION_SUCCESS) {
SLOGE("%{public}s error, failed to GetAVPlaybackStateTestCase", __func__);
state.SkipWithError("GetAVPlaybackStateTestCase failed, return error.");
}
}
}
BENCHMARK_F(AVSessionTest, SetLaunchAbilityTestCase)(benchmark::State &state)
{
while (state.KeepRunning()) {
OHOS::AbilityRuntime::WantAgent::WantAgent ability;
int32_t ret = avsession_->SetLaunchAbility(ability);
if (ret != AVSESSION_SUCCESS) {
SLOGE("%{public}s error, failed to SetLaunchAbilityTestCase", __func__);
state.SkipWithError("SetLaunchAbilityTestCase failed, return error.");
}
}
}
BENCHMARK_F(AVSessionTest, GetControllerTestCase)(benchmark::State &state)
{
while (state.KeepRunning()) {
auto controller = avsession_->GetController();
if (controller == nullptr) {
SLOGE("%{public}s error, failed to GetControllerTestCase", __func__);
state.SkipWithError("GetControllerTestCase failed, return error.");
}
}
}
BENCHMARK_F(AVSessionTest, RegisterCallbackTestCase)(benchmark::State &state)
{
while (state.KeepRunning()) {
std::shared_ptr<AVSessionCallback> callback = std::make_shared<AVSessionCallbackImpl>();
OHOS::ErrCode errCode = avsession_->RegisterCallback(callback);
if (errCode != OHOS::ERR_OK) {
SLOGE("%{public}s error, failed to RegisterCallbackTestCase, error code is %{public}d.", __func__,
errCode);
state.SkipWithError("RegisterCallbackTestCase failed, return error.");
}
}
}
BENCHMARK_F(AVSessionTest, ActivateTestCase)(benchmark::State &state)
{
while (state.KeepRunning()) {
OHOS::ErrCode errCode = avsession_->Activate();
if (errCode != OHOS::ERR_OK) {
SLOGE("%{public}s error, failed to ActivateTestCase, error code is %{public}d.", __func__,
errCode);
state.SkipWithError("ActivateTestCase failed, return error.");
}
}
}
BENCHMARK_F(AVSessionTest, DeactivateTestCase)(benchmark::State &state)
{
while (state.KeepRunning()) {
OHOS::ErrCode errCode = avsession_->Deactivate();
if (errCode != OHOS::ERR_OK) {
SLOGE("%{public}s error, failed to DeactivateTestCase, error code is %{public}d.", __func__,
errCode);
state.SkipWithError("DeactivateTestCase failed, return error.");
}
}
}
BENCHMARK_F(AVSessionTest, AddSupportCommand)(benchmark::State& state)
{
while (state.KeepRunning()) {
int32_t cmd = AVControlCommand::SESSION_CMD_PLAY;
OHOS::ErrCode errCode = avsession_->AddSupportCommand(cmd);
if (errCode != OHOS::ERR_OK) {
SLOGE("%{public}s error, failed to AddSupportCommand, error code is %{public}d.", __func__,
errCode);
state.SkipWithError("AddSupportCommand failed, return error.");
}
}
}
BENCHMARK_F(AVSessionTest, DeleteSupportCommand)(benchmark::State& state)
{
while (state.KeepRunning()) {
int32_t cmd = AVControlCommand::SESSION_CMD_PLAY;
OHOS::ErrCode errCode = avsession_->DeleteSupportCommand(cmd);
if (errCode != OHOS::ERR_OK) {
SLOGE("%{public}s error, failed to DeleteSupportCommand, error code is %{public}d.", __func__,
errCode);
state.SkipWithError("DeleteSupportCommand failed, return error.");
}
}
}
} // namespace
// Run the benchmark
BENCHMARK_MAIN();
编写内层BUILD.gn
import("//build/test.gni")
module_output_path = "multimedia_benchmark_avsession/benchmarksession"
ohos_benchmarktest("BenchmarkAVSessionTest") {
module_out_path = module_output_path
cflags = ["-g","-O0","-Wno-unused-variable","-fno-omit-frame-pointer"]
if (target_cpu == "arm") {
cflags += [ "-DBINDER_IPC_32BIT" ]
}
sources = [ "avsession_benchmark_test.cpp" ]
deps = [
"//foundation/multimedia/av_session/frameworks/native/session:avsession_client",
"//foundation/multimedia/av_session/services/session:avsession_service",
"//utils/native/base:utils"
]
external_deps = [
"ability_base:want",
"ability_runtime:wantagent_innerkits",
"hiviewdfx_hilog_native:libhilog",
"input:libmmi-client",
"ipc:ipc_core",
"multimedia_image_standard:image_native",
"multimedia_audio_framework:audio_client",
"samgr_standard:samgr_proxy"
]
}
编写外层BUILD.gn
group("benchmarktest") {
testonly = true
deps = []
deps += [
# deps file
"avsession_manager_test:BenchmarkAVSessionManagerTest",
"avsession_controller_test:BenchmarkAVSessionControllerTest",
"avsession_benchmark_test:BenchmarkAVSessionTest",
]
}
bundle.json
在需要DTFuzz测试的对应模块bundle.json中添加Fuzz用例路径,如在bundle.json添加(路径在av_session下):
"tests": [
"//foundation/xxx/xxx/xxx/xxx/xxx/test/benchmarktest:benchmarktest" #添加benchmarktest用例路径
]
编译测试用例
全量编译测试用例生成
./build.sh --product-name rk3568 --build-target make_test
单独编译测试用例生成
./build.sh --product-name rk3568 --build-target BenchmarkTestAVSession
编译av_session测试用例生成
./build.sh --product-name rk3568 --export-para PYCACHE_ENABLE:true --ccache --build-target multimedia_av_session_test
生成测试用例位置
/out/rk3568/tests/benchmark
创建tests位置如下:
D:\file_work\22.7.29(benchmarktest)\tests\benchmark\multimedia_av_session\sessionbenchmark
将测试用例copy到sessionbenchmark文件夹;
复制两文件到本地
/home/openharmony/test$ ls
将developertest和xdevice复制到D:\file_work\22.6.13(test)
在tests中添加res:
res中添加测试框架生成的目录(包括源文件夹或者源文件)
(不需要)添加infos_for_testfwk.json
在D:\file_work\22.7.29(benchmarktest)\tests里面添加infos_for_testfwk.json
/home/si/openharmony/out/rk3568/build_configs/infos_for_testfwk.json
修改user_config.xml
修改developertest\config下的user_config.xml文件,如下图
<test_cases>
<dir>D:\file_work\22.7.29(benchmarktest)\tests</dir>
</test_cases>
烧录镜像文件
root@ubuntu:/home/si/openharmony/out/rk3568/packages/phone# cp -r images/ /mnt/hgfs/SharedFolder/
手动拉起av_session进程
蓝区selinux临时关闭及手动拉起av_session进程方法:
hdc_std shell setenforce 0
hdc_std shell service_control start av_session
查看进程是否起来:
hdc shell pgrep "av_session"
运行start.bat
双击developertest下的start.bat
输入3(或者是选择rk3568),回车
跑测试用例
-t [TESTTYPE]: 指定测试用例类型,有UT,MST,ST,PERF,FUZZ,BENCHMARK等。(必选参数)
-tp [TESTPART]: 指定部件,可独立使用。
-tm [TESTMODULE]: 指定模块,不可独立使用,需结合-tp指定上级部件使用。
-ts [TESTSUITE]: 指定测试套,可独立使用。
-tc [TESTCASE]: 指定测试用例,不可独立使用,需结合-ts指定上级测试套使用。
-h : 帮助命令。
run -t BENCHMARK -ts BenchmarkTestAVSession -tc CreatSession_001
run -t BENCHMARK -ts BenchmarkTestAVSession
全部执行:
run -t BENCHMARK
查看运行结果
在developertest下的reports中查看运行结果
测试结果
测试用例的结果会直接显示在控制台上,执行一次的测试结果根路径如下:
reports/xxxx-xx-xx-xx-xx-xx
测试用例日志
D:\file_work\22.7.29(benchmarktest)\developertest\reports\2022-08-04-16-42-31\log\task_log.log
测试报告汇总
D:\file_work\22.7.29(benchmarktest)\developertest\reports\2022-08-04-16-42-31\benchmark\benchmark\report\index.html
注意:
路径太长可能会引起部分link无法生成!!!
测试报告详情
D:\file_work\22.7.29(benchmarktest)\developertest\reports\2022-08-04-16-42-31\benchmark\benchmark\report\multimedia_benchmark_avsession\benchmarksession\BenchmarkAVSessionTest
(非必要)删掉线程
删掉avsession_test.cpp最后的线程
该线程可能会导致测试结果中的Link无法生成