diff --git a/profiler/src/ProfilerEngine/Datadog.Profiler.Native/CorProfilerCallback.cpp b/profiler/src/ProfilerEngine/Datadog.Profiler.Native/CorProfilerCallback.cpp index f10d555f0c5b..f084dcfd0191 100644 --- a/profiler/src/ProfilerEngine/Datadog.Profiler.Native/CorProfilerCallback.cpp +++ b/profiler/src/ProfilerEngine/Datadog.Profiler.Native/CorProfilerCallback.cpp @@ -35,7 +35,7 @@ #include "GCThreadsCpuProvider.h" #include "IMetricsSender.h" #include "IMetricsSenderFactory.h" -#include "LibddprofExporter.h" +#include "ProfileExporter.h" #include "Log.h" #include "ManagedThreadList.h" #include "OpSysTools.h" @@ -323,7 +323,7 @@ bool CorProfilerCallback::InitializeServices() // The different elements of the libddprof pipeline are created and linked together // i.e. the exporter is passed to the aggregator and each provider is added to the aggregator. - _pExporter = std::make_unique( + _pExporter = std::make_unique( sampleTypeDefinitions, _pConfiguration.get(), _pApplicationStore, diff --git a/profiler/src/ProfilerEngine/Datadog.Profiler.Native/Datadog.Profiler.Native.vcxproj b/profiler/src/ProfilerEngine/Datadog.Profiler.Native/Datadog.Profiler.Native.vcxproj index d290538027ee..80458093ad94 100644 --- a/profiler/src/ProfilerEngine/Datadog.Profiler.Native/Datadog.Profiler.Native.vcxproj +++ b/profiler/src/ProfilerEngine/Datadog.Profiler.Native/Datadog.Profiler.Native.vcxproj @@ -320,7 +320,7 @@ - + @@ -397,7 +397,7 @@ - + diff --git a/profiler/src/ProfilerEngine/Datadog.Profiler.Native/LibddprofExporter.cpp b/profiler/src/ProfilerEngine/Datadog.Profiler.Native/ProfileExporter.cpp similarity index 85% rename from profiler/src/ProfilerEngine/Datadog.Profiler.Native/LibddprofExporter.cpp rename to profiler/src/ProfilerEngine/Datadog.Profiler.Native/ProfileExporter.cpp index d633d0867cde..ee5cceccf95d 100644 --- a/profiler/src/ProfilerEngine/Datadog.Profiler.Native/LibddprofExporter.cpp +++ b/profiler/src/ProfilerEngine/Datadog.Profiler.Native/ProfileExporter.cpp @@ -1,7 +1,7 @@ // Unless explicitly stated otherwise all files in this repository are licensed under the Apache 2 License. // This product includes software developed at Datadog (https://www.datadoghq.com/). Copyright 2022 Datadog, Inc. -#include "LibddprofExporter.h" +#include "ProfileExporter.h" #include "Exception.h" #include "Exporter.h" @@ -34,7 +34,7 @@ #define BUFFER_MAX_SIZE 512 -tags LibddprofExporter::CommonTags = { +tags ProfileExporter::CommonTags = { {"language", "dotnet"}, {"profiler_version", PROFILER_VERSION}, #ifdef BIT64 @@ -45,28 +45,28 @@ tags LibddprofExporter::CommonTags = { }; // need to be static so it leave longer for the shared library -std::string const LibddprofExporter::ProcessId = std::to_string(OpSysTools::GetProcId()); +std::string const ProfileExporter::ProcessId = std::to_string(OpSysTools::GetProcId()); -int32_t const LibddprofExporter::RequestTimeOutMs = 10000; +int32_t const ProfileExporter::RequestTimeOutMs = 10000; -std::string const LibddprofExporter::LibraryName = "dd-profiling-dotnet"; +std::string const ProfileExporter::LibraryName = "dd-profiling-dotnet"; -std::string const LibddprofExporter::LibraryVersion = PROFILER_VERSION; +std::string const ProfileExporter::LibraryVersion = PROFILER_VERSION; -std::string const LibddprofExporter::LanguageFamily = "dotnet"; +std::string const ProfileExporter::LanguageFamily = "dotnet"; -std::string const LibddprofExporter::RequestFileName = "auto.pprof"; +std::string const ProfileExporter::RequestFileName = "auto.pprof"; -std::string const LibddprofExporter::ProfilePeriodType = "RealTime"; +std::string const ProfileExporter::ProfilePeriodType = "RealTime"; -std::string const LibddprofExporter::ProfilePeriodUnit = "Nanoseconds"; +std::string const ProfileExporter::ProfilePeriodUnit = "Nanoseconds"; -std::string const LibddprofExporter::MetricsFilename = "metrics.json"; +std::string const ProfileExporter::MetricsFilename = "metrics.json"; -std::string const LibddprofExporter::ProfileExtension = ".pprof"; -std::string const LibddprofExporter::AllocationsExtension = ".balloc"; +std::string const ProfileExporter::ProfileExtension = ".pprof"; +std::string const ProfileExporter::AllocationsExtension = ".balloc"; -LibddprofExporter::LibddprofExporter( +ProfileExporter::ProfileExporter( std::vector sampleTypeDefinitions, IConfiguration* configuration, IApplicationStore* applicationStore, @@ -86,7 +86,7 @@ LibddprofExporter::LibddprofExporter( _metricsFileFolder = configuration->GetProfilesOutputDirectory(); } -LibddprofExporter::~LibddprofExporter() +ProfileExporter::~ProfileExporter() { std::lock_guard lck(_perAppInfoLock); @@ -106,7 +106,7 @@ LibddprofExporter::~LibddprofExporter() _perAppInfo.clear(); } -std::unique_ptr LibddprofExporter::CreateExporter(IConfiguration* configuration, libdatadog::Tags tags) +std::unique_ptr ProfileExporter::CreateExporter(IConfiguration* configuration, libdatadog::Tags tags) { try { @@ -142,24 +142,24 @@ std::unique_ptr LibddprofExporter::CreateExporter(IConfigu } } -std::unique_ptr LibddprofExporter::CreateProfile(std::string serviceName) +std::unique_ptr ProfileExporter::CreateProfile(std::string serviceName) { return std::make_unique(_sampleTypeDefinitions, ProfilePeriodType, ProfilePeriodUnit, std::move(serviceName)); } -void LibddprofExporter::RegisterUpscaleProvider(IUpscaleProvider* provider) +void ProfileExporter::RegisterUpscaleProvider(IUpscaleProvider* provider) { assert(provider != nullptr); _upscaledProviders.push_back(provider); } -void LibddprofExporter::RegisterProcessSamplesProvider(ISamplesProvider* provider) +void ProfileExporter::RegisterProcessSamplesProvider(ISamplesProvider* provider) { assert(provider != nullptr); _processSamplesProviders.push_back(provider); } -libdatadog::Tags LibddprofExporter::CreateTags( +libdatadog::Tags ProfileExporter::CreateTags( IConfiguration* configuration, IRuntimeInfo* runtimeInfo, IEnabledProfilers* enabledProfilers) @@ -190,7 +190,7 @@ libdatadog::Tags LibddprofExporter::CreateTags( return tags; } -std::string LibddprofExporter::GetEnabledProfilersTag(IEnabledProfilers* enabledProfilers) +std::string ProfileExporter::GetEnabledProfilersTag(IEnabledProfilers* enabledProfilers) { const char* separator = "_"; // ',' are not allowed and +/SPACE would be transformed into '_' anyway std::stringstream buffer; @@ -262,7 +262,7 @@ std::string LibddprofExporter::GetEnabledProfilersTag(IEnabledProfilers* enabled return buffer.str(); } -std::string LibddprofExporter::BuildAgentEndpoint(IConfiguration* configuration) +std::string ProfileExporter::BuildAgentEndpoint(IConfiguration* configuration) { // handle "with agent" case auto url = configuration->GetAgentUrl(); // copy expected here @@ -301,7 +301,7 @@ std::string LibddprofExporter::BuildAgentEndpoint(IConfiguration* configuration) return url; } -LibddprofExporter::ProfileInfoScope LibddprofExporter::GetOrCreateInfo(std::string_view runtimeId) +ProfileExporter::ProfileInfoScope ProfileExporter::GetOrCreateInfo(std::string_view runtimeId) { std::lock_guard lock(_perAppInfoLock); @@ -310,7 +310,7 @@ LibddprofExporter::ProfileInfoScope LibddprofExporter::GetOrCreateInfo(std::stri return profileInfo; } -void LibddprofExporter::Add(libdatadog::Profile* profile, std::shared_ptr const& sample) +void ProfileExporter::Add(libdatadog::Profile* profile, std::shared_ptr const& sample) { auto success = profile->Add(sample); if (!success) @@ -325,7 +325,7 @@ void LibddprofExporter::Add(libdatadog::Profile* profile, std::shared_ptr const& sample) +void ProfileExporter::Add(std::shared_ptr const& sample) { auto profileInfoScope = GetOrCreateInfo(sample->GetRuntimeId()); @@ -339,7 +339,7 @@ void LibddprofExporter::Add(std::shared_ptr const& sample) profileInfoScope.profileInfo.samplesCount++; } -std::optional LibddprofExporter::GetInfo(const std::string& runtimeId) +std::optional ProfileExporter::GetInfo(const std::string& runtimeId) { std::lock_guard lock(_perAppInfoLock); @@ -355,7 +355,7 @@ std::optional LibddprofExporter::GetInfo(co return it->second; } -void LibddprofExporter::SetEndpoint(const std::string& runtimeId, uint64_t traceId, const std::string& endpoint) +void ProfileExporter::SetEndpoint(const std::string& runtimeId, uint64_t traceId, const std::string& endpoint) { auto scope = GetInfo(runtimeId); @@ -380,7 +380,7 @@ void LibddprofExporter::SetEndpoint(const std::string& runtimeId, uint64_t trace profile->AddEndpointCount(endpoint, 1); } -std::vector LibddprofExporter::GetUpscalingInfos() +std::vector ProfileExporter::GetUpscalingInfos() { std::vector samplingInfos; samplingInfos.reserve(_upscaledProviders.size()); @@ -393,7 +393,7 @@ std::vector LibddprofExporter::GetUpscalingInfos() return samplingInfos; } -void LibddprofExporter::AddUpscalingRules(libdatadog::Profile* profile, std::vector const& upscalingInfos) +void ProfileExporter::AddUpscalingRules(libdatadog::Profile* profile, std::vector const& upscalingInfos) { for (auto const& upscalingInfo : upscalingInfos) { @@ -420,7 +420,7 @@ void LibddprofExporter::AddUpscalingRules(libdatadog::Profile* profile, std::vec } } -std::list> LibddprofExporter::GetProcessSamples() +std::list> ProfileExporter::GetProcessSamples() { std::list> samples; for (auto const& provider : _processSamplesProviders) @@ -430,7 +430,7 @@ std::list> LibddprofExporter::GetProcessSamples() return samples; } -void LibddprofExporter::AddProcessSamples(libdatadog::Profile* profile, std::list> const& samples) +void ProfileExporter::AddProcessSamples(libdatadog::Profile* profile, std::list> const& samples) { for (auto const& sample : samples) { @@ -438,7 +438,7 @@ void LibddprofExporter::AddProcessSamples(libdatadog::Profile* profile, std::lis } } -bool LibddprofExporter::Export() +bool ProfileExporter::Export() { bool exported = false; @@ -560,7 +560,7 @@ bool LibddprofExporter::Export() return exported; } -void LibddprofExporter::SaveJsonToDisk(const std::string prefix, const std::string& content) const +void ProfileExporter::SaveJsonToDisk(const std::string prefix, const std::string& content) const { std::stringstream filename; filename << prefix << "-" << std::to_string(OpSysTools::GetProcId()) << ".json"; @@ -571,7 +571,7 @@ void LibddprofExporter::SaveJsonToDisk(const std::string prefix, const std::stri file.close(); } -std::string LibddprofExporter::GenerateFilePath(const std::string& applicationName, int32_t idx, const std::string& extension) const +std::string ProfileExporter::GenerateFilePath(const std::string& applicationName, int32_t idx, const std::string& extension) const { auto time = std::time(nullptr); struct tm buf = {}; @@ -592,7 +592,7 @@ std::string LibddprofExporter::GenerateFilePath(const std::string& applicationNa return pprofFilePath.string(); } -std::string LibddprofExporter::CreateMetricsFileContent() const +std::string ProfileExporter::CreateMetricsFileContent() const { // prepare metrics to be sent if any std::stringstream builder; @@ -621,7 +621,7 @@ std::string LibddprofExporter::CreateMetricsFileContent() const return builder.str(); } -std::string LibddprofExporter::GetMetadata() const +std::string ProfileExporter::GetMetadata() const { // in tests, the metadata provider might be null if (_metadataProvider == nullptr) @@ -682,7 +682,7 @@ std::string LibddprofExporter::GetMetadata() const return builder.str(); } -fs::path LibddprofExporter::CreatePprofOutputPath(IConfiguration* configuration) +fs::path ProfileExporter::CreatePprofOutputPath(IConfiguration* configuration) { auto const& pprofOutputPath = configuration->GetProfilesOutputDirectory(); if (pprofOutputPath.empty()) @@ -703,16 +703,16 @@ fs::path LibddprofExporter::CreatePprofOutputPath(IConfiguration* configuration) return {}; } -LibddprofExporter::ProfileInfo::ProfileInfo() +ProfileExporter::ProfileInfo::ProfileInfo() { profile = nullptr; samplesCount = 0; exportsCount = 0; } -LibddprofExporter::ProfileInfo::~ProfileInfo() = default; +ProfileExporter::ProfileInfo::~ProfileInfo() = default; -LibddprofExporter::ProfileInfoScope::ProfileInfoScope(LibddprofExporter::ProfileInfo& profileInfo) : +ProfileExporter::ProfileInfoScope::ProfileInfoScope(ProfileExporter::ProfileInfo& profileInfo) : profileInfo(profileInfo), _lockGuard(profileInfo.lock) { diff --git a/profiler/src/ProfilerEngine/Datadog.Profiler.Native/LibddprofExporter.h b/profiler/src/ProfilerEngine/Datadog.Profiler.Native/ProfileExporter.h similarity index 97% rename from profiler/src/ProfilerEngine/Datadog.Profiler.Native/LibddprofExporter.h rename to profiler/src/ProfilerEngine/Datadog.Profiler.Native/ProfileExporter.h index 3cc4ac5803ab..d658ad5969f9 100644 --- a/profiler/src/ProfilerEngine/Datadog.Profiler.Native/LibddprofExporter.h +++ b/profiler/src/ProfilerEngine/Datadog.Profiler.Native/ProfileExporter.h @@ -33,10 +33,10 @@ class Profile; class Tags; } // namespace libatadog -class LibddprofExporter : public IExporter +class ProfileExporter : public IExporter { public: - LibddprofExporter( + ProfileExporter( std::vector sampleTypeDefinitions, IConfiguration* configuration, IApplicationStore* applicationStore, @@ -45,7 +45,7 @@ class LibddprofExporter : public IExporter MetricsRegistry& metricsRegistry, IMetadataProvider* metadataProvider, IAllocationsRecorder* allocationsRecorder); - ~LibddprofExporter() override; + ~ProfileExporter() override; bool Export() override; void Add(std::shared_ptr const& sample) override; diff --git a/profiler/test/Datadog.Profiler.Native.Tests/Datadog.Profiler.Native.Tests.vcxproj b/profiler/test/Datadog.Profiler.Native.Tests/Datadog.Profiler.Native.Tests.vcxproj index 07925f270296..98b4a9952205 100644 --- a/profiler/test/Datadog.Profiler.Native.Tests/Datadog.Profiler.Native.Tests.vcxproj +++ b/profiler/test/Datadog.Profiler.Native.Tests/Datadog.Profiler.Native.Tests.vcxproj @@ -55,7 +55,7 @@ - + diff --git a/profiler/test/Datadog.Profiler.Native.Tests/Datadog.Profiler.Native.Tests.vcxproj.filters b/profiler/test/Datadog.Profiler.Native.Tests/Datadog.Profiler.Native.Tests.vcxproj.filters index d4bb826e319f..5ef93eea124e 100644 --- a/profiler/test/Datadog.Profiler.Native.Tests/Datadog.Profiler.Native.Tests.vcxproj.filters +++ b/profiler/test/Datadog.Profiler.Native.Tests/Datadog.Profiler.Native.Tests.vcxproj.filters @@ -39,7 +39,7 @@ Helpers - + Tests diff --git a/profiler/test/Datadog.Profiler.Native.Tests/LibddprofExporterTest.cpp b/profiler/test/Datadog.Profiler.Native.Tests/LibddprofExporterTest.cpp deleted file mode 100644 index 4068d4d91e0a..000000000000 --- a/profiler/test/Datadog.Profiler.Native.Tests/LibddprofExporterTest.cpp +++ /dev/null @@ -1,791 +0,0 @@ -// Unless explicitly stated otherwise all files in this repository are licensed under the Apache 2 License. -// This product includes software developed at Datadog (https://www.datadoghq.com/). Copyright 2022 Datadog, Inc. - -#include "gmock/gmock.h" -#include "gtest/gtest.h" - -#include "EnabledProfilers.h" -#include "LibddprofExporter.h" -#include "OpSysTools.h" - -#include "MetricsRegistry.h" -#include "ProfilerMockedInterface.h" -#include "RuntimeInfoHelper.h" -#include "IMetadataProvider.h" - -#include "shared/src/native-src/dd_filesystem.hpp" - -using ::testing::_; -using ::testing::Return; -using ::testing::ReturnRef; -using ::testing::Throw; - -std::string ComputeExpectedFilePrefix(const std::string& applicationName) -{ - std::ostringstream expectedFilePrefix; - expectedFilePrefix << applicationName << "_" << OpSysTools::GetProcId() << "_"; - return expectedFilePrefix.str(); -} - -TEST(LibddprofExporterTest, CheckProfileIsWrittenToDisk) -{ - auto [configuration, mockConfiguration] = CreateConfiguration(); - -#ifdef LINUX - fs::path pprofTempDir = fs::temp_directory_path() / tmpnam(nullptr); -#else - char tempFilename[L_tmpnam]; - tmpnam_s(tempFilename, sizeof(tempFilename)); - fs::path pprofTempDir = fs::temp_directory_path() / tempFilename; -#endif - EXPECT_CALL(mockConfiguration, GetProfilesOutputDirectory()).WillRepeatedly(ReturnRef(pprofTempDir)); - - std::string agentUrl; - EXPECT_CALL(mockConfiguration, GetAgentUrl()).Times(1).WillOnce(ReturnRef(agentUrl)); - -#if _WINDOWS - std::string namedPipeName; - EXPECT_CALL(mockConfiguration, GetNamedPipeName()).Times(1).WillOnce(ReturnRef(namedPipeName)); -#endif - - std::string agentHost = "localhost"; - EXPECT_CALL(mockConfiguration, GetAgentHost()).Times(1).WillOnce(ReturnRef(agentHost)); - int agentPort = 8126; - EXPECT_CALL(mockConfiguration, GetAgentPort()).Times(1).WillOnce(Return(agentPort)); - std::string host = "localhost"; - EXPECT_CALL(mockConfiguration, GetHostname()).Times(1).WillOnce(ReturnRef(host)); - EXPECT_CALL(mockConfiguration, IsAgentless()).Times(1).WillOnce(Return(false)); - - std::vector> tags; - EXPECT_CALL(mockConfiguration, GetUserTags()).Times(1).WillOnce(ReturnRef(tags)); - - auto applicationStore = MockApplicationStore(); - - std::string firstRid = "MyRid"; - ApplicationInfo firstApplicationInfo{"MyApp", "myenv", "1.0.2"}; - - std::string secondRid = "MyRid2"; - ApplicationInfo secondApplicationInfo{"OtherApplication", "myenv", "1.0.2"}; - - // Multiple applications - EXPECT_CALL(applicationStore, GetApplicationInfo(firstRid)).WillRepeatedly(Return(firstApplicationInfo)); - EXPECT_CALL(applicationStore, GetApplicationInfo(secondRid)).WillRepeatedly(Return(secondApplicationInfo)); - - RuntimeInfoHelper helper(6, 0, false); - IRuntimeInfo* runtimeInfo = helper.GetRuntimeInfo(); - EnabledProfilers enabledProfilers(configuration.get(), false, false); - std::vector sampleTypeDefinitions({{"exception", "count"}}); - MetricsRegistry metricsRegistry; - IAllocationsRecorder* allocRecorder = nullptr; - IMetadataProvider* metadataProvider = nullptr; - auto exporter = LibddprofExporter(std::move(sampleTypeDefinitions), &mockConfiguration, &applicationStore, runtimeInfo, - &enabledProfilers, metricsRegistry, metadataProvider, allocRecorder); - - - // Add samples to only one application - auto callstack1 = std::vector>({{"module", "frame1"}, {"module", "frame2"}, {"module", "frame3"}}); - auto labels1 = std::vector>{{"label1", "value1"}, {"label2", "value2"}}; - - auto sample1 = CreateSample(firstRid, - callstack1, - labels1, - 21); - - auto callstack2 = std::vector>({{"module", "frame1"}, {"module", "frame2"}, {"module", "frame3"}, {"module", "frame4"}}); - auto labels2 = std::vector>{{"label1", "value1"}, {"label2", "value2"}, {"label3", "value3"}}; - auto sample2 = CreateSample(firstRid, - callstack2, - labels2, - 42); - - auto callstack3 = std::vector>({{"module", "frame1"}, {"module", "frame2"}}); - auto labels3 = std::vector>{{"label1", "value1"}}; - auto sample3 = CreateSample(firstRid, - callstack3, - labels3, - 84); - exporter.Add(sample1); - exporter.Add(sample2); - exporter.Add(sample3); - - exporter.Export(); - - std::string expectedPrefix = ComputeExpectedFilePrefix(firstApplicationInfo.ServiceName); - - std::vector pprofFiles; - for (auto const& file : fs::directory_iterator(pprofTempDir)) - { - pprofFiles.push_back(file); - } - - ASSERT_EQ(pprofFiles.size(), 1); - - auto& file = pprofFiles[0]; - - ASSERT_TRUE(file.is_regular_file()); - - std::string filename = file.path().filename().string(); - - ASSERT_THAT(filename, ::testing::StartsWith(expectedPrefix)); - - fs::remove_all(pprofTempDir); -} - - -// ---------------------------------------------------------------------------------------------- -// This test is done in 2 steps: -// - Initialize the exporter internal data structure by add samples for 2 different applications, -// exporting them to disk, delete the pprof files. -// - Adding a sample to only one application and doing the checks -TEST(LibddprofExporterTest, EnsureOnlyProfileWithSamplesIsWrittenToDisk) -{ - // ---------------------------------------------------------------------------------------------- - // First step: - // - // Fill the exporter with 2 samples (one per application) - // Export them to disk - // Then delete them - // - auto [configuration, mockConfiguration] = CreateConfiguration(); - -#ifdef LINUX - fs::path pprofTempDir = fs::temp_directory_path() / tmpnam(nullptr); -#else - char tempFilename[L_tmpnam]; - tmpnam_s(tempFilename, sizeof(tempFilename)); - fs::path pprofTempDir = fs::temp_directory_path() / tempFilename; -#endif - EXPECT_CALL(mockConfiguration, GetProfilesOutputDirectory()).WillRepeatedly(ReturnRef(pprofTempDir)); - - std::string agentUrl; - EXPECT_CALL(mockConfiguration, GetAgentUrl()).Times(1).WillOnce(ReturnRef(agentUrl)); - -#if _WINDOWS - std::string namedPipeName; - EXPECT_CALL(mockConfiguration, GetNamedPipeName()).Times(1).WillOnce(ReturnRef(namedPipeName)); -#endif - - std::string agentHost = "localhost"; - EXPECT_CALL(mockConfiguration, GetAgentHost()).Times(1).WillOnce(ReturnRef(agentHost)); - int agentPort = 8126; - EXPECT_CALL(mockConfiguration, GetAgentPort()).Times(1).WillOnce(Return(agentPort)); - std::string host = "localhost"; - EXPECT_CALL(mockConfiguration, GetHostname()).Times(1).WillOnce(ReturnRef(host)); - EXPECT_CALL(mockConfiguration, IsAgentless()).Times(1).WillOnce(Return(false)); - - std::vector> tags; - EXPECT_CALL(mockConfiguration, GetUserTags()).Times(1).WillOnce(ReturnRef(tags)); - - auto applicationStore = MockApplicationStore(); - - std::string firstRid = "MyRid"; - ApplicationInfo firstApplicationInfo{"MyApp", "myenv", "1.0.2"}; - - std::string secondRid = "MyRid2"; - ApplicationInfo secondApplicationInfo{"OtherApplication", "myenv", "1.0.2"}; - - EXPECT_CALL(applicationStore, GetApplicationInfo(firstRid)).WillRepeatedly(Return(firstApplicationInfo)); - EXPECT_CALL(applicationStore, GetApplicationInfo(secondRid)).WillRepeatedly(Return(secondApplicationInfo)); - - RuntimeInfoHelper helper(6, 0, false); - IRuntimeInfo* runtimeInfo = helper.GetRuntimeInfo(); - EnabledProfilers enabledProfilers(configuration.get(), false, false); - std::vector sampleTypeDefinitions({{"exception", "count"}}); - - MetricsRegistry metricsRegistry; - IAllocationsRecorder* allocRecorder = nullptr; - IMetadataProvider* metadataProvider = nullptr; - auto exporter = LibddprofExporter(std::move(sampleTypeDefinitions), &mockConfiguration, &applicationStore, runtimeInfo, &enabledProfilers, - metricsRegistry, metadataProvider, allocRecorder); - - auto callstack1 = std::vector>({{"module", "frame1"}, {"module", "frame2"}, {"module", "frame3"}}); - auto labels1 = std::vector>{{"label1", "value1"}, {"label2", "value2"}}; - auto sample1 = CreateSample(firstRid, - callstack1, - labels1, - 21); - - auto callstack2 = std::vector>({{"module", "frame1"}, {"module", "frame2"}, {"module", "frame3"}, {"module", "frame4"}}); - auto labels2 = std::vector>{{"label1", "value1"}, {"label2", "value2"}, {"label3", "value3"}}; - auto sample2 = CreateSample(secondRid, - callstack2, - labels2, - 42); - - exporter.Add(sample1); - exporter.Add(sample2); - - exporter.Export(); - - for (auto const& file : fs::directory_iterator(pprofTempDir)) - { - fs::remove(file.path()); - } - - // ---------------------------------------------------------------------------------------------- - // Second step: - // This is where the real test begins - - exporter.Add(sample1); - - exporter.Export(); - - std::string expectedPrefix = ComputeExpectedFilePrefix(firstApplicationInfo.ServiceName); - - std::vector pprofFiles; - for (auto const& file : fs::directory_iterator(pprofTempDir)) - { - pprofFiles.push_back(file); - } - - ASSERT_EQ(pprofFiles.size(), 1); - - auto file = pprofFiles[0]; - - ASSERT_TRUE(file.is_regular_file()); - - std::string filename = file.path().filename().string(); - - ASSERT_THAT(filename, ::testing::StartsWith(expectedPrefix)); - - fs::remove_all(pprofTempDir); -} - - -TEST(LibddprofExporterTest, EnsureTwoPprofFilesAreWrittenToDiskForTwoApplications) -{ - auto [configuration, mockConfiguration] = CreateConfiguration(); - -#ifdef LINUX - fs::path pprofTempDir = fs::temp_directory_path() / tmpnam(nullptr); -#else - char tempFilename[L_tmpnam]; - tmpnam_s(tempFilename, sizeof(tempFilename)); - fs::path pprofTempDir = fs::temp_directory_path() / tempFilename; -#endif - EXPECT_CALL(mockConfiguration, GetProfilesOutputDirectory()).WillRepeatedly(ReturnRef(pprofTempDir)); - - std::string agentUrl; - EXPECT_CALL(mockConfiguration, GetAgentUrl()).Times(1).WillOnce(ReturnRef(agentUrl)); - -#if _WINDOWS - std::string namedPipeName; - EXPECT_CALL(mockConfiguration, GetNamedPipeName()).Times(1).WillOnce(ReturnRef(namedPipeName)); -#endif - - std::string agentHost = "localhost"; - EXPECT_CALL(mockConfiguration, GetAgentHost()).Times(1).WillOnce(ReturnRef(agentHost)); - int agentPort = 8126; - EXPECT_CALL(mockConfiguration, GetAgentPort()).Times(1).WillOnce(Return(agentPort)); - std::string host = "localhost"; - EXPECT_CALL(mockConfiguration, GetHostname()).Times(1).WillOnce(ReturnRef(host)); - EXPECT_CALL(mockConfiguration, IsAgentless()).Times(1).WillOnce(Return(false)); - - std::vector> tags; - EXPECT_CALL(mockConfiguration, GetUserTags()).Times(1).WillOnce(ReturnRef(tags)); - - auto applicationStore = MockApplicationStore(); - - std::string firstRid = "MyRid"; - ApplicationInfo firstApplicationInfo{"MyApp", "myenv", "1.0.2"}; - - std::string secondRid = "MyRid2"; - ApplicationInfo secondApplicationInfo{"OtherApplication", "myenv", "1.0.2"}; - - EXPECT_CALL(applicationStore, GetApplicationInfo(firstRid)).WillRepeatedly(Return(firstApplicationInfo)); - EXPECT_CALL(applicationStore, GetApplicationInfo(secondRid)).WillRepeatedly(Return(secondApplicationInfo)); - - RuntimeInfoHelper helper(6, 0, false); - IRuntimeInfo* runtimeInfo = helper.GetRuntimeInfo(); - EnabledProfilers enabledProfilers(configuration.get(), false, false); - std::vector sampleTypeDefinitions({{"exception", "count"}}); - - MetricsRegistry metricsRegistry; - IAllocationsRecorder* allocRecorder = nullptr; - IMetadataProvider* metadataProvider = nullptr; - auto exporter = LibddprofExporter(std::move(sampleTypeDefinitions), &mockConfiguration, &applicationStore, runtimeInfo, &enabledProfilers, - metricsRegistry, metadataProvider, allocRecorder); - - auto callstack1 = std::vector>({{"module", "frame1"}, {"module", "frame2"}, {"module", "frame3"}}); - auto labels1 = std::vector>{{"label1", "value1"}, {"label2", "value2"}}; - auto sample1 = CreateSample(firstRid, - callstack1, - labels1, - 21); - - auto callstack2 = std::vector>({{"module", "frame1"}, {"module", "frame2"}, {"module", "frame3"}}); - auto labels2 = std::vector>{{"label1", "value1"}, {"label2", "value2"}}; - auto sample2 = CreateSample(secondRid, - callstack2, - labels2, - 42); - - exporter.Add(sample1); - exporter.Add(sample2); - - exporter.Export(); - - std::string expectFirstFilePrefix = ComputeExpectedFilePrefix(firstApplicationInfo.ServiceName); - std::string expectedSecondFilePrefix = ComputeExpectedFilePrefix(secondApplicationInfo.ServiceName); - - std::vector pprofFiles; - for (auto const& file : fs::directory_iterator(pprofTempDir)) - { - pprofFiles.push_back(file); - } - - ASSERT_EQ(pprofFiles.size(), 2); - - auto firstFile = pprofFiles[0]; - auto secondFile = pprofFiles[1]; - - ASSERT_TRUE(firstFile.is_regular_file()); - ASSERT_TRUE(secondFile.is_regular_file()); - - std::string firstFilename = firstFile.path().filename().string(); - std::string secondFilename = secondFile.path().filename().string(); - - // check if firstFilename starts with expectFirstFilePrefix - if (firstFilename.rfind(expectFirstFilePrefix) != 0) - { - // no, we make sure that firstFilename starts with expectedSecondFilePrefix - // and secondFilename starts with expectFirstFilePrefix - ASSERT_THAT(firstFilename, ::testing::StartsWith(expectedSecondFilePrefix)); - ASSERT_THAT(secondFilename, ::testing::StartsWith(expectFirstFilePrefix)); - } - else - { - // firstFilename starts with expectFirstFilePrefix - ASSERT_THAT(secondFilename, ::testing::StartsWith(expectedSecondFilePrefix)); - } - - fs::remove_all(pprofTempDir); -} - -TEST(LibddprofExporterTest, MustCreateAgentBasedExporterIfAgentUrlIsSet) -{ - auto [configuration, mockConfiguration] = CreateMockForUniquePtr(); - - std::string agentUrl = "http://host::port"; - EXPECT_CALL(mockConfiguration, GetAgentUrl()).Times(1).WillOnce(ReturnRef(agentUrl)); - EXPECT_CALL(mockConfiguration, GetAgentHost()).Times(0); - EXPECT_CALL(mockConfiguration, GetAgentPort()).Times(0); - - std::string host = "localhost"; - EXPECT_CALL(mockConfiguration, GetHostname()).Times(1).WillOnce(ReturnRef(host)); - - // only used in agentless case - EXPECT_CALL(mockConfiguration, IsAgentless()).Times(1).WillOnce(Return(false)); - EXPECT_CALL(mockConfiguration, GetSite()).Times(0); - EXPECT_CALL(mockConfiguration, GetApiKey()).Times(0); - - fs::path pprofDir; - EXPECT_CALL(mockConfiguration, GetProfilesOutputDirectory()).WillRepeatedly(ReturnRef(pprofDir)); - - std::vector> tags; - EXPECT_CALL(mockConfiguration, GetUserTags()).Times(1).WillOnce(ReturnRef(tags)); - - auto applicationStore = MockApplicationStore(); - - RuntimeInfoHelper helper(6, 0, false); - IRuntimeInfo* runtimeInfo = helper.GetRuntimeInfo(); - EnabledProfilers enabledProfilers(configuration.get(), false, false); - std::vector sampleTypeDefinitions({{"exception", "count"}}); - - MetricsRegistry metricsRegistry; - IAllocationsRecorder* allocRecorder = nullptr; - IMetadataProvider* metadataProvider = nullptr; - auto exporter = LibddprofExporter(std::move(sampleTypeDefinitions), &mockConfiguration, &applicationStore, runtimeInfo, &enabledProfilers, - metricsRegistry, metadataProvider, allocRecorder); -} - -TEST(LibddprofExporterTest, MustCreateAgentBasedExporterIfAgentUrlIsNotSet) -{ - auto [configuration, mockConfiguration] = CreateMockForUniquePtr(); - - std::string agentUrl = ""; - EXPECT_CALL(mockConfiguration, GetAgentUrl()).Times(1).WillOnce(ReturnRef(agentUrl)); - -#if _WINDOWS - std::string namedPipeName; - EXPECT_CALL(mockConfiguration, GetNamedPipeName()).Times(1).WillOnce(ReturnRef(namedPipeName)); -#endif - - std::string agentHost = "localhost"; - EXPECT_CALL(mockConfiguration, GetAgentHost()).Times(1).WillOnce(ReturnRef(agentHost)); - int agentPort = 8126; - EXPECT_CALL(mockConfiguration, GetAgentPort()).Times(1).WillOnce(Return(agentPort)); - - std::string host = "localhost"; - EXPECT_CALL(mockConfiguration, GetHostname()).Times(1).WillOnce(ReturnRef(host)); - - // only used in agentless case - EXPECT_CALL(mockConfiguration, IsAgentless()).Times(1).WillOnce(Return(false)); - EXPECT_CALL(mockConfiguration, GetSite()).Times(0); - EXPECT_CALL(mockConfiguration, GetApiKey()).Times(0); - - fs::path pprofDir; - EXPECT_CALL(mockConfiguration, GetProfilesOutputDirectory()).WillRepeatedly(ReturnRef(pprofDir)); - - std::vector> tags; - EXPECT_CALL(mockConfiguration, GetUserTags()).Times(1).WillOnce(ReturnRef(tags)); - - auto applicationStore = MockApplicationStore(); - - RuntimeInfoHelper helper(6, 0, false); - IRuntimeInfo* runtimeInfo = helper.GetRuntimeInfo(); - EnabledProfilers enabledProfilers(configuration.get(), false, false); - std::vector sampleTypeDefinitions({{"exception", "count"}}); - - MetricsRegistry metricsRegistry; - IAllocationsRecorder* allocRecorder = nullptr; - IMetadataProvider* metadataProvider = nullptr; - auto exporter = LibddprofExporter(std::move(sampleTypeDefinitions), &mockConfiguration, &applicationStore, runtimeInfo, &enabledProfilers, - metricsRegistry, metadataProvider, allocRecorder); -} - -TEST(LibddprofExporterTest, MustCreateAgentLessExporterIfAgentless) -{ - auto [configuration, mockConfiguration] = CreateConfiguration(); - - EXPECT_CALL(mockConfiguration, IsAgentless()).Times(1).WillOnce(Return(true)); - std::string site = "test_site"; - EXPECT_CALL(mockConfiguration, GetSite()).Times(1).WillOnce(ReturnRef(site)); - std::string apiKey = "4224"; - EXPECT_CALL(mockConfiguration, GetApiKey()).Times(1).WillOnce(ReturnRef(apiKey)); - - // not called when agentless - EXPECT_CALL(mockConfiguration, GetAgentUrl()).Times(0); - EXPECT_CALL(mockConfiguration, GetAgentHost()).Times(0); - EXPECT_CALL(mockConfiguration, GetAgentPort()).Times(0); - - std::string host = "localhost"; - EXPECT_CALL(mockConfiguration, GetHostname()).Times(1).WillOnce(ReturnRef(host)); - - fs::path pprofDir; - EXPECT_CALL(mockConfiguration, GetProfilesOutputDirectory()).WillRepeatedly(ReturnRef(pprofDir)); - - std::vector> tags; - EXPECT_CALL(mockConfiguration, GetUserTags()).Times(1).WillOnce(ReturnRef(tags)); - - auto applicationStore = MockApplicationStore(); - - RuntimeInfoHelper helper(6, 0, false); - IRuntimeInfo* runtimeInfo = helper.GetRuntimeInfo(); - EnabledProfilers enabledProfilers(configuration.get(), false, false); - std::vector sampleTypeDefinitions({{"exception", "count"}}); - - MetricsRegistry metricsRegistry; - IAllocationsRecorder* allocRecorder = nullptr; - IMetadataProvider* metadataProvider = nullptr; - auto exporter = LibddprofExporter(std::move(sampleTypeDefinitions), &mockConfiguration, &applicationStore, runtimeInfo, &enabledProfilers, - metricsRegistry, metadataProvider, allocRecorder); -} - -TEST(LibddprofExporterTest, MustCollectSamplesFromProcessProvider) -{ - auto [configuration, mockConfiguration] = CreateConfiguration(); - - EXPECT_CALL(mockConfiguration, IsAgentless()).Times(1).WillOnce(Return(true)); - std::string site = "test_site"; - EXPECT_CALL(mockConfiguration, GetSite()).Times(1).WillOnce(ReturnRef(site)); - std::string apiKey = "4224"; - EXPECT_CALL(mockConfiguration, GetApiKey()).Times(1).WillOnce(ReturnRef(apiKey)); - - // not called when agentless - EXPECT_CALL(mockConfiguration, GetAgentUrl()).Times(0); - EXPECT_CALL(mockConfiguration, GetAgentHost()).Times(0); - EXPECT_CALL(mockConfiguration, GetAgentPort()).Times(0); - - std::string host = "localhost"; - EXPECT_CALL(mockConfiguration, GetHostname()).Times(1).WillOnce(ReturnRef(host)); - - fs::path pprofDir; - EXPECT_CALL(mockConfiguration, GetProfilesOutputDirectory()).WillRepeatedly(ReturnRef(pprofDir)); - - std::vector> tags; - EXPECT_CALL(mockConfiguration, GetUserTags()).Times(1).WillOnce(ReturnRef(tags)); - - auto applicationStore = MockApplicationStore(); - - RuntimeInfoHelper helper(6, 0, false); - IRuntimeInfo* runtimeInfo = helper.GetRuntimeInfo(); - EnabledProfilers enabledProfilers(configuration.get(), false, false); - std::vector sampleTypeDefinitions({{"exception", "count"}}); - - MetricsRegistry metricsRegistry; - IAllocationsRecorder* allocRecorder = nullptr; - MockProcessSamplesProvider processSamplesProvider; - IMetadataProvider* metadataProvider = nullptr; - EXPECT_CALL(processSamplesProvider, GetSamples()).Times(1).WillOnce(Return(std::list>())); - auto exporter = LibddprofExporter(std::move(sampleTypeDefinitions), &mockConfiguration, &applicationStore, runtimeInfo, &enabledProfilers, - metricsRegistry, metadataProvider, allocRecorder); - - exporter.RegisterProcessSamplesProvider(static_cast(&processSamplesProvider)); - - exporter.Export(); -} - -TEST(LibddprofExporterTest, MakeSureNoCrashForReallyLongCallstack) -{ - auto [configuration, mockConfiguration] = CreateConfiguration(); - - fs::path pprofTempDir; - EXPECT_CALL(mockConfiguration, GetProfilesOutputDirectory()).WillRepeatedly(ReturnRef(pprofTempDir)); - - std::string agentUrl; - EXPECT_CALL(mockConfiguration, GetAgentUrl()).Times(1).WillOnce(ReturnRef(agentUrl)); - -#if _WINDOWS - std::string namedPipeName; - EXPECT_CALL(mockConfiguration, GetNamedPipeName()).Times(1).WillOnce(ReturnRef(namedPipeName)); -#endif - - std::string agentHost = "localhost"; - EXPECT_CALL(mockConfiguration, GetAgentHost()).Times(1).WillOnce(ReturnRef(agentHost)); - int agentPort = 8126; - EXPECT_CALL(mockConfiguration, GetAgentPort()).Times(1).WillOnce(Return(agentPort)); - std::string host = "localhost"; - EXPECT_CALL(mockConfiguration, GetHostname()).Times(1).WillOnce(ReturnRef(host)); - EXPECT_CALL(mockConfiguration, IsAgentless()).Times(1).WillOnce(Return(false)); - - std::vector> tags; - EXPECT_CALL(mockConfiguration, GetUserTags()).Times(1).WillOnce(ReturnRef(tags)); - - auto applicationStore = MockApplicationStore(); - RuntimeInfoHelper helper(6, 0, false); - IRuntimeInfo* runtimeInfo = helper.GetRuntimeInfo(); - EnabledProfilers enabledProfilers(configuration.get(), false, false); - std::vector sampleTypeDefinitions({{"exception", "count"}}); - - MetricsRegistry metricsRegistry; - IAllocationsRecorder* allocRecorder = nullptr; - IMetadataProvider* metadataProvider = nullptr; - auto exporter = LibddprofExporter(std::move(sampleTypeDefinitions), &mockConfiguration, &applicationStore, runtimeInfo, &enabledProfilers, - metricsRegistry, metadataProvider, allocRecorder); - - std::string runtimeId = "MyRid"; - auto callstack = CreateCallstack(2048); - auto labels = std::vector>{{"label1", "value1"}, {"label2", "value2"}}; - auto sample1 = CreateSample(runtimeId, callstack, labels, 42); - - EXPECT_NO_THROW(exporter.Add(sample1)); -} - -TEST(LibddprofExporterTest, CheckNoEnabledProfilers) -{ - auto [configuration, mockConfiguration] = CreateConfiguration(); - EXPECT_CALL(mockConfiguration, IsWallTimeProfilingEnabled()).Times(1).WillOnce(Return(false)); - EXPECT_CALL(mockConfiguration, IsCpuProfilingEnabled()).Times(1).WillOnce(Return(false)); - EXPECT_CALL(mockConfiguration, IsExceptionProfilingEnabled()).Times(1).WillOnce(Return(false)); - EXPECT_CALL(mockConfiguration, IsAllocationProfilingEnabled()).Times(0).WillOnce(Return(false)); - EXPECT_CALL(mockConfiguration, IsContentionProfilingEnabled()).Times(0).WillOnce(Return(false)); - EXPECT_CALL(mockConfiguration, IsGarbageCollectionProfilingEnabled()).Times(0).WillOnce(Return(false)); - EXPECT_CALL(mockConfiguration, IsHeapProfilingEnabled()).Times(0).WillOnce(Return(false)); - EnabledProfilers enabledProfilers(configuration.get(), false, false); - - std::string tag = LibddprofExporter::GetEnabledProfilersTag(&enabledProfilers); - - ASSERT_TRUE(tag.empty()); -} - -TEST(LibddprofExporterTest, CheckAllEnabledProfilers) -{ - auto [configuration, mockConfiguration] = CreateConfiguration(); - EXPECT_CALL(mockConfiguration, IsWallTimeProfilingEnabled()).Times(1).WillOnce(Return(true)); - EXPECT_CALL(mockConfiguration, IsCpuProfilingEnabled()).Times(1).WillOnce(Return(true)); - EXPECT_CALL(mockConfiguration, IsExceptionProfilingEnabled()).Times(1).WillOnce(Return(true)); - EXPECT_CALL(mockConfiguration, IsAllocationProfilingEnabled()).Times(1).WillOnce(Return(true)); - EXPECT_CALL(mockConfiguration, IsContentionProfilingEnabled()).Times(1).WillOnce(Return(true)); - EXPECT_CALL(mockConfiguration, IsGarbageCollectionProfilingEnabled()).Times(1).WillOnce(Return(true)); - EnabledProfilers enabledProfilers(configuration.get(), true, true); - - std::string tag = LibddprofExporter::GetEnabledProfilersTag(&enabledProfilers); - - ASSERT_TRUE(tag.find("walltime") != std::string::npos); - ASSERT_TRUE(tag.find("cpu") != std::string::npos); - ASSERT_TRUE(tag.find("exceptions") != std::string::npos); - ASSERT_TRUE(tag.find("allocations") != std::string::npos); - ASSERT_TRUE(tag.find("lock") != std::string::npos); - ASSERT_TRUE(tag.find("gc") != std::string::npos); - ASSERT_TRUE(tag.find("heap") != std::string::npos); -} - -TEST(LibddprofExporterTest, CheckCpuIsEnabled) -{ - auto [configuration, mockConfiguration] = CreateConfiguration(); - EXPECT_CALL(mockConfiguration, IsWallTimeProfilingEnabled()).Times(1).WillOnce(Return(false)); - EXPECT_CALL(mockConfiguration, IsCpuProfilingEnabled()).Times(1).WillOnce(Return(true)); - EXPECT_CALL(mockConfiguration, IsExceptionProfilingEnabled()).Times(1).WillOnce(Return(false)); - EXPECT_CALL(mockConfiguration, IsAllocationProfilingEnabled()).Times(0).WillOnce(Return(false)); - EnabledProfilers enabledProfilers(configuration.get(), false, false); - - std::string tag = LibddprofExporter::GetEnabledProfilersTag(&enabledProfilers); - - ASSERT_TRUE(tag == "cpu"); -} - -TEST(LibddprofExporterTest, CheckWalltimeIsEnabled) -{ - auto [configuration, mockConfiguration] = CreateConfiguration(); - EXPECT_CALL(mockConfiguration, IsWallTimeProfilingEnabled()).Times(1).WillOnce(Return(true)); - EXPECT_CALL(mockConfiguration, IsCpuProfilingEnabled()).Times(1).WillOnce(Return(false)); - EXPECT_CALL(mockConfiguration, IsExceptionProfilingEnabled()).Times(1).WillOnce(Return(false)); - EXPECT_CALL(mockConfiguration, IsAllocationProfilingEnabled()).Times(0).WillOnce(Return(false)); - EnabledProfilers enabledProfilers(configuration.get(), false, false); - - std::string tag = LibddprofExporter::GetEnabledProfilersTag(&enabledProfilers); - - ASSERT_TRUE(tag == "walltime"); -} - -TEST(LibddprofExporterTest, CheckExceptionIsEnabled) -{ - auto [configuration, mockConfiguration] = CreateConfiguration(); - EXPECT_CALL(mockConfiguration, IsWallTimeProfilingEnabled()).Times(1).WillOnce(Return(false)); - EXPECT_CALL(mockConfiguration, IsCpuProfilingEnabled()).Times(1).WillOnce(Return(false)); - EXPECT_CALL(mockConfiguration, IsExceptionProfilingEnabled()).Times(1).WillOnce(Return(true)); - EXPECT_CALL(mockConfiguration, IsAllocationProfilingEnabled()).Times(0).WillOnce(Return(false)); - EnabledProfilers enabledProfilers(configuration.get(), false, false); - - std::string tag = LibddprofExporter::GetEnabledProfilersTag(&enabledProfilers); - - ASSERT_TRUE(tag == "exceptions"); -} - -TEST(LibddprofExporterTest, CheckAllocationIsEnabledWhenEvents) -{ - auto [configuration, mockConfiguration] = CreateConfiguration(); - EXPECT_CALL(mockConfiguration, IsWallTimeProfilingEnabled()).Times(1).WillOnce(Return(false)); - EXPECT_CALL(mockConfiguration, IsCpuProfilingEnabled()).Times(1).WillOnce(Return(false)); - EXPECT_CALL(mockConfiguration, IsExceptionProfilingEnabled()).Times(1).WillOnce(Return(false)); - EXPECT_CALL(mockConfiguration, IsAllocationProfilingEnabled()).Times(1).WillOnce(Return(true)); - EnabledProfilers enabledProfilers(configuration.get(), true, false); - - std::string tag = LibddprofExporter::GetEnabledProfilersTag(&enabledProfilers); - - ASSERT_TRUE(tag == "allocations"); -} - -TEST(LibddprofExporterTest, CheckAllocationIsDisabledWhenNoEvents) -{ - auto [configuration, mockConfiguration] = CreateConfiguration(); - EXPECT_CALL(mockConfiguration, IsWallTimeProfilingEnabled()).Times(1).WillOnce(Return(false)); - EXPECT_CALL(mockConfiguration, IsCpuProfilingEnabled()).Times(1).WillOnce(Return(false)); - EXPECT_CALL(mockConfiguration, IsExceptionProfilingEnabled()).Times(1).WillOnce(Return(false)); - EXPECT_CALL(mockConfiguration, IsAllocationProfilingEnabled()).Times(0).WillOnce(Return(true)); - EnabledProfilers enabledProfilers(configuration.get(), false, false); - - std::string tag = LibddprofExporter::GetEnabledProfilersTag(&enabledProfilers); - - ASSERT_TRUE(tag.empty()); -} - -TEST(LibddprofExporterTest, CheckLockContentionIsEnabledWhenEvents) -{ - auto [configuration, mockConfiguration] = CreateConfiguration(); - EXPECT_CALL(mockConfiguration, IsWallTimeProfilingEnabled()).Times(1).WillOnce(Return(false)); - EXPECT_CALL(mockConfiguration, IsCpuProfilingEnabled()).Times(1).WillOnce(Return(false)); - EXPECT_CALL(mockConfiguration, IsExceptionProfilingEnabled()).Times(1).WillOnce(Return(false)); - EXPECT_CALL(mockConfiguration, IsContentionProfilingEnabled()).Times(1).WillOnce(Return(true)); - EnabledProfilers enabledProfilers(configuration.get(), true, false); - - std::string tag = LibddprofExporter::GetEnabledProfilersTag(&enabledProfilers); - - ASSERT_TRUE(tag == "lock"); -} - -TEST(LibddprofExporterTest, CheckLockContentionIsDisabledWhenNoEvents) -{ - auto [configuration, mockConfiguration] = CreateConfiguration(); - EXPECT_CALL(mockConfiguration, IsWallTimeProfilingEnabled()).Times(1).WillOnce(Return(false)); - EXPECT_CALL(mockConfiguration, IsCpuProfilingEnabled()).Times(1).WillOnce(Return(false)); - EXPECT_CALL(mockConfiguration, IsExceptionProfilingEnabled()).Times(1).WillOnce(Return(false)); - EXPECT_CALL(mockConfiguration, IsContentionProfilingEnabled()).Times(0).WillOnce(Return(true)); - EnabledProfilers enabledProfilers(configuration.get(), false, false); - - std::string tag = LibddprofExporter::GetEnabledProfilersTag(&enabledProfilers); - - ASSERT_TRUE(tag.empty()); -} - -TEST(LibddprofExporterTest, CheckGarbageCollectionIsEnabledWhenEvents) -{ - auto [configuration, mockConfiguration] = CreateConfiguration(); - EXPECT_CALL(mockConfiguration, IsWallTimeProfilingEnabled()).Times(1).WillOnce(Return(false)); - EXPECT_CALL(mockConfiguration, IsCpuProfilingEnabled()).Times(1).WillOnce(Return(false)); - EXPECT_CALL(mockConfiguration, IsExceptionProfilingEnabled()).Times(1).WillOnce(Return(false)); - EXPECT_CALL(mockConfiguration, IsGarbageCollectionProfilingEnabled()).Times(1).WillOnce(Return(true)); - EnabledProfilers enabledProfilers(configuration.get(), true, false); - - std::string tag = LibddprofExporter::GetEnabledProfilersTag(&enabledProfilers); - - ASSERT_TRUE(tag == "gc"); -} - -TEST(LibddprofExporterTest, CheckGarbageCollectionIsDisabledWhenNoEvents) -{ - auto [configuration, mockConfiguration] = CreateConfiguration(); - EXPECT_CALL(mockConfiguration, IsWallTimeProfilingEnabled()).Times(1).WillOnce(Return(false)); - EXPECT_CALL(mockConfiguration, IsCpuProfilingEnabled()).Times(1).WillOnce(Return(false)); - EXPECT_CALL(mockConfiguration, IsExceptionProfilingEnabled()).Times(1).WillOnce(Return(false)); - EXPECT_CALL(mockConfiguration, IsGarbageCollectionProfilingEnabled()).Times(0).WillOnce(Return(true)); - EnabledProfilers enabledProfilers(configuration.get(), false, false); - - std::string tag = LibddprofExporter::GetEnabledProfilersTag(&enabledProfilers); - - ASSERT_TRUE(tag.empty()); -} - -TEST(LibddprofExporterTest, CheckHeapIsEnabledWhenEvents) -{ - auto [configuration, mockConfiguration] = CreateConfiguration(); - EXPECT_CALL(mockConfiguration, IsWallTimeProfilingEnabled()).Times(1).WillOnce(Return(false)); - EXPECT_CALL(mockConfiguration, IsCpuProfilingEnabled()).Times(1).WillOnce(Return(false)); - EXPECT_CALL(mockConfiguration, IsExceptionProfilingEnabled()).Times(1).WillOnce(Return(false)); - EnabledProfilers enabledProfilers(configuration.get(), true, true); - - std::string tag = LibddprofExporter::GetEnabledProfilersTag(&enabledProfilers); - - ASSERT_TRUE(tag.find("heap") != std::string::npos); -} - -TEST(LibddprofExporterTest, CheckHeapIsDisabledWhenNoEvents) -{ - auto [configuration, mockConfiguration] = CreateConfiguration(); - EXPECT_CALL(mockConfiguration, IsWallTimeProfilingEnabled()).Times(1).WillOnce(Return(false)); - EXPECT_CALL(mockConfiguration, IsCpuProfilingEnabled()).Times(1).WillOnce(Return(false)); - EXPECT_CALL(mockConfiguration, IsExceptionProfilingEnabled()).Times(1).WillOnce(Return(false)); - EnabledProfilers enabledProfilers(configuration.get(), false, true); // this should never happen but test it anyway - - std::string tag = LibddprofExporter::GetEnabledProfilersTag(&enabledProfilers); - - ASSERT_TRUE(tag.empty()); -} - -TEST(LibddprofExporterTest, CheckHeapIsDisabledWhenHeapIsNotEnabled) -{ - auto [configuration, mockConfiguration] = CreateConfiguration(); - EXPECT_CALL(mockConfiguration, IsWallTimeProfilingEnabled()).Times(1).WillOnce(Return(false)); - EXPECT_CALL(mockConfiguration, IsCpuProfilingEnabled()).Times(1).WillOnce(Return(false)); - EXPECT_CALL(mockConfiguration, IsAllocationProfilingEnabled()).Times(1).WillOnce(Return(false)); - EnabledProfilers enabledProfilers(configuration.get(), true, false); - - std::string tag = LibddprofExporter::GetEnabledProfilersTag(&enabledProfilers); - - ASSERT_TRUE(tag.find("heap") == std::string::npos); -} - -TEST(LibddprofExporterTest, CheckAllocationIsEnabledWhenHeapIsEnabled) -{ - auto [configuration, mockConfiguration] = CreateConfiguration(); - EXPECT_CALL(mockConfiguration, IsWallTimeProfilingEnabled()).Times(1).WillOnce(Return(false)); - EXPECT_CALL(mockConfiguration, IsCpuProfilingEnabled()).Times(1).WillOnce(Return(false)); - EXPECT_CALL(mockConfiguration, IsAllocationProfilingEnabled()).Times(1).WillOnce(Return(false)); - EnabledProfilers enabledProfilers(configuration.get(), true, true); - - std::string tag = LibddprofExporter::GetEnabledProfilersTag(&enabledProfilers); - - ASSERT_TRUE(tag.find("allocations") != std::string::npos); - ASSERT_TRUE(tag.find("heap") != std::string::npos); -}