async def test_write_blob_data(db, guillotina_main): db = await get_database("db") login() async with transaction(db=db): container = await db.async_get("container") if container is None: container = await create_content_in_container(db, "Container", "container", title="Container") blob = Blob(container) container.blob = blob blobfi = blob.open("w") await blobfi.async_write(b"foobar") async with transaction(db=db): container = await db.async_get("container") assert await container.blob.open().async_read() == b"foobar" assert container.blob.size == 6 assert container.blob.chunks == 1 await db.async_del("container")
async def test_bucket_dict_value(db, guillotina_main): db = await get_database("db") login() bucket = BucketDictValue(bucket_len=10) async with transaction(db=db): container = await create_content_in_container(db, "Container", "container", title="Container") ob = await create_content_in_container(container, "Item", "foobar") for index in range(50): await bucket.assign(ob, str(index), index) assert len(bucket) == 50 assert await bucket.get(ob, "1") == 1 async with transaction(db=db): container = await db.async_get("container") ob = await container.async_get("foobar") await bucket.clear(ob) assert len(bucket) == 0 assert await bucket.get(ob, "1") is None async with transaction(db=db): container = await db.async_get("container") ob = await container.async_get("foobar") for index in range(50, 100): await bucket.assign(ob, str(index), index) assert len(bucket) == 50 assert await bucket.get(ob, "50") == 50
async def test_create_annotation(db, guillotina_main): db = await get_database("db") login() async with transaction(db=db): container = await create_content_in_container(db, "Container", "container", title="Container") ob = await create_content_in_container(container, "Item", "foobar") annotations = IAnnotations(ob) data = AnnotationData() data["foo"] = "bar" await annotations.async_set("foobar", data) async with transaction(db=db): container = await db.async_get("container") ob = await container.async_get("foobar") annotations = IAnnotations(ob) assert "foobar" in (await annotations.async_keys()) await annotations.async_del("foobar") async with transaction(db=db): container = await db.async_get("container") ob = await container.async_get("foobar") annotations = IAnnotations(ob) assert "foobar" not in (await annotations.async_keys()) await container.async_del("foobar") await db.async_del("container")
async def test_bucket_dict_value(db, guillotina_main): db = await get_database("db") login() bucket = BucketDictValue(bucket_len=10) async with transaction(db=db): container = await create_content_in_container(db, "Container", "container", title="Container") ob = await create_content_in_container(container, "Item", "foobar") for index in range(50): await bucket.assign(ob, str(index), index) assert len(bucket) == 50 assert await bucket.get(ob, "1") == 1 async with transaction(db=db): container = await db.async_get("container") ob = await container.async_get("foobar") await bucket.clear(ob) assert len(bucket) == 0 assert await bucket.get(ob, "1") is None async with transaction(db=db): container = await db.async_get("container") ob = await container.async_get("foobar") for index in range(50, 100): await bucket.assign(ob, str(index), index) assert len(bucket) == 50 assert await bucket.get(ob, "50") == 50 # Test iter keys, values and items async with transaction(db=db): # Test iterating on a None object assert [k async for k in bucket.iter_keys(None)] == [] assert [v async for v in bucket.iter_values(None)] == [] assert [(k, v) async for k, v in bucket.iter_items(None)] == [] # Test iterate on empty values container = await db.async_get("container") ob = await create_content_in_container(container, "Item", "foobar2") assert [k async for k in bucket.iter_keys(ob)] == [] assert [v async for v in bucket.iter_values(ob)] == [] assert [(k, v) async for k, v in bucket.iter_items(ob)] == [] # Add some data now _range = range(50, 100) for index in range(50, 100): await bucket.assign(ob, str(index), index) assert [k async for k in bucket.iter_keys(ob) ] == [str(i) for i in _range] assert [v async for v in bucket.iter_values(ob)] == [i for i in _range] assert [(k, v) async for k, v in bucket.iter_items(ob) ] == [(str(i), i) for i in _range]
async def create(self, arguments, db): if arguments.force: async with transaction(db=db) as txn: tm = task_vars.tm.get() root = await tm.get_root(txn=txn) if await root.async_contains(arguments.name): context = await root.async_get(arguments.name) content_id = context.id parent = context.__parent__ await notify( BeforeObjectRemovedEvent(context, parent, content_id)) txn.delete(context) await notify( ObjectRemovedEvent(context, parent, content_id)) site = None async with transaction(db=db) as txn: tm = task_vars.tm.get() root = await tm.get_root(txn=txn) try: site = await create_content_in_container(root, "Site", arguments.name, check_security=False) await addons.install(site, "cms") await addons.install(site, "dbusers") workflow = IWorkflow(site) await workflow.do_action("publish", "Initial setup") except ConflictIdOnContainer: pass if site is None: return async with transaction(db=db) as txn: await txn.refresh(site) groups = await site.async_get("groups") obj = await create_content_in_container(groups, "Group", "Managers", check_security=False) obj.user_roles = [ "guillotina.Manager", "guillotina.ContainerAdmin", "guillotina.Owner", ] obj.register() async with transaction(db=db) as txn: await txn.refresh(site) users = await site.async_get("users") obj: IUser = await create_content_in_container( users, "User", "admin", check_security=False) await obj.set_password("admin") obj.groups = ["Managers"]
async def test_read_data_ranges(db, guillotina_main, dummy_request): db = await get_database("db") login() async with transaction(db=db): container = await db.async_get("container") if container is None: container = await create_content_in_container(db, "Container", "container", title="Container") container.add_behavior(IAttachment) beh = await get_behavior(container, IAttachment, create=True) fm = get_multi_adapter( (container, dummy_request, IAttachment["file"].bind(beh)), IFileManager) async def file_generator(): yield (b"X" * (1024 * 1024 * 1)) + (b"Y" * 512) yield b"Z" * (1024 * 1024 * 10) await fm.save_file(file_generator) async with transaction(db=db): container = await db.async_get("container") container.add_behavior(IAttachment) beh = await get_behavior(container, IAttachment) fm = get_multi_adapter( (container, dummy_request, IAttachment["file"].bind(beh)), IFileManager) data = b"" async for chunk in fm.iter_data(): data += chunk assert len(data) == ((1024 * 1024 * 11) + 512) assert await fm.file_storage_manager.range_supported() assert await _gather_all( fm.file_storage_manager.read_range(0, 1024 * 1024) ) == b"X" * 1024 * 1024 assert (await _gather_all( fm.file_storage_manager.read_range(1024 * 1024, (1024 * 1024) + 512) ) == b"Y" * 512) assert await _gather_all( fm.file_storage_manager.read_range(1024 * 1023, (1024 * 1024) + 1024) ) == (b"X" * 1024) + (b"Y" * 512) + (b"Z" * 512) assert await _gather_all( fm.file_storage_manager.read_range(0, (1024 * 1024 * 11) + 512) ) == (b"X" * (1024 * 1024 * 1)) + (b"Y" * 512) + (b"Z" * (1024 * 1024 * 10))
async def test_registry(my_requester): async with ctx(my_requester): utility = get_utility(IEvolutionUtility) async with transaction(): assert await utility._get_curr_gen() == 0 async with transaction(): await utility._update_curr_gen(5) registry = await get_registry() assert registry[GENERATION_KEY] == 5
async def test_managed_transaction_aborted_on_exception(container_requester): async with container_requester as requester: with pytest.raises(Exception): async with transaction(db=requester.db) as txn: root = await txn.get(ROOT_ID) container = await root.async_get("guillotina") container.title = "changed title" container.register() raise Exception() async with transaction(db=requester.db) as txn: root = await txn.get(ROOT_ID) container = await root.async_get("guillotina") assert container.title == "Guillotina Container"
async def test_large_upload_chunks(manager_type, redis_container, container_requester): async with container_requester as requester: response, status = await requester( "POST", "/db/guillotina/", data=json.dumps({ "@type": "Item", "@behaviors": [IAttachment.__identifier__], "id": "foobar" }), ) assert status == 201 response, status = await requester( "PATCH", "/db/guillotina/foobar/@upload/file", data=b"X" * 1024 * 1024 * 10, headers={"x-upload-size": str(1024 * 1024 * 10)}, ) assert status == 200 response, status = await requester( "GET", "/db/guillotina/foobar/@download/file") assert status == 200 assert len(response) == (1024 * 1024 * 10) root = await utils.get_root(db=requester.db) async with transaction(db=requester.db, abort_when_done=True): container = await root.async_get("guillotina") obj = await container.async_get("foobar") behavior = IAttachment(obj) await behavior.load() assert behavior.file.chunks == 2
async def run(self): if self._request is not None: async with transaction(abort_when_done=False), self._request: await self._func(*self._args or [], **self._kwargs or {}) else: # if no request, we do it without transaction await self._func(*self._args or [], **self._kwargs or {})
async def test_creator_used_from_content_creation(dummy_guillotina): utils.login() async with transaction(db=await get_database("db")): container = await create_content("Container", id="guillotina", title="Guillotina") container.__name__ = "guillotina" utils.register(container) import guillotina.tests configure.register_configuration( Folder, dict( type_name="TestType2", behaviors=[], module=guillotina.tests ), # for registration initialization "contenttype", ) root = get_utility(IApplication, name="root") configure.load_configuration(root.app.config, "guillotina.tests", "contenttype") root.app.config.execute_actions() load_cached_schema() obj = await create_content_in_container( container, "TestType2", "foobar", creators=("root",), contributors=("root",) ) assert obj.creators == ("root",) assert obj.contributors == ("root",) behavior = IDublinCore(obj) assert behavior.creators == ("root",) assert behavior.contributors == ("root",)
async def test_large_upload_chunks(manager_type, redis_container, container_requester): async with container_requester as requester: response, status = await requester('POST', '/db/guillotina/', data=json.dumps({ '@type': 'Item', '@behaviors': [IAttachment.__identifier__], 'id': 'foobar' })) assert status == 201 response, status = await requester( 'PATCH', '/db/guillotina/foobar/@upload/file', data=b'X' * 1024 * 1024 * 10, headers={'x-upload-size': str(1024 * 1024 * 10)}) assert status == 200 response, status = await requester( 'GET', '/db/guillotina/foobar/@download/file') assert status == 200 assert len(response) == (1024 * 1024 * 10) request = utils.get_mocked_request(db=requester.db) root = await utils.get_root(request) async with transaction(db=requester.db, abort_when_done=True): container = await root.async_get('guillotina') obj = await container.async_get('foobar') behavior = IAttachment(obj) await behavior.load() assert behavior.file.chunks == 2
async def test_create_contenttype_with_date(container_requester): async with container_requester as requester: _, status = await requester( 'POST', '/db/guillotina/', data=json.dumps({ "@type": "Item", "title": "Item1", "id": "item1", }) ) assert status == 201 date_to_test = "2016-11-30T14:39:07.394273+01:00" _, status = await requester( 'PATCH', '/db/guillotina/item1', data=json.dumps({ "guillotina.behaviors.dublincore.IDublinCore": { "creation_date": date_to_test, "expiration_date": date_to_test } }) ) request = utils.get_mocked_request(db=requester.db) root = await utils.get_root(request) async with transaction(db=requester.db, abort_when_done=True): container = await root.async_get('guillotina') obj = await container.async_get('item1') from guillotina.behaviors.dublincore import IDublinCore behavior = IDublinCore(obj) await behavior.load() assert behavior.creation_date.isoformat() == date_to_test # pylint: disable=E1101 assert behavior.expiration_date.isoformat() == date_to_test # pylint: disable=E1101
async def test_add_behavior(dummy_guillotina): utils.login() async with transaction(db=await get_database("db")): container = await create_content("Container", id="guillotina", title="Guillotina") container.__name__ = "guillotina" utils.register(container) item = await create_content_in_container(container, "Item", id_="foobar") with pytest.raises(AttributeError): item.add_behavior(123) with pytest.raises(ComponentLookupError): item.add_behavior("foo") all_behaviors = await get_all_behaviors(item) assert len(all_behaviors) == 1 assert all_behaviors[0][0] == IDublinCore # IDublinCore already exists and check it is not added item.add_behavior(IDublinCore.__identifier__) assert len(item.__behaviors__) == 0 assert len(await get_all_behaviors(item)) == 1 # Manually add IDublinCore and check it is not returned twice item.__behaviors__ |= {IDublinCore.__identifier__} assert len(await get_all_behaviors(item)) == 1 item.add_behavior(IAttachment) assert len(await get_all_behaviors(item)) == 2
async def test_tus_multi(manager_type, redis_container, container_requester): async with container_requester as requester: response, status = await requester( 'POST', '/db/guillotina/', data=json.dumps({ '@type': 'Item', '@behaviors': [IMultiAttachment.__identifier__], 'id': 'foobar' })) assert status == 201 response, status = await requester( 'OPTIONS', '/db/guillotina/foobar/@tusupload/files/file', headers={ 'Origin': 'http://foobar.com', 'Access-Control-Request-Method': 'POST' }) assert status == 200 response, status = await requester( 'POST', '/db/guillotina/foobar/@tusupload/files/file', headers={ 'UPLOAD-LENGTH': str(1024 * 1024 * 10), 'TUS-RESUMABLE': '1.0.0' }) assert status == 201 response, status = await requester( 'HEAD', '/db/guillotina/foobar/@tusupload/files/file') assert status == 200 for idx in range(10): # 10, 1mb chunks response, status = await requester( 'PATCH', '/db/guillotina/foobar/@tusupload/files/file', headers={ 'CONTENT-LENGTH': str(1024 * 1024 * 1), 'TUS-RESUMABLE': '1.0.0', 'upload-offset': str(1024 * 1024 * idx) }, data=b'X' * 1024 * 1024 * 1) assert status == 200 response, status = await requester( 'GET', '/db/guillotina/foobar/@download/files/file') assert status == 200 assert len(response) == (1024 * 1024 * 10) request = utils.get_mocked_request(db=requester.db) root = await utils.get_root(request) async with transaction(db=requester.db, abort_when_done=True): container = await root.async_get('guillotina') obj = await container.async_get('foobar') behavior = IMultiAttachment(obj) await behavior.load() assert behavior.files['file'].chunks == 10
async def test_allowed_types(dummy_guillotina): utils.login() async with transaction(db=await get_database("db")): container = await create_content("Container", id="guillotina", title="Guillotina") container.__name__ = "guillotina" utils.register(container) import guillotina.tests configure.register_configuration( Folder, dict( type_name="TestType", allowed_types=["Item"], module=guillotina.tests, # for registration initialization ), "contenttype", ) root = get_utility(IApplication, name="root") configure.load_configuration(root.app.config, "guillotina.tests", "contenttype") root.app.config.execute_actions() load_cached_schema() obj = await create_content_in_container(container, "TestType", "foobar") constrains = IConstrainTypes(obj, None) assert constrains.get_allowed_types() == ["Item"] assert constrains.is_type_allowed("Item") with pytest.raises(NotAllowedContentType): await create_content_in_container(obj, "TestType", "foobar") await create_content_in_container(obj, "Item", "foobar")
async def test_create_blob(db, guillotina_main): root = get_utility(IApplication, name='root') db = root['db'] login() async with transaction(db=db): container = await create_content_in_container( db, 'Container', 'container', title='Container') blob = Blob(container) container.blob = blob async with transaction(db=db): container = await db.async_get('container') assert blob.bid == container.blob.bid assert blob.resource_uid == container.__uuid__ await db.async_del('container')
async def test_allowed_to_create_content(dummy_guillotina): utils.login() async with transaction(db=await get_database("db")): container = await create_content("Container", id="guillotina", title="Guillotina") container.__name__ = "guillotina" utils.register(container) await create_content_in_container(container, "Item", id_="foobar")
async def test_txn_reuse_delete(container_requester): async with container_requester as requester: async with transaction(db=requester.db) as txn: root = await txn.get(ROOT_ID) container1 = await root.async_get("guillotina") assert container1 is not None await root.async_del("guillotina") container2 = await root.async_get("guillotina") assert container2 is None
async def get_container(*, requester=None, tm=None, container_id='guillotina'): kw = {'tm': tm} if requester is not None: kw['db'] = requester.db root = await get_root(**kw) async with transaction(**kw): container = await root.async_get(container_id) task_vars.container.set(container) return container
async def test_create_blob(db, guillotina_main): db = await get_database('db') login() async with transaction(db=db): container = await create_content_in_container(db, 'Container', 'container', title='Container') blob = Blob(container) container.blob = blob async with transaction(db=db): container = await db.async_get('container') assert blob.bid == container.blob.bid assert blob.resource_uid == container.__uuid__ await db.async_del('container')
async def run(self): if self._task_vars is not None: load_task_vars(self._task_vars) tm = task_vars.tm.get() if tm is not None: async with transaction(tm=tm): await self._func(*self._args or [], **self._kwargs or {}) else: # if no request, we do it without transaction await self._func(*self._args or [], **self._kwargs or {})
async def test_txn_reuse(container_requester): async with container_requester as requester: async with transaction(db=requester.db) as txn: root = await txn.get(ROOT_ID) container1 = await root.async_get("guillotina") container1.title = "My new title" container1.register() container2 = await root.async_get("guillotina") assert container1 == container2 assert container2.title == "My new title"
async def test_multiple_evolutions_at_once(loop, my_requester): async with ctx(my_requester) as container: # Create content in the container async with transaction(): await create_content_in_container(container, "Item", id_="foobar") ob = await container.async_get("foobar") assert hasattr(ob, "title") is False # Register a new evolution async def ensure_all_items_have_attribute_title(container): async for item in container.async_values(): item.title = "" item.register() async def ensure_all_items_have_attribute_description(container): async for item in container.async_values(): item.description = "patata" item.register() utility = get_utility(IEvolutionUtility) async with transaction(): await utility._update_curr_gen(0) utility.register(1, ensure_all_items_have_attribute_title) utility.register(2, ensure_all_items_have_attribute_description) # Evolve await utility.evolve(container) # Assert generation was updated on container registry async with transaction(): registry = await get_registry() assert registry[GENERATION_KEY] == 2 # Check objects after evolution async with transaction(): ob = await container.async_get("foobar") assert ob is not None assert hasattr(ob, "title") is True assert hasattr(ob, "description") is True assert ob.title == "" assert ob.description == "patata"
async def test_txn_refresh(container_requester): async with container_requester as requester: async with transaction(db=requester.db) as txn: root = await txn.get(ROOT_ID) container1 = await root.async_get("guillotina") container1.title = "changed title" container1.register() async with transaction(db=requester.db) as txn: container2 = await root.async_get("guillotina") container2.title = "changed title2" container2.register() async with transaction(db=requester.db) as txn: assert container1.__serial__ != container2.__serial__ assert container1.title != container2.title await txn.refresh(container1) assert container1.__serial__ == container2.__serial__ assert container1.title == container2.title
async def create(self, arguments, db): async with transaction(db=db) as txn: tm = task_vars.tm.get() root = await tm.get_root(txn=txn) obj = await create_content_in_container(root, arguments.type, arguments.name, check_security=False) await addons.install(obj, "cms") await addons.install(obj, "dbusers")
async def create_next_index(self): async with transaction(adopt_parent_txn=True) as txn: await txn.refresh(await self.index_manager.get_registry()) next_index_name = await self.index_manager.start_migration() if await self.conn.indices.exists(next_index_name): if self.force: # delete and recreate self.response.write("Clearing index") resp = await self.conn.indices.delete(next_index_name) assert resp["acknowledged"] await self.utility.create_index(next_index_name, self.index_manager) return next_index_name
async def test_txn_reuse_add(container_requester): async with container_requester as requester: async with transaction(db=requester.db) as txn: root = await txn.get(ROOT_ID) container1 = await root.async_get("guillotina") obj = await create_content_in_container(container1, "Folder", "myobj", check_security=False) obj2 = await container1.async_get("myobj") assert obj2 is not None assert obj == obj2
async def test_read_data_range_errors(db, guillotina_main, dummy_request): db = await get_database("db") login() async with transaction(db=db): container = await db.async_get("container") if container is None: container = await create_content_in_container(db, "Container", "container", title="Container") container.add_behavior(IAttachment) beh = await get_behavior(container, IAttachment, create=True) fm = get_multi_adapter( (container, dummy_request, IAttachment["file"].bind(beh)), IFileManager) with pytest.raises(RangeNotSupported): # raise before we've added anything async for c in fm.file_storage_manager.read_range(1, 2): ... # pragma: no cover async def file_generator(): yield (b"X" * (1024 * 1024 * 1)) await fm.save_file(file_generator) async with transaction(db=db): container = await db.async_get("container") container.add_behavior(IAttachment) beh = await get_behavior(container, IAttachment) fm = get_multi_adapter( (container, dummy_request, IAttachment["file"].bind(beh)), IFileManager) with pytest.raises(RangeNotFound): assert await _gather_all( fm.file_storage_manager.read_range(0, 1024 * 1024 * 3))
async def test_managed_transaction_with_adoption(container_requester): async with container_requester as requester: async with transaction(db=requester.db, abort_when_done=True) as txn: root = await txn.get(ROOT_ID) container = await root.async_get('guillotina') container.title = 'changed title' container.register() assert container.__uuid__ in container.__txn__.modified # nest it with adoption async with transaction(adopt_parent_txn=True): # this should commit, take on parent txn for container pass # no longer modified, adopted in previous txn assert container.__uuid__ not in container.__txn__.modified # finally, retrieve it again and make sure it's updated async with transaction(abort_when_done=True): container = await root.async_get('guillotina') assert container.title == 'changed title'