# Path: charms/reactive/relations.py
#     def entry_points():
# def endpoint_from_name(endpoint_name):
# def relation_from_name(relation_name):
# def endpoint_from_flag(flag):
# def relation_from_flag(flag):
# def relation_from_state(state):
#     def discover(cls):
#     def get_factory(cls, relation_name):
#     def from_name(cls, relation_name):
#     def from_flag(cls, state):
# def relation_factory(relation_name):
# def _relation_module(role, interface):
# def _find_relation_factory(module):
#     def __new__(cls, name, parents, dct):
#     def _accessor(field):
#         def __accessor(self):
#     def _startup(cls):
#             def depart_conv():
#     def __init__(self, relation_name, conversations=None):
#     def relation_name(self):
#     def from_state(cls, state):
#     def from_flag(cls, flag):
#     def from_name(cls, relation_name, conversations=None):
#     def _find_impl(cls, role, interface):
#     def _find_subclass(cls, module):
#     def conversations(self):
#     def conversation(self, scope=None):
#     def set_state(self, state, scope=None):
#     def remove_state(self, state, scope=None):
#     def is_state(self, state, scope=None):
#     def toggle_state(self, state, active=TOGGLE, scope=None):
#     def set_remote(self, key=None, value=None, data=None, scope=None, **kwdata):
#     def get_remote(self, key, default=None, scope=None):
#     def set_local(self, key=None, value=None, data=None, scope=None, **kwdata):
#     def get_local(self, key, default=None, scope=None):
#     def __init__(self, namespace, units, scope):
#     def _key(cls, namespace, scope):
#     def key(self):
#     def relation_name(self):
#     def relation_ids(self):
#     def join(cls, scope):
#     def depart(self):
#     def deserialize(cls, conversation):
#     def serialize(cls, conversation):
#     def load(cls, keys):
#     def set_state(self, state):
#     def remove_state(self, state):
#     def is_state(self, state):
#     def toggle_state(self, state, active=TOGGLE):
#     def set_remote(self, key=None, value=None, data=None, **kwdata):
#     def get_remote(self, key, default=None):
#     def set_local(self, key=None, value=None, data=None, **kwdata):
#     def get_local(self, key, default=None):
# def _migrate_conversations():  # noqa
# def relation_call(method, relation_name=None, flag=None, state=None, *args):
# ALL = object()
# TOGGLE = object()
#     GLOBAL = 'global'
#     SERVICE = 'service'
#     UNIT = 'unit'
# class RelationFactory(object):
# class scopes(object):
# class AutoAccessors(type):
# class RelationBase(RelationFactory, metaclass=AutoAccessors):
#     class states(StateList):
# class Conversation(object):


import os
import sys
import types
import mock
import unittest
from charmhelpers.core import hookenv
from charms.reactive import relations
        conv = relations.Conversation('rel',
                                      ['srv1/0', 'srv2/0'],
                                      'scope')

        related_units.side_effect = [['srv1/0'], ['srv2/0']]
        relation_get.side_effect = [None, 'value']
        self.assertEqual(conv.get_remote('key', 'default'), 'value')
        self.assertEqual(related_units.call_args_list, [mock.call('rel:1'),
                                                        mock.call('rel:2')])
        self.assertEqual(relation_get.call_args_list,
                         [mock.call('key', 'srv1/0', 'rel:1'),
                          mock.call('key', 'srv2/0', 'rel:2')])

    @mock.patch.object(relations.unitdata, 'kv')
    def test_set_local(self, kv):
        conv = relations.Conversation('rel', ['srv1/0', 'srv2/0', 'srv2/1'], 'scope')
        conv.set_local('foo', 'bar')
        conv.set_local(data={'foo': 'bar'})
        conv.set_local(foo='bar')
        conv.set_local('foo', 'bof', data={'foo': 'bar'}, foo='qux')
        self.assertEqual(kv().update.call_args_list, [
            mock.call({'foo': 'bar'}, prefix='reactive.conversations.rel.scope.local-data.'),
            mock.call({'foo': 'bar'}, prefix='reactive.conversations.rel.scope.local-data.'),
            mock.call({'foo': 'bar'}, prefix='reactive.conversations.rel.scope.local-data.'),
            mock.call({'foo': 'qux'}, prefix='reactive.conversations.rel.scope.local-data.'),
        ])
        kv().update.reset_mock()
        conv.set_local()
        assert not kv().update.called


# Path: charms/reactive/relations.py
#     def entry_points():
# def endpoint_from_name(endpoint_name):
# def relation_from_name(relation_name):
# def endpoint_from_flag(flag):
# def relation_from_flag(flag):
# def relation_from_state(state):
#     def discover(cls):
#     def get_factory(cls, relation_name):
#     def from_name(cls, relation_name):
#     def from_flag(cls, state):
# def relation_factory(relation_name):
# def _relation_module(role, interface):
# def _find_relation_factory(module):
#     def __new__(cls, name, parents, dct):
#     def _accessor(field):
#         def __accessor(self):
#     def _startup(cls):
#             def depart_conv():
#     def __init__(self, relation_name, conversations=None):
#     def relation_name(self):
#     def from_state(cls, state):
#     def from_flag(cls, flag):
#     def from_name(cls, relation_name, conversations=None):
#     def _find_impl(cls, role, interface):
#     def _find_subclass(cls, module):
#     def conversations(self):
#     def conversation(self, scope=None):
#     def set_state(self, state, scope=None):
#     def remove_state(self, state, scope=None):
#     def is_state(self, state, scope=None):
#     def toggle_state(self, state, active=TOGGLE, scope=None):
#     def set_remote(self, key=None, value=None, data=None, scope=None, **kwdata):
#     def get_remote(self, key, default=None, scope=None):
#     def set_local(self, key=None, value=None, data=None, scope=None, **kwdata):
#     def get_local(self, key, default=None, scope=None):
#     def __init__(self, namespace, units, scope):
#     def _key(cls, namespace, scope):
#     def key(self):
#     def relation_name(self):
#     def relation_ids(self):
#     def join(cls, scope):
#     def depart(self):
#     def deserialize(cls, conversation):
#     def serialize(cls, conversation):
#     def load(cls, keys):
#     def set_state(self, state):
#     def remove_state(self, state):
#     def is_state(self, state):
#     def toggle_state(self, state, active=TOGGLE):
#     def set_remote(self, key=None, value=None, data=None, **kwdata):
#     def get_remote(self, key, default=None):
#     def set_local(self, key=None, value=None, data=None, **kwdata):
#     def get_local(self, key, default=None):
# def _migrate_conversations():  # noqa
# def relation_call(method, relation_name=None, flag=None, state=None, *args):
# ALL = object()
# TOGGLE = object()
#     GLOBAL = 'global'
#     SERVICE = 'service'
#     UNIT = 'unit'
# class RelationFactory(object):
# class scopes(object):
# class AutoAccessors(type):
# class RelationBase(RelationFactory, metaclass=AutoAccessors):
#     class states(StateList):
# class Conversation(object):


# Path: tests/test_relations.py
import os
import sys
import types
import mock
import unittest
from charmhelpers.core import hookenv
from charms.reactive import relations

        conv = relations.Conversation('rel',
                                      ['srv1/0', 'srv2/0'],
                                      'scope')

        related_units.side_effect = [['srv1/0'], ['srv2/0']]
        relation_get.side_effect = [None, 'value']
        self.assertEqual(conv.get_remote('key', 'default'), 'value')
        self.assertEqual(related_units.call_args_list, [mock.call('rel:1'),
                                                        mock.call('rel:2')])
        self.assertEqual(relation_get.call_args_list,
                         [mock.call('key', 'srv1/0', 'rel:1'),
                          mock.call('key', 'srv2/0', 'rel:2')])

    @mock.patch.object(relations.unitdata, 'kv')
    def test_set_local(self, kv):
        conv = relations.Conversation('rel', ['srv1/0', 'srv2/0', 'srv2/1'], 'scope')
        conv.set_local('foo', 'bar')
        conv.set_local(data={'foo': 'bar'})
        conv.set_local(foo='bar')
        conv.set_local('foo', 'bof', data={'foo': 'bar'}, foo='qux')
        self.assertEqual(kv().update.call_args_list, [
            mock.call({'foo': 'bar'}, prefix='reactive.conversations.rel.scope.local-data.'),
            mock.call({'foo': 'bar'}, prefix='reactive.conversations.rel.scope.local-data.'),
            mock.call({'foo': 'bar'}, prefix='reactive.conversations.rel.scope.local-data.'),
            mock.call({'foo': 'qux'}, prefix='reactive.conversations.rel.scope.local-data.'),
        ])
        kv().update.reset_mock()
        conv.set_local()
        assert not kv().update.called


    @mock.patch.object(relations.unitdata, 'kv')