From b4c6344ca96e8b180760dc96ec2ba0563d03fee7 Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Tue, 19 Apr 2022 00:49:51 +0100 Subject: Add a basic perf test setup for key functions --- netfs/unittests/Jamfile.jam | 8 +++ netfs/unittests/testPerf.cpp | 133 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 141 insertions(+) create mode 100644 netfs/unittests/testPerf.cpp 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 : : 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 testCore ; +explicit testPerf ; +run testPerf.cpp + : : : + benchmark + 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 +#include +#include +#include +#include +#include +#include + +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 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 data {}; + for (auto _ : state) { + benchmark::DoNotOptimize(fuse->read("/files/test-0.txt", data.data(), data.size(), 0, &fi)); + } + fuse->release("/", &fi); +} + +BENCHMARK_MAIN(); -- cgit v1.2.3