diff options
author | Håvard Pettersen <havardpe@yahooinc.com> | 2022-08-18 15:50:17 +0000 |
---|---|---|
committer | Håvard Pettersen <havardpe@yahooinc.com> | 2022-08-22 11:22:50 +0000 |
commit | 41b0c5ce9069fe66d5276b5bc584fd6c3b6ef79f (patch) | |
tree | 9a3561a278d5a2cec643d3a0cfb73c8684f71b55 /vespalib/src/tests/execution_profiler | |
parent | b3342e4388abe12660d60e0f3e934c03f1a322b8 (diff) |
added simple profiler
Diffstat (limited to 'vespalib/src/tests/execution_profiler')
-rw-r--r-- | vespalib/src/tests/execution_profiler/CMakeLists.txt | 9 | ||||
-rw-r--r-- | vespalib/src/tests/execution_profiler/execution_profiler_test.cpp | 151 |
2 files changed, 160 insertions, 0 deletions
diff --git a/vespalib/src/tests/execution_profiler/CMakeLists.txt b/vespalib/src/tests/execution_profiler/CMakeLists.txt new file mode 100644 index 00000000000..e303762a110 --- /dev/null +++ b/vespalib/src/tests/execution_profiler/CMakeLists.txt @@ -0,0 +1,9 @@ +# Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +vespa_add_executable(vespalib_execution_profiler_test_app TEST + SOURCES + execution_profiler_test.cpp + DEPENDS + vespalib + GTest::GTest +) +vespa_add_test(NAME vespalib_execution_profiler_test_app COMMAND vespalib_execution_profiler_test_app) diff --git a/vespalib/src/tests/execution_profiler/execution_profiler_test.cpp b/vespalib/src/tests/execution_profiler/execution_profiler_test.cpp new file mode 100644 index 00000000000..565b8572201 --- /dev/null +++ b/vespalib/src/tests/execution_profiler/execution_profiler_test.cpp @@ -0,0 +1,151 @@ +// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. + +#include <vespa/vespalib/util/execution_profiler.h> +#include <vespa/vespalib/data/slime/slime.h> +#include <vespa/vespalib/gtest/gtest.h> +#include <thread> + +using Profiler = vespalib::ExecutionProfiler; +using vespalib::Slime; +using vespalib::slime::Cursor; +using vespalib::slime::Inspector; + +void fox(Profiler &profiler) { + profiler.start(profiler.resolve("fox")); + std::this_thread::sleep_for(1ms); + profiler.complete(); +} + +void baz(Profiler &profiler) { + profiler.start(profiler.resolve("baz")); + fox(profiler); + fox(profiler); + fox(profiler); + profiler.complete(); +} + +void bar(Profiler &profiler) { + profiler.start(profiler.resolve("bar")); + baz(profiler); + fox(profiler); + baz(profiler); + fox(profiler); + profiler.complete(); +} + +void foo(Profiler &profiler) { + profiler.start(profiler.resolve("foo")); + bar(profiler); + baz(profiler); + fox(profiler); + profiler.complete(); +} + +const Inspector *find_child(const Inspector &arr, const std::pair<vespalib::string,size_t> &entry) { + struct MyArrayTraverser : public vespalib::slime::ArrayTraverser { + const Inspector *node = nullptr; + const std::pair<vespalib::string,size_t> &needle; + MyArrayTraverser(const std::pair<vespalib::string,size_t> &needle_in) : needle(needle_in) {} + void entry(size_t, const Inspector &obj) override { + if ((obj["name"].asString().make_string() == needle.first) && + (obj["count"].asLong() == int64_t(needle.second))) + { + assert(node == nullptr); + node = &obj; + } + } + }; + MyArrayTraverser traverser(entry); + arr.traverse(traverser); + return traverser.node; +} + +bool verify_path(const Inspector &root, const std::vector<std::pair<vespalib::string,size_t>> &path) { + const Inspector *pos = &root; + bool first = true; + for (const auto &entry: path) { + if (first) { + pos = find_child((*pos)["roots"], entry); + } else { + pos = find_child((*pos)["children"], entry); + } + first = false; + if (pos == nullptr) { + fprintf(stderr, "could not find entry [%s, %zu]\n", entry.first.c_str(), entry.second); + return false; + } + } + if ((*pos)["roots"].valid() || (*pos)["children"].valid()) { + fprintf(stderr, "path too shallow\n"); + return false; + } + return true; +} + +TEST(ExecutionProfilerTest, resolve_names) { + Profiler profiler(64); + EXPECT_EQ(profiler.resolve("foo"), 0); + EXPECT_EQ(profiler.resolve("bar"), 1); + EXPECT_EQ(profiler.resolve("baz"), 2); + EXPECT_EQ(profiler.resolve("foo"), 0); + EXPECT_EQ(profiler.resolve("bar"), 1); + EXPECT_EQ(profiler.resolve("baz"), 2); +} + +TEST(ExecutionProfilerTest, empty_report) { + Profiler profiler(64); + profiler.resolve("foo"); + profiler.resolve("bar"); + profiler.resolve("baz"); + Slime slime; + profiler.report(slime.setObject()); + fprintf(stderr, "%s\n", slime.toString().c_str()); + EXPECT_EQ(slime["roots"].entries(), 0); + EXPECT_TRUE(verify_path(slime.get(), {})); +} + +TEST(ExecutionProfilerTest, perform_dummy_profiling) { + Profiler profiler(64); + for (int i = 0; i < 3; ++i) { + foo(profiler); + bar(profiler); + baz(profiler); + fox(profiler); + } + Slime slime; + profiler.report(slime.setObject()); + fprintf(stderr, "%s\n", slime.toString().c_str()); + EXPECT_EQ(slime["roots"].entries(), 4); + EXPECT_TRUE(verify_path(slime.get(), {{"foo", 3}, {"bar", 3}, {"baz", 6}, {"fox", 18}})); + EXPECT_TRUE(verify_path(slime.get(), {{"foo", 3}, {"bar", 3}, {"fox", 6}})); + EXPECT_TRUE(verify_path(slime.get(), {{"foo", 3}, {"baz", 3}, {"fox", 9}})); + EXPECT_TRUE(verify_path(slime.get(), {{"foo", 3}, {"fox", 3}})); + EXPECT_TRUE(verify_path(slime.get(), {{"bar", 3}, {"baz", 6}, {"fox", 18}})); + EXPECT_TRUE(verify_path(slime.get(), {{"bar", 3}, {"fox", 6}})); + EXPECT_TRUE(verify_path(slime.get(), {{"baz", 3}, {"fox", 9}})); + EXPECT_TRUE(verify_path(slime.get(), {{"fox", 3}})); +} + +TEST(ExecutionProfilerTest, perform_shallow_dummy_profiling) { + Profiler profiler(2); + for (int i = 0; i < 3; ++i) { + foo(profiler); + bar(profiler); + baz(profiler); + fox(profiler); + } + Slime slime; + profiler.report(slime.setObject()); + fprintf(stderr, "%s\n", slime.toString().c_str()); + EXPECT_EQ(slime["roots"].entries(), 4); + EXPECT_TRUE(verify_path(slime.get(), {{"foo", 3}, {"bar", 3}})); + EXPECT_TRUE(verify_path(slime.get(), {{"foo", 3}, {"bar", 3}})); + EXPECT_TRUE(verify_path(slime.get(), {{"foo", 3}, {"baz", 3}})); + EXPECT_TRUE(verify_path(slime.get(), {{"foo", 3}, {"fox", 3}})); + EXPECT_TRUE(verify_path(slime.get(), {{"bar", 3}, {"baz", 6}})); + EXPECT_TRUE(verify_path(slime.get(), {{"bar", 3}, {"fox", 6}})); + EXPECT_TRUE(verify_path(slime.get(), {{"baz", 3}, {"fox", 9}})); + EXPECT_TRUE(verify_path(slime.get(), {{"fox", 3}})); +} + +GTEST_MAIN_RUN_ALL_TESTS() |