diff options
Diffstat (limited to 'tests')
-rw-r--r-- | tests/test-Http.cc | 138 | ||||
-rw-r--r-- | tests/test-Sockets.cc | 11 | ||||
-rw-r--r-- | tests/test-Tasks.cc | 47 |
3 files changed, 168 insertions, 28 deletions
diff --git a/tests/test-Http.cc b/tests/test-Http.cc index af78e43..88d7a8d 100644 --- a/tests/test-Http.cc +++ b/tests/test-Http.cc @@ -1,41 +1,92 @@ #include <Main.h> #include <HttpServer.h> #include <TaskMan.h> - -#define DAEMON_NAME "Balau/1.0" +#include <Socket.h> +#include <SimpleMustache.h> using namespace Balau; -class TestAction : public HttpServer::Action { - public: - TestAction() : Action(Regexes::any) { } - virtual bool Do(HttpServer * server, Http::Request & req, HttpServer::Action::ActionMatch & match, IO<Handle> out) throw (GeneralException); -}; - -bool TestAction::Do(HttpServer * server, Http::Request & req, HttpServer::Action::ActionMatch & match, IO<Handle> out) throw (GeneralException) { - HttpServer::Response response(server, req, out); - response->writeString( +const char htmlTemplateStr[] = "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\"\n" "\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n" "<html xmlns=\"http://www.w3.org/1999/xhtml\">\n" " <head>\n" -" <title>Test</title>\n" +" <meta http-equiv=\"content-type\" content=\"text/html; charset=utf-8\" />\n" +" <title>{{title}}</title>\n" +" <style type=\"text/css\">\n" +" body { font-family: arial, helvetica, sans-serif; }\n" +" </style>\n" " </head>\n" "\n" " <body>\n" -" This is a test document.\n" +" <h1>{{title}}</h1>\n" +" <h2>{{msg}}</h2>\n" " </body>\n" -"</html>\n"); +"</html>\n" +; + +class TestHtmlTemplate : public AtStart { + public: + TestHtmlTemplate() : AtStart(10), htmlTemplate(m_template) { } + virtual void doStart() { m_template.setTemplate(htmlTemplateStr); } + + const SimpleMustache & htmlTemplate; + private: + SimpleMustache m_template; +}; + +static TestHtmlTemplate testHtmlTemplate; + +static Regex stopURL("/stop$"); + +class StopAction : public HttpServer::Action { + public: + StopAction(Events::Async & event, bool & stop) : Action(stopURL), m_event(event), m_stop(stop) { } + private: + virtual bool Do(HttpServer * server, Http::Request & req, HttpServer::Action::ActionMatch & match, IO<Handle> out) throw (GeneralException); + Events::Async & m_event; + bool & m_stop; +}; + +bool StopAction::Do(HttpServer * server, Http::Request & req, HttpServer::Action::ActionMatch & match, IO<Handle> out) throw (GeneralException) { + m_stop = true; + m_event.trigger(); + SimpleMustache::Context ctx; + HttpServer::Response response(server, req, out); + + ctx["title"] = "Stop"; + ctx["msg"] = "Server stopping"; + testHtmlTemplate.htmlTemplate.render(response.get(), &ctx); response.Flush(); return true; } -Balau::Regex testFailureURL("^/failure.html$"); +class TestAction : public HttpServer::Action { + public: + TestAction() : Action(Regexes::any) { } + private: + virtual bool Do(HttpServer * server, Http::Request & req, HttpServer::Action::ActionMatch & match, IO<Handle> out) throw (GeneralException); +}; + +bool TestAction::Do(HttpServer * server, Http::Request & req, HttpServer::Action::ActionMatch & match, IO<Handle> out) throw (GeneralException) { + SimpleMustache::Context ctx; + HttpServer::Response response(server, req, out); + + ctx["title"] = "Test"; + ctx["msg"] = "This is a test document."; + + testHtmlTemplate.htmlTemplate.render(response.get(), &ctx); + response.Flush(); + return true; +} + +static Regex testFailureURL("^/failure.html$"); class TestFailure : public HttpServer::Action { public: TestFailure() : Action(testFailureURL) { } + private: virtual bool Do(HttpServer * server, Http::Request & req, HttpServer::Action::ActionMatch & match, IO<Handle> out) throw (GeneralException); }; @@ -43,32 +94,75 @@ bool TestFailure::Do(HttpServer * server, Http::Request & req, HttpServer::Actio throw GeneralException("Test..."); } -#define NTHREADS 4 +class Stopper : public Task { + virtual const char * getName() const { return "ServerStopper"; } + virtual void Do(); +}; + +void Stopper::Do() { + IO<Socket> s(new Socket()); + bool c = s->connect("localhost", 8080); + TAssert(c); + s->writeString("GET /stop HTTP/1.0\r\n\r\n"); +} + +static const int NTHREADS = 4; void MainTask::Do() { Printer::enable(M_DEBUG); Printer::log(M_STATUS, "Test::Http running."); - Thread * tms[NTHREADS]; + TaskMan::TaskManThread * tms[NTHREADS]; for (int i = 0; i < NTHREADS; i++) tms[i] = TaskMan::createThreadedTaskMan(); + Events::Async event; + bool stop = false; + + waitFor(&event); + HttpServer * s = new HttpServer(); - HttpServer::Action * a = new TestAction(); - HttpServer::Action * f = new TestFailure(); - a->registerMe(s); - f->registerMe(s); + s->registerAction(new TestAction()); + s->registerAction(new TestFailure()); + s->registerAction(new StopAction(event, stop)); s->setPort(8080); s->setLocal("localhost"); s->start(); + Events::Timeout timeout(1); + waitFor(&timeout); yield(); + Events::TaskEvent stopperEvent; + Task * stopper = TaskMan::registerTask(new Stopper, &stopperEvent); + waitFor(&stopperEvent); + + bool gotEvent = false, gotStopperEvent = false; + int count = 0; + + while (!gotEvent || !gotStopperEvent) { + count++; + yield(); + if (event.gotSignal()) { + TAssert(!gotEvent); + gotEvent = true; + } + if (stopperEvent.gotSignal()) { + TAssert(!gotStopperEvent); + gotStopperEvent = true; + stopperEvent.ack(); + } + } + TAssert(count <= 2); + + TAssert(stop); + Printer::log(M_STATUS, "Test::Http is stopping."); + s->stop(); for (int i = 0; i < NTHREADS; i++) - tms[i]->join(); + TaskMan::stopThreadedTaskMan(tms[i]); Printer::log(M_STATUS, "Test::Http passed."); } diff --git a/tests/test-Sockets.cc b/tests/test-Sockets.cc index a3e2755..4ef0a78 100644 --- a/tests/test-Sockets.cc +++ b/tests/test-Sockets.cc @@ -62,11 +62,16 @@ void MainTask::Do() { Printer::enable(M_ALL); Printer::log(M_STATUS, "Test::Sockets running."); - Events::TaskEvent evtSvr(listener = Balau::createTask(new Listener<Worker>(1234))); - Events::TaskEvent evtCln(Balau::createTask(new Client)); - Printer::log(M_STATUS, "Created %s", listener->getName()); + Events::TaskEvent evtSvr; + Events::TaskEvent evtCln; + + listener = TaskMan::registerTask(new Listener<Worker>(1234), &evtSvr); + TaskMan::registerTask(new Client, &evtCln); + waitFor(&evtSvr); waitFor(&evtCln); + + Printer::log(M_STATUS, "Created %s", listener->getName()); bool svrDone = false, clnDone = false; while (!svrDone || !clnDone) { yield(); diff --git a/tests/test-Tasks.cc b/tests/test-Tasks.cc index 272e61d..6bbb503 100644 --- a/tests/test-Tasks.cc +++ b/tests/test-Tasks.cc @@ -1,6 +1,7 @@ #include <Main.h> #include <Task.h> #include <TaskMan.h> +#include <StacklessTask.h> using namespace Balau; @@ -20,9 +21,42 @@ class TestTask : public Task { } }; +class TestOperation { + public: + TestOperation() : m_count(0), m_completed(false) { } + void Do() { + if (m_count++ == 0) { + m_timeout.set(0.2); + Task::operationYield(&m_timeout, Task::STACKLESS); + } + TAssert(m_timeout.gotSignal()); + m_completed = true; + } + bool completed() { return m_completed; } + private: + int m_count; + bool m_completed; + Events::Timeout m_timeout; +}; + +class TestStackless : public StacklessTask { + public: + virtual const char * getName() const { return "TestStackless"; } + private: + virtual void Do() { + StacklessBegin(); + m_operation = new TestOperation(); + StacklessOperation(m_operation->Do()); + TAssert(m_operation->completed()); + delete m_operation; + StacklessEnd(); + } + TestOperation * m_operation; +}; + static void yieldingFunction() { Events::Timeout timeout(0.2); - Task::yield(&timeout); + Task::operationYield(&timeout); TAssert(timeout.gotSignal()); } @@ -30,8 +64,15 @@ void MainTask::Do() { customPrinter = new CustomPrinter(); Printer::log(M_STATUS, "Test::Tasks running."); - Task * testTask = Balau::createTask(new TestTask()); - Events::TaskEvent taskEvt(testTask); + Events::TaskEvent taskEvt; + Task * testTask = TaskMan::registerTask(new TestTask(), &taskEvt); + waitFor(&taskEvt); + TAssert(!taskEvt.gotSignal()); + yield(); + TAssert(taskEvt.gotSignal()); + taskEvt.ack(); + + Task * testStackless = TaskMan::registerTask(new TestStackless(), &taskEvt); waitFor(&taskEvt); TAssert(!taskEvt.gotSignal()); yield(); |