diff options
Diffstat (limited to 'tests')
-rw-r--r-- | tests/.clang-tidy | 17 | ||||
-rw-r--r-- | tests/TestClient.hpp | 8 | ||||
-rw-r--r-- | tests/connect_disconnect_node_patch.ttl | 6 | ||||
-rw-r--r-- | tests/ingen_bench.cpp | 23 | ||||
-rw-r--r-- | tests/ingen_test.cpp | 58 | ||||
-rw-r--r-- | tests/meson.build | 92 | ||||
-rw-r--r-- | tests/test_utils.hpp | 4 | ||||
-rw-r--r-- | tests/tst_FilePath.cpp | 108 |
8 files changed, 161 insertions, 155 deletions
diff --git a/tests/.clang-tidy b/tests/.clang-tidy new file mode 100644 index 00000000..7e189145 --- /dev/null +++ b/tests/.clang-tidy @@ -0,0 +1,17 @@ +Checks: > + -*-no-malloc, + -*-vararg, + -android-cloexec-fopen, + -cert-err33-c, + -concurrency-mt-unsafe, + -cppcoreguidelines-avoid-non-const-global-variables, + -cppcoreguidelines-owning-memory, + -cppcoreguidelines-pro-bounds-pointer-arithmetic, + -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 da749660..b864928e 100644 --- a/tests/TestClient.hpp +++ b/tests/TestClient.hpp @@ -23,7 +23,7 @@ #include "ingen/Status.hpp" #include "ingen/URI.hpp" -#include <boost/variant/get.hpp> +#include <variant> #include <cstdlib> @@ -32,14 +32,14 @@ namespace ingen { class TestClient : public Interface { public: - explicit TestClient(Log& log) : _log(log) {} + explicit TestClient(Log& log) noexcept : _log(log) {} ~TestClient() override = default; 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/connect_disconnect_node_patch.ttl b/tests/connect_disconnect_node_patch.ttl index 77ada2ad..373b5cbf 100644 --- a/tests/connect_disconnect_node_patch.ttl +++ b/tests/connect_disconnect_node_patch.ttl @@ -13,10 +13,10 @@ <msg1> a patch:Put ; - patch:subject <ingen:/main/sampler> ; + patch:subject <ingen:/main/metro> ; patch:body [ a ingen:Block ; - lv2:prototype <http://lv2plug.in/plugins/eg-sampler> + lv2:prototype <http://lv2plug.in/plugins/eg-metro> ] . <msg2> @@ -85,7 +85,7 @@ patch:body [ a ingen:Arc ; ingen:tail <ingen:/main/control> ; - ingen:head <ingen:/main/sampler/control> + ingen:head <ingen:/main/metro/control> ] . <msg10> diff --git a/tests/ingen_bench.cpp b/tests/ingen_bench.cpp index 2af53f89..82fae78d 100644 --- a/tests/ingen_bench.cpp +++ b/tests/ingen_bench.cpp @@ -32,8 +32,7 @@ #include <memory> #include <string> -namespace ingen { -namespace bench { +namespace ingen::bench { namespace { std::unique_ptr<ingen::World> world; @@ -62,8 +61,7 @@ run(int argc, char** argv) { // Create world try { - world = std::unique_ptr<ingen::World>{ - new ingen::World(nullptr, nullptr, nullptr)}; + world = std::make_unique<ingen::World>(nullptr, nullptr, nullptr); world->conf().add( "output", "output", 'O', "File to write benchmark output", @@ -117,10 +115,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); @@ -129,14 +127,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", 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 @@ -146,8 +144,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 87e02e9f..b1705dfa 100644 --- a/tests/ingen_test.cpp +++ b/tests/ingen_test.cpp @@ -29,7 +29,6 @@ #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" @@ -42,14 +41,14 @@ #include <cstdint> #include <cstdlib> #include <exception> +#include <filesystem> #include <iostream> #include <map> #include <memory> #include <string> #include <utility> -namespace ingen { -namespace test { +namespace ingen::test { namespace { std::unique_ptr<World> world; @@ -67,8 +66,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()}; } @@ -78,10 +77,10 @@ run(int argc, char** argv) { // Create world try { - world = std::unique_ptr<World>{new World(nullptr, nullptr, nullptr)}; + 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() << std::endl; return EXIT_FAILURE; } @@ -105,7 +104,9 @@ run(int argc, char** argv) << std::endl; return EXIT_FAILURE; - } else if (run_path.empty()) { + } + + if (run_path.empty()) { std::cerr << "error: command file '" << run_path << "' does not exist" << std::endl; @@ -144,7 +145,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); @@ -160,13 +161,16 @@ 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); - Sord::URI subject(*world->rdf_world(), subject_str, + const std::string subject_str = fmt("msg%1%", n_events); + + Sord::URI subject(*world->rdf_world(), + subject_str, reinterpret_cast<const char*>(cmds_file_uri.buf)); - Sord::Iter iter = cmds->find(subject, nil, nil); + + auto iter = cmds->find(subject, nil, nil); if (iter.end()) { break; } @@ -197,10 +201,10 @@ 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 (should result in a graph identical to the original) + // Undo every event (makes the graph identical to the original) for (int i = 0; i < n_events; ++i) { world->interface()->undo(); world->engine()->flush_events(std::chrono::milliseconds(20)); @@ -209,10 +213,10 @@ 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 (should result in a graph identical to the pre-undo output) + // Redo every event (makes the graph identical to the pre-undo output) for (int i = 0; i < n_events; ++i) { world->interface()->redo(); world->engine()->flush_events(std::chrono::milliseconds(20)); @@ -221,7 +225,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); @@ -234,14 +238,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() << std::endl; + return EXIT_FAILURE; + } } diff --git a/tests/meson.build b/tests/meson.build new file mode 100644 index 00000000..2c7f799f --- /dev/null +++ b/tests/meson.build @@ -0,0 +1,92 @@ +# Copyright 2019-2022 David Robillard <d@drobilla.net> +# SPDX-License-Identifier: 0BSD OR GPL-3.0-or-later + +##################### +# Integration Tests # +##################### + +ingen_test = executable( + 'ingen_test', + files('ingen_test.cpp'), + cpp_args: cpp_suppressions + platform_defines, + dependencies: [ingen_dep], +) + +ingen_bench = executable( + 'ingen_bench', + files('ingen_bench.cpp'), + cpp_args: cpp_suppressions + platform_defines, + dependencies: [ingen_dep], +) + +empty_manifest = files('empty.ingen/manifest.ttl') +empty_main = files('empty.ingen/main.ttl') + +integration_tests = [ + 'connect_disconnect_node_node', + 'connect_disconnect_node_patch', + 'connect_disconnect_patch_patch', + 'copy_node', + 'create_delete_node', + 'create_delete_patch', + 'create_delete_poly_patch', + 'create_delete_port', + 'disconnect_all_node', + 'disconnect_all_port', + 'duplicate_node', + 'enable_graph', + 'get_engine', + 'get_node', + 'get_patch', + 'get_plugin', + 'get_plugins', + 'get_port', + 'load_graph', + 'move_node', + 'move_port', + 'move_root_port', + 'poly', + 'put_audio_in', + 'save_graph', + 'set_graph_poly', + 'set_patch_port_value', +] + +test_env = environment( + { + 'INGEN_MODULE_PATH': ':'.join( + [ + ingen_build_root / 'src', + ingen_build_root / 'src' / 'client', + ingen_build_root / 'src' / 'gui', + ingen_build_root / 'src' / 'server', + ], + ), + 'LV2_PATH': ':'.join( + [ + lv2_dep.get_variable( + default_value: lv2dir, + internal: 'lv2dir', + pkgconfig: 'lv2dir', + ), + lv2_dep.get_variable( + default_value: lv2dir, + internal: 'plugindir', + pkgconfig: 'plugindir', + ), + ], + ), + }, +) + +foreach test : integration_tests + test( + test, + ingen_test, + env: test_env, + args: [ + ['--load', empty_manifest], + ['--execute', files(test + '.ttl')], + ], + ) +endforeach diff --git a/tests/test_utils.hpp b/tests/test_utils.hpp index 57446ac5..e595b7c8 100644 --- a/tests/test_utils.hpp +++ b/tests/test_utils.hpp @@ -14,13 +14,13 @@ along with Ingen. If not, see <http://www.gnu.org/licenses/>. */ -// IWYU pragma: no_include "ingen/FilePath.hpp" - #include "ingen/fmt.hpp" #include <iostream> #include <string> +// IWYU pragma: no_include "ingen/FilePath.hpp" + #define EXPECT_TRUE(value) \ do { \ if (!(value)) { \ 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; -} |