aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRob Austein <sra@hactrn.net>2011-08-16 01:08:32 +0000
committerRob Austein <sra@hactrn.net>2011-08-16 01:08:32 +0000
commit71d032e4786469da5a18d1788f879653aa9913c1 (patch)
treeff36ee1c2c7079afcfdf98e4917b950ada93b943
parent8b9ca3f3b8443e8a2210d4959817fb51e2d9bbc0 (diff)
More fun with bgpdump testing.
svn path=/rtr-origin/rtr-origin.py; revision=3950
-rwxr-xr-xrtr-origin/rtr-origin.py89
1 files changed, 88 insertions, 1 deletions
diff --git a/rtr-origin/rtr-origin.py b/rtr-origin/rtr-origin.py
index 97cf4f29..917a73bc 100755
--- a/rtr-origin/rtr-origin.py
+++ b/rtr-origin/rtr-origin.py
@@ -1539,6 +1539,92 @@ def bgpdump_select_main(argv):
write_current(serial, nonce)
kick_all(serial)
+
+class bgpsec_replay_clock(object):
+ """
+ Internal clock for replaying BGP dump files.
+
+ * DANGER WILL ROBINSON! *
+ * DEBUGGING AND TEST USE ONLY! *
+
+ This class replaces the normal on-disk serial number mechanism with
+ an in-memory version based on pre-computed data.
+ bgpdump_server_main() uses this hack to replay historical data for
+ testing purposes. DO NOT USE THIS IN PRODUCTION.
+
+ You have been warned.
+ """
+
+ def __init__(self):
+ self.timestamps = [timestamp(int(f.split(".")[0])) for f in glob.iglob("*.ax")]
+ self.offset = self.timestamps[0] - int(time.time())
+ self.nonce = new_nonce()
+
+ def __nonzero__(self):
+ return len(self.timestamps) > 0
+
+ def now(self):
+ return timestamp.now(self.offset)
+
+ @property
+ def current(self):
+ return self.timestamps[0]
+
+ def read_current(self):
+ now = self.now()
+ while len(self.timestamps) > 1 and now >= self.timestamps[1]:
+ del self.timestamps[0]
+ return self.current, self.nonce
+
+ def siesta(self):
+ now = self.now()
+ return now - self.current if now > self.current else None
+
+
+def bgpdump_server_main(argv):
+ """
+ Simulate route origin data from a set of BGP dump files.
+
+ * DANGER WILL ROBINSON! *
+ * DEBUGGING AND TEST USE ONLY! *
+
+ This is a clone of server_main() which replaces the external serial
+ number updates triggered via the kickme channel by cronjob_main with
+ an internal clocking mechanism to replay historical test data.
+
+ DO NOT USE THIS IN PRODUCTION.
+
+ You have been warned.
+ """
+
+ log("[Starting]")
+ if len(argv) > 1:
+ sys.exit("Unexpected arguments: %r" % (argv,))
+ if argv:
+ try:
+ os.chdir(argv[0])
+ except OSError, e:
+ sys.exit(e)
+ #
+ # Yes, this really does replace a global function with a bound
+ # method to our clock object. Fun stuff, huh?
+ #
+ global read_current
+ clock = bgpsec_replay_clock()
+ read_current = clock.read_current
+ #
+ try:
+ server = server_channel()
+ while clock:
+ siesta = clock.siesta()
+ if siesta is None:
+ server.notify()
+ else:
+ asyncore.loop(timeout = siesta, count = 1)
+ except KeyboardInterrupt:
+ sys.exit(0)
+
+
os.environ["TZ"] = "UTC"
time.tzset()
@@ -1560,7 +1646,8 @@ main_dispatch = {
"server" : server_main,
"show" : show_main,
"bgpdump_convert" : bgpdump_convert_main,
- "bgpdump_select" : bgpdump_select_main }
+ "bgpdump_select" : bgpdump_select_main,
+ "bgpdump_server" : bgpdump_server_main }
def usage():
print "Usage: %s --mode [arguments]" % sys.argv[0]