def port_shaper_disconnect_seq(test_step, forward_ep, src, src_stream, dst, dst_stream): expect_change = False if state.get_current().connected(src, src_stream, dst, dst_stream): forward_port = graph.get_forward_port(state.get_current(), src, dst, forward_ep['name']) if forward_port is not None: expect_change = graph.port_will_see_bandwidth_change(state.get_current(), src, src_stream, forward_ep['name'], forward_port, 'disconnect') if expect_change: expected = port_shaper_change_seq(test_step, forward_ep, forward_port, 'Decreasing') else: expected = port_shaper_no_change_seq(test_step, forward_ep) # When running a sequences of checkpointed tests don't check shaper bandwidth # figures for interim steps. Instead, keep track of the state per end-point so # that the final state can be returned at the last checkpoint. if test_step.checkpoint is not None: global final_port_shaper_states if expected: if forward_port is None: final_port_shaper_states['%s' % forward_ep['name']] = expected else: final_port_shaper_states['%s_%s' % (forward_ep['name'], forward_port)] = expected expected = [] return expected
def action_disconnect(args, test_step, expected, params_list): src = choose_src(params_list, 0) src_stream = choose_src_stream(params_list, 1) dst = choose_dst(params_list, 2) dst_stream = choose_dst_stream(params_list, 3) controller_disconnect(args, test_step, expected, src, dst_stream, dst, dst_stream) (talker_expect, listener_expect, controller_expect) = get_expected( args, test_step, src, src_stream, dst, dst_stream, 'disconnect') # Find the path between the src and dst and check whether there are any nodes between them forward_disable = [] nodes = endpoints.get_path_endpoints(graph.find_path(state.get_current(), src, dst)) for node in get_dual_port_nodes(nodes): if graph.node_will_see_stream_disable(state.get_current(), src, src_stream, dst, dst_stream, node): forward_disable += sequences.expected_seq('stream_forward_disable')(test_step, args.user, endpoints.get(node), endpoints.get(src)) forward_disable += sequences.expected_seq('port_shaper_disconnect')(test_step, endpoints.get(node), src, src_stream, dst, dst_stream) # If there are any nodes in the chain then the forward disabling is expected before the # audio will be seen to be lost if forward_disable and listener_expect: listener_expect = [Sequence([AllOf(forward_disable)] + listener_expect)] elif forward_disable: listener_expect = forward_disable elif listener_expect: listener_expect = listener_expect else: listener_expect = [] # Expect not to see any disables from other nodes not_forward_disable = [] temp_nodes = set(endpoints.get_all().keys()) - set(nodes) for node in get_dual_port_nodes(temp_nodes): not_forward_disable += sequences.expected_seq('stream_forward_disable')(test_step, args.user, endpoints.get(node), endpoints.get(src)) if not_forward_disable: if test_step.checkpoint is None: not_forward_disable = [NoneOf(not_forward_disable)] else: not_forward_disable = [] for node in get_dual_port_nodes(temp_nodes): not_forward_disable += sequences.expected_seq('port_shaper_disconnect')(test_step, endpoints.get(node), src, src_stream, dst, dst_stream) if test_step.checkpoint: final_port_shaper_states = sequences.get_and_clear_final_port_shaper_states() else: final_port_shaper_states = [] if test_step.do_checks and (talker_expect or listener_expect or controller_expect or not_forward_disable or final_port_shaper_states): expected += [AllOf(talker_expect + listener_expect + controller_expect + not_forward_disable + final_port_shaper_states)] yield args.master.expect(None)
def action_link_down(args, test_step, expected, params_list): analyzer_name = choose_analyzer(params_list, 0) checks = [] affected_talkers = set() # Expect all the connections which cross the relay to be lost for c,n in state.get_current().active_connections.iteritems(): if not n: continue path = graph.find_path(state.get_current(), c.talker.src, c.listener.dst) if path and analyzer_name in path: affected_talkers |= set([c.talker]) checks += [Expected(c.listener.dst, "ADP: Removing entity who timed out -> GUID", 30)] checks += sequences.analyzer_listener_disconnect_seq(test_step, c.talker.src, c.talker.src_stream, c.listener.dst, c.listener.dst_stream) state.get_next().disconnect(c.talker.src, c.talker.src_stream, c.listener.dst, c.listener.dst_stream) for talker in affected_talkers: if not state.get_next().talker_active_count(talker.src, talker.src_stream): checks += [Expected(talker.src, "Talker stream #%d off" % talker.src_stream, 30)] # Send the command to close the relay '(r)elay (c)lose' args.master.sendLine(analyzer_name, "r o") state.get_next().set_relay_open(analyzer_name) if test_step.do_checks and checks: expected += [AllOf(checks)] yield args.master.expect(None) else: # At least allow time for the relay to actually be closed yield base.sleep(0.1)
def check_clear_clock_masters(args, test_step, expected): for name,ep in endpoints.get_all().iteritems(): if state.get_current().is_clock_source_master(name) and not graph.is_in_loop(state.get_current(), ep['name']): args.master.sendLine(args.controller_id, "set_clock_source_slave 0x%s" % ( endpoints.guid_in_ascii(args.user, ep))) state.get_next().set_clock_source_slave(ep['name']) if test_step.do_checks: controller_expect = [Expected(args.controller_id, "Success", 5)] ep_expect = [Expected(ep['name'], "Setting clock source: INPUT_STREAM_DERIVED", 5)] if controller_expect or ep_expect: expected += [AllOf(controller_expect + ep_expect)]
def port_shaper_disconnect_seq(test_step, forward_ep, src, src_stream, dst, dst_stream): expect_change = False if state.get_current().connected(src, src_stream, dst, dst_stream): forward_port = graph.get_forward_port(state.get_current(), src, dst, forward_ep['name']) if forward_port is not None: expect_change = graph.port_will_see_bandwidth_change(state.get_current(), src, src_stream, forward_ep['name'], forward_port, 'disconnect') if expect_change: return port_shaper_change_seq(test_step, forward_ep, forward_port, 'Decreasing') else: return port_shaper_no_change_seq(test_step, forward_ep)
def analyzer_qav_seq(test_step, src, dst, action, user): """ Get the expected sequence for any QAV analyzers active. """ analyzer_expect = [] for analyzer_name,analyzer in analyzers.get_all().iteritems(): if analyzer['type'] != 'qav': continue # If the analyzer is a QAV analyzer then it will detect the stream through # the packets being forwarded through it if analyzer_name in graph.find_path(state.get_current(), src, dst): guid_string = endpoints.guid_in_ascii(user, endpoints.get(src)) stream_string = endpoints.stream_from_guid(guid_string) if action == 'connect': action_string = "Adding" completionFn = hook_register_error else: action_string = "Removing" completionFn = hook_unregister_error analyzer_expect += [Expected(analyzer_name, "%s stream 0x%s" % (action_string, stream_string), timeoutTime=10, completionFn=completionFn, completionArgs=(analyzer_name, ['ERROR']))] return analyzer_expect
def action_check_connections(args, test_step, expected, params_list): """ Check that the current state the controller reads from the endpoints matches the state the test framework expects. """ checks = [] # Expect all connections to be restored for c,n in state.get_current().active_connections.iteritems(): if n: if args.controller_type == 'python': checks += [Expected(args.controller_id, "0x%s\[%d\] -> 0x%s\[%d\]" % ( endpoints.guid_in_ascii(args.user, endpoints.get(c.talker.src)), c.talker.src_stream, endpoints.guid_in_ascii(args.user, endpoints.get(c.listener.dst)), c.listener.dst_stream), 10)] else: checks += [Expected(args.controller_id, "0x%s\[%d\] -> 0x%s\[%d\]" % ( endpoints.guid_in_ascii(args.user, endpoints.get(c.talker.src)).zfill(16), c.talker.src_stream, endpoints.guid_in_ascii(args.user, endpoints.get(c.listener.dst)).zfill(16), c.listener.dst_stream), 10)] print_title("Command: show_connections") args.master.sendLine(args.controller_id, "show connections") if test_step.do_checks: if checks: expected += [AllOf(checks)] elif test_step.checkpoint is None: expected += [NoneOf([Expected(args.controller_id, "->", 5)])] yield args.master.expect(None)
def action_discover(args, test_step, expected, params_list): if args.controller_type == 'c': # Can take up to 20 seconds to timeout entities which have disappeared yield base.sleep(20) print_title("Command: list") args.master.sendLine(args.controller_id, "list") yield base.sleep(2) else: args.master.clearExpectHistory(args.controller_id) print_title("Command: discover") args.master.sendLine(args.controller_id, "discover") yield args.master.expect(Expected(args.controller_id, "Found \d+ entities", 15)) # Actually check that the right number of entities have been seen visible_endpoints = graph.get_endpoints_connected_to(state.get_current(), args.controller_id) controller = getActiveProcesses()[args.controller_id] if len(controller.entities) != len(visible_endpoints): base.testError("Found %d entities, expecting %d" % (len(controller.entities), len(visible_endpoints)), critical=True) else: log_info("Found %d entities" % len(controller.entities)) yield args.master.expect(None)
def action_discover(args, test_step, expected, params_list): args.master.clearExpectHistory(args.controller_id) args.master.sendLine(args.controller_id, "discover") visible_endpoints = graph.get_endpoints_connected_to(state.get_current(), args.controller_id) if test_step.do_checks: expected += [Expected(args.controller_id, "Found %d entities" % len(visible_endpoints), 15)] yield args.master.expect(None)
def get_expected(args, test_step, src, src_stream, dst, dst_stream, command): state.get_current().dump() talker_state = state.get_current().get_talker_state(src, src_stream, dst, dst_stream, command) talker_expect = sequences.expected_seq(talker_state)(test_step, args.user, src, src_stream, dst, dst_stream) listener_state = state.get_current().get_listener_state(src, src_stream, dst, dst_stream, command) analyzer_state = "analyzer_" + listener_state analyzer_expect = sequences.expected_seq(analyzer_state)(test_step, src, src_stream, dst, dst_stream) analyzer_expect += sequences.analyzer_qav_seq(test_step, src, dst, command, args.user) if analyzer_expect: analyzer_expect = [AllOf(analyzer_expect)] listener_expect = sequences.expected_seq(listener_state)(test_step, dst, dst_stream, analyzer_expect) controller_state = state.get_current().get_controller_state(args.controller_id, src, src_stream, dst, dst_stream, command) controller_expect = sequences.expected_seq(controller_state)(test_step, args.controller_id) return (talker_expect, listener_expect, controller_expect)
def check_clear_clock_masters(args, test_step, expected): for name,ep in endpoints.get_all().iteritems(): if state.get_current().is_clock_source_master(name) and not graph.is_in_loop(state.get_current(), ep['name']): print_title("Command: set_clock_source_slave %s" % name) if args.controller_type == 'python': args.master.sendLine(args.controller_id, "set_clock_source_slave 0x%s" % ( endpoints.guid_in_ascii(args.user, ep))) else: select_endpoint(args, ep) args.master.sendLine(args.controller_id, "set clock_source 0 0 0") state.get_next().set_clock_source_slave(ep['name']) if test_step.do_checks: controller_expect = sequences.expected_seq('controller_success_set_clock_source')(args, test_step) ep_expect = [Expected(ep['name'], "Setting clock source: INPUT_STREAM_DERIVED", 5)] if controller_expect or ep_expect: expected += [AllOf(controller_expect + ep_expect)]
def check_set_clock_masters(args, test_step, expected): for loop in graph.get_loops(state.get_current()): loop_master = loop[0] for ep_name in loop: if state.get_current().is_clock_source_master(ep_name): loop_master = ep_name break if not state.get_current().is_clock_source_master(loop_master): ep = endpoints.get(loop_master) args.master.sendLine(args.controller_id, "set_clock_source_master 0x%s" % ( endpoints.guid_in_ascii(args.user, ep))) state.get_next().set_clock_source_master(ep['name']) if test_step.do_checks: controller_expect = [Expected(args.controller_id, "Success", 5)] ep_expect = [Expected(loop_master, "Setting clock source: LOCAL_CLOCK", 5)] if controller_expect or ep_expect: expected += [AllOf(controller_expect + ep_expect)]
def action_link_downup(args, test_step, expected, params_list): """ Expect all connections which bridge the relay to be lost and restored if there is a quick link down/up event. The first argument is the analyzer controlling the relay. The second is the time to sleep before restoring the link. """ analyzer_name = choose_analyzer(params_list, 0) sleep_time = int(params_list[1]) lost = [] # Expect all the connections which cross the relay to be lost for c,n in state.get_current().active_connections.iteritems(): if n and analyzer_name in graph.find_path(state.get_current(), c.talker.src, c.listener.dst): lost += sequences.analyzer_listener_disconnect_seq(test_step, c.talker.src, c.talker.src_stream, c.listener.dst, c.listener.dst_stream) # Send the command to open the relay '(r)elay (o)pen' args.master.sendLine(analyzer_name, "r o") state.get_next().set_relay_open(analyzer_name) if test_step.do_checks and lost: expected += [AllOf(lost)] # Perform a sleep as defined by the second argument yield base.sleep(sleep_time) found = [] # Expect all the connections which cross the relay to be restored state.get_next().set_relay_closed(analyzer_name) for c,n in state.get_current().active_connections.iteritems(): if n and analyzer_name in graph.find_path(state.get_current(), c.talker.src, c.listener.dst): found += sequences.analyzer_listener_connect_seq(test_step, c.talker.src, c.talker.src_stream, c.listener.dst, c.listener.dst_stream) # Send the command to close the relay '(r)elay (c)lose' args.master.sendLine(analyzer_name, "r c") if test_step.do_checks and found: expected += [AllOf(found)] yield args.master.expect(None)
def talker_self_connect_seq(test_step, user, src, src_stream, dst, dst_stream): """ Even though attempting to connect to self, the talker will become ready. Can only guarantee this message will be printed the first time the talker is activated. """ if state.get_current().get_talker_on_count(src): talker_connection = [] else: talker_connection = [Expected(src, "Talker stream #%d ready" % src_stream, 10)] return talker_connection
def talker_new_connect_seq(test_step, user, src, src_stream, dst, dst_stream): """ Only on the first time the talker is turned on must the 'ready' be seen. """ stream_id = endpoints.stream_from_guid(endpoints.guid_in_ascii(user, endpoints.get(src))) listener_mac = endpoints.mac_in_ascii(user, endpoints.get(dst)) seq = [Expected(src, "CONNECTING Talker stream #%d \(%s\) -> Listener %s" % (src_stream, stream_id, listener_mac), 10)] if not state.get_current().get_talker_on_count(src): seq += [Expected(src, "Talker stream #%d ready" % src_stream, 10)] seq += [Expected(src, "Talker stream #%d on" % src_stream, 10)] talker_connection = [Sequence(seq)] return talker_connection
def controller_enumerate_seq(args, test_step, endpoint_name): """ Build an enumerated sequence for an entity by reading from a topology file """ expected_seq = [] descriptors = endpoints.get(endpoint_name)['descriptors'] if args.controller_type == 'python': # The python controller reads the descriptors each time. The C controller has # them cached and so can always return the values. visible_endpoints = graph.get_endpoints_connected_to(state.get_current(), args.controller_id) if endpoint_name not in visible_endpoints: return [Expected(args.controller_id, "No descriptors found", 10, consumeOnMatch=True)] for dtor in sorted(descriptors.keys()): # Note that the .* is required because the STREAM_INPUT/STREAM_OUTPUT are mapped to the same descriptor temp_string = "AVB 1722\.1.*%s" % re.sub('\d*_', '', dtor, 1) expected_seq.append(Expected(args.controller_id, temp_string, 10, consumeOnMatch=True)) for dtor_name in descriptors[str(dtor)].keys(): temp_string = "object_name\s*=\s*\'%s\'" % dtor_name expected_seq.append(Expected(args.controller_id, temp_string, 10, consumeOnMatch=True)) for element in descriptors[str(dtor)][dtor_name]: element_type = element.get('type', 'none') if element_type == 'hex': temp_string = "%s\s*=\s*0x%x" % (element['item'], element['value']) elif element_type == 'state': value = eval('state.get_current().get_%s' % element['item'])(endpoint_name) temp_string = "%s\s*=\s*%s" % (element['item'], value) else: temp_string = "%s\s*=\s*%s" % (element['item'], element['value']) expected_seq.append(Expected(args.controller_id, temp_string, 10, consumeOnMatch=True)) else: for dtor in sorted(descriptors.keys()): temp_string = "descriptor_type: %s" % re.sub('\d*_', '', dtor, 1) expected_seq.append(Expected(args.controller_id, temp_string, 10, consumeOnMatch=True)) for dtor_name in descriptors[str(dtor)].keys(): temp_string = "object_name\s*=\s*%s" % dtor_name expected_seq.append(Expected(args.controller_id, temp_string, 10, consumeOnMatch=True)) for element in descriptors[str(dtor)][dtor_name]: element_type = element.get('type', 'none') if element_type == 'flag': temp_string = "%s\s*=\s*1" % element['value'].lower() elif element_type == 'state': value = eval('state.get_current().get_%s' % element['item'])(endpoint_name) temp_string = "%s\s*=\s*%s" % (element['item'], value) else: temp_string = "%s\s*=\s*%s" % (element['item'], element['value']) expected_seq.append(Expected(args.controller_id, temp_string, 10, consumeOnMatch=True)) return [Sequence(expected_seq)]
def talker_new_connect_seq(test_step, user, src, src_stream, dst, dst_stream): """ Only on the first time the talker is turned on must the 'ready' be seen. """ stream_id = endpoints.stream_from_guid(endpoints.guid_in_ascii(user, endpoints.get(src))) listener_mac = endpoints.mac_in_ascii(user, endpoints.get(dst)) seq = [Expected(src, "CONNECTING Talker stream #%d \(%s\) -> Listener %s" % (src_stream, stream_id, listener_mac), 10)] if not state.get_current().get_talker_on_count(src): seq += [Expected(src, "Talker stream #%d ready" % src_stream, 10)] seq += [Expected(src, "Talker stream #%d on" % src_stream, 10)] # If in a sequence of commands then the order cannot be guaranteed - so only # expect a Sequence when not checkpointing if test_step.checkpoint is None: talker_connection = [Sequence(seq)] else: talker_connection = [AllOf(seq)] return talker_connection
def controller_enumerate_seq(test_step, controller_id, endpoint_name): """ Build an enumerated sequence for an entity by reading from a topology file """ expected_seq = [] visible_endpoints = graph.get_endpoints_connected_to(state.get_current(), controller_id) if endpoint_name not in visible_endpoints: return [Expected(controller_id, "No descriptors found", 10)] descriptors = endpoints.get(endpoint_name)['descriptors'] for dtor in sorted(descriptors.keys()): temp_string = "AVB 1722.1 {0} ".format(re.sub('\d*_', '', dtor, 1)) expected_seq.append(Expected(controller_id, temp_string, 10)) for dtor_name in descriptors[str(dtor)].keys(): temp_string = "object_name\s*=\s*\'{0}\'".format(dtor_name) expected_seq.append(Expected(controller_id, temp_string, 10)) for element in descriptors[str(dtor)][dtor_name]: temp_string = "{0}\s*=\s*{1}".format(element['item'], element['value']) expected_seq.append(Expected(controller_id, temp_string, 10)) return [Sequence(expected_seq)]