Exemplo n.º 1
0
def test_remove():

    env = ODir('bin', push_up=True)

    a1 = env.add('A1')
    env.A1.add('A2')
    b1 = env.add('B1')
    env.B1.add('B2')

    assert hasattr(env, 'A1')
    assert hasattr(env, 'B1')
    assert hasattr(env.A1, 'A2')
    assert hasattr(env.B1, 'B2')
    assert hasattr(env, 'A2')
    assert hasattr(env, 'B2')

    env.A1.remove_parent()

    g = env.descendents()

    # Cannot access A1 from env. Can still access A2 from a1
    assert not hasattr(env, 'A1')
    assert not hasattr(env, 'A2')
    assert hasattr(a1, 'A2')

    # B1 and B2 are still exist
    assert hasattr(env, 'B1')
    assert hasattr(env.B1, 'B2')
    assert hasattr(env, 'B2')
Exemplo n.º 2
0
def test_attr():
    env = ODir('bin')
    name = 'somethigldj'
    attr = 'asldkfjlsdfj'
    env.add(name, attr=attr)
    assert hasattr(env, attr)
    assert not hasattr(env, name)
Exemplo n.º 3
0
    def __init__(self, dir, name="FishTank", meta_dir=None, meta_name=None):
        """
        SessionManager constructor

        :param dir: directory
        :type dir: str
        :param name: name of the folder
        :type name: str
        :param meta_dir: directory to store the metadata
        :type meta_dir: str
        :param meta_name: name of the file to store the metadata
        :type meta_name: str
        """
        super().__init__(name, push_up=False, check_attr=False)
        self.set_dir(dir)

        # Add metadata (has default)
        # this is where session manager information will be stored
        if meta_dir is None:
            meta_dir = self.DEFAULT_METADATA_LOC
        if meta_name is None:
            meta_name = self.DEFAULT_METADATA_NAME
        self.metadata = ODir(meta_dir)
        self.metadata.add_file(meta_name, 'env_settings')

        self._curr_session_name = None
Exemplo n.º 4
0
def test_paths():
    env = ODir('bin')
    env.add('session1')
    env.session1.add('cat1')
    env.session1.add('cat2')

    assert len(env.paths) == 4
    print(env.paths)
Exemplo n.º 5
0
def test_list_dirs():

    env = ODir('bin')
    env.add('A1').add('B1')
    env.add('C1').add("D1")

    dirs = env.list_dirs()
    assert env.A1 in dirs
    assert env.C1 in dirs
    assert not env.B1 in dirs
    assert not env.D1 in dirs
Exemplo n.º 6
0
def test_dont_sanitize_attr():
    env = ODir('bin')
    with pytest.raises(AttributeError):
        env.add('in')
    env.add('in', attr='myin')
    assert env.has('myin')
    assert not env.has('in')
Exemplo n.º 7
0
def env(tmpdir):
    tmpdir = str(tmpdir)
    env = ODir('bin')
    env.set_dir(tmpdir)
    env.add('A1')
    env.A1.add('A2')
    env.add('B1')
    env.B1.add('B2')
    return env
Exemplo n.º 8
0
def test_print_tree():
    env = ODir('bin', push_up=True)
    env.add('session1')
    env.session1.add('cat1')
    env.session1.add('cat2')
    env.add('session2')
    env.session2.add('cat1', attr="s2cat1")

    print(env._children)

    env.print()
Exemplo n.º 9
0
def a(request):
    env = ODir('bin', push_up=request.param)
    labels = ['a', 'b']

    for l1 in labels:
        env.add(l1)
        assert hasattr(env, l1)

        level = getattr(env, l1)
        for l2 in labels:

            next_level = l1 + l2
            getattr(env, l1).add(next_level)

            if request.param:
                assert hasattr(env, next_level)
            else:
                assert not hasattr(env, next_level)
            assert hasattr(level, next_level)
Exemplo n.º 10
0
def test_remove_children():

    env = ODir('bin', push_up=True)

    a1 = env.add('A1')
    env.A1.add('A2')
    b1 = env.add('B1')
    env.B1.add('B2')

    assert hasattr(env, 'A1')
    assert hasattr(env, 'B1')
    assert hasattr(env.A1, 'A2')
    assert hasattr(env.B1, 'B2')
    assert hasattr(env, 'A2')
    assert hasattr(env, 'B2')

    print(env.children.remove_parent())

    g = env.descendents()
    assert len(g) == 0
Exemplo n.º 11
0
def test_path():
    env = ODir('bin')
    env.add('session1')
    env.session1.add('cat1')
    env.session1.add('cat2')
    env.add('session2')
    env.session2.add('cat1', attr="s2cat1")

    assert str(env.path) == 'bin'
    assert str(env.s2cat1.path) == 'bin/session2/cat1'
    assert str(env.cat1.path) == 'bin/session1/cat1'
    assert str(env.cat2.path) == 'bin/session1/cat2'
Exemplo n.º 12
0
def test_list_files():

    env = ODir('bin')
    env.add('A1').add_file('afile')
    env.add('C1').add_file("dfile")
    env.add_file('efile')
    env.add_file('ffile')

    files = env.list_files()
    assert not env.A1 in files
    assert not env.afile in files
    assert not env.C1 in files
    assert not env.dfile in files

    assert env.efile in files
    assert env.ffile in files
Exemplo n.º 13
0
def test_unsanitized_attr():
    env = ODir('bin')
    assert env.add('something') == env.add('something')
    assert env.something.add('core') == env.add('something').add(
        'core') == env.something.core
    with pytest.raises(AttributeError):
        env.add('alskdf;;asd;flj')
    with pytest.raises(AttributeError):
        env.add('in')
    with pytest.raises(AttributeError):
        env.add('something', attr='somethingelse')
Exemplo n.º 14
0
class SessionManager(ODir):
    """
    Manages multiple :class:`SessionEnvironment` instances.
    SessionEnvironments live in a single directory managed by this class.
    Information about where the SessionManager directory resides is stored in
    the 'environment_data/environment_settings.json` file.
    By default, this is located where ParrotFish is installed so that is can be
    used globally on the machine.
    Alternatively, a SessionManager can be constructed that uses a new
    environement_settings file.
    The **environment_settings.json** also stores an encryption key so that
    :class:`SessionEnvironment`s can be decrypted and used properly.

    Example session structure::

        meta_dir
        └──environment_data
            └──environment_settings.json      (information about top directory)

        SessionManagerName          (Master or root directory)
        |──SessionEnvironment1      (Aquarium session)
        |   └──Category1            (Protocol Category)
        |       |──.env_pkl         (SessionEnvironment1's AqSession)
        |       |──protocols        (protocols folder)
        |       |   |──OperationType1
        |       |   |   |──OperationType1.json
        |       |   |   |──OperationType1.rb
        |       |   |   |──OperationType1__cost_model.rb
        |       |   |   |──OperationType1__documentation.rb
        |       |   |   |──OperationType1__precondition.rb
        |       |   |   └──test_data.rb
        |       |   └──LibraryType1
        |       |       |──LibraryType1.rb
        |       |       └──LibraryType1.json
        |       └──OperationType1
        └──SessionEnvironment2
            └── ...
    """

    DEFAULT_METADATA_LOC = os.path.join(
        os.path.dirname(os.path.abspath(__file__)), 'environment_data')
    DEFAULT_METADATA_NAME = 'environment_settings.json'

    def __init__(self, dir, name="FishTank", meta_dir=None, meta_name=None):
        """
        SessionManager constructor

        :param dir: directory
        :type dir: str
        :param name: name of the folder
        :type name: str
        :param meta_dir: directory to store the metadata
        :type meta_dir: str
        :param meta_name: name of the file to store the metadata
        :type meta_name: str
        """
        super().__init__(name, push_up=False, check_attr=False)
        self.set_dir(dir)

        # Add metadata (has default)
        # this is where session manager information will be stored
        if meta_dir is None:
            meta_dir = self.DEFAULT_METADATA_LOC
        if meta_name is None:
            meta_name = self.DEFAULT_METADATA_NAME
        self.metadata = ODir(meta_dir)
        self.metadata.add_file(meta_name, 'env_settings')

        self._curr_session_name = None

    def register_session(self, login, password, aquarium_url, name):
        """
        Registers a new session by creating a AqSession, creating
        a SessionEnvironment and adding it to the SessionManager
        """
        if name in self.sessions:
            logger.warning("'{}' already exists!".format(name))
            return
        key = str.encode(self.__meta['encryption_key'])
        session_env = SessionEnvironment(
            name, login, password, aquarium_url, key)
        self._add_session_env(session_env)

    def remove_session(self, name):
        """
        Removes and deletes a managed session

        :param name: name of the session to delete
        :type name: str
        :return: None
        :rtype: None
        """
        session = self.get(name)
        session.remove_parent()
        session.rmdirs()

    def _add_session_env(self, session_env):
        """Adds the session environment to the session manager"""
        self._add(session_env.name, session_env,
                  push_up=False, check_attr=False)

    @property
    def __meta(self):
        if not self.metadata.env_settings.exists():
            self.save()
        return self.metadata.env_settings.load_json()

    @property
    def current_env(self):
        """Current session environment"""
        if self._curr_session_name is None:
            return None
        return self.get(self._curr_session_name)

    @property
    def current_session(self):
        """Returns the current session"""
        if self._curr_session_name is None:
            return None
        return self.get_session(self._curr_session_name)

    def set_current(self, name):
        """Sets the current session name"""
        if name is None:
            return
        if name in self.sessions:
            self._curr_session_name = name
        else:
            logger.warning("'{}' not in sessions ({})".format(
                name, ', '.join(self.sessions.keys())))

    @property
    def session_env_list(self):
        """Return all session environments"""
        return [env for env in self.list_dirs()
                if isinstance(env, SessionEnvironment)]

    @property
    def sessions(self):
        """Returns all sessions"""
        return {env.name: env.aquarium_session
                for env in self.session_env_list}

    def get_session(self, name):
        """Gets a AqSession by name"""
        session_env = self.get(name)
        return session_env.aquarium_session

    def delete_session(self, name):
        """Deletes a session, removing the folders and files as well as the
        abstract ODir link"""
        session_env = self.get(name)
        session_env.rmdirs()
        session_env.remove_parent()

    def move_repo(self, path):
        """Move all of the folders to a new location"""
        super().mvdirs(path)
        self.save()

    def __new_encryption_key(self):
        return Fernet.generate_key()

    def save(self, force_new_key=False, key=None):
        """Save the metadata"""
        encryption_key = None
        if not self.metadata.env_settings.exists() or force_new_key:
            if key is None:
                logger.warning(
                    "No encryption key found. Generating new key...")
                encryption_key = self.__new_encryption_key().decode()
            else:
                encryption_key = key
        else:
            encryption_key = self.metadata.env_settings.load_json()[
                'encryption_key']
        self.metadata.env_settings.dump_json(
            {
                "root": str(self.abspath),
                'current': self._curr_session_name,
                "updated_at": str(datetime.datetime.now()),
                "version": __version__,
                "encryption_key": encryption_key,
                "container_id": self.get_container_id()
            },
            indent=4)
        self.save_environments()

    def load(self, meta=None):
        """Load from the metadata"""
        if meta is None:
            meta = self.__meta
        if __version__ != meta['version']:
            logger.warning("Version mismatched! Environment data stored using "
                           "ParrotFish version '{}' but currently using '{}'"
                           .format(meta['version'], __version__))

        # load encryption key from meta
        encryption_key = meta['encryption_key']
        env = self.load_environments(encryption_key)
        env.set_current(meta['current'])
        self.save()
        return env

    def save_environments(self):
        """Save all of the session environments"""
        for session_env in self.session_env_list:
            session_env.save_to_pkl()

    def update_encryption_key(self, new_key):
        """
        Updates the encryption key used to decrypt :class:`SessionEnvironment`s
        """
        old_key = self.__meta['encryption_key']
        for session_env in self.session_env_list:
            if session_env:
                session_env.update_encryption_key(old_key, new_key)

    # TODO: consolidate password hashes here
    def load_environments(self, encryption_key):
        """
        Collects the SessionEnvironment pickles and returns a SessionManager
        with these session_environments.

        For examples `dir="User/Documents/Fishtank"` would load a
        SessionManager with the name "Fishtank."
        Environments would be loaded from `User/Documents/FishTank/*/.env_pkl`
        """
        meta = self.__meta
        self.name = os.path.basename(self.metadata.env_settings.name)

        # set root path
        root_dir = os.path.dirname(meta['root'])
        root_name = os.path.basename(meta['root'])
        self.set_dir(root_dir)
        self.name = root_name

        env_pkls = glob(os.path.join(str(self.abspath),
                                     "*", SessionEnvironment.ENV_PKL))
        for env_pkl in env_pkls:
            session_env = SessionEnvironment.load_from_pkl(
                env_pkl, encryption_key)
            if session_env is not None:
                self._add_session_env(session_env)
        self.set_current(meta['current'])
        return self

    def get_container_id(self):
        try:
            with self.metadata.env_settings.open(mode='r') as f:
                settings = json.load(f)
                return settings.get('container_id', '')
        except FileNotFoundError:
            return ''

    def set_container_id(self, cid):
        with self.metadata.env_settings.open(mode='r') as f:
            settings = json.load(f)
            settings['container_id'] = cid
            self.metadata.env_settings.write(json.dumps(settings), 'w')

    def __str__(self):
        return "SessionManager(\n" \
               "  name={name}\n" \
               "  current_session={current}\n" \
               "  environment_location=\"{metadata}\"\n" \
               "  session_directory=\"{dir}\"\n" \
               "  container_id=\"{container_id}\")".format(
                   name=self.name,
                   metadata=str(self.metadata.env_settings.abspath),
                   current=self.current_session,
                   container_id=self.get_container_id(),
                   dir=str(self.abspath)
               )

    def __repr__(self):
        return "SessionManager(name={name}, env={env}".format(
            name=self.name,
            env=str(self.metadata.env_settings.abspath))
Exemplo n.º 15
0
def test_unique_attrs():
    env = ODir('bin')
    with pytest.raises(AttributeError):
        env.add('L1').add('L2')
        env.add('L1a').add('L2')
Exemplo n.º 16
0
def test_chained():

    env = ODir('bin')
    env.add('A1').add('B1')
    env.add('C1').add("D1")
Exemplo n.º 17
0
def test_resolve():
    env = ODir('bin')
    env.add('session1')
    env.session1.add('cat1')
    env.session1.add('cat2')
    print(env.paths.resolve)