// -*- c-basic-offset: 4 -*- /* * queueyanktest.{cc,hh} -- test Queue yank() functionality * Eddie Kohler * * Copyright (c) 2003 International Computer Science Institute * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, subject to the conditions * listed in the Click LICENSE file. These conditions include: you must * preserve this copyright notice, and you cannot mention the copyright * holders in advertising related to the Software without their permission. * The Software is provided WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED. This * notice is a summary of the Click LICENSE file; the license in that file is * legally binding. */ #include #include "queueyanktest.hh" #include #include CLICK_DECLS QueueYankTest::QueueYankTest() : _t(this) { } QueueYankTest::~QueueYankTest() { } int QueueYankTest::configure(Vector &conf, ErrorHandler *errh) { Element *e; if (cp_va_parse(conf, this, errh, cpElement, "Queue element", &e, cpEnd) < 0) return -1; if (!(_q = static_cast(e->cast("SimpleQueue")))) return errh->error("QUEUE argument must be a Queue element"); return 0; } int QueueYankTest::initialize(ErrorHandler *) { _t.initialize(this); _t.schedule_now(); return 0; } #define CHECK(x) if (!(x)) { errh->error("%s:%d: test `%s' failed", __FILE__, __LINE__, #x); return; } #define CHECK_PKT(p, c) do { Packet *p_ = (p); if (!p_ || p_->data()[0] != (c)) { errh->error("%s:%d: test '%s' produced %s packet (expected '%c')", __FILE__, __LINE__, #p, (p_ ? "wrong" : "no"), (c)); return; } p_->kill(); } while (0) #define CHECK_NOPKT(p) do { Packet *p_ = (p); if (p_) { errh->error("%s:%d: test '%s' produced a packet (expected nothing)", __FILE__, __LINE__, #p); return; } } while (0) #define CHECK_DEQ(s) do { for (const char *s_ = (s); *s_; s_++) CHECK_PKT(_q->deq(), *s_); } while (0) #define PREPARE_Q() do { _q->enq(a->clone()); _q->enq(b->clone()); _q->enq(c->clone()); _q->enq(d->clone()); _q->enq(e->clone()); CHECK(_q->size() == 5); } while (0) namespace { struct Foo { const unsigned char *s; Foo(const char *ss) : s(reinterpret_cast(ss)) { } bool operator()(const Packet *p) { for (const unsigned char *ss = s; *ss; ss++) if (p->data()[0] == *ss) return true; return false; } }; } void QueueYankTest::run_timer(Timer *) { PrefixErrorHandler perrh(ErrorHandler::default_handler(), declaration() + ": "); ErrorHandler *errh = &perrh; Packet *a = Packet::make("a", 1); Packet *b = Packet::make("b", 1); Packet *c = Packet::make("c", 1); Packet *d = Packet::make("d", 1); Packet *e = Packet::make("e", 1); CHECK(_q->size() == 0); PREPARE_Q(); CHECK_DEQ("abcde"); PREPARE_Q(); CHECK_PKT(_q->yank1(Foo("c")), 'c'); CHECK(_q->size() == 4); CHECK_DEQ("abde"); PREPARE_Q(); CHECK_NOPKT(_q->yank1(Foo("f"))); CHECK_DEQ("abcde"); PREPARE_Q(); CHECK_DEQ("abcd"); CHECK_PKT(_q->yank1(Foo("hgkje")), 'e'); CHECK(_q->size() == 0); Vector v; PREPARE_Q(); _q->yank(Foo("ade"), v); CHECK(v.size() == 3); CHECK(_q->size() == 2); CHECK_PKT(v[0], 'e'); CHECK_PKT(v[1], 'd'); CHECK_PKT(v[2], 'a'); CHECK_DEQ("bc"); v.clear(); PREPARE_Q(); _q->yank(Foo("fhq"), v); CHECK(v.size() == 0); CHECK_DEQ("abcde"); v.clear(); PREPARE_Q(); _q->yank(Foo("edcba"), v); CHECK(v.size() == 5); CHECK(_q->size() == 0); CHECK_PKT(v[0], 'e'); CHECK_PKT(v[1], 'd'); CHECK_PKT(v[2], 'c'); CHECK_PKT(v[3], 'b'); CHECK_PKT(v[4], 'a'); CHECK(_q->size() == 0); a->kill(); b->kill(); c->kill(); d->kill(); e->kill(); errh->message("All tests pass!"); } CLICK_ENDDECLS EXPORT_ELEMENT(QueueYankTest)