📄 test_timers.cc
字号:
// -*- c-basic-offset: 4; tab-width: 8; indent-tabs-mode: t -*-// Copyright (c) 2001-2008 XORP, Inc.//// 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 XORP 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 XORP LICENSE file; the license in that file is// legally binding.#ident "$XORP: xorp/rip/test_timers.cc,v 1.24 2008/07/23 05:11:37 pavlin Exp $"#include <set>#include "rip_module.h"#include "libxorp/xlog.h"#include "libxorp/c_format.hh"#include "libxorp/eventloop.hh"#include "libxorp/ipv4.hh"#include "libxorp/ipv4net.hh"#include "port.hh"#include "peer.hh"#include "route_db.hh"#include "system.hh"#include "test_utils.hh"#ifdef HAVE_GETOPT_H#include <getopt.h>#endif/////////////////////////////////////////////////////////////////////////////////// Constants//static const char *program_name = "test_timers";static const char *program_description = "Test RIP timers and route scan";static const char *program_version_id = "0.1";static const char *program_date = "March, 2003";static const char *program_copyright = "See file LICENSE";static const char *program_return_value = "0 on success, 1 if test error, 2 if internal error";static const uint32_t N_TEST_ROUTES = 32000;static boolprint_twirl(void){ static const char t[] = { '\\', '|', '/', '-' }; static const size_t nt = sizeof(t) / sizeof(t[0]); static size_t n = 0; static char erase = '\0'; printf("%c%c", erase, t[n % nt]); fflush(stdout); n++; erase = '\b'; return true;}// ----------------------------------------------------------------------------template <typename A>struct Address { static A me(); static A peer();};template <>IPv4 Address<IPv4>::me() { return IPv4("10.0.0.1"); }template <>IPv4 Address<IPv4>::peer() { return IPv4("10.10.0.1"); }template <>IPv6 Address<IPv6>::me() { return IPv6("10::1"); }template <>IPv6 Address<IPv6>::peer() { return IPv6("1010::1"); }// ----------------------------------------------------------------------------// Spoof Port that supports just a single Peer//template <typename A>class SpoofPort : public Port<A> {public: SpoofPort(PortManagerBase<A>& pm, A addr) : Port<A>(pm) { this->_peers.push_back(new Peer<A>(*this, addr)); verbose_log("Constructing SpoofPort<IPv%u> instance\n", XORP_UINT_CAST(A::ip_version())); } ~SpoofPort() { verbose_log("Destructing SpoofPort<IPv%u> instance\n", XORP_UINT_CAST(A::ip_version())); while (this->_peers.empty() == false) { delete this->_peers.front(); this->_peers.pop_front(); } }};// ----------------------------------------------------------------------------// Spoof Port Manager instance support a single Spoof Port which in turn// contains a single Peer.//template <typename A>class SpoofPortManager : public PortManagerBase<A> {public: SpoofPortManager(System<A>& s, const IfMgrIfTree& iftree) : PortManagerBase<A>(s, iftree) { this->_ports.push_back(new SpoofPort<A>(*this, Address<A>::me())); } ~SpoofPortManager() { while (!this->_ports.empty()) { delete this->_ports.front(); this->_ports.pop_front(); } } Port<A>* the_port() { XLOG_ASSERT(this->_ports.size() == 1); return this->_ports.front(); } Peer<A>* the_peer() { XLOG_ASSERT(this->_ports.size() == 1); XLOG_ASSERT(this->_ports.front()->peers().size() == 1); return this->_ports.front()->peers().front(); }};//----------------------------------------------------------------------------// The teststatic const IfMgrIfTree ift_dummy = IfMgrIfTree();template <typename A>static inttest_main(){ string ifname, vifname; // XXX: not set, because not needed const uint32_t n_routes = N_TEST_ROUTES; set<IPNet<A> > nets; make_nets(nets, n_routes); EventLoop e; System<A> rip_system(e); SpoofPortManager<A> spm(rip_system, ift_dummy); RouteDB<A>& rdb = rip_system.route_db(); Peer<A>* peer = spm.the_peer(); // Fix up time constants for the impatient. spm.the_port()->constants().set_expiry_secs(3); spm.the_port()->constants().set_deletion_secs(2); for_each(nets.begin(), nets.end(), RouteInjector<A>(rdb, Address<A>::me(), ifname, vifname, 1, peer)); if (peer->route_count() != n_routes) { verbose_log("Routes lost (count %u != %u)\n", XORP_UINT_CAST(peer->route_count()), XORP_UINT_CAST(n_routes)); return 1; } e.timer_list().advance_time(); // XXX { // Quick route dump test TimeVal t1, t2; e.current_time(t1); vector<typename RouteDB<A>::ConstDBRouteEntry> l; rdb.dump_routes(l); e.timer_list().advance_time(); // XXX e.current_time(t2); t2 -= t1; fprintf(stderr, "route db route dump took %d.%06d seconds\n", t2.sec(), t2.usec()); } { // Quick route dump test TimeVal t1, t2; e.current_time(t1); vector<const typename RouteEntryOrigin<A>::Route*> l; peer->dump_routes(l); e.timer_list().advance_time(); // XXX e.current_time(t2); t2 -= t1; fprintf(stderr, "peer route dump took %d.%06d seconds\n", t2.sec(), t2.usec()); } { // Quick route dump test TimeVal t1, t2; e.current_time(t1); vector<typename RouteDB<A>::ConstDBRouteEntry> l; rdb.dump_routes(l); e.timer_list().advance_time(); // XXX e.current_time(t2); t2 -= t1; fprintf(stderr, "route db route dump took %d.%06d seconds\n", t2.sec(), t2.usec()); } const PortTimerConstants& ptc = peer->port().constants(); uint32_t timeout_secs = ptc.expiry_secs() + ptc.deletion_secs() + 5; XorpTimer twirl; if (verbose()) twirl = e.new_periodic_ms(250, callback(print_twirl)); bool timeout = false; XorpTimer t = e.set_flag_after_ms(1000 * timeout_secs, &timeout); while (timeout == false) { size_t route_count = peer->route_count(); verbose_log("Route count = %u\n", XORP_UINT_CAST(route_count)); if (route_count == 0) break; e.run(); } if (peer->route_count()) { verbose_log("Routes did not clean up\n"); return 1; } return 0;}/** * Print program info to output stream. * * @param stream the output stream the print the program info to. */static voidprint_program_info(FILE *stream){ fprintf(stream, "Name: %s\n", program_name); fprintf(stream, "Description: %s\n", program_description); fprintf(stream, "Version: %s\n", program_version_id); fprintf(stream, "Date: %s\n", program_date); fprintf(stream, "Copyright: %s\n", program_copyright); fprintf(stream, "Return: %s\n", program_return_value);}/** * Print program usage information to the stderr. * * @param progname the name of the program. */static voidusage(const char* progname){ print_program_info(stderr); fprintf(stderr, "usage: %s [-v] [-h]\n", progname); fprintf(stderr, " -h : usage (this message)\n"); fprintf(stderr, " -v : verbose output\n");}intmain(int argc, char* const argv[]){ // // Initialize and start xlog // xlog_init(argv[0], NULL); xlog_set_verbose(XLOG_VERBOSE_LOW); // Least verbose messages // XXX: verbosity of the error messages temporary increased xlog_level_set_verbose(XLOG_LEVEL_ERROR, XLOG_VERBOSE_HIGH); xlog_add_default_output(); xlog_start(); int ch; while ((ch = getopt(argc, argv, "hv")) != -1) { switch (ch) { case 'v': set_verbose(true); break; case 'h': case '?': default: usage(argv[0]); xlog_stop(); xlog_exit(); if (ch == 'h') return (0); else return (1); } } argc -= optind; argv += optind; int rval = 0; XorpUnexpectedHandler x(xorp_unexpected_handler); try { rval = test_main<IPv4>(); rval |= test_main<IPv6>(); } catch (...) { // Internal error xorp_print_standard_exceptions(); rval = 2; } // // Gracefully stop and exit xlog // xlog_stop(); xlog_exit(); return rval;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -