def main(args): # N.B. it would be nice to include link discovery or host location discovery # events here, but that's specific to the Controller's log output. network_failure_events = EventGrouping("Topology Change Events") controlplane_failure_events = EventGrouping("Control Plane Blockages") controller_failure_events = EventGrouping("Controller Change Events") host_events = EventGrouping("Host Migrations") event2grouping = { SwitchFailure: network_failure_events, SwitchRecovery: network_failure_events, LinkFailure: network_failure_events, LinkRecovery: network_failure_events, ControlChannelBlock: controlplane_failure_events, ControlChannelUnblock: controlplane_failure_events, ControllerFailure: controller_failure_events, ControllerRecovery: controller_failure_events, BlockControllerPair: controller_failure_events, UnblockControllerPair: controller_failure_events, HostMigration: host_events, # TODO(cs): support TrafficInjection, DataplaneDrop? Might get too noisy. } with open(args.input) as input_file: trace = parse(input_file) for event in trace: if type(event) in event2grouping: event2grouping[type(event)].append(event) for grouping in [ network_failure_events, controlplane_failure_events, controller_failure_events, host_events ]: grouping.printToConsole() print
def snapshot_and_play_forward(self, simulation, controller, inject_input, wait_time_seconds): snapshotter = Snapshotter(simulation, controller) snapshotter.snapshot_controller() # Here we also fork() ourselves (the network simulator), since we need # switches to respond to messages, and potentially change their state in # order to properly peek(). # TODO(cs): I believe that to be technically correct we need to use Chandy-Lamport # here, since STS + POX = a distributed system. def play_forward_and_marshal(): # Can't marshal the simulation object, so use this method as a closure # instead. # N.B. depends on LocalForker() -- cannot be used with RemoteForker(). # TODO(cs): even though DataplaneDrops are technically InputEvents, they # may time out, and we might do well to try to infer this somehow. found_events = play_forward(simulation, inject_input, wait_time_seconds) # TODO(cs): DataplaneDrops are a special case of an InputEvent that may # time out. We should check whether the input for this peek() was a # DataplaneDrop, and return whether it timed out. return [ e.to_json() for e in found_events ] self.forker.register_task("snapshot_fork_task", play_forward_and_marshal) # N.B. play_forward cleans up the simulation, including snaphotted controller unmarshalled_found_events = self.forker.fork("snapshot_fork_task") found_events = parse(unmarshalled_found_events) # Finally, bring the controller back to the state it was at just after # injecting inject_input # N.B. this must be invoked in the parent process (not a forker.fork()ed # child), since it mutates class variables in Controller. snapshotter.snapshot_proceed() return found_events
def snapshot_and_play_forward(self, simulation, controller, inject_input, wait_time_seconds): snapshotter = Snapshotter(simulation, controller) snapshotter.snapshot_controller() # Here we also fork() ourselves (the network simulator), since we need # switches to respond to messages, and potentially change their state in # order to properly peek(). # TODO(cs): I believe that to be technically correct we need to use Chandy-Lamport # here, since STS + POX = a distributed system. def play_forward_and_marshal(): # Can't marshal the simulation object, so use this method as a closure # instead. # N.B. depends on LocalForker() -- cannot be used with RemoteForker(). # TODO(cs): even though DataplaneDrops are technically InputEvents, they # may time out, and we might do well to try to infer this somehow. found_events = play_forward(simulation, inject_input, wait_time_seconds) # TODO(cs): DataplaneDrops are a special case of an InputEvent that may # time out. We should check whether the input for this peek() was a # DataplaneDrop, and return whether it timed out. return [ e.to_json() for e in found_events ] self.forker.register_task("snapshot_fork_task", play_forward_and_marshal) # N.B. play_forward cleans up the simulation, including snaphotted controller unmarshalled_found_events = self.forker.fork("snapshot_fork_task") found_events = parse(unmarshalled_found_events) # Finally, bring the controller back to the state it was at just after # injecting inject_input # N.B. this must be invoked in the parent process (not a forker.fork()ed # child), since it mutates class variables in Controller. return (found_events, snapshotter)
def main(args): # N.B. it would be nice to include link discovery or host location discovery # events here, but that's specific to the Controller's log output. network_failure_events = EventGrouping("Topology Change Events") controlplane_failure_events = EventGrouping("Control Plane Blockages") controller_failure_events = EventGrouping("Controller Change Events") host_events = EventGrouping("Host Migrations") event2grouping = { SwitchFailure : network_failure_events, SwitchRecovery : network_failure_events, LinkFailure : network_failure_events, LinkRecovery : network_failure_events, ControlChannelBlock : controlplane_failure_events, ControlChannelUnblock : controlplane_failure_events, ControllerFailure : controller_failure_events, ControllerRecovery : controller_failure_events, BlockControllerPair : controller_failure_events, UnblockControllerPair : controller_failure_events, HostMigration : host_events, # TODO(cs): support TrafficInjection, DataplaneDrop? Might get too noisy. } with open(args.input) as input_file: trace = parse(input_file) for event in trace: if type(event) in event2grouping: event2grouping[type(event)].append(event) for grouping in [network_failure_events, controlplane_failure_events, controller_failure_events, host_events]: grouping.printToConsole() print
def main(args): def load_format_file(format_file): if format_file.endswith('.py'): format_file = format_file[:-3].replace("/", ".") config = __import__(format_file, globals(), locals(), ["*"]) return config if args.format_file is not None: format_def = load_format_file(args.format_file) else: format_def = object() dp_trace = None if args.dp_trace_path is not None: dp_trace = Trace(args.dp_trace_path).dataplane_trace if hasattr(format_def, "fields"): fields = format_def.fields else: fields = default_fields for field in fields: if field not in field_formatters: raise ValueError("unknown field %s" % field) if hasattr(format_def, "filtered_classes"): filtered_classes = format_def.filtered_classes else: filtered_classes = default_filtered_classes stats = Stats() # all events are printed with a fixed number of lines, and (optionally) # separated by delimiter lines of the form: # ---------------------------------- with open(args.input) as input_file: trace = parse(input_file) for event in trace: if type(event) not in filtered_classes: if dp_trace is not None and type( event) == replay_events.TrafficInjection: event.dp_event = dp_trace.pop(0) for field in fields: field_formatters[field](event) stats.update(event) if check_for_violation_signature(trace, args.violation_signature): print "Violation occurs at end of trace: %s" % args.violation_signature elif args.violation_signature is not None: print("Violation does not occur at end of trace: %s", args.violation_signature) print if args.stats: print "Stats: %s" % stats
def main(args): def load_format_file(format_file): if format_file.endswith('.py'): format_file = format_file[:-3].replace("/", ".") config = __import__(format_file, globals(), locals(), ["*"]) return config if args.format_file is not None: format_def = load_format_file(args.format_file) else: format_def = object() dp_trace = None if args.dp_trace_path is not None: dp_trace = Trace(args.dp_trace_path).dataplane_trace if hasattr(format_def, "fields"): fields = format_def.fields else: fields = default_fields for field in fields: if field not in field_formatters: raise ValueError("unknown field %s" % field) if hasattr(format_def, "filtered_classes"): filtered_classes = format_def.filtered_classes else: filtered_classes = default_filtered_classes stats = Stats() # all events are printed with a fixed number of lines, and (optionally) # separated by delimiter lines of the form: # ---------------------------------- with open(args.input) as input_file: trace = parse(input_file) for event in trace: if type(event) not in filtered_classes: if dp_trace is not None and type(event) == replay_events.TrafficInjection: event.dp_event = dp_trace.pop(0) for field in fields: field_formatters[field](event) stats.update(event) if check_for_violation_signature(trace, args.violation_signature): print "Violation occurs at end of trace: %s" % args.violation_signature elif args.violation_signature is not None: print ("Violation does not occur at end of trace: %s", args.violation_signature) print if args.stats: print "Stats: %s" % stats
def main(args): if args.dp_trace_path is None: args.dp_trace_path = os.path.dirname(args.input) + "/dataplane.trace" dp_trace = Trace(args.dp_trace_path).dataplane_trace event_logger = InputLogger() event_logger.open(results_dir="/tmp/events.trace") with open(args.input) as input_file: trace = parse(input_file) for event in trace: if type(event) == replay_events.TrafficInjection: event.dp_event = dp_trace.pop(0) event_logger.log_input_event(event) event_logger.output.close()
def main(args): with open(args.input) as input_file: trace = parse(input_file) # TODO(cs): binary search instead of linear? while len(trace) > 0 and trace[0].label_id < args.ti_id: trace.pop(0) ti_event = trace[0] if type(ti_event) != replay_events.TrafficInjection: raise ValueError("Event %s with is not a TrafficInjection" % str(ti_event)) pkt_fingerprint = DPFingerprint.from_pkt(ti_event.dp_event.packet) for event in trace: t = type(event) if t in dp_class_to_filter and dp_class_to_filter[t](event, pkt_fingerprint): for field in default_fields: field_formatters[field](event)
def main(args): with open(args.input) as input_file: trace = parse(input_file) # TODO(cs): binary search instead of linear? while len(trace) > 0 and trace[0].label_id < args.ti_id: trace.pop(0) ti_event = trace[0] if type(ti_event) != replay_events.TrafficInjection: raise ValueError("Event %s with is not a TrafficInjection" % str(ti_event)) pkt_fingerprint = DPFingerprint.from_pkt(ti_event.dp_event.packet) for event in trace: t = type(event) if t in dp_class_to_filter and dp_class_to_filter[t]( event, pkt_fingerprint): for field in default_fields: field_formatters[field](event)
def parse_event_trace(trace_path): with open(trace_path) as input_file: return EventDag(parse(input_file))