move parse_hint/encode_hint into _hints.py, add tests
This commit is contained in:
parent
d64c94a1dc
commit
b4c90b40a2
|
@ -21,42 +21,9 @@ from .roles import LEADER
|
|||
|
||||
from .._hints import (DirectTCPV1Hint, TorTCPV1Hint, RelayV1Hint,
|
||||
parse_hint_argv, describe_hint_obj, endpoint_from_hint_obj,
|
||||
parse_tcp_v1_hint)
|
||||
encode_hint)
|
||||
|
||||
|
||||
def parse_hint(hint_struct):
|
||||
hint_type = hint_struct.get("type", "")
|
||||
if hint_type == "relay-v1":
|
||||
# the struct can include multiple ways to reach the same relay
|
||||
rhints = filter(lambda h: h, # drop None (unrecognized)
|
||||
[parse_tcp_v1_hint(rh) for rh in hint_struct["hints"]])
|
||||
return RelayV1Hint(rhints)
|
||||
return parse_tcp_v1_hint(hint_struct)
|
||||
|
||||
|
||||
def encode_hint(h):
|
||||
if isinstance(h, DirectTCPV1Hint):
|
||||
return {"type": "direct-tcp-v1",
|
||||
"priority": h.priority,
|
||||
"hostname": h.hostname,
|
||||
"port": h.port, # integer
|
||||
}
|
||||
elif isinstance(h, RelayV1Hint):
|
||||
rhint = {"type": "relay-v1", "hints": []}
|
||||
for rh in h.hints:
|
||||
rhint["hints"].append({"type": "direct-tcp-v1",
|
||||
"priority": rh.priority,
|
||||
"hostname": rh.hostname,
|
||||
"port": rh.port})
|
||||
return rhint
|
||||
elif isinstance(h, TorTCPV1Hint):
|
||||
return {"type": "tor-tcp-v1",
|
||||
"priority": h.priority,
|
||||
"hostname": h.hostname,
|
||||
"port": h.port, # integer
|
||||
}
|
||||
raise ValueError("unknown hint type", h)
|
||||
|
||||
|
||||
def HKDF(skm, outlen, salt=None, CTXinfo=b""):
|
||||
return Hkdf(salt, skm).expand(CTXinfo, outlen)
|
||||
|
|
|
@ -15,7 +15,8 @@ from .encode import to_be4
|
|||
from .subchannel import (SubChannel, _SubchannelAddress, _WormholeAddress,
|
||||
ControlEndpoint, SubchannelConnectorEndpoint,
|
||||
SubchannelListenerEndpoint)
|
||||
from .connector import Connector, parse_hint
|
||||
from .connector import Connector
|
||||
from .._hints import parse_hint
|
||||
from .roles import LEADER, FOLLOWER
|
||||
from .connection import KCM, Ping, Pong, Open, Data, Close, Ack
|
||||
from .inbound import Inbound
|
||||
|
|
|
@ -103,3 +103,36 @@ def parse_tcp_v1_hint(hint): # hint_struct -> hint_obj
|
|||
return DirectTCPV1Hint(hint["hostname"], hint["port"], priority)
|
||||
else:
|
||||
return TorTCPV1Hint(hint["hostname"], hint["port"], priority)
|
||||
|
||||
def parse_hint(hint_struct):
|
||||
hint_type = hint_struct.get("type", "")
|
||||
if hint_type == "relay-v1":
|
||||
# the struct can include multiple ways to reach the same relay
|
||||
rhints = filter(lambda h: h, # drop None (unrecognized)
|
||||
[parse_tcp_v1_hint(rh) for rh in hint_struct["hints"]])
|
||||
return RelayV1Hint(list(rhints))
|
||||
return parse_tcp_v1_hint(hint_struct)
|
||||
|
||||
|
||||
def encode_hint(h):
|
||||
if isinstance(h, DirectTCPV1Hint):
|
||||
return {"type": "direct-tcp-v1",
|
||||
"priority": h.priority,
|
||||
"hostname": h.hostname,
|
||||
"port": h.port, # integer
|
||||
}
|
||||
elif isinstance(h, RelayV1Hint):
|
||||
rhint = {"type": "relay-v1", "hints": []}
|
||||
for rh in h.hints:
|
||||
rhint["hints"].append({"type": "direct-tcp-v1",
|
||||
"priority": rh.priority,
|
||||
"hostname": rh.hostname,
|
||||
"port": rh.port})
|
||||
return rhint
|
||||
elif isinstance(h, TorTCPV1Hint):
|
||||
return {"type": "tor-tcp-v1",
|
||||
"priority": h.priority,
|
||||
"hostname": h.hostname,
|
||||
"port": h.port, # integer
|
||||
}
|
||||
raise ValueError("unknown hint type", h)
|
||||
|
|
|
@ -5,7 +5,7 @@ import mock
|
|||
from twisted.internet import endpoints, reactor
|
||||
from twisted.trial import unittest
|
||||
from .._hints import (endpoint_from_hint_obj, parse_hint_argv, parse_tcp_v1_hint,
|
||||
describe_hint_obj,
|
||||
describe_hint_obj, parse_hint, encode_hint,
|
||||
DirectTCPV1Hint, TorTCPV1Hint, RelayV1Hint)
|
||||
|
||||
UnknownHint = namedtuple("UnknownHint", ["stuff"])
|
||||
|
@ -89,6 +89,24 @@ class Hints(unittest.TestCase):
|
|||
"port": "not a number"
|
||||
}), None) # invalid port
|
||||
|
||||
def test_parse_hint(self):
|
||||
p = parse_hint
|
||||
self.assertEqual(p({"type": "direct-tcp-v1",
|
||||
"hostname": "foo",
|
||||
"port": 12}),
|
||||
DirectTCPV1Hint("foo", 12, 0.0))
|
||||
self.assertEqual(p({"type": "relay-v1",
|
||||
"hints": [
|
||||
{"type": "direct-tcp-v1",
|
||||
"hostname": "foo",
|
||||
"port": 12},
|
||||
{"type": "unrecognized"},
|
||||
{"type": "direct-tcp-v1",
|
||||
"hostname": "bar",
|
||||
"port": 13}]}),
|
||||
RelayV1Hint([DirectTCPV1Hint("foo", 12, 0.0),
|
||||
DirectTCPV1Hint("bar", 13, 0.0)]))
|
||||
|
||||
def test_parse_hint_argv(self):
|
||||
def p(hint):
|
||||
stderr = io.StringIO()
|
||||
|
@ -147,3 +165,32 @@ class Hints(unittest.TestCase):
|
|||
"->tor:host:1234")
|
||||
self.assertEqual(d(UnknownHint("stuff"), False, False),
|
||||
"->%s" % str(UnknownHint("stuff")))
|
||||
|
||||
def test_encode_hint(self):
|
||||
e = encode_hint
|
||||
self.assertEqual(e(DirectTCPV1Hint("host", 1234, 1.0)),
|
||||
{"type": "direct-tcp-v1",
|
||||
"priority": 1.0,
|
||||
"hostname": "host",
|
||||
"port": 1234})
|
||||
self.assertEqual(e(RelayV1Hint([DirectTCPV1Hint("foo", 12, 0.0),
|
||||
DirectTCPV1Hint("bar", 13, 0.0)])),
|
||||
{"type": "relay-v1",
|
||||
"hints": [
|
||||
{"type": "direct-tcp-v1",
|
||||
"hostname": "foo",
|
||||
"port": 12,
|
||||
"priority": 0.0},
|
||||
{"type": "direct-tcp-v1",
|
||||
"hostname": "bar",
|
||||
"port": 13,
|
||||
"priority": 0.0},
|
||||
]})
|
||||
self.assertEqual(e(TorTCPV1Hint("host", 1234, 1.0)),
|
||||
{"type": "tor-tcp-v1",
|
||||
"priority": 1.0,
|
||||
"hostname": "host",
|
||||
"port": 1234})
|
||||
e = self.assertRaises(ValueError, e, "not a Hint")
|
||||
self.assertIn("unknown hint type", str(e))
|
||||
self.assertIn("not a Hint", str(e))
|
||||
|
|
Loading…
Reference in New Issue
Block a user