[tor-commits] [bridgedb/master] Refactor unittests for bridgedb.parse.networkstatus.parseRLine().
isis at torproject.org
isis at torproject.org
Sun Jan 12 06:06:33 UTC 2014
commit 56f7a51adbe2278bc7894390f5c1f5bf29b517c2
Author: Isis Lovecruft <isis at torproject.org>
Date: Sat Dec 7 12:54:10 2013 +0000
Refactor unittests for bridgedb.parse.networkstatus.parseRLine().
---
lib/bridgedb/test/test_parse_networkstatus.py | 210 +++++++++++++++++++++----
1 file changed, 180 insertions(+), 30 deletions(-)
diff --git a/lib/bridgedb/test/test_parse_networkstatus.py b/lib/bridgedb/test/test_parse_networkstatus.py
index 830f96c..5467a85 100644
--- a/lib/bridgedb/test/test_parse_networkstatus.py
+++ b/lib/bridgedb/test/test_parse_networkstatus.py
@@ -16,7 +16,11 @@ module is functioning correctly.
"""
from __future__ import print_function
+from __future__ import unicode_literals
+import binascii
+
+from twisted.python import log
from twisted.trial import unittest
from bridgedb.parse import networkstatus
@@ -24,6 +28,14 @@ import sure
from sure import this, these, those, the, it
+logFormat = "%(created)d [%(levelname)s] %(module)s.%(funcName)s(): "
+logFormat += "%(message)s"
+networkstatus.logging.basicConfig(
+ filename='test_parse_networkstatus.log',
+ level=networkstatus.logging.DEBUG,
+ flags='w', format=logFormat)
+
+
class ParseNetworkStatusRLineTests(unittest.TestCase):
"""Tests for :func:`bridgedb.parse.networkstatus.parseRLine`."""
@@ -36,25 +48,62 @@ class ParseNetworkStatusRLineTests(unittest.TestCase):
port = '9001'
dirp = '0'
+ def makeRLine(self, *args, **kwargs):
+ """Concatenate parameters into an 'r'-line and store the result as
+ ``self.line``.
+
+ To create an invalid networkstatus 'r'-line, for example with an
+ invalid IP address, use me like this:
+
+ >>> makeRLine(ip='0.0.0.0')
+
+ :keywords: The keyword arguments may be any of the class variables,
+ i.e. 'nick' or 'ident', and the variables should be similar to the
+ defaults in the class variables. If not given as parameters, the
+ class variables will be used.
+ """
+ line = []
+ for kw in ('pre', 'nick', 'ident', 'desc', 'ts', 'ip', 'port', 'dirp'):
+ if kw in kwargs.keys():
+ if kwargs[kw]:
+ line.append(kwargs[kw])
+ elif kwargs[kw] is False:
+ pass
+ else:
+ line.append(getattr(self, kw, ''))
+
+ self.line = ' '.join([l for l in line]).strip()
+ log.msg("\n Testing networkstatusline:\n %r..." % self.line)
+ self.assertTrue(self.line != '')
+
+ def tearDown(self):
+ self.line = ''
+
+ def assertAllFieldsAreNone(self, fields):
+ """Assert that every field in the iterable ``fields`` is None."""
+ for field in fields:
+ self.assertTrue(field is None)
+
def test_missingPrefix(self):
- line = ' '.join([self.nick, self.ident, self.desc,
- self.ts, self.ip, self.port, self.dirp])
- self.assertRaises(networkstatus.NetworkstatusParsingError,
- networkstatus.parseRLine, line)
+ """Test a networkstatus 'r'-line that is missing the 'r ' prefix."""
+ self.makeRLine(pre=False)
+ fields = networkstatus.parseRLine(self.line)
+ self.assertAllFieldsAreNone(fields)
def test_wrongNumberOfFields(self):
- line = ' '.join([self.pre, self.nick, self.ident, self.ts, self.ip])
- self.assertRaises(networkstatus.NetworkstatusParsingError,
- networkstatus.parseRLine, line)
+ """Test a line missing digest, ORPort, and DirPort fields."""
+ self.makeRLine(desc=False, port=False, dirp=False)
+ fields = networkstatus.parseRLine(self.line)
+ self.assertAllFieldsAreNone(fields)
def test_wrongFieldOrder(self):
- line = ' '.join([self.pre, self.nick, self.desc, self.ident,
- self.ts, self.ip, self.port, self.dirp])
- fields = networkstatus.parseRLine(line)
+ """Test a line with the identity and descriptor digests switched."""
+ self.makeRLine(desc=self.ident, ident=self.desc)
+ fields = networkstatus.parseRLine(self.line)
nick, others = fields[0], fields[1:]
this(nick).should.be.ok
- this(nick).should.be.a(str)
+ this(nick).should.be.a(basestring)
this(nick).should.equal(self.nick)
the(others).should.be.a(tuple)
@@ -62,31 +111,132 @@ class ParseNetworkStatusRLineTests(unittest.TestCase):
for other in others:
the(other).should.be(None)
- def test_invalidTimestampMissingDate(self):
- line = ' '.join([self.pre, self.nick, self.ident, self.desc,
- '15:15:15', self.ip, self.port, self.dirp])
- self.assertRaises(networkstatus.NetworkstatusParsingError,
- networkstatus.parseRLine, line)
+ def test_invalidNicknameNonAlphanumeric(self):
+ """Test a line with a non-alphanumeric router nickname."""
+ self.makeRLine(nick='abcdef/*comment*/')
+ fields = networkstatus.parseRLine(self.line)
+ nick, ident, desc = fields[:3]
+ this(nick).should.be(None)
+ the(ident).should.be.a(basestring)
+ the(desc).should.be(None)
+
+ def test_invalidNicknameTooLong(self):
+ """Test a line with a router nickname which is way too long."""
+ self.makeRLine(nick='ThisIsAReallyReallyLongRouterNickname')
+ fields = networkstatus.parseRLine(self.line)
+ nick, ident, desc = fields[:3]
+ this(nick).should.be(None)
+ the(ident).should.be.a(basestring)
+ the(desc).should.be(None)
- def test_invalidBase64(self):
- line = ' '.join([self.pre, self.nick, '%$>#@,<', self.desc,
- self.ts, self.ip, self.port, self.dirp])
- nick, ident, desc, ts, ip, port, dirp = networkstatus.parseRLine(line)
+ def test_invalidIdentBase64(self):
+ """Test line with '%$>@,<' for an identity digest."""
+ self.makeRLine(ident='%$>#@,<')
+ (nick, ident, desc, ts,
+ ip, port, dirp) = networkstatus.parseRLine(self.line)
the(nick).should.be.ok
- the(nick).should.be.a(str)
+ the(nick).should.be.a(basestring)
the(nick).should.equal(self.nick)
-
the(ident).should.be(None)
the(desc).should.be(None)
+ def test_invalidIdentSingleQuoteChar(self):
+ """Test a line with a single quote character for the identity digest."""
+ self.makeRLine(ident=chr(0x27))
+ fields = networkstatus.parseRLine(self.line)
+ nick, ident, desc = fields[:3]
+
+ the(nick).should.be.ok
+ the(nick).should.be.a(basestring)
+ the(nick).should.be.equal(str(self.nick))
+ the(ident).should.be.equal(None)
+ the(desc).should.be.equal(None)
+
+ def test_invalidDescriptorDigest(self):
+ """Test an 'r'-line with invalid base64 descriptor digest."""
+ self.makeRLine(desc='æå¸è¥¶')
+ fields = networkstatus.parseRLine(self.line)
+ nick, ident, desc, ts, ip = fields[:5]
+
+ the(nick).should.be.ok
+ the(nick).should.be.a(basestring)
+ the(nick).should.be.equal(str(self.nick))
+
+ b64ident = binascii.b2a_base64(ident).strip().rstrip('==')
+ the(ident).should.be.a(basestring)
+ this(b64ident).should.be.a(basestring)
+ this(b64ident).should.be.equal(self.ident)
+
+ the(desc).should.be.equal(None)
+ the(ts).should.be.equal(None)
+ the(ip).should.be.equal(None)
+
+ def test_invalidDescriptorDigest_missingBase64padding(self):
+ """Test a line with invalid base64 (no padding) descriptor digest."""
+ self.makeRLine(desc=self.desc.rstrip('=='))
+ fields = networkstatus.parseRLine(self.line)
+ nick, ident, desc, ts, ip = fields[:5]
+
+ the(nick).should.be.ok
+ the(nick).should.be.a(basestring)
+ the(nick).should.be.equal(str(self.nick))
+
+ b64ident = binascii.b2a_base64(ident).strip().rstrip('==')
+ the(ident).should.be.a(basestring)
+ this(b64ident).should.be.a(basestring)
+ this(b64ident).should.be.equal(self.ident)
+
+ the(desc).should.be.equal(None)
+ the(ts).should.be.equal(None)
+ the(ip).should.be.equal(None)
+
+ def test_missingAfterDesc(self):
+ """Test a line that has a valid descriptor digest, and is missing
+ everything after the descriptor digest, i.e. the timestamp, IP address,
+ and DirPort.
+ """
+ self.makeRLine(nick='missingAfterDesc', ts=False, ip=False, dirp=False)
+ fields = networkstatus.parseRLine(self.line)
+ self.assertAllFieldsAreNone(fields)
+
+ def test_missingAfterIdent(self):
+ """Test a line that and is missing the descriptor digest and
+ everything after it, i.e. the timestamp, IP address, and DirPort.
+ """
+ self.makeRLine(nick='noDesc', desc=False, ts=False,
+ ip=False, dirp=False)
+ fields = networkstatus.parseRLine(self.line)
+ self.assertAllFieldsAreNone(fields)
+
def test_invalidTimestamp(self):
- line = ' '.join([self.pre, self.nick, self.ident, self.desc,
- '123456789 987654321', self.ip, self.port, self.dirp])
- fields = networkstatus.parseRLine(line)
-
+ """Test line with two large integers for the timestamp."""
+ self.makeRLine(ts='123456789 987654321')
+ fields = networkstatus.parseRLine(self.line)
+
+ def test_invalidTimestampMissingDate(self):
+ """Test a line where the timestamp is missing the date portion."""
+ self.makeRLine(ts='15:15:15')
+ fields = networkstatus.parseRLine(self.line)
+ self.assertAllFieldsAreNone(fields)
+
def test_invalidIPAddress(self):
- line = ' '.join([self.pre, self.nick, self.ident, self.desc,
- self.ts, '0.0.0.0', self.port, self.dirp])
- fields = networkstatus.parseRLine(line)
-
+ """Test a line with an invalid IP address."""
+ self.makeRLine(ip='0.0.0.0')
+ fields = networkstatus.parseRLine(self.line)
+ nick, ident, desc, ts, ip, port = fields[:6]
+
+ the(nick).should.be.equal(self.nick)
+
+ b64ident = binascii.b2a_base64(ident).strip().strip('==')
+ the(ident).should.be.a(basestring)
+ this(b64ident).should.be.a(basestring)
+ this(b64ident).should.be.equal(self.ident)
+
+ b64desc = binascii.b2a_base64(desc).strip()
+ the(desc).should.be.a(basestring)
+ this(b64desc).should.be.a(basestring)
+ this(b64desc).should.be.equal(self.desc)
+
+ the(ts).should.be.a(float)
+ the(ip).should.be(None)
More information about the tor-commits
mailing list