Source code for blackwidow.blackwidow

import parser
from graph import CsvGrapher
import re
import os


[docs]class BlackWidow(object): """Runs simulation based on settings. Generalizes Python's print to adapt to custom settings, and direct different types of messages to different outputs including files, or functions that dynamically generate graphs. Parameters ---------- settings : dict Contains settings to initialize the printer. Values include: real_time : bool Whether to graph in real time or write to files. show_verbose : bool Whether to print statements labelled verbose. log_file : str Name of file to write to. This is the prefix for all data types written to files. See documentation for write for more information. data_dir : str Directory where the data is stored. static_routing : bool Whether to use static routing. routing_packet_size : int Size of routing packets. tcp_alg : str Which TCP algorithm to use. Must be 'Reno', 'Fast', or 'Tahoe'. Methods ------- run(file_name) Runs the overall simulation based on settings specified when the BlackWidow object is constructed. print_verbose(msg) Handles a verbose message based on specified settings. record(data, data_type) Records data based on specified settings. Examples ------- >>> from blackwidow import BlackWidow >>> settings = {'filename': 'case0.json' ... } >>> bw = BlackWidow(settings) >>> bw.run() """ def __init__(self, settings={}): """Initializes settings fields. settings is a dictionary generated from the argsparse arguments, with some extra options added in. """ # Set settings # Real time graphing self.real_time = False # Default setting if 'real_time' in settings: self.real_time = settings['real_time'] # Override default # Show verbose output self.show_verbose = False if 'show_verbose' in settings: self.show_verbose = settings['show_verbose'] # Static routing self.static_routing = False if 'static_routing' in settings: self.static_routing = settings['static_routing'] # Directory to write data to self.data_dir = './data' if 'data_dir' in settings: self.data_dir = settings['data_dir'] # Size of routing packet self.routing_packet_size = 32 * 8 * 0 if ('routing_packet_size' in settings and settings['routing_packet_size'] is not None): self.routing_packet_size = settings['routing_packet_size'] # Log file. Prefix for all data files self.log_file = None if 'log_file' in settings: # Regex to match old version of particular case. regex = re.compile(r'{}\..*'.format(settings['log_file'])) for f in os.listdir(self.data_dir): if regex.match(f) is not None: os.remove('{}/{}'.format(self.data_dir, f)) self.log_file = settings['log_file'] # TCP algorithm self.tcp_alg = 'Reno' if ('tcp_alg' in settings and settings['tcp_alg'] is not None): self.tcp_alg = settings['tcp_alg'] # Initialize the data to be empty. This dictionary will contain all # recorded data. self.data = {}
[docs] def run(self, file_name): """Runs the overall simulation based on settings specified when the BlackWidow object is constructed. Parameters ---------- file_name : string Name of config file containing network. Returns ------- sim_time : float The amount of time taken for the network to finish running. """ print "Parsing {0} ...".format(file_name), "\n" # Create network from file self.network = parser.config_network(file_name, self) # Initialize grapher self.grapher = CsvGrapher(self) print "Parsed network: \n" self.network.dump() # Run the network. print "\nRunning network: \n" # sim_time is the amount of time taken for the network to run sim_time = self.network.run() # Graph the data if we are not graphing in real time if not self.real_time: self.grapher.graph(int(sim_time)) return sim_time
[docs] def run_network(self, network): """Runs the overall simulation based on settings specified when the BlackWidow object is constructed. Parameters ---------- network : `Network` The network to run. Returns ------- sim_time : float The amount of time taken for the network to finish running. """ self.network = network self.grapher = CsvGrapher(self) sim_time = network.run() if not self.real_time: self.grapher.graph(int(sim_time)) return sim_time
[docs] def print_verbose(self, msg): """Handles a verbose message based on specified settings. Parameters ---------- msg : str Message to show. """ if self.show_verbose: print msg
[docs] def record(self, data, data_type): """Records data based on specified settings. Parameters ---------- data : str Data point to record/plot. data_type : str Type of data, will be used as a file extension. Notes ----- Standard data types: link.drop - "Time in ms", "Number of drops" link.sent - "Time in ms", "Number of packets sent" flow.window - "Time in ms", "Window size" flow.sent - "Time in ms", "Mega bits" flow.delay - "Time in ms", "Delay in ms" """ if self.real_time: data_num = [float(x) for x in data.split(", ")] pass # Add to existing data type if data_type in self.data: self.data[data_type].append(data) # Create new data type and add the data else: self.data[data_type] = [data] if self.show_verbose: print data
[docs] def write(self): """ Writes data to files. This function writes each type of data to a file. The files are dependent on the extensions used to save data and the log_file file. Files are created as: [log_file].[data_type].csv Files are created in the data_dir directory in CSV format. """ # Check if the log file is defined. If not, we cannot write data. if self.log_file is not None: # Write each data type to a file for data_type in self.data: # Open file with open('{}/{}.{}.csv'.format(self.data_dir, self.log_file, data_type), 'a') as f: # Write data for data in self.data[data_type]: f.write(data + '\n')