diff options
author | Milian Wolff <milian.wolff@kdab.com> | 2022-06-04 22:44:52 +0200 |
---|---|---|
committer | Milian Wolff <milian.wolff@kdab.com> | 2022-06-10 08:46:24 +0000 |
commit | bf8d70fd31f2d8ad7e208847303f6317788d1e32 (patch) | |
tree | fdc37b5639c6e69b2b2624098130959e155f8aa4 | |
parent | 990b8c2dceea8a63bdb67798d7594189f07fb0f5 (diff) |
Add parallel_static_gcc and basic test coverage
This is a somewhat more elaborate example which uses multiple
threads, lambdas and std::async which has the tendency to stress
our dwarf debug symbol resolution code. More on that in a follow-up
patch. For now, this test only uncovered an issue in
PerfParserTestClient::convertToText, where we iterated over a QHash
to generate text output, which is not going to produce stable results.
Instead, we now convert to a stable QMap first and output that.
Furthermore, the test harness is updated to also allow us to test
never version than 0.5 that we got in the past, i.e. 0.6 is now
expected for the new data files I'm adding here.
Change-Id: I2de65503b2c853528b301166a5b58a406d34a059
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
-rw-r--r-- | .gitignore | 2 | ||||
-rw-r--r-- | tests/auto/perfdata/parallel_static_gcc/parallel_static_gcc.zlib | bin | 0 -> 1048168 bytes | |||
-rw-r--r-- | tests/auto/perfdata/parallel_static_gcc/perf.data.zstd.expected.txt.zlib | bin | 0 -> 14836 bytes | |||
-rw-r--r-- | tests/auto/perfdata/parallel_static_gcc/perf.data.zstd.zlib | bin | 0 -> 27100 bytes | |||
-rw-r--r-- | tests/auto/perfdata/tst_perfdata.cpp | 20 | ||||
-rw-r--r-- | tests/auto/shared/perfparsertestclient.cpp | 5 | ||||
-rw-r--r-- | tests/manual/clients/parallel.cpp | 37 |
7 files changed, 57 insertions, 7 deletions
@@ -7,3 +7,5 @@ tests/auto/perfdata/vector_static_gcc/perf.data tests/auto/perfdata/vector_static_gcc/perf.data.zstd tests/auto/perfdata/vector_static_gcc/perf.lbr.data tests/auto/perfdata/vector_static_gcc/vector_static_gcc_v9.1.0 +tests/auto/perfdata/parallel_static_gcc/parallel_static_gcc +tests/auto/perfdata/parallel_static_gcc/perf.data.zstd diff --git a/tests/auto/perfdata/parallel_static_gcc/parallel_static_gcc.zlib b/tests/auto/perfdata/parallel_static_gcc/parallel_static_gcc.zlib Binary files differnew file mode 100644 index 0000000..18d41b4 --- /dev/null +++ b/tests/auto/perfdata/parallel_static_gcc/parallel_static_gcc.zlib diff --git a/tests/auto/perfdata/parallel_static_gcc/perf.data.zstd.expected.txt.zlib b/tests/auto/perfdata/parallel_static_gcc/perf.data.zstd.expected.txt.zlib Binary files differnew file mode 100644 index 0000000..eaaa310 --- /dev/null +++ b/tests/auto/perfdata/parallel_static_gcc/perf.data.zstd.expected.txt.zlib diff --git a/tests/auto/perfdata/parallel_static_gcc/perf.data.zstd.zlib b/tests/auto/perfdata/parallel_static_gcc/perf.data.zstd.zlib Binary files differnew file mode 100644 index 0000000..645bc3f --- /dev/null +++ b/tests/auto/perfdata/parallel_static_gcc/perf.data.zstd.zlib diff --git a/tests/auto/perfdata/tst_perfdata.cpp b/tests/auto/perfdata/tst_perfdata.cpp index 04915c7..b4a72dd 100644 --- a/tests/auto/perfdata/tst_perfdata.cpp +++ b/tests/auto/perfdata/tst_perfdata.cpp @@ -43,7 +43,7 @@ private slots: }; static void setupUnwind(PerfUnwind *unwind, PerfHeader *header, QIODevice *input, - PerfAttributes *attributes, PerfData *data) + PerfAttributes *attributes, PerfData *data, const QByteArray &expectedVersion) { if (!header->isPipe()) { const qint64 filePos = input->pos(); @@ -58,7 +58,7 @@ static void setupUnwind(PerfUnwind *unwind, PerfHeader *header, QIODevice *input PerfTracingData tracingData = features.tracingData(); if (tracingData.size() > 0) - QCOMPARE(tracingData.version(), QByteArray("0.5")); + QCOMPARE(tracingData.version(), expectedVersion); unwind->features(features); const auto& attrs = attributes->attributes(); @@ -70,7 +70,7 @@ static void setupUnwind(PerfUnwind *unwind, PerfHeader *header, QIODevice *input } } -static void process(PerfUnwind *unwind, QIODevice *input) +static void process(PerfUnwind *unwind, QIODevice *input, const QByteArray &expectedVersion) { PerfHeader header(input); PerfAttributes attributes; @@ -79,7 +79,7 @@ static void process(PerfUnwind *unwind, QIODevice *input) QSignalSpy spy(&data, SIGNAL(finished())); QObject::connect(&header, &PerfHeader::finished, &data, [&](){ - setupUnwind(unwind, &header, input, &attributes, &data); + setupUnwind(unwind, &header, input, &attributes, &data, expectedVersion); data.read(); }); @@ -146,7 +146,7 @@ void TestPerfData::testTracingData() "/lib/x86_64-linux-gnu/libc-2.24.so. " "This can break stack unwinding and lead to missing symbols."))); } - process(&unwind, &input); + process(&unwind, &input, QByteArray("0.5")); if (stats) { const PerfUnwind::Stats stats = unwind.stats(); @@ -200,7 +200,7 @@ void TestPerfData::testContentSize() // Don't try to load any system files. They are not the same as the ones we use to report. PerfUnwind unwind(&output, ":/", QString(), QString(), QString(), true); - process(&unwind, &input); + process(&unwind, &input, QByteArray("0.5")); QCOMPARE(unwind.stats().numSamples, 69u); } @@ -254,6 +254,7 @@ void TestPerfData::testFiles_data() uncompressFile(QFINDTESTDATA("vector_static_clang/vector_static_clang_v8.0.1.zlib")); uncompressFile(QFINDTESTDATA("vector_static_gcc/vector_static_gcc_v9.1.0.zlib")); uncompressFile(QFINDTESTDATA("fork_static_gcc/fork.zlib")); + uncompressFile(QFINDTESTDATA("parallel_static_gcc/parallel_static_gcc.zlib")); const auto files = { "vector_static_clang/perf.data", @@ -261,6 +262,7 @@ void TestPerfData::testFiles_data() "vector_static_gcc/perf.lbr.data", "vector_static_gcc/perf.data.zstd", "fork_static_gcc/perf.data.zstd", + "parallel_static_gcc/perf.data.zstd", }; for (auto file : files) QTest::addRow("%s", file) << file; @@ -297,7 +299,11 @@ void TestPerfData::testFiles() if (QTest::currentDataTag() != QLatin1String("fork_static_gcc/perf.data.zstd")) QTest::ignoreMessage(QtWarningMsg, QRegularExpression("Failed to parse kernel symbol mapping file \".+\": Mapping is empty")); unwind.setKallsymsPath(QProcess::nullDevice()); - process(&unwind, &input); + + auto version = QByteArray("0.5"); + if (dataFile == "parallel_static_gcc/perf.data.zstd") + version = "0.6"; + process(&unwind, &input, version); } output.close(); diff --git a/tests/auto/shared/perfparsertestclient.cpp b/tests/auto/shared/perfparsertestclient.cpp index ce7482c..942d7b2 100644 --- a/tests/auto/shared/perfparsertestclient.cpp +++ b/tests/auto/shared/perfparsertestclient.cpp @@ -214,7 +214,12 @@ void PerfParserTestClient::convertToText(QTextStream &out) const if (attribute.type == 2) { const auto format = tracePointFormat(static_cast<qint32>(attribute.config)); out << string(format.system) << ' ' << string(format.name) << ' ' << Qt::hex << format.flags << Qt::dec << '\n'; + // we need stable output to allow comparisons, so convert to map + QMap<qint32, QVariant> sortedTracePointData; for (auto it = sample.tracePointData.begin(); it != sample.tracePointData.end(); ++it) { + sortedTracePointData.insert(it.key(), it.value()); + } + for (auto it = sortedTracePointData.begin(); it != sortedTracePointData.end(); ++it) { out << "\t\t" << string(it.key()) << '=' << it.value().toString() << '\n'; } } else { diff --git a/tests/manual/clients/parallel.cpp b/tests/manual/clients/parallel.cpp new file mode 100644 index 0000000..a70ece4 --- /dev/null +++ b/tests/manual/clients/parallel.cpp @@ -0,0 +1,37 @@ +// SPDX-License-Identifier: LGPL-2.1-or-later + +#include <cmath> +#include <complex> +#include <future> +#include <iostream> +#include <mutex> +#include <random> +#include <thread> +#include <vector> + +using namespace std; + +double worker() +{ + uniform_real_distribution<double> uniform(-1E5, 1E5); + default_random_engine engine; + double s = 0; + for (int i = 0; i < 10000; ++i) { + s += norm(complex<double>(uniform(engine), uniform(engine))); + } + cout << s << endl; + return s; +} + +int main(int argc, char** argv) +{ + const int numTasks = argc > 1 ? stoi(argv[1]) : std::thread::hardware_concurrency(); + vector<std::future<double>> results; + for (int i = 0; i < numTasks; ++i) { + results.push_back(async(launch::async, [i]() { + return worker() * i; + })); + } + return 0; +} + |