示例#1
0
def test_monkey_in_tree():
    """Ask tester to share a folder with this account and ensure that the node is created.

    Note: The share needs to be accepted and added to the account being tested.
    """
    init_storage = init_onedrive()
    input(
        termcolor.colored(
            'Please share a folder called "monkey" to this accout and hit [ENTER]',
            'green',
            attrs=['blink', 'bold']))

    tree = init_storage.storage.model
    monkey = bushn.Node('monkey')

    assert monkey in tree, 'monkeys live in trees.'

    monkey = tree.get_node(['monkey'])
    logger.info(monkey.props)

    # assert some expected props
    assert monkey.props[IS_DIR] is True
    assert monkey.props['_remote_item'] is True
    assert monkey.props[VERSION_ID] == IS_DIR
    assert '_id' in monkey.props

    # test iter_share_roots
    share_roots = list(onedrive.iter_share_roots(init_storage.storage.model))
    assert monkey in share_roots
示例#2
0
def root(request):
    """Create a default Root node

    TODO: Copy pasted during move to jars. Is there a better place?
    :return: Node
    """
    if request.param:
        return bushn.Node(name=None)
    else:
        return bushn.IndexingNode(name=None, indexes=['_id'])
示例#3
0
def test_dropbox_tree_to_sync_engine_adapter_transform_path():
    """Ensure that the custom dropbox adapter properly transforms given paths."""
    root = bushn.Node("root", parent=None, props={'cursor': None})
    adapter = DropboxTreeToSyncEngineAdapter(node=root, sync_engine=None, storage_id='test')

    assert root.parent is None
    assert adapter.transform_path(root) == []

    node_a = bushn.Node("a", parent=root, props={'_path_display_node': 'a', '_id': 'id:1'})
    assert '_path_display_node' in node_a.props

    assert adapter.transform_path(node_a) == ['a']

    node_b = bushn.Node("b", parent=node_a, props={'_path_display_node': 'b', '_id': 'id:2'})
    assert '_path_display_node' in node_b.props
    assert adapter.transform_path(node_b) == ['a', 'b']

    node_c = bushn.Node("c", parent=node_b, props={'_path_display_node': 'c', '_id': 'id:3'})
    assert adapter.transform_path(node_c) == ['a', 'b', 'c']
示例#4
0
def tree_adapter():
    """ simple tree adapter with one node in the root """
    tree_root = bushn.Node(None)
    se_mock = mock.Mock()
    adapter = jars.TreeToSyncEngineEngineAdapter(tree_root,
                                                 se_mock,
                                                 storage_id=TEST_STORAGE_ID)
    with adapter:
        tree_root.add_child('Hello', props=TEST_PROPS)
    return tree_root, se_mock, adapter
示例#5
0
    def get_tree(self, cached=False):
        """This will fetch and return the full tree and its metadata.

        Should return the root node for the tree. This basic implementation will use`get_children`.
        ..Note. get_tree should never modify the storage's state.

        if cached is False, no internal state may be used to create the tree. Else a filtered copy
        of self.model can be returned

        :param cached: whether to use internal state to return tree.
        :param parent: The path from which children are returned.
            If None its done from the root.

        :throws: :class:`InvalidOperationError` if no subtree with parent exists.
        :throws: :class:`CurrentlyNotPossibleError` if operation can currently not be
            executed.
        :throws: :class:`UnavailableError` if storage is not reachable.
        :throws: :class:`AuthenticationError` if storage is not authenticated properly.
        :throws: :class:`SevereError` if storage is not valid.
        :returns: :class:`bushn.Node` object
        """
        # pylint:disable=unused-argument

        root = bushn.Node(name=None)

        working_stack = [root]

        while working_stack:
            parent = working_stack.pop()
            try:
                # children_to_add [(recurse, child)]
                filter_node = self.filter_tree.get_node(parent.path)

                # if we have a filter node see if it has children, if yes, only deliver
                # non-dirs if children is set to true
                if filter_node.children:
                    children_to_add = \
                        [(child, True)
                         for child in self.get_tree_children(parent.path)
                         if not child[1]['is_dir'] or filter_node.has_child(child[0])]
                else:
                    # it has no children just recurse
                    children_to_add = \
                        [(child, True) for child in self.get_tree_children(parent.path)]
            except KeyError:
                children_to_add = \
                    [(child, True) for child in self.get_tree_children(parent.path)]

            for (name, props), recurse in children_to_add:
                child = parent.add_child(name, props)

                if props.get('is_dir') and recurse:
                    working_stack.append(child)

        return root
示例#6
0
def base_tree():
    """Simple tree with 4 nodes.

    a
    +-b
    +-a
    c
    """
    tree = bushn.Node(None)
    a_node = tree.add_child('a', props={'_inode': 'a_node'})
    c_node = tree.add_child('c', props={'_inode': 'c_node'})

    a_node.add_child('b', props={'_inode': 'b_node'})
    a_node.add_child('a', props={'_inode': 'aa_node'})

    logger.info('base_tree fixture\n%s',
                bushn.tree_to_str(tree, prop_key='_inode'))
    return tree
示例#7
0
    def __init__(self,
                 event_sink,
                 storage_id,
                 storage_cache_dir=None,
                 storage_cache_version=None,
                 default_model=None):
        """ :param event_sink: In productive use this is the SyncEngine. Might be any
         other class implementing the event handling methods.
        :param storage_id: The storage_id of this storage.
        :param storage_cache_dir the directory to store model caches in
        :param storage_cache_version the version of the storage cache to load (older
        versions will be ignored if present = new model with new version will be generated
        :raise bushn.AuthenticationError in case the authentication data is wrong
        :raise
        """
        # settig storage id and events sink
        self.storage_id = storage_id
        self._event_sink = event_sink

        # The display name for the user, if available a username should be displayed, otherwise
        # default to email address.
        self._storage_user_name = None

        # setting cache dir (will be used to store model caches)
        self.cache_dir = storage_cache_dir

        # None permutable default model
        if default_model is None:
            default_model = Node(name=None)

        # read model cache if present and set it as internal model -> if no model is
        # present: generate new nodel using default node passed (e.g. Node,
        # or IndexedNode) dependent on what the specific service needs
        self.tree = load_model(cache_dir=self.cache_dir,
                               default=default_model,
                               version=storage_cache_version)

        # private member for offline handling
        # DO NOT ACCESS DIRECTLY - use self.offline instead
        self._offline = False

        # directories to sync
        self.filter_tree = bushn.Node(name=None)
示例#8
0
    def __init__(self, event_sink, storage_id, storage_cache_dir,
                 storage_cred_reader, storage_cred_writer, polling_interval=30):
        # pylint: disable=too-many-arguments,unused-argument

        # getting credentials from store
        self._credentials = json.loads(storage_cred_reader())

        super(CifsFileSystem, self).__init__(self._credentials['unc_path'],
                                             event_sink,
                                             storage_id)

        try:
            net_use(self._credentials)
        except WindowsError:
            self._offline = False
            logger.debug('Cant access windows share at the moment', exc_info=True)

        self.storage_cache_dir = storage_cache_dir
        self._event_sink = ModelUpdatingEventSink(
            next_event_sync=self._event_sink,
            root_node=jars.load_model(storage_cache_dir,
                                      bushn.Node(None)))
示例#9
0
def test_on_shared_state_changed(encryption_wrapper_mock, mocker):
    """check for issue CC-409.

    The bug was that it propagated the wrong properties for the children of a node
    """

    mocker.patch('cc.encryption.storage_wrapper.get_key_subjects',
                 return_value=('abc', ))

    new_props = {
        'c': {
            'version_id': 'is_dir',
            'share_id': 1
        },
        FILESYSTEM_ID: {
            'version_id': 'is_dir',
            'is_dir': True
        }
    }

    new_props_child = {
        'c': {
            'version_id': 123,
            'share_id': 1
        },
        FILESYSTEM_ID: {
            'version_id': 123
        }
    }

    sender = mock.Mock()
    sender.root_node = bushn.Node(name=None)
    changed_node = sender.root_node.add_child('a', {STORAGE: new_props})

    changed_node.add_child('xyz', {STORAGE: new_props_child})
    sender.query_shared_state = mock.Mock(return_value=('v', 1, None))

    encryption_wrapper_mock.on_shared_state_changed(
        sender,
        old_props={STORAGE: {
            'c': {
                'version_id': 'is_dir'
            }
        }},
        node=changed_node,
        storage_id='c')

    new_props_with_enc_tag = deepcopy(new_props[FILESYSTEM_ID])
    new_props_with_enc_tag['version_id'] = EncryptedVersionTag(
        version_id='is_dir', key_subjects=('abc', ))
    new_props_with_enc_tag_child = deepcopy(new_props_child[FILESYSTEM_ID])
    new_props_with_enc_tag_child['version_id'] = EncryptedVersionTag(
        version_id=123, key_subjects=('abc', ))

    expected = [
        mock.call(storage_id=FILESYSTEM_ID,
                  path=['a'],
                  event_props=new_props_with_enc_tag),
        mock.call(storage_id=FILESYSTEM_ID,
                  path=['a', 'xyz'],
                  event_props=new_props_with_enc_tag_child)
    ]

    encryption_wrapper_mock._syncengine.storage_modify.has_calls(
        expected, any_order=True)