/* * Copyright (c) 2021 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include #include "htrace_cpu_detail_parser.h" #include "htrace_event_parser.h" #include "irq_filter.h" #include "trace_streamer_selector.h" #include "ts_common.h" #include "types/plugins/ftrace_data/trace_plugin_result.pb.h" using namespace testing::ext; using namespace SysTuning::TraceStreamer; namespace SysTuning { namespace TraceStreamer { class HtraceIrqEventTest : public ::testing::Test { public: void SetUp() { stream_.InitFilter();} void TearDown() {} public: SysTuning::TraceStreamer::TraceStreamerSelector stream_ = {}; }; /** * @tc.name: IrqHandlerEntryTest * @tc.desc: Binary formate IrqHandlerEntry Normal TEST * @tc.type: FUNC */ HWTEST_F(HtraceIrqEventTest, IrqHandlerEntryTest, TestSize.Level1) { TS_LOGI("test10-1"); int64_t ts1 = 100; uint32_t cpu1 = 1; std::string appName = "app1"; uint32_t tid1 = 1; int32_t irq = 12; IrqHandlerEntryFormat* irqHandlerEvent = new IrqHandlerEntryFormat(); irqHandlerEvent->set_irq(irq); irqHandlerEvent->set_name("user_irq"); FtraceCpuDetailMsg ftraceCpuDetail; ftraceCpuDetail.set_cpu(cpu1); ftraceCpuDetail.set_overwrite(0); auto ftraceEvent = ftraceCpuDetail.add_event(); ftraceEvent->set_timestamp(ts1); ftraceEvent->set_tgid(tid1); ftraceEvent->set_comm(appName); ftraceEvent->set_allocated_irq_handler_entry_format(irqHandlerEvent); HtraceEventParser eventParser(stream_.traceDataCache_.get(), stream_.streamFilters_.get()); eventParser.ParseDataItem(&ftraceCpuDetail, TS_CLOCK_BOOTTIME); EXPECT_TRUE(stream_.traceDataCache_->GetConstInternalSlicesData().Size() == 1); } /** * @tc.name: IrqHandlerEntryTestNotMatch * @tc.desc: Binary formate IrqHandlerEntry, only start, no end * @tc.type: FUNC */ HWTEST_F(HtraceIrqEventTest, IrqHandlerEntryTestNotMatch, TestSize.Level1) { TS_LOGI("test10-2"); int64_t ts1 = 120; uint32_t cpu1 = 1; std::string appName = "app1"; uint32_t tid1 = 1; int32_t irq = 12; IrqHandlerEntryFormat* irqHandlerEvent = new IrqHandlerEntryFormat(); irqHandlerEvent->set_irq(irq); irqHandlerEvent->set_name("user_irq"); FtraceCpuDetailMsg ftraceCpuDetail; ftraceCpuDetail.set_cpu(cpu1); ftraceCpuDetail.set_overwrite(0); auto ftraceEvent = ftraceCpuDetail.add_event(); ftraceEvent->set_timestamp(ts1); ftraceEvent->set_tgid(tid1); ftraceEvent->set_comm(appName); ftraceEvent->set_allocated_irq_handler_entry_format(irqHandlerEvent); HtraceEventParser eventParser(stream_.traceDataCache_.get(), stream_.streamFilters_.get()); eventParser.ParseDataItem(&ftraceCpuDetail, TS_CLOCK_BOOTTIME); EXPECT_TRUE(stream_.traceDataCache_->GetConstInternalSlicesData().Size() == 1); ts1 = 110; IrqHandlerEntryFormat* irqHandlerEvent2 = new IrqHandlerEntryFormat(); irqHandlerEvent2->set_irq(irq); irqHandlerEvent2->set_name("user_irq"); FtraceCpuDetailMsg ftraceCpuDetail2; ftraceCpuDetail2.set_cpu(cpu1); ftraceCpuDetail2.set_overwrite(0); auto ftraceEvent2 = ftraceCpuDetail2.add_event(); ftraceEvent2->set_timestamp(ts1); ftraceEvent2->set_tgid(tid1); ftraceEvent2->set_comm(appName); ftraceEvent2->set_allocated_irq_handler_entry_format(irqHandlerEvent2); eventParser.ParseDataItem(&ftraceCpuDetail2, TS_CLOCK_BOOTTIME); EXPECT_TRUE(stream_.traceDataCache_->GetConstInternalSlicesData().Size() == 2); auto eventCount = stream_.traceDataCache_->GetConstStatAndInfo().GetValue(TRACE_EVENT_IRQ_HANDLER_ENTRY, STAT_EVENT_DATA_LOST); EXPECT_TRUE(1 == eventCount); } /** * @tc.name: IrqHandlerExitTestEmpty * @tc.desc: Binary formate IrqHandlerExit, Interrupt only ends, not starts * @tc.type: FUNC */ HWTEST_F(HtraceIrqEventTest, IrqHandlerExitTestEmpty, TestSize.Level1) { TS_LOGI("test10-3"); int64_t ts1 = 100; uint32_t cpu1 = 1; uint32_t ret = 1; std::string appName = "app1"; uint32_t tid1 = 1; int32_t irq = 12; // 1 for handled, else for unhandled IrqHandlerExitFormat* irqHandlerExitEvent = new IrqHandlerExitFormat(); irqHandlerExitEvent->set_irq(irq); irqHandlerExitEvent->set_ret(ret); FtraceCpuDetailMsg ftraceCpuDetail; ftraceCpuDetail.set_cpu(cpu1); ftraceCpuDetail.set_overwrite(0); auto ftraceEvent = ftraceCpuDetail.add_event(); ftraceEvent->set_timestamp(ts1); ftraceEvent->set_tgid(tid1); ftraceEvent->set_comm(appName); ftraceEvent->set_allocated_irq_handler_exit_format(irqHandlerExitEvent); HtraceEventParser eventParser(stream_.traceDataCache_.get(), stream_.streamFilters_.get()); eventParser.ParseDataItem(&ftraceCpuDetail, TS_CLOCK_BOOTTIME); EXPECT_TRUE(stream_.traceDataCache_->GetConstInternalSlicesData().Size() == 0); auto eventCount = stream_.traceDataCache_->GetConstStatAndInfo().GetValue(TRACE_EVENT_IRQ_HANDLER_EXIT, STAT_EVENT_NOTMATCH); EXPECT_TRUE(1 == eventCount); } /** * @tc.name: IrqHandlerEnterAndExitTest * @tc.desc: Binary formate IrqHandlerEnter, Interrupt normal start and end * @tc.type: FUNC */ HWTEST_F(HtraceIrqEventTest, IrqHandlerEnterAndExitTest, TestSize.Level1) { TS_LOGI("test10-4"); int64_t ts1 = 100; uint32_t cpu1 = 1; std::string appName = "app1"; uint32_t tid1 = 1; int32_t irq = 12; HtraceEventParser eventParser(stream_.traceDataCache_.get(), stream_.streamFilters_.get()); IrqHandlerEntryFormat* irqHandlerEvent = new IrqHandlerEntryFormat(); irqHandlerEvent->set_irq(irq); irqHandlerEvent->set_name("user_irq"); FtraceCpuDetailMsg ftraceCpuDetail; ftraceCpuDetail.set_cpu(cpu1); ftraceCpuDetail.set_overwrite(0); auto ftraceEvent = ftraceCpuDetail.add_event(); ftraceEvent->set_timestamp(ts1); ftraceEvent->set_tgid(tid1); ftraceEvent->set_comm(appName); ftraceEvent->set_allocated_irq_handler_entry_format(irqHandlerEvent); eventParser.ParseDataItem(&ftraceCpuDetail, TS_CLOCK_BOOTTIME); EXPECT_TRUE(stream_.traceDataCache_->GetConstInternalSlicesData().Size() == 1); uint32_t ret = 1; // 1 for handled, else for unhandled IrqHandlerExitFormat* irqHandlerExitEvent = new IrqHandlerExitFormat(); irqHandlerExitEvent->set_irq(irq); irqHandlerExitEvent->set_ret(ret); FtraceCpuDetailMsg ftraceCpuDetail2; ftraceCpuDetail2.set_cpu(cpu1); ftraceCpuDetail2.set_overwrite(0); auto ftraceEvent2 = ftraceCpuDetail2.add_event(); ftraceEvent2->set_timestamp(ts1); ftraceEvent2->set_tgid(tid1); ftraceEvent2->set_comm(appName); ftraceEvent2->set_allocated_irq_handler_exit_format(irqHandlerExitEvent); eventParser.ParseDataItem(&ftraceCpuDetail2, TS_CLOCK_BOOTTIME); EXPECT_TRUE(stream_.traceDataCache_->GetConstInternalSlicesData().Size() == 1); EXPECT_TRUE(stream_.traceDataCache_->GetConstInternalSlicesData().ArgSetIdsData()[0] == 0); } /** * @tc.name: IrqHandlerEnterAndExitTestTwice * @tc.desc: Binary formate IrqHandlerEnter and Exit, Interrupt normal start and end Twice * @tc.type: FUNC */ HWTEST_F(HtraceIrqEventTest, IrqHandlerEnterAndExitTestTwice, TestSize.Level1) { TS_LOGI("test10-4-2"); int64_t ts1 = 100; uint32_t cpu1 = 1; std::string appName = "app1"; uint32_t tid1 = 1; int32_t irq = 12; HtraceEventParser eventParser(stream_.traceDataCache_.get(), stream_.streamFilters_.get()); IrqHandlerEntryFormat* irqHandlerEvent = new IrqHandlerEntryFormat(); irqHandlerEvent->set_irq(irq); irqHandlerEvent->set_name("user_irq"); FtraceCpuDetailMsg ftraceCpuDetail; ftraceCpuDetail.set_cpu(cpu1); ftraceCpuDetail.set_overwrite(0); auto ftraceEvent = ftraceCpuDetail.add_event(); ftraceEvent->set_timestamp(ts1); ftraceEvent->set_tgid(tid1); ftraceEvent->set_comm(appName); ftraceEvent->set_allocated_irq_handler_entry_format(irqHandlerEvent); eventParser.ParseDataItem(&ftraceCpuDetail, TS_CLOCK_BOOTTIME); EXPECT_TRUE(stream_.traceDataCache_->GetConstInternalSlicesData().Size() == 1); uint32_t ret = 1; // 1 for handled, else for unhandled cpu1 = 2; ts1 = 150; IrqHandlerExitFormat* irqHandlerExitEvent = new IrqHandlerExitFormat(); irqHandlerExitEvent->set_irq(irq); irqHandlerExitEvent->set_ret(ret); FtraceCpuDetailMsg ftraceCpuDetail2; ftraceCpuDetail2.set_cpu(cpu1); ftraceCpuDetail2.set_overwrite(0); auto ftraceEvent2 = ftraceCpuDetail2.add_event(); ftraceEvent2->set_timestamp(ts1); ftraceEvent2->set_tgid(tid1); ftraceEvent2->set_comm(appName); ftraceEvent2->set_allocated_irq_handler_exit_format(irqHandlerExitEvent); eventParser.ParseDataItem(&ftraceCpuDetail2, TS_CLOCK_BOOTTIME); EXPECT_TRUE(stream_.traceDataCache_->GetConstInternalSlicesData().Size() == 1); EXPECT_TRUE(stream_.traceDataCache_->GetConstStatAndInfo().GetValue(TRACE_EVENT_IRQ_HANDLER_EXIT, STAT_EVENT_NOTMATCH) == 1); cpu1 = 1; ts1 = 200; IrqHandlerExitFormat* irqHandlerExitEvent2 = new IrqHandlerExitFormat(); irqHandlerExitEvent2->set_irq(irq); irqHandlerExitEvent2->set_ret(ret); FtraceCpuDetailMsg ftraceCpuDetail3; ftraceCpuDetail3.set_cpu(cpu1); ftraceCpuDetail3.set_overwrite(0); auto ftraceEvent3 = ftraceCpuDetail3.add_event(); ftraceEvent3->set_timestamp(ts1); ftraceEvent3->set_tgid(tid1); ftraceEvent3->set_comm(appName); ftraceEvent3->set_allocated_irq_handler_exit_format(irqHandlerExitEvent2); eventParser.ParseDataItem(&ftraceCpuDetail3, TS_CLOCK_BOOTTIME); EXPECT_TRUE(stream_.traceDataCache_->GetConstInternalSlicesData().Size() == 1); EXPECT_TRUE(stream_.traceDataCache_->GetConstInternalSlicesData().ArgSetIdsData()[0] == 0); } /** * @tc.name: SoftIrqEntryTest * @tc.desc: Binary format Soft interrupt normal test * @tc.type: FUNC */ HWTEST_F(HtraceIrqEventTest, SoftIrqEntryTest, TestSize.Level1) { TS_LOGI("test10-6"); int64_t ts1 = 100; uint32_t cpu1 = 1; uint32_t vec = 1; std::string appName = "app1"; uint32_t tid1 = 1; HtraceEventParser eventParser(stream_.traceDataCache_.get(), stream_.streamFilters_.get()); SoftirqEntryFormat* softirqEntryEvent = new SoftirqEntryFormat(); softirqEntryEvent->set_vec(vec); FtraceCpuDetailMsg ftraceCpuDetail; ftraceCpuDetail.set_cpu(cpu1); ftraceCpuDetail.set_overwrite(0); auto ftraceEvent = ftraceCpuDetail.add_event(); ftraceEvent->set_timestamp(ts1); ftraceEvent->set_tgid(tid1); ftraceEvent->set_comm(appName); ftraceEvent->set_allocated_softirq_entry_format(softirqEntryEvent); eventParser.ParseDataItem(&ftraceCpuDetail, TS_CLOCK_BOOTTIME); EXPECT_TRUE(stream_.traceDataCache_->GetConstInternalSlicesData().Size() == 1); } /** * @tc.name: SoftIrqEntryNotMatch * @tc.desc: The binary format soft interrupts do not match. The two interrupts have only the beginning and no end * @tc.type: FUNC */ HWTEST_F(HtraceIrqEventTest, SoftIrqEntryNotMatch, TestSize.Level1) { TS_LOGI("test10-7"); int64_t ts1 = 100; uint32_t cpu1 = 1; uint32_t vec = 1; std::string appName = "app1"; uint32_t tid1 = 1; HtraceEventParser eventParser(stream_.traceDataCache_.get(), stream_.streamFilters_.get()); SoftirqEntryFormat* softirqEntryEvent = new SoftirqEntryFormat(); softirqEntryEvent->set_vec(vec); FtraceCpuDetailMsg ftraceCpuDetail; ftraceCpuDetail.set_cpu(cpu1); ftraceCpuDetail.set_overwrite(0); auto ftraceEvent = ftraceCpuDetail.add_event(); ftraceEvent->set_timestamp(ts1); ftraceEvent->set_tgid(tid1); ftraceEvent->set_comm(appName); ftraceEvent->set_allocated_softirq_entry_format(softirqEntryEvent); eventParser.ParseDataItem(&ftraceCpuDetail, TS_CLOCK_BOOTTIME); EXPECT_TRUE(stream_.traceDataCache_->GetConstInternalSlicesData().Size() == 1); ts1 = 150; SoftirqEntryFormat* softirqEntryEvent2 = new SoftirqEntryFormat(); softirqEntryEvent2->set_vec(vec); FtraceCpuDetailMsg ftraceCpuDetail2; ftraceCpuDetail2.set_cpu(cpu1); ftraceCpuDetail2.set_overwrite(0); auto ftraceEvent2 = ftraceCpuDetail2.add_event(); ftraceEvent2->set_timestamp(ts1); ftraceEvent2->set_tgid(tid1); ftraceEvent2->set_comm(appName); ftraceEvent2->set_allocated_softirq_entry_format(softirqEntryEvent2); eventParser.ParseDataItem(&ftraceCpuDetail2, TS_CLOCK_BOOTTIME); EXPECT_TRUE(stream_.traceDataCache_->GetConstInternalSlicesData().Size() == 2); EXPECT_TRUE( stream_.traceDataCache_->GetConstStatAndInfo().GetValue(TRACE_EVENT_SOFTIRQ_ENTRY, STAT_EVENT_DATA_LOST) == 1); } /** * @tc.name: SoftIrqExitEmptyTest * @tc.desc: The binary format soft interrupt only ends without starting * @tc.type: FUNC */ HWTEST_F(HtraceIrqEventTest, SoftIrqExitEmptyTest, TestSize.Level1) { TS_LOGI("test10-8"); int64_t ts1 = 100; uint32_t cpu1 = 1; uint32_t vec = 1; std::string appName = "app1"; uint32_t tid1 = 1; HtraceEventParser eventParser(stream_.traceDataCache_.get(), stream_.streamFilters_.get()); SoftirqExitFormat* softirqExitEvent = new SoftirqExitFormat(); softirqExitEvent->set_vec(vec); FtraceCpuDetailMsg ftraceCpuDetail; ftraceCpuDetail.set_cpu(cpu1); ftraceCpuDetail.set_overwrite(0); auto ftraceEvent = ftraceCpuDetail.add_event(); ftraceEvent->set_timestamp(ts1); ftraceEvent->set_tgid(tid1); ftraceEvent->set_comm(appName); ftraceEvent->set_allocated_softirq_exit_format(softirqExitEvent); eventParser.ParseDataItem(&ftraceCpuDetail, TS_CLOCK_BOOTTIME); EXPECT_TRUE(stream_.traceDataCache_->GetConstInternalSlicesData().Size() == 0); EXPECT_TRUE( stream_.traceDataCache_->GetConstStatAndInfo().GetValue(TRACE_EVENT_SOFTIRQ_EXIT, STAT_EVENT_DATA_LOST) == 1); } /** * @tc.name: SoftIrqTest * @tc.desc: The binary format soft interrupt normal test * @tc.type: FUNC */ HWTEST_F(HtraceIrqEventTest, SoftIrqTest, TestSize.Level1) { TS_LOGI("test10-9"); int64_t ts1 = 100; uint32_t cpu1 = 1; uint32_t vec = 1; std::string appName = "app1"; uint32_t tid1 = 1; HtraceEventParser eventParser(stream_.traceDataCache_.get(), stream_.streamFilters_.get()); SoftirqEntryFormat* softirqEntryEvent = new SoftirqEntryFormat(); softirqEntryEvent->set_vec(vec); FtraceCpuDetailMsg ftraceCpuDetail; ftraceCpuDetail.set_cpu(cpu1); ftraceCpuDetail.set_overwrite(0); auto ftraceEvent = ftraceCpuDetail.add_event(); ftraceEvent->set_timestamp(ts1); ftraceEvent->set_tgid(tid1); ftraceEvent->set_comm(appName); ftraceEvent->set_allocated_softirq_entry_format(softirqEntryEvent); eventParser.ParseDataItem(&ftraceCpuDetail, TS_CLOCK_BOOTTIME); EXPECT_TRUE(stream_.traceDataCache_->GetConstInternalSlicesData().Size() == 1); ts1 = 150; SoftirqExitFormat* softirqExitEvent = new SoftirqExitFormat(); softirqExitEvent->set_vec(vec); FtraceCpuDetailMsg ftraceCpuDetail2; ftraceCpuDetail2.set_cpu(cpu1); ftraceCpuDetail2.set_overwrite(0); auto ftraceEvent2 = ftraceCpuDetail2.add_event(); ftraceEvent2->set_timestamp(ts1); ftraceEvent2->set_tgid(tid1); ftraceEvent2->set_comm(appName); ftraceEvent2->set_allocated_softirq_exit_format(softirqExitEvent); eventParser.ParseDataItem(&ftraceCpuDetail2, TS_CLOCK_BOOTTIME); EXPECT_TRUE(stream_.traceDataCache_->GetConstInternalSlicesData().Size() == 1); } /** * @tc.name: SoftIrqTestNotMatch * @tc.desc: The binary soft interrupt test not match * @tc.type: FUNC */ HWTEST_F(HtraceIrqEventTest, SoftIrqTestNotMatch, TestSize.Level1) { TS_LOGI("test10-10"); int64_t ts1 = 100; uint32_t cpu1 = 1; uint32_t vec = 1; std::string appName = "app1"; uint32_t tid1 = 1; HtraceEventParser eventParser(stream_.traceDataCache_.get(), stream_.streamFilters_.get()); SoftirqEntryFormat* softirqEntryEvent = new SoftirqEntryFormat(); softirqEntryEvent->set_vec(vec); FtraceCpuDetailMsg ftraceCpuDetail; ftraceCpuDetail.set_cpu(cpu1); ftraceCpuDetail.set_overwrite(0); auto ftraceEvent = ftraceCpuDetail.add_event(); ftraceEvent->set_timestamp(ts1); ftraceEvent->set_tgid(tid1); ftraceEvent->set_comm(appName); ftraceEvent->set_allocated_softirq_entry_format(softirqEntryEvent); eventParser.ParseDataItem(&ftraceCpuDetail, TS_CLOCK_BOOTTIME); EXPECT_TRUE(stream_.traceDataCache_->GetConstInternalSlicesData().Size() == 1); ts1 = 150; cpu1 = 2; SoftirqExitFormat* softirqExitEvent = new SoftirqExitFormat(); softirqExitEvent->set_vec(vec); FtraceCpuDetailMsg ftraceCpuDetail2; ftraceCpuDetail2.set_cpu(cpu1); ftraceCpuDetail2.set_overwrite(0); auto ftraceEvent2 = ftraceCpuDetail2.add_event(); ftraceEvent2->set_timestamp(ts1); ftraceEvent2->set_tgid(tid1); ftraceEvent2->set_comm(appName); ftraceEvent2->set_allocated_softirq_exit_format(softirqExitEvent); eventParser.ParseDataItem(&ftraceCpuDetail2, TS_CLOCK_BOOTTIME); EXPECT_TRUE(stream_.traceDataCache_->GetConstInternalSlicesData().Size() == 1); EXPECT_TRUE(stream_.traceDataCache_->GetConstStatAndInfo().GetValue(TRACE_EVENT_SOFTIRQ_EXIT, STAT_EVENT_DATA_LOST) == 1); } } // namespace TraceStreamer } // namespace SysTuning