[stem/master] Moving DocumentFooter parsing to helpers

commit 65595d3e0d3bb771b40ef3ea99281b6110036c47 Author: Damian Johnson <atagar@torproject.org> Date: Sun Jan 18 13:34:25 2015 -0800 Moving DocumentFooter parsing to helpers --- stem/descriptor/networkstatus.py | 72 ++++++++++++++------- test/unit/descriptor/networkstatus/document_v3.py | 6 +- 2 files changed, 49 insertions(+), 29 deletions(-) diff --git a/stem/descriptor/networkstatus.py b/stem/descriptor/networkstatus.py index 910f684..a712eb2 100644 --- a/stem/descriptor/networkstatus.py +++ b/stem/descriptor/networkstatus.py @@ -871,7 +871,46 @@ class _DocumentHeader(object): raise ValueError("'%s' value on the params line must be in the range of %i - %i, was %i" % (key, minimum, maximum, value)) +def _parse_directory_footer_line(descriptor, entries): + # nothing to parse, simply checking that we don't have a value + + value = _value('directory-footer', entries) + + if value: + raise ValueError("A network status document's 'directory-footer' line shouldn't have any content, got 'directory-footer %s'" % value) + + +def _parse_directory_signature_line(descriptor, entries): + signatures = [] + + for sig_value, block_type, block_contents in entries['directory-signature']: + if sig_value.count(' ') not in (1, 2): + raise ValueError("Authority signatures in a network status document are expected to be of the form 'directory-signature [METHOD] FINGERPRINT KEY_DIGEST', received: %s" % sig_value) + + if not block_contents or block_type != 'SIGNATURE': + raise ValueError("'directory-signature' should be followed by a SIGNATURE block, but was a %s" % block_type) + + if sig_value.count(' ') == 1: + method = 'sha1' # default if none was provided + fingerprint, key_digest = sig_value.split(' ', 1) + else: + method, fingerprint, key_digest = sig_value.split(' ', 2) + + signatures.append(DocumentSignature(method, fingerprint, key_digest, block_contents, True)) + + descriptor.signatures = signatures + + +_parse_bandwidth_weights_line = lambda descriptor, entries: setattr(descriptor, 'bandwidth_weights', _parse_int_mappings('bandwidth-weights', _value('bandwidth-weights', entries), True)) + + class _DocumentFooter(object): + PARSER_FOR_LINE = { + 'directory-footer': _parse_directory_footer_line, + 'bandwidth-weights': _parse_bandwidth_weights_line, + 'directory-signature': _parse_directory_signature_line, + } + def __init__(self, document_file, validate, header): self.signatures = [] self.bandwidth_weights = {} @@ -912,31 +951,14 @@ class _DocumentFooter(object): if not (keyword == 'directory-signature' and header.is_consensus): raise ValueError("Network status documents can only have a single '%s' line, got %i" % (keyword, len(values))) - if keyword == 'directory-footer': - # nothing to parse, simply checking that we don't have a value - - if validate and value: - raise ValueError("A network status document's 'directory-footer' line shouldn't have any content, got '%s'" % line) - elif keyword == 'bandwidth-weights': - self.bandwidth_weights = _parse_int_mappings(keyword, value, validate) - elif keyword == 'directory-signature': - for sig_value, block_type, block_contents in values: - if sig_value.count(' ') not in (1, 2): - if not validate: - continue - - raise ValueError("Authority signatures in a network status document are expected to be of the form 'directory-signature [METHOD] FINGERPRINT KEY_DIGEST', received: %s" % sig_value) - - if validate and (not block_contents or block_type != 'SIGNATURE'): - raise ValueError("'directory-signature' should be followed by a SIGNATURE block: %s" % line) - - if sig_value.count(' ') == 1: - method = 'sha1' # default if none was provided - fingerprint, key_digest = sig_value.split(' ', 1) - else: - method, fingerprint, key_digest = sig_value.split(' ', 2) - - self.signatures.append(DocumentSignature(method, fingerprint, key_digest, block_contents, validate)) + try: + if keyword in self.PARSER_FOR_LINE: + self.PARSER_FOR_LINE[keyword](self, entries) + else: + self._unrecognized_lines.append(line) + except ValueError as exc: + if validate: + raise exc def _check_for_missing_and_disallowed_fields(header, entries, fields): diff --git a/test/unit/descriptor/networkstatus/document_v3.py b/test/unit/descriptor/networkstatus/document_v3.py index e31600f..b0bb14a 100644 --- a/test/unit/descriptor/networkstatus/document_v3.py +++ b/test/unit/descriptor/networkstatus/document_v3.py @@ -953,7 +953,6 @@ DnN5aFtYKiTc19qIC7Nmo+afPdDEf0MlJvEOP5EWl3w= ) 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) @@ -961,7 +960,7 @@ DnN5aFtYKiTc19qIC7Nmo+afPdDEf0MlJvEOP5EWl3w= self.assertRaises(ValueError, NetworkStatusDocumentV3, content) document = NetworkStatusDocumentV3(content, False) - self.assertEqual(expected, document.bandwidth_weights) + self.assertEqual({}, document.bandwidth_weights) def test_bandwidth_wights_misordered(self): """ @@ -969,13 +968,12 @@ DnN5aFtYKiTc19qIC7Nmo+afPdDEf0MlJvEOP5EWl3w= """ 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.assertEqual(expected, document.bandwidth_weights) + self.assertEqual({}, document.bandwidth_weights) def test_bandwidth_wights_in_vote(self): """
participants (1)
-
atagar@torproject.org