mirror of
https://github.com/tahoe-lafs/tahoe-lafs.git
synced 2025-04-19 00:06:57 +00:00
Sketch of first IStorageServer test with HTTP server/client.
This commit is contained in:
parent
6480e0c8d3
commit
d23fdcdb8a
@ -75,6 +75,7 @@ from allmydata.util.observer import ObserverList
|
||||
from allmydata.util.rrefutil import add_version_to_remote_reference
|
||||
from allmydata.util.hashutil import permute_server_hash
|
||||
from allmydata.util.dictutil import BytesKeyDict, UnicodeKeyDict
|
||||
from allmydata.storage.http_client import StorageClient
|
||||
|
||||
|
||||
# who is responsible for de-duplication?
|
||||
@ -1024,3 +1025,40 @@ class _StorageServer(object):
|
||||
shnum,
|
||||
reason,
|
||||
).addErrback(log.err, "Error from remote call to advise_corrupt_share")
|
||||
|
||||
|
||||
# WORK IN PROGRESS, for now it doesn't actually implement whole thing.
|
||||
@implementer(IStorageServer) # type: ignore
|
||||
@attr.s
|
||||
class _HTTPStorageServer(object):
|
||||
"""
|
||||
Talk to remote storage server over HTTP.
|
||||
"""
|
||||
_http_client = attr.ib(type=StorageClient)
|
||||
|
||||
@staticmethod
|
||||
def from_http_client(http_client): # type: (StorageClient) -> _HTTPStorageServer
|
||||
"""
|
||||
Create an ``IStorageServer`` from a HTTP ``StorageClient``.
|
||||
"""
|
||||
return _HTTPStorageServer(_http_client=http_client)
|
||||
|
||||
def get_version(self):
|
||||
return self._http_client.get_version()
|
||||
|
||||
def allocate_buckets(
|
||||
self,
|
||||
storage_index,
|
||||
renew_secret,
|
||||
cancel_secret,
|
||||
sharenums,
|
||||
allocated_size,
|
||||
canary,
|
||||
):
|
||||
pass
|
||||
|
||||
def get_buckets(
|
||||
self,
|
||||
storage_index,
|
||||
):
|
||||
pass
|
||||
|
@ -1,6 +1,8 @@
|
||||
"""
|
||||
Tests for the ``IStorageServer`` interface.
|
||||
|
||||
Keep in mind that ``IStorageServer`` is actually the storage _client_ interface.
|
||||
|
||||
Note that for performance, in the future we might want the same node to be
|
||||
reused across tests, so each test should be careful to generate unique storage
|
||||
indexes.
|
||||
@ -22,6 +24,10 @@ from random import Random
|
||||
|
||||
from twisted.internet.defer import inlineCallbacks, returnValue
|
||||
from twisted.internet.task import Clock
|
||||
from twisted.internet import reactor
|
||||
from twisted.web.server import Site
|
||||
from hyperlink import DecodedURL
|
||||
from treq.api import get_global_pool as get_treq_pool
|
||||
|
||||
from foolscap.api import Referenceable, RemoteException
|
||||
|
||||
@ -29,6 +35,10 @@ from allmydata.interfaces import IStorageServer # really, IStorageClient
|
||||
from .common_system import SystemTestMixin
|
||||
from .common import AsyncTestCase
|
||||
from allmydata.storage.server import StorageServer # not a IStorageServer!!
|
||||
from allmydata.storage.http_server import HTTPServer
|
||||
from allmydata.storage.http_client import StorageClient
|
||||
from allmydata.util.iputil import allocate_tcp_port
|
||||
|
||||
|
||||
# Use random generator with known seed, so results are reproducible if tests
|
||||
# are run in the same order.
|
||||
@ -998,11 +1008,11 @@ class IStorageServerMutableAPIsTestsMixin(object):
|
||||
self.assertEqual(lease2.get_expiration_time() - initial_expiration_time, 167)
|
||||
|
||||
|
||||
class _FoolscapMixin(SystemTestMixin):
|
||||
"""Run tests on Foolscap version of ``IStorageServer."""
|
||||
class _SharedMixin(SystemTestMixin):
|
||||
"""Base class for Foolscap and HTTP mixins."""
|
||||
|
||||
def _get_native_server(self):
|
||||
return next(iter(self.clients[0].storage_broker.get_known_servers()))
|
||||
def _get_istorage_server(self):
|
||||
raise NotImplementedError("implement in subclass")
|
||||
|
||||
@inlineCallbacks
|
||||
def setUp(self):
|
||||
@ -1010,8 +1020,6 @@ class _FoolscapMixin(SystemTestMixin):
|
||||
self.basedir = "test_istorageserver/" + self.id()
|
||||
yield SystemTestMixin.setUp(self)
|
||||
yield self.set_up_nodes(1)
|
||||
self.storage_client = self._get_native_server().get_storage_server()
|
||||
self.assertTrue(IStorageServer.providedBy(self.storage_client))
|
||||
self.server = None
|
||||
for s in self.clients[0].services:
|
||||
if isinstance(s, StorageServer):
|
||||
@ -1021,6 +1029,7 @@ class _FoolscapMixin(SystemTestMixin):
|
||||
self._clock = Clock()
|
||||
self._clock.advance(123456)
|
||||
self.server._clock = self._clock
|
||||
self.storage_client = self._get_istorage_server()
|
||||
|
||||
def fake_time(self):
|
||||
"""Return the current fake, test-controlled, time."""
|
||||
@ -1035,6 +1044,25 @@ class _FoolscapMixin(SystemTestMixin):
|
||||
AsyncTestCase.tearDown(self)
|
||||
yield SystemTestMixin.tearDown(self)
|
||||
|
||||
@inlineCallbacks
|
||||
def disconnect(self):
|
||||
"""
|
||||
Disconnect and then reconnect with a new ``IStorageServer``.
|
||||
"""
|
||||
raise NotImplementedError("implement in subclass")
|
||||
|
||||
|
||||
class _FoolscapMixin(_SharedMixin):
|
||||
"""Run tests on Foolscap version of ``IStorageServer``."""
|
||||
|
||||
def _get_native_server(self):
|
||||
return next(iter(self.clients[0].storage_broker.get_known_servers()))
|
||||
|
||||
def _get_istorage_server(self):
|
||||
client = self._get_native_server().get_storage_server()
|
||||
self.assertTrue(IStorageServer.providedBy(client))
|
||||
return client
|
||||
|
||||
@inlineCallbacks
|
||||
def disconnect(self):
|
||||
"""
|
||||
@ -1046,12 +1074,43 @@ class _FoolscapMixin(SystemTestMixin):
|
||||
assert self.storage_client is not current
|
||||
|
||||
|
||||
class _HTTPMixin(_SharedMixin):
|
||||
"""Run tests on the HTTP version of ``IStorageServer``."""
|
||||
|
||||
def _get_istorage_server(self):
|
||||
swissnum = b"1234"
|
||||
self._http_storage_server = HTTPServer(self.server, swissnum)
|
||||
self._port_number = allocate_tcp_port()
|
||||
self._listening_port = reactor.listenTCP(
|
||||
self._port_number, Site(self._http_storage_server.get_resource()),
|
||||
interface="127.0.0.1"
|
||||
)
|
||||
return StorageClient(
|
||||
DecodedURL.from_text("http://127.0.0.1:{}".format(self._port_number)),
|
||||
swissnum
|
||||
)
|
||||
# Eventually should also:
|
||||
# self.assertTrue(IStorageServer.providedBy(client))
|
||||
|
||||
@inlineCallbacks
|
||||
def tearDown(self):
|
||||
yield _SharedMixin.tearDown(self)
|
||||
self._listening_port.stopListening()
|
||||
yield get_treq_pool().closeCachedConnections()
|
||||
|
||||
|
||||
class FoolscapSharedAPIsTests(
|
||||
_FoolscapMixin, IStorageServerSharedAPIsTestsMixin, AsyncTestCase
|
||||
):
|
||||
"""Foolscap-specific tests for shared ``IStorageServer`` APIs."""
|
||||
|
||||
|
||||
class HTTPSharedAPIsTests(
|
||||
_HTTPMixin, IStorageServerSharedAPIsTestsMixin, AsyncTestCase
|
||||
):
|
||||
"""HTTP-specific tests for shared ``IStorageServer`` APIs."""
|
||||
|
||||
|
||||
class FoolscapImmutableAPIsTests(
|
||||
_FoolscapMixin, IStorageServerImmutableAPIsTestsMixin, AsyncTestCase
|
||||
):
|
||||
|
Loading…
x
Reference in New Issue
Block a user