예제 #1
0
 def test__init__db__ok_nominal_case(self, hapic, session,
                                     user_api_factory):
     """
     Test database initialisation
     """
     api = user_api_factory.get()
     user = api.get_one_by_email("*****@*****.**")
     assert user.email == "*****@*****.**"
     assert user.validate_password("*****@*****.**")
     assert not user.validate_password("new_password")
     session.close()
     # NOTE GM 2019-07-21: Unset Depot configuration. Done here and not in fixture because
     # TracimCLI need reseted context when ran.
     DepotManager._clear()
     app = TracimCLI()
     # delete config to be sure command will work
     app.run([
         "db",
         "delete",
         "--force",
         "-c",
         "{}#command_test".format(TEST_CONFIG_FILE_PATH),
         "--debug",
     ])
     result = app.run([
         "db", "init", "-c",
         "{}#command_test".format(TEST_CONFIG_FILE_PATH), "--debug"
     ])
     assert result == 0
예제 #2
0
 def test_func__user_create_command__ok__nominal_case(
         self, session, user_api_factory) -> None:
     """
     Test User creation
     """
     api = user_api_factory.get()
     with pytest.raises(UserDoesNotExist):
         api.get_one_by_email("command_test@user")
     session.close()
     # NOTE GM 2019-07-21: Unset Depot configuration. Done here and not in fixture because
     # TracimCLI needs the context to be reset when ran.
     DepotManager._clear()
     app = TracimCLI()
     result = app.run([
         "user",
         "create",
         "-c",
         "{}#command_test".format(TEST_CONFIG_FILE_PATH),
         "-e",
         "command_test@user",
         "-p",
         "new_password",
         "--debug",
     ])
     assert result == 0
     api = user_api_factory.get()
     new_user = api.get_one_by_email("command_test@user")
     assert new_user.email == "command_test@user"
     assert new_user.validate_password("new_password")
     assert new_user.profile.slug == "users"
예제 #3
0
    def setup(self):
        DepotManager._clear()

        try:
            global S3Storage
            from depot.io.awss3 import S3Storage
        except ImportError:
            raise SkipTest('Boto not installed')

        env = os.environ
        access_key_id = env.get('AWS_ACCESS_KEY_ID')
        secret_access_key = env.get('AWS_SECRET_ACCESS_KEY')
        if access_key_id is None or secret_access_key is None:
            raise SkipTest('Amazon S3 credentials not available')

        PID = os.getpid()
        NODE = str(uuid.uuid1()).rsplit('-', 1)[-1]  # Travis runs multiple tests concurrently
        default_bucket_name = 'filedepot-%s' % (access_key_id.lower(), )
        cred = (access_key_id, secret_access_key)
        bucket_name = 'filedepot-testfs-%s-%s-%s' % (access_key_id.lower(), NODE, PID)

        DepotManager.configure('awss3', {'depot.backend': 'depot.io.awss3.S3Storage',
                                         'depot.access_key_id': access_key_id,
                                         'depot.secret_access_key': secret_access_key,
                                         'depot.bucket': bucket_name})
        DepotManager.set_default('awss3')
예제 #4
0
 def test_func__user_update_command__err_password_modification_failed__external_auth(
         self, hapic, session, user_api_factory) -> None:
     """
     Test user password update
     """
     api = user_api_factory.get()
     user = api.get_one_by_email("*****@*****.**")
     assert user.email == "*****@*****.**"
     assert user.validate_password("*****@*****.**")
     assert not user.validate_password("new_password")
     user.auth_type = AuthType.LDAP
     assert user.auth_type == AuthType.LDAP
     session.add(user)
     session.flush()
     transaction.commit()
     session.close()
     # NOTE GM 2019-07-21: Unset Depot configuration. Done here and not in fixture because
     # TracimCLI need reseted context when ran.
     DepotManager._clear()
     app = TracimCLI()
     with pytest.raises(ExternalAuthUserPasswordModificationDisallowed):
         app.run([
             "user",
             "update",
             "-c",
             "{}#command_test".format(TEST_CONFIG_FILE_PATH),
             "-l",
             "*****@*****.**",
             "-p",
             "new_ldap_password",
             "--debug",
         ])
예제 #5
0
    def setUp(self):
        logger.debug(self, 'Setup Test...')
        self.config = testing.setUp(
            settings={
                'sqlalchemy.url': 'sqlite:///:memory:',
                'user.auth_token.validity': '604800',
                'depot_storage_dir': '/tmp/test/depot',
                'depot_storage_name': 'test',
                'preview_cache_dir': '/tmp/test/preview_cache',
            })
        self.config.include('tracim.models')
        DepotManager._clear()
        DepotManager.configure(
            'test', {'depot.backend': 'depot.io.memory.MemoryFileStorage'})
        settings = self.config.get_settings()
        self.app_config = CFG(settings)
        from tracim.models import (
            get_engine,
            get_session_factory,
            get_tm_session,
        )

        self.engine = get_engine(settings)
        session_factory = get_session_factory(self.engine)

        self.session = get_tm_session(session_factory, transaction.manager)
        self.init_database()
예제 #6
0
def webdav_testapp(config_uri, config_section) -> TestApp:
    DepotManager._clear()
    settings = plaster.get_settings(config_uri, config_section)
    settings["here"] = os.path.dirname(os.path.abspath(TEST_CONFIG_FILE_PATH))
    app_factory = WebdavAppFactory(**settings)
    app = app_factory.get_wsgi_app()
    return TestApp(app)
예제 #7
0
 def test__delete__db__err_no_force_param(self, hapic, session,
                                          user_api_factory):
     """
     Test database deletion
     """
     api = user_api_factory.get()
     user = api.get_one_by_email("*****@*****.**")
     assert user.email == "*****@*****.**"
     assert user.validate_password("*****@*****.**")
     assert not user.validate_password("new_password")
     session.close()
     # NOTE GM 2019-07-21: Unset Depot configuration. Done here and not in fixture because
     # TracimCLI need reseted context when ran.
     DepotManager._clear()
     app = TracimCLI()
     with pytest.raises(ForceArgumentNeeded):
         app.run([
             "db", "delete", "-c",
             "{}#command_test".format(TEST_CONFIG_FILE_PATH), "--debug"
         ])
     result = app.run([
         "db", "delete", "-c",
         "{}#command_test".format(TEST_CONFIG_FILE_PATH)
     ])
     assert result == 1
예제 #8
0
 def test_func__user_update_command__ok__nominal_case(
         self, hapic, session, user_api_factory) -> None:
     """
     Test user password update
     """
     api = user_api_factory.get()
     user = api.get_one_by_email("*****@*****.**")
     assert user.email == "*****@*****.**"
     assert user.validate_password("*****@*****.**")
     assert not user.validate_password("new_password")
     session.close()
     # NOTE GM 2019-07-21: Unset Depot configuration. Done here and not in fixture because
     # TracimCLI need reseted context when ran.
     DepotManager._clear()
     app = TracimCLI()
     result = app.run([
         "user",
         "update",
         "-c",
         "{}#command_test".format(TEST_CONFIG_FILE_PATH),
         "-l",
         "*****@*****.**",
         "-p",
         "new_password",
         "--debug",
     ])
     assert result == 0
     api = user_api_factory.get()
     new_user = api.get_one_by_email("*****@*****.**")
     assert new_user.email == "*****@*****.**"
     assert new_user.validate_password("new_password")
     assert not new_user.validate_password("*****@*****.**")
예제 #9
0
def setup():
    setup_database()

    DepotManager._clear()
    DepotManager.configure('default', {'depot.storage_path': './lfs'})
    DepotManager.configure('another', {'depot.storage_path': './lfs'})
    DepotManager.alias('another_alias', 'another')
    DepotManager.make_middleware(None)
예제 #10
0
def setup():
    setup_database()

    DepotManager._clear()
    DepotManager.configure("default", {"depot.storage_path": "./lfs"})
    DepotManager.configure("another", {"depot.storage_path": "./lfs"})
    DepotManager.alias("another_alias", "another")
    DepotManager.make_middleware(None)
예제 #11
0
def setup():
    setup_database()

    DepotManager._clear()
    DepotManager.configure('default', {'depot.storage_path': './lfs'})
    DepotManager.configure('another', {'depot.storage_path': './lfs'})
    DepotManager.alias('another_alias', 'another')
    DepotManager.make_middleware(None)
예제 #12
0
    def tearDown(self):
        logger.debug(self, 'TearDown Test...')
        from tracim.models.meta import DeclarativeBase

        testing.tearDown()
        transaction.abort()
        DeclarativeBase.metadata.drop_all(self.engine)
        DepotManager._clear()
예제 #13
0
 def disconnect_database(self, remove_tables: bool = False) -> None:
     self.session.rollback()
     transaction.abort()
     self.session.close_all()
     self.engine.dispose()
     if remove_tables:
         DeclarativeBase.metadata.drop_all(self.engine)
     DepotManager._clear()
예제 #14
0
def depot(temporary_directory):
    DepotManager.configure('default', {
        'depot.backend': 'depot.io.local.LocalFileStorage',
        'depot.storage_path': temporary_directory
    })

    yield DepotManager.get()

    DepotManager._clear()
예제 #15
0
def depot(temporary_directory):
    DepotManager.configure(
        'default', {
            'depot.backend': 'depot.io.local.LocalFileStorage',
            'depot.storage_path': temporary_directory
        })

    yield DepotManager.get()

    DepotManager._clear()
예제 #16
0
    def tearDown(self) -> None:
        logger.debug(self, "TearDown Test...")
        from tracim_backend.models.meta import DeclarativeBase

        self.session.rollback()
        self.session.close_all()
        transaction.abort()
        DeclarativeBase.metadata.drop_all(self.engine)
        self.engine.dispose()
        DepotManager._clear()
        testing.tearDown()
예제 #17
0
파일: test_app.py 프로젝트: Kotti/Kotti
    def test_default_filedepot(self, db_session):
        from kotti import main
        from depot.manager import DepotManager

        settings = self.required_settings()

        with patch("kotti.resources.initialize_sql"):
            with patch("kotti.filedepot.TweenFactory"):
                main({}, **settings)
        assert DepotManager.get().__class__.__name__ == "DBFileStorage"
        DepotManager._clear()
예제 #18
0
파일: __init__.py 프로젝트: rkx-forks/Kotti
def no_filedepots(db_session, depot_tween):
    """A filedepot fixture to empty and then restore DepotManager configuration"""
    from depot.manager import DepotManager

    DepotManager._depots = {}
    DepotManager._default_depot = None

    yield DepotManager

    db_session.rollback()
    DepotManager._clear()
예제 #19
0
    def test_default_filedepot(self, db_session):
        from kotti import main
        from depot.manager import DepotManager

        settings = self.required_settings()

        with patch('kotti.resources.initialize_sql'):
            with patch('kotti.filedepot.TweenFactory'):
                main({}, **settings)
        assert DepotManager.get().__class__.__name__ == 'DBFileStorage'
        DepotManager._clear()
예제 #20
0
    def tearDown(self) -> None:
        logger.debug(self, "TearDown Test...")

        self.session.rollback()
        self.session.close_all()
        transaction.abort()
        DeclarativeBase.metadata.drop_all(self.engine)
        sql = text("DROP TABLE IF EXISTS migrate_version;")
        self.engine.execute(sql)
        self.engine.dispose()
        DepotManager._clear()
        testing.tearDown()
예제 #21
0
    def tearDown(self) -> None:
        logger.debug(self, 'TearDown Test...')

        self.session.rollback()
        self.session.close_all()
        transaction.abort()
        DeclarativeBase.metadata.drop_all(self.engine)
        sql = text('DROP TABLE IF EXISTS migrate_version;')
        result = self.engine.execute(sql)
        self.engine.dispose()
        DepotManager._clear()
        testing.tearDown()
예제 #22
0
파일: __init__.py 프로젝트: Kotti/Kotti
def no_filedepots(db_session, depot_tween):
    """ A filedepot fixture to empty and then restore DepotManager configuration
    """
    from depot.manager import DepotManager

    DepotManager._depots = {}
    DepotManager._default_depot = None

    yield DepotManager

    db_session.rollback()
    DepotManager._clear()
예제 #23
0
파일: __init__.py 프로젝트: uggla/tracim
 def setUp(self) -> None:
     self._set_logger()
     DepotManager._clear()
     settings = plaster.get_settings(self.config_uri, self.config_section)
     self.settings = self.override_settings(settings)
     hapic.reset_context()
     self.connect_database(create_tables=True)
     self.app_config = CFG(self.settings)
     self.app_config.configure_filedepot()
     self.init_database(self.settings)
     DepotManager._clear()
     self.run_app()
예제 #24
0
    def test_func__anonymize_user__ok__specific_display_name(
        self,
        session,
        user_api_factory,
        hapic,
        content_api_factory,
        workspace_api_factory,
        role_api_factory,
        content_type_list,
        admin_user,
    ) -> None:
        """
        Test User anonymization
        """
        uapi = user_api_factory.get()
        test_user = uapi.create_user(
            email="*****@*****.**",
            password="******",
            name="bob",
            profile=Profile.USER,
            timezone="Europe/Paris",
            lang="fr",
            do_save=True,
            do_notify=False,
        )
        user_id = test_user.user_id
        transaction.commit()
        assert session.query(User).filter(User.user_id == user_id).one()
        assert session.query(UserConfig).filter(
            UserConfig.user_id == user_id).one()
        session.close()
        # NOTE GM 2019-07-21: Unset Depot configuration. Done here and not in fixture because
        # TracimCLI need reseted context when ran.
        DepotManager._clear()
        app = TracimCLI()
        result = app.run([
            "user",
            "anonymize",
            "-c",
            "{}#command_test".format(TEST_CONFIG_FILE_PATH),
            "-l",
            "*****@*****.**",
            "--anonymize-name",
            "Custom Name",
        ])
        assert result == 0

        test_user_retrieve = session.query(User).filter(
            User.user_id == user_id).one()
        assert test_user_retrieve.display_name == "Custom Name"
        assert test_user_retrieve.email.endswith("@anonymous.local")
        assert test_user_retrieve.config.fields == {}
예제 #25
0
파일: __init__.py 프로젝트: Kotti/Kotti
def filedepot(db_session, depot_tween):
    """ Configures a dbsession integrated mock depot store for
    :class:`depot.manager.DepotManager`
    """
    from depot.manager import DepotManager

    DepotManager._depots = {"filedepot": MagicMock(wraps=TestStorage())}
    DepotManager._default_depot = "filedepot"

    yield DepotManager

    db_session.rollback()
    DepotManager._clear()
예제 #26
0
파일: __init__.py 프로젝트: rkx-forks/Kotti
def filedepot(db_session, depot_tween):
    """Configures a dbsession integrated mock depot store for
    :class:`depot.manager.DepotManager`
    """
    from depot.manager import DepotManager

    DepotManager._depots = {"filedepot": MagicMock(wraps=TestStorage())}
    DepotManager._default_depot = "filedepot"

    yield DepotManager

    db_session.rollback()
    DepotManager._clear()
예제 #27
0
파일: __init__.py 프로젝트: Kotti/Kotti
def mock_filedepot(depot_tween):
    """ Configures a mock depot store for :class:`depot.manager.DepotManager`

    This filedepot is not integrated with dbsession.
    Can be used in simple, standalone unit tests.
    """
    from depot.manager import DepotManager

    DepotManager._depots = {"mockdepot": MagicMock(wraps=TestStorage())}
    DepotManager._default_depot = "mockdepot"

    yield DepotManager

    DepotManager._clear()
예제 #28
0
파일: __init__.py 프로젝트: rkx-forks/Kotti
def mock_filedepot(depot_tween):
    """Configures a mock depot store for :class:`depot.manager.DepotManager`

    This filedepot is not integrated with dbsession.
    Can be used in simple, standalone unit tests.
    """
    from depot.manager import DepotManager

    DepotManager._depots = {"mockdepot": MagicMock(wraps=TestStorage())}
    DepotManager._default_depot = "mockdepot"

    yield DepotManager

    DepotManager._clear()
예제 #29
0
파일: testing.py 프로젝트: xiang12383/Kotti
def tearDown():
    from depot.manager import DepotManager
    from kotti import events
    from kotti import security
    from kotti.message import _inject_mailer

    # These should arguable use the configurator, so they don't need
    # to be torn down separately:
    events.clear()
    security.reset()

    _inject_mailer[:] = []
    transaction.abort()
    DepotManager._clear()
    testing.tearDown()
예제 #30
0
파일: testing.py 프로젝트: Kotti/Kotti
def tearDown():
    from depot.manager import DepotManager
    from kotti import events
    from kotti import security
    from kotti.message import _inject_mailer

    # These should arguable use the configurator, so they don't need
    # to be torn down separately:
    events.clear()
    security.reset()

    _inject_mailer[:] = []
    transaction.abort()
    DepotManager._clear()
    testing.tearDown()
예제 #31
0
 def test_func__delete_user__ok__nominal_case(
     self,
     session,
     user_api_factory,
     hapic,
     content_api_factory,
     workspace_api_factory,
     content_type_list,
 ) -> None:
     """
     Test User deletion : nominal case, user has change nothing in other user workspace
     """
     uapi = user_api_factory.get()
     test_user = uapi.create_user(
         email="*****@*****.**",
         password="******",
         name="bob",
         profile=Profile.USER,
         timezone="Europe/Paris",
         lang="fr",
         do_save=True,
         do_notify=False,
     )
     session.add(test_user)
     session.flush()
     transaction.commit()
     user_id = test_user.user_id
     session.close()
     # NOTE GM 2019-07-21: Unset Depot configuration. Done here and not in fixture because
     # TracimCLI need reseted context when ran.
     DepotManager._clear()
     app = TracimCLI()
     result = app.run([
         "user",
         "delete",
         "-c",
         "{}#command_test".format(TEST_CONFIG_FILE_PATH),
         "-l",
         "*****@*****.**",
         "-d",
     ])
     assert result == 0
     with pytest.raises(NoResultFound):
         session.query(User).filter(User.user_id == user_id).one()
     with pytest.raises(NoResultFound):
         session.query(UserConfig).filter(
             UserConfig.user_id == user_id).one()
예제 #32
0
 def setUp(self) -> None:
     self._set_logger()
     DepotManager._clear()
     settings = plaster.get_settings(self.config_uri, self.config_section)
     self.settings = self.override_settings(settings)
     # INFO - G.M - 2019-03-19 - Reset all hapic context: PyramidContext
     # and controllers
     hapic.reset_context()
     # TODO - G.M - 2019-03-19 - Replace this code by something better, see
     # https://github.com/algoo/hapic/issues/144
     hapic._controllers = []
     self.app_config = CFG(self.settings)  # type: CFG
     self.app_config = self.override_app_config(self.app_config)
     self.app_config.configure_filedepot()
     self.connect_database(create_tables=True)
     self.init_database()
     DepotManager._clear()
     self.run_app()
예제 #33
0
 def test__init__db__ok_db_already_exist(self, hapic, session,
                                         user_api_factory):
     """
     Test database initialisation
     """
     api = user_api_factory.get()
     user = api.get_one_by_email("*****@*****.**")
     assert user.email == "*****@*****.**"
     assert user.validate_password("*****@*****.**")
     assert not user.validate_password("new_password")
     session.close()
     # NOTE GM 2019-07-21: Unset Depot configuration. Done here and not in fixture because
     # TracimCLI need reseted context when ran.
     DepotManager._clear()
     app = TracimCLI()
     with pytest.raises(DatabaseInitializationFailed):
         app.run([
             "db", "init", "-c",
             "{}#command_test".format(TEST_CONFIG_FILE_PATH), "--debug"
         ])
예제 #34
0
 def setUp(self):
     logger._logger.setLevel('WARNING')
     DepotManager._clear()
     self.settings = {
         'sqlalchemy.url': self.sqlalchemy_url,
         'user.auth_token.validity': '604800',
         'depot_storage_dir': '/tmp/test/depot',
         'depot_storage_name': 'test',
         'preview_cache_dir': '/tmp/test/preview_cache',
         'preview.jpg.restricted_dims': True,
         'email.notification.activated': 'false',
     }
     hapic.reset_context()
     self.engine = get_engine(self.settings)
     DeclarativeBase.metadata.create_all(self.engine)
     self.session_factory = get_session_factory(self.engine)
     self.app_config = CFG(self.settings)
     self.app_config.configure_filedepot()
     self.init_database(self.settings)
     DepotManager._clear()
     self.run_app()
예제 #35
0
 def test_func__user_create_command__err__password_required(
         self, hapic, session) -> None:
     """
     Test User creation without filling password
     """
     session.close()
     # NOTE GM 2019-07-21: Unset Depot configuration. Done here and not in fixture because
     # TracimCLI need reseted context when ran.
     DepotManager._clear()
     app = TracimCLI()
     with pytest.raises(BadCommandError):
         app.run([
             "--debug",
             "user",
             "create",
             "-c",
             "{}#command_test".format(TEST_CONFIG_FILE_PATH),
             "-l",
             "*****@*****.**",
             "--debug",
         ])
예제 #36
0
 def test__delete__db__err_no_config_file(self, hapic, session,
                                          user_api_factory):
     """
     Test database deletion
     """
     api = user_api_factory.get()
     user = api.get_one_by_email("*****@*****.**")
     assert user.email == "*****@*****.**"
     assert user.validate_password("*****@*****.**")
     assert not user.validate_password("new_password")
     session.close()
     # NOTE GM 2019-07-21: Unset Depot configuration. Done here and not in fixture because
     # TracimCLI need reseted context when ran.
     DepotManager._clear()
     app = TracimCLI()
     with pytest.raises(FileNotFoundError):
         app.run([
             "db", "delete", "-c", "donotexit.ini#command_test", "--debug"
         ])
     result = app.run(["db", "delete", "-c", "donotexist.ini#command_test"])
     assert result == 1
예제 #37
0
 def test_func__delete_user__err__workspace_left(
     self,
     session,
     user_api_factory,
     hapic,
     content_api_factory,
     workspace_api_factory,
     content_type_list,
     admin_user,
 ) -> None:
     """
     Test User deletion : nominal case, user has change nothing in other user workspace
     """
     user_id = admin_user.user_id
     workspace_api = workspace_api_factory.get()
     test_workspace = workspace_api.create_workspace("test_workspace")
     session.add(test_workspace)
     session.flush()
     workspace_id = test_workspace.workspace_id
     transaction.commit()
     assert session.query(Workspace).filter(
         Workspace.workspace_id == workspace_id).one()
     assert session.query(User).filter(User.user_id == user_id).one()
     assert session.query(UserConfig).filter(
         UserConfig.user_id == user_id).one()
     session.close()
     # NOTE GM 2019-07-21: Unset Depot configuration. Done here and not in fixture because
     # TracimCLI need reseted context when ran.
     DepotManager._clear()
     app = TracimCLI()
     result = app.run([
         "user",
         "delete",
         "-c",
         "{}#command_test".format(TEST_CONFIG_FILE_PATH),
         "-l",
         "*****@*****.**",
         "-d",
     ])
     assert result == 1
예제 #38
0
    def setUp(self) -> None:
        self._set_logger()
        logger.debug(self, "Setup Test...")
        self.settings = plaster.get_settings(self.config_uri,
                                             self.config_section)
        self.config = testing.setUp(settings=self.settings)
        DepotManager._clear()
        DepotManager.configure(
            "test", {"depot.backend": "depot.io.memory.MemoryFileStorage"})
        settings = self.config.get_settings()
        self.app_config = CFG(settings)
        init_models(self.config, self.app_config)
        from tracim_backend.models.setup_models import (
            get_engine,
            get_session_factory,
            get_tm_session,
        )

        self.engine = get_engine(self.app_config)
        self.session_factory = get_session_factory(self.engine)
        self.init_database()
        self.session = get_tm_session(self.session_factory,
                                      transaction.manager)
예제 #39
0
 def test_func__user_create_command__err_user_already_exist(
         self, hapic, session) -> None:
     """
     Test User creation with existing user login
     """
     session.close()
     # NOTE GM 2019-07-21: Unset Depot configuration. Done here and not in fixture because
     # TracimCLI need reseted context when ran.
     DepotManager._clear()
     app = TracimCLI()
     with pytest.raises(EmailAlreadyExists):
         app.run([
             "--debug",
             "user",
             "create",
             "-c",
             "{}#command_test".format(TEST_CONFIG_FILE_PATH),
             "-e",
             "*****@*****.**",
             "-p",
             "new_password",
             "--debug",
         ])
예제 #40
0
 def restore():
     db_session.rollback()
     DepotManager._clear()
예제 #41
0
 def setup(self):
     DepotManager._clear()
     DepotManager.configure('default', {'depot.storage_path': './lfs'})
예제 #42
0
 def setup(self):
     DepotManager._clear()
예제 #43
0
 def restore():
     DepotManager._clear()
예제 #44
0
def setup():
    setup_database()

    DepotManager._clear()
    DepotManager.configure('default', {'depot.storage_path': './lfs'})