1 /* 2 * Copyright (c) 2021 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 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 "htrace_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 HtraceSysVMemParserTest : 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_ = "../../../data/resource/out.db"; 50 }; 51 52 /** 53 * @tc.name: ParseSysVMemParse 54 * @tc.desc: Virtual memory parsing test, input a random reasonable value 55 * @tc.type: FUNC 56 */ 57 HWTEST_F(HtraceSysVMemParserTest, ParseSysVMemParse, TestSize.Level1) 58 { 59 TS_LOGI("test20-1"); 60 HtraceMemParser* memParser = new HtraceMemParser(stream_.traceDataCache_.get(), stream_.streamFilters_.get()); 61 62 MemoryData tracePacket; 63 SysVMeminfo* vmem = tracePacket.add_vmeminfo(); 64 EXPECT_TRUE(vmem != nullptr); 65 int32_t size = tracePacket.vmeminfo_size(); 66 EXPECT_TRUE(size == 1); 67 vmem->set_key(SysVMeminfoType::VMEMINFO_UNSPECIFIED); 68 uint64_t value = random(); 69 vmem->set_value(value); 70 HtraceDataSegment dataSeg; 71 dataSeg.dataType = DATA_SOURCE_TYPE_MEM; 72 dataSeg.clockId = TS_CLOCK_REALTIME; 73 dataSeg.status = TS_PARSE_STATUS_PARSED; 74 dataSeg.timeStamp = 1616439852302; 75 76 std::string memStrMsg = ""; 77 tracePacket.SerializeToString(&memStrMsg); 78 ProtoReader::BytesView memBytesView(reinterpret_cast<const uint8_t*>(memStrMsg.data()), memStrMsg.size()); 79 dataSeg.protoData = memBytesView; 80 81 memParser->Parse(dataSeg, dataSeg.timeStamp, dataSeg.clockId); 82 stream_.traceDataCache_->ExportDatabase(dbPath_); 83 84 EXPECT_TRUE(access(dbPath_.c_str(), F_OK) == 0); 85 tracePacket.clear_meminfo(); 86 delete memParser; 87 88 auto eventCount = 89 stream_.traceDataCache_->GetConstStatAndInfo().GetValue(TRACE_SYS_VIRTUAL_MEMORY, STAT_EVENT_RECEIVED); 90 EXPECT_TRUE(1 == eventCount); 91 EXPECT_TRUE(stream_.traceDataCache_->GetConstSysMemMeasureData().Size() == 1); 92 EXPECT_TRUE(stream_.traceDataCache_->GetConstSysMemMeasureData().ValuesData()[0] == static_cast<int64_t>(value)); 93 } 94 95 /** 96 * @tc.name: ParseSysVMemNomal 97 * @tc.desc: Virtual memory parsing test nomal 98 * @tc.type: FUNC 99 */ 100 HWTEST_F(HtraceSysVMemParserTest, ParseSysVMemNomal, TestSize.Level1) 101 { 102 TS_LOGI("test20-2"); 103 HtraceMemParser* memParser = new HtraceMemParser(stream_.traceDataCache_.get(), stream_.streamFilters_.get()); 104 105 MemoryData tracePacket; 106 SysVMeminfo* vmem = tracePacket.add_vmeminfo(); 107 EXPECT_TRUE(vmem != nullptr); 108 int32_t size = tracePacket.vmeminfo_size(); 109 EXPECT_TRUE(size == 1); 110 vmem->set_key(SysVMeminfoType::VMEMINFO_NR_FREE_PAGES); 111 uint64_t value = random(); 112 vmem->set_value(value); 113 114 vmem = tracePacket.add_vmeminfo(); 115 EXPECT_TRUE(vmem != nullptr); 116 size = tracePacket.vmeminfo_size(); 117 EXPECT_TRUE(size == 2); 118 vmem->set_key(SysVMeminfoType::VMEMINFO_NR_ALLOC_BATCH); 119 uint64_t value2 = random(); 120 vmem->set_value(value2); 121 122 HtraceDataSegment dataSeg; 123 dataSeg.dataType = DATA_SOURCE_TYPE_MEM; 124 dataSeg.clockId = TS_CLOCK_REALTIME; 125 dataSeg.status = TS_PARSE_STATUS_PARSED; 126 dataSeg.timeStamp = 1616439852302; 127 128 std::string memStrMsg = ""; 129 tracePacket.SerializeToString(&memStrMsg); 130 ProtoReader::BytesView memBytesView(reinterpret_cast<const uint8_t*>(memStrMsg.data()), memStrMsg.size()); 131 dataSeg.protoData = memBytesView; 132 133 memParser->Parse(dataSeg, dataSeg.timeStamp, dataSeg.clockId); 134 stream_.traceDataCache_->ExportDatabase(dbPath_); 135 136 EXPECT_TRUE(access(dbPath_.c_str(), F_OK) == 0); 137 tracePacket.clear_meminfo(); 138 delete memParser; 139 140 auto eventCount = 141 stream_.traceDataCache_->GetConstStatAndInfo().GetValue(TRACE_SYS_VIRTUAL_MEMORY, STAT_EVENT_RECEIVED); 142 EXPECT_TRUE(1 == eventCount); 143 EXPECT_TRUE(stream_.traceDataCache_->GetConstSysMemMeasureData().Size() == 2); 144 EXPECT_TRUE(stream_.traceDataCache_->GetConstSysMemMeasureData().ValuesData()[0] == static_cast<int64_t>(value)); 145 EXPECT_TRUE(stream_.traceDataCache_->GetConstSysMemMeasureData().ValuesData()[1] == static_cast<int64_t>(value2)); 146 } 147 148 /** 149 * @tc.name: ParseSysVMemAbnomal 150 * @tc.desc: Virtual memory parsing test abnomal 151 * @tc.type: FUNC 152 */ 153 HWTEST_F(HtraceSysVMemParserTest, ParseSysVMemAbnomal, TestSize.Level1) 154 { 155 TS_LOGI("test20-3"); 156 HtraceMemParser* memParser = new HtraceMemParser(stream_.traceDataCache_.get(), stream_.streamFilters_.get()); 157 158 MemoryData tracePacket; 159 SysVMeminfo* vmem = tracePacket.add_vmeminfo(); 160 EXPECT_TRUE(vmem != nullptr); 161 int32_t size = tracePacket.vmeminfo_size(); 162 EXPECT_TRUE(size == 1); 163 vmem->set_key(SysVMeminfoType::VMEMINFO_NR_FREE_PAGES); 164 uint64_t value = random(); 165 vmem->set_value(value); 166 167 vmem = tracePacket.add_vmeminfo(); 168 EXPECT_TRUE(vmem != nullptr); 169 size = tracePacket.vmeminfo_size(); 170 EXPECT_TRUE(size == 2); 171 uint64_t value2 = random(); 172 vmem->set_value(value2); 173 174 HtraceDataSegment dataSeg; 175 dataSeg.dataType = DATA_SOURCE_TYPE_MEM; 176 dataSeg.clockId = TS_CLOCK_REALTIME; 177 dataSeg.status = TS_PARSE_STATUS_PARSED; 178 dataSeg.timeStamp = 1616439852302; 179 180 std::string memStrMsg = ""; 181 tracePacket.SerializeToString(&memStrMsg); 182 ProtoReader::BytesView memBytesView(reinterpret_cast<const uint8_t*>(memStrMsg.data()), memStrMsg.size()); 183 dataSeg.protoData = memBytesView; 184 185 memParser->Parse(dataSeg, dataSeg.timeStamp, dataSeg.clockId); 186 stream_.traceDataCache_->ExportDatabase(dbPath_); 187 188 EXPECT_TRUE(access(dbPath_.c_str(), F_OK) == 0); 189 tracePacket.clear_meminfo(); 190 delete memParser; 191 192 auto eventCount = 193 stream_.traceDataCache_->GetConstStatAndInfo().GetValue(TRACE_SYS_VIRTUAL_MEMORY, STAT_EVENT_RECEIVED); 194 EXPECT_TRUE(1 == eventCount); 195 eventCount = 196 stream_.traceDataCache_->GetConstStatAndInfo().GetValue(TRACE_SYS_VIRTUAL_MEMORY, STAT_EVENT_DATA_INVALID); 197 EXPECT_TRUE(0 == eventCount); 198 EXPECT_TRUE(stream_.traceDataCache_->GetConstSysMemMeasureData().Size() == 2); 199 EXPECT_TRUE(stream_.traceDataCache_->GetConstSysMemMeasureData().ValuesData()[0] == static_cast<int64_t>(value)); 200 } 201 202 /** 203 * @tc.name: ParseSysVMemWithMutiNomal 204 * @tc.desc: Virtual memory parsing test with muti nomal 205 * @tc.type: FUNC 206 */ 207 HWTEST_F(HtraceSysVMemParserTest, ParseSysVMemWithMutiNomal, TestSize.Level1) 208 { 209 TS_LOGI("test20-4"); 210 HtraceMemParser* memParser = new HtraceMemParser(stream_.traceDataCache_.get(), stream_.streamFilters_.get()); 211 212 MemoryData tracePacket; 213 SysVMeminfo* vmem = tracePacket.add_vmeminfo(); 214 EXPECT_TRUE(vmem != nullptr); 215 int32_t size = tracePacket.vmeminfo_size(); 216 EXPECT_TRUE(size == 1); 217 vmem->set_key(SysVMeminfoType::VMEMINFO_WORKINGSET_RESTORE); 218 uint64_t value = random(); 219 vmem->set_value(value); 220 221 vmem = tracePacket.add_vmeminfo(); 222 EXPECT_TRUE(vmem != nullptr); 223 size = tracePacket.vmeminfo_size(); 224 EXPECT_TRUE(size == 2); 225 vmem->set_key(SysVMeminfoType::SysVMeminfoType_INT_MIN_SENTINEL_DO_NOT_USE_); 226 uint64_t value2 = random(); 227 vmem->set_value(value2); 228 229 vmem = tracePacket.add_vmeminfo(); 230 EXPECT_TRUE(vmem != nullptr); 231 size = tracePacket.vmeminfo_size(); 232 EXPECT_TRUE(size == 3); 233 vmem->set_key(SysVMeminfoType::SysVMeminfoType_INT_MAX_SENTINEL_DO_NOT_USE_); 234 uint64_t value3 = random(); 235 vmem->set_value(value3); 236 237 HtraceDataSegment dataSeg; 238 dataSeg.dataType = DATA_SOURCE_TYPE_MEM; 239 dataSeg.clockId = TS_CLOCK_REALTIME; 240 dataSeg.status = TS_PARSE_STATUS_PARSED; 241 dataSeg.timeStamp = 1616439852302; 242 243 std::string memStrMsg = ""; 244 tracePacket.SerializeToString(&memStrMsg); 245 ProtoReader::BytesView memBytesView(reinterpret_cast<const uint8_t*>(memStrMsg.data()), memStrMsg.size()); 246 dataSeg.protoData = memBytesView; 247 248 memParser->Parse(dataSeg, dataSeg.timeStamp, dataSeg.clockId); 249 stream_.traceDataCache_->ExportDatabase(dbPath_); 250 251 EXPECT_TRUE(access(dbPath_.c_str(), F_OK) == 0); 252 tracePacket.clear_vmeminfo(); 253 delete memParser; 254 255 auto eventCount = 256 stream_.traceDataCache_->GetConstStatAndInfo().GetValue(TRACE_SYS_VIRTUAL_MEMORY, STAT_EVENT_RECEIVED); 257 EXPECT_TRUE(1 == eventCount); 258 eventCount = 259 stream_.traceDataCache_->GetConstStatAndInfo().GetValue(TRACE_SYS_VIRTUAL_MEMORY, STAT_EVENT_DATA_INVALID); 260 EXPECT_TRUE(2 == eventCount); 261 EXPECT_TRUE(stream_.traceDataCache_->GetConstSysMemMeasureData().Size() == 1); 262 EXPECT_TRUE(stream_.traceDataCache_->GetConstSysMemMeasureData().ValuesData()[0] == static_cast<int64_t>(value)); 263 } 264 265 /** 266 * @tc.name: ParseSysVMemWithRandomValue 267 * @tc.desc: Virtual memory parsing test, input a random reasonable value 268 * @tc.type: FUNC 269 */ 270 HWTEST_F(HtraceSysVMemParserTest, ParseSysVMemWithRandomValue, TestSize.Level1) 271 { 272 TS_LOGI("test20-5"); 273 HtraceMemParser* memParser = new HtraceMemParser(stream_.traceDataCache_.get(), stream_.streamFilters_.get()); 274 275 MemoryData tracePacket; 276 277 std::map<SysVMeminfoType, int64_t> sysVMemValueMap_ = {}; 278 for (auto i = 0; i < SysVMeminfoType::VMEMINFO_WORKINGSET_RESTORE + 1; i++) { 279 uint64_t value = random(); 280 sysVMemValueMap_.insert(std::make_pair(static_cast<SysVMeminfoType>(i), value)); 281 SysVMeminfo* vmem = tracePacket.add_vmeminfo(); 282 EXPECT_TRUE(vmem != nullptr); 283 vmem->set_key(static_cast<SysVMeminfoType>(i)); 284 vmem->set_value(value); 285 int32_t size = tracePacket.vmeminfo_size(); 286 EXPECT_TRUE(size == i + 1); 287 } 288 289 HtraceDataSegment dataSeg; 290 dataSeg.dataType = DATA_SOURCE_TYPE_MEM; 291 dataSeg.clockId = TS_CLOCK_REALTIME; 292 dataSeg.status = TS_PARSE_STATUS_PARSED; 293 dataSeg.timeStamp = 1616439852302; 294 295 std::string memStrMsg = ""; 296 tracePacket.SerializeToString(&memStrMsg); 297 ProtoReader::BytesView memBytesView(reinterpret_cast<const uint8_t*>(memStrMsg.data()), memStrMsg.size()); 298 dataSeg.protoData = memBytesView; 299 300 memParser->Parse(dataSeg, dataSeg.timeStamp, dataSeg.clockId); 301 stream_.traceDataCache_->ExportDatabase(dbPath_); 302 303 EXPECT_TRUE(access(dbPath_.c_str(), F_OK) == 0); 304 tracePacket.clear_vmeminfo(); 305 delete memParser; 306 307 auto eventCount = 308 stream_.traceDataCache_->GetConstStatAndInfo().GetValue(TRACE_SYS_VIRTUAL_MEMORY, STAT_EVENT_RECEIVED); 309 EXPECT_TRUE(1 == eventCount); 310 311 for (auto i = 0; i < SysVMeminfoType::VMEMINFO_WORKINGSET_RESTORE + 1; i++) { 312 EXPECT_TRUE(stream_.traceDataCache_->GetConstSysMemMeasureData().ValuesData()[i] == 313 sysVMemValueMap_.at(static_cast<SysVMeminfoType>(i))); 314 } 315 } 316 } // namespace TraceStreamer 317 } // namespace SysTuning 318