First passing immutable-API-over-HTTP IStorageServer tests.
This commit is contained in:
parent
ef56435578
commit
66abe5dfca
|
@ -40,7 +40,7 @@ if PY2:
|
|||
from six import ensure_text
|
||||
|
||||
import re, time, hashlib
|
||||
|
||||
from os import urandom
|
||||
# On Python 2 this will be the backport.
|
||||
from configparser import NoSectionError
|
||||
|
||||
|
@ -75,7 +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
|
||||
from allmydata.storage.http_client import StorageClient, StorageClientImmutables
|
||||
|
||||
|
||||
# who is responsible for de-duplication?
|
||||
|
@ -1027,6 +1027,48 @@ class _StorageServer(object):
|
|||
).addErrback(log.err, "Error from remote call to advise_corrupt_share")
|
||||
|
||||
|
||||
|
||||
@attr.s
|
||||
class _FakeRemoteReference(object):
|
||||
"""
|
||||
Emulate a Foolscap RemoteReference, calling a local object instead.
|
||||
"""
|
||||
local_object = attr.ib(type=object)
|
||||
|
||||
def callRemote(self, action, *args, **kwargs):
|
||||
return getattr(self.local_object, action)(*args, **kwargs)
|
||||
|
||||
|
||||
@attr.s
|
||||
class _HTTPBucketWriter(object):
|
||||
"""
|
||||
Emulate a ``RIBucketWriter``.
|
||||
"""
|
||||
client = attr.ib(type=StorageClientImmutables)
|
||||
storage_index = attr.ib(type=bytes)
|
||||
share_number = attr.ib(type=int)
|
||||
upload_secret = attr.ib(type=bytes)
|
||||
finished = attr.ib(type=bool, default=False)
|
||||
|
||||
def abort(self):
|
||||
pass # TODO in later ticket
|
||||
|
||||
@defer.inlineCallbacks
|
||||
def write(self, offset, data):
|
||||
result = yield self.client.write_share_chunk(
|
||||
self.storage_index, self.share_number, self.upload_secret, offset, data
|
||||
)
|
||||
if result.finished:
|
||||
self.finished = True
|
||||
defer.returnValue(None)
|
||||
|
||||
def close(self):
|
||||
# A no-op in HTTP protocol.
|
||||
if not self.finished:
|
||||
return defer.fail(RuntimeError("You didn't finish writing?!"))
|
||||
return defer.succeed(None)
|
||||
|
||||
|
||||
# WORK IN PROGRESS, for now it doesn't actually implement whole thing.
|
||||
@implementer(IStorageServer) # type: ignore
|
||||
@attr.s
|
||||
|
@ -1041,11 +1083,12 @@ class _HTTPStorageServer(object):
|
|||
"""
|
||||
Create an ``IStorageServer`` from a HTTP ``StorageClient``.
|
||||
"""
|
||||
return _HTTPStorageServer(_http_client=http_client)
|
||||
return _HTTPStorageServer(http_client=http_client)
|
||||
|
||||
def get_version(self):
|
||||
return self._http_client.get_version()
|
||||
|
||||
@defer.inlineCallbacks
|
||||
def allocate_buckets(
|
||||
self,
|
||||
storage_index,
|
||||
|
@ -1055,7 +1098,24 @@ class _HTTPStorageServer(object):
|
|||
allocated_size,
|
||||
canary,
|
||||
):
|
||||
pass
|
||||
upload_secret = urandom(20)
|
||||
immutable_client = StorageClientImmutables(self._http_client)
|
||||
result = immutable_client.create(
|
||||
storage_index, sharenums, allocated_size, upload_secret, renew_secret,
|
||||
cancel_secret
|
||||
)
|
||||
result = yield result
|
||||
defer.returnValue(
|
||||
(result.already_have, {
|
||||
share_num: _FakeRemoteReference(_HTTPBucketWriter(
|
||||
client=immutable_client,
|
||||
storage_index=storage_index,
|
||||
share_number=share_num,
|
||||
upload_secret=upload_secret
|
||||
))
|
||||
for share_num in result.allocated
|
||||
})
|
||||
)
|
||||
|
||||
def get_buckets(
|
||||
self,
|
||||
|
|
|
@ -39,6 +39,7 @@ 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
|
||||
from allmydata.storage_client import _HTTPStorageServer
|
||||
|
||||
|
||||
# Use random generator with known seed, so results are reproducible if tests
|
||||
|
@ -1084,12 +1085,15 @@ class _HTTPMixin(_SharedMixin):
|
|||
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"
|
||||
self._port_number,
|
||||
Site(self._http_storage_server.get_resource()),
|
||||
interface="127.0.0.1",
|
||||
)
|
||||
return StorageClient(
|
||||
return _HTTPStorageServer.from_http_client(
|
||||
StorageClient(
|
||||
DecodedURL.from_text("http://127.0.0.1:{}".format(self._port_number)),
|
||||
swissnum
|
||||
swissnum,
|
||||
)
|
||||
)
|
||||
# Eventually should also:
|
||||
# self.assertTrue(IStorageServer.providedBy(client))
|
||||
|
@ -1118,6 +1122,12 @@ class FoolscapImmutableAPIsTests(
|
|||
"""Foolscap-specific tests for immutable ``IStorageServer`` APIs."""
|
||||
|
||||
|
||||
class HTTPImmutableAPIsTests(
|
||||
_HTTPMixin, IStorageServerImmutableAPIsTestsMixin, AsyncTestCase
|
||||
):
|
||||
"""HTTP-specific tests for immutable ``IStorageServer`` APIs."""
|
||||
|
||||
|
||||
class FoolscapMutableAPIsTests(
|
||||
_FoolscapMixin, IStorageServerMutableAPIsTestsMixin, AsyncTestCase
|
||||
):
|
||||
|
|
Loading…
Reference in New Issue