blob: 473058760e6c3c70a15c86ff1b6fcd6127ca6e32 [file] [log] [blame]
Alex Lane587b78f2020-08-13 18:43:14 -05001#!/usr/bin/env python3
2# -*- Mode:bash; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
3#
4# Copyright (C) 2015-2020, The University of Memphis,
5# Arizona Board of Regents,
6# Regents of the University of California.
7#
8# This file is part of Mini-NDN.
9# See AUTHORS.md for a complete list of Mini-NDN authors and contributors.
10#
11# Mini-NDN is free software: you can redistribute it and/or modify
12# it under the terms of the GNU General Public License as published by
13# the Free Software Foundation, either version 3 of the License, or
14# (at your option) any later version.
15#
16# Mini-NDN is distributed in the hope that it will be useful,
17# but WITHOUT ANY WARRANTY; without even the implied warranty of
18# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19# GNU General Public License for more details.
20#
21# You should have received a copy of the GNU General Public License
22# along with Mini-NDN, e.g., in COPYING.md file.
23# If not, see <http://www.gnu.org/licenses/>.
24
25# This script generates a testbed topology based on current data. Note
26# that this topology is memory intensive and can have issues on lower specced
27# systems due to its size.
28# To use, run with python3
29
30import argparse
31import datetime
32import json
33import logging
34from os import path
35from urllib.request import urlopen
36
37def testbedGen():
38 """Returns a string with the Mini-NDN topology version of the testbed"""
39 topology = None
40 connections = None
41 hosts = []
42 links = []
43 try:
44 with urlopen("https://ndndemo.arl.wustl.edu/testbedNodes.json") as url:
45 topology = json.loads(url.read().decode())
46 with urlopen("https://ndndemo.arl.wustl.edu/links.json") as url:
47 connections = json.loads(url.read().decode())
48 except:
49 logging.error("Failed to retrieve testbed info from WUSTL servers")
50 if __name__ == '__main__':
51 from sys import exit
52 exit(1)
53 raise
54
55 logging.info("Generating testbed topology...")
56 for node_name in topology:
57 node = topology[node_name]
58 if node['neighbors']:
59 radius = node['hr_radius']
60 angle = node['hr_angle']
61 host_str = "{}: _ radius={} angle={}\n".format(node_name, radius, angle)
62 hosts.append(host_str)
63 logging.debug("Add node: {}".format(host_str)[:-1])
64 else:
65 # A node without neighbors shouldn't be considered part of the testbed
66 # for testing purposes
67 logging.debug("Node {} has no neighbors, passing...".format(node_name))
68 for link in connections:
69 node1 = link['start']
70 node2 = link['end']
71 # This value is equivalent to RTT in the testbed
72 delay = link['nlsr_weight']
73 link_str = "{}:{} delay={}ms\n".format(node1, node2, delay)
74 logging.debug("Add link: {}".format(link_str)[:-1])
75 links.append(link_str.strip())
76
77 topo_str = "[nodes]\n"
78 for host in hosts:
79 topo_str = topo_str + host
80 topo_str = topo_str + "[links]\n"
81 for link in links:
82 topo_str = topo_str + link
83 return topo_str.strip()
84
85if __name__ == '__main__':
86 default_path = path.dirname(__file__) + '/../topologies/testbed{}.conf'.format(str(datetime.date.today()))
87 parser = argparse.ArgumentParser()
88 parser.add_argument("-l", "--log_level", help="Log level to output", default="info", choices=["debug", "info", "warning", "error"])
89 parser.add_argument("-o", "--output_dir", help="File output location", default=default_path)
90 args = parser.parse_args()
91 log_level = getattr(logging, args.log_level.upper())
92 topologies_path = path.abspath(args.output_dir)
93 logging.basicConfig(format="%(levelname)s: %(message)s", level=log_level)
94 topo = testbedGen()
95 logging.info("Testbed generated, writing to file...")
96 with open(topologies_path, "w") as file:
97 file.writelines(topo)
98 logging.info("Finished")