mirror of
https://github.com/freedombox/FreedomBox.git
synced 2026-06-10 11:00:22 +00:00
Added a few notes about why this is difficult to test.
- Reorganized file a little. - Test requests are now from and to real clients.
This commit is contained in:
parent
bffb2d93b5
commit
2d1e473a9b
@ -1,3 +1,6 @@
|
||||
#! /usr/bin/python -*- mode: autofill; fill-column: 80 -*-
|
||||
|
||||
|
||||
"""Making Santiago dance, in 4 parts:
|
||||
|
||||
- Validating the initial request (playing B).
|
||||
@ -11,8 +14,33 @@
|
||||
- Validating the direct response (playing A).
|
||||
- Validating the indirect response (playing C, B, and A).
|
||||
|
||||
FIXME: Can't use the current CPy setup. It never returns, so I can't test
|
||||
against it.
|
||||
|
||||
If I produce a listener that just echoes the parameters, I can validate the response:
|
||||
|
||||
import httplib, urllib
|
||||
|
||||
params = urllib.urlencode({'@number': 12524, '@type': 'issue', '@action': 'show'})
|
||||
headers = {"Content-type": "application/x-www-form-urlencoded",
|
||||
"Accept": "text/plain"}
|
||||
conn = httplib.HTTPConnection("bugs.python.org")
|
||||
print params, headers, conn
|
||||
|
||||
conn.request("POST", "", params, headers)
|
||||
response = conn.getresponse()
|
||||
print response.status, response.reason
|
||||
|
||||
data = response.read()
|
||||
print data
|
||||
|
||||
conn.close()
|
||||
|
||||
|
||||
"""
|
||||
|
||||
|
||||
import cherrypy
|
||||
import unittest
|
||||
from protocols.http import SantiagoHttpSender, SantiagoHttpListener
|
||||
import santiago
|
||||
@ -43,6 +71,29 @@ class SantiagoTest(unittest.TestCase):
|
||||
self.santiago_a = Santiago(listeners_a, senders_a, hosting_a, consuming_a)
|
||||
self.santiago_b = Santiago(listeners_b, senders_b, hosting_b, consuming_b)
|
||||
|
||||
def serveOnPort(self, port):
|
||||
"""Start listening for connections on a named port.
|
||||
|
||||
Used in testing as a mock listener for responses from a Santiago server.
|
||||
|
||||
"""
|
||||
class RequestReceiver(object):
|
||||
"""A very basic listener.
|
||||
|
||||
It merely records the calling arguments.
|
||||
|
||||
"""
|
||||
@cherrypy.expose
|
||||
def index(self, *args, **kwargs):
|
||||
self.args = args
|
||||
self.kwargs = kwargs
|
||||
|
||||
self.socket_port = port
|
||||
|
||||
self.receiver = RequestReceiver()
|
||||
|
||||
cherrypy.quickstart(self.receiver)
|
||||
|
||||
if sys.version_info < (2, 7):
|
||||
"""Add a poor man's forward compatibility."""
|
||||
|
||||
@ -53,6 +104,44 @@ class SantiagoTest(unittest.TestCase):
|
||||
if not a in b:
|
||||
raise self.ContainsError("%s not in %s" % (a, b))
|
||||
|
||||
class TestClientInitialRequest(SantiagoTest):
|
||||
"""Does the client send a correctly formed request?
|
||||
|
||||
In these tests, we're sending requests to a mock listener which merely
|
||||
records that the requests were well-formed.
|
||||
|
||||
"""
|
||||
def setUp(self):
|
||||
super(SantiagoTest, self).setUp()
|
||||
|
||||
self.serveOnPort(8000)
|
||||
|
||||
def test_request(self):
|
||||
"""Verify that A queues a properly formatted initial request."""
|
||||
|
||||
self.santiago_a.request(from_="a", to="b",
|
||||
client="a", host="b",
|
||||
service="wiki", reply_to="localhost:9001")
|
||||
|
||||
self.assertEqual(self.santiago_a.outgoing_messages,
|
||||
[{ "from": "a", "to": "b",
|
||||
"client": "a", "host": "b",
|
||||
"service": "wiki", "reply-to": "localhost:9001"}])
|
||||
|
||||
def test_request(self):
|
||||
"""Verify that A sends out a properly formatted initial request."""
|
||||
|
||||
self.santiago_a.request(from_="a", to="b",
|
||||
client="a", host="b",
|
||||
service="wiki", reply_to="localhost:9001")
|
||||
|
||||
self.santiago_a.process()
|
||||
|
||||
self.assertEqual(self.receiver.kwargs,
|
||||
[{ "from": "a", "to": "b",
|
||||
"client": "a", "host": "b",
|
||||
"service": "wiki", "reply-to": "localhost:9001"}])
|
||||
|
||||
class TestServerInitialRequest(SantiagoTest):
|
||||
"""Test how the Santiago server replies to initial service requests.
|
||||
|
||||
@ -68,6 +157,11 @@ class TestServerInitialRequest(SantiagoTest):
|
||||
untrusted client, B ignores it.
|
||||
|
||||
"""
|
||||
def setUp(self):
|
||||
super(SantiagoTest, self).setUp()
|
||||
|
||||
self.serveOnPort(9000)
|
||||
|
||||
def test_acknowledgement(self):
|
||||
"""If B receives an authorized request, then it replies with a location.
|
||||
|
||||
@ -77,7 +171,7 @@ class TestServerInitialRequest(SantiagoTest):
|
||||
In this case, B will answer with the wiki's location.
|
||||
|
||||
"""
|
||||
self.santiago_b.receive(from_=None, to=None,
|
||||
self.santiago_b.receive(from_="a", to="b",
|
||||
client="a", host="b",
|
||||
service="wiki", reply_to=None)
|
||||
|
||||
@ -90,13 +184,13 @@ class TestServerInitialRequest(SantiagoTest):
|
||||
"locations": ["192.168.0.13"],
|
||||
"reply-to": "localhost:8000"}])
|
||||
|
||||
def test_reject_bad_service(self)
|
||||
def test_reject_bad_service(self):
|
||||
"""Does B reject requests for unsupported services?
|
||||
|
||||
In this case, B should reply with an empty list of locations.
|
||||
|
||||
"""
|
||||
self.santiago_b.receive(from_=None, to=None,
|
||||
self.santiago_b.receive(from_="a", to="b",
|
||||
client="a", host="b",
|
||||
service="wiki", reply_to=None)
|
||||
|
||||
@ -119,7 +213,7 @@ class TestServerInitialRequest(SantiagoTest):
|
||||
In this case, B will never answer the request.
|
||||
|
||||
"""
|
||||
self.santiago_b.receive(from_=None, to=None,
|
||||
self.santiago_b.receive(from_="a", to="b",
|
||||
client="z", host="b",
|
||||
service="wiki", reply_to=None)
|
||||
|
||||
@ -132,7 +226,11 @@ class TestServerInitialRequest(SantiagoTest):
|
||||
untrusted key connection attempt.
|
||||
|
||||
"""
|
||||
self.fail()
|
||||
self.santiago_b.receive(from_="a", to="b",
|
||||
client="z", host="b",
|
||||
service="wiki", reply_to=None)
|
||||
|
||||
self.assertEqual(self.santiago_b.outgoing_messages, [])
|
||||
|
||||
def test_reject_bad_source_good_client(self):
|
||||
"""B is silent when an untrusted key proxies anything for a trusted key.
|
||||
@ -141,7 +239,11 @@ class TestServerInitialRequest(SantiagoTest):
|
||||
untrusted key connection attempt.
|
||||
|
||||
"""
|
||||
self.fail()
|
||||
self.santiago_b.receive(from_="z", to="b",
|
||||
client="a", host="b",
|
||||
service="wiki", reply_to=None)
|
||||
|
||||
self.assertEqual(self.santiago_b.outgoing_messages, [])
|
||||
|
||||
def test_reject_bad_source_bad_client(self):
|
||||
"""B is silent when untrusted keys proxy anything for untrusted keys.
|
||||
@ -150,7 +252,11 @@ class TestServerInitialRequest(SantiagoTest):
|
||||
connection attempt.
|
||||
|
||||
"""
|
||||
self.fail()
|
||||
self.santiago_b.receive(from_="y", to="b",
|
||||
client="z", host="b",
|
||||
service="wiki", reply_to=None)
|
||||
|
||||
self.assertEqual(self.santiago_b.outgoing_messages, [])
|
||||
|
||||
def test_learn_santaigo(self):
|
||||
"""Does B learn new Santiago locations from trusted requests?
|
||||
@ -158,7 +264,7 @@ class TestServerInitialRequest(SantiagoTest):
|
||||
If A sends B a request with a new Santiago location, B should learn it.
|
||||
|
||||
"""
|
||||
self.santiago_b.receive(from_=None, to=None,
|
||||
self.santiago_b.receive(from_="a", to="b",
|
||||
client="a", host="b",
|
||||
service="wiki", reply_to="localhost:9001")
|
||||
|
||||
@ -168,62 +274,13 @@ class TestServerInitialRequest(SantiagoTest):
|
||||
def test_handle_requests_once(self):
|
||||
"""Verify that we reply to each request only once."""
|
||||
|
||||
self.santiago_b.receive(from_=None, to=None,
|
||||
self.santiago_b.receive(from_="a", to="b",
|
||||
client="a", host="b",
|
||||
service="wiki", reply_to=None)
|
||||
self.santiago_b.process()
|
||||
|
||||
self.assertEqual(self.santiago_b.outgoing_messages, [])
|
||||
|
||||
class TestClientInitialRequest(SantiagoTest):
|
||||
"""Does the client send a correctly formed request?
|
||||
|
||||
In these tests, we're sending requests to a mock listener which merely
|
||||
records that the requests were well-formed.
|
||||
|
||||
"""
|
||||
def setUp(self):
|
||||
super(SantiagoTest, self).setUp()
|
||||
|
||||
import cherrypy
|
||||
class RequestReceiver(object):
|
||||
|
||||
def index(self, *args, **kwargs):
|
||||
self.args = *args
|
||||
self.kwargs = **kwargs
|
||||
|
||||
index.exposed = True
|
||||
self.socket_port = 8000
|
||||
|
||||
self.receiver = RequestReceiver()
|
||||
cherrypy.quickstart(self.receiver)
|
||||
|
||||
def test_request(self):
|
||||
"""Verify that A queues a properly formatted initial request."""
|
||||
|
||||
self.santiago_a.request(from_="a", to="b",
|
||||
client="a", host="b",
|
||||
service="wiki", reply_to="localhost:9001")
|
||||
|
||||
self.assertEqual(self.santiago_a.outgoing_messages,
|
||||
[{ "from": "a", "to": "b",
|
||||
"client": "a", "host": "b",
|
||||
"service": "wiki", "reply-to": "localhost:9001"})]
|
||||
|
||||
def test_request(self):
|
||||
"""Verify that A sends out a properly formatted initial request."""
|
||||
|
||||
self.santiago_a.request(from_="a", to="b",
|
||||
client="a", host="b",
|
||||
service="wiki", reply_to="localhost:9001")
|
||||
|
||||
self.santiago_a.process()
|
||||
|
||||
self.assertEqual(self.receiver.kwargs,
|
||||
[{ "from": "a", "to": "b",
|
||||
"client": "a", "host": "b",
|
||||
"service": "wiki", "reply-to": "localhost:9001"})]
|
||||
|
||||
class TestServerInitialResponse(SantiagoTest):
|
||||
pass
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user