Ejemplo n.º 1
0
  def test_with_microdescriptor_router_status_entries(self):
    """
    Includes microdescriptor flavored router status entries within the
    document.
    """

    entry1 = get_router_status_entry_micro_v3({'s': "Fast"})
    entry2 = get_router_status_entry_micro_v3({
      'r': "tornodeviennasil AcWxDFxrHetHYS5m6/MVt8ZN6AM 2013-03-13 22:09:13 78.142.142.246 443 80",
      's': "Valid",
    })

    document = get_network_status_document_v3({"network-status-version": "3 microdesc"}, routers = (entry1, entry2))

    self.assertTrue(entry1 in document.routers.values())
    self.assertTrue(entry2 in document.routers.values())

    # try with an invalid RouterStatusEntry

    entry3 = RouterStatusEntryMicroV3(get_router_status_entry_micro_v3({'r': "ugabuga"}, content = True), False)

    content = get_network_status_document_v3({"network-status-version": "3 microdesc"}, routers = (entry3,), content = True)
    self.assertRaises(ValueError, NetworkStatusDocumentV3, content)

    document = NetworkStatusDocumentV3(content, False)
    self.assertEquals([entry3], document.routers.values())

    # try including microdescriptor entry in a normal consensus

    content = get_network_status_document_v3(routers = (entry1,), content = True)
    self.assertRaises(ValueError, NetworkStatusDocumentV3, content)

    document = NetworkStatusDocumentV3(content, False)
    self.assertEqual([RouterStatusEntryV3(str(entry1), False)], document.routers.values())
Ejemplo n.º 2
0
    def test_vote_status(self):
        """
    Parses the vote-status field.
    """

        document = get_network_status_document_v3({"vote-status": "vote"})
        self.assertEquals(False, document.is_consensus)
        self.assertEquals(True, document.is_vote)

        content = get_network_status_document_v3({"vote-status": "consensus"},
                                                 content=True)
        document = NetworkStatusDocumentV3(content)
        self.assertEquals(True, document.is_consensus)
        self.assertEquals(False, document.is_vote)

        test_values = (
            "",
            "   ",
            "votee",
        )

        for test_value in test_values:
            content = get_network_status_document_v3(
                {"vote-status": test_value}, content=True)
            self.assertRaises(ValueError, NetworkStatusDocumentV3, content)

            document = NetworkStatusDocumentV3(content, False)
            self.assertEquals(True, document.is_consensus)
            self.assertEquals(False, document.is_vote)
Ejemplo n.º 3
0
    def test_with_directory_authorities(self):
        """
    Includes a couple directory authorities in the document.
    """

        for is_document_vote in (False, True):
            for is_authorities_vote in (False, True):
                authority1 = get_directory_authority(
                    {'contact': 'doctor jekyll'}, is_vote=is_authorities_vote)
                authority2 = get_directory_authority(
                    {'contact': 'mister hyde'}, is_vote=is_authorities_vote)

                vote_status = "vote" if is_document_vote else "consensus"
                content = get_network_status_document_v3(
                    {"vote-status": vote_status},
                    authorities=(authority1, authority2),
                    content=True)

                if is_document_vote == is_authorities_vote:
                    document = NetworkStatusDocumentV3(content)
                    self.assertEquals((authority1, authority2),
                                      document.directory_authorities)
                else:
                    # authority votes in a consensus or consensus authorities in a vote
                    self.assertRaises(ValueError, NetworkStatusDocumentV3,
                                      content)
                    document = NetworkStatusDocumentV3(content, validate=False)
                    self.assertEquals((authority1, authority2),
                                      document.directory_authorities)
Ejemplo n.º 4
0
    def test_consensus_method(self):
        """
    Parses the consensus-method field.
    """

        document = get_network_status_document_v3({"consensus-method": "12"})
        self.assertEquals(12, document.consensus_method)

        # check that we default to being consensus-method 1
        content = get_network_status_document_v3(
            exclude=("consensus-method", ), content=True)
        document = NetworkStatusDocumentV3(content, False)
        self.assertEquals(1, document.consensus_method)
        self.assertEquals([], document.consensus_methods)

        test_values = (
            "",
            "   ",
            "a",
            "1 2",
            "2.0",
        )

        for test_value in test_values:
            content = get_network_status_document_v3(
                {"consensus-method": test_value}, content=True)
            self.assertRaises(ValueError, NetworkStatusDocumentV3, content)

            document = NetworkStatusDocumentV3(content, False)
            self.assertEquals(1, document.consensus_method)
Ejemplo n.º 5
0
  def test_params_range(self):
    """
    Check both the furthest valid 'params' values and values that are out of
    bounds.
    """

    test_values = (
      ("foo=2147483648", {"foo": 2147483648}, False),
      ("foo=-2147483649", {"foo": -2147483649}, False),
      ("foo=2147483647", {"foo": 2147483647}, True),
      ("foo=-2147483648", {"foo": -2147483648}, True),

      # param with special range constraints
      ("circwindow=99", {"circwindow": 99}, False),
      ("circwindow=1001", {"circwindow": 1001}, False),
      ("circwindow=500", {"circwindow": 500}, True),

      # param that relies on another param for its constraints
      ("cbtclosequantile=79 cbtquantile=80", {"cbtclosequantile": 79, "cbtquantile": 80}, False),
      ("cbtclosequantile=80 cbtquantile=80", {"cbtclosequantile": 80, "cbtquantile": 80}, True),
    )

    for test_value, expected_value, is_ok in test_values:
      content = get_network_status_document_v3({"params": test_value}, content = True)

      if is_ok:
        document = NetworkStatusDocumentV3(content, default_params = False)
      else:
        self.assertRaises(ValueError, NetworkStatusDocumentV3, content)
        document = NetworkStatusDocumentV3(content, False, default_params = False)

      self.assertEquals(expected_value, document.params)
Ejemplo n.º 6
0
    def test_bandwidth_wights_omissions(self):
        """
    Leaves entries out of the 'bandwidth-wights' line.
    """

        # try parsing an empty value

        content = get_network_status_document_v3({"bandwidth-weights": ""},
                                                 content=True)
        self.assertRaises(ValueError, NetworkStatusDocumentV3, content)

        document = NetworkStatusDocumentV3(content, False)
        self.assertEquals({}, document.bandwidth_weights)

        # drop individual values

        for missing_entry in BANDWIDTH_WEIGHT_ENTRIES:
            weight_entries = [
                "%s=5" % e for e in BANDWIDTH_WEIGHT_ENTRIES
                if e != missing_entry
            ]
            expected = dict([(e, 5) for e in BANDWIDTH_WEIGHT_ENTRIES
                             if e != missing_entry])

            content = get_network_status_document_v3(
                {"bandwidth-weights": " ".join(weight_entries)}, content=True)
            self.assertRaises(ValueError, NetworkStatusDocumentV3, content)

            document = NetworkStatusDocumentV3(content, False)
            self.assertEquals(expected, document.bandwidth_weights)
Ejemplo n.º 7
0
  def test_with_router_status_entries(self):
    """
    Includes router status entries within the document. This isn't to test the
    RouterStatusEntry parsing but rather the inclusion of it within the
    document.
    """

    entry1 = get_router_status_entry_v3({'s': "Fast"})
    entry2 = get_router_status_entry_v3({
      'r': "Nightfae AWt0XNId/OU2xX5xs5hVtDc5Mes 6873oEfM7fFIbxYtwllw9GPDwkA 2013-02-20 11:12:27 85.177.66.233 9001 9030",
      's': "Valid",
    })

    document = get_network_status_document_v3(routers = (entry1, entry2))

    self.assertTrue(entry1 in document.routers.values())
    self.assertTrue(entry2 in document.routers.values())

    # try with an invalid RouterStatusEntry

    entry3 = RouterStatusEntryV3(get_router_status_entry_v3({'r': "ugabuga"}, content = True), False)
    content = get_network_status_document_v3(routers = (entry3,), content = True)

    self.assertRaises(ValueError, NetworkStatusDocumentV3, content)
    document = NetworkStatusDocumentV3(content, False)
    self.assertEquals([entry3], document.routers.values())

    # try including with a microdescriptor consensus

    content = get_network_status_document_v3({"network-status-version": "3 microdesc"}, routers = (entry1,), content = True)
    self.assertRaises(ValueError, NetworkStatusDocumentV3, content)

    document = NetworkStatusDocumentV3(content, False)
    self.assertEqual([RouterStatusEntryMicroV3(str(entry1), False)], document.routers.values())
Ejemplo n.º 8
0
  def test_consensus_methods(self):
    """
    Parses the consensus-methods field.
    """

    document = get_network_status_document_v3({"vote-status": "vote", "consensus-methods": "12 3 1 780"})
    self.assertEquals([12, 3, 1, 780], document.consensus_methods)

    # check that we default to including consensus-method 1
    content = get_network_status_document_v3({"vote-status": "vote"}, ("consensus-methods",), content = True)
    document = NetworkStatusDocumentV3(content, False)
    self.assertEquals([1], document.consensus_methods)
    self.assertEquals(None, document.consensus_method)

    test_values = (
      ("", []),
      ("   ", []),
      ("1 2 3 a 5", [1, 2, 3, 5]),
      ("1 2 3 4.0 5", [1, 2, 3, 5]),
      ("2 3 4", [2, 3, 4]),  # spec says version one must be included
    )

    for test_value, expected_consensus_methods in test_values:
      content = get_network_status_document_v3({"vote-status": "vote", "consensus-methods": test_value}, content = True)
      self.assertRaises(ValueError, NetworkStatusDocumentV3, content)

      document = NetworkStatusDocumentV3(content, False)
      self.assertEquals(expected_consensus_methods, document.consensus_methods)
Ejemplo n.º 9
0
    def test_compare_flags(self, authorities_mock, query_mock, stdout_mock):
        authorities_mock().items.return_value = [
            ('moria1', DIRECTORY_AUTHORITIES['moria1']),
            ('maatuska', DIRECTORY_AUTHORITIES['maatuska'])
        ]

        fingerprint = [
            ('92FCB6748A40E6088E22FBAB943AB2DD743EA818',
             'kvy2dIpA5giOIvurlDqy3XQ+qBg='),
            ('6871F682350BA931838C0EC1E4A23044DAE06A73',
             'aHH2gjULqTGDjA7B5KIwRNrganM='),
            ('E2BB13AA2F6960CD93ABE5257A825687F3973C62',
             '4rsTqi9pYM2Tq+UleoJWh/OXPGI='),
            ('546C54E2A89D88E0794D04AECBF1AC8AC9DA81DE',
             'VGxU4qidiOB5TQSuy/Gsisnagd4='),
            ('DCAEC3D069DC39AAE43D13C8AF31B5645E05ED61',
             '3K7D0GncOarkPRPIrzG1ZF4F7WE='),
        ]

        entry = [
            # entries for moria1
            _get_router_status(fingerprint_base64=fingerprint[0][1],
                               s_line=' '),
            _get_router_status(fingerprint_base64=fingerprint[1][1],
                               s_line=' '),
            _get_router_status(fingerprint_base64=fingerprint[2][1],
                               s_line=' '),
            _get_router_status(fingerprint_base64=fingerprint[3][1]),
            _get_router_status(fingerprint_base64=fingerprint[4][1]),

            # entries for maatuska
            _get_router_status(fingerprint_base64=fingerprint[0][1]),
            _get_router_status(fingerprint_base64=fingerprint[1][1]),
            _get_router_status(fingerprint_base64=fingerprint[2][1]),
            _get_router_status(fingerprint_base64=fingerprint[3][1],
                               s_line=' '),
            _get_router_status(fingerprint_base64=fingerprint[4][1],
                               s_line=' '),
        ]

        query_mock().run.side_effect = [
            [
                NetworkStatusDocumentV3.create(routers=(entry[0], entry[1],
                                                        entry[2], entry[3],
                                                        entry[4]))
            ],
            [
                NetworkStatusDocumentV3.create(routers=(entry[5], entry[6],
                                                        entry[7], entry[8],
                                                        entry[9]))
            ],
        ]

        exec_documentation_example('compare_flags.py')

        self.assertCountEqual(COMPARE_FLAGS_OUTPUT.splitlines(),
                              stdout_mock.getvalue().splitlines())
Ejemplo n.º 10
0
    def test_compare_flags(self, stdout_mock, query_mock, authorities_mock):
        authorities_mock().items.return_value = [
            ('moria1', DIRECTORY_AUTHORITIES['moria1']),
            ('maatuska', DIRECTORY_AUTHORITIES['maatuska']),
        ]

        r_line = 'caerSidi %s oQZFLYe9e4A7bOkWKR7TaNxb0JE 2012-08-06 11:19:31 71.35.150.29 9001 0'

        moria1_consensus = NetworkStatusDocumentV3.create(routers=[
            RouterStatusEntryV3.create({
                'r': r_line % 'kvy2dIpA5giOIvurlDqy3XQ+qBg=',
                's': ' '
            }),
            RouterStatusEntryV3.create({
                'r': r_line % 'aHH2gjULqTGDjA7B5KIwRNrganM=',
                's': ' '
            }),
            RouterStatusEntryV3.create({
                'r': r_line % '4rsTqi9pYM2Tq+UleoJWh/OXPGI=',
                's': ' '
            }),
            RouterStatusEntryV3.create(
                {'r': r_line % 'VGxU4qidiOB5TQSuy/Gsisnagd4='}),
            RouterStatusEntryV3.create(
                {'r': r_line % '3K7D0GncOarkPRPIrzG1ZF4F7WE='}),
        ])

        maatuska_consensus = NetworkStatusDocumentV3.create(routers=[
            RouterStatusEntryV3.create(
                {'r': r_line % 'kvy2dIpA5giOIvurlDqy3XQ+qBg='}),
            RouterStatusEntryV3.create(
                {'r': r_line % 'aHH2gjULqTGDjA7B5KIwRNrganM='}),
            RouterStatusEntryV3.create(
                {'r': r_line % '4rsTqi9pYM2Tq+UleoJWh/OXPGI='}),
            RouterStatusEntryV3.create({
                'r': r_line % 'VGxU4qidiOB5TQSuy/Gsisnagd4=',
                's': ' '
            }),
            RouterStatusEntryV3.create({
                'r': r_line % '3K7D0GncOarkPRPIrzG1ZF4F7WE=',
                's': ' '
            }),
        ])

        query_mock().run.side_effect = [[moria1_consensus],
                                        [maatuska_consensus]]

        import compare_flags

        self.assertEqual(EXPECTED_COMPARE_FLAGS, stdout_mock.getvalue())
Ejemplo n.º 11
0
    def test_voting_delay(self):
        """
    Parses the voting-delay field.
    """

        document = get_network_status_document_v3({'voting-delay': '12 345'})
        self.assertEquals(12, document.vote_delay)
        self.assertEquals(345, document.dist_delay)

        test_values = (
            '',
            '   ',
            '1 a',
            '1\t2',
            '1 2.0',
        )

        for test_value in test_values:
            content = get_network_status_document_v3(
                {'voting-delay': test_value}, content=True)
            self.assertRaises(ValueError, NetworkStatusDocumentV3, content)

            document = NetworkStatusDocumentV3(content, False)
            self.assertEquals(None, document.vote_delay)
            self.assertEquals(None, document.dist_delay)
Ejemplo n.º 12
0
    def test_misordered_fields(self):
        """
    Rearranges our descriptor fields.
    """

        for is_consensus in (True, False):
            attr = {
                'vote-status': 'consensus'
            } if is_consensus else {
                'vote-status': 'vote'
            }
            lines = get_network_status_document_v3(attr,
                                                   content=True).split(b'\n')

            for index in xrange(len(lines) - 1):
                # once we reach the authority entry or later we're done since swapping
                # those won't be detected

                if is_consensus and lines[index].startswith(
                        stem.util.str_tools._to_bytes(CRYPTO_BLOB[1:10])):
                    break
                elif not is_consensus and lines[index].startswith(
                        b'dir-source'):
                    break

                # swaps this line with the one after it
                test_lines = list(lines)
                test_lines[index], test_lines[index + 1] = test_lines[
                    index + 1], test_lines[index]

                content = b'\n'.join(test_lines)
                self.assertRaises(ValueError, NetworkStatusDocumentV3, content)
                NetworkStatusDocumentV3(content,
                                        False)  # constructs without validation
Ejemplo n.º 13
0
    def _getInitialEndpoints(self):
        '''Get an initial set of servers to download the network status
        documents from.

        First try reading from the "cached-consensus" file. If this isn't
        successful for any reason fallback to using the directory
        authorities.

        This is only called on instantiation, and any future downloads will
        already have a fresh set of V2Dir endpoints.

        .. note: We just use the directory authorities defined in stem.

        :returns: **list** containing either RouterStatusEntry objects with
            the 'V2Dir' flag or DirectoryAuthorities
        '''
        endpoints = None
        try:
            with open(DEF.CONSENSUS_CACHE_FILE, 'rb') as f:
                data = f.read()
            old_consensus = NetworkStatusDocumentV3(data)
            endpoints = self._extractV2DirEndpoints(old_consensus)
            msg = "Found {} V2Dir endpoints in cached-consensus."
            logging.debug(msg.format(len(endpoints)))
        except (IOError, ValueError) as e:
            logging.debug("Error reading from cached-consensus: {}".format(e))
            logging.debug("Falling back to directory authorities.")

        return list(endpoints) if endpoints else get_authorities().values()
Ejemplo n.º 14
0
    def test_voting_delay(self):
        """
    Parses the voting-delay field.
    """

        document = get_network_status_document_v3({"voting-delay": "12 345"})
        self.assertEquals(12, document.vote_delay)
        self.assertEquals(345, document.dist_delay)

        test_values = (
            "",
            "   ",
            "1 a",
            "1\t2",
            "1 2.0",
        )

        for test_value in test_values:
            content = get_network_status_document_v3(
                {"voting-delay": test_value}, content=True)
            self.assertRaises(ValueError, NetworkStatusDocumentV3, content)

            document = NetworkStatusDocumentV3(content, False)
            self.assertEquals(None, document.vote_delay)
            self.assertEquals(None, document.dist_delay)
Ejemplo n.º 15
0
    def test_version(self):
        """
    Parses the network-status-version field, including trying to handle a
    different document version with the v3 parser.
    """

        document = get_network_status_document_v3(
            {"network-status-version": "3"})
        self.assertEquals(3, document.version)
        self.assertEquals(None, document.version_flavor)
        self.assertEquals(False, document.is_microdescriptor)

        document = get_network_status_document_v3(
            {"network-status-version": "3 microdesc"})
        self.assertEquals(3, document.version)
        self.assertEquals('microdesc', document.version_flavor)
        self.assertEquals(True, document.is_microdescriptor)

        content = get_network_status_document_v3(
            {"network-status-version": "4"}, content=True)
        self.assertRaises(ValueError, NetworkStatusDocumentV3, content)

        document = NetworkStatusDocumentV3(content, False)
        self.assertEquals(4, document.version)
        self.assertEquals(None, document.version_flavor)
        self.assertEquals(False, document.is_microdescriptor)
Ejemplo n.º 16
0
    def test_examples(self):
        """
    Run something similar to the examples in the header pydocs.
    """

        # makes a consensus with a couple routers, both with the same nickname

        entry1 = get_router_status_entry_v3({'s': "Fast"})
        entry2 = get_router_status_entry_v3({'s': "Valid"})
        content = get_network_status_document_v3(routers=(entry1, entry2),
                                                 content=True)

        # first example: parsing via the NetworkStatusDocumentV3 constructor

        consensus_file = StringIO.StringIO(content)
        consensus = NetworkStatusDocumentV3(consensus_file.read())
        consensus_file.close()

        for router in consensus.routers:
            self.assertEqual('caerSidi', router.nickname)

        # second example: using stem.descriptor.parse_file

        with support_with(StringIO.StringIO(content)) as consensus_file:
            for router in stem.descriptor.parse_file(
                    consensus_file, 'network-status-consensus-3 1.0'):
                self.assertEqual('caerSidi', router.nickname)
Ejemplo n.º 17
0
  def test_footer_consensus_method_requirement(self):
    """
    Check that validation will notice if a footer appears before it was
    introduced.
    """

    content = get_network_status_document_v3({"consensus-method": "8"}, content = True)
    self.assertRaises(ValueError, NetworkStatusDocumentV3, content)

    document = NetworkStatusDocumentV3(content, False)
    self.assertEqual([DOC_SIG], document.signatures)
    self.assertEqual([], document.get_unrecognized_lines())

    # excludes a footer from a version that shouldn't have it

    document = get_network_status_document_v3({"consensus-method": "8"}, ("directory-footer", "directory-signature"))
    self.assertEqual([], document.signatures)
    self.assertEqual([], document.get_unrecognized_lines())

    # Prior to conensus method 9 votes can still have a signature in their
    # footer...
    #
    # https://trac.torproject.org/7932

    document = get_network_status_document_v3(
      {
        "vote-status": "vote",
        "consensus-methods": "1 8",
      },
      exclude = ("directory-footer",),
      authorities = (get_directory_authority(is_vote = True),)
    )

    self.assertEqual([DOC_SIG], document.signatures)
    self.assertEqual([], document.get_unrecognized_lines())
Ejemplo n.º 18
0
    def test_misordered_fields(self):
        """
    Rearranges our descriptor fields.
    """

        for is_consensus in (True, False):
            attr = {
                "vote-status": "consensus"
            } if is_consensus else {
                "vote-status": "vote"
            }
            lines = get_network_status_document_v3(attr,
                                                   content=True).split("\n")

            for index in xrange(len(lines) - 1):
                # once we reach the crypto blob we're done since swapping those won't
                # be detected
                if lines[index].startswith(CRYPTO_BLOB[1:10]): break

                # swaps this line with the one after it
                test_lines = list(lines)
                test_lines[index], test_lines[index + 1] = test_lines[
                    index + 1], test_lines[index]

                content = "\n".join(test_lines)
                self.assertRaises(ValueError, NetworkStatusDocumentV3, content)
                NetworkStatusDocumentV3(content,
                                        False)  # constructs without validation
Ejemplo n.º 19
0
    def test_duplicate_fields(self):
        """
    Almost all fields can only appear once. Checking that duplicates cause
    validation errors.
    """

        for is_consensus in (True, False):
            attr = {
                "vote-status": "consensus"
            } if is_consensus else {
                "vote-status": "vote"
            }
            lines = get_network_status_document_v3(attr,
                                                   content=True).split("\n")

            for index, line in enumerate(lines):
                # Stop when we hit the 'directory-signature' for a couple reasons...
                # - that is the one field that can validly appear multiple times
                # - after it is a crypto blob, which won't trigger this kind of
                #   validation failure

                test_lines = list(lines)
                if line.startswith("directory-signature "):
                    break

                # duplicates the line
                test_lines.insert(index, line)

                content = "\n".join(test_lines)
                self.assertRaises(ValueError, NetworkStatusDocumentV3, content)
                NetworkStatusDocumentV3(content,
                                        False)  # constructs without validation
Ejemplo n.º 20
0
    def test_bandwidth_wights_malformed(self):
        """
    Provides malformed content in the 'bandwidth-wights' line.
    """

        test_values = (
            "Wbe",
            "Wbe=",
            "Wbe=a",
            "Wbe=+7",
        )

        base_weight_entry = " ".join(
            ["%s=5" % e for e in BANDWIDTH_WEIGHT_ENTRIES])
        expected = dict([(e, 5) for e in BANDWIDTH_WEIGHT_ENTRIES
                         if e != "Wbe"])

        for test_value in test_values:
            weight_entry = base_weight_entry.replace("Wbe=5", test_value)
            content = get_network_status_document_v3(
                {"bandwidth-weights": weight_entry}, content=True)

            self.assertRaises(ValueError, NetworkStatusDocumentV3, content)
            document = NetworkStatusDocumentV3(content, False)
            self.assertEquals(expected, document.bandwidth_weights)
Ejemplo n.º 21
0
    def test_malformed_signature(self):
        """
    Provides malformed or missing content in the 'directory-signature' line.
    """

        test_values = (
            "",
            "\n",
            "blarg",
        )

        for test_value in test_values:
            for test_attr in xrange(3):
                attrs = [
                    DOC_SIG.identity, DOC_SIG.key_digest, DOC_SIG.signature
                ]
                attrs[test_attr] = test_value

                content = get_network_status_document_v3(
                    {"directory-signature": "%s %s\n%s" % tuple(attrs)},
                    content=True)
                self.assertRaises(ValueError, NetworkStatusDocumentV3, content)
                NetworkStatusDocumentV3(
                    content, False
                )  # checks that it's still parsable without validation
Ejemplo n.º 22
0
    def test_persisting_a_consensus(self, query_mock, parse_file_mock,
                                    stdout_mock):
        def tutorial_example_2():
            from stem.descriptor import DocumentHandler, parse_file

            consensus = next(
                parse_file(
                    '/tmp/descriptor_dump',
                    descriptor_type='network-status-consensus-3 1.0',
                    document_handler=DocumentHandler.DOCUMENT,
                ))

            for fingerprint, relay in consensus.routers.items():
                print('%s: %s' % (fingerprint, relay.nickname))

        network_status = NetworkStatusDocumentV3.create(
            routers=(RouterStatusEntryV3.create({
                'r':
                'caerSidi p1aag7VwarGxqctS7/fS0y5FU+s oQZFLYe9e4A7bOkWKR7TaNxb0JE 2012-08-06 11:19:31 71.35.150.29 9001 0',
            }), ))

        query_mock().run.return_value = [network_status]
        parse_file_mock.return_value = itertools.cycle([network_status])

        exec_documentation_example('persisting_a_consensus.py')
        exec_documentation_example('persisting_a_consensus_with_parse_file.py')

        self.assertEqual(PERSISTING_A_CONSENSUS_OUTPUT, stdout_mock.getvalue())

        if os.path.exists('/tmp/descriptor_dump'):
            os.remove('/tmp/descriptor_dump')
Ejemplo n.º 23
0
  def test_version_lists(self):
    """
    Parses client-versions and server-versions fields. Both are comma separated
    lists of tor versions.
    """

    expected = [stem.version.Version("1.2.3.4"), stem.version.Version("56.789.12.34-alpha")]
    test_value = "1.2.3.4,56.789.12.34-alpha"

    document = get_network_status_document_v3({"client-versions": test_value, "server-versions": test_value})
    self.assertEquals(expected, document.client_versions)
    self.assertEquals(expected, document.server_versions)

    test_values = (
      ("", []),
      ("   ", []),
      ("1.2.3.4,", [stem.version.Version("1.2.3.4")]),
      ("1.2.3.4,1.2.3.a", [stem.version.Version("1.2.3.4")]),
    )

    for field in ('client-versions', 'server-versions'):
      attr = field.replace('-', '_')

      for test_value, expected_value in test_values:
        content = get_network_status_document_v3({field: test_value}, content = True)
        self.assertRaises(ValueError, NetworkStatusDocumentV3, content)

        document = NetworkStatusDocumentV3(content, False)
        self.assertEquals(expected_value, getattr(document, attr))
Ejemplo n.º 24
0
  def test_params(self):
    """
    General testing for the 'params' line, exercising the happy cases.
    """

    document = get_network_status_document_v3({"params": "CircuitPriorityHalflifeMsec=30000 bwauthpid=1 unrecognized=-122"})
    self.assertEquals(30000, document.params["CircuitPriorityHalflifeMsec"])
    self.assertEquals(1, document.params["bwauthpid"])
    self.assertEquals(-122, document.params["unrecognized"])

    # empty params line
    content = get_network_status_document_v3({"params": ""}, content = True)
    document = NetworkStatusDocumentV3(content, default_params = True)
    self.assertEquals(DEFAULT_PARAMS, document.params)

    content = get_network_status_document_v3({"params": ""}, content = True)
    document = NetworkStatusDocumentV3(content, default_params = False)
    self.assertEquals({}, document.params)
Ejemplo n.º 25
0
  def test_params_misordered(self):
    """
    Check that the 'params' line is rejected if out of order.
    """

    content = get_network_status_document_v3({"params": "unrecognized=-122 bwauthpid=1"}, content = True)
    self.assertRaises(ValueError, NetworkStatusDocumentV3, content)

    document = NetworkStatusDocumentV3(content, False, default_params = False)
    self.assertEquals({"unrecognized": -122, "bwauthpid": 1}, document.params)
Ejemplo n.º 26
0
  def test_footer_with_value(self):
    """
    Tries to parse a descriptor with content on the 'directory-footer' line.
    """

    content = get_network_status_document_v3({"directory-footer": "blarg"}, content = True)
    self.assertRaises(ValueError, NetworkStatusDocumentV3, content)

    document = NetworkStatusDocumentV3(content, False)
    self.assertEqual([DOC_SIG], document.signatures)
    self.assertEqual([], document.get_unrecognized_lines())
Ejemplo n.º 27
0
def _readV2DirsFromCacheFile():
    try:
        with open(MICRO_CONSENSUS_CACHE_FILE, 'rb') as f:
            data = f.read()
        consensus = NetworkStatusDocumentV3(data)
        return getV2DirsFromConsensus(consensus)
    except Exception as e:
        msg = (
            "Failed to read cached-consensus-microdesc. Reason: {}.".format(e))
        logging.debug(msg)
        return None
Ejemplo n.º 28
0
    def test_with_microdescriptor_router_status_entries(self):
        """
    Includes microdescriptor flavored router status entries within the
    document.
    """

        entry1 = get_router_status_entry_micro_v3({'s': "Fast"})
        entry2 = get_router_status_entry_micro_v3({'s': "Valid"})
        document = get_network_status_document_v3(
            {"network-status-version": "3 microdesc"},
            routers=(entry1, entry2))

        self.assertEquals((entry1, entry2), document.routers)

        # try with an invalid RouterStatusEntry

        entry3 = RouterStatusEntryMicroV3(
            get_router_status_entry_micro_v3({'r': "ugabuga"}, content=True),
            False)
        content = get_network_status_document_v3(
            {"network-status-version": "3 microdesc"},
            routers=(entry3, ),
            content=True)

        self.assertRaises(ValueError, NetworkStatusDocumentV3, content)
        document = NetworkStatusDocumentV3(content, False)
        self.assertEquals((entry3, ), document.routers)

        # try including microdescriptor entries in a normal consensus

        content = get_network_status_document_v3(routers=(entry1, entry2),
                                                 content=True)
        self.assertRaises(ValueError, NetworkStatusDocumentV3, content)

        expected_routers = (
            RouterStatusEntryV3(str(entry1), False),
            RouterStatusEntryV3(str(entry2), False),
        )

        document = NetworkStatusDocumentV3(content, False)
        self.assertEquals(expected_routers, document.routers)
Ejemplo n.º 29
0
  def test_bandwidth_wights_in_vote(self):
    """
    Tries adding a 'bandwidth-wights' line to a vote.
    """

    weight_entry = " ".join(["%s=5" % e for e in BANDWIDTH_WEIGHT_ENTRIES])
    expected = dict([(e, 5) for e in BANDWIDTH_WEIGHT_ENTRIES])

    content = get_network_status_document_v3({"vote-status": "vote", "bandwidth-weights": weight_entry}, content = True)
    self.assertRaises(ValueError, NetworkStatusDocumentV3, content)

    document = NetworkStatusDocumentV3(content, False)
    self.assertEquals(expected, document.bandwidth_weights)
Ejemplo n.º 30
0
  def test_bandwidth_wights_misordered(self):
    """
    Check that the 'bandwidth-wights' line is rejected if out of order.
    """

    weight_entry = " ".join(["%s=5" % e for e in reversed(BANDWIDTH_WEIGHT_ENTRIES)])
    expected = dict([(e, 5) for e in BANDWIDTH_WEIGHT_ENTRIES])

    content = get_network_status_document_v3({"bandwidth-weights": weight_entry}, content = True)
    self.assertRaises(ValueError, NetworkStatusDocumentV3, content)

    document = NetworkStatusDocumentV3(content, False)
    self.assertEquals(expected, document.bandwidth_weights)
Ejemplo n.º 31
0
  def test_mirror_mirror_on_the_wall_3(self, open_mock, stdout_mock):
    def tutorial_example():
      from stem.descriptor import parse_file

      for desc in parse_file(open('/home/atagar/.tor/cached-consensus')):
        print('found relay %s (%s)' % (desc.nickname, desc.fingerprint))

    test_file = io.BytesIO(NetworkStatusDocumentV3.content(routers = [RouterStatusEntryV3.create({
      'r': 'caerSidi p1aag7VwarGxqctS7/fS0y5FU+s oQZFLYe9e4A7bOkWKR7TaNxb0JE 2012-08-06 11:19:31 71.35.150.29 9001 0',
    })]))
    test_file.name = '/home/atagar/.tor/cached-consensus'
    open_mock.return_value = test_file

    tutorial_example()
    self.assertEqual('found relay caerSidi (A7569A83B5706AB1B1A9CB52EFF7D2D32E4553EB)\n', stdout_mock.getvalue())