def __init__(self, simulation_cfg, superlog_path_or_dag, create_event_scheduler=None, **kwargs): ControlFlow.__init__(self, simulation_cfg) self.sync_callback = ReplaySyncCallback(self.get_interpolated_time) if type(superlog_path_or_dag) == str: superlog_path = superlog_path_or_dag # The dag is codefied as a list, where each element has # a list of its dependents self.dag = EventDag(superlog_parser.parse_path(superlog_path)) else: self.dag = superlog_path_or_dag # compute interpolate to time to be just before first event self.compute_interpolated_time(self.dag.events[0]) if create_event_scheduler: self.create_event_scheduler = create_event_scheduler else: self.create_event_scheduler = \ lambda simulation: EventScheduler(simulation, **{ k: v for k,v in kwargs.items() if k in EventScheduler.kwargs })
def __init__(self, simulation_cfg, fuzzer_params="config.fuzzer_params", check_interval=None, traffic_inject_interval=10, random_seed=None, delay=0.1, steps=None, input_logger=None, invariant_check=InvariantChecker.check_correspondence, halt_on_violation=False, log_invariant_checks=True): ControlFlow.__init__(self, simulation_cfg) self.sync_callback = RecordingSyncCallback(input_logger) self.check_interval = check_interval self.invariant_check = invariant_check self.log_invariant_checks = log_invariant_checks self.traffic_inject_interval = traffic_inject_interval # Make execution deterministic to allow the user to easily replay if random_seed is None: self.random = random.Random() else: self.random = random.Random(random_seed) self.traffic_generator = TrafficGenerator(self.random) self.delay = delay self.steps = steps self.params = object() self._load_fuzzer_params(fuzzer_params) self._input_logger = input_logger self.halt_on_violation = halt_on_violation # Logical time (round #) for the simulation execution self.logical_time = 0
def __init__(self, simulation_cfg, superlog_path_or_dag, create_event_scheduler=None, print_buffers=True, wait_on_deterministic_values=False, fail_to_interactive=False, **kwargs): ControlFlow.__init__(self, simulation_cfg) if wait_on_deterministic_values: self.sync_callback = ReplaySyncCallback() else: self.sync_callback = ReplaySyncCallback(self.get_interpolated_time) if type(superlog_path_or_dag) == str: superlog_path = superlog_path_or_dag # The dag is codefied as a list, where each element has # a list of its dependents self.dag = EventDag(superlog_parser.parse_path(superlog_path)) else: self.dag = superlog_path_or_dag self.dp_checker = DataplaneChecker(self.dag) self.print_buffers = print_buffers # compute interpolate to time to be just before first event self.compute_interpolated_time(self.dag.events[0]) self.unexpected_state_changes = [] self.early_state_changes = [] self.event_scheduler_stats = None self.fail_to_interactive = fail_to_interactive if create_event_scheduler: self.create_event_scheduler = create_event_scheduler else: self.create_event_scheduler = \ lambda simulation: EventScheduler(simulation, **{ k: v for k,v in kwargs.items() if k in EventScheduler.kwargs })
def __init__(self, simulation_cfg, input_logger=None, pass_through_of_messages=True): ControlFlow.__init__(self, simulation_cfg) self.sync_callback = RecordingSyncCallback(input_logger) self.logical_time = 0 self._input_logger = input_logger self.traffic_generator = TrafficGenerator(random.Random()) # TODO(cs): we don't actually have a way to support pass_through=False, in # a reasonable way -- the user has no (easy) way to examine and route # OpenFlowBuffer's pending_receives and pending_sends. self.pass_through_of_messages = pass_through_of_messages
def __init__(self, simulation_cfg, fuzzer_params="config.fuzzer_params", check_interval=None, traffic_inject_interval=10, random_seed=None, delay=0.1, steps=None, input_logger=None, invariant_check_name="InvariantChecker.check_correspondence", halt_on_violation=False, log_invariant_checks=True, delay_startup=True, print_buffers=True, record_deterministic_values=False, mock_link_discovery=False, never_drop_whitelisted_packets=True, initialization_rounds=0): ''' Options: - fuzzer_params: path to event probabilities - check_interval: the period for checking invariants, in terms of logical rounds - traffic_inject_interval: how often to inject dataplane trace packets - random_seed: optionally set the seed of the random number generator - delay: how long to sleep between each logical round - input_logger: None, or a InputLogger instance - invariant_check_name: the name of the invariant check, from config/invariant_checks.py - halt_on_violation: whether to stop after a bug has been detected - log_invariant_checks: whether to log InvariantCheck events - delay_startup: whether to until the first OpenFlow message is received before proceeding with fuzzing - print_buffers: whether to print the remaining contents of the dataplane/controlplane buffers at the end of the execution - record_deterministic_values: whether to record gettimeofday requests for replay - mock_link_discovery: optional module for POX to experiment with better determinism -- tell POX exactly when links should be discovered - initialization_rounds: if non-zero, will wait the specified rounds to let the controller discover the topology before injecting inputs ''' ControlFlow.__init__(self, simulation_cfg) self.sync_callback = RecordingSyncCallback( input_logger, record_deterministic_values=record_deterministic_values) self.check_interval = check_interval if self.check_interval is None: print >> sys.stderr, "Fuzzer Warning: Check interval is not specified... not checking invariants" if invariant_check_name not in name_to_invariant_check: raise ValueError( '''Unknown invariant check %s.\n''' '''Invariant check name must be defined in config.invariant_checks''', invariant_check_name) self.invariant_check_name = invariant_check_name self.invariant_check = name_to_invariant_check[invariant_check_name] self.log_invariant_checks = log_invariant_checks self.traffic_inject_interval = traffic_inject_interval # Make execution deterministic to allow the user to easily replay if random_seed is None: random_seed = random.randint(0, sys.maxint) self.random_seed = random_seed self.random = random.Random(random_seed) self.traffic_generator = TrafficGenerator(self.random) self.delay = delay self.steps = steps self.params = object() self._load_fuzzer_params(fuzzer_params) self._input_logger = input_logger self.halt_on_violation = halt_on_violation self.delay_startup = delay_startup self.print_buffers = print_buffers self.mock_link_discovery = mock_link_discovery # How many rounds to let the controller initialize: # send one round of packets directed at the source host itself (to facilitate # learning), then send all-to-all packets until all pairs have been # pinged. Tell MCSFinder not to prune initial inputs during this period. self.initialization_rounds = initialization_rounds # If initialization_rounds isn't 0, also make sure to send all-to-all # pings before starting any events self._pending_all_to_all = initialization_rounds != 0 # Our current place in the all-to-all cycle. Stop when == len(hosts) self._all_to_all_iterations = 0 # How often (in terms of logical rounds) to inject all-to-all packets self._all_to_all_interval = 5 self.blocked_controller_pairs = [] self.unblocked_controller_pairs = [] # Logical time (round #) for the simulation execution self.logical_time = 0 self.never_drop_whitelisted_packets = never_drop_whitelisted_packets # Determine whether to use delayed and randomized flow mod processing # (Set by fuzzer_params, not by an optional __init__ argument) self.delay_flow_mods = False
def __init__(self, simulation_cfg, superlog_path_or_dag, create_event_scheduler=None, print_buffers=True, wait_on_deterministic_values=False, default_dp_permit=False, fail_to_interactive=False, fail_to_interactive_on_persistent_violations=False, end_in_interactive=False, input_logger=None, allow_unexpected_messages=False, expected_message_round_window=3, pass_through_whitelisted_messages=False, delay_flow_mods=False, invariant_check_name="", bug_signature="", end_wait_seconds=0.5, transform_dag=None, pass_through_sends=False, fail_fast=False, check_interval=5, **kwargs): ''' - If invariant_check_name is not None, check it at the end for the execution - If bug_signature is not None, check whether this particular signature appears in the output of the invariant check at the end of the execution ''' ControlFlow.__init__(self, simulation_cfg) # Label uniquely identifying this replay, set in init_results() self.replay_id = "N/A" self.logical_time = 0 if wait_on_deterministic_values: self.sync_callback = ReplaySyncCallback() else: self.sync_callback = ReplaySyncCallback(self.get_interpolated_time) if type(superlog_path_or_dag) == str: superlog_path = superlog_path_or_dag # The dag is codefied as a list, where each element has # a list of its dependents self.dag = EventDag(log_parser.parse_path(superlog_path)) else: self.dag = superlog_path_or_dag if len(self.dag.events) == 0: raise ValueError("No events to replay!") self.default_dp_permit = default_dp_permit self.dp_checker = self._setup_dp_checker(default_dp_permit) if self.default_dp_permit: # Set DataplanePermit and DataplaneDrop to passive if permit is set # to default # TODO(cs): rather than setting these to passive (which still causes them to # be scheduled as regular events) should these just be removed from the # event dag altogether? for event in [e for e in self.dag.events if type(e) in dp_events]: event.passive = default_dp_permit self.print_buffers_flag = print_buffers self.fail_fast = fail_fast self.check_interval = check_interval # compute interpolate to time to be just before first event self.compute_interpolated_time(self.dag.events[0]) # String repesentations of unexpected state changes we've passed through, for # statistics purposes. self.unexpected_state_changes = [] self.early_state_changes = [] self.event_scheduler_stats = None self.end_in_interactive = end_in_interactive self.fail_to_interactive = fail_to_interactive self.fail_to_interactive_on_persistent_violations =\ fail_to_interactive_on_persistent_violations self._input_logger = input_logger self.allow_unexpected_messages = allow_unexpected_messages self.expected_message_round_window = expected_message_round_window self.pass_through_whitelisted_messages = pass_through_whitelisted_messages self.pass_through_sends = pass_through_sends # How many logical rounds to peek ahead when deciding if a message is # expected or not. # String repesentations of unexpected messages we've passed through, for # statistics purposes. self.passed_unexpected_messages = [] self.delay_flow_mods = delay_flow_mods self.end_wait_seconds = end_wait_seconds self.transform_dag = transform_dag self.bug_signature = bug_signature self.invariant_check_name = invariant_check_name self.invariant_check = None if self.invariant_check_name: if self.invariant_check_name not in name_to_invariant_check: raise ValueError( '''Unknown invariant check %s.\n''' '''Invariant check name must be defined in config.invariant_checks''', self.invariant_check_name) self.invariant_check = name_to_invariant_check[ self.invariant_check_name] if self.pass_through_whitelisted_messages: for event in self.dag.events: if hasattr(event, "ignore_whitelisted_packets"): event.ignore_whitelisted_packets = True if self.simulation_cfg.ignore_interposition: self._ignore_interposition() if create_event_scheduler: self.create_event_scheduler = create_event_scheduler else: if self.default_dp_permit: # Tell EventScheduler to use call into us whenever it wants to sleep or # select, so that we can keep forwarding dataplane packets. kwargs[ 'sleep_continuation'] = self._sleep_with_dataplane_passthrough kwargs[ 'select_continuation'] = self._select_with_dataplane_passthrough self.create_event_scheduler = \ lambda simulation: EventScheduler(simulation, **{ k: v for k,v in kwargs.items() if k in EventScheduler.kwargs }) unknown_kwargs = [ k for k in kwargs.keys() if k not in EventScheduler.kwargs ] if unknown_kwargs != []: raise ValueError("Unknown kwargs %s" % str(unknown_kwargs))
def __init__(self, simulation_cfg, fuzzer_params="config.fuzzer_params", check_interval=None, traffic_inject_interval=10, random_seed=None, delay=0.1, steps=None, input_logger=None, invariant_check_name="InvariantChecker.check_correspondence", halt_on_violation=False, log_invariant_checks=True, delay_startup=True, print_buffers=True, record_deterministic_values=False, mock_link_discovery=False, never_drop_whitelisted_packets=True, initialization_rounds=0): ''' Options: - fuzzer_params: path to event probabilities - check_interval: the period for checking invariants, in terms of logical rounds - traffic_inject_interval: how often to inject dataplane trace packets - random_seed: optionally set the seed of the random number generator - delay: how long to sleep between each logical round - input_logger: None, or a InputLogger instance - invariant_check_name: the name of the invariant check, from config/invariant_checks.py - halt_on_violation: whether to stop after a bug has been detected - log_invariant_checks: whether to log InvariantCheck events - delay_startup: whether to until the first OpenFlow message is received before proceeding with fuzzing - print_buffers: whether to print the remaining contents of the dataplane/controlplane buffers at the end of the execution - record_deterministic_values: whether to record gettimeofday requests for replay - mock_link_discovery: optional module for POX to experiment with better determinism -- tell POX exactly when links should be discovered - initialization_rounds: if non-zero, will wait the specified rounds to let the controller discover the topology before injecting inputs ''' ControlFlow.__init__(self, simulation_cfg) self.sync_callback = RecordingSyncCallback(input_logger, record_deterministic_values=record_deterministic_values) self.check_interval = check_interval if self.check_interval is None: print >> sys.stderr, "Fuzzer Warning: Check interval is not specified... not checking invariants" if invariant_check_name not in name_to_invariant_check: raise ValueError('''Unknown invariant check %s.\n''' '''Invariant check name must be defined in config.invariant_checks''', invariant_check_name) self.invariant_check_name = invariant_check_name self.invariant_check = name_to_invariant_check[invariant_check_name] self.log_invariant_checks = log_invariant_checks self.traffic_inject_interval = traffic_inject_interval # Make execution deterministic to allow the user to easily replay if random_seed is None: random_seed = random.randint(0, sys.maxint) self.random_seed = random_seed self.random = random.Random(random_seed) self.traffic_generator = TrafficGenerator(self.random) self.delay = delay self.steps = steps self.params = object() self._load_fuzzer_params(fuzzer_params) self._input_logger = input_logger self.halt_on_violation = halt_on_violation self.delay_startup = delay_startup self.print_buffers = print_buffers self.mock_link_discovery = mock_link_discovery # How many rounds to let the controller initialize: # send one round of packets directed at the source host itself (to facilitate # learning), then send all-to-all packets until all pairs have been # pinged. Tell MCSFinder not to prune initial inputs during this period. self.initialization_rounds = initialization_rounds # If initialization_rounds isn't 0, also make sure to send all-to-all # pings before starting any events self._pending_all_to_all = initialization_rounds != 0 # Our current place in the all-to-all cycle. Stop when == len(hosts) self._all_to_all_iterations = 0 # How often (in terms of logical rounds) to inject all-to-all packets self._all_to_all_interval = 5 self.blocked_controller_pairs = [] self.unblocked_controller_pairs = [] # Logical time (round #) for the simulation execution self.logical_time = 0 self.never_drop_whitelisted_packets = never_drop_whitelisted_packets # Determine whether to use delayed and randomized flow mod processing # (Set by fuzzer_params, not by an optional __init__ argument) self.delay_flow_mods = False
def __init__(self, simulation_cfg, superlog_path_or_dag, create_event_scheduler=None, print_buffers=True, wait_on_deterministic_values=False, default_dp_permit=False, fail_to_interactive=False, fail_to_interactive_on_persistent_violations=False, end_in_interactive=False, input_logger=None, allow_unexpected_messages=False, expected_message_round_window=3, pass_through_whitelisted_messages=False, delay_flow_mods=False, invariant_check_name="", bug_signature="", end_wait_seconds=0.5, transform_dag=None, pass_through_sends=False, **kwargs): ''' - If invariant_check_name is not None, check it at the end for the execution - If bug_signature is not None, check whether this particular signature appears in the output of the invariant check at the end of the execution ''' ControlFlow.__init__(self, simulation_cfg) # Label uniquely identifying this replay, set in init_results() self.replay_id = "N/A" self.logical_time = 0 if wait_on_deterministic_values: self.sync_callback = ReplaySyncCallback() else: self.sync_callback = ReplaySyncCallback(self.get_interpolated_time) if type(superlog_path_or_dag) == str: superlog_path = superlog_path_or_dag # The dag is codefied as a list, where each element has # a list of its dependents self.dag = EventDag(log_parser.parse_path(superlog_path)) else: self.dag = superlog_path_or_dag if len(self.dag.events) == 0: raise ValueError("No events to replay!") self.default_dp_permit = default_dp_permit # Set DataplanePermit and DataplaneDrop to passive if permit is set # to default for event in [ e for e in self.dag.events if type(e) in dp_events ]: event.passive = default_dp_permit self.dp_checker = None no_dp_drops = [ e for e in self.dag.events if type(e) == DataplaneDrop ] == [] if not default_dp_permit and no_dp_drops: print >> sys.stderr, ('''No DataplaneDrops to replay. We suggest you ''' '''set Replayer's default_dp_permit=True ''') if default_dp_permit: if no_dp_drops: self.dp_checker = AlwaysAllowDataplane(self.dag) else: self.dp_checker = DataplaneChecker(self.dag) self.print_buffers_flag = print_buffers # compute interpolate to time to be just before first event self.compute_interpolated_time(self.dag.events[0]) # String repesentations of unexpected state changes we've passed through, for # statistics purposes. self.unexpected_state_changes = [] self.early_state_changes = [] self.event_scheduler_stats = None self.end_in_interactive = end_in_interactive self.fail_to_interactive = fail_to_interactive self.fail_to_interactive_on_persistent_violations =\ fail_to_interactive_on_persistent_violations self._input_logger = input_logger self.allow_unexpected_messages = allow_unexpected_messages self.expected_message_round_window = expected_message_round_window self.pass_through_whitelisted_messages = pass_through_whitelisted_messages self.pass_through_sends = pass_through_sends # How many logical rounds to peek ahead when deciding if a message is # expected or not. # String repesentations of unexpected messages we've passed through, for # statistics purposes. self.passed_unexpected_messages = [] self.delay_flow_mods = delay_flow_mods self.end_wait_seconds = end_wait_seconds self.transform_dag = transform_dag self.bug_signature = bug_signature self.invariant_check_name = invariant_check_name self.invariant_check = None if self.invariant_check_name: if self.invariant_check_name not in name_to_invariant_check: raise ValueError('''Unknown invariant check %s.\n''' '''Invariant check name must be defined in config.invariant_checks''', self.invariant_check_name) self.invariant_check = name_to_invariant_check[self.invariant_check_name] if self.pass_through_whitelisted_messages: for event in self.dag.events: if hasattr(event, "ignore_whitelisted_packets"): event.ignore_whitelisted_packets = True if create_event_scheduler: self.create_event_scheduler = create_event_scheduler else: self.create_event_scheduler = \ lambda simulation: EventScheduler(simulation, **{ k: v for k,v in kwargs.items() if k in EventScheduler.kwargs }) unknown_kwargs = [ k for k in kwargs.keys() if k not in EventScheduler.kwargs ] if unknown_kwargs != []: raise ValueError("Unknown kwargs %s" % str(unknown_kwargs))
def __init__(self, simulation_cfg, input_logger=None): ControlFlow.__init__(self, simulation_cfg) self.sync_callback = RecordingSyncCallback(input_logger) self.logical_time = 0 self._input_logger = input_logger
def __init__( self, simulation_cfg, fuzzer_params="config.fuzzer_params", check_interval=None, traffic_inject_interval=10, random_seed=None, delay=0.1, steps=None, input_logger=None, invariant_check_name="InvariantChecker.check_correspondence", halt_on_violation=False, log_invariant_checks=True, delay_startup=True, print_buffers=True, record_deterministic_values=False, mock_link_discovery=False, initialization_rounds=0, ): ControlFlow.__init__(self, simulation_cfg) self.sync_callback = RecordingSyncCallback( input_logger, record_deterministic_values=record_deterministic_values ) self.check_interval = check_interval if invariant_check_name not in name_to_invariant_check: raise ValueError( """Unknown invariant check %s.\n""" """Invariant check name must be defined in config.invariant_checks""", invariant_check_name, ) self.invariant_check_name = invariant_check_name self.invariant_check = name_to_invariant_check[invariant_check_name] self.log_invariant_checks = log_invariant_checks self.traffic_inject_interval = traffic_inject_interval # Make execution deterministic to allow the user to easily replay if random_seed is None: random_seed = random.randint(0, sys.maxint) self.random_seed = random_seed self.random = random.Random(random_seed) self.traffic_generator = TrafficGenerator(self.random) self.delay = delay self.steps = steps self.params = object() self._load_fuzzer_params(fuzzer_params) self._input_logger = input_logger self.halt_on_violation = halt_on_violation self.delay_startup = delay_startup self.print_buffers = print_buffers self.mock_link_discovery = mock_link_discovery # How many rounds to let the controller initialize: # send one round of packets directed at the source host itself (to facilitate # learning), then send all-to-all packets until all pairs have been # pinged. Tell MCSFinder not to prune initial inputs during this period. self.initialization_rounds = initialization_rounds # If initialization_rounds isn't 0, also make sure to send all-to-all # pings before starting any events self._pending_all_to_all = initialization_rounds != 0 # Our current place in the all-to-all cycle. Stop when == len(hosts) self._all_to_all_iterations = 0 # How often (in terms of logical rounds) to inject all-to-all packets self._all_to_all_interval = 5 # Logical time (round #) for the simulation execution self.logical_time = 0
def __init__(self, simulation_cfg, input_logger=None): ControlFlow.__init__(self, simulation_cfg) self.sync_callback = RecordingSyncCallback(input_logger) self.logical_time = 0 self._input_logger = input_logger self.traffic_generator = TrafficGenerator(random.Random())
def __init__(self, simulation_cfg, superlog_path_or_dag, create_event_scheduler=None, print_buffers=True, wait_on_deterministic_values=False, default_dp_permit=False, fail_to_interactive=False, fail_to_interactive_on_persistent_violations=False, end_in_interactive=False, input_logger=None, allow_unexpected_messages=False, expected_message_round_window=3, pass_through_whitelisted_messages=False, delay_flow_mods=False, invariant_check_name="", bug_signature="", end_wait_seconds=0.5, transform_dag=None, pass_through_sends=False, fail_fast=False, check_interval=5, **kwargs): ''' - If invariant_check_name is not None, check it at the end for the execution - If bug_signature is not None, check whether this particular signature appears in the output of the invariant check at the end of the execution ''' ControlFlow.__init__(self, simulation_cfg) # Label uniquely identifying this replay, set in init_results() self.replay_id = "N/A" self.logical_time = 0 if wait_on_deterministic_values: self.sync_callback = ReplaySyncCallback() else: self.sync_callback = ReplaySyncCallback(self.get_interpolated_time) if type(superlog_path_or_dag) == str: superlog_path = superlog_path_or_dag # The dag is codefied as a list, where each element has # a list of its dependents self.dag = EventDag(log_parser.parse_path(superlog_path)) else: self.dag = superlog_path_or_dag if len(self.dag.events) == 0: raise ValueError("No events to replay!") self.default_dp_permit = default_dp_permit self.dp_checker = self._setup_dp_checker(default_dp_permit) if self.default_dp_permit: # Set DataplanePermit and DataplaneDrop to passive if permit is set # to default # TODO(cs): rather than setting these to passive (which still causes them to # be scheduled as regular events) should these just be removed from the # event dag altogether? for event in [ e for e in self.dag.events if type(e) in dp_events ]: event.passive = default_dp_permit self.print_buffers_flag = print_buffers self.fail_fast = fail_fast self.check_interval = check_interval # compute interpolate to time to be just before first event self.compute_interpolated_time(self.dag.events[0]) # String repesentations of unexpected state changes we've passed through, for # statistics purposes. self.unexpected_state_changes = [] self.early_state_changes = [] self.event_scheduler_stats = None self.end_in_interactive = end_in_interactive self.fail_to_interactive = fail_to_interactive self.fail_to_interactive_on_persistent_violations =\ fail_to_interactive_on_persistent_violations self._input_logger = input_logger self.allow_unexpected_messages = allow_unexpected_messages self.expected_message_round_window = expected_message_round_window self.pass_through_whitelisted_messages = pass_through_whitelisted_messages self.pass_through_sends = pass_through_sends # How many logical rounds to peek ahead when deciding if a message is # expected or not. # String repesentations of unexpected messages we've passed through, for # statistics purposes. self.passed_unexpected_messages = [] self.delay_flow_mods = delay_flow_mods self.end_wait_seconds = end_wait_seconds self.transform_dag = transform_dag self.bug_signature = bug_signature self.invariant_check_name = invariant_check_name self.invariant_check = None if self.invariant_check_name: if self.invariant_check_name not in name_to_invariant_check: raise ValueError('''Unknown invariant check %s.\n''' '''Invariant check name must be defined in config.invariant_checks''', self.invariant_check_name) self.invariant_check = name_to_invariant_check[self.invariant_check_name] if self.pass_through_whitelisted_messages: for event in self.dag.events: if hasattr(event, "ignore_whitelisted_packets"): event.ignore_whitelisted_packets = True if self.simulation_cfg.ignore_interposition: self._ignore_interposition() if create_event_scheduler: self.create_event_scheduler = create_event_scheduler else: if self.default_dp_permit: # Tell EventScheduler to use call into us whenever it wants to sleep or # select, so that we can keep forwarding dataplane packets. kwargs['sleep_continuation'] = self._sleep_with_dataplane_passthrough kwargs['select_continuation'] = self._select_with_dataplane_passthrough self.create_event_scheduler = \ lambda simulation: EventScheduler(simulation, **{ k: v for k,v in kwargs.items() if k in EventScheduler.kwargs }) unknown_kwargs = [ k for k in kwargs.keys() if k not in EventScheduler.kwargs ] if unknown_kwargs != []: raise ValueError("Unknown kwargs %s" % str(unknown_kwargs))
def __init__(self, simulation_cfg, superlog_path_or_dag, create_event_scheduler=None, print_buffers=True, wait_on_deterministic_values=False, default_dp_permit=False, fail_to_interactive=False, fail_to_interactive_on_persistent_violations=False, end_in_interactive=False, input_logger=None, allow_unexpected_messages=False, pass_through_whitelisted_messages=True, delay_flow_mods=False, **kwargs): ControlFlow.__init__(self, simulation_cfg) if wait_on_deterministic_values: self.sync_callback = ReplaySyncCallback() else: self.sync_callback = ReplaySyncCallback(self.get_interpolated_time) if type(superlog_path_or_dag) == str: superlog_path = superlog_path_or_dag # The dag is codefied as a list, where each element has # a list of its dependents self.dag = EventDag(log_parser.parse_path(superlog_path)) else: self.dag = superlog_path_or_dag if len(self.dag.events) == 0: raise ValueError("No events to replay!") self.default_dp_permit = default_dp_permit # Set DataplanePermit and DataplaneDrop to passive if permit is set # to default for event in [ e for e in self.dag.events if type(e) in dp_events ]: event.passive = default_dp_permit self.dp_checker = None if default_dp_permit: self.dp_checker = DataplaneChecker(self.dag) self.print_buffers_flag = print_buffers # compute interpolate to time to be just before first event self.compute_interpolated_time(self.dag.events[0]) # String repesentations of unexpected state changes we've passed through, for # statistics purposes. self.unexpected_state_changes = [] self.early_state_changes = [] self.event_scheduler_stats = None self.end_in_interactive = end_in_interactive self.fail_to_interactive = fail_to_interactive self.fail_to_interactive_on_persistent_violations =\ fail_to_interactive_on_persistent_violations self._input_logger = input_logger self.allow_unexpected_messages = allow_unexpected_messages self.pass_through_whitelisted_messages = pass_through_whitelisted_messages # How many logical rounds to peek ahead when deciding if a message is # expected or not. self.expected_message_round_window = 3 # String repesentations of unexpected messages we've passed through, for # statistics purposes. self.passed_unexpected_messages = [] self.delay_flow_mods = delay_flow_mods if self.pass_through_whitelisted_messages: for event in self.dag.events: if hasattr(event, "ignore_whitelisted_packets"): event.ignore_whitelisted_packets = True if create_event_scheduler: self.create_event_scheduler = create_event_scheduler else: self.create_event_scheduler = \ lambda simulation: EventScheduler(simulation, **{ k: v for k,v in kwargs.items() if k in EventScheduler.kwargs })