-
Notifications
You must be signed in to change notification settings - Fork 790
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add flamegraph generation in CI build
Flamegraphs are attached to the build as artifacts. New tests can be added by creating a new gtest in slow_test. Tests like TEST (flamegraph, testname_x) will be executed if testname_x is added to the flamegraph.yaml file test matrix.
- Loading branch information
Showing
6 changed files
with
197 additions
and
9 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
name: Code Flamegraphs | ||
|
||
on: [push, pull_request, workflow_dispatch] | ||
|
||
jobs: | ||
linux_flamegraphs: | ||
name: Linux [${{ matrix.TEST_NAME }}] | ||
timeout-minutes: 120 | ||
strategy: | ||
fail-fast: false | ||
matrix: | ||
TEST_NAME: [large_confirmation, large_direct_processing] # slow_test --gtest_filter=flamegraph.[name] | ||
runs-on: ubuntu-22.04 | ||
env: | ||
TEST_NAME: ${{ matrix.TEST_NAME }} | ||
BACKEND: lmdb | ||
COMPILER: gcc | ||
TEST_USE_ROCKSDB: "0" | ||
DEADLINE_SCALE_FACTOR: "1" | ||
BUILD_TYPE: "RelWithDebInfo" | ||
OUTPUT_FILE: ${{ matrix.TEST_NAME }}.${{ github.sha }}.svg | ||
if: github.event_name == 'push' || github.event.pull_request.head.repo.full_name != github.repository | ||
steps: | ||
- name: Checkout | ||
uses: actions/checkout@v3 | ||
with: | ||
submodules: "recursive" | ||
|
||
- name: Prepare | ||
run: sudo -E ci/prepare/linux/prepare.sh | ||
|
||
- name: Install perf and FlameGraph | ||
run: | | ||
sudo apt-get update | ||
sudo apt-get install -y linux-tools-common linux-tools-generic linux-tools-$(uname -r) | ||
git clone https://github.com/brendangregg/FlameGraph.git | ||
export PATH=$PATH:$(pwd)/FlameGraph | ||
- name: Build Tests | ||
id: build | ||
run: ci/build-tests.sh | ||
|
||
- name: Run Flamegraph Tests | ||
if: steps.build.outcome == 'success' | ||
run: sudo perf record -F 397 -g --call-graph dwarf -o perf.data -- ../ci/tests/run-flamegraph-tests.sh ${{ matrix.TEST_NAME }} | ||
working-directory: build | ||
|
||
- name: CHOWN perf.data | ||
if: steps.build.outcome == 'success' | ||
run: sudo chown $(whoami) perf.data | ||
working-directory: build | ||
|
||
- name: Generate Flamegraph | ||
if: steps.build.outcome == 'success' | ||
run: | | ||
perf script -i perf.data > out.perf | ||
../FlameGraph/stackcollapse-perf.pl out.perf > out.folded | ||
../FlameGraph/flamegraph.pl out.folded > ${{ env.OUTPUT_FILE }} | ||
working-directory: build | ||
|
||
- name: Upload Flamegraph | ||
if: steps.build.outcome == 'success' | ||
uses: actions/upload-artifact@v3 | ||
with: | ||
name: flamegraph-${{ env.OUTPUT_FILE }} | ||
path: build/${{ env.OUTPUT_FILE }} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
#!/bin/bash | ||
set -euo pipefail | ||
|
||
# Ensure that an argument is provided | ||
if [ "$#" -ne 1 ]; then | ||
echo "Usage: $0 <argument>" | ||
exit 1 | ||
fi | ||
|
||
# Capture the argument | ||
ARGUMENT="$1" | ||
|
||
# Run the command with the argument | ||
$(dirname "$BASH_SOURCE")/run-tests.sh slow_test --gtest_filter=flamegraph.${ARGUMENT} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
#include <nano/lib/blockbuilders.hpp> | ||
#include <nano/secure/ledger.hpp> | ||
#include <nano/test_common/system.hpp> | ||
#include <nano/test_common/testutil.hpp> | ||
|
||
#include <gtest/gtest.h> | ||
|
||
#include <chrono> | ||
|
||
using namespace std::chrono_literals; | ||
|
||
namespace | ||
{ | ||
std::deque<nano::keypair> rep_set (size_t count) | ||
{ | ||
std::deque<nano::keypair> result; | ||
for (auto i = 0; i < count; ++i) | ||
{ | ||
result.emplace_back (nano::keypair{}); | ||
} | ||
return result; | ||
} | ||
} | ||
|
||
TEST (flamegraph, large_direct_processing) | ||
{ | ||
auto reps = rep_set (4); | ||
auto circulating = 10 * nano::Gxrb_ratio; | ||
nano::test::system system; | ||
system.ledger_initialization_set (reps, circulating); | ||
auto & node = *system.add_node (); | ||
auto prepare = [&] () { | ||
nano::state_block_builder builder; | ||
std::deque<std::shared_ptr<nano::block>> blocks; | ||
std::deque<nano::keypair> keys; | ||
auto previous = *std::prev (std::prev (system.initialization_blocks.end ())); | ||
for (auto i = 0; i < 20000; ++i) | ||
{ | ||
keys.emplace_back (); | ||
auto const & key = keys.back (); | ||
auto block = builder.make_block () | ||
.account (nano::dev::genesis_key.pub) | ||
.representative (nano::dev::genesis_key.pub) | ||
.previous (previous->hash ()) | ||
.link (key.pub) | ||
.balance (previous->balance_field ().value ().number () - nano::xrb_ratio) | ||
.sign (nano::dev::genesis_key.prv, nano::dev::genesis_key.pub) | ||
.work (*system.work.generate (previous->hash ())) | ||
.build (); | ||
blocks.push_back (block); | ||
previous = block; | ||
} | ||
return std::make_tuple (blocks, keys); | ||
}; | ||
auto const & [blocks, keys] = prepare (); | ||
auto execute = [&] () { | ||
auto count = 0; | ||
for (auto block : blocks) | ||
{ | ||
ASSERT_EQ (nano::block_status::progress, node.process (block)); | ||
} | ||
}; | ||
execute (); | ||
} | ||
|
||
TEST (flamegraph, large_confirmation) | ||
{ | ||
auto reps = rep_set (4); | ||
auto circulating = 10 * nano::Gxrb_ratio; | ||
nano::test::system system; | ||
system.ledger_initialization_set (reps, circulating); | ||
auto prepare = [&] () { | ||
nano::state_block_builder builder; | ||
std::deque<std::shared_ptr<nano::block>> blocks; | ||
std::deque<nano::keypair> keys; | ||
auto previous = *std::prev (std::prev (system.initialization_blocks.end ())); | ||
for (auto i = 0; i < 100; ++i) | ||
{ | ||
keys.emplace_back (); | ||
auto const & key = keys.back (); | ||
auto block = builder.make_block () | ||
.account (nano::dev::genesis_key.pub) | ||
.representative (nano::dev::genesis_key.pub) | ||
.previous (previous->hash ()) | ||
.link (key.pub) | ||
.balance (previous->balance_field ().value ().number () - nano::xrb_ratio) | ||
.sign (nano::dev::genesis_key.prv, nano::dev::genesis_key.pub) | ||
.work (*system.work.generate (previous->hash ())) | ||
.build (); | ||
blocks.push_back (block); | ||
previous = block; | ||
} | ||
return std::make_tuple (blocks, keys); | ||
}; | ||
auto const & [blocks, keys] = prepare (); | ||
system.initialization_blocks.insert (system.initialization_blocks.end (), blocks.begin (), blocks.end ()); | ||
nano::node_config config; | ||
nano::node_flags flags; | ||
auto & node1 = *system.add_node (config, flags, nano::transport::transport_type::tcp, reps[0]); | ||
auto & node2 = *system.add_node (config, flags, nano::transport::transport_type::tcp, reps[1]); | ||
auto & node3 = *system.add_node (config, flags, nano::transport::transport_type::tcp, reps[2]); | ||
auto & node4 = *system.add_node (config, flags, nano::transport::transport_type::tcp, reps[3]); | ||
ASSERT_TIMELY (300s, std::all_of (system.nodes.begin (), system.nodes.end (), [&] (auto const & node) { | ||
return node->block_confirmed (system.initialization_blocks.back ()->hash ()); | ||
})); | ||
} |