Skip to content
Snippets Groups Projects
Commit badbd585 authored by Jean-Paul Calderone's avatar Jean-Paul Calderone
Browse files

Some more basic testing

parent dac9a434
No related branches found
No related tags found
1 merge request!4Cryptoless Tahoe-LAFS storage server plugin
......@@ -9,13 +9,16 @@ buildPythonPackage rec {
];
propagatedBuildInputs = with pythonPackages; [
attrs
zope_interface
twisted
tahoe-lafs
];
checkInputs = with pythonPackages; [
fixtures
testtools
hypothesis
];
checkPhase = ''
......
......@@ -17,18 +17,33 @@ The Twisted plugin that glues the Secure Access Token system into
Tahoe-LAFS.
"""
import attr
from zope.interface import (
implementer,
)
from twisted.internet.defer import (
succeed,
)
from allmydata.interfaces import (
IFoolscapStoragePlugin,
IAnnounceableStorageServer,
)
from .api import (
SecureAccessTokenAuthorizerStorageServer,
)
@implementer(IAnnounceableStorageServer)
@attr.s
class AnnounceableStorageServer(object):
announcement = attr.ib()
storage_server = attr.ib()
@implementer(IFoolscapStoragePlugin)
class SecureAccessTokenAuthorizer(object):
"""
......@@ -38,10 +53,18 @@ class SecureAccessTokenAuthorizer(object):
name = u"privatestorageio-satauthz-v1"
def get_storage_server(self, configuration, get_anonymous_storage_server):
return SecureAccessTokenAuthorizerStorageServer(
announcement = {}
storage_server = SecureAccessTokenAuthorizerStorageServer(
get_anonymous_storage_server(),
**configuration
)
return succeed(
AnnounceableStorageServer(
announcement,
storage_server,
),
)
def get_storage_client(self, configuration, announcement):
raise NotImplementedError()
......@@ -30,6 +30,7 @@ from foolscap.constraint import (
)
from foolscap.api import (
ListOf,
Referenceable,
)
from foolscap.remoteinterface import (
RemoteMethodSchema,
......@@ -95,7 +96,7 @@ class RITokenAuthorizedStorageServer(RemoteInterface):
@implementer(RITokenAuthorizedStorageServer)
class SecureAccessTokenAuthorizerStorageServer(proxyForInterface(RIStorageServer)):
class SecureAccessTokenAuthorizerStorageServer(proxyForInterface(RIStorageServer), Referenceable):
def allocate_buckets(self, tokens, *a, **kw):
self._validate_tokens(tokens)
return super(SecureAccessTokenAuthorizerStorageServer, self).allocate_buckets(*a, **kw)
......
# Copyright 2019 PrivateStorage.io, LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""
Testtools matchers useful for the test suite.
"""
import attr
from testtools.matchers import (
Mismatch,
)
@attr.s
class Provides(object):
"""
Match objects that provide one or more Zope Interface interfaces.
"""
interfaces = attr.ib()
def match(self, obj):
missing = set()
for iface in self.interfaces:
if not iface.providedBy(obj):
missing.add(iface)
if missing:
return Mismatch("{} does not provide expected {}".format(
obj, ", ".join(str(iface) for iface in missing),
))
# Copyright 2019 PrivateStorage.io, LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""
Hypothesis strategies for property testing.
"""
from hypothesis.strategies import (
just,
)
def configurations():
"""
Build configuration values for the plugin.
"""
return just({})
......@@ -25,10 +25,24 @@ from testtools import (
)
from testtools.matchers import (
Contains,
AfterPreprocessing,
)
from testtools.twistedsupport import (
succeeded,
)
from hypothesis import (
given,
)
from foolscap.ipb import (
IReferenceable,
IRemotelyCallable,
)
from allmydata.interfaces import (
IFoolscapStoragePlugin,
IAnnounceableStorageServer,
)
from twisted.plugin import (
......@@ -38,6 +52,17 @@ from twisted.plugins.secureaccesstokenauthorizer import (
storage_server,
)
from .strategies import (
configurations,
)
from .matchers import (
Provides,
)
def get_anonymous_storage_server():
return None
class PluginTests(TestCase):
"""
Tests for ``twisted.plugins.secureaccesstokenauthorizer.storage_server``.
......@@ -57,3 +82,45 @@ class PluginTests(TestCase):
``storage_server`` provides ``IFoolscapStoragePlugin``.
"""
verifyObject(IFoolscapStoragePlugin, storage_server)
@given(configurations())
def test_returns_announceable(self, configuration):
"""
``storage_server.get_storage_server`` returns an instance which provides
``IAnnounceableStorageServer``.
"""
storage_server_deferred = storage_server.get_storage_server(
configuration,
get_anonymous_storage_server,
)
self.assertThat(
storage_server_deferred,
succeeded(Provides([IAnnounceableStorageServer])),
)
@given(configurations())
def test_returns_referenceable(self, configuration):
"""
The storage server attached to the result of
``storage_server.get_storage_server`` provides ``IReferenceable`` and
``IRemotelyCallable``.
"""
# XXX It's not clear what the actual Foolscap-imposed requirements on
# this object should be. Maybe the two above-mentioned interfaces are
# important ... or maybe not?
storage_server_deferred = storage_server.get_storage_server(
configuration,
get_anonymous_storage_server,
)
self.assertThat(
storage_server_deferred,
succeeded(
AfterPreprocessing(
lambda ann: ann.storage_server,
Provides([IReferenceable, IRemotelyCallable]),
),
),
)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment