summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMilian Wolff <milian.wolff@kdab.com>2022-06-04 22:44:52 +0200
committerMilian Wolff <milian.wolff@kdab.com>2022-06-10 08:46:24 +0000
commitbf8d70fd31f2d8ad7e208847303f6317788d1e32 (patch)
treefdc37b5639c6e69b2b2624098130959e155f8aa4
parent990b8c2dceea8a63bdb67798d7594189f07fb0f5 (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--.gitignore2
-rw-r--r--tests/auto/perfdata/parallel_static_gcc/parallel_static_gcc.zlibbin0 -> 1048168 bytes
-rw-r--r--tests/auto/perfdata/parallel_static_gcc/perf.data.zstd.expected.txt.zlibbin0 -> 14836 bytes
-rw-r--r--tests/auto/perfdata/parallel_static_gcc/perf.data.zstd.zlibbin0 -> 27100 bytes
-rw-r--r--tests/auto/perfdata/tst_perfdata.cpp20
-rw-r--r--tests/auto/shared/perfparsertestclient.cpp5
-rw-r--r--tests/manual/clients/parallel.cpp37
7 files changed, 57 insertions, 7 deletions
diff --git a/.gitignore b/.gitignore
index d218ddf..6ee67b1 100644
--- a/.gitignore
+++ b/.gitignore
@@ -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
new file mode 100644
index 0000000..18d41b4
--- /dev/null
+++ b/tests/auto/perfdata/parallel_static_gcc/parallel_static_gcc.zlib
Binary files differ
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
new file mode 100644
index 0000000..eaaa310
--- /dev/null
+++ b/tests/auto/perfdata/parallel_static_gcc/perf.data.zstd.expected.txt.zlib
Binary files differ
diff --git a/tests/auto/perfdata/parallel_static_gcc/perf.data.zstd.zlib b/tests/auto/perfdata/parallel_static_gcc/perf.data.zstd.zlib
new file mode 100644
index 0000000..645bc3f
--- /dev/null
+++ b/tests/auto/perfdata/parallel_static_gcc/perf.data.zstd.zlib
Binary files differ
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;
+}
+