diff options
Diffstat (limited to 'simpleperf/RecordReadThread_test.cpp')
-rw-r--r-- | simpleperf/RecordReadThread_test.cpp | 162 |
1 files changed, 14 insertions, 148 deletions
diff --git a/simpleperf/RecordReadThread_test.cpp b/simpleperf/RecordReadThread_test.cpp index eae58345..a39b30ac 100644 --- a/simpleperf/RecordReadThread_test.cpp +++ b/simpleperf/RecordReadThread_test.cpp @@ -106,14 +106,10 @@ TEST(RecordParser, smoke) { } struct MockEventFd : public EventFd { - MockEventFd(const perf_event_attr& attr, int cpu, char* buffer, size_t buffer_size, - bool mock_aux_buffer) + MockEventFd(const perf_event_attr& attr, int cpu, char* buffer, size_t buffer_size) : EventFd(attr, -1, "", 0, cpu) { mmap_data_buffer_ = buffer; mmap_data_buffer_size_ = buffer_size; - if (mock_aux_buffer) { - aux_buffer_size_ = 1; // Make HasAuxBuffer() return true. - } } MOCK_METHOD2(CreateMappedBuffer, bool(size_t, bool)); @@ -122,11 +118,6 @@ struct MockEventFd : public EventFd { MOCK_METHOD0(StopPolling, bool()); MOCK_METHOD1(GetAvailableMmapDataSize, size_t(size_t&)); MOCK_METHOD1(DiscardMmapData, void(size_t)); - - MOCK_METHOD2(CreateAuxBuffer, bool(size_t, bool)); - MOCK_METHOD0(DestroyAuxBuffer, void()); - MOCK_METHOD4(GetAvailableAuxData, uint64_t(char**, size_t*, char**, size_t*)); - MOCK_METHOD1(DiscardAuxData, void(size_t)); }; static perf_event_attr CreateFakeEventAttr() { @@ -179,7 +170,7 @@ TEST(KernelRecordReader, smoke) { pos += records[i]->size(); } // Read records using KernelRecordReader. - MockEventFd event_fd(attr, 0, buffer.data(), buffer.size(), false); + MockEventFd event_fd(attr, 0, buffer.data(), buffer.size()); EXPECT_CALL(event_fd, GetAvailableMmapDataSize(Truly(SetArg(data_pos)))) .Times(1).WillOnce(Return(data_size)); @@ -217,7 +208,7 @@ class RecordReadThreadTest : public ::testing::Test { } event_fds_.resize(event_fd_count); for (size_t i = 0; i < event_fd_count; ++i) { - event_fds_[i].reset(new MockEventFd(attr, i, buffers_[i].data(), buffer_size, false)); + event_fds_[i].reset(new MockEventFd(attr, i, buffers_[i].data(), buffer_size)); EXPECT_CALL(*event_fds_[i], CreateMappedBuffer(_, _)).Times(1).WillOnce(Return(true)); EXPECT_CALL(*event_fds_[i], StartPolling(_, _)).Times(1).WillOnce(Return(true)); EXPECT_CALL(*event_fds_[i], GetAvailableMmapDataSize(Truly(SetArg(0)))).Times(1) @@ -225,7 +216,6 @@ class RecordReadThreadTest : public ::testing::Test { EXPECT_CALL(*event_fds_[i], DiscardMmapData(Eq(data_size))).Times(1); EXPECT_CALL(*event_fds_[i], StopPolling()).Times(1).WillOnce(Return(true)); EXPECT_CALL(*event_fds_[i], DestroyMappedBuffer()).Times(1); - EXPECT_CALL(*event_fds_[i], DestroyAuxBuffer()).Times(1); } std::vector<EventFd*> result; for (auto& fd : event_fds_) { @@ -243,7 +233,7 @@ TEST_F(RecordReadThreadTest, handle_cmds) { perf_event_attr attr = CreateFakeEventAttr(); records_ = CreateFakeRecords(attr, 2, 0, 0); std::vector<EventFd*> event_fds = CreateFakeEventFds(attr, 2); - RecordReadThread thread(128 * 1024, event_fds[0]->attr(), 1, 1, 0); + RecordReadThread thread(128 * 1024, event_fds[0]->attr(), 1, 1); IOEventLoop loop; bool has_notify = false; auto callback = [&]() { @@ -262,7 +252,7 @@ TEST_F(RecordReadThreadTest, handle_cmds) { TEST_F(RecordReadThreadTest, read_records) { perf_event_attr attr = CreateFakeEventAttr(); - RecordReadThread thread(128 * 1024, attr, 1, 1, 0); + RecordReadThread thread(128 * 1024, attr, 1, 1); IOEventLoop loop; size_t record_index; auto callback = [&]() { @@ -297,7 +287,7 @@ TEST_F(RecordReadThreadTest, process_sample_record) { attr.sample_type |= PERF_SAMPLE_STACK_USER; attr.sample_stack_user = 64 * 1024; size_t record_buffer_size = 128 * 1024; - RecordReadThread thread(record_buffer_size, attr, 1, 1, 0); + RecordReadThread thread(record_buffer_size, attr, 1, 1); IOEventLoop loop; ASSERT_TRUE(thread.RegisterDataCallback(loop, []() { return true; })); @@ -339,16 +329,20 @@ TEST_F(RecordReadThreadTest, process_sample_record) { thread.SetBufferLevels(record_buffer_size, record_buffer_size); read_record(r); ASSERT_FALSE(r); - ASSERT_EQ(thread.GetStat().lost_samples, 1u); - ASSERT_EQ(thread.GetStat().lost_non_samples, 0u); - ASSERT_EQ(thread.GetStat().cut_stack_samples, 1u); + size_t lost_samples; + size_t lost_non_samples; + size_t cut_stack_samples; + thread.GetLostRecords(&lost_samples, &lost_non_samples, &cut_stack_samples); + ASSERT_EQ(lost_samples, 1u); + ASSERT_EQ(lost_non_samples, 0u); + ASSERT_EQ(cut_stack_samples, 1u); } // Test that the data notification exists until the RecordBuffer is empty. So we can read all // records even if reading one record at a time. TEST_F(RecordReadThreadTest, has_data_notification_until_buffer_empty) { perf_event_attr attr = CreateFakeEventAttr(); - RecordReadThread thread(128 * 1024, attr, 1, 1, 0); + RecordReadThread thread(128 * 1024, attr, 1, 1); IOEventLoop loop; size_t record_index = 0; auto read_one_record = [&]() { @@ -371,131 +365,3 @@ TEST_F(RecordReadThreadTest, has_data_notification_until_buffer_empty) { ASSERT_EQ(record_index, records_.size()); ASSERT_TRUE(thread.RemoveEventFds(event_fds)); } - -TEST_F(RecordReadThreadTest, no_cut_samples) { - perf_event_attr attr = CreateFakeEventAttr(); - attr.sample_type |= PERF_SAMPLE_STACK_USER; - attr.sample_stack_user = 64 * 1024; - RecordReadThread thread(128 * 1024, attr, 1, 1, 0, false); - IOEventLoop loop; - ASSERT_TRUE(thread.RegisterDataCallback(loop, []() { return true; })); - const size_t total_samples = 100; - records_ = CreateFakeRecords(attr, total_samples, 8 * 1024, 8 * 1024); - std::vector<EventFd*> event_fds = CreateFakeEventFds(attr, 1); - ASSERT_TRUE(thread.AddEventFds(event_fds)); - ASSERT_TRUE(thread.SyncKernelBuffer()); - ASSERT_TRUE(thread.RemoveEventFds(event_fds)); - size_t received_samples = 0; - while (thread.GetRecord()) { - received_samples++; - } - ASSERT_GT(received_samples, 0u); - ASSERT_GT(thread.GetStat().lost_samples, 0u); - ASSERT_EQ(thread.GetStat().lost_samples, total_samples - received_samples); - ASSERT_EQ(thread.GetStat().cut_stack_samples, 0u); -} - -struct FakeAuxData { - std::vector<char> buf1; - std::vector<char> buf2; - std::vector<char> pad; - bool lost; - - FakeAuxData(size_t buf1_size, size_t buf2_size, char c, size_t pad_size, bool lost) - : buf1(buf1_size, c), buf2(buf2_size, c), pad(pad_size, 0), lost(lost) {} -}; - -TEST_F(RecordReadThreadTest, read_aux_data) { - const EventType* type = FindEventTypeByName("cs-etm"); - if (type == nullptr) { - GTEST_LOG_(INFO) << "Omit this test as cs-etm event type isn't available"; - return; - } - std::vector<FakeAuxData> aux_data; - aux_data.emplace_back(40, 0, '0', 0, false); // one buffer - aux_data.emplace_back(40, 40, '1', 0, false); // two buffers - aux_data.emplace_back(36, 0, '2', 4, false); // one buffer needs padding to 8 bytes alignment - aux_data.emplace_back(1024, 0, '3', 0, true); // one buffer too big to fit into RecordReadThread - size_t test_index = 0; - - auto SetBuf1 = [&](char** buf1) { - *buf1 = aux_data[test_index].buf1.data(); - return true; - }; - auto SetSize1 = [&](size_t* size1) { - *size1 = aux_data[test_index].buf1.size(); - return true; - }; - auto SetBuf2 = [&](char** buf2) { - *buf2 = aux_data[test_index].buf2.data(); - return true; - }; - auto SetSize2 = [&](size_t* size2) { - *size2 = aux_data[test_index].buf2.size(); - return true; - }; - auto CheckDiscardSize = [&](size_t size) { - return size == aux_data[test_index].buf1.size() + aux_data[test_index].buf2.size(); - }; - - const size_t AUX_BUFFER_SIZE = 4096; - - perf_event_attr attr = CreateDefaultPerfEventAttr(*type); - MockEventFd fd(attr, 0, nullptr, 1, true); - EXPECT_CALL(fd, CreateMappedBuffer(_, _)).Times(1).WillOnce(Return(true)); - EXPECT_CALL(fd, CreateAuxBuffer(Eq(AUX_BUFFER_SIZE), _)).Times(1).WillOnce(Return(true)); - EXPECT_CALL(fd, StartPolling(_, _)).Times(1).WillOnce(Return(true)); - EXPECT_CALL(fd, GetAvailableMmapDataSize(_)).Times(aux_data.size()).WillRepeatedly(Return(0)); - EXPECT_CALL(fd, - GetAvailableAuxData(Truly(SetBuf1), Truly(SetSize1), Truly(SetBuf2), Truly(SetSize2))) - .Times(aux_data.size()); - EXPECT_CALL(fd, DiscardAuxData(Truly(CheckDiscardSize))).Times(aux_data.size()); - EXPECT_CALL(fd, StopPolling()).Times(1).WillOnce(Return(true)); - EXPECT_CALL(fd, DestroyMappedBuffer()).Times(1); - EXPECT_CALL(fd, DestroyAuxBuffer()).Times(1); - - RecordReadThread thread(1024, attr, 1, 1, AUX_BUFFER_SIZE); - IOEventLoop loop; - ASSERT_TRUE(thread.RegisterDataCallback(loop, []() { return true; })); - ASSERT_TRUE(thread.AddEventFds({&fd})); - for (; test_index < aux_data.size(); ++test_index) { - ASSERT_TRUE(thread.SyncKernelBuffer()); - std::unique_ptr<Record> r = thread.GetRecord(); - if (aux_data[test_index].lost) { - ASSERT_TRUE(r == nullptr); - continue; - } - ASSERT_TRUE(r); - ASSERT_EQ(r->type(), PERF_RECORD_AUXTRACE); - auto auxtrace = static_cast<AuxTraceRecord*>(r.get()); - auto& expected = aux_data[test_index]; - ASSERT_EQ(auxtrace->data->aux_size, - expected.buf1.size() + expected.buf2.size() + expected.pad.size()); - const char* p = auxtrace->location.addr; - ASSERT_TRUE(p != nullptr); - if (!expected.buf1.empty()) { - ASSERT_EQ(memcmp(p, expected.buf1.data(), expected.buf1.size()), 0); - p += expected.buf1.size(); - } - if (!expected.buf2.empty()) { - ASSERT_EQ(memcmp(p, expected.buf2.data(), expected.buf2.size()), 0); - p += expected.buf2.size(); - } - if (!expected.pad.empty()) { - ASSERT_EQ(memcmp(p, expected.pad.data(), expected.pad.size()), 0); - } - } - ASSERT_TRUE(thread.GetRecord() == nullptr); - ASSERT_TRUE(thread.RemoveEventFds({&fd})); - size_t aux_data_size = 0; - size_t lost_aux_data_size = 0; - for (auto& aux : aux_data) { - if (aux.lost) { - lost_aux_data_size += aux.buf1.size() + aux.buf2.size(); - } else { - aux_data_size += aux.buf1.size() + aux.buf2.size(); - } - } - ASSERT_EQ(aux_data_size, thread.GetStat().aux_data_size); - ASSERT_EQ(lost_aux_data_size, thread.GetStat().lost_aux_data_size); -}
\ No newline at end of file |