diff options
Diffstat (limited to 'test')
-rw-r--r-- | test/array_test.cpp | 74 | ||||
-rw-r--r-- | test/build_test.cpp | 39 | ||||
-rw-r--r-- | test/double_buffer_test.cpp | 39 | ||||
-rw-r--r-- | test/maid_test.cpp | 128 | ||||
-rw-r--r-- | test/path_test.cpp | 102 | ||||
-rw-r--r-- | test/ringbuffer_test.cpp | 210 | ||||
-rw-r--r-- | test/sem_test.cpp | 72 | ||||
-rw-r--r-- | test/socket_test.cpp | 116 | ||||
-rw-r--r-- | test/symbol_test.cpp | 75 | ||||
-rw-r--r-- | test/thread_test.cpp | 68 | ||||
-rw-r--r-- | test/time_test.cpp | 46 |
11 files changed, 969 insertions, 0 deletions
diff --git a/test/array_test.cpp b/test/array_test.cpp new file mode 100644 index 0000000..e401fc8 --- /dev/null +++ b/test/array_test.cpp @@ -0,0 +1,74 @@ +/* + This file is part of Raul. + Copyright 2007-2016 David Robillard <http://drobilla.net> + + Raul is free software: you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation, either version 3 of the License, or any later version. + + Raul 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Raul. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include "raul/Array.hpp" + +#include <cstdio> + +int +main() +{ + Raul::Array<int> array1(32, 2); + + array1[0] = 42; + if (array1[0] != 42) { + fprintf(stderr, "array1[0] != 42\n"); + return 1; + } else if (array1[1] != 2) { + fprintf(stderr, "array1[1] != 2\n"); + return 1; + } else if (array1.size() != 32) { + fprintf(stderr, "array1.size() != 1\n"); + return 1; + } + + array1.alloc(16, 0); + if (array1[0] != 0) { + fprintf(stderr, "array1[0] != 0\n"); + return 1; + } else if (array1.at(0) != 0) { + fprintf(stderr, "array1.at(0) != 0\n"); + return 1; + } else if (array1.size() != 16) { + fprintf(stderr, "array1.size() != 16\n"); + return 1; + } + + array1.alloc(8, 0); + if (array1.size() != 8) { + fprintf(stderr, "array1.size() != 8\n"); + return 1; + } + + Raul::Array<int> array2(array1); + for (size_t i = 0; i < array1.size(); ++i) { + if (array2[i] != array1[i]) { + fprintf(stderr, "Mismatch at %zu\n", i); + return 1; + } + } + + Raul::Array<int> array3(8, 47); + if (array3[0] != 47) { + fprintf(stderr, "array3[0] != 47\n"); + return 1; + } else if (array3.size() != 8) { + fprintf(stderr, "array3.size() != 8\n"); + return 1; + } + + return 0; +} diff --git a/test/build_test.cpp b/test/build_test.cpp new file mode 100644 index 0000000..cbf153d --- /dev/null +++ b/test/build_test.cpp @@ -0,0 +1,39 @@ +/* + This file is part of Raul. + Copyright 2007-2017 David Robillard <http://drobilla.net> + + Raul is free software: you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation, either version 3 of the License, or any later version. + + Raul 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Raul. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include "raul/Array.hpp" +#include "raul/Deletable.hpp" +#include "raul/DoubleBuffer.hpp" +#include "raul/Exception.hpp" +#include "raul/Maid.hpp" +#include "raul/Noncopyable.hpp" +#include "raul/Path.hpp" +#include "raul/RingBuffer.hpp" +#include "raul/Semaphore.hpp" +#include "raul/Symbol.hpp" +#include "raul/TimeSlice.hpp" +#include "raul/TimeStamp.hpp" + +#ifndef _WIN32 +#include "raul/Process.hpp" +#include "raul/Socket.hpp" +#endif + +int +main() +{ + return 0; +} diff --git a/test/double_buffer_test.cpp b/test/double_buffer_test.cpp new file mode 100644 index 0000000..1717d0e --- /dev/null +++ b/test/double_buffer_test.cpp @@ -0,0 +1,39 @@ +/* + This file is part of Raul. + Copyright 2013 David Robillard <http://drobilla.net> + + Raul is free software: you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation, either version 3 of the License, or any later version. + + Raul 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Raul. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include "raul/DoubleBuffer.hpp" + +int +main() +{ + Raul::DoubleBuffer<int> db(0); + + if (db.get() != 0) { + return 1; + } + + db.set(42); + if (db.get() != 42) { + return 1; + } + + db.set(43); + if (db.get() != 43) { + return 1; + } + + return 0; +} diff --git a/test/maid_test.cpp b/test/maid_test.cpp new file mode 100644 index 0000000..94e09c6 --- /dev/null +++ b/test/maid_test.cpp @@ -0,0 +1,128 @@ +/* + This file is part of Raul. + Copyright 2007-2017 David Robillard <http://drobilla.net> + + Raul is free software: you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation, either version 3 of the License, or any later version. + + Raul 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Raul. If not, see <http://www.gnu.org/licenses/>. +*/ + +#undef NDEBUG + +#include "raul/Maid.hpp" + +#include <atomic> +#include <cassert> +#include <chrono> +#include <cstdio> +#include <memory> +#include <thread> +#include <vector> + +using Raul::Maid; + +static const size_t n_threads = 8U; +static const size_t n_junk_per_thread = 1U << 18U; + +static std::atomic<size_t> n_junk(0); +static std::atomic<size_t> n_finished_threads(0); + +class Junk : public Maid::Disposable { +public: + explicit Junk(size_t v) : val(v) { ++n_junk; } + ~Junk() override { --n_junk; } + + size_t val; +}; + +static void +litter(Maid* maid) +{ + for (size_t i = 0; i < n_junk_per_thread; ++i) { + Maid::managed_ptr<Junk> a = maid->make_managed<Junk>(i); + } + + ++n_finished_threads; +} + +static void +test() +{ + Maid maid; + + // Check basic single-threaded correctness + { + assert(n_junk == 0); + Maid::managed_ptr<Junk> a = maid.make_managed<Junk>(1U); + assert(n_junk == 1); + Maid::managed_ptr<Junk> b = maid.make_managed<Junk>(2U); + assert(n_junk == 2); + } + + maid.dispose(nullptr); // Mustn't crash + + // All referenes dropped, but deletion deferred + assert(n_junk == 2); + + // Trigger actual deletion + maid.cleanup(); + assert(n_junk == 0); + assert(maid.empty()); + + // Create some threads to produce garbage + std::vector<std::thread> litterers; + for (size_t i = 0; i < n_threads; ++i) { + litterers.emplace_back(litter, &maid); + } + + // Wait for some garbage to show up if necessary (unlikely) + size_t initial_n_junk = n_junk; + while (maid.empty()) { + std::this_thread::sleep_for(std::chrono::milliseconds(1)); + initial_n_junk = n_junk; + } + + printf("Starting with %zu initial bits of junk\n", initial_n_junk); + + // Ensure we're actually cleaning things up concurrently + maid.cleanup(); + assert(n_junk != initial_n_junk); + + // Continue cleaning up as long as threads are running + size_t n_cleanup_calls = 1; + while (n_finished_threads < n_threads) { + maid.cleanup(); + ++n_cleanup_calls; + } + + printf("Called cleanup %zu times\n", n_cleanup_calls); + + // Join litterer threads + for (auto& t : litterers) { + t.join(); + } + + // Clean up any leftover garbage (unlikely/impossible?) + maid.cleanup(); + assert(n_junk == 0); + + // Allocate a new object, then let it and the Maid go out of scope + Maid::managed_ptr<Junk> c = maid.make_managed<Junk>(5U); + assert(n_junk == 1); +} + +int +main() +{ + assert(n_junk == 0); + test(); + assert(n_junk == 0); + return 0; +} diff --git a/test/path_test.cpp b/test/path_test.cpp new file mode 100644 index 0000000..538a262 --- /dev/null +++ b/test/path_test.cpp @@ -0,0 +1,102 @@ +/* + This file is part of Raul. + Copyright 2007-2012 David Robillard <http://drobilla.net> + + Raul is free software: you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation, either version 3 of the License, or any later version. + + Raul 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Raul. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include "raul/Path.hpp" +#include "raul/Symbol.hpp" + +#include <cstring> +#include <iostream> +#include <string> + +int +main() +{ + using Path = Raul::Path; + using Symbol = Raul::Symbol; + +#define CHECK(cond) \ + do { if (!(cond)) { \ + std::cerr << "Test failed: " << (cond) << std::endl; \ + return 1; \ + } } while (0) + + CHECK(Path("/foo/bar").parent() == Path("/foo")); + CHECK(Path("/foo").parent() == Path("/")); + CHECK(Path("/").parent() == Path("/")); + + CHECK(Path("/").is_parent_of(Path("/foo"))); + CHECK(Path("/foo").is_parent_of(Path("/foo/bar"))); + CHECK(!(Path("/foo").is_parent_of(Path("/foo2")))); + CHECK(!(Path("/foo").is_parent_of(Path("/foo")))); + + CHECK(Path::lca(Path("/foo"), Path("/foo/bar/baz")) == Path("/")); + CHECK(Path::lca(Path("/foo/bar"), Path("/foo/bar/baz")) == Path("/foo")); + CHECK(Path::lca(Path("/foo/bar/quux"), Path("/foo/bar/baz")) == Path("/foo/bar")); + + CHECK(!Path::is_valid("")); + CHECK(!Path::is_valid("hello")); + CHECK(!Path::is_valid("/foo/bar/")); + CHECK(!Path::is_valid("/foo//bar")); + CHECK(!Path::is_valid("/foo/bar/d*s")); + CHECK(Path::is_valid("/")); + CHECK(!Path::is_valid("/foo/3foo/bar")); + + CHECK(Path::descendant_comparator(Path("/"), Path("/"))); + CHECK(Path::descendant_comparator(Path("/"), Path("/foo"))); + CHECK(Path::descendant_comparator(Path("/foo"), Path("/foo/bar"))); + CHECK(Path::descendant_comparator(Path("/foo"), Path("/foo"))); + CHECK(Path::descendant_comparator(Path("/"), Path("/"))); + CHECK(!Path::descendant_comparator(Path("/baz"), Path("/"))); + CHECK(!Path::descendant_comparator(Path("/foo"), Path("/bar"))); + CHECK(!Path::descendant_comparator(Path("/foo/bar"), Path("/foo"))); + + CHECK(!Symbol::is_valid("")); + CHECK(!Symbol::is_valid("/I/have/slashes")); + CHECK(!Symbol::is_valid("!illegalchar")); + CHECK(!Symbol::is_valid("0illegalleadingdigit")); + CHECK(strcmp(Symbol::symbolify("").c_str(), "")); + + CHECK(Path("/foo").child(Symbol("bar")) == "/foo/bar"); + CHECK(Path("/foo").child(Path("/bar/baz")) == "/foo/bar/baz"); + CHECK(Path("/foo").child(Path("/")) == "/foo"); + + CHECK(!strcmp(Path("/foo").symbol(), "foo")); + CHECK(!strcmp(Path("/foo/bar").symbol(), "bar")); + CHECK(!strcmp(Path("/").symbol(), "")); + + Path original(std::string("/foo/bar")); + CHECK(original == Path(original)); + + bool valid = true; + try { + Path path("/ends/in/slash/"); + } catch (const Path::BadPath& e) { + std::cerr << "Caught exception: " << e.what() << std::endl; + valid = false; + } + CHECK(!valid); + + valid = true; + try { + Path path(std::string("/has//double/slash")); + } catch (const Path::BadPath& e) { + std::cerr << "Caught exception: " << e.what() << std::endl; + valid = false; + } + CHECK(!valid); + + return 0; +} diff --git a/test/ringbuffer_test.cpp b/test/ringbuffer_test.cpp new file mode 100644 index 0000000..daae419 --- /dev/null +++ b/test/ringbuffer_test.cpp @@ -0,0 +1,210 @@ +/* + This file is part of Raul. + Copyright 2007-2012 David Robillard <http://drobilla.net> + + Raul is free software: you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation, either version 3 of the License, or any later version. + + Raul 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Raul. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include "raul/RingBuffer.hpp" + +#include <climits> +#include <cstdint> +#include <cstdio> +#include <cstring> +#include <memory> +#include <string> +#include <thread> + +#define MSG_SIZE 20 + +namespace { + +using RingBuffer = Raul::RingBuffer; + +struct Context { + std::unique_ptr<RingBuffer> ring; + size_t n_writes{0}; + size_t ring_errors{0}; +}; + +int +gen_msg(int* msg, int start) +{ + for (int i = 0; i < MSG_SIZE; ++i) { + msg[i] = start; + start = (start + 1) % INT_MAX; + } + return start; +} + +int +cmp_msg(int* msg1, int* msg2) +{ + for (int i = 0; i < MSG_SIZE; ++i) { + if (msg1[i] != msg2[i]) { + fprintf(stderr, "ERROR: %d != %d @ %d\n", msg1[i], msg2[i], i); + return 0; + } + } + + return 1; +} + +void +reader(Context& ctx) +{ + printf("Reader starting\n"); + + int ref_msg[MSG_SIZE]; // Reference generated for comparison + int read_msg[MSG_SIZE]; // Read from ring + size_t count = 0; + int start = gen_msg(ref_msg, 0); + for (size_t i = 0; i < ctx.n_writes; ++i) { + if (ctx.ring->read_space() >= MSG_SIZE * sizeof(int)) { + const uint32_t n_read = ctx.ring->read(MSG_SIZE * sizeof(int), read_msg); + if (n_read != MSG_SIZE * sizeof(int)) { + fprintf(stderr, "FAIL: Read size incorrect\n"); + ++ctx.ring_errors; + return; + } + if (!cmp_msg(ref_msg, read_msg)) { + fprintf(stderr, "FAIL: Message %zu is corrupt\n", count); + ++ctx.ring_errors; + return; + } + start = gen_msg(ref_msg, start); + ++count; + } + } + + printf("Reader finished\n"); +} + +void +writer(Context& ctx) +{ + printf("Writer starting\n"); + + int write_msg[MSG_SIZE]; // Written to ring + int start = gen_msg(write_msg, 0); + for (size_t i = 0; i < ctx.n_writes; ++i) { + if (ctx.ring->write_space() >= MSG_SIZE * sizeof(int)) { + const uint32_t n_write = ctx.ring->write(MSG_SIZE * sizeof(int), write_msg); + if (n_write != MSG_SIZE * sizeof(int)) { + fprintf(stderr, "FAIL: Write size incorrect\n"); + ++ctx.ring_errors; + return; + } + start = gen_msg(write_msg, start); + } + } + + printf("Writer finished\n"); +} + +} // namespace + +int +main(int argc, char** argv) +{ + if (argc > 1 && argv[1][0] == '-') { + printf("Usage: %s SIZE N_WRITES\n", argv[0]); + return 1; + } + + Context ctx; + + size_t size = 1024; + if (argc > 1) { + size = std::stoul(argv[1]); + } + + ctx.n_writes = size * 1024; + if (argc > 2) { + ctx.n_writes = std::stoul(argv[2]); + } + + printf("Testing %zu writes of %u ints to a %zu int ring...\n", + ctx.n_writes, MSG_SIZE, size); + + ctx.ring = std::unique_ptr<RingBuffer>(new RingBuffer(uint32_t(size))); + + auto& ring = ctx.ring; + if (ring->capacity() < size - 1) { + fprintf(stderr, "Ring capacity is smaller than expected\n"); + return 1; + } + + if (ring->skip(1)) { + fprintf(stderr, "Successfully skipped in empty RingBuffer\n"); + return 1; + } + + char buf[6] = { 'h', 'e', 'l', 'l', '0', '\0' }; + if (ring->read(1, buf)) { + fprintf(stderr, "Successfully read from empty RingBuffer\n"); + return 1; + } + + ring->write(sizeof(buf), buf); + ring->skip(1); + char buf2[sizeof(buf) - 1]; + ring->read(sizeof(buf2), buf2); + if (strcmp(buf2, buf + 1)) { + fprintf(stderr, "Skip failed\n"); + return 1; + } + + ring->reset(); + if (ring->read_space() != 0) { + fprintf(stderr, "Reset RingBuffer is not empty\n"); + return 1; + } + + for (uint32_t i = 0; i < ring->capacity(); ++i) { + const char c = 'X'; + if (ring->write(1, &c) != 1) { + fprintf(stderr, "Write failed\n"); + return 1; + } + } + + if (ring->write_space() != 0) { + fprintf(stderr, "Ring is not full as expected\n"); + return 1; + } + + if (ring->write(1, buf) != 0) { + fprintf(stderr, "Successfully wrote to full RingBuffer\n"); + return 1; + } + + if (ring->peek(1, buf2) != 1 || buf2[0] != 'X') { + fprintf(stderr, "Failed to read from full RingBuffer\n"); + return 1; + } + + ring->reset(); + + std::thread reader_thread(reader, std::ref(ctx)); + std::thread writer_thread(writer, std::ref(ctx)); + + reader_thread.join(); + writer_thread.join(); + + if (ctx.ring_errors) { + fprintf(stderr, "FAIL: Error occurred\n"); + return 1; + } + + return 0; +} diff --git a/test/sem_test.cpp b/test/sem_test.cpp new file mode 100644 index 0000000..3830604 --- /dev/null +++ b/test/sem_test.cpp @@ -0,0 +1,72 @@ +/* + This file is part of Raul. + Copyright 2007-2017 David Robillard <http://drobilla.net> + + Raul is free software: you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation, either version 3 of the License, or any later version. + + Raul 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Raul. If not, see <http://www.gnu.org/licenses/>. +*/ + +#undef NDEBUG + +#include "raul/Semaphore.hpp" + +#include <cassert> +#include <chrono> +#include <thread> + +static void +wait_for_sem(Raul::Semaphore* sem) +{ + sem->wait(); +} + +static void +timed_wait_for_sem(Raul::Semaphore* sem) +{ + while (!sem->timed_wait(std::chrono::milliseconds(100))) {} +} + +int +main() +{ + Raul::Semaphore sem(0); + assert(!sem.try_wait()); + + // Check that semaphore wakes up strict waiter + std::thread waiter(wait_for_sem, &sem); + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + sem.post(); + waiter.join(); + + // Check that semaphore wakes up timed waiter + std::thread timed_waiter(timed_wait_for_sem, &sem); + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + sem.post(); + timed_waiter.join(); + + // Check that timed_wait actually waits + const auto start = std::chrono::steady_clock::now(); + sem.timed_wait(std::chrono::milliseconds(100)); + const auto end = std::chrono::steady_clock::now(); + assert(end - start > std::chrono::milliseconds(80)); + assert(end - start < std::chrono::milliseconds(200)); + + // Check that we can't successfully wait on a zero semaphore + assert(!sem.timed_wait(std::chrono::milliseconds(100))); + + // Check that initial value works correctly + Raul::Semaphore sem2(2); + assert(sem2.wait()); + assert(sem2.wait()); + assert(!sem2.try_wait()); + + return 0; +} diff --git a/test/socket_test.cpp b/test/socket_test.cpp new file mode 100644 index 0000000..9208dc3 --- /dev/null +++ b/test/socket_test.cpp @@ -0,0 +1,116 @@ +/* + This file is part of Raul. + Copyright 2007-2014 David Robillard <http://drobilla.net> + + Raul is free software: you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation, either version 3 of the License, or any later version. + + Raul 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Raul. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include "raul/Socket.hpp" + +#include <poll.h> +#include <sys/wait.h> +#include <unistd.h> + +#include <cerrno> +#include <cstdio> +#include <cstring> +#include <memory> +#include <string> +#include <utility> + +int +main() +{ + using Socket = Raul::Socket; + + std::string unix_uri("unix:///tmp/raul_test_sock"); + std::string tcp_uri("tcp://127.0.0.1:12345"); + + Socket unix_server_sock(Socket::Type::UNIX); + Socket tcp_server_sock(Socket::Type::TCP); + if (!unix_server_sock.bind(unix_uri)) { + fprintf(stderr, "Failed to bind UNIX server socket (%s)\n", + strerror(errno)); + return 1; + } else if (!unix_server_sock.listen()) { + fprintf(stderr, "Failed to listen on UNIX server socket (%s)\n", + strerror(errno)); + return 1; + } else if (!tcp_server_sock.bind(tcp_uri)) { + fprintf(stderr, "Failed to bind TCP server socket (%s)\n", + strerror(errno)); + return 1; + } else if (!tcp_server_sock.listen()) { + fprintf(stderr, "Failed to listen on TCP server socket (%s)\n", + strerror(errno)); + return 1; + } + + const pid_t child_pid = fork(); + if (child_pid) { + // This is the parent (server) process + int status = 0; + waitpid(child_pid, &status, 0); + + struct pollfd pfds[2]; + pfds[0].fd = unix_server_sock.fd(); + pfds[0].events = POLLIN; + pfds[0].revents = 0; + pfds[1].fd = tcp_server_sock.fd(); + pfds[1].events = POLLIN; + pfds[1].revents = 0; + + unsigned n_received = 0; + while (n_received < 2) { + const int ret = poll(pfds, 2, -1); + if (ret == -1) { + fprintf(stderr, "poll error (%s)\n", strerror(errno)); + break; + } else if ((pfds[0].revents & POLLHUP) || pfds[1].revents & POLLHUP) { + break; + } else if (ret == 0) { + fprintf(stderr, "poll returned with no data\n"); + continue; + } + + if (pfds[0].revents & POLLIN) { + std::shared_ptr<Socket> conn = unix_server_sock.accept(); + ++n_received; + } + + if (pfds[1].revents & POLLIN) { + std::shared_ptr<Socket> conn = tcp_server_sock.accept(); + ++n_received; + } + } + + unix_server_sock.shutdown(); + tcp_server_sock.shutdown(); + unlink("/tmp/raul_test_sock"); + fprintf(stderr, "n received: %d\n", n_received); + return n_received != 2; + } + + // This is the child (client) process + Raul::Socket unix_sock(Socket::Type::UNIX); + Raul::Socket tcp_sock(Socket::Type::TCP); + + if (!unix_sock.connect(unix_uri)) { + fprintf(stderr, "Failed to connect to UNIX socket\n"); + return 1; + } else if (!tcp_sock.connect(tcp_uri)) { + fprintf(stderr, "Failed to connect to TCP socket\n"); + return 1; + } + + return 0; +} diff --git a/test/symbol_test.cpp b/test/symbol_test.cpp new file mode 100644 index 0000000..4af598b --- /dev/null +++ b/test/symbol_test.cpp @@ -0,0 +1,75 @@ +/* + This file is part of Raul. + Copyright 2007-2012 David Robillard <http://drobilla.net> + + Raul is free software: you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation, either version 3 of the License, or any later version. + + Raul 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Raul. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include "raul/Symbol.hpp" + +#include <iostream> +#include <list> +#include <string> + +int +main() +{ + using Symbol = Raul::Symbol; + +#define CHECK(cond) \ + do { if (!(cond)) { \ + std::cerr << "Test failed: " << (cond) << std::endl; \ + return 1; \ + } } while (0) + + std::list<std::string> names; + names.emplace_back("Dry/Wet Balance"); + names.emplace_back("foo+1bar(baz)"); + names.emplace_back("ThisCRAR"); + names.emplace_back("NAME"); + names.emplace_back("thing with a bunch of spaces"); + names.emplace_back("thing-with-a-bunch-of-dashes"); + names.emplace_back("CamelCaseABC"); + names.emplace_back("Signal Level [dB]"); + names.emplace_back("Gain dB"); + names.emplace_back("Dry/Wet Balance"); + names.emplace_back("Phaser1 - Similar to CSound's phaser1 by Sean Costello"); + names.emplace_back("1"); + names.emplace_back(""); + + for (const auto& name : names) { + CHECK(!Symbol::symbolify(name).empty()); + } + + Symbol original("sym"); + CHECK(original == Symbol(original)); + + bool valid = true; + try { + Symbol symbol("0startswithdigit"); + } catch (const Symbol::BadSymbol& e) { + std::cerr << "Caught exception: " << e.what() << std::endl; + valid = false; + } + CHECK(!valid); + + valid = true; + try { + Symbol symbol(std::string("invalid/symbol")); + } catch (const Symbol::BadSymbol& e) { + std::cerr << "Caught exception: " << e.what() << std::endl; + valid = false; + } + CHECK(!valid); + + return 0; +} diff --git a/test/thread_test.cpp b/test/thread_test.cpp new file mode 100644 index 0000000..72ba93f --- /dev/null +++ b/test/thread_test.cpp @@ -0,0 +1,68 @@ +/* + This file is part of Raul. + Copyright 2007-2017 David Robillard <http://drobilla.net> + + Raul is free software: you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation, either version 3 of the License, or any later version. + + Raul 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Raul. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include "raul/Semaphore.hpp" + +#include <atomic> +#include <iostream> +#include <thread> + +namespace { + +using Semaphore = Raul::Semaphore; + +thread_local int var(0); +std::atomic<int> n_errors(0); + +void +wait_for_sem(Semaphore* sem) +{ + var = 41; + std::cout << "[Waiter] Waiting for signal..." << std::endl; + sem->wait(); + std::cout << "[Waiter] Received signal, exiting" << std::endl; + var = 42; + if (var != 42) { + std::cerr << "[Waiter] var != 42" << std::endl; + ++n_errors; + } +} + +} // namespace + +int +main() +{ + Semaphore sem(0); + std::thread waiter(wait_for_sem, &sem); + + var = 24; + + std::cout << "[Main] Signalling..." << std::endl; + sem.post(); + + std::cout << "[Main] Waiting for waiter..." << std::endl; + waiter.join(); + + std::cout << "[Main] Exiting" << std::endl; + + if (var != 24) { + std::cerr << "[Main] var != 24" << std::endl; + ++n_errors; + } + + return n_errors.load(); +} diff --git a/test/time_test.cpp b/test/time_test.cpp new file mode 100644 index 0000000..4b72feb --- /dev/null +++ b/test/time_test.cpp @@ -0,0 +1,46 @@ +/* + This file is part of Raul. + Copyright 2007-2015 David Robillard <http://drobilla.net> + + Raul is free software: you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation, either version 3 of the License, or any later version. + + Raul 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Raul. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include "raul/TimeStamp.hpp" +#include "raul/TimeSlice.hpp" + +#include <cstdint> +#include <iostream> + +int +main() +{ + Raul::TimeUnit unit(Raul::TimeUnit::BEATS, 19200); + Raul::TimeSlice ts(48000, 19200, 120.0); + + double in_double = 2.5; + + Raul::TimeStamp t(unit, + static_cast<uint32_t>(in_double), + static_cast<uint32_t>( + (in_double - static_cast<uint32_t>(in_double)) * + unit.ppt())); + + std::cout << "\tSeconds: "; + std::cout << ts.beats_to_seconds(t); + std::cout << std::endl; + + std::cout << "\tTicks: "; + std::cout << ts.beats_to_ticks(t); + std::cout << std::endl; + + return 0; +} |