def test_contains(self):
        """Test creating a :class:`addr.PortList` with valid ports.

        Then check that ``__contains__`` works properly.
        """
        ports = (443, 9001, 9030)
        portList = addr.PortList(*ports)
        self.assertIn(443, portList)
    def test_str(self):
        """Test creating a :class:`addr.PortList` with valid ports.

        Then check that ``__str__`` works properly.
        """
        ports = (443, 9001, 9030)
        portList = addr.PortList(*ports)
        self.assertTrue(isinstance(str(portList), basestring))
        for port in ports:
            self.assertIn(str(port), str(portList))
    def test_iter(self):
        """Test creating a :class:`addr.PortList` with valid ports.

        Then check that ``__iter__`` works properly.
        """
        ports = (443, 9001, 9030)
        portList = addr.PortList(*ports)
        iterator = iter(portList)
        for x in xrange(len(ports)):
            self.assertIn(iterator.next(), portList)
    def test_tooManyPorts(self):
        """Create a :class:`addr.PortList` with more than the maximum
        allowed ports, as given in ``PortList.PORTSPEC_LEN``.

        We don't currently do anything to deal with a PortList having too many
        ports.
        """
        tooMany = addr.PortList.PORTSPEC_LEN + 1
        ports = [self.getRandomPort() for x in xrange(tooMany)]
        log.msg("Testing addr.PortList(%s))" %
                ', '.join([type('')(port) for port in ports]))
        portList = addr.PortList(*ports)
        self.assertEqual(len(portList), tooMany)
def fakeBridge6(orport=8080,
                running=True,
                stable=True,
                or_addresses=False,
                transports=False):
    nn = "bridge-%s" % random.randrange(0, 1000000)
    ip = ipaddr.IPAddress(randomIPv6())
    fp = "".join([random.choice("0123456789ABCDEF") for _ in xrange(40)])
    b = bridgedb.Bridges.Bridge(nn, ip, orport, fingerprint=fp)
    b.setStatus(running, stable)

    oraddrs = []
    if or_addresses:
        for i in xrange(8):
            # Only add or_addresses if they are valid. Otherwise, the test
            # will randomly fail if an invalid address is chosen:
            address = randomIPv6()
            portlist = addr.PortList(randomPortSpec())
            if addr.isValidIP(address):
                address = bracketIPv6(address)
                oraddrs.append((
                    address,
                    portlist,
                ))

    for address, portlist in oraddrs:
        networkstatus.parseALine("{0}:{1}".format(address, portlist))
        try:
            portlist.add(b.or_addresses[address])
        except KeyError:
            pass
        finally:
            b.or_addresses[address] = portlist

            try:
                portlist.add(b.or_addresses[address])
            except KeyError:
                pass
            finally:
                b.or_addresses[address] = portlist

    if transports:
        for i in xrange(0, 8):
            b.transports.append(
                bridgedb.Bridges.PluggableTransport(
                    b, random.choice(["obfs", "obfs2", "pt1"]), randomIP(),
                    randomPort()))

    return b
 def test_mixedArgs(self):
     """Create a :class:`addr.PortList` with mixed type parameters."""
     firstList = addr.PortList('1111,2222,3333')
     portList = addr.PortList(443, "9001,9030, 9050", firstList)
     self.assertTrue(portList)
 def test_getitem_long(self):
     """Test ``__getitem__`` with a string."""
     ports = (443, 9001, 9030)
     portList = addr.PortList(*ports)
     self.assertEqual(portList.__getitem__(long(0)), 9001)
 def test_getitem_string(self):
     """Test ``__getitem__`` with a string."""
     ports = (443, 9001, 9030)
     portList = addr.PortList(*ports)
     self.assertRaises(TypeError, portList.__getitem__, '443')
 def test_getitem_shouldNotContain(self):
     """Test ``__getitem__`` with a port number not in the PortList."""
     ports = (443, 9001, 9030)
     portList = addr.PortList(*ports)
     self.assertRaises(IndexError, portList.__getitem__, 555)
 def test_getitem_shouldContain(self):
     """Test ``__getitem__`` with a port number in the PortList."""
     ports = (443, 9001, 9030)
     portList = addr.PortList(*ports)
     self.assertEqual(portList.__getitem__(0), 9001)
 def test_tooFewPorts(self):
     """Create a :class:`addr.PortList` with no ports at all."""
     portList = addr.PortList()
     self.assertEqual(len(portList), 0)
def parseALine(line, fingerprint=None):
    """Parse an 'a'-line of a bridge networkstatus document.

    From torspec.git/dir-spec.txt, commit 36761c7d553d L1499-1512:
      |
      | "a" SP address ":" port NL
      |
      |    [Any number.]
      |
      |    Present only if the OR has at least one IPv6 address.
      |
      |    Address and portlist are as for "or-address" as specified in
      |    2.1.
      |
      |    (Only included when the vote or consensus is generated with
      |    consensus-method 14 or later.)

    :param string line: An 'a'-line from an bridge-network-status descriptor.
    :type fingerprint: string or None
    :param fingerprint: A string which identifies which OR the descriptor
        we're parsing came from (since the 'a'-line doesn't tell us, this can
        help make the log messages clearer).
    :raises: :exc:`NetworkstatusParsingError`
    :rtype: tuple
    :returns: A 2-tuple of a string respresenting the IP address and a
        :class:`bridgedb.parse.addr.PortList`.
    """
    ip = None
    portlist = None

    if line.startswith('a '):
        line = line[2:]  # Chop off the 'a '
    else:
        logging.warn("Networkstatus parser received non 'a'-line for %r:"\
                     "  %r" % (fingerprint or 'Unknown', line))

    try:
        ip, portlist = line.rsplit(':', 1)
    except ValueError as error:
        logging.error("Bad separator in networkstatus 'a'-line: %r" % line)
        return (None, None)

    if ip.startswith('[') and ip.endswith(']'):
        ip = ip.strip('[]')

    try:
        if not addr.isIPAddress(ip):
            raise NetworkstatusParsingError(
                "Got invalid IP Address in networkstatus 'a'-line for %r: %r" %
                (fingerprint or 'Unknown', line))

        if addr.isIPv4(ip):
            warnings.warn(FutureWarning(
                "Got IPv4 address in networkstatus 'a'-line! "\
                "Networkstatus document format may have changed!"))
    except NetworkstatusParsingError as error:
        logging.error(error)
        ip, portlist = None, None

    try:
        portlist = addr.PortList(portlist)
        if not portlist:
            raise NetworkstatusParsingError(
                "Got invalid portlist in 'a'-line for %r!\n  Line: %r" %
                (fingerprint or 'Unknown', line))
    except (addr.InvalidPort, NetworkstatusParsingError) as error:
        logging.error(error)
        portlist = None
    else:
        logging.debug("Parsed networkstatus ORAddress line for %r:"\
                      "\n  Address: %s  \tPorts: %s"
                      % (fingerprint or 'Unknown', ip, portlist))
    finally:
        return (ip, portlist)