• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024 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 "spe_decoder_test.h"
16 
17 #include "command.h"
18 #include "subcommand_dump.h"
19 #include "subcommand_record.h"
20 #include "utilities_test.h"
21 
22 using namespace testing::ext;
23 using namespace std;
24 using namespace OHOS::HiviewDFX;
25 namespace OHOS {
26 namespace Developtools {
27 namespace HiPerf {
28 
29 class SpeDecoderTest : public testing::Test {
30 public:
31     static void SetUpTestCase(void);
32     static void TearDownTestCase(void);
33     void SetUp();
34     void TearDown();
35 };
36 
SetUpTestCase()37 void SpeDecoderTest::SetUpTestCase() {}
38 
TearDownTestCase()39 void SpeDecoderTest::TearDownTestCase() {}
40 
SetUp()41 void SpeDecoderTest::SetUp()
42 {
43     SubCommand::ClearSubCommands(); // clear the subCommands left from other UT
44     ASSERT_EQ(SubCommand::GetSubCommands().size(), 0u);
45     SubCommandRecord::RegisterSubCommandRecord();
46     SubCommandDump::RegisterSubCommandDump();
47     ASSERT_EQ(SubCommand::GetSubCommands().size(), 2u); // 2u: 2 size
48 }
49 
TearDown()50 void SpeDecoderTest::TearDown()
51 {
52     ASSERT_EQ(SubCommand::GetSubCommands().size(), 2u); // 2u: 2 size
53     SubCommand::ClearSubCommands();
54     ASSERT_EQ(SubCommand::GetSubCommands().size(), 0u);
55     MemoryHold::Get().Clean();
56 }
57 
58 /**
59  * @tc.name: TestGetSpeEventNameByType
60  * @tc.desc:
61  * @tc.type: FUNC
62  */
63 HWTEST_F(SpeDecoderTest, TestGetSpeEventNameByType, TestSize.Level1)
64 {
65     std::string eventName = "";
66     GetSpeEventNameByType(PERF_SPE_L1D_ACCESS, eventName);
67     ASSERT_EQ(eventName, "l1d-access");
68     GetSpeEventNameByType(PERF_SPE_L1D_MISS, eventName);
69     ASSERT_EQ(eventName, "l1d-miss");
70     GetSpeEventNameByType(PERF_SPE_LLC_ACCESS, eventName);
71     ASSERT_EQ(eventName, "llc-access");
72     GetSpeEventNameByType(PERF_SPE_LLC_MISS, eventName);
73     ASSERT_EQ(eventName, "llc-miss");
74     GetSpeEventNameByType(PERF_SPE_TLB_ACCESS, eventName);
75     ASSERT_EQ(eventName, "tlb-access");
76     GetSpeEventNameByType(PERF_SPE_TLB_MISS, eventName);
77     ASSERT_EQ(eventName, "tlb-miss");
78     GetSpeEventNameByType(PERF_SPE_BRANCH_MISS, eventName);
79     ASSERT_EQ(eventName, "branch-miss");
80     GetSpeEventNameByType(PERF_SPE_REMOTE_ACCESS, eventName);
81     ASSERT_EQ(eventName, "remote-access");
82     GetSpeEventNameByType(PERF_SPE_SVE_PARTIAL_PRED, eventName);
83     ASSERT_EQ(eventName, "paritial_read");
84     GetSpeEventNameByType(PERF_SPE_SVE_EMPTY_PRED, eventName);
85     ASSERT_EQ(eventName, "empty_read");
86     GetSpeEventNameByType(1 << 10, eventName); // 10: displacement
87     ASSERT_EQ(eventName, "unknow");
88 }
89 
90 /**
91  * @tc.name: TestRecord
92  * @tc.desc:
93  * @tc.type: FUNC
94  */
95 HWTEST_F(SpeDecoderTest, TestRecord, TestSize.Level1)
96 {
97     StdoutRecord stdoutRecord;
98 
99     std::string cmdString = "record -e arm_spe_0/load_filter=1,min_latency=100/ -d 10 --app ";
100     cmdString += " " + TEST_PROCESSES;
101     printf("command : %s\n", cmdString.c_str());
102 
103     // it need load some symbols and much more log
104     stdoutRecord.Start();
105     const auto startTime = chrono::steady_clock::now();
106     bool ret = Command::DispatchCommand(cmdString);
107     const auto costMs = std::chrono::duration_cast<std::chrono::milliseconds>(
108         chrono::steady_clock::now() - startTime);
109     std::string stringOut = stdoutRecord.Stop();
110     printf("run %" PRId64 " ms return %d\n", (uint64_t)costMs.count(), static_cast<int>(ret));
111     EXPECT_EQ(true, ret);
112 }
113 
114 /**
115  * @tc.name: TestDump
116  * @tc.desc:
117  * @tc.type: FUNC
118  */
119 HWTEST_F(SpeDecoderTest, TestDump, TestSize.Level1)
120 {
121     if (access("/data/test/resource/testdata/spe_perf.data", R_OK) == 0) {
122         StdoutRecord stdoutRecord;
123 
124         std::string cmdString = "dump -i /data/test/resource/testdata/spe_perf.data";
125 
126         // it need load some symbols and much more log
127         ScopeDebugLevel tempLogLevel {LEVEL_DEBUG};
128 
129         stdoutRecord.Start();
130         const auto startTime = chrono::steady_clock::now();
131         bool ret = Command::DispatchCommand(cmdString);
132         const auto costMs = std::chrono::duration_cast<std::chrono::milliseconds>(
133             chrono::steady_clock::now() - startTime);
134         std::string stringOut = stdoutRecord.Stop();
135 
136         printf("command : %s(run %" PRId64 " ms) return %d\n", cmdString.c_str(),
137             static_cast<uint64_t>(costMs.count()), static_cast<int>(ret));
138         EXPECT_EQ(true, ret);
139     } else {
140         printf("spe_perf.data not exist.\n");
141     }
142 }
143 
144 /**
145  * @tc.name: TestSpeDecoder
146  * @tc.desc:
147  * @tc.type: FUNC
148  */
149 HWTEST_F(SpeDecoderTest, TestSpeDecoder, TestSize.Level1)
150 {
151     const size_t dataDize = 192;
152     const u8 rawData[dataDize] = {0xb0, 0x68, 0xe0, 0x20, 0x84, 0xc0, 0xff, 0xff,
153         0xa0, 0x99, 0x06, 0x00, 0x98, 0x08, 0x00, 0x62,
154         0x16, 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00,
155         0xb2, 0xb0, 0x80, 0xad, 0xae, 0xe5, 0xff, 0xff,
156         0x00, 0x9a, 0x01, 0x00, 0x00, 0x00, 0x00, 0x71,
157         0x46, 0xf9, 0xd5, 0x4a, 0x10, 0x62, 0x01, 0x00,
158         0xb0, 0x0c, 0x27, 0xb9, 0xf2, 0x59, 0x00, 0x00,
159         0x80, 0x99, 0x07, 0x00, 0x98, 0x0a, 0x00, 0x62,
160         0x12, 0x00, 0x00, 0x00, 0x49, 0x01, 0x00, 0x00,
161         0xb2, 0x60, 0x73, 0x2b, 0x81, 0x5a, 0x00, 0x00,
162         0x00, 0x9a, 0x01, 0x00, 0x00, 0x00, 0x00, 0x71,
163         0x20, 0x43, 0xd6, 0x4a, 0x10, 0x62, 0x01, 0x00,
164         0xb0, 0x68, 0x54, 0xf9, 0xf4, 0x59, 0x00, 0x00,
165         0x80, 0x99, 0x02, 0x00, 0x98, 0x03, 0x00, 0x62,
166         0x42, 0x00, 0x00, 0x00, 0x4a, 0x01, 0x00, 0x00,
167         0xb1, 0x6c, 0x54, 0xf9, 0xf4, 0x59, 0x00, 0x00,
168         0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x71,
169         0xa1, 0x6c, 0xd6, 0x4a, 0x10, 0x62, 0x01, 0x00,
170         0xb0, 0xb4, 0x2b, 0x20, 0x84, 0xc0, 0xff, 0xff,
171         0xa0, 0x99, 0x02, 0x00, 0x98, 0x03, 0x00, 0x62,
172         0x02, 0x00, 0x00, 0x00, 0x4a, 0x02, 0x00, 0x00,
173         0xb1, 0xac, 0x5c, 0x35, 0x84, 0xc0, 0xff, 0xff,
174         0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x71,
175         0xcc, 0x99, 0xd6, 0x4a, 0x10, 0x62, 0x01, 0x00};
176     SpeDecoder *decoder = SpeDecoderDataNew(rawData, dataDize);
177     EXPECT_EQ(decoder != nullptr, true);
178     std::vector<SpeRecord> records;
179     while (true) {
180         int ret = SpeDecode(decoder);
181         if (ret <= 0) {
182             break;
183         }
184         struct SpeRecord record = SpeRecord(decoder->record);
185         records.emplace_back(record);
186     }
187     EXPECT_EQ(records.empty(), false);
188     SpeDecoderFree(decoder);
189 }
190 } // namespace HiPerf
191 } // namespace Developtools
192 } // namespace OHOS