148f512ceSopenharmony_ci/* 248f512ceSopenharmony_ci * Copyright (c) 2021 Huawei Device Co., Ltd. 348f512ceSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 448f512ceSopenharmony_ci * you may not use this file except in compliance with the License. 548f512ceSopenharmony_ci * You may obtain a copy of the License at 648f512ceSopenharmony_ci * 748f512ceSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 848f512ceSopenharmony_ci * 948f512ceSopenharmony_ci * Unless required by applicable law or agreed to in writing, software 1048f512ceSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 1148f512ceSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1248f512ceSopenharmony_ci * See the License for the specific language governing permissions and 1348f512ceSopenharmony_ci * limitations under the License. 1448f512ceSopenharmony_ci */ 1548f512ceSopenharmony_ci 1648f512ceSopenharmony_ci#include "perf_events_test.h" 1748f512ceSopenharmony_ci 1848f512ceSopenharmony_ci#include <chrono> 1948f512ceSopenharmony_ci#include <cinttypes> 2048f512ceSopenharmony_ci#include <cstdlib> 2148f512ceSopenharmony_ci#include <thread> 2248f512ceSopenharmony_ci#include <unistd.h> 2348f512ceSopenharmony_ci 2448f512ceSopenharmony_ci#include "debug_logger.h" 2548f512ceSopenharmony_ci#include "utilities.h" 2648f512ceSopenharmony_ci 2748f512ceSopenharmony_ciusing namespace testing::ext; 2848f512ceSopenharmony_ciusing namespace std; 2948f512ceSopenharmony_ciusing namespace OHOS::HiviewDFX; 3048f512ceSopenharmony_ci 3148f512ceSopenharmony_cinamespace OHOS { 3248f512ceSopenharmony_cinamespace Developtools { 3348f512ceSopenharmony_cinamespace HiPerf { 3448f512ceSopenharmony_ciclass PerfEventsTest : public testing::Test { 3548f512ceSopenharmony_cipublic: 3648f512ceSopenharmony_ci static void SetUpTestCase(void); 3748f512ceSopenharmony_ci static void TearDownTestCase(void); 3848f512ceSopenharmony_ci void SetUp(); 3948f512ceSopenharmony_ci void TearDown(); 4048f512ceSopenharmony_ci 4148f512ceSopenharmony_ci static void TestCodeThread(void); 4248f512ceSopenharmony_ci static void RunTestThreads(std::vector<std::thread> &threads); 4348f512ceSopenharmony_ci static void SetAllConfig(PerfEvents &event); 4448f512ceSopenharmony_ci static bool RecordCount(std::unique_ptr<PerfEventRecord> record); 4548f512ceSopenharmony_ci static void StatCount( 4648f512ceSopenharmony_ci const std::map<std::string, std::unique_ptr<PerfEvents::CountEvent>> &countEvents); 4748f512ceSopenharmony_ci 4848f512ceSopenharmony_ci static constexpr int TEST_CODE_MEM_FILE_SIZE = 1024; 4948f512ceSopenharmony_ci static constexpr auto TEST_CODE_SLEEP_BEFORE_RUN = 500ms; 5048f512ceSopenharmony_ci static constexpr auto TEST_CODE_SLEEP_AFTER_RUN = 1000ms; 5148f512ceSopenharmony_ci static constexpr int TEST_CODE_RUN_TIME = 10240; 5248f512ceSopenharmony_ci static constexpr int DOUBLE = 2; 5348f512ceSopenharmony_ci static constexpr int TRIPLE = 3; 5448f512ceSopenharmony_ci static constexpr auto TEST_TIME = 3s; 5548f512ceSopenharmony_ci static constexpr auto DEFAULT_TRACKING_TIME = 1000; 5648f512ceSopenharmony_ci static constexpr auto DEFAULT_STAT_REPORT_TIME = 500; 5748f512ceSopenharmony_ci static constexpr auto DEFAULT_SAMPLE_MMAPAGE = 256; 5848f512ceSopenharmony_ci 5948f512ceSopenharmony_ci static uint64_t g_recordCount; 6048f512ceSopenharmony_ci static uint64_t g_statCount; 6148f512ceSopenharmony_ci}; 6248f512ceSopenharmony_ci 6348f512ceSopenharmony_civoid PerfEventsTest::SetUpTestCase() {} 6448f512ceSopenharmony_ci 6548f512ceSopenharmony_civoid PerfEventsTest::TearDownTestCase() {} 6648f512ceSopenharmony_ci 6748f512ceSopenharmony_civoid PerfEventsTest::SetUp() {} 6848f512ceSopenharmony_ci 6948f512ceSopenharmony_civoid PerfEventsTest::TearDown() {} 7048f512ceSopenharmony_ci 7148f512ceSopenharmony_ciuint64_t PerfEventsTest::g_recordCount = 0; 7248f512ceSopenharmony_ciuint64_t PerfEventsTest::g_statCount = 0; 7348f512ceSopenharmony_ci 7448f512ceSopenharmony_cibool PerfEventsTest::RecordCount(std::unique_ptr<PerfEventRecord> record) 7548f512ceSopenharmony_ci{ 7648f512ceSopenharmony_ci g_recordCount++; 7748f512ceSopenharmony_ci if (record->GetType() == PERF_RECORD_SAMPLE) { 7848f512ceSopenharmony_ci // the record is allowed from a cache memory, does not free memory after use 7948f512ceSopenharmony_ci record.release(); 8048f512ceSopenharmony_ci } 8148f512ceSopenharmony_ci return true; 8248f512ceSopenharmony_ci} 8348f512ceSopenharmony_ci 8448f512ceSopenharmony_civoid PerfEventsTest::StatCount( 8548f512ceSopenharmony_ci const std::map<std::string, std::unique_ptr<PerfEvents::CountEvent>> &countEvents) 8648f512ceSopenharmony_ci{ 8748f512ceSopenharmony_ci g_statCount++; 8848f512ceSopenharmony_ci} 8948f512ceSopenharmony_ci 9048f512ceSopenharmony_civoid PerfEventsTest::TestCodeThread() 9148f512ceSopenharmony_ci{ 9248f512ceSopenharmony_ci std::vector<std::unique_ptr<char[]>> mems; 9348f512ceSopenharmony_ci int tid = gettid(); 9448f512ceSopenharmony_ci printf("%s:%d ++\n", __FUNCTION__, tid); 9548f512ceSopenharmony_ci for (int n = 0; n < TRIPLE; n++) { 9648f512ceSopenharmony_ci std::this_thread::sleep_for(TEST_CODE_SLEEP_BEFORE_RUN); 9748f512ceSopenharmony_ci constexpr size_t memSize {TEST_CODE_MEM_FILE_SIZE}; 9848f512ceSopenharmony_ci for (int i = 0; i < TEST_CODE_RUN_TIME; i++) { 9948f512ceSopenharmony_ci if (i % DOUBLE == 0) { 10048f512ceSopenharmony_ci mems.push_back(std::make_unique<char[]>(memSize)); 10148f512ceSopenharmony_ci } else { 10248f512ceSopenharmony_ci mems.push_back(std::make_unique<char[]>(memSize * DOUBLE)); 10348f512ceSopenharmony_ci } 10448f512ceSopenharmony_ci } 10548f512ceSopenharmony_ci 10648f512ceSopenharmony_ci for (int i = 0; i < TEST_CODE_RUN_TIME; i++) { 10748f512ceSopenharmony_ci mems.pop_back(); 10848f512ceSopenharmony_ci } 10948f512ceSopenharmony_ci 11048f512ceSopenharmony_ci std::this_thread::sleep_for(TEST_CODE_SLEEP_AFTER_RUN); 11148f512ceSopenharmony_ci } 11248f512ceSopenharmony_ci printf("%s:%d --\n", __FUNCTION__, tid); 11348f512ceSopenharmony_ci} 11448f512ceSopenharmony_ci 11548f512ceSopenharmony_civoid PerfEventsTest::RunTestThreads(std::vector<std::thread> &threads) 11648f512ceSopenharmony_ci{ 11748f512ceSopenharmony_ci for (long i = 0; i < sysconf(_SC_NPROCESSORS_CONF); i++) { 11848f512ceSopenharmony_ci threads.emplace_back(std::thread(&TestCodeThread)); 11948f512ceSopenharmony_ci } 12048f512ceSopenharmony_ci} 12148f512ceSopenharmony_ci 12248f512ceSopenharmony_ci// it isn't include sample and stat 12348f512ceSopenharmony_civoid PerfEventsTest::SetAllConfig(PerfEvents &event) 12448f512ceSopenharmony_ci{ 12548f512ceSopenharmony_ci std::vector<pid_t> selectCpus_; 12648f512ceSopenharmony_ci event.SetCpu(selectCpus_); 12748f512ceSopenharmony_ci std::vector<pid_t> pids; 12848f512ceSopenharmony_ci event.SetPid(pids); 12948f512ceSopenharmony_ci event.SetSystemTarget(true); 13048f512ceSopenharmony_ci event.SetTimeOut(DEFAULT_TRACKING_TIME); 13148f512ceSopenharmony_ci event.SetInherit(false); 13248f512ceSopenharmony_ci std::vector<std::string> trackedCommand_ {"ls"}; 13348f512ceSopenharmony_ci event.SetTrackedCommand(trackedCommand_); 13448f512ceSopenharmony_ci const unsigned int frequency = 1000; 13548f512ceSopenharmony_ci event.SetSampleFrequency(frequency); 13648f512ceSopenharmony_ci const uint32_t dwarfSampleStackSize = 64; 13748f512ceSopenharmony_ci event.SetDwarfSampleStackSize(dwarfSampleStackSize); 13848f512ceSopenharmony_ci const int clockId = 1; 13948f512ceSopenharmony_ci event.SetClockId(clockId); 14048f512ceSopenharmony_ci 14148f512ceSopenharmony_ci // addevent must be tail 14248f512ceSopenharmony_ci event.AddDefaultEvent(PERF_TYPE_HARDWARE); 14348f512ceSopenharmony_ci event.AddDefaultEvent(PERF_TYPE_SOFTWARE); 14448f512ceSopenharmony_ci} 14548f512ceSopenharmony_ci 14648f512ceSopenharmony_cistatic void RunTrack(PerfEvents &event) 14748f512ceSopenharmony_ci{ 14848f512ceSopenharmony_ci ASSERT_EQ(event.StartTracking(), true); 14948f512ceSopenharmony_ci} 15048f512ceSopenharmony_ci 15148f512ceSopenharmony_ci/** 15248f512ceSopenharmony_ci * @tc.name: Test 15348f512ceSopenharmony_ci * @tc.desc: 15448f512ceSopenharmony_ci * @tc.type: FUNC 15548f512ceSopenharmony_ci */ 15648f512ceSopenharmony_ciHWTEST_F(PerfEventsTest, GetSupportEvents, TestSize.Level1) 15748f512ceSopenharmony_ci{ 15848f512ceSopenharmony_ci ScopeDebugLevel tempLogLevel(LEVEL_DEBUG); 15948f512ceSopenharmony_ci StdoutRecord stdoutRecord; 16048f512ceSopenharmony_ci stdoutRecord.Start(); 16148f512ceSopenharmony_ci 16248f512ceSopenharmony_ci PerfEvents event; 16348f512ceSopenharmony_ci perf_type_id id = PERF_TYPE_HARDWARE; 16448f512ceSopenharmony_ci while (id < PERF_TYPE_MAX) { 16548f512ceSopenharmony_ci std::map<__u64, std::string> supportEvent = event.GetSupportEvents(id); 16648f512ceSopenharmony_ci for (auto it = supportEvent.begin(); it != supportEvent.end(); ++it) { 16748f512ceSopenharmony_ci printf("[%lld]\t%s\n", it->first, it->second.c_str()); 16848f512ceSopenharmony_ci } 16948f512ceSopenharmony_ci id = perf_type_id(id + 1); 17048f512ceSopenharmony_ci } 17148f512ceSopenharmony_ci 17248f512ceSopenharmony_ci std::string stringOut = stdoutRecord.Stop(); 17348f512ceSopenharmony_ci} 17448f512ceSopenharmony_ci 17548f512ceSopenharmony_ciHWTEST_F(PerfEventsTest, GetTypeName, TestSize.Level1) 17648f512ceSopenharmony_ci{ 17748f512ceSopenharmony_ci ScopeDebugLevel tempLogLevel(LEVEL_DEBUG); 17848f512ceSopenharmony_ci StdoutRecord stdoutRecord; 17948f512ceSopenharmony_ci stdoutRecord.Start(); 18048f512ceSopenharmony_ci 18148f512ceSopenharmony_ci PerfEvents event; 18248f512ceSopenharmony_ci perf_type_id id = PERF_TYPE_HARDWARE; 18348f512ceSopenharmony_ci while (id < PERF_TYPE_MAX) { 18448f512ceSopenharmony_ci std::string typeName = event.GetTypeName(id); 18548f512ceSopenharmony_ci EXPECT_GT(typeName.size(), 0u) << "the type should have name"; 18648f512ceSopenharmony_ci printf("type[%d]\tname : %s\n", id, typeName.c_str()); 18748f512ceSopenharmony_ci id = perf_type_id(id + 1); 18848f512ceSopenharmony_ci } 18948f512ceSopenharmony_ci 19048f512ceSopenharmony_ci std::string stringOut = stdoutRecord.Stop(); 19148f512ceSopenharmony_ci} 19248f512ceSopenharmony_ci 19348f512ceSopenharmony_ciHWTEST_F(PerfEventsTest, RecordNormal, TestSize.Level1) 19448f512ceSopenharmony_ci{ 19548f512ceSopenharmony_ci ScopeDebugLevel tempLogLevel(LEVEL_DEBUG); 19648f512ceSopenharmony_ci StdoutRecord stdoutRecord; 19748f512ceSopenharmony_ci stdoutRecord.Start(); 19848f512ceSopenharmony_ci 19948f512ceSopenharmony_ci PerfEvents event; 20048f512ceSopenharmony_ci // prepare 20148f512ceSopenharmony_ci g_recordCount = 0; 20248f512ceSopenharmony_ci event.SetMmapPages(DEFAULT_SAMPLE_MMAPAGE); 20348f512ceSopenharmony_ci event.SetRecordCallBack(RecordCount); 20448f512ceSopenharmony_ci 20548f512ceSopenharmony_ci std::vector<pid_t> selectCpus_; 20648f512ceSopenharmony_ci event.SetCpu(selectCpus_); 20748f512ceSopenharmony_ci std::vector<pid_t> pids; 20848f512ceSopenharmony_ci event.SetPid(pids); 20948f512ceSopenharmony_ci const unsigned int frequency = 1000; 21048f512ceSopenharmony_ci event.SetSampleFrequency(frequency); 21148f512ceSopenharmony_ci event.SetSystemTarget(true); 21248f512ceSopenharmony_ci event.SetTimeOut(DEFAULT_TRACKING_TIME); 21348f512ceSopenharmony_ci event.SetInherit(false); 21448f512ceSopenharmony_ci std::vector<std::string> trackedCommand_ {"ls"}; 21548f512ceSopenharmony_ci event.SetTrackedCommand(trackedCommand_); 21648f512ceSopenharmony_ci event.AddDefaultEvent(PERF_TYPE_SOFTWARE); 21748f512ceSopenharmony_ci event.AddDefaultEvent(PERF_TYPE_HARDWARE); 21848f512ceSopenharmony_ci 21948f512ceSopenharmony_ci ASSERT_EQ(event.PrepareTracking(), true); 22048f512ceSopenharmony_ci std::thread runThread(RunTrack, std::ref(event)); 22148f512ceSopenharmony_ci std::vector<std::thread> testThreads; 22248f512ceSopenharmony_ci RunTestThreads(testThreads); 22348f512ceSopenharmony_ci 22448f512ceSopenharmony_ci std::this_thread::sleep_for(TEST_TIME); 22548f512ceSopenharmony_ci EXPECT_EQ(event.PauseTracking(), true); 22648f512ceSopenharmony_ci std::this_thread::sleep_for(TEST_TIME); // wait for clearing mmap buffer 22748f512ceSopenharmony_ci uint64_t recordCount = g_recordCount; 22848f512ceSopenharmony_ci std::this_thread::sleep_for(TEST_TIME); 22948f512ceSopenharmony_ci EXPECT_EQ(recordCount, g_recordCount) << "now should have no record"; 23048f512ceSopenharmony_ci EXPECT_EQ(event.ResumeTracking(), true); 23148f512ceSopenharmony_ci TestCodeThread(); 23248f512ceSopenharmony_ci std::this_thread::sleep_for(TEST_TIME); 23348f512ceSopenharmony_ci EXPECT_EQ(event.StopTracking(), true); 23448f512ceSopenharmony_ci runThread.join(); 23548f512ceSopenharmony_ci for (std::thread &t : testThreads) { 23648f512ceSopenharmony_ci t.join(); 23748f512ceSopenharmony_ci } 23848f512ceSopenharmony_ci ASSERT_GT(g_recordCount, recordCount) << "should have more records"; 23948f512ceSopenharmony_ci 24048f512ceSopenharmony_ci size_t lostSamples = 0; 24148f512ceSopenharmony_ci size_t lostNonSamples = 0; 24248f512ceSopenharmony_ci event.GetLostSamples(lostSamples, lostNonSamples); 24348f512ceSopenharmony_ci 24448f512ceSopenharmony_ci std::string stringOut = stdoutRecord.Stop(); 24548f512ceSopenharmony_ci} 24648f512ceSopenharmony_ci 24748f512ceSopenharmony_ciHWTEST_F(PerfEventsTest, RecordSetAll, TestSize.Level1) 24848f512ceSopenharmony_ci{ 24948f512ceSopenharmony_ci ScopeDebugLevel tempLogLevel(LEVEL_DEBUG); 25048f512ceSopenharmony_ci StdoutRecord stdoutRecord; 25148f512ceSopenharmony_ci stdoutRecord.Start(); 25248f512ceSopenharmony_ci 25348f512ceSopenharmony_ci PerfEvents event; 25448f512ceSopenharmony_ci // prepare 25548f512ceSopenharmony_ci g_recordCount = 0; 25648f512ceSopenharmony_ci event.SetMmapPages(DEFAULT_SAMPLE_MMAPAGE); 25748f512ceSopenharmony_ci event.SetRecordCallBack(RecordCount); 25848f512ceSopenharmony_ci SetAllConfig(event); 25948f512ceSopenharmony_ci ASSERT_EQ(event.PrepareTracking(), true); 26048f512ceSopenharmony_ci std::thread runThread(RunTrack, std::ref(event)); 26148f512ceSopenharmony_ci std::vector<std::thread> testThreads; 26248f512ceSopenharmony_ci RunTestThreads(testThreads); 26348f512ceSopenharmony_ci 26448f512ceSopenharmony_ci std::this_thread::sleep_for(TEST_TIME); 26548f512ceSopenharmony_ci EXPECT_EQ(event.PauseTracking(), true); 26648f512ceSopenharmony_ci std::this_thread::sleep_for(TEST_TIME); // wait for clearing mmap buffer 26748f512ceSopenharmony_ci uint64_t recordCount = g_recordCount; 26848f512ceSopenharmony_ci std::this_thread::sleep_for(TEST_TIME); 26948f512ceSopenharmony_ci EXPECT_EQ(recordCount, g_recordCount) << "now should have no record"; 27048f512ceSopenharmony_ci EXPECT_EQ(event.ResumeTracking(), true); 27148f512ceSopenharmony_ci TestCodeThread(); 27248f512ceSopenharmony_ci std::this_thread::sleep_for(TEST_TIME); 27348f512ceSopenharmony_ci EXPECT_EQ(event.StopTracking(), true); 27448f512ceSopenharmony_ci runThread.join(); 27548f512ceSopenharmony_ci for (std::thread &t : testThreads) { 27648f512ceSopenharmony_ci t.join(); 27748f512ceSopenharmony_ci } 27848f512ceSopenharmony_ci ASSERT_GT(g_recordCount, recordCount) << "should have more records"; 27948f512ceSopenharmony_ci 28048f512ceSopenharmony_ci std::string stringOut = stdoutRecord.Stop(); 28148f512ceSopenharmony_ci} 28248f512ceSopenharmony_ci 28348f512ceSopenharmony_ciHWTEST_F(PerfEventsTest, StatNormal, TestSize.Level1) 28448f512ceSopenharmony_ci{ 28548f512ceSopenharmony_ci ScopeDebugLevel tempLogLevel(LEVEL_DEBUG); 28648f512ceSopenharmony_ci StdoutRecord stdoutRecord; 28748f512ceSopenharmony_ci stdoutRecord.Start(); 28848f512ceSopenharmony_ci 28948f512ceSopenharmony_ci PerfEvents event; 29048f512ceSopenharmony_ci // prepare 29148f512ceSopenharmony_ci g_statCount = 0; 29248f512ceSopenharmony_ci std::vector<pid_t> selectCpus_; 29348f512ceSopenharmony_ci event.SetCpu(selectCpus_); 29448f512ceSopenharmony_ci std::vector<pid_t> pids; 29548f512ceSopenharmony_ci event.SetPid(pids); 29648f512ceSopenharmony_ci event.SetSystemTarget(true); 29748f512ceSopenharmony_ci event.SetTimeOut(DEFAULT_TRACKING_TIME); 29848f512ceSopenharmony_ci event.SetTimeReport(DEFAULT_STAT_REPORT_TIME); 29948f512ceSopenharmony_ci event.SetVerboseReport(false); 30048f512ceSopenharmony_ci event.SetInherit(false); 30148f512ceSopenharmony_ci std::vector<std::string> trackedCommand_ {"ls"}; 30248f512ceSopenharmony_ci event.SetTrackedCommand(trackedCommand_); 30348f512ceSopenharmony_ci event.AddDefaultEvent(PERF_TYPE_SOFTWARE); 30448f512ceSopenharmony_ci event.AddDefaultEvent(PERF_TYPE_TRACEPOINT); 30548f512ceSopenharmony_ci event.SetStatCallBack(StatCount); 30648f512ceSopenharmony_ci ASSERT_EQ(event.PrepareTracking(), true); 30748f512ceSopenharmony_ci std::thread runThread(RunTrack, std::ref(event)); 30848f512ceSopenharmony_ci std::vector<std::thread> testThreads; 30948f512ceSopenharmony_ci RunTestThreads(testThreads); 31048f512ceSopenharmony_ci 31148f512ceSopenharmony_ci std::this_thread::sleep_for(TEST_TIME); 31248f512ceSopenharmony_ci EXPECT_EQ(event.PauseTracking(), true); 31348f512ceSopenharmony_ci EXPECT_GT(g_statCount, 0u) << "should have stats"; 31448f512ceSopenharmony_ci uint64_t statCount = g_statCount; 31548f512ceSopenharmony_ci std::this_thread::sleep_for(TEST_TIME); 31648f512ceSopenharmony_ci EXPECT_EQ(event.ResumeTracking(), true); 31748f512ceSopenharmony_ci std::this_thread::sleep_for(TEST_TIME); 31848f512ceSopenharmony_ci EXPECT_EQ(event.StopTracking(), true); 31948f512ceSopenharmony_ci runThread.join(); 32048f512ceSopenharmony_ci for (std::thread &t : testThreads) { 32148f512ceSopenharmony_ci t.join(); 32248f512ceSopenharmony_ci } 32348f512ceSopenharmony_ci EXPECT_GT(g_statCount, statCount) << "should have more stats"; 32448f512ceSopenharmony_ci 32548f512ceSopenharmony_ci std::string stringOut = stdoutRecord.Stop(); 32648f512ceSopenharmony_ci} 32748f512ceSopenharmony_ci} // namespace HiPerf 32848f512ceSopenharmony_ci} // namespace Developtools 32948f512ceSopenharmony_ci} // namespace OHOS 330