1 /* 2 * Copyright (c) Huawei Technologies Co., Ltd. 2021. 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 #define LOG_TAG "TraceFileWriterTest" 17 #include <fstream> 18 #include <gtest/gtest.h> 19 #include <unistd.h> 20 #include <vector> 21 #include <fcntl.h> 22 23 #include "common_types.pb.h" 24 #include "logging.h" 25 #include "trace_file_writer.h" 26 27 using namespace testing::ext; 28 29 namespace { 30 class TraceFileWriterTest : public ::testing::Test { 31 protected: 32 std::string path = "trace.bin"; 33 SetUpTestCase()34 static void SetUpTestCase() {} TearDownTestCase()35 static void TearDownTestCase() {} 36 SetUp()37 void SetUp() override {} 38 TearDown()39 void TearDown() override 40 { 41 int retval = unlink(path.c_str()); 42 PROFILER_LOG_DEBUG(LOG_CORE, "unlink(%s): %d", path.c_str(), retval); 43 } 44 }; 45 46 /** 47 * @tc.name: server 48 * @tc.desc: Class-strengthening. 49 * @tc.type: FUNC 50 */ 51 HWTEST_F(TraceFileWriterTest, CtorDtor, TestSize.Level1) 52 { 53 auto writer = std::make_shared<TraceFileWriter>(path); 54 EXPECT_NE(writer, nullptr); 55 } 56 57 /** 58 * @tc.name: server 59 * @tc.desc: write. 60 * @tc.type: FUNC 61 */ 62 HWTEST_F(TraceFileWriterTest, Write, TestSize.Level1) 63 { 64 path = "trace-write.bin"; 65 auto writer = std::make_shared<TraceFileWriter>(path); 66 ASSERT_NE(writer, nullptr); 67 68 std::string testData = "Hello, Wrold!"; 69 EXPECT_EQ(writer->Write(testData.data(), testData.size()), sizeof(uint32_t) + testData.size()); 70 } 71 72 /** 73 * @tc.name: server 74 * @tc.desc: flush. 75 * @tc.type: FUNC 76 */ 77 HWTEST_F(TraceFileWriterTest, Flush, TestSize.Level1) 78 { 79 std::string testData = "Hello, Wrold!"; 80 path = "trace-flush.bin"; 81 { 82 auto writer = std::make_shared<TraceFileWriter>(path); 83 ASSERT_NE(writer, nullptr); 84 EXPECT_EQ(writer->Write(testData.data(), testData.size()), sizeof(uint32_t) + testData.size()); 85 EXPECT_EQ(writer->Flush(), true); 86 } 87 88 uint32_t msgLen = 0; 89 std::ifstream fin(path, std::ios_base::in | std::ios_base::binary); 90 ASSERT_TRUE(fin.is_open()); 91 92 // check file length 93 fin.seekg(0, std::ios_base::end); 94 EXPECT_EQ(fin.tellg(), TraceFileHeader::HEADER_SIZE + sizeof(msgLen) + testData.size()); 95 96 // check msg length 97 fin.seekg(TraceFileHeader::HEADER_SIZE, std::ios_base::beg); // skip file header 98 fin.read(reinterpret_cast<char*>(&msgLen), sizeof(msgLen)); 99 EXPECT_EQ(msgLen, testData.size()); 100 101 // check msg data 102 std::vector<char> outData(testData.size()); 103 fin.read(outData.data(), outData.size()); // read into outData 104 EXPECT_EQ(memcmp(outData.data(), testData.data(), outData.size()), 0); 105 } 106 107 /** 108 * @tc.name: server 109 * @tc.desc: write message. 110 * @tc.type: FUNC 111 */ 112 HWTEST_F(TraceFileWriterTest, WriteMessage, TestSize.Level1) 113 { 114 path = "trace-write-message.bin"; 115 auto writer = std::make_shared<TraceFileWriter>(path); 116 ASSERT_NE(writer, nullptr); 117 118 ProfilerPluginData pluginData; 119 pluginData.set_name("ABC"); 120 pluginData.set_status(0); 121 pluginData.set_data("DEF"); 122 EXPECT_GT(writer->Write(pluginData), 0); 123 } 124 125 /** 126 * @tc.name: server 127 * @tc.desc: Split file. 128 * @tc.type: FUNC 129 */ 130 HWTEST_F(TraceFileWriterTest, SplitFileWriter, TestSize.Level1) 131 { 132 path = "trace-write-test.bin"; 133 auto writer = std::make_shared<TraceFileWriter>(path, true, 0, 0); 134 EXPECT_NE(writer, nullptr); 135 writer->Path(); 136 writer->SetStopSplitFile(false); 137 std::string testData = "this is a test case!"; 138 EXPECT_EQ(writer->Write(testData.data(), testData.size()), sizeof(uint32_t) + testData.size()); 139 std::string testStr = "test case"; 140 writer->SetPluginConfig(testStr.data(), testStr.size()); 141 142 std::string testPath = "trace-write-bin"; 143 auto writerTestPath = std::make_shared<TraceFileWriter>(testPath, true, 0, 1); 144 EXPECT_NE(writerTestPath, nullptr); 145 writerTestPath->splitFilePaths_.push("trace-write-path-1"); 146 writerTestPath->splitFilePaths_.push("trace-write-path-2"); 147 writerTestPath->DeleteOldSplitFile(); 148 EXPECT_TRUE(writerTestPath->IsSplitFile(300 * 1024 * 1024)); 149 150 std::string testPathTemp = "/data/local/tmp/trace-write-path"; 151 auto writerTemp = std::make_shared<TraceFileWriter>(testPathTemp, true, 0, 1); 152 EXPECT_NE(writerTemp, nullptr); 153 } 154 155 /** 156 * @tc.name: server 157 * @tc.desc: remap 158 * @tc.type: FUNC 159 */ 160 HWTEST_F(TraceFileWriterTest, RemapFile, TestSize.Level1) 161 { 162 path = "remap-test.bin"; 163 int fd = open(path.c_str(), O_RDWR | O_CREAT, 0644); 164 if (fd == -1) { 165 perror("open"); 166 return; 167 } 168 auto writer = std::make_shared<TraceFileWriter>(fd); 169 EXPECT_NE(writer, nullptr); 170 uint32_t applySize = 1024 * 1024; // 1MB 171 char temp[1024] = {"this is a test ,this is a test ,this is a test, this is a test\n"}; 172 for (size_t i = 0; i < 2000; i++) { // 2000: loop count 173 uint8_t* memory = nullptr; 174 uint32_t offset = 0; 175 writer->GetMemory(applySize, &memory, &offset); 176 if (i < 1023) { // 1023: remap critical point 177 EXPECT_NE(memory, nullptr); 178 if (memcpy_s(memory, applySize, temp, sizeof(temp)) != EOK) { 179 PROFILER_LOG_INFO(LOG_CORE, "memcpy_s failed,apply size %u", applySize); 180 continue; 181 } 182 writer->FinishReport(applySize); 183 } else { 184 EXPECT_EQ(memory, nullptr); 185 } 186 } 187 EXPECT_GE(writer->fileLength_, 1024 * 1024 * 1024); 188 close(fd); 189 } 190 } // namespace 191