#include "drivertests.hpp" #include "drivenengine.hpp" #include #include static void write_closed_message(Channel *ch, StreamBuffer *out) { std::ostringstream oss; oss << "Chan " << ch->chid() << " closed [" << ch->error() << "]\n"; out->write_bytes(oss.str()); } static void dump_lines(StreamBuffer *in, StreamBuffer *out, int chid) { while (true) { std::string l = in->readline(); if (l == "") break; std::ostringstream oss; oss << "Chan " << chid << ": " << l; out->write_bytes(oss.str()); } } // This test allows input on stdin or on port 8085. // You can type lines and see them echoed. class DriverListenTest : public DrivenEngine { public: std::vector channels_; virtual void event_init(int argc, char *argv[]) { listen_port(8085); } virtual void event_update() { while (true) { UniqueChannel ch = new_incoming_channel(); if (ch == nullptr) break; ch->set_readline(true); channels_.emplace_back(std::move(ch)); } Channel *stdioch = get_stdio_channel(); dump_lines(stdioch->in(), stdioch->out(), 0); std::vector keep; for (UniqueChannel &ch : channels_) { dump_lines(ch->in(), stdioch->out(), ch->chid()); if (ch->closed()) { write_closed_message(ch.get(), stdioch->out()); } else { keep.emplace_back(std::move(ch)); } } channels_ = std::move(keep); } }; // This test connects to a public webserver and prints // the output from the server. class DriverWebServerTest : public DrivenEngine { public: std::vector channels_; virtual void event_init(int argc, char *argv[]) { UniqueChannel ch = new_outgoing_channel("stanford.edu:80"); ch->out()->write_bytes("GET http://stanford.edu/index.html HTTP/1.1\n\n"); channels_.emplace_back(std::move(ch)); } virtual void event_update() { Channel *stdioch = get_stdio_channel(); dump_lines(stdioch->in(), stdioch->out(), 0); std::vector keep; for (UniqueChannel &ch : channels_) { dump_lines(ch->in(), stdioch->out(), ch->chid()); if (ch->closed()) { write_closed_message(ch.get(), stdioch->out()); } else { keep.emplace_back(std::move(ch)); } } channels_ = std::move(keep); } }; // This test produces a DNS resolution failure. class DriverDNSFailTest : public DrivenEngine { public: std::vector channels_; virtual void event_init(int argc, char *argv[]) { UniqueChannel ch = new_outgoing_channel("akjsdkajshdakjshd.alk:80"); ch->out()->write_bytes("GET http://stanford.edu/index.html HTTP/1.1\n\n"); channels_.emplace_back(std::move(ch)); } virtual void event_update() { Channel *stdioch = get_stdio_channel(); dump_lines(stdioch->in(), stdioch->out(), 0); std::vector keep; for (UniqueChannel &ch : channels_) { dump_lines(ch->in(), stdioch->out(), ch->chid()); if (ch->closed()) { write_closed_message(ch.get(), stdioch->out()); } else { keep.emplace_back(std::move(ch)); } } channels_ = std::move(keep); } }; // This test just prints the time. class DriverPrintClockTest : public DrivenEngine { public: int count; virtual void event_init(int argc, char *argv[]) { count = 0; } virtual void event_update() { std::cerr << std::fixed << std::setprecision(2) << get_clock() << " "; count++; if (count == 10) { std::cerr << std::endl; count = 0; } } }; UniqueDrivenEngine make_DriverListenTest() { return UniqueDrivenEngine(new DriverListenTest); } UniqueDrivenEngine make_DriverWebServerTest() { return UniqueDrivenEngine(new DriverWebServerTest); } UniqueDrivenEngine make_DriverDNSFailTest() { return UniqueDrivenEngine(new DriverDNSFailTest); } UniqueDrivenEngine make_DriverPrintClockTest() { return UniqueDrivenEngine(new DriverPrintClockTest); }