summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Goodliffe <dan@randomdan.homeip.net>2022-04-19 00:49:51 +0100
committerDan Goodliffe <dan@randomdan.homeip.net>2022-04-19 00:49:51 +0100
commitb4c6344ca96e8b180760dc96ec2ba0563d03fee7 (patch)
treeca6bbcd9c7fc8f9732cab332cc1b42fa128c6fff
parentUse cpp:array on write data, prevents copying (diff)
downloadnetfs-b4c6344ca96e8b180760dc96ec2ba0563d03fee7.tar.bz2
netfs-b4c6344ca96e8b180760dc96ec2ba0563d03fee7.tar.xz
netfs-b4c6344ca96e8b180760dc96ec2ba0563d03fee7.zip
Add a basic perf test setup for key functions
-rw-r--r--netfs/unittests/Jamfile.jam8
-rw-r--r--netfs/unittests/testPerf.cpp133
2 files changed, 141 insertions, 0 deletions
diff --git a/netfs/unittests/Jamfile.jam b/netfs/unittests/Jamfile.jam
index 736c370..53d600f 100644
--- a/netfs/unittests/Jamfile.jam
+++ b/netfs/unittests/Jamfile.jam
@@ -1,4 +1,5 @@
lib boost_utf : : <name>boost_unit_test_framework ;
+lib benchmark ;
path-constant leak-san-suppressions : leak-suppressions.txt ;
path-constant thread-san-suppressions : thread-suppressions.txt ;
@@ -99,3 +100,10 @@ run testDaemon.cpp ../daemon//modeCheck
<dependency>testCore
;
+explicit testPerf ;
+run testPerf.cpp
+ : : :
+ <library>benchmark
+ <library>testMocks
+ ;
+
diff --git a/netfs/unittests/testPerf.cpp b/netfs/unittests/testPerf.cpp
new file mode 100644
index 0000000..eff3ae4
--- /dev/null
+++ b/netfs/unittests/testPerf.cpp
@@ -0,0 +1,133 @@
+#include "mockDaemon.h"
+#include "mockFuse.h"
+#include <algorithm>
+#include <benchmark/benchmark.h>
+#include <climits>
+#include <compileTimeFormatter.h>
+#include <definedDirs.h>
+#include <filesystem>
+#include <fuseFiles.h>
+
+const std::filesystem::path tmpDir {getenv("XDG_RUNTIME_DIR") / selfExe.filename()};
+const std::string testEndpoint("tcp -h localhost -p 12016");
+const std::string testUri("tcp://localhost:12016/testvol");
+
+class Core {
+public:
+ Core() :
+ daemonHost(testEndpoint,
+ {"--Ice.ThreadPool.Client.Size=4", "--Ice.ThreadPool.Client.SizeMax=20",
+ "--Ice.ThreadPool.Server.Size=5", "--Ice.ThreadPool.Server.SizeMax=20",
+ "--NetFSD.ConfigPath=" + (rootDir / "defaultDaemon.xml").string()})
+ {
+ }
+
+protected:
+ MockDaemonHost daemonHost;
+
+public:
+};
+
+Core globalCore;
+
+class Fuse : public FuseMockHost, public benchmark::Fixture {
+public:
+ Fuse() :
+ FuseMockHost(testEndpoint,
+ {"--Ice.ThreadPool.Client.Size=6", "--Ice.ThreadPool.Client.SizeMax=20",
+ (rootDir / "defaultFuse.xml").string() + ":testvol", (tmpDir / "test").string()})
+ {
+ }
+
+ static int
+ nameListDiscard(void *, const char *, const struct stat *, off_t, fuse_fill_dir_flags)
+ {
+ return 0;
+ }
+};
+
+BENCHMARK_F(Fuse, statfs_root)(benchmark::State & state)
+{
+ struct statvfs st { };
+ for (auto _ : state) {
+ benchmark::DoNotOptimize(fuse->statfs("/", &st));
+ }
+}
+
+BENCHMARK_F(Fuse, getattr_root)(benchmark::State & state)
+{
+ struct stat st { };
+ for (auto _ : state) {
+ benchmark::DoNotOptimize(fuse->getattr("/", &st, nullptr));
+ }
+}
+
+BENCHMARK_F(Fuse, openclose_dir_root)(benchmark::State & state)
+{
+ for (auto _ : state) {
+ fuse_file_info fi {};
+ benchmark::DoNotOptimize(fuse->opendir("/", &fi));
+ benchmark::DoNotOptimize(fuse->releasedir("/", &fi));
+ }
+}
+
+AdHocFormatter(numbered_filename, "/files/test-%?.txt");
+AdHocFormatter(numbered_dir, "/dirs/test-%?");
+
+BENCHMARK_F(Fuse, create_files)(benchmark::State & state)
+{
+ fuse->mkdir("/files", 0700);
+ unsigned int n {};
+ for (auto _ : state) {
+ fuse_file_info fi {};
+ const std::string filename {numbered_filename::get(n++)};
+ benchmark::DoNotOptimize(fuse->create(filename.c_str(), 0600, &fi));
+ benchmark::DoNotOptimize(fuse->release(filename.c_str(), &fi));
+ }
+}
+
+BENCHMARK_F(Fuse, create_dirs)(benchmark::State & state)
+{
+ fuse->mkdir("/dirs", 0700);
+ unsigned int n {};
+ for (auto _ : state) {
+ const std::string dirname {numbered_dir::get(n++)};
+ benchmark::DoNotOptimize(fuse->mkdir(dirname.c_str(), 0600));
+ }
+}
+
+BENCHMARK_F(Fuse, ls_files)(benchmark::State & state)
+{
+ fuse_file_info fi {};
+ fuse->opendir("/files", &fi);
+ for (auto _ : state) {
+ benchmark::DoNotOptimize(fuse->readdir("/files", nullptr, nameListDiscard, 0, &fi, FUSE_READDIR_PLUS));
+ }
+ fuse->releasedir("/", &fi);
+}
+
+BENCHMARK_F(Fuse, write_file)(benchmark::State & state)
+{
+ fuse_file_info fi {};
+ fuse->open("/files/test-0.txt", &fi);
+ std::array<char, 1024> data {};
+ off_t off {};
+ for (auto _ : state) {
+ benchmark::DoNotOptimize(fuse->write("/files/test-0.txt", data.data(), data.size(), off, &fi));
+ off += data.size();
+ }
+ fuse->release("/", &fi);
+}
+
+BENCHMARK_F(Fuse, read_file)(benchmark::State & state)
+{
+ fuse_file_info fi {};
+ fuse->open("/files/test-0.txt", &fi);
+ std::array<char, 1024> data {};
+ for (auto _ : state) {
+ benchmark::DoNotOptimize(fuse->read("/files/test-0.txt", data.data(), data.size(), 0, &fi));
+ }
+ fuse->release("/", &fi);
+}
+
+BENCHMARK_MAIN();