2016-05-03 21:49:31 +00:00
|
|
|
from mock import Mock, patch
|
2016-04-25 23:39:33 +00:00
|
|
|
from allmydata.util import base32
|
2014-11-23 05:46:33 +00:00
|
|
|
|
|
|
|
from twisted.trial import unittest
|
2016-04-26 17:44:58 +00:00
|
|
|
from twisted.internet.defer import succeed, inlineCallbacks
|
2016-04-25 23:39:33 +00:00
|
|
|
|
2014-11-23 05:46:33 +00:00
|
|
|
from allmydata.storage_client import NativeStorageServer
|
2016-04-26 17:44:58 +00:00
|
|
|
from allmydata.storage_client import StorageFarmBroker, ConnectedEnough
|
2014-11-23 05:46:33 +00:00
|
|
|
|
|
|
|
|
|
|
|
class NativeStorageServerWithVersion(NativeStorageServer):
|
2016-05-03 22:09:13 +00:00
|
|
|
def __init__(self, version):
|
|
|
|
# note: these instances won't work for anything other than
|
|
|
|
# get_available_space() because we don't upcall
|
|
|
|
self.version = version
|
2014-11-23 05:46:33 +00:00
|
|
|
def get_version(self):
|
|
|
|
return self.version
|
|
|
|
|
|
|
|
|
|
|
|
class TestNativeStorageServer(unittest.TestCase):
|
|
|
|
def test_get_available_space_new(self):
|
|
|
|
nss = NativeStorageServerWithVersion(
|
|
|
|
{ "http://allmydata.org/tahoe/protocols/storage/v1":
|
|
|
|
{ "maximum-immutable-share-size": 111,
|
|
|
|
"available-space": 222,
|
|
|
|
}
|
|
|
|
})
|
|
|
|
self.failUnlessEqual(nss.get_available_space(), 222)
|
|
|
|
|
|
|
|
def test_get_available_space_old(self):
|
|
|
|
nss = NativeStorageServerWithVersion(
|
|
|
|
{ "http://allmydata.org/tahoe/protocols/storage/v1":
|
|
|
|
{ "maximum-immutable-share-size": 111,
|
|
|
|
}
|
|
|
|
})
|
|
|
|
self.failUnlessEqual(nss.get_available_space(), 111)
|
|
|
|
|
2016-04-25 23:39:33 +00:00
|
|
|
|
|
|
|
class TestStorageFarmBroker(unittest.TestCase):
|
|
|
|
|
2016-04-26 06:32:21 +00:00
|
|
|
@inlineCallbacks
|
2016-04-25 23:39:33 +00:00
|
|
|
def test_threshold_reached(self):
|
|
|
|
introducer = Mock()
|
2016-05-02 15:23:07 +00:00
|
|
|
broker = StorageFarmBroker(True)
|
2016-04-26 17:44:58 +00:00
|
|
|
done = ConnectedEnough(broker, 5).when_connected_enough()
|
2016-04-25 23:39:33 +00:00
|
|
|
broker.use_introducer(introducer)
|
|
|
|
# subscribes to "storage" to learn of new storage nodes
|
|
|
|
subscribe = introducer.mock_calls[0]
|
|
|
|
self.assertEqual(subscribe[0], 'subscribe_to')
|
2016-05-03 21:03:17 +00:00
|
|
|
self.assertEqual(subscribe[1][0], 'storage')
|
|
|
|
got_announcement = subscribe[1][1]
|
2016-04-25 23:39:33 +00:00
|
|
|
|
|
|
|
data = {
|
|
|
|
"service-name": "storage",
|
|
|
|
"anonymous-storage-FURL": None,
|
|
|
|
"permutation-seed-base32": "aaaaaaaaaaaaaaaaaaaaaaaa",
|
|
|
|
}
|
|
|
|
|
|
|
|
def add_one_server(x):
|
|
|
|
data["anonymous-storage-FURL"] = "pb://{}@nowhere/fake".format(base32.b2a(str(x)))
|
2016-05-03 21:49:31 +00:00
|
|
|
tub = Mock()
|
|
|
|
with patch("allmydata.storage_client.Tub", side_effect=[tub]):
|
|
|
|
got_announcement('v0-1234-{}'.format(x), data)
|
|
|
|
self.assertEqual(tub.mock_calls[-1][0], 'connectTo')
|
|
|
|
got_connection = tub.mock_calls[-1][1][1]
|
2016-04-25 23:39:33 +00:00
|
|
|
rref = Mock()
|
|
|
|
rref.callRemote = Mock(return_value=succeed(1234))
|
|
|
|
got_connection(rref)
|
|
|
|
|
|
|
|
# first 4 shouldn't trigger connected_threashold
|
|
|
|
for x in range(4):
|
|
|
|
add_one_server(x)
|
|
|
|
self.assertFalse(done.called)
|
|
|
|
|
|
|
|
# ...but the 5th *should* trigger the threshold
|
|
|
|
add_one_server(42)
|
2016-04-26 06:32:21 +00:00
|
|
|
|
|
|
|
# so: the OneShotObserverList only notifies via
|
|
|
|
# foolscap.eventually() -- which forces the Deferred call
|
|
|
|
# through the reactor -- so it's no longer synchronous,
|
|
|
|
# meaning that we have to do "real reactor stuff" for the
|
|
|
|
# Deferred from when_connected_enough() to actually fire. (or
|
|
|
|
# @patch() out the reactor in foolscap.eventually to be a
|
|
|
|
# Clock() so we can advance time ourselves, but ... luckily
|
|
|
|
# eventually() uses 0 as the timeout currently)
|
|
|
|
|
|
|
|
yield done
|
2016-04-25 23:39:33 +00:00
|
|
|
self.assertTrue(done.called)
|