mirror of
https://github.com/tahoe-lafs/tahoe-lafs.git
synced 2024-12-20 21:43:09 +00:00
Baseline tests for anonymous storage server announcements
This commit is contained in:
parent
49abfbb62a
commit
212f96dfe7
@ -210,7 +210,7 @@ def create_client(basedir=u".", _client_factory=None):
|
||||
return defer.fail()
|
||||
|
||||
|
||||
def create_client_from_config(config, _client_factory=None):
|
||||
def create_client_from_config(config, _client_factory=None, introducer_factory=None):
|
||||
"""
|
||||
Creates a new client instance (a subclass of Node). Most code
|
||||
should probably use `create_client` instead.
|
||||
@ -222,6 +222,9 @@ def create_client_from_config(config, _client_factory=None):
|
||||
|
||||
:param _client_factory: for testing; the class to instantiate
|
||||
instead of _Client
|
||||
|
||||
:param introducer_factory: for testing; the class to instantiate instead
|
||||
of IntroducerClient
|
||||
"""
|
||||
try:
|
||||
if _client_factory is None:
|
||||
@ -239,7 +242,7 @@ def create_client_from_config(config, _client_factory=None):
|
||||
)
|
||||
control_tub = node.create_control_tub()
|
||||
|
||||
introducer_clients = create_introducer_clients(config, main_tub)
|
||||
introducer_clients = create_introducer_clients(config, main_tub, introducer_factory)
|
||||
storage_broker = create_storage_farm_broker(
|
||||
config, default_connection_handlers, foolscap_connection_handlers,
|
||||
tub_options, introducer_clients
|
||||
@ -281,12 +284,18 @@ def _sequencer(config):
|
||||
return seqnum, nonce
|
||||
|
||||
|
||||
def create_introducer_clients(config, main_tub):
|
||||
def create_introducer_clients(config, main_tub, introducer_factory=None):
|
||||
"""
|
||||
Read, validate and parse any 'introducers.yaml' configuration.
|
||||
|
||||
:param introducer_factory: for testing; the class to instantiate instead
|
||||
of IntroducerClient
|
||||
|
||||
:returns: a list of IntroducerClient instances
|
||||
"""
|
||||
if introducer_factory is None:
|
||||
introducer_factory = IntroducerClient
|
||||
|
||||
# we return this list
|
||||
introducer_clients = []
|
||||
|
||||
@ -332,7 +341,7 @@ def create_introducer_clients(config, main_tub):
|
||||
|
||||
for petname, introducer in introducers.items():
|
||||
introducer_cache_filepath = FilePath(config.get_private_path("introducer_{}_cache.yaml".format(petname)))
|
||||
ic = IntroducerClient(
|
||||
ic = introducer_factory(
|
||||
main_tub,
|
||||
introducer['furl'].encode("ascii"),
|
||||
config.nickname,
|
||||
|
49
src/allmydata/test/matchers.py
Normal file
49
src/allmydata/test/matchers.py
Normal file
@ -0,0 +1,49 @@
|
||||
"""
|
||||
Testtools-style matchers useful to the Tahoe-LAFS test suite.
|
||||
"""
|
||||
|
||||
from testtools.matchers import (
|
||||
AfterPreprocessing,
|
||||
MatchesStructure,
|
||||
MatchesDict,
|
||||
Always,
|
||||
Equals,
|
||||
)
|
||||
|
||||
from foolscap.furl import (
|
||||
decode_furl,
|
||||
)
|
||||
|
||||
from allmydata.util import (
|
||||
base32,
|
||||
)
|
||||
|
||||
|
||||
def matches_anonymous_storage_announcement():
|
||||
"""
|
||||
Match an anonymous storage announcement.
|
||||
"""
|
||||
return MatchesStructure(
|
||||
# Has each of these keys with associated values that match
|
||||
service_name=Equals("storage"),
|
||||
ann=MatchesDict({
|
||||
"anonymous-storage-FURL": matches_furl(),
|
||||
"permutation-seed-base32": matches_base32(),
|
||||
}),
|
||||
# Not sure what kind of assertion to make against the key
|
||||
signing_key=Always(),
|
||||
)
|
||||
|
||||
|
||||
def matches_furl():
|
||||
"""
|
||||
Match any Foolscap fURL byte string.
|
||||
"""
|
||||
return AfterPreprocessing(decode_furl, Always())
|
||||
|
||||
|
||||
def matches_base32():
|
||||
"""
|
||||
Match any base32 encoded byte string.
|
||||
"""
|
||||
return AfterPreprocessing(base32.a2b, Always())
|
@ -1,5 +1,8 @@
|
||||
import os, sys
|
||||
import mock
|
||||
|
||||
import attr
|
||||
|
||||
import twisted
|
||||
from yaml import (
|
||||
safe_dump,
|
||||
@ -21,6 +24,7 @@ from twisted.python.filepath import (
|
||||
from testtools.matchers import (
|
||||
Equals,
|
||||
AfterPreprocessing,
|
||||
MatchesListwise,
|
||||
)
|
||||
from testtools.twistedsupport import (
|
||||
succeeded,
|
||||
@ -41,10 +45,12 @@ from allmydata.interfaces import IFilesystemNode, IFileNode, \
|
||||
IImmutableFileNode, IMutableFileNode, IDirectoryNode
|
||||
from foolscap.api import flushEventualQueue
|
||||
import allmydata.test.common_util as testutil
|
||||
from allmydata.test.common import (
|
||||
from .common import (
|
||||
SyncTestCase,
|
||||
)
|
||||
|
||||
from .matchers import (
|
||||
matches_anonymous_storage_announcement,
|
||||
)
|
||||
|
||||
BASECONFIG = ("[client]\n"
|
||||
"introducer.furl = \n"
|
||||
@ -980,3 +986,143 @@ class NodeMaker(testutil.ReallyEqualMixin, unittest.TestCase):
|
||||
self.failUnlessReallyEqual(n.get_uri(), unknown_rw)
|
||||
self.failUnlessReallyEqual(n.get_write_uri(), unknown_rw)
|
||||
self.failUnlessReallyEqual(n.get_readonly_uri(), "ro." + unknown_ro)
|
||||
|
||||
|
||||
|
||||
@attr.s
|
||||
class MemoryIntroducerClient(object):
|
||||
"""
|
||||
A model-only (no behavior) stand-in for ``IntroducerClient``.
|
||||
"""
|
||||
tub = attr.ib()
|
||||
introducer_furl = attr.ib()
|
||||
nickname = attr.ib()
|
||||
my_version = attr.ib()
|
||||
oldest_supported = attr.ib()
|
||||
app_versions = attr.ib()
|
||||
sequencer = attr.ib()
|
||||
cache_filepath = attr.ib()
|
||||
|
||||
subscribed_to = attr.ib(default=attr.Factory(list))
|
||||
published_announcements = attr.ib(default=attr.Factory(list))
|
||||
|
||||
|
||||
def setServiceParent(self, parent):
|
||||
pass
|
||||
|
||||
|
||||
def subscribe_to(self, service_name, cb, *args, **kwargs):
|
||||
self.subscribed_to.append(Subscription(service_name, cb, args, kwargs))
|
||||
|
||||
|
||||
def publish(self, service_name, ann, signing_key):
|
||||
self.published_announcements.append(Announcement(service_name, ann, signing_key))
|
||||
|
||||
|
||||
|
||||
@attr.s
|
||||
class Subscription(object):
|
||||
"""
|
||||
A model of an introducer subscription.
|
||||
"""
|
||||
service_name = attr.ib()
|
||||
cb = attr.ib()
|
||||
args = attr.ib()
|
||||
kwargs = attr.ib()
|
||||
|
||||
|
||||
|
||||
@attr.s
|
||||
class Announcement(object):
|
||||
"""
|
||||
A model of an introducer announcement.
|
||||
"""
|
||||
service_name = attr.ib()
|
||||
ann = attr.ib()
|
||||
signing_key = attr.ib()
|
||||
|
||||
|
||||
|
||||
def get_published_announcements(client):
|
||||
"""
|
||||
Get a flattened list of all announcements sent using all introducer
|
||||
clients.
|
||||
"""
|
||||
return list(
|
||||
announcement
|
||||
for introducer_client
|
||||
in client.introducer_clients
|
||||
for announcement
|
||||
in introducer_client.published_announcements
|
||||
)
|
||||
|
||||
|
||||
|
||||
class StorageAnnouncementTests(SyncTestCase):
|
||||
"""
|
||||
Tests for the storage announcement published by the client.
|
||||
"""
|
||||
def setUp(self):
|
||||
super(StorageAnnouncementTests, self).setUp()
|
||||
self.basedir = self.useFixture(TempDir()).path
|
||||
create_node_dir(self.basedir, u"")
|
||||
|
||||
|
||||
def get_config(self, storage_enabled):
|
||||
return b"""
|
||||
[node]
|
||||
tub.location = tcp:192.0.2.0:1234
|
||||
|
||||
[storage]
|
||||
enabled = {storage_enabled}
|
||||
|
||||
[client]
|
||||
introducer.furl = pb://abcde@nowhere/fake
|
||||
""".format(storage_enabled=storage_enabled)
|
||||
|
||||
|
||||
def test_no_announcement(self):
|
||||
"""
|
||||
No storage announcement is published if storage is not enabled.
|
||||
"""
|
||||
config = config_from_string(
|
||||
self.basedir,
|
||||
u"tub.port",
|
||||
self.get_config(storage_enabled=False),
|
||||
)
|
||||
self.assertThat(
|
||||
client.create_client_from_config(config, introducer_factory=MemoryIntroducerClient),
|
||||
succeeded(AfterPreprocessing(
|
||||
get_published_announcements,
|
||||
Equals([]),
|
||||
)),
|
||||
)
|
||||
|
||||
|
||||
def test_anonymous_storage_announcement(self):
|
||||
"""
|
||||
A storage announcement with the anonymous storage fURL is published when
|
||||
storage is enabled.
|
||||
"""
|
||||
config = config_from_string(
|
||||
self.basedir,
|
||||
u"tub.port",
|
||||
self.get_config(storage_enabled=True),
|
||||
)
|
||||
client_deferred = client.create_client_from_config(
|
||||
config,
|
||||
introducer_factory=MemoryIntroducerClient,
|
||||
)
|
||||
self.assertThat(
|
||||
client_deferred,
|
||||
# The Deferred succeeds
|
||||
succeeded(AfterPreprocessing(
|
||||
# The announcements published by the client should ...
|
||||
get_published_announcements,
|
||||
# Match the following list (of one element) ...
|
||||
MatchesListwise([
|
||||
# The only element in the list ...
|
||||
matches_anonymous_storage_announcement(),
|
||||
]),
|
||||
)),
|
||||
)
|
||||
|
Loading…
Reference in New Issue
Block a user