def test_upload_download(self):
     manager = BlobManager('', self.uri, self.secret,
                           self.secret, uuid4().hex)
     fd = BytesIO("save me")
     yield manager._encrypt_and_upload('blob_id', fd)
     blob, size = yield manager._download_and_decrypt('blob_id')
     self.assertEquals(blob.getvalue(), "save me")
예제 #2
0
 def test_upload_then_delete_updates_list(self):
     manager = BlobManager('', self.uri, self.secret, self.secret, 'user')
     yield manager._encrypt_and_upload('blob_id1', BytesIO("1"))
     yield manager._encrypt_and_upload('blob_id2', BytesIO("2"))
     yield manager._delete_from_remote('blob_id1')
     blobs_list = yield manager.remote_list()
     self.assertEquals(set(['blob_id2']), set(blobs_list))
 def test_upload_changes_remote_list(self):
     manager = BlobManager('', self.uri, self.secret,
                           self.secret, uuid4().hex)
     yield manager._encrypt_and_upload('blob_id1', BytesIO("1"))
     yield manager._encrypt_and_upload('blob_id2', BytesIO("2"))
     blobs_list = yield manager.remote_list()
     self.assertEquals(set(['blob_id1', 'blob_id2']), set(blobs_list))
 def test_get_empty_flags(self):
     manager = BlobManager('', self.uri, self.secret,
                           self.secret, uuid4().hex)
     fd = BytesIO("flag me")
     yield manager._encrypt_and_upload('blob_id', fd)
     flags = yield manager.get_flags('blob_id')
     self.assertEquals([], flags)
예제 #5
0
 def test_set_get_flags(self):
     manager = BlobManager('', self.uri, self.secret, self.secret, 'user')
     fd = BytesIO("flag me")
     yield manager._encrypt_and_upload('blob_id', fd)
     yield manager.set_flags('blob_id', [Flags.PROCESSING])
     flags = yield manager.get_flags('blob_id')
     self.assertEquals([Flags.PROCESSING], flags)
예제 #6
0
 def test_flags_ignored_by_listing(self):
     manager = BlobManager('', self.uri, self.secret, self.secret, 'user')
     fd = BytesIO("flag me")
     yield manager._encrypt_and_upload('blob_id', fd)
     yield manager.set_flags('blob_id', [Flags.PROCESSING])
     blobs_list = yield manager.remote_list()
     self.assertEquals(['blob_id'], blobs_list)
예제 #7
0
 def test_upload_deny_duplicates(self):
     manager = BlobManager('', self.uri, self.secret, self.secret, 'user')
     fd = BytesIO("save me")
     yield manager._encrypt_and_upload('blob_id', fd)
     fd = BytesIO("save me")
     with pytest.raises(BlobAlreadyExistsError):
         yield manager._encrypt_and_upload('blob_id', fd)
예제 #8
0
 def test_cant_set_invalid_flags(self):
     manager = BlobManager('', self.uri, self.secret, self.secret, 'user')
     fd = BytesIO("flag me")
     yield manager._encrypt_and_upload('blob_id', fd)
     with pytest.raises(InvalidFlagsError):
         yield manager.set_flags('blob_id', ['invalid'])
     flags = yield manager.get_flags('blob_id')
     self.assertEquals([], flags)
예제 #9
0
 def test_download_from_namespace(self):
     manager = BlobManager('', self.uri, self.secret, self.secret, 'user')
     namespace, blob_id, content = 'incoming', 'blob_id1', 'test'
     yield manager._encrypt_and_upload(blob_id,
                                       BytesIO(content),
                                       namespace=namespace)
     got_blob = yield manager._download_and_decrypt(blob_id, namespace)
     self.assertEquals(content, got_blob[0].getvalue())
예제 #10
0
 def test_list_restricted_by_namespace(self):
     manager = BlobManager('', self.uri, self.secret, self.secret, 'user')
     namespace = 'incoming'
     yield manager._encrypt_and_upload('blob_id1',
                                       BytesIO("1"),
                                       namespace=namespace)
     yield manager._encrypt_and_upload('blob_id2', BytesIO("2"))
     blobs_list = yield manager.remote_list(namespace=namespace)
     self.assertEquals(['blob_id1'], blobs_list)
예제 #11
0
 def test_list_default_doesnt_list_other_namespaces(self):
     manager = BlobManager('', self.uri, self.secret, self.secret, 'user')
     namespace = 'incoming'
     yield manager._encrypt_and_upload('blob_id1',
                                       BytesIO("1"),
                                       namespace=namespace)
     yield manager._encrypt_and_upload('blob_id2', BytesIO("2"))
     blobs_list = yield manager.remote_list()
     self.assertEquals(['blob_id2'], blobs_list)
예제 #12
0
    def test_count(self):
        manager = BlobManager('', self.uri, self.secret, self.secret, 'user')
        deferreds = []
        for i in range(10):
            deferreds.append(manager._encrypt_and_upload(str(i), BytesIO("1")))
        yield defer.gatherResults(deferreds)

        result = yield manager.count()
        self.assertEquals({"count": len(deferreds)}, result)
예제 #13
0
 def test_send_missing(self):
     manager = BlobManager(self.tempdir, self.uri, self.secret, self.secret,
                           'user')
     self.addCleanup(manager.close)
     blob_id = 'local_only_blob_id'
     yield manager.local.put(blob_id, BytesIO("X"), size=1)
     yield manager.send_missing()
     result = yield manager._download_and_decrypt(blob_id)
     self.assertIsNotNone(result)
     self.assertEquals(result[0].getvalue(), "X")
예제 #14
0
 def test_fetch_missing(self):
     manager = BlobManager(self.tempdir, self.uri, self.secret, self.secret,
                           'user')
     self.addCleanup(manager.close)
     blob_id = 'remote_only_blob_id'
     yield manager._encrypt_and_upload(blob_id, BytesIO("X"))
     yield manager.fetch_missing()
     result = yield manager.local.get(blob_id)
     self.assertIsNotNone(result)
     self.assertEquals(result.getvalue(), "X")
 def test_send_missing(self):
     manager = BlobManager(self.tempdir, self.uri, self.secret,
                           self.secret, uuid4().hex)
     self.addCleanup(manager.close)
     blob_id = 'local_only_blob_id'
     yield manager.local.put(blob_id, BytesIO("X"), size=1)
     pending = SyncStatus.PENDING_UPLOAD
     yield manager.local.update_sync_status(blob_id, pending)
     yield manager.send_missing()
     result = yield manager._download_and_decrypt(blob_id)
     self.assertIsNotNone(result)
     self.assertEquals(result[0].getvalue(), "X")
 def test_upstream_from_namespace(self):
     manager = BlobManager(self.tempdir, self.uri, self.secret,
                           self.secret, uuid4().hex,
                           remote_stream=self.stream_uri)
     self.addCleanup(manager.close)
     blob_ids = [uuid4().hex for _ in range(5)]
     for i, blob_id in enumerate(blob_ids):
         yield manager.local.put(blob_id, BytesIO("X" * i), size=i,
                                 namespace='test')
     yield manager._upstream(blob_ids, namespace='test')
     for i, blob_id in enumerate(blob_ids):
         got_blob = yield manager._download_and_decrypt(blob_id,
                                                        namespace='test')
         self.assertEquals(got_blob[0].getvalue(), "X" * i)
예제 #17
0
    def test_decrypt_uploading_encrypted_blob(self):
        @defer.inlineCallbacks
        def _check_result(uri, data, *args, **kwargs):
            decryptor = _crypto.BlobDecryptor(self.doc_info,
                                              data,
                                              armor=False,
                                              secret=self.secret)
            decrypted = yield decryptor.decrypt()
            self.assertEquals(decrypted.getvalue(), 'up and up')
            defer.returnValue(Mock(code=200))

        manager = BlobManager('', '', self.secret, self.secret, 'user')
        fd = BytesIO('up and up')
        manager._client.put = _check_result
        yield manager._encrypt_and_upload(self.doc_info.doc_id, fd)
 def test_get_range(self):
     user_id = uuid4().hex
     manager = BlobManager(self.tempdir, self.uri, self.secret,
                           self.secret, user_id)
     self.addCleanup(manager.close)
     blob_id, content = 'blob_id', '0123456789'
     doc = BlobDoc(BytesIO(content), blob_id)
     yield manager.put(doc, len(content))
     uri = urljoin(self.uri, '%s/%s' % (user_id, blob_id))
     res = yield _get(uri, headers={'Range': 'bytes=10-20'})
     text = yield res.text()
     self.assertTrue(res.headers.hasHeader('content-range'))
     content_range = res.headers.getRawHeaders('content-range').pop()
     self.assertIsNotNone(re.match('^bytes 10-20/[0-9]+$', content_range))
     self.assertEqual(10, len(text))
 def test_refresh_deletions_from_server(self):
     manager = BlobManager(self.tempdir, self.uri, self.secret,
                           self.secret, uuid4().hex)
     self.addCleanup(manager.close)
     blob_id, content = 'delete_me', 'content'
     blob_id2 = 'dont_delete_me'
     doc1 = BlobDoc(BytesIO(content), blob_id)
     doc2 = BlobDoc(BytesIO(content), blob_id2)
     yield manager.put(doc1, len(content))
     yield manager.put(doc2, len(content))
     yield manager._delete_from_remote(blob_id)  # remote only deletion
     self.assertTrue((yield manager.local.exists(blob_id)))
     yield manager.sync()
     self.assertFalse((yield manager.local.exists(blob_id)))
     self.assertTrue((yield manager.local.exists(blob_id2)))
    def test_sync_fetch_missing_retry(self):
        manager = BlobManager(self.tempdir, self.uri, self.secret,
                              self.secret, uuid4().hex)
        self.addCleanup(manager.close)
        blob_id = 'remote_only_blob_id'
        yield manager._encrypt_and_upload(blob_id, BytesIO("X"))
        yield manager.refresh_sync_status_from_server()
        yield self.port.stopListening()

        d = manager.fetch_missing()
        yield sleep(0.1)
        self.port = reactor.listenTCP(
            self.host.port, self.site, interface='127.0.0.1')
        yield d
        result = yield manager.local.get(blob_id)
        self.assertIsNotNone(result)
        self.assertEquals(result.getvalue(), "X")
 def test_downstream_from_namespace(self):
     manager = BlobManager(self.tempdir, self.uri, self.secret,
                           self.secret, uuid4().hex,
                           remote_stream=self.stream_uri)
     self.addCleanup(manager.close)
     namespace, blob_id, content = 'incoming', 'blob_id1', 'test'
     yield manager._encrypt_and_upload(blob_id, BytesIO(content),
                                       namespace=namespace)
     blob_id2, content2 = 'blob_id2', 'second test'
     yield manager._encrypt_and_upload(blob_id2, BytesIO(content2),
                                       namespace=namespace)
     blobs_list = [blob_id, blob_id2]
     yield manager._downstream(blobs_list, namespace)
     result = yield manager.local.get(blob_id, namespace)
     self.assertEquals(content, result.getvalue())
     result = yield manager.local.get(blob_id2, namespace)
     self.assertEquals(content2, result.getvalue())
class IncomingFlowIntegrationTestCase(unittest.TestCase):

    def setUp(self):
        root = Resource()
        state = BlobsServerState('filesystem', blobs_path=self.tempdir)
        incoming_resource = IncomingResource(state)
        blobs_resource = server_blobs.BlobsResource("filesystem", self.tempdir)
        root.putChild('blobs', blobs_resource)
        root.putChild('incoming', incoming_resource)
        site = Site(root)
        self.port = reactor.listenTCP(0, site, interface='127.0.0.1')
        self.host = self.port.getHost()
        self.uri = 'http://%s:%s/' % (self.host.host, self.host.port)
        self.blobs_uri = self.uri + 'blobs/'
        self.incoming_uri = self.uri + 'incoming'
        self.user_id = 'user-' + uuid4().hex
        self.secret = 'A' * 96
        self.blob_manager = BlobManager(self.tempdir, self.blobs_uri,
                                        self.secret, self.secret,
                                        self.user_id)
        self.box = IncomingBox(self.blob_manager, 'MX')
        self.loop = IncomingBoxProcessingLoop(self.box)
        # FIXME: We use blob_manager client only to avoid DelayedCalls
        # Somehow treq being used here keeps a connection pool open
        self.client = self.blob_manager._client

    def fill(self, messages):
        deferreds = []
        for message_id, message in messages:
            uri = '%s/%s/%s' % (self.incoming_uri, self.user_id, message_id)
            deferreds.append(self.blob_manager._client.put(uri, data=message))
        return defer.gatherResults(deferreds)

    def tearDown(self):
        self.port.stopListening()
        self.blob_manager.close()

    @defer.inlineCallbacks
    @pytest.mark.usefixtures("method_tmpdir")
    def test_consume_a_incoming_message(self):
        yield self.fill([('msg1', 'blob')])
        consumer = GoodConsumer()
        self.loop.add_consumer(consumer)
        yield self.loop()
        self.assertIn('msg1', consumer.processed)
    def test_send_missing_retry(self):
        manager = BlobManager(self.tempdir, self.uri, self.secret,
                              self.secret, uuid4().hex)
        self.addCleanup(manager.close)
        blob_id = 'remote_only_blob_id'
        yield manager.local.put(blob_id, BytesIO("X"), size=1)
        pending = SyncStatus.PENDING_UPLOAD
        yield manager.local.update_sync_status(blob_id, pending)
        yield self.port.stopListening()

        d = manager.send_missing()
        yield sleep(0.1)
        self.port = reactor.listenTCP(
            self.host.port, self.site, interface='127.0.0.1')
        yield d
        result = yield manager._download_and_decrypt(blob_id)
        self.assertIsNotNone(result)
        self.assertEquals(result[0].getvalue(), "X")
 def test_download_corrupted_tag_marks_blob_as_failed(self):
     user_id = uuid4().hex
     manager = BlobManager(self.tempdir, self.uri, self.secret,
                           self.secret, user_id)
     self.addCleanup(manager.close)
     blob_id = 'corrupted'
     yield manager._encrypt_and_upload(blob_id, BytesIO("corrupted"))
     parts = ['default'] + [blob_id[0], blob_id[0:3], blob_id[0:6]]
     parts += [blob_id]
     corrupted_blob_path = os.path.join(self.tempdir, user_id, *parts)
     with open(corrupted_blob_path, 'r+b') as corrupted_blob:
         # Corrupt the tag (last 16 bytes)
         corrupted_blob.seek(-16, 2)
         corrupted_blob.write('x' * 16)
     with pytest.raises(MaximumRetriesError):
         yield manager.sync()
     status, retries = yield manager.local.get_sync_status(blob_id)
     self.assertEquals(status, SyncStatus.FAILED_DOWNLOAD)
     self.assertEquals(retries, 3)
예제 #25
0
 def test_list_filter_flag_order_by_date(self):
     manager = BlobManager('', self.uri, self.secret, self.secret, 'user')
     yield manager._encrypt_and_upload('blob_id1', BytesIO("x"))
     yield manager._encrypt_and_upload('blob_id2', BytesIO("x"))
     yield manager._encrypt_and_upload('blob_id3', BytesIO("x"))
     yield manager.set_flags('blob_id1', [Flags.PROCESSING])
     yield manager.set_flags('blob_id2', [Flags.PROCESSING])
     yield manager.set_flags('blob_id3', [Flags.PROCESSING])
     blobs_list = yield manager.remote_list(filter_flag=Flags.PROCESSING,
                                            order_by='+date')
     expected_list = ['blob_id1', 'blob_id2', 'blob_id3']
     self.assertEquals(expected_list, blobs_list)
     blobs_list = yield manager.remote_list(filter_flag=Flags.PROCESSING,
                                            order_by='-date')
     self.assertEquals(list(reversed(expected_list)), blobs_list)
 def setUp(self):
     root = Resource()
     state = BlobsServerState('filesystem', blobs_path=self.tempdir)
     incoming_resource = IncomingResource(state)
     blobs_resource = server_blobs.BlobsResource("filesystem", self.tempdir)
     root.putChild('blobs', blobs_resource)
     root.putChild('incoming', incoming_resource)
     site = Site(root)
     self.port = reactor.listenTCP(0, site, interface='127.0.0.1')
     self.host = self.port.getHost()
     self.uri = 'http://%s:%s/' % (self.host.host, self.host.port)
     self.blobs_uri = self.uri + 'blobs/'
     self.incoming_uri = self.uri + 'incoming'
     self.user_id = 'user-' + uuid4().hex
     self.secret = 'A' * 96
     self.blob_manager = BlobManager(self.tempdir, self.blobs_uri,
                                     self.secret, self.secret,
                                     self.user_id)
     self.box = IncomingBox(self.blob_manager, 'MX')
     self.loop = IncomingBoxProcessingLoop(self.box)
     # FIXME: We use blob_manager client only to avoid DelayedCalls
     # Somehow treq being used here keeps a connection pool open
     self.client = self.blob_manager._client
 def test_upload_then_delete_updates_list_using_namespace(self):
     manager = BlobManager('', self.uri, self.secret,
                           self.secret, uuid4().hex)
     namespace = 'special_archives'
     yield manager._encrypt_and_upload('blob_id1', BytesIO("1"),
                                       namespace=namespace)
     yield manager._encrypt_and_upload('blob_id2', BytesIO("2"),
                                       namespace=namespace)
     yield manager._delete_from_remote('blob_id1', namespace=namespace)
     blobs_list = yield manager.remote_list(namespace=namespace)
     deleted_blobs_list = yield manager.remote_list(namespace, deleted=True)
     self.assertEquals(set(['blob_id2']), set(blobs_list))
     self.assertEquals(set(['blob_id1']), set(deleted_blobs_list))
 def test_get_range_not_satisfiable(self):
     # put a blob in place
     user_id = uuid4().hex
     manager = BlobManager(self.tempdir, self.uri, self.secret,
                           self.secret, user_id)
     self.addCleanup(manager.close)
     blob_id, content = uuid4().hex, 'content'
     doc = BlobDoc(BytesIO(content), blob_id)
     yield manager.put(doc, len(content))
     # and check possible parsing errors
     uri = urljoin(self.uri, '%s/%s' % (user_id, blob_id))
     ranges = [
         'bytes',
         'bytes=',
         'bytes=1',
         'bytes=blah-100',
         'potatoes=10-100'
         'blah'
     ]
     for range in ranges:
         res = yield _get(uri, headers={'Range': range})
         self.assertEqual(416, res.code)
         content_range = res.headers.getRawHeaders('content-range').pop()
         self.assertIsNotNone(re.match('^bytes \*/[0-9]+$', content_range))
 def test_list_filter_flag(self):
     manager = BlobManager('', self.uri, self.secret,
                           self.secret, uuid4().hex)
     fd = BytesIO("flag me")
     yield manager._encrypt_and_upload('blob_id', fd)
     yield manager.set_flags('blob_id', [Flags.PROCESSING])
     blobs_list = yield manager.remote_list(filter_flag=Flags.PENDING)
     self.assertEquals([], blobs_list)
     blobs_list = yield manager.remote_list(filter_flag=Flags.PROCESSING)
     self.assertEquals(['blob_id'], blobs_list)
예제 #30
0
 def test_list_orders_by_date(self):
     manager = BlobManager('', self.uri, self.secret, self.secret, 'user')
     yield manager._encrypt_and_upload('blob_id1', BytesIO("1"))
     yield manager._encrypt_and_upload('blob_id2', BytesIO("2"))
     blobs_list = yield manager.remote_list(order_by='date')
     self.assertEquals(['blob_id1', 'blob_id2'], blobs_list)
     parts = ['user', 'default', 'b', 'blo', 'blob_i', 'blob_id1']
     self.__touch(self.tempdir, *parts)
     blobs_list = yield manager.remote_list(order_by='+date')
     self.assertEquals(['blob_id2', 'blob_id1'], blobs_list)
     blobs_list = yield manager.remote_list(order_by='-date')
     self.assertEquals(['blob_id1', 'blob_id2'], blobs_list)