diff options
-rw-r--r-- | server/src/.cvsignore | 3 | ||||
-rw-r--r-- | server/src/Makefile.am | 238 | ||||
-rw-r--r-- | server/src/mutex.cc | 76 | ||||
-rw-r--r-- | server/src/mutex.h | 10 | ||||
-rw-r--r-- | server/src/saxparser.cc | 224 | ||||
-rw-r--r-- | server/src/session.cc | 26 |
6 files changed, 214 insertions, 363 deletions
diff --git a/server/src/.cvsignore b/server/src/.cvsignore index e7654ee..6fa7094 100644 --- a/server/src/.cvsignore +++ b/server/src/.cvsignore @@ -4,4 +4,5 @@ Makefile.in Makefile .libs .deps -test_*
\ No newline at end of file +test_* +tests.make
\ No newline at end of file diff --git a/server/src/Makefile.am b/server/src/Makefile.am index 2daa37e..d3745f7 100644 --- a/server/src/Makefile.am +++ b/server/src/Makefile.am @@ -11,6 +11,7 @@ pracrod_SOURCES = \ database.cc \ configuration.cc \ configurationparser.cc \ + connectionpool.cc \ debug.cc \ exception.cc \ queryhandlerpentominos.cc \ @@ -29,6 +30,7 @@ pracrod_SOURCES = \ pracrodaotest.cc \ resumeparser.cc \ saxparser.cc \ + semaphore.cc \ server.cc \ session.cc \ templatelist.cc \ @@ -71,6 +73,7 @@ macrotool_SOURCES = \ EXTRA_DIST = \ configuration.h \ configurationparser.h \ + connectionpool.h \ daemon.h \ database.h \ dbtypes.h \ @@ -97,6 +100,7 @@ EXTRA_DIST = \ pracrodaotest.h \ resumeparser.h \ saxparser.h \ + semaphore.h \ server.h \ session.h \ templatelist.h \ @@ -113,238 +117,18 @@ EXTRA_DIST = \ # Test Section # ################ -TESTFILES = \ - test_tcpsocket \ - test_pracrodaotest \ - test_widgetgenerator \ - test_configurationparser \ - test_exception \ - test_templateheaderparser \ - test_macroheaderparser \ - test_templatelist \ - test_saxparser \ - test_transactionparser \ - test_versionstr \ - test_macrolist \ - test_queryhandlerpentominos \ - test_queryhandlerpracro \ - test_queryparser \ - test_luaquerymapper \ - test_templateparser \ - test_server \ - test_pracrodaopgsql \ - test_macroparser \ - test_xml_encode_decode \ - test_journal_commit \ - test_session +tests.make: ${pracrod_SOURCES} ${EXTRA_DIST} + ../../tools/testlist > tests.make + @touch Makefile.am -TESTLOGS = `for F in ${TESTFILES}; do echo $$F.log; done` - -BASICFILES = exception.cc log.cc debug.cc configuration.cc utf8.cc -BASICFLAGS = -I.. -DHAVE_CONFIG_H $(CONFIG_CXXFLAGS) $(CONFIG_LIBS) - -PARSERFILES = saxparser.cc -PARSERFLAGS = -lexpat +include tests.make -DBFILES = database.cc pracrodao.cc pracrodaopgsql.cc pracrodaotest.cc mutex.cc -DBFLAGS = $(PQXX_LIBS) $(PQXX_CXXFLAGS) - -test: $(TESTFILES) +test: tests.make $(TESTFILES) @echo "All tests done." test_clean: rm -f $(TESTFILES) $(TESTLOGS) -TEST_SESSION_FILES = \ - session.cc \ - journal_commit.cc \ - templateparser.cc \ - $(PARSERFILES) \ - $(BASICFILES) -test_session: $(TEST_SESSION_FILES) - @../../tools/test $(TEST_SESSION_FILES) $(PARSERFLAGS) $(BASICFLAGS) - -TEST_TCPSOCKET_FILES = \ - tcpsocket.cc \ - $(BASICFILES) -test_tcpsocket: $(TEST_TCPSOCKET_FILES) - @../../tools/test $(TEST_TCPSOCKET_FILES) $(BASICFLAGS) - -TEST_PRACRODAOTEST_FILES = \ - pracrodaotest.cc \ - pracrodao.cc \ - $(BASICFILES) -test_pracrodaotest: $(TEST_PRACRODAOTEST_FILES) - @../../tools/test $(TEST_PRACRODAOTEST_FILES) $(BASICFLAGS) - -TEST_WIDGETGENERATOR_FILES = \ - widgetgenerator.cc \ - xml_encode_decode.cc \ - luaquerymapper.cc \ - $(BASICFILES) \ - $(DBFILES) -test_widgetgenerator: $(TEST_WIDGETGENERATOR_FILES) - @../../tools/test $(TEST_WIDGETGENERATOR_FILES) $(BASICFLAGS) $(LUA_LIBS) $(DBFLAGS) - -TEST_CONFIGURATIONPARSER_FILES = \ - configurationparser.cc \ - configuration.cc \ - exception.cc \ - log.cc -test_configurationparser: $(TEST_CONFIGURATIONPARSER_FILES) - @../../tools/test $(TEST_CONFIGURATIONPARSER_FILES) $(BASICFLAGS) - -TEST_EXCEPTION_FILES = \ - exception.cc \ - log.cc -test_exception: $(TEST_EXCEPTION_FILES) - @../../tools/test $(TEST_EXCEPTION_FILES) - -TEST_TEMPLATEHEADERPARSER_FILES = \ - templateheaderparser.cc \ - $(PARSERFILES) \ - $(BASICFILES) -test_templateheaderparser: $(TEST_TEMPLATEHEADERPARSER_FILES) - @../../tools/test $(TEST_TEMPLATEHEADERPARSER_FILES) $(BASICFLAGS) $(PARSERFLAGS) - -TEST_MACROHEADERPARSER_FILES = \ - macroheaderparser.cc \ - $(PARSERFILES) \ - $(BASICFILES) -test_macroheaderparser: $(TEST_MACROHEADERPARSER_FILES) - @../../tools/test $(TEST_MACROHEADERPARSER_FILES) $(BASICFLAGS) $(PARSERFLAGS) - -TEST_TEMPLATELIST_FILES = \ - templatelist.cc \ - versionstr.cc \ - templateheaderparser.cc \ - $(PARSERFILES) \ - $(BASICFILES) -test_templatelist: $(TEST_TEMPLATELIST_FILES) - @../../tools/test $(TEST_TEMPLATELIST_FILES) $(PARSERFLAGS) $(BASICFLAGS) - -TEST_MACROLIST_FILES = \ - macrolist.cc \ - versionstr.cc \ - macroheaderparser.cc \ - $(PARSERFILES) \ - $(BASICFILES) -test_macrolist: $(TEST_MACROLIST_FILES) - @../../tools/test $(TEST_MACROLIST_FILES) $(PARSERFLAGS) $(BASICFLAGS) - -TEST_SAXPARSER_FILES = \ - saxparser.cc \ - $(BASICFILES) -test_saxparser: $(TEST_SAXPARSER_FILES) - @../../tools/test $(TEST_SAXPARSER_FILES) $(BASICFLAGS) $(PARSERFLAGS) - -TEST_TRANSACTIONPARSER_FILES = \ - transactionparser.cc \ - $(BASICFILES) \ - $(PARSERFILES) -test_transactionparser: $(TEST_TRANSACTIONPARSER_FILES) - @../../tools/test $(TEST_TRANSACTIONPARSER_FILES) $(BASICFLAGS) $(PARSERFLAGS) - -TEST_VERSIONSTR_FILES = \ - versionstr.cc \ - $(BASICFILES) -test_versionstr: $(TEST_VERSIONSTR_FILES) - @../../tools/test $(TEST_VERSIONSTR_FILES) $(BASICFLAGS) - -TEST_QUERYHANDLERPENTOMINOS_FILES = \ - queryhandlerpentominos.cc \ - tcpsocket.cc \ - queryparser.cc \ - $(PARSERFILES) \ - $(BASICFILES) -test_queryhandlerpentominos: $(TEST_QUERYHANDLERPENTOMINOS_FILES) - @../../tools/test $(TEST_QUERYHANDLERPENTOMINOS_FILES) $(PARSERFLAGS) $(BASICFLAGS) - -TEST_QUERYHANDLERPRACRO_FILES = \ - queryhandlerpracro.cc \ - tcpsocket.cc \ - queryparser.cc \ - $(DBFILES) \ - $(PARSERFILES) \ - $(BASICFILES) -test_queryhandlerpracro: $(TEST_QUERYHANDLERPRACRO_FILES) - @../../tools/test $(TEST_QUERYHANDLERPRACRO_FILES) $(DBFLAGS) $(PARSERFLAGS) $(BASICFLAGS) - -TEST_QUERYPARSER_FILES = \ - queryparser.cc \ - $(BASICFILES) \ - $(PARSERFILES) -test_queryparser: $(TEST_QUERYPARSER_FILES) - @../../tools/test $(TEST_QUERYPARSER_FILES) $(BASICFLAGS) $(PARSERFLAGS) - -TEST_LUAQUERMAPPER_FILES = \ - luaquerymapper.cc \ - $(BASICFILES) -test_luaquerymapper: $(TEST_LUAQUERMAPPER_FILES) - @../../tools/test $(TEST_LUAQUERMAPPER_FILES) $(LUA_LIBS) $(BASICFLAGS) - -TEST_TEMPLATEPARSER_FILES = \ - templateparser.cc \ - $(PARSERFILES) \ - $(BASICFILES) -test_templateparser: $(TEST_TEMPLATEPARSER_FILES) - @../../tools/test $(TEST_TEMPLATEPARSER_FILES) $(BASICFLAGS) $(PARSERFLAGS) - -TEST_MACROPARSER_FILES = \ - macroparser.cc \ - $(PARSERFILES) \ - $(BASICFILES) -test_macroparser: $(TEST_MACROPARSER_FILES) - @../../tools/test $(TEST_MACROPARSER_FILES) $(BASICFLAGS) $(PARSERFLAGS) - -TEST_SERVER_FILES = \ - server.cc \ - templateparser.cc \ - templatelist.cc \ - templateheaderparser.cc \ - queryparser.cc \ - queryhandlerpentominos.cc \ - journal_commit.cc \ - macrolist.cc \ - queryhandlerpracro.cc \ - macroheaderparser.cc \ - versionstr.cc \ - resumeparser.cc \ - luaquerymapper.cc \ - tcpsocket.cc \ - transactionparser.cc \ - widgetgenerator.cc \ - database.cc \ - pracrodao.cc \ - pracrodaotest.cc \ - pracrodaopgsql.cc \ - luaresume.cc \ - macroparser.cc \ - mutex.cc \ - xml_encode_decode.cc \ - $(PARSERFILES) \ - $(BASICFILES) -test_server: $(TEST_SERVER_FILES) - @../../tools/test $(TEST_SERVER_FILES) $(BASICFLAGS) $(LUA_LIBS) $(DBFLAGS) $(PARSERFLAGS) $(HTTPD_LIBS) $(HTTPD_CFLAGS) - -TEST_PRACRODAOPGSQL_FILES = \ - pracrodaopgsql.cc \ - pracrodao.cc \ - $(BASICFILES) -test_pracrodaopgsql: $(TEST_PRACRODAOPGSQL_FILES) - @../../tools/test $(TEST_PRACRODAOPGSQL_FILES) $(DBFLAGS) $(BASICFLAGS) - -TEST_XMLENCODEDECODE_FILES = \ - xml_encode_decode.cc -test_xml_encode_decode: $(TEST_XMLENCODEDECODE_FILES) - @../../tools/test $(TEST_XMLENCODEDECODE_FILES) - -TEST_JOURNALCOMMIT_FILES = \ - journal_commit.cc \ - templateparser.cc \ - $(PARSERFILES) \ - $(BASICFILES) -test_journal_commit: $(TEST_JOURNALCOMMIT_FILES) - @../../tools/test $(TEST_JOURNALCOMMIT_FILES) $(PARSERFLAGS) $(BASICFLAGS) +TESTLOGS = `for F in ${TESTFILES}; do echo $$F.log; done` -CLEANFILES = $(TESTFILES) $(TESTLOGS) *~ +CLEANFILES = $(TESTFILES) $(TESTLOGS) tests.make *~ diff --git a/server/src/mutex.cc b/server/src/mutex.cc index 2cc75cc..23ec255 100644 --- a/server/src/mutex.cc +++ b/server/src/mutex.cc @@ -37,21 +37,89 @@ Mutex::~Mutex() pthread_mutex_destroy(&mutex); } +bool Mutex::trylock() +{ + return pthread_mutex_trylock(&mutex) == 0; +} + void Mutex::lock() { - pthread_mutex_lock( &mutex ); + pthread_mutex_lock(&mutex); } void Mutex::unlock() { - pthread_mutex_unlock( &mutex ); + pthread_mutex_unlock(&mutex); +} + + +MutexAutolock::MutexAutolock(Mutex &m) + : mutex(m) +{ + mutex.lock(); +} + +MutexAutolock::~MutexAutolock() +{ + mutex.unlock(); } #ifdef TEST_MUTEX +//deps: +//cflags: +//libs: -lpthread +#include <test.h> -int main() +#include <unistd.h> + +volatile int cnt = 0; + +static void* thread_run(void *data) { - return 0; + Mutex *mutex = (Mutex*)data; + mutex->lock(); + cnt++; + mutex->unlock(); + return NULL; } +TEST_BEGIN; + +Mutex mutex; + +mutex.lock(); +TEST_FALSE(mutex.trylock(), "Testing if trylock works negative."); +mutex.unlock(); +TEST_TRUE(mutex.trylock(), "Testing if trylock works positive."); +mutex.unlock(); + +mutex.lock(); + +pthread_attr_t attr; +pthread_t tid; +pthread_attr_init(&attr); +pthread_create(&tid, &attr, thread_run, &mutex); + +usleep(100); +TEST_EQUAL(cnt, 0, "Testing if lock prevent cnt from increasing."); +mutex.unlock(); + +usleep(100); +TEST_EQUAL(cnt, 1, "Testing if unlock makes cnt increase."); + +pthread_join(tid, NULL); +pthread_attr_destroy(&attr); + +{ + TEST_TRUE(mutex.trylock(), "Testing if autolock has not yet locked the mutex."); + mutex.unlock(); + MutexAutolock mlock(mutex); + TEST_FALSE(mutex.trylock(), "Testing if autolock worked."); +} + +TEST_TRUE(mutex.trylock(), "Testing if autolock has released the lock on the mutex."); +mutex.unlock(); + +TEST_END; + #endif/*TEST_MUTEX*/ diff --git a/server/src/mutex.h b/server/src/mutex.h index 8b35042..cf052ad 100644 --- a/server/src/mutex.h +++ b/server/src/mutex.h @@ -35,6 +35,7 @@ public: Mutex(); ~Mutex(); + bool trylock(); void lock(); void unlock(); @@ -42,4 +43,13 @@ private: pthread_mutex_t mutex; }; +class MutexAutolock { +public: + MutexAutolock(Mutex &mutex); + ~MutexAutolock(); + +private: + Mutex &mutex; +}; + #endif/*__PRACRO_MUTEX_H__*/ diff --git a/server/src/saxparser.cc b/server/src/saxparser.cc index 9072ab6..2018645 100644 --- a/server/src/saxparser.cc +++ b/server/src/saxparser.cc @@ -167,6 +167,10 @@ unsigned int SAXParser::usedBytes() #ifdef TEST_SAXPARSER +//deps: log.cc debug.cc exception.cc +//cflags: -I.. +//libs: -lexpat +#include <test.h> #define XMLFILE "/tmp/saxparsertest.xml" @@ -253,139 +257,125 @@ public: } }; -int main(int argc, char *argv[]) -{ - FILE *fp = fopen(XMLFILE, "w"); - if(!fp) { - printf("Could not write to %s\n", XMLFILE); - return 1; - } - fprintf(fp, xml); - fclose(fp); +TEST_BEGIN; - // Test callback parser - { - MyFileParser parser(XMLFILE); - parser.parse(); - } +FILE *fp = fopen(XMLFILE, "w"); +TEST_NOTEQUAL(fp, NULL, "Test if file \""XMLFILE"\" could be written."); +if(!fp) TEST_FATAL("Could not write "XMLFILE); +fprintf(fp, xml); +fclose(fp); - // Test buffer parser - for(size_t sz = 1; sz < 1000; sz++) { - bool test = false; - MyBufferParser parser; - std::string buf = xml; - size_t pos = 0; - while(pos < buf.length()) { - std::string substr = buf.substr(pos, sz); - - try { - test |= parser.parse((char*)substr.c_str(), substr.length()); - } catch(Exception &e) { - printf("Buffer parser failed on size %d: %s [%s]\n", sz, e.what(), substr.c_str()); - } - pos += sz; - } +TEST_MSG("Test callback parser."); +{ + MyFileParser parser(XMLFILE); + parser.parse(); +} - if(!test) { - printf("Buffer parser failed on size %d\n", sz); - return 1; +TEST_MSG("Test buffer parser."); +for(size_t sz = 1; sz < 1000; sz++) { + bool test = false; + MyBufferParser parser; + std::string buf = xml; + size_t pos = 0; + while(pos < buf.length()) { + std::string substr = buf.substr(pos, sz); + + try { + test |= parser.parse((char*)substr.c_str(), substr.length()); + } catch(Exception &e) { + TEST_TRUE(true, "Buffer parser failed on size %d: %s [%s]", + sz, e.what(), substr.c_str()); } + pos += sz; } + + TEST_TRUE(test, "Test buffer parser on %d bytes", sz); + } - fp = fopen(XMLFILE, "w"); - if(!fp) { - printf("Could not write to %s\n", XMLFILE); - return 1; - } - fprintf(fp, xml_notrailingwhitespace); - fprintf(fp, xml_notrailingwhitespace); - fclose(fp); - // Test buffer parser with multiple documents in the same buffer - { - fp = fopen(XMLFILE, "r"); - if(!fp) { - printf("Could not write to %s\n", XMLFILE); - return 1; - } - for(size_t sz = 1; sz < 1000; sz++) { - MyBufferParser *parser = NULL; - rewind(fp); - size_t numdocs = 0; - char *buf = new char[sz + 1]; - memset(buf, 0, sz + 1); - size_t size; - while( (size = fread(buf, 1, sz, fp)) > 0) { - while(size) { - if(parser == NULL) { - parser = new MyBufferParser(); - } - if(parser->parse(buf, size)) { - - // Got one - numdocs++; - - size = size - parser->usedBytes(); - strcpy(buf, buf + parser->usedBytes()); - delete parser; parser = NULL; - } else { - size = 0; - memset(buf, 0, sz + 1); - } +fp = fopen(XMLFILE, "w"); +TEST_NOTEQUAL(fp, NULL, "Test if file \""XMLFILE"\" could be written."); +if(!fp) TEST_FATAL("Could not write "XMLFILE); +fprintf(fp, xml_notrailingwhitespace); +fprintf(fp, xml_notrailingwhitespace); +fclose(fp); + +TEST_MSG("Test buffer parser with multiple documents in the same buffer."); +{ + fp = fopen(XMLFILE, "r"); + TEST_NOTEQUAL(fp, NULL, "Test if file \""XMLFILE"\" could be read."); + if(!fp) TEST_FATAL("Could not read from "XMLFILE); + + for(size_t sz = 1; sz < 1000; sz++) { + MyBufferParser *parser = NULL; + rewind(fp); + size_t numdocs = 0; + char *buf = new char[sz + 1]; + memset(buf, 0, sz + 1); + size_t size; + while( (size = fread(buf, 1, sz, fp)) > 0) { + while(size) { + if(parser == NULL) { + parser = new MyBufferParser(); + } + if(parser->parse(buf, size)) { + + // Got one + numdocs++; + + size = size - parser->usedBytes(); + strcpy(buf, buf + parser->usedBytes()); + delete parser; parser = NULL; + } else { + size = 0; + memset(buf, 0, sz + 1); } } - if(numdocs != 2) { - printf("Failed to parse two documents.\n"); - return 1; - } - if(parser) delete parser; parser = NULL; - delete[] buf; } - fclose(fp); - } - - fp = fopen(XMLFILE, "w"); - if(!fp) { - printf("Could not write to %s\n", XMLFILE); - return 1; + TEST_EQUAL(numdocs, 2, "Test if 2 documents were parsed on docsize %d.", sz); + if(parser) delete parser; parser = NULL; + delete[] buf; } - fprintf(fp, xml_fail); fclose(fp); +} - // Test failure - { - MyFileParser parser(XMLFILE); - try { - parser.parse(); - } catch(Exception &e) { - goto goon; - } - printf("This test should fail...\n"); - return 1; - } - goon: +fp = fopen(XMLFILE, "w"); +TEST_NOTEQUAL(fp, NULL, "Test if file \""XMLFILE"\" could be written."); +if(!fp) TEST_FATAL("Could not write "XMLFILE); +fprintf(fp, xml_fail); +fclose(fp); - fp = fopen(XMLFILE, "w"); - if(!fp) { - printf("Could not write to %s\n", XMLFILE); - return 1; +TEST_MSG("Test failure"); +{ + MyFileParser parser(XMLFILE); + try { + parser.parse(); + } catch(Exception &e) { + goto goon; } - fprintf(fp, xml_fail2); - fclose(fp); + TEST_TRUE(false, "This test should fail...\n"); +} +goon: - // Test failure - { - MyFileParser parser(XMLFILE); - try { - parser.parse(); - } catch(Exception &e) { - goto goonagain; - } - printf("This test should fail...\n"); - return 1; - } - goonagain: +fp = fopen(XMLFILE, "w"); +TEST_NOTEQUAL(fp, NULL, "Test if file \""XMLFILE"\" could be written."); +if(!fp) TEST_FATAL("Could not write "XMLFILE); +fprintf(fp, xml_fail2); +fclose(fp); - unlink(XMLFILE); +// Test failure +{ + MyFileParser parser(XMLFILE); + try { + parser.parse(); + } catch(Exception &e) { + goto goonagain; + } + TEST_TRUE(false, "This test should fail...\n"); } +goonagain: + +unlink(XMLFILE); + +TEST_END; #endif/*TEST_SAXPARSER*/ diff --git a/server/src/session.cc b/server/src/session.cc index 02a78c5..0e8679c 100644 --- a/server/src/session.cc +++ b/server/src/session.cc @@ -85,23 +85,21 @@ void Sessions::deleteSession(std::string sessionid) } #ifdef TEST_SESSION +//deps: +//cflags: +//libs: +#include <test.h> -int main() -{ - Sessions sessions; - - srand(0); - Session *s1 = sessions.newSession(); - srand(0); - Session *s2 = sessions.newSession(); +TEST_BEGIN; +Sessions sessions; - if(s1->id() == s2->id()) { - printf("IDs not unique.\n"); - return 1; - } +srand(0); +Session *s1 = sessions.newSession(); +srand(0); +Session *s2 = sessions.newSession(); - return 0; +TEST_NOTEQUAL(s1->id(), s2->id(), "Testing if IDs are unique."); -} +TEST_END; #endif/*TEST_SESSION*/ |