core/unittest/ebpf/ProcessCacheUnittest.cpp (120 lines of code) (raw):

// Copyright 2025 LoongCollector Authors // // 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 <memory> #include "ebpf/plugin/ProcessCache.h" #include "type/table/BaseElements.h" #include "unittest/Unittest.h" using namespace logtail; using namespace logtail::ebpf; class ProcessCacheValueUnittest : public ::testing::Test { protected: void TestCloneContents(); void TestCloneContentsExcessive(); void TestSetContent(); }; void ProcessCacheValueUnittest::TestCloneContents() { ProcessCacheValue v1; v1.mPPid = 1; v1.mPKtime = 2; v1.mRefCount = 3; v1.SetContent<ebpf::kArguments>(StringView("arg1 arg2 arg3")); std::unique_ptr<ProcessCacheValue> v2(v1.CloneContents()); APSARA_TEST_EQUAL_FATAL(0U, v2->mPPid); APSARA_TEST_EQUAL_FATAL(0UL, v2->mPKtime); APSARA_TEST_EQUAL_FATAL(0, v2->mRefCount); APSARA_TEST_EQUAL_FATAL(StringView("arg1 arg2 arg3"), v2->Get<ebpf::kArguments>()); } void ProcessCacheValueUnittest::TestCloneContentsExcessive() { ProcessCacheValue v1; v1.mPPid = 1; v1.mPKtime = 2; v1.mRefCount = 3; v1.SetContent<ebpf::kArguments>(StringView("arg1 arg2 arg3")); std::array<std::unique_ptr<ProcessCacheValue>, 10000> clones; for (size_t i = 0; i < clones.size(); ++i) { auto& v2 = clones[i]; if (i == 0) { v2.reset(v1.CloneContents()); } else { auto& parent = clones[i - 1]; v2.reset(parent->CloneContents()); } APSARA_TEST_EQUAL_FATAL(0U, v2->mPPid); APSARA_TEST_EQUAL_FATAL(0UL, v2->mPKtime); APSARA_TEST_EQUAL_FATAL(0, v2->mRefCount); APSARA_TEST_EQUAL_FATAL(StringView("arg1 arg2 arg3"), v2->Get<ebpf::kArguments>()); } APSARA_TEST_NOT_EQUAL_FATAL(v1.GetSourceBuffer().get(), clones.back()->GetSourceBuffer().get()); } void ProcessCacheValueUnittest::TestSetContent() { ProcessCacheValue v; v.SetContent<ebpf::kProcessId>(uint32_t(1000U)); v.SetContent<ebpf::kKtime>(uint64_t(1000000000UL)); APSARA_TEST_EQUAL_FATAL(StringView("1000"), v.Get<ebpf::kProcessId>()); APSARA_TEST_EQUAL_FATAL(StringView("1000000000"), v.Get<ebpf::kKtime>()); } UNIT_TEST_CASE(ProcessCacheValueUnittest, TestCloneContents); UNIT_TEST_CASE(ProcessCacheValueUnittest, TestCloneContentsExcessive); UNIT_TEST_CASE(ProcessCacheValueUnittest, TestSetContent); class ProcessCacheUnittest : public ::testing::Test { protected: void TestAddCache(); void TestRefCount(); void TestClearExpiredCache(); private: ProcessCache mProcessCache; }; void ProcessCacheUnittest::TestAddCache() { data_event_id key{12345, 1234567890}; std::shared_ptr<ProcessCacheValue> cacheValue = mProcessCache.Lookup(key); APSARA_TEST_TRUE(cacheValue == nullptr); cacheValue = std::make_shared<ProcessCacheValue>(); cacheValue->SetContent<kProcessId>(StringView("1234")); cacheValue->SetContent<kKtime>(StringView("5678")); cacheValue->SetContent<kUid>(StringView("1000")); cacheValue->SetContent<kBinary>(StringView("test_binary")); // 测试缓存更新 mProcessCache.AddCache(key, std::move(cacheValue)); APSARA_TEST_TRUE(mProcessCache.Contains(key)); // 测试缓存查找 cacheValue = mProcessCache.Lookup(key); APSARA_TEST_TRUE(cacheValue != nullptr); APSARA_TEST_EQUAL(cacheValue->Get<kProcessId>(), StringView("1234")); APSARA_TEST_EQUAL(cacheValue->Get<kKtime>(), StringView("5678")); APSARA_TEST_EQUAL(cacheValue->Get<kUid>(), StringView("1000")); APSARA_TEST_EQUAL(cacheValue->Get<kBinary>(), StringView("test_binary")); } void ProcessCacheUnittest::TestRefCount() { data_event_id key{12345, 1234567890}; auto cacheValue = std::make_shared<ProcessCacheValue>(); cacheValue->SetContent<kProcessId>(StringView("1234")); cacheValue->SetContent<kKtime>(StringView("5678")); cacheValue->SetContent<kUid>(StringView("1000")); cacheValue->SetContent<kBinary>(StringView("test_binary")); mProcessCache.AddCache(key, std::move(cacheValue)); cacheValue = mProcessCache.Lookup(key); APSARA_TEST_TRUE(cacheValue != nullptr); APSARA_TEST_EQUAL(1, cacheValue->mRefCount); mProcessCache.IncRef(key); APSARA_TEST_EQUAL(2, cacheValue->mRefCount); mProcessCache.DecRef(key, 1234567890); APSARA_TEST_EQUAL(1, cacheValue->mRefCount); mProcessCache.DecRef(key, 1234567890); APSARA_TEST_EQUAL(0, cacheValue->mRefCount); } void ProcessCacheUnittest::TestClearExpiredCache() { data_event_id key{12345, 1234567890}; auto cacheValue = std::make_shared<ProcessCacheValue>(); cacheValue->SetContent<kProcessId>(StringView("1234")); cacheValue->SetContent<kKtime>(StringView("5678")); cacheValue->SetContent<kUid>(StringView("1000")); cacheValue->SetContent<kBinary>(StringView("test_binary")); mProcessCache.AddCache(key, std::move(cacheValue)); mProcessCache.DecRef(key, 1234567890); cacheValue = mProcessCache.Lookup(key); APSARA_TEST_TRUE(cacheValue != nullptr); APSARA_TEST_EQUAL(0, cacheValue->mRefCount); mProcessCache.ClearExpiredCache(1234567890 + kMaxCacheExpiredTimeout + 1); cacheValue = mProcessCache.Lookup(key); APSARA_TEST_TRUE(cacheValue == nullptr); } UNIT_TEST_CASE(ProcessCacheUnittest, TestAddCache); UNIT_TEST_CASE(ProcessCacheUnittest, TestRefCount); UNIT_TEST_CASE(ProcessCacheUnittest, TestClearExpiredCache); UNIT_TEST_MAIN