Example #1
0
    def test_input_dict_type(self):
        sample_meta_dir = self.make_resource_meta("""
id: sample
handler: ansible
version: 1.0.0
input:
  values:
    schema: {a: int, b: int}
    value: {}
        """)

        sample1 = self.create_resource('sample1', sample_meta_dir, {'values':
                                                                    {'a': 1,
                                                                     'b': 2}})
        sample2 = self.create_resource('sample2', sample_meta_dir)
        xs.connect(sample1, sample2)
        self.assertEqual(sample1.args['values'], sample2.args['values'])

        # Check update
        sample1.update({'values': {'a': 2}})
        self.assertEqual(sample1.args['values'], {'a': 2})
        self.assertEqual(sample1.args['values'], sample2.args['values'], )

        # Check disconnect
        # TODO: should sample2.value be reverted to original value?
        sample1.disconnect(sample2)
        sample1.update({'values': {'a': 3}})
        self.assertEqual(sample1.args['values'], {'a': 3})
Example #2
0
    def test_hash_input_with_multiple_connections(self):
        sample_meta_dir = self.make_resource_meta("""
id: sample
handler: ansible
version: 1.0.0
input:
    ip:
        schema: str!
        value:
        """)
        receiver_meta_dir = self.make_resource_meta("""
id: receiver
handler: ansible
version: 1.0.0
input:
    ip:
        schema: str!
        value:
    server:
        schema: {ip: str!}
        """)

        sample = self.create_resource('sample',
                                      sample_meta_dir,
                                      args={'ip': '10.0.0.1'})
        receiver = self.create_resource('receiver', receiver_meta_dir)
        xs.connect(sample, receiver, mapping={'ip': ['ip', 'server:ip']})
        self.assertEqual(sample.args['ip'], receiver.args['ip'])
        self.assertDictEqual(
            {'ip': sample.args['ip']},
            receiver.args['server'],
        )
Example #3
0
def setup_resources():
    ModelMeta.remove_all()

    node2 = vr.create('node2', 'resources/ro_node/', {
        'ip': '10.0.0.4',
        'ssh_key': '/vagrant/.vagrant/machines/solar-dev2/virtualbox/private_key',
        'ssh_user': '******'
    })[0]

    solar_bootstrap2 = vr.create('solar_bootstrap2', 'resources/solar_bootstrap', {'master_ip': '10.0.0.2'})[0]

    signals.connect(node2, solar_bootstrap2)

    has_errors = False
    for r in locals().values():
        if not isinstance(r, resource.Resource):
            continue

        print 'Validating {}'.format(r.name)
        errors = validation.validate_resource(r)
        if errors:
            has_errors = True
            print 'ERROR: %s: %s' % (r.name, errors)

    if has_errors:
        sys.exit(1)
Example #4
0
def deploy(filename):
    with open(filename) as f:
        config = yaml.load(f)

    workdir = config['workdir']
    resource_save_path = os.path.join(workdir, config['resource-save-path'])

    # Clean stuff first
    db.clear()
    xs.Connections.clear()
    shutil.rmtree(resource_save_path, ignore_errors=True)
    os.makedirs(resource_save_path)

    # Create resources first
    for resource_definition in config['resources']:
        name = resource_definition['name']
        model = os.path.join(workdir, resource_definition['model'])
        args = resource_definition.get('args', {})
        log.debug('Creating %s %s %s %s', name, model, resource_save_path, args)
        xr.create(name, model, resource_save_path, args=args)

    # Create resource connections
    for connection in config['connections']:
        emitter = db.get_resource(connection['emitter'])
        receiver = db.get_resource(connection['receiver'])
        mapping = connection.get('mapping')
        log.debug('Connecting %s %s %s', emitter.name, receiver.name, mapping)
        xs.connect(emitter, receiver, mapping=mapping)

    # Run all tests
    if 'test-suite' in config:
        log.debug('Running tests from %s', config['test-suite'])
        test_suite = __import__(config['test-suite'], {}, {}, ['main'])
        test_suite.main()
Example #5
0
def create_virtual_resource(vr_name, template):
    resources = template["resources"]
    connections = []
    created_resources = []

    cwd = os.getcwd()
    for resource in resources:
        name = resource["id"]
        base_path = os.path.join(cwd, resource["from"])
        args = resource["values"]
        new_resources = create(name, base_path, args, vr_name)
        created_resources += new_resources

        if not is_virtual(base_path):
            for key, arg in args.items():
                if isinstance(arg, basestring) and "::" in arg:
                    emitter, src = arg.split("::")
                    connections.append((emitter, name, {src: key}))

        db = load_all()
        for emitter, reciver, mapping in connections:
            emitter = db[emitter]
            reciver = db[reciver]
            signals.connect(emitter, reciver, mapping)

    return created_resources
Example #6
0
def setup_resources():
    ModelMeta.remove_all()

    node2 = vr.create(
        'node2', 'resources/ro_node/', {
            'ip': '10.0.0.4',
            'ssh_key':
            '/vagrant/.vagrant/machines/solar-dev2/virtualbox/private_key',
            'ssh_user': '******'
        })[0]

    solar_bootstrap2 = vr.create('solar_bootstrap2',
                                 'resources/solar_bootstrap',
                                 {'master_ip': '10.0.0.2'})[0]

    signals.connect(node2, solar_bootstrap2)

    has_errors = False
    for r in locals().values():
        if not isinstance(r, resource.Resource):
            continue

        print 'Validating {}'.format(r.name)
        errors = validation.validate_resource(r)
        if errors:
            has_errors = True
            print 'ERROR: %s: %s' % (r.name, errors)

    if has_errors:
        sys.exit(1)
Example #7
0
def test_revert_removed_child():
    res1 = orm.DBResource(id='test1', name='test1', base_path='x')
    res1.save()
    res1.add_input('a', 'str', '9')

    res2 = orm.DBResource(id='test2', name='test2', base_path='x')
    res2.save()
    res2.add_input('a', 'str', 0)

    res1 = resource.load('test1')
    res2 = resource.load('test2')
    signals.connect(res1, res2)

    staged_log = change.stage_changes()
    assert len(staged_log) == 2
    for item in staged_log:
        operations.move_to_commited(item.log_action)
    res2.remove()

    staged_log = change.stage_changes()
    assert len(staged_log) == 1
    logitem = next(staged_log.collection())
    operations.move_to_commited(logitem.log_action)

    with mock.patch.object(resource, 'read_meta') as mread:
        mread.return_value = {'input': {'a': {'schema': 'str!'}}}
        change.revert(logitem.uid)

    res2 = resource.load('test2')
    assert res2.args == {'a': '9'}
Example #8
0
    def test_simple_observer_unsubscription(self):
        sample_meta_dir = self.make_resource_meta("""
id: sample
handler: ansible
version: 1.0.0
input:
  ip:
    schema: str
    value:
        """)

        sample = self.create_resource('sample', sample_meta_dir, {'ip': None})
        sample1 = self.create_resource('sample1', sample_meta_dir,
                                       {'ip': '10.0.0.1'})
        sample2 = self.create_resource('sample2', sample_meta_dir,
                                       {'ip': '10.0.0.2'})

        xs.connect(sample1, sample)
        self.assertEqual(sample1.args['ip'], sample.args['ip'])
        #self.assertEqual(len(list(sample1.args['ip'].receivers)), 1)
        #self.assertEqual(
        #    sample.args['ip'].emitter,
        #    sample1.args['ip']
        #)

        xs.connect(sample2, sample)
        self.assertEqual(sample2.args['ip'], sample.args['ip'])
        # sample should be unsubscribed from sample1 and subscribed to sample2
        #self.assertEqual(len(list(sample1.args['ip'].receivers)), 0)
        #self.assertEqual(sample.args['ip'].emitter, sample2.args['ip'])

        sample2.update({'ip': '10.0.0.3'})
        self.assertEqual(sample2.args['ip'], sample.args['ip'])
Example #9
0
 def connect_with_events(self, receiver, mapping=None, events=None,
         use_defaults=False):
     signals.connect(self, receiver, mapping=mapping)
     if use_defaults:
         api.add_default_events(self, receiver)
     if events:
         api.add_events(self.name, events)
Example #10
0
def prepare_nodes(nodes_count):
    resources = vr.create("nodes", "templates/nodes_with_transports.yaml", {"count": nodes_count})
    nodes = [x for x in resources if x.name.startswith("node")]
    resources = vr.create("nodes_network", "templates/nodes_network.yaml", {"count": nodes_count})
    nodes_sdn = [x for x in resources if x.name.startswith("node")]
    r = {}

    for node, node_sdn in zip(nodes, nodes_sdn):
        r[node.name] = node
        r[node_sdn.name] = node_sdn

        # LIBRARIAN
        librarian = vr.create("librarian_{}".format(node.name), "resources/librarian", {})[0]
        r[librarian.name] = librarian

        node.connect(librarian, {})

        # NETWORKING
        # TODO(bogdando) node's IPs should be populated as br-mgmt IPs, but now are hardcoded in templates
        signals.connect(node, node_sdn)
        node_sdn.connect_with_events(librarian, {"module": "modules"}, {})
        evapi.add_dep(librarian.name, node_sdn.name, actions=("run", "update"))

        signals.connect(node, node_sdn)
        node_sdn.connect_with_events(librarian, {"module": "modules"}, {})
        evapi.add_dep(librarian.name, node_sdn.name, actions=("run", "update"))

    return r
Example #11
0
    def test_hash_input_with_multiple_connections(self):
        sample_meta_dir = self.make_resource_meta("""
id: sample
handler: ansible
version: 1.0.0
input:
    ip:
        schema: str!
        value:
        """)
        receiver_meta_dir = self.make_resource_meta("""
id: receiver
handler: ansible
version: 1.0.0
input:
    ip:
        schema: str!
        value:
    server:
        schema: {ip: str!}
        """)

        sample = self.create_resource('sample',
                                      sample_meta_dir,
                                      args={'ip': '10.0.0.1'})
        receiver = self.create_resource('receiver', receiver_meta_dir)
        xs.connect(sample, receiver, mapping={'ip': ['ip', 'server:ip']})
        self.assertEqual(sample.args['ip'], receiver.args['ip'])
        self.assertDictEqual({'ip': sample.args['ip']},
                             receiver.args['server'], )
Example #12
0
    def test_removal(self):
        """Test that connection removed with resource."""
        sample_meta_dir = self.make_resource_meta("""
id: sample
handler: ansible
version: 1.0.0
input:
  value:
    schema: int
    value: 0
        """)

        sample1 = self.create_resource(
            'sample1', sample_meta_dir, {'value': 1}
        )
        sample2 = self.create_resource(
            'sample2', sample_meta_dir, {}
        )
        signals.connect(sample1, sample2)
        self.assertEqual(sample1.args['value'], sample2.args['value'])

        sample1 = resource.load('sample1')
        sample2 = resource.load('sample2')
        sample1.delete()
        self.assertEqual(sample2.args['value'], 0)
Example #13
0
def test_revert_removed_child():
    res1 = orm.DBResource(id="test1", name="test1", base_path="x")  # NOQA
    res1.save()
    res1.add_input("a", "str", "9")

    res2 = orm.DBResource(id="test2", name="test2", base_path="x")  # NOQA
    res2.save()
    res2.add_input("a", "str", 0)

    res1 = resource.load("test1")
    res2 = resource.load("test2")
    signals.connect(res1, res2)

    staged_log = change.stage_changes()
    assert len(staged_log) == 2
    for item in staged_log:
        operations.move_to_commited(item.log_action)
    res2.remove()

    staged_log = change.stage_changes()
    assert len(staged_log) == 1
    logitem = next(staged_log.collection())
    operations.move_to_commited(logitem.log_action)

    with mock.patch.object(resource, "read_meta") as mread:
        mread.return_value = {"input": {"a": {"schema": "str!"}}}
        change.revert(logitem.uid)

    res2 = resource.load("test2")
    assert res2.args == {"a": "9"}
Example #14
0
    def connect_list_to_each(self, resources, mapping=None, events=None):
        """Connect each resource in self.resources to each resource in resources.

        mapping -- optional mapping
          "{emitter_num}" -- substitutes for emitter's index in mapping (from
            self.resources)
          "{receiver_num}" -- substitutes for receiver's index in mapping (from
            resources argument)
        """
        mapping = mapping or {}

        for emitter_num, emitter in enumerate(self.resources):
            for receiver_num, receiver in enumerate(resources.resources):
                kwargs = {
                    'emitter_num': emitter_num,
                    'receiver_num': receiver_num,
                }

                mapping_fmt = self.args_fmt(mapping, kwargs)

                signals.connect(
                    emitter,
                    receiver,
                    mapping=mapping_fmt,
                    events=events
                )
Example #15
0
def prepare_nodes(nodes_count):
    resources = vr.create('nodes', 'templates/nodes_with_transports.yaml',
                          {"count": nodes_count})
    nodes = [x for x in resources if x.name.startswith('node')]
    resources = vr.create('nodes_network', 'templates/nodes_network.yaml',
                          {"count": nodes_count})
    nodes_sdn = [x for x in resources if x.name.startswith('node')]
    r = {}

    for node, node_sdn in zip(nodes, nodes_sdn):
        r[node.name] = node
        r[node_sdn.name] = node_sdn

        # LIBRARIAN
        librarian = vr.create('librarian_{}'.format(node.name),
                              'resources/librarian', {})[0]
        r[librarian.name] = librarian

        node.connect(librarian, {})

        # NETWORKING
        # TODO(bogdando) node's IPs should be populated as br-mgmt IPs, but now are hardcoded in templates
        signals.connect(node, node_sdn)
        node_sdn.connect_with_events(librarian, {'module': 'modules'}, {})
        evapi.add_dep(librarian.name, node_sdn.name, actions=('run', 'update'))

        signals.connect(node, node_sdn)
        node_sdn.connect_with_events(librarian, {'module': 'modules'}, {})
        evapi.add_dep(librarian.name, node_sdn.name, actions=('run', 'update'))

    return r
Example #16
0
def prepare_nodes(nodes_count):
    resources = cr.create('nodes', 'templates/nodes', {"count": nodes_count})
    nodes = resources.like('node')
    resources = cr.create('nodes_network', 'templates/nodes_network', {"count": nodes_count})
    nodes_sdn = resources.like('node')
    r = {}

    for node, node_sdn in zip(nodes, nodes_sdn):
        r[node.name] = node
        r[node_sdn.name] = node_sdn

        # LIBRARIAN
        librarian = cr.create('librarian_{}'.format(node.name), 'resources/librarian', {})[0]
        r[librarian.name] = librarian

        node.connect(librarian, {})

        # NETWORKING
        # TODO(bogdando) node's IPs should be populated as br-mgmt IPs, but now are hardcoded in templates
        signals.connect(node, node_sdn)
        node_sdn.connect_with_events(librarian, {'module': 'modules'}, {})
        evapi.add_dep(librarian.name, node_sdn.name, actions=('run', 'update'))

        signals.connect(node, node_sdn)
        node_sdn.connect_with_events(librarian, {'module': 'modules'}, {})
        evapi.add_dep(librarian.name, node_sdn.name, actions=('run', 'update'))

    return r
Example #17
0
    def connect_list_to_each(self, resources, mapping=None, events=None):
        """Connect resources

        Connect each resource in self.resources to each resource in
        resources.

        mapping -- optional mapping
          "{emitter_num}" -- substitutes for emitter's index in mapping (from
            self.resources)
          "{receiver_num}" -- substitutes for receiver's index in mapping (from
            resources argument)
        """
        mapping = mapping or {}

        for emitter_num, emitter in enumerate(self.resources):
            for receiver_num, receiver in enumerate(resources.resources):
                kwargs = {
                    'emitter_num': emitter_num,
                    'receiver_num': receiver_num,
                }

                mapping_fmt = self.args_fmt(mapping, kwargs)

                signals.connect(emitter,
                                receiver,
                                mapping=mapping_fmt,
                                events=events)
Example #18
0
    def test_no_cycles(self):
        sample_meta_dir = self.make_resource_meta("""
id: sample
handler: ansible
version: 1.0.0
input:
  value:
    schema: str!
    value:
        """)

        sample1 = self.create_resource(
            'sample1', sample_meta_dir, {'value': 'x'}
        )

        sample2 = self.create_resource(
            'sample2', sample_meta_dir, {'value': 'y'}
        )

        xs.connect(sample1, sample2)

        with self.assertRaisesRegexp(
                Exception,
                'Prevented creating a cycle'):
            xs.connect(sample2, sample1)
Example #19
0
    def connect_list_to_each(self, resources, args={}, events=None):
        """Connect each resource in self.resources to each resource in resources.

        args -- optional list of arguments
          "{emitter_num}" -- substitutes for emitter's index in args (from
            self.resources)
          "{receiver_num}" -- substitutes for receiver's index in args (from
            resources argument)
        """

        for emitter_num, emitter in enumerate(self.resources):
            for receiver_num, receiver in enumerate(resources.resources):
                kwargs = {
                    'emitter_num': emitter_num,
                    'receiver_num': receiver_num,
                }

                args_fmt = self.args_fmt(args, kwargs)

                signals.connect(
                    emitter,
                    receiver,
                    mapping=args_fmt,
                    events=events
                )
Example #20
0
def test_revert_removed_child():
    res1 = orm.DBResource(id='test1', name='test1', base_path='x')  # NOQA
    res1.save()
    res1.add_input('a', 'str', '9')

    res2 = orm.DBResource(id='test2', name='test2', base_path='x')  # NOQA
    res2.save()
    res2.add_input('a', 'str', 0)

    res1 = resource.load('test1')
    res2 = resource.load('test2')
    signals.connect(res1, res2)

    staged_log = change.stage_changes()
    assert len(staged_log) == 2
    for item in staged_log:
        operations.move_to_commited(item.log_action)
    res2.remove()

    staged_log = change.stage_changes()
    assert len(staged_log) == 1
    logitem = next(staged_log.collection())
    operations.move_to_commited(logitem.log_action)

    with mock.patch.object(resource, 'read_meta') as mread:
        mread.return_value = {'input': {'a': {'schema': 'str!'}}}
        change.revert(logitem.uid)

    res2 = resource.load('test2')
    assert res2.args == {'a': '9'}
Example #21
0
    def test_input_dict_type(self):
        sample_meta_dir = self.make_resource_meta("""
id: sample
handler: ansible
version: 1.0.0
input:
  values:
    schema: {a: int, b: int}
    value: {}
        """)

        sample1 = self.create_resource('sample1', sample_meta_dir,
                                       {'values': {
                                           'a': 1,
                                           'b': 2
                                       }})
        sample2 = self.create_resource('sample2', sample_meta_dir)
        xs.connect(sample1, sample2)
        self.assertEqual(sample1.args['values'], sample2.args['values'])

        # Check update
        sample1.update({'values': {'a': 2}})
        self.assertEqual(sample1.args['values'], {'a': 2})
        self.assertEqual(
            sample1.args['values'],
            sample2.args['values'],
        )

        # Check disconnect
        # TODO: should sample2.value be reverted to original value?
        xs.disconnect(sample1, sample2)
        sample1.update({'values': {'a': 3}})
        self.assertEqual(sample1.args['values'], {'a': 3})
Example #22
0
    def test_simple_observer_unsubscription(self):
        sample_meta_dir = self.make_resource_meta("""
id: sample
handler: ansible
version: 1.0.0
input:
  ip:
    schema: str
    value:
        """)

        sample = self.create_resource('sample', sample_meta_dir, {'ip': None})
        sample1 = self.create_resource('sample1', sample_meta_dir,
                                       {'ip': '10.0.0.1'})
        sample2 = self.create_resource('sample2', sample_meta_dir,
                                       {'ip': '10.0.0.2'})

        xs.connect(sample1, sample)
        self.assertEqual(sample1.args['ip'], sample.args['ip'])

        xs.connect(sample2, sample)
        self.assertEqual(sample2.args['ip'], sample.args['ip'])
        # sample should be unsubscribed from sample1 and subscribed to sample2

        sample2.update({'ip': '10.0.0.3'})
        self.assertEqual(sample2.args['ip'], sample.args['ip'])
Example #23
0
    def test_hash_input_with_list(self):
        sample_meta_dir = self.make_resource_meta("""
id: sample
handler: ansible
version: 1.0.0
input:
    ip:
        schema: str!
        value:
    port:
        schema: int!
        value:
        """)
        receiver_meta_dir = self.make_resource_meta("""
id: receiver
handler: ansible
version: 1.0.0
input:
    server:
        schema: [{ip: str!, port: int!}]
        """)

        sample1 = self.create_resource('sample1',
                                       sample_meta_dir,
                                       args={'ip': '10.0.0.1',
                                             'port': 5000})
        receiver = self.create_resource('receiver', receiver_meta_dir)
        xs.connect(sample1,
                   receiver,
                   mapping={
                       'ip': 'server:ip',
                       'port': 'server:port'
                   })
        self.assertItemsEqual(
            [{'ip': sample1.args['ip'],
              'port': sample1.args['port']}],
            receiver.args['server'], )
        sample2 = self.create_resource('sample2',
                                       sample_meta_dir,
                                       args={'ip': '10.0.0.2',
                                             'port': 5001})
        xs.connect(sample2,
                   receiver,
                   mapping={
                       'ip': 'server:ip',
                       'port': 'server:port'
                   })
        self.assertItemsEqual(
            [{'ip': sample1.args['ip'],
              'port': sample1.args['port']}, {'ip': sample2.args['ip'],
                                              'port': sample2.args['port']}],
            receiver.args['server'], )
        sample1.disconnect(receiver)
        self.assertItemsEqual(
            [{'ip': sample2.args['ip'],
              'port': sample2.args['port']}],
            receiver.args['server'], )
Example #24
0
 def creating_process():
     sample1 = self.create_resource('sample1', sample_meta_dir,
                                    {'value': 1})
     sample2 = self.create_resource(
         'sample2',
         sample_meta_dir,
     )
     signals.connect(sample1, sample2)
     self.assertEqual(sample1.args['value'], sample2.args['value'])
Example #25
0
 def creating_process():
     sample1 = self.create_resource(
         'sample1', sample_meta_dir, {'value': 1}
     )
     sample2 = self.create_resource(
         'sample2', sample_meta_dir, {}
     )
     signals.connect(sample1, sample2)
     self.assertEqual(sample1.args['value'], sample2.args['value'])
Example #26
0
 def connect_with_events(self,
                         receiver,
                         mapping=None,
                         events=None,
                         use_defaults=False):
     signals.connect(self, receiver, mapping=mapping)
     if use_defaults:
         api.add_default_events(self, receiver)
     if events:
         api.add_events(self.name, events)
Example #27
0
def _revert_remove(logitem):
    """Resource should be created with all previous connections
    """
    commited = orm.DBCommitedState.load(logitem.res)
    args = dictdiffer.revert(logitem.diff, commited.inputs)
    connections = dictdiffer.revert(logitem.signals_diff, sorted(commited.connections))
    resource.Resource(logitem.res, logitem.base_path, args=args, tags=commited.tags)
    for emitter, emitter_input, receiver, receiver_input in connections:
        emmiter_obj = resource.load(emitter)
        receiver_obj = resource.load(receiver)
        signals.connect(emmiter_obj, receiver_obj, {emitter_input: receiver_input})
Example #28
0
def update_inputs(child, args):
    child = load_resource(child)
    connections, assignments = parse_inputs(args)
    for c in connections:
        mapping = {}
        parent = load_resource(c['parent'])
        events = c['events']
        mapping[c['parent_input']] = c['child_input']
        signals.connect(parent, child, mapping, events)

    child.update(assignments)
Example #29
0
    def on_each(self, resource_path, args=None):
        """Create resource form resource_path on each resource."""
        args = args or {}

        created_resources = ResourceListTemplate.create(len(self.resources),
                                                        resource_path,
                                                        args=args)

        for i, resource in enumerate(self.resources):
            signals.connect(resource, created_resources.resources[i])

        return created_resources
Example #30
0
    def test_multiple_resource_disjoint_connect(self):
        sample_meta_dir = self.make_resource_meta("""
id: sample
handler: ansible
version: 1.0.0
input:
  ip:
    schema: string
    value:
  port:
    schema: int
    value:
        """)
        sample_ip_meta_dir = self.make_resource_meta("""
id: sample-ip
handler: ansible
version: 1.0.0
input:
  ip:
    schema: string
    value:
        """)
        sample_port_meta_dir = self.make_resource_meta("""
id: sample-port
handler: ansible
version: 1.0.0
input:
  port:
    schema: int
    value:
        """)

        sample = self.create_resource(
            'sample', sample_meta_dir, {'ip': None, 'port': None}
        )
        sample_ip = self.create_resource(
            'sample-ip', sample_ip_meta_dir, {'ip': '10.0.0.1'}
        )
        sample_port = self.create_resource(
            'sample-port', sample_port_meta_dir, {'port': '8000'}
        )
        xs.connect(sample_ip, sample)
        xs.connect(sample_port, sample)
        self.assertEqual(sample.args['ip'], sample_ip.args['ip'])
        self.assertEqual(sample.args['port'], sample_port.args['port'])
        self.assertEqual(
            sample.args['ip'].emitter,
            sample_ip.args['ip']
        )
        self.assertEqual(
            sample.args['port'].emitter,
            sample_port.args['port']
        )
Example #31
0
    def test_backtrack_list(self):
        sample_meta_dir = self.make_resource_meta("""
id: sample
handler: ansible
version: 1.0.0
input:
  value:
    schema: str!
    value:
        """)
        sample_list_meta_dir = self.make_resource_meta("""
id: sample_list
handler: ansible
version: 1.0.0
input:
  values:
    schema: [str!]
    value:
        """)

        sample_list = self.create_resource(
            'sample_list', sample_list_meta_dir
        )
        vi = sample_list.resource_inputs()['values']
        sample1 = self.create_resource(
            'sample1', sample_meta_dir, {'value': 'x'}
        )
        sample2 = self.create_resource(
            'sample2', sample_meta_dir, {'value': 'y'}
        )
        sample3 = self.create_resource(
            'sample3', sample_meta_dir, {'value': 'z'}
        )
        self.assertEqual(vi.backtrack_value_emitter(), vi)

        # [sample1] -> sample_list
        signals.connect(sample1, sample_list, {'value': 'values'})
        self.assertEqual(vi.backtrack_value_emitter(),
                         [sample1.resource_inputs()['value']])

        # [sample3, sample1] -> sample_list
        signals.connect(sample3, sample_list, {'value': 'values'})
        self.assertSetEqual(set(vi.backtrack_value_emitter()),
                            set([sample1.resource_inputs()['value'],
                                 sample3.resource_inputs()['value']]))

        # sample2 disconnected
        signals.disconnect(sample1, sample_list)
        self.assertEqual(vi.backtrack_value_emitter(),
                         [sample3.resource_inputs()['value']])
Example #32
0
def run():
    db.clear()

    resources = vr.create('nodes', 'templates/nodes_with_transports.yaml', {'count': 2})
    nodes = [x for x in resources if x.name.startswith('node')]
    node1, node2 = nodes

    hosts1 = vr.create('hosts_file1', 'resources/hosts_file', {})[0]
    hosts2 = vr.create('hosts_file2', 'resources/hosts_file', {})[0]
    signals.connect(node1, hosts1, {
        'name': 'hosts:name',
        'ip': 'hosts:ip',
    })

    signals.connect(node2, hosts2, {
        'name': 'hosts:name',
        'ip': 'hosts:ip',
    })

    signals.connect(node1, hosts2, {
        'name': 'hosts:name',
        'ip': 'hosts:ip',
    })

    signals.connect(node2, hosts1, {
        'name': 'hosts:name',
        'ip': 'hosts:ip',
    })
Example #33
0
    def test_backtrack_list(self):
        sample_meta_dir = self.make_resource_meta("""
id: sample
handler: ansible
version: 1.0.0
input:
  value:
    schema: str!
    value:
        """)
        sample_list_meta_dir = self.make_resource_meta("""
id: sample_list
handler: ansible
version: 1.0.0
input:
  values:
    schema: [str!]
    value:
        """)

        sample_list = self.create_resource(
            'sample_list', sample_list_meta_dir
        )
        vi = sample_list.resource_inputs()['values']
        sample1 = self.create_resource(
            'sample1', sample_meta_dir, {'value': 'x'}
        )
        sample2 = self.create_resource(
            'sample2', sample_meta_dir, {'value': 'y'}
        )
        sample3 = self.create_resource(
            'sample3', sample_meta_dir, {'value': 'z'}
        )
        self.assertEqual(vi.backtrack_value_emitter(), vi)

        # [sample1] -> sample_list
        signals.connect(sample1, sample_list, {'value': 'values'})
        self.assertEqual(vi.backtrack_value_emitter(),
                         [sample1.resource_inputs()['value']])

        # [sample3, sample1] -> sample_list
        signals.connect(sample3, sample_list, {'value': 'values'})
        self.assertSetEqual(set(vi.backtrack_value_emitter()),
                            set([sample1.resource_inputs()['value'],
                                 sample3.resource_inputs()['value']]))

        # sample2 disconnected
        signals.disconnect(sample1, sample_list)
        self.assertEqual(vi.backtrack_value_emitter(),
                         [sample3.resource_inputs()['value']])
Example #34
0
    def on_each(self, resource_path, args=None):
        """Create resource form resource_path on each resource."""
        args = args or {}

        created_resources = ResourceListTemplate.create(
            len(self.resources),
            resource_path,
            args=args
        )

        for i, resource in enumerate(self.resources):
            signals.connect(resource, created_resources.resources[i])

        return created_resources
Example #35
0
    def test_hash_input_mixed(self):
        sample_meta_dir = self.make_resource_meta("""
id: sample
handler: ansible
version: 1.0.0
input:
    ip:
        schema: str!
        value:
    port:
        schema: int!
        value:
        """)
        receiver_meta_dir = self.make_resource_meta("""
id: receiver
handler: ansible
version: 1.0.0
input:
    server:
        schema: {ip: str!, port: int!}
        """)

        sample = self.create_resource('sample',
                                      sample_meta_dir,
                                      args={
                                          'ip': '10.0.0.1',
                                          'port': 5000
                                      })
        receiver = self.create_resource('receiver',
                                        receiver_meta_dir,
                                        args={'server': {
                                            'port': 5001
                                        }})
        xs.connect(sample, receiver, mapping={'ip': 'server:ip'})
        self.assertDictEqual(
            {
                'ip': sample.args['ip'],
                'port': 5001
            },
            receiver.args['server'],
        )
        sample.update({'ip': '10.0.0.2'})
        self.assertDictEqual(
            {
                'ip': sample.args['ip'],
                'port': 5001
            },
            receiver.args['server'],
        )
Example #36
0
    def connect(mapping, receiver, emitter):
        mapping_parsed = {}

        click.echo('Connect {} to {}'.format(emitter, receiver))
        emitter = sresource.load(emitter)
        receiver = sresource.load(receiver)
        try:
            mapping_parsed.update(json.loads(mapping))
        except ValueError:
            for m in mapping.split():
                k, v = m.split('->')
                mapping_parsed.update({k: v})
        signals.connect(emitter, receiver, mapping=mapping_parsed)

        show_emitter_connections(emitter)
Example #37
0
def _revert_remove(logitem):
    """Resource should be created with all previous connections"""
    commited = CommitedResource.get(logitem.resource)
    args = dictdiffer.revert(logitem.diff, commited.inputs)
    connections = dictdiffer.revert(
        logitem.connections_diff, sorted(commited.connections))

    resource.Resource(logitem.resource, logitem.base_path,
                      args=_get_args_to_update(args, connections),
                      tags=commited.tags)
    for emitter, emitter_input, receiver, receiver_input in connections:
        emmiter_obj = resource.load(emitter)
        receiver_obj = resource.load(receiver)
        signals.connect(emmiter_obj, receiver_obj, {
                        emitter_input: receiver_input})
Example #38
0
def _revert_remove(logitem):
    """Resource should be created with all previous connections"""
    commited = CommitedResource.get(logitem.resource)
    args = dictdiffer.revert(logitem.diff, commited.inputs)
    connections = dictdiffer.revert(
        logitem.connections_diff, sorted(commited.connections))

    resource.Resource(logitem.resource, logitem.base_path,
                      args=_get_args_to_update(args, connections),
                      tags=commited.tags)
    for emitter, emitter_input, receiver, receiver_input in connections:
        emmiter_obj = resource.load(emitter)
        receiver_obj = resource.load(receiver)
        signals.connect(emmiter_obj, receiver_obj, {
                        emitter_input: receiver_input})
Example #39
0
    def test_multiple_resource_disjoint_connect(self):
        sample_meta_dir = self.make_resource_meta("""
id: sample
handler: ansible
version: 1.0.0
input:
  ip:
    schema: str
    value:
  port:
    schema: int
    value:
        """)
        sample_ip_meta_dir = self.make_resource_meta("""
id: sample-ip
handler: ansible
version: 1.0.0
input:
  ip:
    schema: str
    value:
        """)
        sample_port_meta_dir = self.make_resource_meta("""
id: sample-port
handler: ansible
version: 1.0.0
input:
  port:
    schema: int
    value:
        """)

        sample = self.create_resource('sample', sample_meta_dir, {
            'ip': None,
            'port': None
        })
        sample_ip = self.create_resource('sample-ip', sample_ip_meta_dir,
                                         {'ip': '10.0.0.1'})
        sample_port = self.create_resource('sample-port', sample_port_meta_dir,
                                           {'port': 8000})
        self.assertNotEqual(
            sample.resource_inputs()['ip'],
            sample_ip.resource_inputs()['ip'],
        )
        xs.connect(sample_ip, sample)
        xs.connect(sample_port, sample)
        self.assertEqual(sample.args['ip'], sample_ip.args['ip'])
        self.assertEqual(sample.args['port'], sample_port.args['port'])
Example #40
0
    def connect_list(self, resources, args={}):
        """Connect this resource to a ResourceListTemplate object.

        args - optional connect mapping. This mapping can have the
          "{receiver_num}" string which enumerates each resrouce in resources
          list.
        """

        for receiver_num, resource in enumerate(resources.resources):
            kwargs = {
                'receiver_num': receiver_num,
            }

            args_fmt = self.args_fmt(args, kwargs)

            signals.connect(self.resource, resource, args_fmt)
Example #41
0
    def connect(mapping, receiver, emitter):
        mapping_parsed = None
        emitter = sresource.load(emitter)
        receiver = sresource.load(receiver)
        click.echo('Connect {} to {}'.format(emitter, receiver))

        if mapping:
            mapping_parsed = {}
            try:
                mapping_parsed.update(json.loads(mapping))
            except ValueError:
                for m in mapping.split():
                    k, v = m.split('->')
                    mapping_parsed.update({k: v})
        signals.connect(emitter, receiver, mapping=mapping_parsed)

        show_emitter_connections(emitter)
Example #42
0
    def test_no_self_connection(self):
        sample_meta_dir = self.make_resource_meta("""
id: sample
handler: ansible
version: 1.0.0
input:
  value:
    schema: str!
    value:
        """)

        sample = self.create_resource('sample', sample_meta_dir,
                                      {'value': 'x'})

        with self.assertRaisesRegexp(Exception,
                                     'Trying to connect value-.* to itself'):
            xs.connect(sample, sample, {'value'})
Example #43
0
    def test_no_self_connection(self):
        sample_meta_dir = self.make_resource_meta("""
id: sample
handler: ansible
version: 1.0.0
input:
  value:
    schema: str!
    value:
        """)

        sample = self.create_resource('sample', sample_meta_dir,
                                      {'value': 'x'})

        with self.assertRaisesRegexp(Exception,
                                     'Trying to connect value-.* to itself'):
            xs.connect(sample, sample, {'value'})
Example #44
0
    def connect_list(self, resources, mapping=None):
        """Connect this resource to a ResourceListTemplate object.

        mapping - optional connect mapping. This mapping can have the
          "{receiver_num}" string which enumerates each resrouce in resources
          list.
        """
        mapping = mapping or {}

        for receiver_num, resource in enumerate(resources.resources):
            kwargs = {
                'receiver_num': receiver_num,
            }

            mapping_fmt = self.args_fmt(mapping, kwargs)

            signals.connect(self.resource, resource, mapping_fmt)
Example #45
0
    def test_backtrack_dict(self):
        sample_meta_dir = self.make_resource_meta("""
id: sample
handler: ansible
version: 1.0.0
input:
  value:
    schema: str!
    value:
        """)
        sample_dict_meta_dir = self.make_resource_meta("""
id: sample_dict
handler: ansible
version: 1.0.0
input:
  value:
    schema: {a: str!}
    value:
        """)

        sample_dict = self.create_resource(
            'sample_dict', sample_dict_meta_dir
        )
        vi = sample_dict.resource_inputs()['value']
        sample1 = self.create_resource(
            'sample1', sample_meta_dir, {'value': 'x'}
        )
        sample2 = self.create_resource(
            'sample2', sample_meta_dir, {'value': 'z'}
        )
        self.assertEqual(vi.backtrack_value_emitter(), vi)

        # {a: sample1} -> sample_dict
        signals.connect(sample1, sample_dict, {'value': 'value:a'})
        self.assertDictEqual(vi.backtrack_value_emitter(),
                             {'a': sample1.resource_inputs()['value']})

        # {a: sample2} -> sample_dict
        signals.connect(sample2, sample_dict, {'value': 'value:a'})
        self.assertDictEqual(vi.backtrack_value_emitter(),
                             {'a': sample2.resource_inputs()['value']})

        # sample2 disconnected
        signals.disconnect(sample2, sample_dict)
        self.assertEqual(vi.backtrack_value_emitter(), vi)
Example #46
0
    def test_backtrack_dict(self):
        sample_meta_dir = self.make_resource_meta("""
id: sample
handler: ansible
version: 1.0.0
input:
  value:
    schema: str!
    value:
        """)
        sample_dict_meta_dir = self.make_resource_meta("""
id: sample_dict
handler: ansible
version: 1.0.0
input:
  value:
    schema: {a: str!}
    value:
        """)

        sample_dict = self.create_resource(
            'sample_dict', sample_dict_meta_dir
        )
        vi = sample_dict.resource_inputs()['value']
        sample1 = self.create_resource(
            'sample1', sample_meta_dir, {'value': 'x'}
        )
        sample2 = self.create_resource(
            'sample2', sample_meta_dir, {'value': 'z'}
        )
        self.assertEqual(vi.backtrack_value_emitter(), vi)

        # {a: sample1} -> sample_dict
        signals.connect(sample1, sample_dict, {'value': 'value:a'})
        self.assertDictEqual(vi.backtrack_value_emitter(),
                             {'a': sample1.resource_inputs()['value']})

        # {a: sample2} -> sample_dict
        signals.connect(sample2, sample_dict, {'value': 'value:a'})
        self.assertDictEqual(vi.backtrack_value_emitter(),
                             {'a': sample2.resource_inputs()['value']})

        # sample2 disconnected
        signals.disconnect(sample2, sample_dict)
        self.assertEqual(vi.backtrack_value_emitter(), vi)
Example #47
0
def assign_resources_to_nodes(resources, nodes):
    for node in nodes:
        for resource in resources:
            res = deepcopy(resource)
            res['tags'] = list(set(node.get('tags', [])) |
                               set(resource.get('tags', [])))
            resource_uuid = '{0}-{1}'.format(res['id'], solar.utils.generate_uuid())
            # We should not generate here any uuid's, because
            # a single node should be represented with a single
            # resource
            node_uuid = node['id']

            node_resource_template = solar.utils.read_config()['node_resource_template']
            args = {k: v['value'] for k, v in res['input'].items()}
            created_resource = create(resource_uuid, resource['dir_path'], args, tags=res['tags'])
            created_node = create(node_uuid, node_resource_template, node, tags=node.get('tags', []))

            signals.connect(created_node, created_resource)
Example #48
0
def add_connections(resource_name, args):
    connections = []
    for receiver_input, arg in args.items():
        if isinstance(arg, list):
            for item in arg:
                c = parse_connection(resource_name, receiver_input, item)
                connections.append(c)
        else:
           c = parse_connection(resource_name, receiver_input, arg)
           connections.append(c)

    connections = [c for c in connections if c is not None]
    for c in connections:
        parent = resource.load(c['parent'])
        child = resource.load(c['child'])
        events = c['events']
        mapping = {c['parent_input'] : c['child_input']}
        signals.connect(parent, child, mapping, events)
Example #49
0
    def test_circular_connection_prevention(self):
        # TODO: more complex cases
        sample_meta_dir = self.make_resource_meta("""
id: sample
handler: ansible
version: 1.0.0
input:
  ip:
    schema: str
    value:
        """)

        sample1 = self.create_resource('sample1', sample_meta_dir,
                                       {'ip': '10.0.0.1'})
        sample2 = self.create_resource('sample2', sample_meta_dir,
                                       {'ip': '10.0.0.2'})
        xs.connect(sample1, sample2)

        with self.assertRaises(Exception):
            xs.connect(sample2, sample1)
Example #50
0
def create_resources(resources, tags=None):
    created_resources = []
    cwd = os.getcwd()
    for r in resources:
        resource_name = r['id']
        args = r.get('values', {})
        node = r.get('location', None)
        from_path = r.get('from', None)
        tags = r.get('tags', [])
        base_path = os.path.join(cwd, from_path)
        new_resources = create(resource_name, base_path, args=args, tags=tags)
        created_resources += new_resources
        if not is_virtual(base_path):
            if node:
                node = load_resource(node)
                r = new_resources[0]
                signals.connect(node, r, {})
                r.add_tags('location={}'.format(node.name))
            update_inputs(resource_name, args)
    return created_resources
Example #51
0
    def test_no_cycles(self):
        sample_meta_dir = self.make_resource_meta("""
id: sample
handler: ansible
version: 1.0.0
input:
  value:
    schema: str!
    value:
        """)

        sample1 = self.create_resource('sample1', sample_meta_dir,
                                       {'value': 'x'})

        sample2 = self.create_resource('sample2', sample_meta_dir,
                                       {'value': 'y'})

        xs.connect(sample1, sample2)

        with self.assertRaisesRegexp(Exception, 'Prevented creating a cycle'):
            xs.connect(sample2, sample1)
Example #52
0
def add_solard(i):
    solard_transport = vr.create('solard_transport%s' % i,
                                 'resources/transport_solard', {
                                     'solard_user': '******',
                                     'solard_password': '******'
                                 })[0]
    transports = resource.load('transports%s' % i)
    ssh_transport = resource.load('ssh_transport%s' % i)
    transports_for_solard = vr.create('transports_for_solard%s' % i,
                                      'resources/transports')[0]

    # install solard with ssh
    signals.connect(transports_for_solard, solard_transport, {})

    signals.connect(
        ssh_transport, transports_for_solard, {
            'ssh_key': 'transports:key',
            'ssh_user': '******',
            'ssh_port': 'transports:port',
            'name': 'transports:name'
        })

    # add solard to transports on this node
    signals.connect(
        solard_transport, transports, {
            'solard_user': '******',
            'solard_port': 'transports:port',
            'solard_password': '******',
            'name': 'transports:name'
        })
Example #53
0
def deploy():
    db = get_db()
    db.clear()

    signals.Connections.clear()

    node1 = resources_compiled.RoNodeResource('node1', None, {})
    node1.ip = '10.0.0.3'
    node1.ssh_key = '/vagrant/.vagrant/machines/solar-dev1/virtualbox/private_key'
    node1.ssh_user = '******'

    rabbitmq_service1 = resources_compiled.RabbitmqServiceResource(
        'rabbitmq_service1', None, {
            'management_port': 15672,
            'port': 5672,
            'container_name': 'rabbitmq_service1',
            'image': 'rabbitmq:3-management'
        })
    openstack_vhost = resource.create('openstack_vhost',
                                      'resources/rabbitmq_vhost/',
                                      {'vhost_name': 'openstack'})[0]
    openstack_rabbitmq_user = resource.create(
        'openstack_rabbitmq_user', 'resources/rabbitmq_user/', {
            'user_name': 'openstack',
            'password': '******'
        })[0]

    ####
    # connections
    ####

    # rabbitmq
    signals.connect(node1, rabbitmq_service1)
    signals.connect(rabbitmq_service1, openstack_vhost)
    signals.connect(rabbitmq_service1, openstack_rabbitmq_user)
    signals.connect(openstack_vhost, openstack_rabbitmq_user,
                    {'vhost_name': 'vhost_name'})

    errors = vr.validate_resources()
    if errors:
        for r, error in errors:
            print 'ERROR: %s: %s' % (r.name, error)
        sys.exit(1)

    # run
    actions.resource_action(rabbitmq_service1, 'run')
    actions.resource_action(openstack_vhost, 'run')
    actions.resource_action(openstack_rabbitmq_user, 'run')
    time.sleep(10)
Example #54
0
def test_discard_connection():
    res1 = orm.DBResource(id='test1', name='test1', base_path='x')
    res1.save()
    res1.add_input('a', 'str', '9')

    res2 = orm.DBResource(id='test2', name='test2', base_path='x')
    res2.save()
    res2.add_input('a', 'str', '0')

    staged_log = change.stage_changes()
    for item in staged_log:
        operations.move_to_commited(item.log_action)

    res1 = resource.load('test1')
    res2 = resource.load('test2')
    signals.connect(res1, res2)
    staged_log = change.stage_changes()
    assert len(staged_log) == 1
    assert res2.args == {'a': '9'}
    change.discard_all()
    assert res2.args == {'a': '0'}
    assert len(change.stage_changes()) == 0
Example #55
0
def test_revert_update_connected():
    res1 = orm.DBResource(id='test1', name='test1', base_path='x')
    res1.save()
    res1.add_input('a', 'str', '9')

    res2 = orm.DBResource(id='test2', name='test2', base_path='x')
    res2.save()
    res2.add_input('a', 'str', 0)

    res3 = orm.DBResource(id='test3', name='test3', base_path='x')
    res3.save()
    res3.add_input('a', 'str', 0)

    res1 = resource.load('test1')
    res2 = resource.load('test2')
    res3 = resource.load('test3')
    signals.connect(res1, res2)
    signals.connect(res2, res3)

    staged_log = change.stage_changes()
    assert len(staged_log) == 3
    for item in staged_log:
        operations.move_to_commited(item.log_action)
    assert len(staged_log) == 0

    signals.disconnect(res1, res2)

    staged_log = change.stage_changes()
    assert len(staged_log) == 2
    to_revert = []
    for item in staged_log:
        operations.move_to_commited(item.log_action)
        to_revert.append(item.uid)

    change.revert_uids(sorted(to_revert, reverse=True))
    staged_log = change.stage_changes()
    assert len(staged_log) == 2
    for item in staged_log:
        assert item.diff == [['change', 'a', [0, '9']]]
Example #56
0
def _update_inputs_connections(res_obj, args, old_connections, new_connections):
    res_obj.update(args)


    removed = []
    for item in old_connections:
        if item not in new_connections:
            removed.append(item)

    added = []
    for item in new_connections:
        if item not in old_connections:
            added.append(item)

    for emitter, _, receiver, _ in removed:
        emmiter_obj = resource.load(emitter)
        receiver_obj = resource.load(receiver)
        signals.disconnect(emmiter_obj, receiver_obj)


    for emitter, emitter_input, receiver, receiver_input in added:
        emmiter_obj = resource.load(emitter)
        receiver_obj = resource.load(receiver)
        signals.connect(emmiter_obj, receiver_obj, {emitter_input: receiver_input})
Example #57
0
    def test_backtrack_dict_list(self):
        sample_meta_dir = self.make_resource_meta("""
id: sample
handler: ansible
version: 1.0.0
input:
  value:
    schema: str!
    value:
        """)
        sample_dict_list_meta_dir = self.make_resource_meta("""
id: sample_dict_list
handler: ansible
version: 1.0.0
input:
  value:
    schema: [{a: str!}]
    value:
        """)

        sample_dict_list = self.create_resource(
            'sample_dict', sample_dict_list_meta_dir
        )
        vi = sample_dict_list.resource_inputs()['value']
        sample1 = self.create_resource(
            'sample1', sample_meta_dir, {'value': 'x'}
        )
        sample2 = self.create_resource(
            'sample2', sample_meta_dir, {'value': 'y'}
        )
        sample3 = self.create_resource(
            'sample3', sample_meta_dir, {'value': 'z'}
        )
        self.assertEqual(vi.backtrack_value_emitter(), vi)

        # [{a: sample1}] -> sample_dict_list
        signals.connect(sample1, sample_dict_list, {'value': 'value:a'})
        self.assertListEqual(vi.backtrack_value_emitter(),
                             [{'a': sample1.resource_inputs()['value']}])

        # [{a: sample1}, {a: sample3}] -> sample_dict_list
        signals.connect(sample3, sample_dict_list, {'value': 'value:a'})
        self.assertItemsEqual(vi.backtrack_value_emitter(),
                              [{'a': sample1.resource_inputs()['value']},
                               {'a': sample3.resource_inputs()['value']}])

        # [{a: sample1}, {a: sample2}] -> sample_dict_list
        signals.connect(sample2, sample_dict_list, {'value': 'value:a|sample3'})
        self.assertItemsEqual(vi.backtrack_value_emitter(),
                              [{'a': sample1.resource_inputs()['value']},
                               {'a': sample2.resource_inputs()['value']}])

        # sample2 disconnected
        signals.disconnect(sample2, sample_dict_list)
        self.assertEqual(vi.backtrack_value_emitter(),
                         [{'a': sample1.resource_inputs()['value']}])
Example #58
0
    def test_backtrack_simple(self):
        sample_meta_dir = self.make_resource_meta("""
id: sample
handler: ansible
version: 1.0.0
input:
  value:
    schema: str!
    value:
        """)

        sample1 = self.create_resource(
            'sample1', sample_meta_dir, {'value': 'x'}
        )
        sample2 = self.create_resource(
            'sample2', sample_meta_dir, {'value': 'y'}
        )
        sample3 = self.create_resource(
            'sample3', sample_meta_dir, {'value': 'z'}
        )
        vi = sample2.resource_inputs()['value']
        self.assertEqual(vi.backtrack_value_emitter(), vi)

        # sample1 -> sample2
        signals.connect(sample1, sample2)
        self.assertEqual(vi.backtrack_value_emitter(),
                         sample1.resource_inputs()['value'])

        # sample3 -> sample1 -> sample2
        signals.connect(sample3, sample1)
        self.assertEqual(vi.backtrack_value_emitter(),
                         sample3.resource_inputs()['value'])

        # sample2 disconnected
        signals.disconnect(sample1, sample2)
        self.assertEqual(vi.backtrack_value_emitter(), vi)
Example #59
0
    def connect_list(self, resources, mapping=None, events=None):
        """Connect self.resources to given resources in a 1-1 fashion.

        First resource in self.resources is connected to first resource in
        resources, second to second, etc.

        mapping -- optional mapping
          "{num}" -- substitutes for resource's index in args
        """
        mapping = mapping or {}

        for num, er in enumerate(zip(self.resources, resources.resources)):
            emitter, receiver = er

            kwargs = {
                'num': num,
            }

            mapping_fmt = self.args_fmt(mapping, kwargs)

            signals.connect(emitter,
                            receiver,
                            mapping=mapping_fmt,
                            events=events)