summaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/.clang-tidy2
-rw-r--r--tests/TestClient.hpp16
-rw-r--r--tests/ingen_bench.cpp52
-rw-r--r--tests/ingen_test.cpp107
-rw-r--r--tests/lint/meson.build24
-rw-r--r--tests/meson.build38
-rw-r--r--tests/test_utils.hpp4
-rw-r--r--tests/tst_FilePath.cpp108
8 files changed, 124 insertions, 227 deletions
diff --git a/tests/.clang-tidy b/tests/.clang-tidy
index fb68f4e4..6c26f23c 100644
--- a/tests/.clang-tidy
+++ b/tests/.clang-tidy
@@ -10,7 +10,7 @@ Checks: >
-cppcoreguidelines-pro-type-reinterpret-cast,
-cppcoreguidelines-pro-type-union-access,
-fuchsia-statically-constructed-objects,
- -google-readability-casting,
-google-readability-todo,
+ -llvm-header-guard,
-readability-function-cognitive-complexity,
InheritParentConfig: true
diff --git a/tests/TestClient.hpp b/tests/TestClient.hpp
index f282ee6d..72265b14 100644
--- a/tests/TestClient.hpp
+++ b/tests/TestClient.hpp
@@ -17,13 +17,13 @@
#ifndef INGEN_TESTCLIENT_HPP
#define INGEN_TESTCLIENT_HPP
-#include "ingen/Interface.hpp"
-#include "ingen/Log.hpp"
-#include "ingen/Message.hpp"
-#include "ingen/Status.hpp"
-#include "ingen/URI.hpp"
+#include <ingen/Interface.hpp>
+#include <ingen/Log.hpp>
+#include <ingen/Message.hpp>
+#include <ingen/Status.hpp>
+#include <ingen/URI.hpp>
-#include <boost/variant/get.hpp>
+#include <variant>
#include <cstdlib>
@@ -39,7 +39,7 @@ public:
URI uri() const override { return URI("ingen:testClient"); }
void message(const Message& msg) override {
- if (const Response* const response = boost::get<Response>(&msg)) {
+ if (const Response* const response = std::get_if<Response>(&msg)) {
if (response->status != Status::SUCCESS) {
_log.error("error on message %1%: %2% (%3%)\n",
response->id,
@@ -47,7 +47,7 @@ public:
response->subject);
exit(EXIT_FAILURE);
}
- } else if (const Error* const error = boost::get<Error>(&msg)) {
+ } else if (const Error* const error = std::get_if<Error>(&msg)) {
_log.error("error: %1%\n", error->message);
exit(EXIT_FAILURE);
}
diff --git a/tests/ingen_bench.cpp b/tests/ingen_bench.cpp
index 07a59f9b..ee890401 100644
--- a/tests/ingen_bench.cpp
+++ b/tests/ingen_bench.cpp
@@ -14,14 +14,14 @@
along with Ingen. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "ingen/Atom.hpp"
-#include "ingen/Clock.hpp"
-#include "ingen/Configuration.hpp"
-#include "ingen/EngineBase.hpp"
-#include "ingen/Forge.hpp"
-#include "ingen/Parser.hpp"
-#include "ingen/World.hpp"
-#include "ingen/runtime_paths.hpp"
+#include <ingen/Atom.hpp>
+#include <ingen/Clock.hpp>
+#include <ingen/Configuration.hpp>
+#include <ingen/EngineBase.hpp>
+#include <ingen/Forge.hpp>
+#include <ingen/Parser.hpp>
+#include <ingen/World.hpp>
+#include <ingen/runtime_paths.hpp>
#include <chrono>
#include <cstdint>
@@ -32,8 +32,7 @@
#include <memory>
#include <string>
-namespace ingen {
-namespace bench {
+namespace ingen::bench {
namespace {
std::unique_ptr<ingen::World> world;
@@ -42,7 +41,7 @@ void
ingen_try(bool cond, const char* msg)
{
if (!cond) {
- std::cerr << "ingen: Error: " << msg << std::endl;
+ std::cerr << "ingen: Error: " << msg << "\n";
world.reset();
exit(EXIT_FAILURE);
}
@@ -69,7 +68,7 @@ run(int argc, char** argv)
ingen::Configuration::SESSION, world->forge().String, Atom());
world->load_configuration(argc, argv);
} catch (std::exception& e) {
- std::cout << "ingen: " << e.what() << std::endl;
+ std::cout << "ingen: " << e.what() << "\n";
return EXIT_FAILURE;
}
@@ -77,9 +76,7 @@ run(int argc, char** argv)
const Atom& load = world->conf().option("load");
const Atom& out = world->conf().option("output");
if (!load.is_valid() || !out.is_valid()) {
- std::cerr << "Usage: ingen_bench --load START_GRAPH --output OUT_FILE"
- << std::endl;
-
+ std::cerr << "Usage: ingen_bench --load START_GRAPH --output OUT_FILE\n";
return EXIT_FAILURE;
}
@@ -91,7 +88,7 @@ run(int argc, char** argv)
if (start_graph.empty()) {
std::cerr << "error: initial graph '"
<< static_cast<const char*>(load.get_body())
- << "' does not exist" << std::endl;
+ << "' does not exist\n";
return EXIT_FAILURE;
}
@@ -100,7 +97,7 @@ run(int argc, char** argv)
"Unable to load server module");
// Initialise engine
- ingen_try(bool(world->engine()),
+ ingen_try(!!world->engine(),
"Unable to create engine");
world->engine()->init(48000.0, 4096, 4096);
world->engine()->activate();
@@ -108,7 +105,7 @@ run(int argc, char** argv)
// Load graph
if (!world->parser()->parse_file(*world, *world->interface(), start_graph)) {
std::cerr << "error: failed to load initial graph " << start_graph
- << std::endl;
+ << "\n";
return EXIT_FAILURE;
}
@@ -116,10 +113,10 @@ run(int argc, char** argv)
// Run benchmark
// TODO: Set up real-time scheduling for this and worker threads
- ingen::Clock clock;
- const uint32_t n_test_frames = 1 << 20;
- const uint32_t block_length = 4096;
- const uint64_t t_start = clock.now_microseconds();
+ const ingen::Clock clock;
+ const uint32_t n_test_frames = 1 << 20;
+ const uint32_t block_length = 4096;
+ const uint64_t t_start = clock.now_microseconds();
for (uint32_t i = 0; i < n_test_frames; i += block_length) {
world->engine()->advance(block_length);
world->engine()->run(block_length);
@@ -128,14 +125,14 @@ run(int argc, char** argv)
const uint64_t t_end = clock.now_microseconds();
// Write log output
- std::unique_ptr<FILE, decltype(&fclose)> log{fopen(out_file.c_str(), "a"),
- &fclose};
+ const std::unique_ptr<FILE, int (*)(FILE*)> log{fopen(out_file.c_str(), "a"),
+ &fclose};
if (ftell(log.get()) == 0) {
fprintf(log.get(), "# n_threads\trun_time\treal_time\n");
}
- fprintf(log.get(), "%u\t%f\t%f\n",
+ fprintf(log.get(), "%d\t%f\t%f\n",
world->conf().option("threads").get<int32_t>(),
- (t_end - t_start) / 1000000.0,
+ static_cast<double>(t_end - t_start) / 1000000.0,
(n_test_frames / 48000.0));
// Shut down
@@ -145,8 +142,7 @@ run(int argc, char** argv)
}
} // namespace
-} // namespace bench
-} // namespace ingen
+} // namespace ingen::bench
int
main(int argc, char** argv)
diff --git a/tests/ingen_test.cpp b/tests/ingen_test.cpp
index df7e9d34..215d20a1 100644
--- a/tests/ingen_test.cpp
+++ b/tests/ingen_test.cpp
@@ -16,40 +16,41 @@
#include "TestClient.hpp"
-#include "ingen/Atom.hpp"
-#include "ingen/AtomForge.hpp"
-#include "ingen/AtomReader.hpp"
-#include "ingen/Configuration.hpp"
-#include "ingen/EngineBase.hpp"
-#include "ingen/FilePath.hpp"
-#include "ingen/Interface.hpp"
-#include "ingen/Parser.hpp"
-#include "ingen/Serialiser.hpp"
-#include "ingen/Store.hpp"
-#include "ingen/URI.hpp"
-#include "ingen/URIMap.hpp"
-#include "ingen/World.hpp"
-#include "ingen/filesystem.hpp"
-#include "ingen/fmt.hpp"
-#include "ingen/memory.hpp"
-#include "ingen/runtime_paths.hpp"
-#include "raul/Path.hpp"
-#include "serd/serd.h"
-#include "sord/sordmm.hpp"
-#include "sratom/sratom.h"
+#include <ingen/Atom.hpp>
+#include <ingen/AtomForge.hpp>
+#include <ingen/AtomReader.hpp>
+#include <ingen/Configuration.hpp>
+#include <ingen/EngineBase.hpp>
+#include <ingen/FilePath.hpp>
+#include <ingen/Interface.hpp>
+#include <ingen/Parser.hpp>
+#include <ingen/Serialiser.hpp>
+#include <ingen/Store.hpp>
+#include <ingen/URI.hpp>
+#include <ingen/URIMap.hpp>
+#include <ingen/World.hpp>
+#include <ingen/fmt.hpp>
+#include <ingen/memory.hpp>
+#include <ingen/runtime_paths.hpp>
+#include <raul/Path.hpp>
+#include <serd/serd.h>
+#include <sord/sordmm.hpp>
+#include <sratom/sratom.h>
#include <chrono>
#include <cstdint>
#include <cstdlib>
#include <exception>
+#include <filesystem>
#include <iostream>
#include <map>
#include <memory>
#include <string>
#include <utility>
-namespace ingen {
-namespace test {
+// #define DUMP_EVENTS 1
+
+namespace ingen::test {
namespace {
std::unique_ptr<World> world;
@@ -58,7 +59,7 @@ void
ingen_try(bool cond, const char* msg)
{
if (!cond) {
- std::cerr << "ingen: Error: " << msg << std::endl;
+ std::cerr << "ingen: Error: " << msg << "\n";
world.reset();
exit(EXIT_FAILURE);
}
@@ -67,8 +68,8 @@ ingen_try(bool cond, const char* msg)
FilePath
real_file_path(const char* path)
{
- std::unique_ptr<char, FreeDeleter<char>> real_path{realpath(path, nullptr),
- FreeDeleter<char>{}};
+ const std::unique_ptr<char, FreeDeleter<char>> real_path{realpath(path, nullptr),
+ FreeDeleter<char>{}};
return FilePath{real_path.get()};
}
@@ -80,8 +81,8 @@ run(int argc, char** argv)
try {
world = std::make_unique<World>(nullptr, nullptr, nullptr);
world->load_configuration(argc, argv);
- } catch (std::exception& e) {
- std::cout << "ingen: " << e.what() << std::endl;
+ } catch (const std::exception& e) {
+ std::cerr << "ingen: " << e.what() << "\n";
return EXIT_FAILURE;
}
@@ -90,8 +91,7 @@ run(int argc, char** argv)
const Atom& execute = world->conf().option("execute");
if (!load.is_valid() || !execute.is_valid()) {
std::cerr
- << "Usage: ingen_test --load START_GRAPH --execute COMMANDS_FILE"
- << std::endl;
+ << "Usage: ingen_test --load START_GRAPH --execute COMMANDS_FILE\n";
return EXIT_FAILURE;
}
@@ -101,16 +101,12 @@ run(int argc, char** argv)
const FilePath run_path = real_file_path(static_cast<const char*>(execute.get_body()));
if (load_path.empty()) {
- std::cerr << "error: initial graph '" << load_path << "' does not exist"
- << std::endl;
-
+ std::cerr << "error: initial graph '" << load_path << "' does not exist\n";
return EXIT_FAILURE;
}
if (run_path.empty()) {
- std::cerr << "error: command file '" << run_path << "' does not exist"
- << std::endl;
-
+ std::cerr << "error: command file '" << run_path << "' does not exist\n";
return EXIT_FAILURE;
}
@@ -119,16 +115,14 @@ run(int argc, char** argv)
"Unable to load server module");
// Initialise engine
- ingen_try(bool(world->engine()),
+ ingen_try(!!world->engine(),
"Unable to create engine");
world->engine()->init(48000.0, 4096, 4096);
world->engine()->activate();
// Load graph
if (!world->parser()->parse_file(*world, *world->interface(), load_path)) {
- std::cerr << "error: failed to load initial graph " << load_path
- << std::endl;
-
+ std::cerr << "error: failed to load initial graph " << load_path << "\n";
return EXIT_FAILURE;
}
world->engine()->flush_events(std::chrono::milliseconds(20));
@@ -146,7 +140,7 @@ run(int argc, char** argv)
*world->interface());
// AtomWriter to serialise responses from the engine
- std::shared_ptr<Interface> client(new TestClient(world->log()));
+ const std::shared_ptr<Interface> client{new TestClient(world->log())};
world->interface()->set_respondee(client);
world->engine()->register_client(client);
@@ -162,10 +156,10 @@ run(int argc, char** argv)
SerdEnv* env = serd_env_new(&cmds_file_uri);
cmds->load_file(env, SERD_TURTLE, run_path);
- Sord::Node nil;
- int n_events = 0;
+ const Sord::Node nil;
+ int n_events = 0;
for (;; ++n_events) {
- std::string subject_str = fmt("msg%1%", n_events);
+ const std::string subject_str = fmt("msg%1%", n_events);
Sord::URI subject(*world->rdf_world(),
subject_str,
@@ -179,9 +173,9 @@ run(int argc, char** argv)
forge.clear();
forge.read(*world->rdf_world(), cmds->c_obj(), subject.c_obj());
-#if 0
+#ifdef DUMP_EVENTS
const LV2_Atom* atom = forge.atom();
- cerr << "READ " << atom->size << " BYTES" << endl;
+ cerr << "READ " << atom->size << " BYTES\n";
cerr << sratom_to_turtle(
sratom,
&world->uri_map().urid_unmap_feature()->urid_unmap,
@@ -190,6 +184,7 @@ run(int argc, char** argv)
#endif
if (!atom_reader.write(forge.atom(), n_events + 1)) {
+ delete cmds;
return EXIT_FAILURE;
}
@@ -202,7 +197,7 @@ run(int argc, char** argv)
auto r = world->store()->find(raul::Path("/"));
const std::string base = run_path.stem();
const std::string out_name = base.substr(0, base.find('.')) + ".out.ingen";
- const FilePath out_path = filesystem::current_path() / out_name;
+ const FilePath out_path = std::filesystem::current_path() / out_name;
world->serialiser()->write_bundle(r->second, URI(out_path));
// Undo every event (makes the graph identical to the original)
@@ -214,7 +209,7 @@ run(int argc, char** argv)
// Save completely undone graph
r = world->store()->find(raul::Path("/"));
const std::string undo_name = base.substr(0, base.find('.')) + ".undo.ingen";
- const FilePath undo_path = filesystem::current_path() / undo_name;
+ const FilePath undo_path = std::filesystem::current_path() / undo_name;
world->serialiser()->write_bundle(r->second, URI(undo_path));
// Redo every event (makes the graph identical to the pre-undo output)
@@ -226,7 +221,7 @@ run(int argc, char** argv)
// Save completely redone graph
r = world->store()->find(raul::Path("/"));
const std::string redo_name = base.substr(0, base.find('.')) + ".redo.ingen";
- const FilePath redo_path = filesystem::current_path() / redo_name;
+ const FilePath redo_path = std::filesystem::current_path() / redo_name;
world->serialiser()->write_bundle(r->second, URI(redo_path));
serd_env_free(env);
@@ -239,14 +234,18 @@ run(int argc, char** argv)
}
} // namespace
-} // namespace test
-} // namespace ingen
+} // namespace ingen::test
int
main(int argc, char** argv)
{
- ingen::set_bundle_path_from_code(
- reinterpret_cast<void (*)()>(&ingen::test::ingen_try));
+ try {
+ ingen::set_bundle_path_from_code(
+ reinterpret_cast<void (*)()>(&ingen::test::ingen_try));
- return ingen::test::run(argc, argv);
+ return ingen::test::run(argc, argv);
+ } catch (const std::exception& e) {
+ std::cerr << "ingen: " << e.what() << "\n";
+ return EXIT_FAILURE;
+ }
}
diff --git a/tests/lint/meson.build b/tests/lint/meson.build
new file mode 100644
index 00000000..c641cbaa
--- /dev/null
+++ b/tests/lint/meson.build
@@ -0,0 +1,24 @@
+# Copyright 2019-2024 David Robillard <d@drobilla.net>
+# SPDX-License-Identifier: 0BSD OR GPL-3.0-or-later
+
+if not meson.is_subproject()
+ # Check code with cppcheck
+ cppcheck = find_program('cppcheck', required: false)
+ if cppcheck.found()
+ compdb_path = join_paths(ingen_build_root, 'compile_commands.json')
+ suppress_path = join_paths(ingen_src_root, '.suppress.cppcheck')
+ test(
+ 'cppcheck',
+ cppcheck,
+ args: [
+ '--cppcheck-build-dir=' + meson.current_build_dir(),
+ '--enable=warning,style,performance,portability',
+ '--error-exitcode=1',
+ '--project=' + compdb_path,
+ '--suppressions-list=' + suppress_path,
+ '-q',
+ ],
+ suite: 'code',
+ )
+ endif
+endif
diff --git a/tests/meson.build b/tests/meson.build
index a9bf5725..1637230b 100644
--- a/tests/meson.build
+++ b/tests/meson.build
@@ -1,27 +1,6 @@
# Copyright 2019-2022 David Robillard <d@drobilla.net>
# SPDX-License-Identifier: 0BSD OR GPL-3.0-or-later
-##############
-# Unit Tests #
-##############
-
-unit_tests = [
- 'FilePath',
-]
-
-foreach test : unit_tests
- test(
- test,
- executable(
- test,
- files('tst_@0@.cpp'.format(test)),
- cpp_args: cpp_suppressions + platform_defines,
- dependencies: [ingen_dep],
- ),
- suite: 'unit',
- )
-endforeach
-
#####################
# Integration Tests #
#####################
@@ -94,10 +73,11 @@ test_env = environment(
default_value: lv2dir,
internal: 'plugindir',
pkgconfig: 'plugindir',
- )
+ ),
],
),
- })
+ },
+)
foreach test : integration_tests
test(
@@ -105,8 +85,16 @@ foreach test : integration_tests
ingen_test,
env: test_env,
args: [
- '--load', empty_manifest,
- '--execute', files(test + '.ttl'),
+ ['--load', empty_manifest],
+ ['--execute', files(test + '.ttl')],
],
)
endforeach
+
+########
+# Lint #
+########
+
+if get_option('lint')
+ subdir('lint')
+endif
diff --git a/tests/test_utils.hpp b/tests/test_utils.hpp
index 57446ac5..4c358739 100644
--- a/tests/test_utils.hpp
+++ b/tests/test_utils.hpp
@@ -14,9 +14,7 @@
along with Ingen. If not, see <http://www.gnu.org/licenses/>.
*/
-// IWYU pragma: no_include "ingen/FilePath.hpp"
-
-#include "ingen/fmt.hpp"
+#include <ingen/fmt.hpp>
#include <iostream>
#include <string>
diff --git a/tests/tst_FilePath.cpp b/tests/tst_FilePath.cpp
deleted file mode 100644
index 75744f46..00000000
--- a/tests/tst_FilePath.cpp
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- This file is part of Ingen.
- Copyright 2018 David Robillard <http://drobilla.net/>
-
- Ingen is free software: you can redistribute it and/or modify it under the
- terms of the GNU Affero General Public License as published by the Free
- Software Foundation, either version 3 of the License, or any later version.
-
- Ingen is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE. See the GNU Affero General Public License for details.
-
- You should have received a copy of the GNU Affero General Public License
- along with Ingen. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include "test_utils.hpp"
-
-#include "ingen/FilePath.hpp"
-#include "ingen/fmt.hpp"
-
-#include <boost/utility/string_view_fwd.hpp>
-
-#include <string>
-
-using ingen::FilePath;
-using ingen::fmt;
-
-int
-main(int, char**)
-{
- EXPECT_EQ(FilePath("/").parent_path(), FilePath("/"));
-
- EXPECT_TRUE(FilePath("/abs").is_absolute());
- EXPECT_FALSE(FilePath("/abs").is_relative());
- EXPECT_EQ(FilePath("/abs").root_name(), FilePath());
- EXPECT_EQ(FilePath("/abs").root_directory(), FilePath("/"));
- EXPECT_EQ(FilePath("/abs").root_path(), FilePath("/"));
- EXPECT_EQ(FilePath("/abs").relative_path(), FilePath("abs"));
- EXPECT_EQ(FilePath("/abs").parent_path(), FilePath("/"));
- EXPECT_EQ(FilePath("/abs").filename(), FilePath("abs"));
- EXPECT_EQ(FilePath("/abs").stem(), FilePath("abs"));
- EXPECT_EQ(FilePath("/abs").extension(), FilePath());
-
- EXPECT_FALSE(FilePath("rel").is_absolute());
- EXPECT_TRUE(FilePath("rel").is_relative());
- EXPECT_EQ(FilePath("rel").root_name(), FilePath());
- EXPECT_EQ(FilePath("rel").root_directory(), FilePath());
- EXPECT_EQ(FilePath("rel").root_path(), FilePath());
- EXPECT_EQ(FilePath("rel").relative_path(), FilePath());
- EXPECT_EQ(FilePath("rel").parent_path(), FilePath());
- EXPECT_EQ(FilePath("rel").filename(), "rel");
- EXPECT_EQ(FilePath("rel").stem(), "rel");
- EXPECT_EQ(FilePath("rel").extension(), FilePath());
-
- EXPECT_FALSE(FilePath("file.txt").is_absolute());
- EXPECT_TRUE(FilePath("file.txt").is_relative());
- EXPECT_EQ(FilePath("file.txt").filename(), "file.txt");
- EXPECT_EQ(FilePath("file.txt").stem(), "file");
- EXPECT_EQ(FilePath("file.txt").extension(), ".txt");
-
- EXPECT_TRUE(FilePath("/abs/file.txt").is_absolute());
- EXPECT_FALSE(FilePath("/abs/file.txt").is_relative());
- EXPECT_EQ(FilePath("/abs/file.txt").filename(), "file.txt");
- EXPECT_EQ(FilePath("/abs/file.txt").stem(), "file");
- EXPECT_EQ(FilePath("/abs/file.txt").extension(), ".txt");
-
- EXPECT_FALSE(FilePath("rel/file.txt").is_absolute());
- EXPECT_TRUE(FilePath("rel/file.txt").is_relative());
- EXPECT_EQ(FilePath("rel/file.txt").filename(), "file.txt");
- EXPECT_EQ(FilePath("rel/file.txt").stem(), "file");
- EXPECT_EQ(FilePath("rel/file.txt").extension(), ".txt");
-
- FilePath path("/x");
- EXPECT_EQ(path, "/x");
- path = std::string("/a");
- EXPECT_EQ(path, "/a");
-
- path /= FilePath("b");
- EXPECT_EQ(path, "/a/b");
-
- path += FilePath("ar");
- EXPECT_EQ(path, "/a/bar");
-
- path += std::string("/c");
- EXPECT_EQ(path, "/a/bar/c");
-
- path += "a";
- EXPECT_EQ(path, "/a/bar/ca");
-
- path += 'r';
- EXPECT_EQ(path, "/a/bar/car");
-
- path += boost::string_view("/d");
- EXPECT_EQ(path, "/a/bar/car/d");
-
- const FilePath apple("apple");
- const FilePath zebra("zebra");
- EXPECT_TRUE(apple == apple);
- EXPECT_TRUE(apple != zebra);
- EXPECT_TRUE(apple < zebra);
- EXPECT_TRUE(apple <= zebra);
- EXPECT_TRUE(apple <= apple);
- EXPECT_TRUE(zebra > apple);
- EXPECT_TRUE(zebra >= apple);
- EXPECT_TRUE(zebra >= zebra);
- return 0;
-}