1 /* 2 * Copyright (c) Huawei Technologies Co., Ltd. 2023. All rights reserved. 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 16 #include <fcntl.h> 17 #include <hwext/gtest-ext.h> 18 #include <hwext/gtest-tag.h> 19 #include <string> 20 #include <unordered_map> 21 22 #include "mem_parser/pbreader_mem_parser.h" 23 #include "memory_plugin_result.pb.h" 24 #include "memory_plugin_result.pbreader.h" 25 #include "parser/common_types.h" 26 #include "trace_streamer_selector.h" 27 28 using namespace testing::ext; 29 using namespace SysTuning::TraceStreamer; 30 31 namespace SysTuning { 32 namespace TraceStreamer { 33 class HtraceSysMemParserTest : public ::testing::Test { 34 public: SetUp()35 void SetUp() 36 { 37 stream_.InitFilter(); 38 } 39 TearDown()40 void TearDown() 41 { 42 if (access(dbPath_.c_str(), F_OK) == 0) { 43 remove(dbPath_.c_str()); 44 } 45 } 46 47 public: 48 SysTuning::TraceStreamer::TraceStreamerSelector stream_ = {}; 49 const std::string dbPath_ = "../../test/resource/out.db"; 50 }; 51 52 /** 53 * @tc.name: ParseSysMemParseInputEmpty 54 * @tc.desc: Kernel memory parsing test, input empty 55 * @tc.type: FUNC 56 */ 57 HWTEST_F(HtraceSysMemParserTest, ParseSysMemParseInputEmpty, TestSize.Level1) 58 { 59 TS_LOGI("test19-1"); 60 PbreaderMemParser *memParser = new PbreaderMemParser(stream_.traceDataCache_.get(), stream_.streamFilters_.get()); 61 MemoryData tracePacket; 62 SysMeminfo *mem = tracePacket.add_meminfo(); 63 EXPECT_TRUE(mem != nullptr); 64 int32_t size = tracePacket.meminfo_size(); 65 EXPECT_TRUE(size == 1); 66 mem->set_key(SysMeminfoType::PMEM_MEM_TOTAL); 67 uint64_t value = random(); 68 mem->set_value(value); 69 uint64_t zarm = 100; 70 tracePacket.set_zram(zarm); 71 72 PbreaderDataSegment dataSeg; 73 dataSeg.dataType = DATA_SOURCE_TYPE_MEM; 74 dataSeg.clockId = TS_CLOCK_REALTIME; 75 dataSeg.status = TS_PARSE_STATUS_PARSED; 76 dataSeg.timeStamp = 1616439852302; 77 78 std::string memStrMsg = ""; 79 tracePacket.SerializeToString(&memStrMsg); 80 ProtoReader::BytesView memBytesView(reinterpret_cast<const uint8_t *>(memStrMsg.data()), memStrMsg.size()); 81 dataSeg.protoData = memBytesView; 82 83 memParser->Parse(dataSeg, dataSeg.timeStamp, dataSeg.clockId); 84 stream_.traceDataCache_->ExportDatabase(dbPath_); 85 86 EXPECT_TRUE(access(dbPath_.c_str(), F_OK) == 0); 87 tracePacket.clear_meminfo(); 88 delete memParser; 89 90 auto eventCount = stream_.traceDataCache_->GetConstStatAndInfo().GetValue(TRACE_SYS_MEMORY, STAT_EVENT_RECEIVED); 91 EXPECT_TRUE(1 == eventCount); 92 EXPECT_EQ(4, stream_.traceDataCache_->GetConstSysMeasureFilterData().Size()); 93 EXPECT_EQ(stream_.traceDataCache_->GetConstSysMemMeasureData().ValuesData()[0], static_cast<int64_t>(value)); 94 } 95 96 /** 97 * @tc.name: ParseSysMemParseNormal 98 * @tc.desc: Kernel memory parsing test normal 99 * @tc.type: FUNC 100 */ 101 HWTEST_F(HtraceSysMemParserTest, ParseSysMemParseNormal, TestSize.Level1) 102 { 103 TS_LOGI("test19-2"); 104 PbreaderMemParser *memParser = new PbreaderMemParser(stream_.traceDataCache_.get(), stream_.streamFilters_.get()); 105 106 MemoryData tracePacket; 107 SysMeminfo *mem = tracePacket.add_meminfo(); 108 EXPECT_TRUE(mem != nullptr); 109 int32_t size = tracePacket.meminfo_size(); 110 EXPECT_TRUE(size == 1); 111 mem->set_key(SysMeminfoType::PMEM_MEM_TOTAL); 112 uint64_t value = random(); 113 mem->set_value(value); 114 115 mem = tracePacket.add_meminfo(); 116 EXPECT_TRUE(mem != nullptr); 117 size = tracePacket.meminfo_size(); 118 EXPECT_TRUE(size == 2); 119 mem->set_key(SysMeminfoType::PMEM_MEM_FREE); 120 uint64_t value2 = random(); 121 mem->set_value(value2); 122 uint64_t zarm = 100; 123 tracePacket.set_zram(zarm); 124 125 PbreaderDataSegment dataSeg; 126 dataSeg.dataType = DATA_SOURCE_TYPE_MEM; 127 dataSeg.clockId = TS_CLOCK_REALTIME; 128 dataSeg.status = TS_PARSE_STATUS_PARSED; 129 dataSeg.timeStamp = 1616439852302; 130 131 std::string memStrMsg = ""; 132 tracePacket.SerializeToString(&memStrMsg); 133 ProtoReader::BytesView memBytesView(reinterpret_cast<const uint8_t *>(memStrMsg.data()), memStrMsg.size()); 134 dataSeg.protoData = memBytesView; 135 136 memParser->Parse(dataSeg, dataSeg.timeStamp, dataSeg.clockId); 137 stream_.traceDataCache_->ExportDatabase(dbPath_); 138 139 EXPECT_TRUE(access(dbPath_.c_str(), F_OK) == 0); 140 tracePacket.clear_meminfo(); 141 delete memParser; 142 143 auto eventCount = stream_.traceDataCache_->GetConstStatAndInfo().GetValue(TRACE_SYS_MEMORY, STAT_EVENT_RECEIVED); 144 EXPECT_TRUE(1 == eventCount); 145 EXPECT_EQ(5, stream_.traceDataCache_->GetConstSysMemMeasureData().Size()); 146 EXPECT_TRUE(stream_.traceDataCache_->GetConstSysMemMeasureData().ValuesData()[0] == static_cast<int64_t>(value)); 147 EXPECT_TRUE(stream_.traceDataCache_->GetConstSysMemMeasureData().ValuesData()[1] == static_cast<int64_t>(value2)); 148 } 149 150 /** 151 * @tc.name: ParseSysMemParseAbnomal 152 * @tc.desc: Kernel memory parsing test abnomal 153 * @tc.type: FUNC 154 */ 155 HWTEST_F(HtraceSysMemParserTest, ParseSysMemParseAbnomal, TestSize.Level1) 156 { 157 TS_LOGI("test19-3"); 158 PbreaderMemParser *memParser = new PbreaderMemParser(stream_.traceDataCache_.get(), stream_.streamFilters_.get()); 159 160 MemoryData tracePacket; 161 SysMeminfo *mem = tracePacket.add_meminfo(); 162 EXPECT_TRUE(mem != nullptr); 163 int32_t size = tracePacket.meminfo_size(); 164 EXPECT_TRUE(size == 1); 165 mem->set_key(SysMeminfoType::PMEM_MEM_TOTAL); 166 uint64_t value = random(); 167 mem->set_value(value); 168 169 mem = tracePacket.add_meminfo(); 170 EXPECT_TRUE(mem != nullptr); 171 size = tracePacket.meminfo_size(); 172 EXPECT_TRUE(size == 2); 173 mem->set_key(static_cast<SysMeminfoType>(199999)); // invalid data 174 uint64_t value2 = random(); 175 mem->set_value(value2); 176 uint64_t zarm = 100; 177 tracePacket.set_zram(zarm); 178 179 PbreaderDataSegment dataSeg; 180 dataSeg.dataType = DATA_SOURCE_TYPE_MEM; 181 dataSeg.clockId = TS_CLOCK_REALTIME; 182 dataSeg.status = TS_PARSE_STATUS_PARSED; 183 dataSeg.timeStamp = 1616439852302; 184 185 std::string memStrMsg = ""; 186 tracePacket.SerializeToString(&memStrMsg); 187 ProtoReader::BytesView memBytesView(reinterpret_cast<const uint8_t *>(memStrMsg.data()), memStrMsg.size()); 188 dataSeg.protoData = memBytesView; 189 190 memParser->Parse(dataSeg, dataSeg.timeStamp, dataSeg.clockId); 191 stream_.traceDataCache_->ExportDatabase(dbPath_); 192 193 EXPECT_TRUE(access(dbPath_.c_str(), F_OK) == 0); 194 tracePacket.clear_meminfo(); 195 delete memParser; 196 197 auto eventCount = stream_.traceDataCache_->GetConstStatAndInfo().GetValue(TRACE_SYS_MEMORY, STAT_EVENT_RECEIVED); 198 EXPECT_TRUE(1 == eventCount); 199 eventCount = stream_.traceDataCache_->GetConstStatAndInfo().GetValue(TRACE_SYS_MEMORY, STAT_EVENT_DATA_INVALID); 200 EXPECT_TRUE(1 == eventCount); 201 EXPECT_EQ(4, stream_.traceDataCache_->GetConstSysMemMeasureData().Size()); 202 EXPECT_TRUE(stream_.traceDataCache_->GetConstSysMemMeasureData().ValuesData()[0] == static_cast<int64_t>(value)); 203 } 204 205 /** 206 * @tc.name: ParseSysMemParseMutiNomal 207 * @tc.desc: Kernel memory parsing test with muti nomal 208 * @tc.type: FUNC 209 */ 210 HWTEST_F(HtraceSysMemParserTest, ParseSysMemParseMutiNomal, TestSize.Level1) 211 { 212 TS_LOGI("test19-4"); 213 PbreaderMemParser *memParser = new PbreaderMemParser(stream_.traceDataCache_.get(), stream_.streamFilters_.get()); 214 215 MemoryData tracePacket; 216 SysMeminfo *mem = tracePacket.add_meminfo(); 217 EXPECT_TRUE(mem != nullptr); 218 int32_t size = tracePacket.meminfo_size(); 219 EXPECT_TRUE(size == 1); 220 mem->set_key(SysMeminfoType::PMEM_KERNEL_RECLAIMABLE); 221 uint64_t value = random(); 222 mem->set_value(value); 223 224 mem = tracePacket.add_meminfo(); 225 EXPECT_TRUE(mem != nullptr); 226 size = tracePacket.meminfo_size(); 227 EXPECT_TRUE(size == 2); 228 mem->set_key(SysMeminfoType::SysMeminfoType_INT_MIN_SENTINEL_DO_NOT_USE_); 229 uint64_t value2 = random(); 230 mem->set_value(value2); 231 232 mem = tracePacket.add_meminfo(); 233 EXPECT_TRUE(mem != nullptr); 234 size = tracePacket.meminfo_size(); 235 EXPECT_TRUE(size == 3); 236 mem->set_key(SysMeminfoType::SysMeminfoType_INT_MAX_SENTINEL_DO_NOT_USE_); 237 uint64_t value3 = random(); 238 mem->set_value(value3); 239 uint64_t zarm = 100; 240 tracePacket.set_zram(zarm); 241 242 PbreaderDataSegment dataSeg; 243 dataSeg.dataType = DATA_SOURCE_TYPE_MEM; 244 dataSeg.clockId = TS_CLOCK_REALTIME; 245 dataSeg.status = TS_PARSE_STATUS_PARSED; 246 dataSeg.timeStamp = 1616439852302; 247 248 std::string memStrMsg = ""; 249 tracePacket.SerializeToString(&memStrMsg); 250 ProtoReader::BytesView memBytesView(reinterpret_cast<const uint8_t *>(memStrMsg.data()), memStrMsg.size()); 251 dataSeg.protoData = memBytesView; 252 253 memParser->Parse(dataSeg, dataSeg.timeStamp, dataSeg.clockId); 254 stream_.traceDataCache_->ExportDatabase(dbPath_); 255 256 EXPECT_TRUE(access(dbPath_.c_str(), F_OK) == 0); 257 tracePacket.clear_meminfo(); 258 delete memParser; 259 260 auto eventCount = stream_.traceDataCache_->GetConstStatAndInfo().GetValue(TRACE_SYS_MEMORY, STAT_EVENT_RECEIVED); 261 EXPECT_TRUE(1 == eventCount); 262 eventCount = stream_.traceDataCache_->GetConstStatAndInfo().GetValue(TRACE_SYS_MEMORY, STAT_EVENT_DATA_INVALID); 263 EXPECT_TRUE(2 == eventCount); 264 EXPECT_EQ(4, stream_.traceDataCache_->GetConstSysMemMeasureData().Size()); 265 EXPECT_TRUE(stream_.traceDataCache_->GetConstSysMemMeasureData().ValuesData()[0] == static_cast<int64_t>(value)); 266 } 267 268 /** 269 * @tc.name: ParseSysMemParseWithRandomValue 270 * @tc.desc: Kernel memory parsing test, input a random reasonable value 271 * @tc.type: FUNC 272 */ 273 HWTEST_F(HtraceSysMemParserTest, ParseSysMemParseWithRandomValue, TestSize.Level1) 274 { 275 TS_LOGI("test19-5"); 276 PbreaderMemParser *memParser = new PbreaderMemParser(stream_.traceDataCache_.get(), stream_.streamFilters_.get()); 277 278 MemoryData tracePacket; 279 280 std::map<SysMeminfoType, int64_t> sysMemValueMap_ = {}; 281 for (auto i = 0; i < SysMeminfoType::PMEM_KERNEL_RECLAIMABLE + 1; i++) { 282 uint64_t value = random(); 283 sysMemValueMap_.insert(std::make_pair(static_cast<SysMeminfoType>(i), value)); 284 SysMeminfo *mem = tracePacket.add_meminfo(); 285 EXPECT_TRUE(mem != nullptr); 286 mem->set_key(static_cast<SysMeminfoType>(i)); 287 mem->set_value(value); 288 int32_t size = tracePacket.meminfo_size(); 289 EXPECT_TRUE(size == i + 1); 290 } 291 292 PbreaderDataSegment dataSeg; 293 dataSeg.dataType = DATA_SOURCE_TYPE_MEM; 294 dataSeg.clockId = TS_CLOCK_REALTIME; 295 dataSeg.status = TS_PARSE_STATUS_PARSED; 296 dataSeg.timeStamp = 1616439852302; 297 298 std::string memStrMsg = ""; 299 tracePacket.SerializeToString(&memStrMsg); 300 ProtoReader::BytesView memBytesView(reinterpret_cast<const uint8_t *>(memStrMsg.data()), memStrMsg.size()); 301 dataSeg.protoData = memBytesView; 302 303 memParser->Parse(dataSeg, dataSeg.timeStamp, dataSeg.clockId); 304 stream_.traceDataCache_->ExportDatabase(dbPath_); 305 306 EXPECT_TRUE(access(dbPath_.c_str(), F_OK) == 0); 307 tracePacket.clear_meminfo(); 308 delete memParser; 309 310 auto eventCount = stream_.traceDataCache_->GetConstStatAndInfo().GetValue(TRACE_SYS_MEMORY, STAT_EVENT_RECEIVED); 311 EXPECT_TRUE(1 == eventCount); 312 313 for (auto i = 0; i < SysMeminfoType::PMEM_KERNEL_RECLAIMABLE + 1; i++) { 314 EXPECT_TRUE(stream_.traceDataCache_->GetConstSysMemMeasureData().ValuesData()[i] == 315 sysMemValueMap_.at(static_cast<SysMeminfoType>(i))); 316 } 317 } 318 } // namespace TraceStreamer 319 } // namespace SysTuning 320