Пример #1
0
async def test_add_sync_utility(guillotina, loop):
    requester = await guillotina

    app = getUtility(IApplication, name='root')
    app.add_async_utility(QUEUE_UTILITY_CONFIG, loop)

    util = getUtility(IQueueUtility)
    var = []

    async def printHi(msg):
        asyncio.sleep(0.01)
        var.append(msg)

    request = utils.get_mocked_request(requester.db)
    root = await utils.get_root(request)

    await util.add(AsyncMockView(root, request, printHi, 'hola1'))
    await util.add(AsyncMockView(root, request, printHi, 'hola2'))
    await util.add(AsyncMockView(root, request, printHi, 'hola3'))
    await util.add(AsyncMockView(root, request, printHi, 'hola4'))
    await util._queue.join()
    assert 'hola1' in var
    assert 'hola2' in var
    assert 'hola3' in var
    assert 'hola4' in var
    assert len(var) == 4

    app.del_async_utility(QUEUE_UTILITY_CONFIG)
Пример #2
0
    async def load_videos(self, prefix='Movies/'):
        db = await self._db.get()
        if 'videos' not in db:
            db['videos'] = {}

        util = getUtility(IGCloudBlobStore)
        async with aiohttp.ClientSession() as session:
            access_token = await util.get_access_token()
            url = '{}/vangheem-media/o'.format(OBJECT_BASE_URL)
            resp = await session.get(
                url,
                headers={'AUTHORIZATION': 'Bearer %s' % access_token},
                params={'prefix': prefix})
            data = await resp.json()

        for video in data['items']:
            filename = video['name']
            if filename == prefix:
                continue
            ext = filename.split('.')[-1].lower()
            if ext not in ('m4v', 'mov', 'mp4'):
                continue
            video = {
                'name': filename,
                'id': video['id'],
                'created': video['timeCreated'],
                'updated': video['updated'],
                'link': video['mediaLink'],
                'size': video['size'],
                'selfLink': video['selfLink']
            }
            db['videos'][video['id']] = video
            await self._queue.put(video)
            await self._db.save()
Пример #3
0
async def es_migrate(path,
                     root,
                     request,
                     reindex_security=False,
                     mapping_only=False,
                     full=False,
                     force=False):
    try:
        ob, end_path = await traverse(request, root,
                                      path.lstrip('/').split('/'))
        if len(end_path) != 0:
            raise Exception('Could not found object')
        search = getUtility(ICatalogUtility)
        migrator = Migrator(search,
                            ob,
                            reindex_security=reindex_security,
                            full=full,
                            force=force,
                            mapping_only=mapping_only,
                            request=request,
                            log_details=True)
        await migrator.run_migration()
    finally:
        txn = get_transaction(request)
        if txn is not None:
            tm = get_tm(request)
            await tm.abort(txn=txn)
Пример #4
0
    async def migrate_all(self, arguments):
        search = getUtility(ICatalogUtility)
        change_transaction_strategy('none')
        await asyncio.sleep(1)  # since something initialize custom types...
        async for _, tm, container in get_containers(self.request):
            try:
                self.migrator = Migrator(
                    search,
                    container,
                    response=printer(),
                    full=arguments.full,
                    force=arguments.force,
                    log_details=arguments.log_details,
                    memory_tracking=arguments.memory_tracking,
                    reindex_security=arguments.reindex_security,
                    mapping_only=arguments.mapping_only)
                await self.migrator.run_migration()
                seconds = int(time.time() - self.migrator.start_time)
                logger.warning(f'''Finished migration:
Total Seconds: {seconds}
Processed: {self.migrator.processed}
Indexed: {self.migrator.indexed}
Objects missing: {len(self.migrator.missing)}
Objects orphaned: {len(self.migrator.orphaned)}
Mapping Diff: {self.migrator.mapping_diff}
''')
            finally:
                await tm.commit(self.request)
Пример #5
0
async def _test_new_deletes_are_performed_during_migration(es_requester):
    async with es_requester as requester:
        await add_content(requester)
        container, request, txn, tm = await setup_txn_on_container(requester)

        search = getUtility(ICatalogUtility)
        migrator = Migrator(search, container, force=True, request=request)
        await migrator.setup_next_index()
        await migrator.copy_to_next_index()

        await search.refresh(container, migrator.work_index_name)
        await search.refresh(container)
        num_docs = await search.get_doc_count(container, migrator.work_index_name)
        current_docs = await search.get_doc_count(container)
        assert num_docs == current_docs

        keys = await container.async_keys()
        key = random.choice(keys)
        ob = await container.async_get(key)
        keys = await ob.async_keys()
        key = random.choice(keys)
        ob = await ob.async_get(key)

        await search.remove(container, [(
            ob._p_oid, ob.type_name, get_content_path(ob)
        )], request=request)

        await search.refresh(container, migrator.work_index_name)
        await search.refresh(container)
        num_docs = await search.get_doc_count(container, migrator.work_index_name)
        current_count = await search.get_doc_count(container)
        assert num_docs == current_count
Пример #6
0
async def _test_new_indexes_are_performed_during_migration(es_requester):
    async with es_requester as requester:
        await add_content(requester)
        container, request, txn, tm = await setup_txn_on_container(requester)

        search = getUtility(ICatalogUtility)
        migrator = Migrator(search, container, force=True, request=request)
        await migrator.setup_next_index()
        await migrator.copy_to_next_index()

        await asyncio.sleep(1)
        await search.refresh(container, migrator.work_index_name)
        await search.refresh(container)
        await asyncio.sleep(1)
        num_docs = await search.get_doc_count(container, migrator.work_index_name)
        assert num_docs == await search.get_doc_count(container)

        await add_content(requester, base_id='foobar1-')

        await asyncio.sleep(1)
        await search.refresh(container, migrator.work_index_name)
        await search.refresh(container)
        await asyncio.sleep(1)
        num_docs = await search.get_doc_count(container, migrator.work_index_name)
        assert num_docs == await search.get_doc_count(container)
async def test_removes_orphans(es_requester):
    async with es_requester as requester:
        container, request, txn, tm = await setup_txn_on_container(requester)
        search = getUtility(ICatalogUtility)
        await search.index(
            container, {'foobar': {
                'title': 'foobar',
                'type_name': 'Item'
            }})
        # foobar here is an orphaned object because it doesn't reference an object

        index_name = await search.get_index_name(container)  # alias

        doc = await search.conn.get(index=index_name,
                                    doc_type=DOC_TYPE,
                                    id='foobar')
        assert doc['found']

        migrator = Migrator(search, container, force=True)
        await migrator.run_migration()

        async def _test():
            with pytest.raises(aioelasticsearch.exceptions.NotFoundError):
                await search.conn.get(index=index_name,
                                      doc_type=DOC_TYPE,
                                      id='foobar')

            assert len(migrator.orphaned) == 1
            assert migrator.orphaned[0] == 'foobar'

        await run_with_retries(_test, requester)
async def test_calculate_mapping_diff(es_requester):
    async with es_requester as requester:
        container, request, txn, tm = await setup_txn_on_container(requester)
        search = getUtility(ICatalogUtility)

        migrator = Migrator(search, container, force=True, request=request)
        version, new_index_name = await migrator.create_next_index()
        migrator.work_index_name = new_index_name

        mappings = get_mappings()
        index_settings = DEFAULT_SETTINGS.copy()
        index_settings.update(app_settings.get('index', {}))

        # tweak mappings so we can get the diff...
        if 'creators' in mappings['properties']:
            mappings['properties']['creators']['type'] = 'text'
        mappings['properties']['foobar'] = {'type': 'keyword', 'index': True}

        await search.conn.indices.close(new_index_name)
        await search.conn.indices.put_settings(body=index_settings,
                                               index=new_index_name)
        await search.conn.indices.put_mapping(index=new_index_name,
                                              doc_type=DOC_TYPE,
                                              body=mappings)
        await search.conn.indices.open(new_index_name)

        diff = await migrator.calculate_mapping_diff()
        assert len(diff[DOC_TYPE]) == 2
Пример #9
0
    async def test_allowed_types(self, dummy_request):
        self.request = dummy_request
        utils.login(self.request)

        site = await create_content('Site',
                                    id='guillotina',
                                    title='Guillotina')
        site.__name__ = 'guillotina'
        utils._p_register(site)

        import guillotina.tests
        configure.register_configuration(
            Folder,
            dict(
                portal_type="TestType",
                allowed_types=['Item'],
                module=guillotina.tests  # for registration initialization
            ),
            'contenttype')
        root = getUtility(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(site, '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')
Пример #10
0
def get_cached_factory(portal_type):
    if portal_type in FACTORY_CACHE:
        factory = FACTORY_CACHE[portal_type]
    else:
        factory = getUtility(IResourceFactory, portal_type)
        FACTORY_CACHE[portal_type] = factory
    return factory
Пример #11
0
async def test_calculate_mapping_diff(es_requester):
    async with es_requester as requester:
        container, request, txn, tm = await setup_txn_on_container(requester)
        search = getUtility(ICatalogUtility)

        migrator = Migrator(search, container, force=True, request=request)
        version, new_index_name = await migrator.create_next_index()
        migrator.work_index_name = new_index_name

        mappings = get_mappings()
        index_settings = DEFAULT_SETTINGS.copy()
        index_settings.update(app_settings.get('index', {}))

        # tweak mappings so we can get the diff...
        for key, value in mappings.items():
            # need to modify on *all* or it won't work with ES..
            if 'creators' in value['properties']:
                value['properties']['creators']['type'] = 'text'
        mappings['Item']['properties']['foobar'] = {
            'type': 'keyword',
            'index': True
        }

        await search.conn.indices.close(new_index_name)
        await search.conn.indices.put_settings(index_settings, new_index_name)
        for key, value in mappings.items():
            await search.conn.indices.put_mapping(new_index_name, key, value)
        await search.conn.indices.open(new_index_name)

        diff = await migrator.calculate_mapping_diff()
        assert len(diff['Folder']) == 1
        assert len(diff['Item']) == 2
def test_negotiate_complex_accept_header(dummy_guillotina):
    np = getUtility(IContentNegotiation, 'content_type')
    ap = np.negotiate(accept='application/vnd.google.protobuf;'
                      'proto=io.prometheus.client.MetricFamily;'
                      'encoding=delimited;q=0.7,text/plain;'
                      'version=0.0.4;q=0.3,*/*;q=0.1')
    assert str(ap.content_type) == 'text/plain'
Пример #13
0
def get_cached_factory(type_name):
    if type_name in FACTORY_CACHE:
        factory = FACTORY_CACHE[type_name]
    else:
        factory = getUtility(IResourceFactory, type_name)
        FACTORY_CACHE[type_name] = factory
    return factory
Пример #14
0
 def del_async_utility(self, config):
     self.cancel_async_utility(config['provides'])
     interface = import_class(config['provides'])
     utility = getUtility(interface)
     gsm = getGlobalSiteManager()
     gsm.unregisterUtility(utility, provided=interface)
     del self._async_utilities[config['provides']]
Пример #15
0
 def __init__(self,
              txn,
              tm,
              request,
              container,
              last_tid=-2,
              index_scroll='15m',
              hits_scroll='5m',
              use_tid_query=True):
     self.txn = txn
     self.tm = tm
     self.request = request
     self.container = container
     self.orphaned = set()
     self.missing = set()
     self.out_of_date = set()
     self.utility = getUtility(ICatalogUtility)
     self.migrator = Migrator(self.utility,
                              self.container,
                              full=True,
                              bulk_size=10)
     self.cache = LRU(200)
     self.last_tid = last_tid
     print(f'Last TID: {self.last_tid}')
     self.use_tid_query = use_tid_query
     self.last_zoid = None
     # for state tracking so we get boundries right
     self.last_result_set = []
     self.index_scroll = index_scroll
     self.hits_scroll = hits_scroll
Пример #16
0
async def test_removes_orphans(es_requester):
    async with es_requester as requester:
        container, request, txn, tm = await setup_txn_on_container(requester)
        search = getUtility(ICatalogUtility)
        await search.index(
            container, {'foobar': {
                'title': 'foobar',
                'type_name': 'Item'
            }})
        # foobar here is an orphaned object because it doesn't reference an object

        index_name = await search.get_index_name(container)  # alias

        doc = await search.conn.get(index_name, 'foobar')
        assert doc['found']

        migrator = Migrator(search, container, force=True)
        await migrator.run_migration()
        await asyncio.sleep(1)
        await search.refresh(container, index_name)
        await asyncio.sleep(1)

        with pytest.raises(aioes.exception.NotFoundError):
            doc = await search.conn.get(index_name, 'foobar')

        assert len(migrator.orphaned) == 1
        assert migrator.orphaned[0] == 'foobar'
Пример #17
0
async def test_subscriber_ignores_trsn_on_invalidate(
        redis_container, dummy_guillotina, loop):
    await cache.close_redis_pool()
    trns = mocks.MockTransaction(mocks.MockTransactionManager())
    trns.added = trns.deleted = {}
    content = create_content()
    trns.modified = {content._p_oid: content}
    rcache = RedisCache(trns, loop=loop)
    await rcache.clear()

    await rcache.set('foobar', oid=content._p_oid)
    assert serialize.loads(
        await rcache._redis.get(
            CACHE_PREFIX + 'root-' + content._p_oid)) == "foobar"
    assert rcache._memory_cache.get('root-' + content._p_oid) == 'foobar'
    assert await rcache.get(oid=content._p_oid) == 'foobar'

    assert 'root-' + content._p_oid in rcache._memory_cache

    utility = getUtility(IRedisChannelUtility)
    utility.ignore_tid(5555)

    await rcache._redis.publish(
        app_settings['redis']['updates_channel'], serialize.dumps({
            'tid': 5555,
            'keys': ['root-' + content._p_oid]
        }))
    await asyncio.sleep(1)  # should be enough for pub/sub to finish
    # should still be there because we set to ignore this tid
    assert 'root-' + content._p_oid in rcache._memory_cache
    # tid should also now be removed from ignored list
    assert 5555 not in utility._ignored_tids

    await cache.close_redis_pool()
Пример #18
0
async def _test_migrate_while_content_getting_added(es_requester):
    async with es_requester as requester:
        add_count = await add_content(requester)

        container, request, txn, tm = await setup_txn_on_container(requester)

        search = getUtility(ICatalogUtility)
        await search.refresh(container)
        await asyncio.sleep(3)

        assert add_count == await search.get_doc_count(container)

        migrator = Migrator(search, container, force=True)
        add_content_task1 = asyncio.ensure_future(
            add_content(requester, base_id='foo1-'))
        add_content_task2 = asyncio.ensure_future(
            add_content(requester, base_id='foo2-'))
        reindex_task = asyncio.ensure_future(migrator.run_migration())

        await asyncio.wait(
            [add_content_task1, reindex_task, add_content_task2])
        await search.refresh(container)
        await asyncio.sleep(3)

        idx_count = await search.get_doc_count(container)
        # +1 here because container ob now indexed and it isn't by default in tests
        assert (add_count * 3) + 1 == idx_count

        await tm.abort(txn=txn)
Пример #19
0
async def test_migrator_emmits_events_on_end(es_requester, event_handler):
    async with es_requester as requester:
        resp, status = await requester('POST',
                                       '/db/guillotina/',
                                       data=json.dumps({
                                           '@type': 'Folder',
                                           'title': 'Folder',
                                           'id': 'foobar'
                                       }))

        container, req, txn, tm = await setup_txn_on_container(requester)
        search = getUtility(ICatalogUtility)

        gr.base.adapters.subscribe([IIndexProgress], None,
                                   event_handler.subscribe)
        migrator = Reindexer(search,
                             container,
                             force=True,
                             request=req,
                             reindex_security=True)

        ob = await container.async_get('foobar')
        await migrator.reindex(ob)
        assert event_handler.called == True
        assert len(event_handler.event) == 2
        assert event_handler.event[0].completed == None
        assert event_handler.event[0].processed == 0
        assert event_handler.event[1].completed == True
        assert event_handler.event[0].context == container
Пример #20
0
async def test_write_large_blob_data(postgres, guillotina_main):
    root = getUtility(IApplication, name='root')
    db = root['db']
    request = get_mocked_request(db)
    login(request)

    async with managed_transaction(request=request):
        container = await create_content_in_container(
            db, 'Container', 'container', request=request,
            title='Container')

        blob = Blob(container)
        container.blob = blob

        multiplier = 999999

        blobfi = blob.open('w')
        await blobfi.async_write(b'foobar' * multiplier)

    async with managed_transaction(request=request):
        container = await db.async_get('container')
        assert await container.blob.open().async_read() == (b'foobar' * multiplier)
        assert container.blob.size == len(b'foobar' * multiplier)
        assert container.blob.chunks == 6

        await db.async_del('container')
Пример #21
0
async def get_video(video_id):
    util = getUtility(IGlexUtility)
    db = await util.get_db()
    try:
        return db['videos'][video_id]
    except IndexError:
        return None
Пример #22
0
async def download_task(video):
    util = getUtility(IGCloudBlobStore)
    if not os.path.exists(app_settings['download_folder']):
        os.mkdir(app_settings['download_folder'])
    filepath = os.path.join(app_settings['download_folder'],
                            _get_filename(video))
    fi = open(filepath, 'wb')
    os.utime(filepath, None)  # force filename...

    print(f'Downloading {video["id"]}')
    async with aiohttp.ClientSession() as session:
        api_resp = await session.get(video['link'],
                                     headers={
                                         'AUTHORIZATION':
                                         'Bearer %s' %
                                         await util.get_access_token()
                                     })

        count = 0
        # file_size = int(video['size'])
        while True:
            chunk = await api_resp.content.read(1024 * 1024 * 5)
            if len(chunk) > 0:
                count += len(chunk)
                # print("Download {}%.".format(int((count / file_size) * 100)))
                fi.write(chunk)
                fi.flush()
                os.fsync(fi.fileno())
            else:
                break
    fi.close()
    print(f'Finished download {video["id"]}')
    if video['id'] in _tasks:
        del _tasks[video['id']]
Пример #23
0
    async def handle_ws_request(self, ws, message):
        method = app_settings['http_methods']['GET']
        path = tuple(p for p in message['value'].split('/') if p)

        # avoid circular import
        from guillotina.traversal import do_traverse

        obj, tail = await do_traverse(self.request, self.request.container,
                                      path)

        traverse_to = None

        if tail and len(tail) == 1:
            view_name = tail[0]
        elif tail is None or len(tail) == 0:
            view_name = ''
        else:
            view_name = tail[0]
            traverse_to = tail[1:]

        permission = getUtility(IPermission, name='guillotina.AccessContent')

        allowed = IInteraction(self.request).check_permission(
            permission.id, obj)
        if not allowed:
            response = {'error': 'Not allowed'}
            ws.send_str(ujson.dumps(response))

        try:
            view = queryMultiAdapter((obj, self.request),
                                     method,
                                     name=view_name)
        except AttributeError:
            view = None

        if traverse_to is not None:
            if view is None or not ITraversableView.providedBy(view):
                response = {'error': 'Not found'}
                ws.send_str(ujson.dumps(response))
            else:
                try:
                    view = await view.publish_traverse(traverse_to)
                except Exception as e:
                    logger.error("Exception on view execution", exc_info=e)
                    response = {'error': 'Not found'}
                    ws.send_str(ujson.dumps(response))

        view_result = await view()
        if isinstance(view_result, Response):
            view_result = view_result.response

        # Return the value
        ws.send_str(ujson.dumps(view_result))

        # Wait for possible value
        futures_to_wait = self.request._futures.values()
        if futures_to_wait:
            await asyncio.gather(*list(futures_to_wait))
            self.request._futures = {}
Пример #24
0
async def download_head(context, request):
    util = getUtility(IGlexUtility)
    db = await util.get_db()
    try:
        video = db['videos'][request.GET['id']]
    except IndexError:
        return HTTPNotFound()
    return Response(headers={'Content-Length': video['size']})
Пример #25
0
async def test_create_next_index(es_requester):
    async with es_requester as requester:
        container, request, txn, tm = await setup_txn_on_container(requester)
        search = getUtility(ICatalogUtility)
        migrator = Migrator(search, container, force=True, request=request)
        version, name = await migrator.create_next_index()
        assert version == 2
        assert name == 'guillotina-guillotina_2'
Пример #26
0
def dummy_request(dummy_guillotina, monkeypatch):
    from guillotina.interfaces import IApplication
    from guillotina.component import getUtility
    root = getUtility(IApplication, name='root')
    db = root['db']

    request = get_mocked_request(db)
    return request
Пример #27
0
async def test_register_behavior(container_requester):
    cur_count = len(
        configure.get_configurations('guillotina.tests', 'behavior'))

    from guillotina.interfaces import IFormFieldProvider, IResource
    from zope.interface import provider
    from guillotina import schema

    @provider(IFormFieldProvider)
    class IMyBehavior(Interface):
        foobar = schema.Text()

    class IMyBehavior2(Interface):
        foobar = schema.Text()

    configure.behavior(
        title="MyBehavior",
        provides=IMyBehavior,
        factory="guillotina.behaviors.instance.AnnotationBehavior",
        for_="guillotina.interfaces.IResource"
    )()
    configure.behavior(
        title="MyBehavior2",
        provides=IMyBehavior2,
        factory="guillotina.behaviors.instance.AnnotationBehavior",
        for_="guillotina.interfaces.IResource"
    )()

    assert len(configure.get_configurations('guillotina.tests', 'behavior')) == cur_count + 2

    class IMyType(IResource):
        pass

    class MyType(Item):
        pass

    configure.register_configuration(MyType, dict(
        context=IContainer,
        schema=IMyType,
        type_name="MyType2",
        behaviors=[IMyBehavior]
    ), 'contenttype')

    root = getUtility(IApplication, name='root')
    config = root.app.config
    # now test it...
    configure.load_configuration(config, 'guillotina.tests', 'contenttype')
    configure.load_configuration(config, 'guillotina.tests', 'behavior')
    config.execute_actions()

    async with await container_requester as requester:
        response, status = await requester('GET', '/db/guillotina/@types')
        type_ = [s for s in response if s['title'] == 'MyType2'][0]
        assert 'foobar' in type_['definitions']['IMyBehavior']['properties']

    # also get_all_possible_schemas_for_type should come with this new behavior
    behaviors_schemas = get_all_possible_schemas_for_type('MyType2')
    assert IMyBehavior2 in behaviors_schemas
Пример #28
0
 async def get_dbs(self):
     root = getUtility(IApplication, name='root')
     for _id, db in root:
         if IDatabase.providedBy(db):
             tm = db.get_transaction_manager()
             tm.request = self.request
             await tm.begin(self.request)
             async for s_id, container in db.async_items():
                 tm.request.container = container
                 yield tm, container
Пример #29
0
async def get_containers(request):
    root = getUtility(IApplication, name='root')
    for _id, db in root:
        if IDatabase.providedBy(db):
            db._db._storage._transaction_strategy = 'none'
            tm = db.get_transaction_manager()
            tm.request = request
            txn = await tm.begin(request)
            async for s_id, container in db.async_items():
                tm.request.container = container
                yield txn, tm, container
Пример #30
0
async def test_updates_index_name(es_requester):
    async with es_requester as requester:
        container, request, txn, tm = await setup_txn_on_container(requester)
        search = getUtility(ICatalogUtility)
        existing_index = await search.get_real_index_name(container)
        assert await search.conn.indices.exists(existing_index)
        migrator = Migrator(search, container, force=True, request=request)
        await migrator.run_migration()
        assert not await search.conn.indices.exists(existing_index)
        assert search.conn.indices.exists(migrator.work_index_name)
        assert await search.get_real_index_name(container
                                                ) == migrator.work_index_name