diff options
author | David Robillard <d@drobilla.net> | 2010-01-07 21:27:39 +0000 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2010-01-07 21:27:39 +0000 |
commit | 0d009a4e980e40dc8a9c9b5e3d25c3fafb363e95 (patch) | |
tree | 4d41dea009f1647519af8df10f114cd7a6165792 /test | |
parent | 61ac4a41f0aea63f45d7b27be3ef2e0554e93ece (diff) | |
download | raul-0d009a4e980e40dc8a9c9b5e3d25c3fafb363e95.tar.gz raul-0d009a4e980e40dc8a9c9b5e3d25c3fafb363e95.tar.bz2 raul-0d009a4e980e40dc8a9c9b5e3d25c3fafb363e95.zip |
Move unit testing and coverage framework into autowaf.
Make raul tests return 0 on success, 1 on failure.
Test coverage for Raul.
git-svn-id: http://svn.drobilla.net/lad/trunk/raul@2368 a436a847-0d15-0410-975c-d299462d15a1
Diffstat (limited to 'test')
-rw-r--r-- | test/atomic_test.cpp | 14 | ||||
-rw-r--r-- | test/list_test.cpp | 141 | ||||
-rw-r--r-- | test/midi_ringbuffer_test.cpp | 43 | ||||
-rw-r--r-- | test/path_test.cpp | 68 | ||||
-rw-r--r-- | test/quantize_test.cpp | 25 | ||||
-rw-r--r-- | test/queue_test.cpp | 254 | ||||
-rw-r--r-- | test/ringbuffer_test.cpp | 47 | ||||
-rw-r--r-- | test/smf_test.cpp | 62 | ||||
-rw-r--r-- | test/table_test.cpp | 379 | ||||
-rw-r--r-- | test/thread_test.cpp | 19 | ||||
-rw-r--r-- | test/time_test.cpp | 32 |
11 files changed, 1084 insertions, 0 deletions
diff --git a/test/atomic_test.cpp b/test/atomic_test.cpp new file mode 100644 index 0000000..6611c91 --- /dev/null +++ b/test/atomic_test.cpp @@ -0,0 +1,14 @@ +#include <iostream> +#include "raul/AtomicInt.hpp" +#include "raul/AtomicPtr.hpp" + +using namespace std; +using namespace Raul; + +int +main() +{ + cout << "Well, at least I compiled; that's gotta count for something eh?" << endl; + + return 0; +} diff --git a/test/list_test.cpp b/test/list_test.cpp new file mode 100644 index 0000000..664ca5b --- /dev/null +++ b/test/list_test.cpp @@ -0,0 +1,141 @@ +#include <iostream> +#include <cstddef> +#include "raul/log.hpp" +#include "raul/List.hpp" + +using namespace std; +using namespace Raul; + +int +main() +{ +#define CHECK(cond) \ + do { if (!(cond)) { \ + error << "Test at " << __FILE__ << ":" << __LINE__ << " failed: " << __STRING(cond) << endl; \ + return 1; \ + } } while (0) + + List<int> l; + + l.push_back(new List<int>::Node(1)); + l.push_back(new List<int>::Node(2)); + l.push_back(new List<int>::Node(3)); + l.push_back(new List<int>::Node(4)); + l.push_back(new List<int>::Node(5)); + l.push_back(new List<int>::Node(6)); + l.push_back(new List<int>::Node(7)); + l.push_back(new List<int>::Node(8)); + + /*cout << "List:" << endl; + for (List<int>::iterator i = l.begin(); i != l.end(); ++i) { + cout << *i << endl; + } + cout << endl;*/ + + // Remove 4 + for (List<int>::iterator i = l.begin(); i != l.end(); ++i) { + if ((*i) == 4) { + l.erase(i); + break; + } + } + + // Check + int idx = 0; + for (List<int>::iterator i = l.begin(); i != l.end(); ++i, ++idx) { + if (idx < 3) + CHECK(*i == idx + 1); + else + CHECK(*i == idx + 2); + } + + // Remove 1 (head) + for (List<int>::iterator i = l.begin(); i != l.end(); ++i) { + if ((*i) == 1) { + l.erase(i); + break; + } + } + + // Check + idx = 0; + for (List<int>::iterator i = l.begin(); i != l.end(); ++i, ++idx) { + if (idx < 2) + CHECK(*i == idx + 2); + else + CHECK(*i == idx + 3); + } + + // Remove 8 (tail) + for (List<int>::iterator i = l.begin(); i != l.end(); ++i) { + if ((*i) == 8) { + l.erase(i); + break; + } + } + + // Check + idx = 0; + for (List<int>::iterator i = l.begin(); i != l.end(); ++i, ++idx) { + if (idx < 2) + CHECK(*i == idx + 2); + else if (idx < 4) + CHECK(*i == idx + 3); + else + CHECK(*i == 7); + } + + // Create, push, erase (should get empty list) + List<int> r; + r.push_back(new List<int>::Node(9)); + r.erase(r.begin()); + CHECK(r.size() == 0); + CHECK(r.empty()); + + // Appending to an empty list + l.clear(); + CHECK(l.size() == 0); + CHECK(l.empty()); + + List<int> l2; + l2.push_back(new List<int>::Node(0)); + l2.push_back(new List<int>::Node(2)); + l2.push_back(new List<int>::Node(4)); + l2.push_back(new List<int>::Node(6)); + + l.append(l2); + idx = 0; + for (List<int>::iterator i = l.begin(); i != l.end(); ++i, ++idx) { + CHECK(*i == idx * 2); + } + + // Appending non-empty lists + l2.push_back(new List<int>::Node(5)); + l2.push_back(new List<int>::Node(6)); + l2.push_back(new List<int>::Node(7)); + l2.push_back(new List<int>::Node(8)); + + l.append(l2); + idx = 0; + for (List<int>::iterator i = l.begin(); i != l.end(); ++i, ++idx) { + if (idx < 4) + CHECK(*i == idx * 2); + else + CHECK(*i == idx + 1); + } + + + // Appending an empty list + l2.clear(); + l.append(l2); + + idx = 0; + for (List<int>::iterator i = l.begin(); i != l.end(); ++i, ++idx) { + if (idx < 4) + CHECK(*i == idx * 2); + else + CHECK(*i == idx + 1); + } + + return 0; +} diff --git a/test/midi_ringbuffer_test.cpp b/test/midi_ringbuffer_test.cpp new file mode 100644 index 0000000..f75cfd5 --- /dev/null +++ b/test/midi_ringbuffer_test.cpp @@ -0,0 +1,43 @@ +#include <iostream> +#include <cstring> +#include <cstdio> +#include <stdio.h> +#include "raul/TimeStamp.hpp" +#include "raul/EventRingBuffer.hpp" +#include "raul/midi_names.h" + +using namespace std; +using namespace Raul; + +int +read_write_test(EventRingBuffer& rb, unsigned offset) +{ + TimeStamp t(TimeUnit(TimeUnit::FRAMES, 48000), 0, 0); + size_t size; + unsigned char write_buf[5]; + unsigned char read_buf[5]; + + snprintf((char*)write_buf, 5, "%d", offset); + size = strlen((char*)write_buf); + + const size_t written = rb.write(t, size, write_buf); + assert(written == size); + + rb.read(&t, &size, read_buf); + + return (strncmp((const char*)write_buf, (const char*)read_buf, size)); +} + + +int +main() +{ + EventRingBuffer rb(32); + + for (size_t i = 0; i < 1000000; ++i) + if (read_write_test(rb, i)) + return 1; + + return 0; +} + diff --git a/test/path_test.cpp b/test/path_test.cpp new file mode 100644 index 0000000..099b463 --- /dev/null +++ b/test/path_test.cpp @@ -0,0 +1,68 @@ +#include <iostream> +#include <list> +#include "raul/log.hpp" +#include "raul/Path.hpp" + +using namespace std; +using namespace Raul; + +int +main() +{ +#define CHECK(cond) \ + do { if (!(cond)) { \ + error << "Test failed: " << (cond) << endl; \ + return 1; \ + } } while (0) + + list<string> names; + names.push_back("Dry/Wet Balance"); + names.push_back("foo+1bar(baz)"); + names.push_back("ThisCRAR"); + names.push_back("NAME"); + names.push_back("thing with a bunch of spaces"); + names.push_back("thing-with-a-bunch-of-dashes"); + names.push_back("CamelCaseABC"); + names.push_back("Signal Level [dB]"); + names.push_back("Gain dB"); + names.push_back("Dry/Wet Balance"); + names.push_back("Phaser1 - Similar to CSound's phaser1 by Sean Costello"); + + for (list<string>::iterator i = names.begin(); i != names.end(); ++i) { + CHECK(Symbol::is_valid(Path::nameify(*i))); + CHECK(Symbol::is_valid(Symbol::symbolify(*i))); + } + + 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::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("/", "/foo")); + CHECK(Path::descendant_comparator("/foo", "/foo/bar")); + CHECK(Path::descendant_comparator("/foo", "/foo")); + CHECK(Path::descendant_comparator("/", "/")); + CHECK(!Path::descendant_comparator("/baz", "/")); + CHECK(!Path::descendant_comparator("/foo", "/bar")); + CHECK(!Path::descendant_comparator("/foo/bar", "/foo")); + + CHECK(!Symbol::is_valid("")); + CHECK(!Symbol::is_valid("/I/have/slashes")); + CHECK(!Symbol::is_valid("!illegalchar")); + CHECK(!Symbol::is_valid("0illegalleadingdigit")); + CHECK(Symbol::is_valid(Symbol::symbolify(""))); + CHECK(Symbol::is_valid(Symbol::symbolify("1hello"))); + + return 0; +} diff --git a/test/quantize_test.cpp b/test/quantize_test.cpp new file mode 100644 index 0000000..39ba899 --- /dev/null +++ b/test/quantize_test.cpp @@ -0,0 +1,25 @@ +#include "raul/Quantizer.hpp" +#include <iostream> + +using namespace std; +using namespace Raul; + + +int +main() +{ + TimeStamp q(TimeUnit(TimeUnit::BEATS, 19200), 0.25); + + for (double in = 0.0; in < 32; in += 0.23) { + TimeStamp beats(TimeUnit(TimeUnit::BEATS, 19200), in); + + cout << "Q(" << in << ", 1/4) = " + << Quantizer::quantize(q, beats) << endl; + + if (Quantizer::quantize(q, beats).subticks() % (19200/4) != 0) + return 1; + } + + return 0; +} + diff --git a/test/queue_test.cpp b/test/queue_test.cpp new file mode 100644 index 0000000..49ba6f2 --- /dev/null +++ b/test/queue_test.cpp @@ -0,0 +1,254 @@ +#include <iostream> +#include <string> +#include <vector> +#include <algorithm> +#include <stdio.h> +#include <stdlib.h> +#include "raul/SRSWQueue.hpp" +#include "raul/SRMWQueue.hpp" +#include "raul/Thread.hpp" +#include "raul/AtomicInt.hpp" + +using namespace std; +using namespace Raul; + +static const unsigned NUM_DATA = 10; +static const unsigned QUEUE_SIZE = 128; +static const unsigned NUM_WRITERS = 2; +static const unsigned PUSHES_PER_ITERATION = 3; + +// Data to read/write using actions pumped through the queue +struct Record { + Record() : read_count(0), write_count(0) {} + + AtomicInt read_count; + AtomicInt write_count; +}; + +Record data[NUM_DATA]; + + +// Actions pumped through the queue to manipulate data +struct WriteAction { + WriteAction(unsigned idx) : index(idx) {} + + inline void read() const { + ++(data[index].read_count); + }; + + unsigned index; +}; + + +// The victim +SRMWQueue<WriteAction> queue(QUEUE_SIZE); + + +class WriteThread : public Thread { +protected: + void _run() { + // Wait for everything to get ready + sleep(1); + + while (true) { + for (unsigned j=0; j < PUSHES_PER_ITERATION; ++j) { + unsigned i = rand() % NUM_DATA; + if (queue.push(WriteAction(i))) { + ++(data[i].write_count); + //cout << "WRITE " << i << "\r\n"; + } else { + //cerr << "FAILED WRITE\r\n"; + } + } + + // This thread will never cancel without this here since + // this loop is hard RT safe and thus cancellation point free + pthread_testcancel(); + } + + cout << "Writer exiting." << endl; + } +}; + + +// Returns 0 if all read count/write count pairs are equal, +// otherwise how far off total count was +unsigned +data_is_sane() +{ + unsigned ret = 0; + for (unsigned i = 0; i < NUM_DATA; ++i) { + unsigned diff = abs(data[i].read_count.get() - data[i].write_count.get()); + ret += diff; + } + + return ret; +} + + +void +dump_data() +{ + for (unsigned i = 0; i < NUM_DATA; ++i) { + cout << i << ":\t" << data[i].read_count.get() + << "\t : \t" << data[i].write_count.get(); + if (data[i].read_count.get() == data[i].write_count.get()) + cout << "\t OK" << endl; + else + cout << "\t FAIL" << endl; + } +} + + +int +main() +{ + unsigned long total_processed = 0; + + cout << "Testing size" << endl; + for (unsigned i=0; i < queue.capacity(); ++i) { + queue.push(i); + if (i == queue.capacity()-1) { + if (!queue.full()) { + cerr << "ERROR: Should be full at " << i + << " (size " << queue.capacity() << ")" << endl; + return -1; + } + } else { + if (queue.full()) { + cerr << "ERROR: Prematurely full at " << i + << " (size " << queue.capacity() << ")" << endl; + return -1; + } + } + } + + for (unsigned i = 0; i < queue.capacity(); ++i) + queue.pop(); + + if (!queue.empty()) { + cerr << "ERROR: Should be empty" << endl; + return -1; + } + + cout << "Testing concurrent reading/writing" << endl; + vector<WriteThread*> writers(NUM_WRITERS, new WriteThread()); + + for (unsigned i=0; i < NUM_WRITERS; ++i) { + writers[i]->set_name(string("Writer ") + (char)('0' + i)); + writers[i]->start(); + } + + sleep(1); + + // Read + unsigned count = 0; + for (unsigned i = 0; i < 10000000; ++i) { + while (count < queue.capacity() && !queue.empty()) { + WriteAction action = queue.front(); + queue.pop(); + action.read(); + ++count; + ++total_processed; + } + + /*if (count > 0) + cout << "Processed " << count << " requests\t\t" + << "(total " << total_processed << ")\r\n"; + + if (total_processed > 0 && total_processed % 128l == 0) + cout << "Total processed: " << total_processed << "\r\n";*/ + } + + cout << "Processed " << total_processed << " requests" << endl; + + // Stop the writers + for (unsigned i=0; i < NUM_WRITERS; ++i) + writers[i]->stop(); + + //cout << "\n\n****************** DONE *********************\n\n"; + + unsigned leftovers = 0; + + // Drain anything left in the queue + while (!queue.empty()) { + WriteAction action = queue.front(); + queue.pop(); + action.read(); + leftovers++; + ++total_processed; + } + + if (leftovers > 0) + cout << "Processed " << leftovers << " leftovers." << endl; + + + //cout << "\n\n*********************************************\n\n"; + + cout << "Total processed: " << total_processed << endl; + if (total_processed > INT_MAX) + cout << "(Counter had to wrap)" << endl; + else + cout << "(Counter did NOT have to wrap)" << endl; + + + const unsigned diff = data_is_sane(); + + if (diff == 0) { + return EXIT_SUCCESS; + } else { + cout << "FAILED BY " << diff << endl; + return EXIT_FAILURE; + } + + //dump_data(); + + return 0; +} + + +#if 0 +int main() +{ + //SRSWQueue<int> q(10); + SRMWQueue<int> q(10); + + cout << "New queue. Should be empty: " << q.empty() << endl; + cout << "Capacity: " << q.capacity() << endl; + //cout << "Fill: " << q.fill() << endl; + + for (uint i=0; i < 5; ++i) { + q.push(i); + assert(!q.full()); + q.pop(); + } + cout << "Pushed and popped 5 elements. Queue should be empty: " << q.empty() << endl; + //cout << "Fill: " << q.fill() << endl; + + for (uint i=10; i < 20; ++i) { + assert(q.push(i)); + } + cout << "Pushed 10 elements. Queue should be full: " << q.full() << endl; + //cout << "Fill: " << q.fill() << endl; + + cout << "The digits 10->19 should print: " << endl; + while (!q.empty()) { + int foo = q.front(); + q.pop(); + cout << "Popped: " << foo << endl; + } + cout << "Queue should be empty: " << q.empty() << endl; + //cout << "Fill: " << q.fill() << endl; + + cout << "Attempting to add eleven elements to queue of size 10. Only first 10 should succeed:" << endl; + for (uint i=20; i <= 39; ++i) { + cout << i; + //cout << " - Fill: " << q.fill(); + cout << " - full: " << q.full(); + cout << ", succeeded: " << q.push(i) << endl; + } + + return 0; +} +#endif + diff --git a/test/ringbuffer_test.cpp b/test/ringbuffer_test.cpp new file mode 100644 index 0000000..87b81c6 --- /dev/null +++ b/test/ringbuffer_test.cpp @@ -0,0 +1,47 @@ +#include <iostream> +#include <cstring> +#include "raul/RingBuffer.hpp" + +using namespace std; +using namespace Raul; + +void +print_buf(size_t size, char* buf) +{ + cout << "{ "; + for (size_t i=0; i < size; ++i) { + cout << buf[i]; + if (i < size-1) + cout << ", "; + } + + cout << " }" << endl; +} + + +int +main() +{ + RingBuffer<char> rb(5); + + char ev[] = { 'a', 'b', 'c' }; + + rb.write(3, ev); + + char buf[3]; + rb.read(3, buf); + print_buf(3, buf); + + char ev2[] = { 'd', 'e', 'f' }; + rb.write(3, ev2); + + + size_t read = rb.read(3, buf); + if (read < 3) + rb.read(3 - read, buf + read); + + print_buf(3, buf); + + return 0; +} + diff --git a/test/smf_test.cpp b/test/smf_test.cpp new file mode 100644 index 0000000..40465ed --- /dev/null +++ b/test/smf_test.cpp @@ -0,0 +1,62 @@ +#include <iostream> +#include <string> +#include "raul/SMFReader.hpp" +#include "raul/SMFWriter.hpp" + +using namespace std; +using namespace Raul; + + +int +main(int argc, char** argv) +{ + const char* filename = NULL; + + if (argc < 2) { + filename = "./test.mid"; + SMFWriter writer(TimeUnit(TimeUnit::BEATS, 19200)); + writer.start(string(filename), TimeStamp(writer.unit(), 0, 0)); + writer.finish(); + cout << "Wrote " << filename << " with PPQN = " << writer.unit().ppt() << endl; + + } else { + filename = argv[1]; + } + + + SMFReader reader; + bool opened = reader.open(filename); + + if (!opened) { + cerr << "Unable to open SMF file " << filename << endl; + return -1; + } + + cout << "Opened SMF file " << filename << endl; + + cout << "Type: " << reader.type() << endl; + cout << "Num tracks: " << reader.num_tracks() << endl; + cout << "PPQN: " << reader.ppqn() << endl; + + for (unsigned t=1; t <= reader.num_tracks(); ++t) { + cout << "******** Track " << t << " ********" << endl; + reader.seek_to_track(t); + + unsigned char buf[4]; + uint32_t ev_size; + uint32_t ev_delta_time; + while (reader.read_event(4, buf, &ev_size, &ev_delta_time) >= 0) { + + cout << "Event, size = " << ev_size << ", time = " << ev_delta_time; + cout << ":\t"; + cout.flags(ios::hex); + for (uint32_t i=0; i < ev_size; ++i) { + cout << "0x" << (int)buf[i] << " "; + } + cout.flags(ios::dec); + cout << endl; + } + } + + return 0; +} diff --git a/test/table_test.cpp b/test/table_test.cpp new file mode 100644 index 0000000..882873a --- /dev/null +++ b/test/table_test.cpp @@ -0,0 +1,379 @@ +#include <string> +#include <iostream> +#include <utility> +#include <map> +#include <set> +#include <sys/time.h> +#include "raul/PathTable.hpp" +#include "raul/Table.hpp" +#include "raul/TableImpl.hpp" + +//#define WITH_TR1 1 + +#ifdef WITH_TR1 + #define BOOST_MULTI_INDEX_DISABLE_SERIALIZATION 1 + #include <boost/functional/hash.hpp> + #include <tr1/unordered_map> +#endif + +using namespace Raul; +using namespace std; + +int range_end_val; + +bool range_comparator(const int& a, const int& b) +{ + bool ret = (b >= a && b <= range_end_val); + //cout << "COMP: " << a << " . " << b << " = " << ret << endl; + return ret; +} + +void benchmark(size_t n); + +int +main(int argc, char** argv) +{ + if (argc == 3 && !strcmp(argv[1], "-b")) { + benchmark(atoi(argv[2])); + return 0; + } + + cout << "run with -b num_elems to benchmark" << endl; + srand(time(NULL)); + + range_end_val = rand()%10; + + Table<int, int> t; + for (size_t i=0; i < 20; ++i) { + int val = rand()%10; + t.insert(make_pair(val, val)); + } + + t[20] = 20; + t[21] = 21; + + cout << "Contents:" << endl; + for (Table<int,int>::const_iterator i = t.begin(); i != t.end(); ++i) + cout << i->first << " "; + cout << endl; + + std::cout << "Range " << t.begin()->first << " .. " << range_end_val << std::endl; + + Table<int,int>::const_iterator range_begin = t.begin(); + ++range_begin; ++range_begin; + + Table<int,int>::iterator range_end = t.find_range_end(t.begin(), range_comparator); + + for (Table<int,int>::const_iterator i = t.begin(); i != range_end; ++i) + cout << i->first << " "; + cout << endl; + + Table<int, int>::iterator first = t.begin(); + ++first; + Table<int, int>::iterator last = first; + ++last; ++last; ++last; + + cout << "Erasing elements 1..3:" << endl; + t.erase(first, last); + + for (Table<int,int>::const_iterator i = t.begin(); i != t.end(); ++i) + cout << i->first << " "; + cout << endl; + + cout << "Erasing elements 0..3" << endl; + first = t.begin(); + last = first; + ++last; ++last; ++last; + t.erase(first, last); + + for (Table<int,int>::const_iterator i = t.begin(); i != t.end(); ++i) + cout << i->first << " "; + cout << endl; + + cout << "Erasing elements end()-2..end()" << endl; + last = t.end(); + first = last; + --first; --first; + t.erase(first, last); + + for (Table<int,int>::const_iterator i = t.begin(); i != t.end(); ++i) + cout << i->first << " "; + cout << endl; + + cout << "Erasing everything" << endl; + first = t.begin(); + last = t.end(); + t.erase(first, last); + + for (Table<int,int>::const_iterator i = t.begin(); i != t.end(); ++i) + cout << i->first << " "; + cout << endl; + + /* **** */ + + PathTable<char> pt; + pt.insert(make_pair("/foo", 'a')); + pt.insert(make_pair("/bar", 'a')); + pt.insert(make_pair("/bar/baz", 'b')); + pt.insert(make_pair("/bar/bazz/NO", 'c')); + pt.insert(make_pair("/bar/baz/YEEEAH", 'c')); + pt.insert(make_pair("/bar/baz/YEEEAH/BOOOEEEEE", 'c')); + pt.insert(make_pair("/bar/buzz", 'b')); + pt.insert(make_pair("/bar/buzz/WHAT", 'c')); + pt.insert(make_pair("/bar/buzz/WHHHhhhhhAT", 'c')); + pt.insert(make_pair("/quux", 'a')); + + cout << "Paths: " << endl; + for (PathTable<char>::const_iterator i = pt.begin(); i != pt.end(); ++i) + cout << i->first << " "; + cout << endl; + + PathTable<char>::const_iterator descendants_begin = pt.begin(); + size_t begin_index = rand() % pt.size(); + for (size_t i=0; i < begin_index; ++i) + ++descendants_begin; + + cout << "\nDescendants of " << descendants_begin->first << endl; + PathTable<char>::const_iterator descendants_end = pt.find_descendants_end(descendants_begin); + + for (PathTable<char>::const_iterator i = pt.begin(); i != descendants_end; ++i) + cout << i->first << " "; + cout << endl; + + const Path yank_path("/bar"); + PathTable<char>::iterator quux = pt.find(yank_path); + assert(quux != pt.end()); + PathTable<char>::iterator quux_end = pt.find_descendants_end(quux ); + assert(quux_end != quux); + + SharedPtr< Table<Path,char> > yanked = pt.yank(quux, quux_end); + + cout << "Yanked " << yank_path << endl; + for (PathTable<char>::const_iterator i = pt.begin(); i != pt.end(); ++i) + cout << i->first << " "; + cout << endl; + + pt.cram(*yanked.get()); + + cout << "Crammed " << yank_path << endl; + for (PathTable<char>::const_iterator i = pt.begin(); i != pt.end(); ++i) + cout << i->first << " "; + cout << endl; + + /* **** */ + + Table<string, string> st; + + st.insert(make_pair("apple", "core")); + st.insert(make_pair("candy", "cane")); + st.insert(make_pair("banana", "peel")); + //st["alpha"] = "zero"; + //st["zeta"] = "one"; + + st.erase("banana"); + + for (Table<int,int>::const_iterator i = t.begin(); i != t.end(); ++i) + cout << i->first << " "; + cout << endl; + + for (int i = 0; i < 1000; ++i) { + Table<int, int> t; + + size_t table_size = (rand() % 1000) + 1; + + for (size_t i=0; i < table_size; ++i) { + int val = rand()%100; + t.insert(make_pair(val, ((val + 3) * 17))); + } + + for (int i=0; i < (int)table_size; ++i) { + int val = rand()%100; + Table<int, int>::iterator iter = t.find(val); + assert(iter == t.end() || iter->second == (val + 3) * 17); + } + + /*cout << "CONTENTS:" << endl; + + for (Table<int,int>::const_iterator i = t.begin(); i != t.end(); ++i) { + cout << i->first << ": " << i->second << endl; + } + + Table<int,int>::iterator i = t.find(7); + if (i != t.end()) + cout << "Find: 7: " << i->second << endl;*/ + } + + return 0; +} + +string +random_string() +{ + string ret(60, 'A' + (rand() % 26)); + return ret; +} + + +void +benchmark(size_t n) +{ + cout << "Benchmarking with n = " << n << endl; + + int useless_accumulator = 0; + + srand(time(NULL)); + + vector<string> values(n); + for (size_t i=0; i < n; ++i) + values.push_back(random_string()); + + timeval t1; + t1.tv_sec=0; + t1.tv_usec=0; + + timeval t2; + t2.tv_sec=0; + t2.tv_usec=0; + + + /** std::map **/ + + std::map<string,int> m; + + gettimeofday(&t1, NULL); + + for (size_t i=0; i < n; ++i) + m.insert(make_pair(values[i], i)); + + gettimeofday(&t2, NULL); + + float delta_t = (t2.tv_sec - t1.tv_sec) + (t2.tv_usec - t1.tv_usec) * 0.000001f; + + cout << "std::map time to insert " << n << " values: \t" << delta_t << endl; + + gettimeofday(&t1, NULL); + + for (size_t i=0; i < n; ++i) + useless_accumulator += m.find(values[i])->second; + + gettimeofday(&t2, NULL); + + delta_t = (t2.tv_sec - t1.tv_sec) + (t2.tv_usec - t1.tv_usec) * 0.000001f; + + cout << "std::map time to lookup " << n << " values: \t" << delta_t << endl; + + + /** std::set **/ + + std::set<std::string> s; + + gettimeofday(&t1, NULL); + + for (size_t i=0; i < n; ++i) + s.insert(values[i]); + + gettimeofday(&t2, NULL); + + delta_t = (t2.tv_sec - t1.tv_sec) + (t2.tv_usec - t1.tv_usec) * 0.000001f; + + cout << "std::set time to insert " << n << " values: \t" << delta_t << endl; + + gettimeofday(&t1, NULL); + + for (size_t i=0; i < n; ++i) + useless_accumulator += (int)(*s.find(values[i]))[0]; + + gettimeofday(&t2, NULL); + + delta_t = (t2.tv_sec - t1.tv_sec) + (t2.tv_usec - t1.tv_usec) * 0.000001f; + + cout << "std::set time to lookup " << n << " values: \t" << delta_t << endl; + + + /** sorted std::vector **/ + + /*std::vector<int> v; + + gettimeofday(&t1, NULL); + + for (size_t i=0; i < n; ++i) + v.push_back(values[i]); + + sort(v.begin(), v.end()); + + gettimeofday(&t2, NULL); + + delta_t = (t2.tv_sec - t1.tv_sec) + (t2.tv_usec - t1.tv_usec) * 0.000001f; + + cout << "std::vector (sorted) time to insert " << n << " values: \t" << delta_t << endl; + + gettimeofday(&t1, NULL); + + for (size_t i=0; i < n; ++i) + useless_accumulator += *lower_bound(v.begin(), v.end(), values[i]); + + gettimeofday(&t2, NULL); + + delta_t = (t2.tv_sec - t1.tv_sec) + (t2.tv_usec - t1.tv_usec) * 0.000001f; + + cout << "std::vector (sorted) time to lookup " << n << " values: \t" << delta_t << endl;*/ + + + /** Raul::Table **/ + + Raul::Table<string,int> t(n); + + gettimeofday(&t1, NULL); + + for (size_t i=0; i < n; ++i) + t.insert(make_pair(values[i], i)); + + gettimeofday(&t2, NULL); + + delta_t = (t2.tv_sec - t1.tv_sec) + (t2.tv_usec - t1.tv_usec) * 0.000001f; + + cout << "Raul::Table time to insert " << n << " values: " << delta_t << endl; + + gettimeofday(&t1, NULL); + + for (size_t i=0; i < n; ++i) + useless_accumulator += t.find(values[i])->second; + + gettimeofday(&t2, NULL); + + delta_t = (t2.tv_sec - t1.tv_sec) + (t2.tv_usec - t1.tv_usec) * 0.000001f; + + cout << "Raul::Table time to lookup " << n << " values: \t" << delta_t << endl; + + +#ifdef WITH_TR1 + /** boost::hash && std::unordered_map **/ + + tr1::unordered_map<string, int, boost::hash<string> > um; + + gettimeofday(&t1, NULL); + + um.rehash(n); + + for (size_t i=0; i < n; ++i) + um.insert(make_pair(values[i], i)); + + gettimeofday(&t2, NULL); + + delta_t = (t2.tv_sec - t1.tv_sec) + (t2.tv_usec - t1.tv_usec) * 0.000001f; + + cout << "tr1::unordered_map + boost::hash time to insert " << n << " values: \t" << delta_t << endl; + + gettimeofday(&t1, NULL); + + for (size_t i=0; i < n; ++i) + useless_accumulator += um.find(values[i])->second; + + gettimeofday(&t2, NULL); + + delta_t = (t2.tv_sec - t1.tv_sec) + (t2.tv_usec - t1.tv_usec) * 0.000001f; + + cout << "tr1::unordered_map + boost::hash time to lookup " << n << " values: \t" << delta_t << endl; +#endif +} + diff --git a/test/thread_test.cpp b/test/thread_test.cpp new file mode 100644 index 0000000..fd7a411 --- /dev/null +++ b/test/thread_test.cpp @@ -0,0 +1,19 @@ +#include <iostream> +#include "raul/Thread.hpp" + +using namespace std; +using namespace Raul; + +int +main() +{ + Thread& this_thread = Thread::get(); + this_thread.set_name("Main"); + + cout << "Thread name should be Main" << endl; + + cout << "Thread name: " << Thread::get().name() << endl; + + return 0; +} + diff --git a/test/time_test.cpp b/test/time_test.cpp new file mode 100644 index 0000000..2b53207 --- /dev/null +++ b/test/time_test.cpp @@ -0,0 +1,32 @@ +#include "raul/TimeStamp.hpp" +#include "raul/TimeSlice.hpp" +#include <iostream> + +using namespace std; +using namespace Raul; + + +int +main() +{ + TimeUnit unit(TimeUnit::BEATS, 19200); + TimeSlice ts(48000, 19200, 120.0); + + double in_double; + cout << "Beats: "; + cin >> in_double; + + TimeStamp t(unit, (uint32_t)in_double, + (uint32_t)((in_double - (uint32_t)in_double) * unit.ppt())); + + cout << "\tSeconds: "; + cout << ts.beats_to_seconds(t); + cout << endl; + + cout << "\tTicks: "; + cout << ts.beats_to_ticks(t); + cout << endl; + + return 0; +} + |