Example #1
0
  def get_talker_state(self, src, src_stream, dst, dst_stream, action):
    if graph.find_path(self, src, dst) is None:
      state = 'talker_redundant'

    elif action == 'connect':
      if self.connected(src, src_stream, dst, dst_stream):
        state = 'talker_redundant'
      else:
        if self.listener_active_count(dst, dst_stream):
          state = 'talker_redundant'
        elif self.talker_active_count(src, src_stream):
          state = 'talker_existing'
        else:
          state = 'talker_new'

    elif action == 'disconnect':
      if not self.connected(src, src_stream, dst, dst_stream):
        state = 'talker_redundant'
      else:
        if self.talker_active_count(src, src_stream) == 1:
          state = 'talker_all'
        else:
          state = 'talker_existing'

    else:
      base.testError("Unknown action '%s'" % action, critical=True)

    log_debug("get_talker_state for %s %d %s %d: %s" % (src, src_stream, dst, dst_stream, state))
    return (state + '_' + action)
Example #2
0
def get_endpoints_connected_to(state, node):
  connected = set()
  for endpoint in endpoints.get_all():
    if find_path(state, node, endpoint):
      connected |= set([endpoint])
  log_debug("get_endpoints_connected_to %s: %s" % (node, connected))
  return connected
Example #3
0
  def get_controller_state(self, controller_id, src, src_stream, dst, dst_stream, action):
    controllable_endpoints = graph.get_endpoints_connected_to(self, controller_id)
    if src not in controllable_endpoints or dst not in controllable_endpoints:
      state = 'timeout'

    elif action == 'connect':
      if src == dst:
        if self.listener_active_count(dst, dst_stream):
          state = 'listener_exclusive'
        else:
          state = 'listener_talker_timeout'
      elif self.connected(src, src_stream, dst, dst_stream):
        state = 'success'
      elif self.listener_active_count(dst, dst_stream):
        state = 'listener_exclusive'
      else:
        state = 'success'

    elif action == 'disconnect':
      if not self.connected(src, src_stream, dst, dst_stream):
        state = 'redundant'
      else:
        state = 'success'

    else:
      base.testError("Unknown action '%s'" % action, critical=True)

    log_debug("get_controller_state for %s %d %s %d: %s" % (src, src_stream, dst, dst_stream, state))
    return ('controller_' + state + '_' + action)
Example #4
0
def is_in_loop(state, node):
  in_loop = False
  loops = get_loops(state)
  for loop in loops:
    if node in loop:
      in_loop = True
      break

  log_debug("is_in_loop %s = %d" % (node, in_loop))
  return in_loop
Example #5
0
def get_eth_id(args):
  """ Get the ethernet interface ID for the current user
  """
  with open('eth.json') as f:
    eth = json.load(f)

  if args.user not in eth:
    log_debug('User %s missing from eth.json' % args.user)
    sys.exit(1)

  return eth[args.user]
Example #6
0
def get_loops(state):
  """ Find all the loops in the current set of connections.
  """
  loops = []

  for t,n in state.active_talkers.iteritems():
    # If the endpoint is not active or already in a loop then ignore it
    if not n or any(t.src in loop for loop in loops):
      continue

    _get_loops(state, t.src, [t.src], loops)

  log_debug("get_loops got %s" % loops)
  return loops
Example #7
0
def node_will_see_stream_enable(state, src, src_stream, dst, dst_stream, node):
  """ Determine whether a given node will see the stream between src/dst as a new
      stream. Returns True if it will be a new stream, False if it is an existing
      stream.
  """
  log_debug("node_will_see_stream_enable %s ?" % node)
  if (state.connected(src, src_stream, dst, dst_stream) or
      state.listener_active_count(dst, dst_stream)):
    # Connection will have no effect
    log_debug("No, connection will not happen")
    return False

  # Look at all connections of this src stream
  for c,n in state.active_connections.iteritems():
    if not n or c.talker.src != src or c.talker.src_stream != src_stream:
      continue

    nodes = find_path(state, src, c.listener.dst)
    log_debug("What about path %s?" % nodes)
      
    # Look for all nodes past this one in the path. If one of them is connected to
    # this stream then this node won't see enable, otherwise it should expect to
    past_node = False
    for n in nodes:
      if past_node:
        if state.connected(src, src_stream, n):
          log_debug("No forwarding, node %s is connected beyond %s?" % (n, node))
          return False

      elif n == node:
        past_node = True

  return True
Example #8
0
def get_forward_port(state, src, dst, node):
  """ Find the port name that is used to forward out of a node on a path from
      src -> dst. This is done by finding the node in the path. Its forwarding
      port name is the next node in the path. The port ID is the last character
      of that name.
  """
  port = None
  try:
    path = find_path(state, src, dst)
    index = path.index(node)
    port_name = path[index + 1]
    port = int(port_name[-1])
  except:
    pass

  log_debug("get_forward_port %s in %s -> %s: %s" % (node, src, dst, port))
  return port
Example #9
0
def port_will_see_bandwidth_change(state, src, src_stream, ep_name, port, command):
  num_active_streams = 0
  
  # Look at all connections of this src stream
  for c,n in state.active_connections.iteritems():
    if not n or c.talker.src != src or c.talker.src_stream != src_stream:
      continue

    if port_is_egress_in_path(state, c, ep_name, port):
      num_active_streams += 1

  log_debug("port_will_see_bandwidth_change found %d active streams for %s:%s" % (
        num_active_streams, ep_name, port))

  if command == 'connect':
    # On connect the bandwidth should only change if this stream is not currently
    # forwarded through this port
    return num_active_streams == 0
  else:
    # On disconnect the bandwidth should only change if there is 1 active
    # stream as this will be removed
    return num_active_streams == 1
Example #10
0
  def connected(self, src, src_stream, dst, dst_stream=None):
    """ Check whether a src stream is connected to a dest node. Can specify the
        dest stream if desired.
    """
    talker = Talker(src, src_stream)
    listener = Listener(dst, dst_stream)
    connected = False
    if dst_stream:
      connection = Connection(talker, listener)
      if self.active_connections.get(connection, 0):
          connected = True

    else:
      for c,n in self.active_connections.iteritems():
        if not n:
          continue

        if c.talker == talker and c.listener.dst == dst:
          connected = True

    # Note that the format of each operand is %s because that copes with a None
    log_debug("connected %s %s %s %s ? %s" % (src, src_stream, dst, dst_stream, connected))
    return connected
Example #11
0
def node_will_see_stream_disable(state, src, src_stream, dst, dst_stream, node):
  """ Determine whether a given node will see being disabled if it is turned off.
  """
  log_debug("node_will_see_stream_disable %s ?" % node)
  if not state.connected(src, src_stream, dst, dst_stream):
    # Disconnection will have no effect
    log_debug("No, stream not connected")
    return False

  # Look at all connections of this src stream
  for c,n in state.active_connections.iteritems():
    if not n:
      continue

    if c.talker.src != src or c.talker.src_stream != src_stream:
      continue

    nodes = find_path(state, src, c.listener.dst)
    log_debug("What about path %s?" % nodes)
      
    # Look for all nodes past this one in the path. If one of them is connected to
    # this stream then this node won't see disable, otherwise it should expect to
    past_node = False
    for n in nodes:
      if n == dst:
        # Ignore the current connection
        continue

      if past_node:
        if state.connected(src, src_stream, n):
          log_debug("No forwarding, node %s is connected beyond %s?" % (n, node))
          return False

      elif n == node:
        past_node = True

  return True
Example #12
0
def runTest(args):
  """ The test program - needs to yield on each expect and be decorated
    with @inlineCallbacks
  """

  startup = AllOf([Expected(e, "Started", 10) for e in endpoints])
  log_debug(startup)
  yield master.expect(startup)

  next_steps = AllOf([AllOf([Expected('ep0', "Next", 10)]), AllOf([Expected('ep1', "Next", 10)])])
  log_debug(next_steps)
  yield master.expect(next_steps)

  seq = AllOf([Sequence([Expected(e, "Count0", 10), Expected(e, "Count1", 10)]) for e in endpoints])
  log_debug(seq)
  yield master.expect(seq)

  base.testComplete(reactor)
Example #13
0
def find_path(state, start, end, path=[]):
  """ A front-end for debug purposes
  """
  path = _find_path(state, start, end)
  log_debug("find_path %s -> %s : %s" % (start, end, path))
  return path
Example #14
0
def draw_state(s, ep_names):
  """ Draw a graph of the connections.
      Creates the endpoints down the left.
      Creates connections at a depth to right which depends on the talker index.
  """
  ep_offset = 0
  ep_num = 0
  active_talkers = set()
  num_endpoints = len(ep_names)
  lines = []

  # The endpoints are rendered over 5 lines (start, out, name, in, end)
  # and then there is a 1-line gap between.
  num_lines = num_endpoints * 5 + num_endpoints - 1
  for line_num in range(0, num_lines):
    ep_name = ep_names[ep_num]
    line = ""
    if ep_offset == 0 or ep_offset == 4:
      line += get_header(s, ep_name)
      line += "  " + non_connection_line(ep_names, active_talkers)

    elif ep_offset == 1:
      line += " |      | "
      if s.talker_active_count(ep_name, 0):
        max_listener_index = get_max_listener_index(s, ep_names, ep_name)

        if max_listener_index > ep_num:
          active_talkers |= set([ep_name])
        else:
          if ep_name in active_talkers:
            active_talkers.remove(ep_name)
        line += "--"
        line += connection_line(ep_names, ep_num, active_talkers)
      else:
        line += "  " + non_connection_line(ep_names, active_talkers)

    elif ep_offset == 2:
      line += " | %-4s | " % ep_name
      line += "  " + non_connection_line(ep_names, active_talkers)

    elif ep_offset == 3:
      line += " |      | "
      if s.listener_active_count(ep_name, 0):
        talker = get_talker_for_listener(s, ep_name)
        talker_index = ep_names.index(talker)
        if talker_index > ep_num:
          active_talkers |= set([talker])
        else:
          max_listener_index = get_max_listener_index(s, ep_names, talker)
          if max_listener_index <= ep_num and talker in active_talkers:
            active_talkers.remove(talker)

        line += "<-"
        line += connection_line(ep_names, talker_index, active_talkers)
      else:
        line += "  " + non_connection_line(ep_names, active_talkers)

    else:
      line += "          "
      line += "  " + non_connection_line(ep_names, active_talkers)
      ep_num += 1
      ep_offset = -1

    ep_offset += 1
    lines += [line]

  for line in lines:
    log_debug(line)
Example #15
0
  def dump(self):
    log_debug("State:")
    for t,n in self.active_talkers.iteritems():
      log_debug("Talker %s : %d" % (t, n))
    for l,n in self.active_listeners.iteritems():
      log_debug("Listeners %s : %d" % (l, n))
    for c,n in self.active_connections.iteritems():
      log_debug("Connection %s : %d" % (c, n))
    for c,n in self.talker_on_count.iteritems():
      log_debug("Talker on count %s : %d" % (c, n))
    for c,n in self.clock_source_master.iteritems():
      if n:
        log_debug("Clock source master %s" % c)

    rendering.draw_state(self, sorted(endpoints.get_all().keys()))