Remove cli.py, move all to solar/solar/cli.py, migrate all to click
This commit is contained in:
parent
8dd75ed449
commit
d2a4e50ff1
236
cli.py
236
cli.py
@ -1,236 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
import click
|
||||
import json
|
||||
#import matplotlib
|
||||
#matplotlib.use('Agg') # don't show windows
|
||||
#import matplotlib.pyplot as plt
|
||||
import networkx as nx
|
||||
import os
|
||||
import subprocess
|
||||
|
||||
from solar.core import actions as xa
|
||||
from solar.core import resource as xr
|
||||
from solar.core import signals as xs
|
||||
from solar import operations
|
||||
from solar import state
|
||||
|
||||
from solar.interfaces.db import get_db
|
||||
|
||||
db = get_db()
|
||||
|
||||
|
||||
@click.group()
|
||||
def cli():
|
||||
pass
|
||||
|
||||
|
||||
def init_cli_resource():
|
||||
@click.group()
|
||||
def resource():
|
||||
pass
|
||||
|
||||
cli.add_command(resource)
|
||||
|
||||
@click.command()
|
||||
@click.argument('resource_path')
|
||||
@click.argument('action_name')
|
||||
def action(action_name, resource_path):
|
||||
print 'action', resource_path, action_name
|
||||
r = xr.load(resource_path)
|
||||
xa.resource_action(r, action_name)
|
||||
|
||||
resource.add_command(action)
|
||||
|
||||
@click.command()
|
||||
@click.argument('name')
|
||||
@click.argument('base_path')
|
||||
@click.argument('dest_path')
|
||||
@click.argument('args')
|
||||
def create(args, dest_path, base_path, name):
|
||||
print 'create', name, base_path, dest_path, args
|
||||
args = json.loads(args)
|
||||
xr.create(name, base_path, dest_path, args)
|
||||
|
||||
resource.add_command(create)
|
||||
|
||||
@click.command()
|
||||
@click.argument('resource_path')
|
||||
@click.argument('tag_name')
|
||||
@click.option('--add/--delete', default=True)
|
||||
def tag(add, tag_name, resource_path):
|
||||
print 'Tag', resource_path, tag_name, add
|
||||
r = xr.load(resource_path)
|
||||
if add:
|
||||
r.add_tag(tag_name)
|
||||
else:
|
||||
r.remove_tag(tag_name)
|
||||
r.save()
|
||||
|
||||
resource.add_command(tag)
|
||||
|
||||
@click.command()
|
||||
@click.argument('path')
|
||||
@click.option('--all/--one', default=False)
|
||||
@click.option('--tag', default=None)
|
||||
@click.option('--use-json/--no-use-json', default=False)
|
||||
def show(use_json, tag, all, path):
|
||||
import json
|
||||
import six
|
||||
|
||||
printer = lambda r: six.print_(r)
|
||||
if use_json:
|
||||
printer = lambda r: six.print_(json.dumps(r.to_dict()))
|
||||
|
||||
if all or tag:
|
||||
for name, resource in xr.load_all(path).items():
|
||||
show = True
|
||||
if tag:
|
||||
if tag not in resource.tags:
|
||||
show = False
|
||||
|
||||
if show:
|
||||
printer(resource)
|
||||
else:
|
||||
printer(xr.load(path))
|
||||
|
||||
resource.add_command(show)
|
||||
|
||||
@click.command()
|
||||
@click.argument('name')
|
||||
@click.argument('args')
|
||||
def update(name, args):
|
||||
args = json.loads(args)
|
||||
all = xr.load_all()
|
||||
r = all[name]
|
||||
r.update(args)
|
||||
resource.add_command(update)
|
||||
|
||||
|
||||
def init_cli_connect():
|
||||
@click.command()
|
||||
@click.argument('emitter')
|
||||
@click.argument('receiver')
|
||||
@click.option('--mapping', default=None)
|
||||
def connect(mapping, receiver, emitter):
|
||||
print 'Connect', emitter, receiver
|
||||
emitter = xr.load(emitter)
|
||||
receiver = xr.load(receiver)
|
||||
print emitter
|
||||
print receiver
|
||||
if mapping is not None:
|
||||
mapping = json.loads(mapping)
|
||||
xs.connect(emitter, receiver, mapping=mapping)
|
||||
|
||||
cli.add_command(connect)
|
||||
|
||||
@click.command()
|
||||
@click.argument('emitter')
|
||||
@click.argument('receiver')
|
||||
def disconnect(receiver, emitter):
|
||||
print 'Disconnect', emitter, receiver
|
||||
emitter = xr.load(emitter)
|
||||
receiver = xr.load(receiver)
|
||||
print emitter
|
||||
print receiver
|
||||
xs.disconnect(emitter, receiver)
|
||||
|
||||
cli.add_command(disconnect)
|
||||
|
||||
|
||||
def init_changes():
|
||||
@click.group()
|
||||
def changes():
|
||||
pass
|
||||
|
||||
cli.add_command(changes)
|
||||
|
||||
@click.command()
|
||||
def stage():
|
||||
log = operations.stage_changes()
|
||||
print log.show()
|
||||
|
||||
changes.add_command(stage)
|
||||
|
||||
@click.command()
|
||||
@click.option('--one', is_flag=True, default=False)
|
||||
def commit(one):
|
||||
if one:
|
||||
operations.commit_one()
|
||||
else:
|
||||
operations.commit_changes()
|
||||
|
||||
changes.add_command(commit)
|
||||
|
||||
@click.command()
|
||||
@click.option('--limit', default=5)
|
||||
def history(limit):
|
||||
print state.CL().show()
|
||||
|
||||
changes.add_command(history)
|
||||
|
||||
@click.command()
|
||||
@click.option('--last', is_flag=True, default=False)
|
||||
@click.option('--all', is_flag=True, default=False)
|
||||
@click.option('--uid', default=None)
|
||||
def rollback(last, all, uid):
|
||||
if last:
|
||||
print operations.rollback_last()
|
||||
elif all:
|
||||
print operations.rollback_all()
|
||||
elif uid:
|
||||
print operations.rollback_uid(uid)
|
||||
|
||||
changes.add_command(rollback)
|
||||
|
||||
|
||||
def init_cli_connections():
|
||||
@click.group()
|
||||
def connections():
|
||||
pass
|
||||
|
||||
cli.add_command(connections)
|
||||
|
||||
@click.command()
|
||||
def show():
|
||||
print json.dumps(xs.CLIENTS, indent=2)
|
||||
|
||||
connections.add_command(show)
|
||||
|
||||
# TODO: this requires graphing libraries
|
||||
@click.command()
|
||||
def graph():
|
||||
#g = xs.connection_graph()
|
||||
g = xs.detailed_connection_graph()
|
||||
|
||||
nx.write_dot(g, 'graph.dot')
|
||||
subprocess.call(['dot', '-Tpng', 'graph.dot', '-o', 'graph.png'])
|
||||
|
||||
# Matplotlib
|
||||
#pos = nx.spring_layout(g)
|
||||
#nx.draw_networkx_nodes(g, pos)
|
||||
#nx.draw_networkx_edges(g, pos, arrows=True)
|
||||
#nx.draw_networkx_labels(g, pos)
|
||||
#plt.axis('off')
|
||||
#plt.savefig('graph.png')
|
||||
|
||||
connections.add_command(graph)
|
||||
|
||||
|
||||
def init_cli_deployment_config():
|
||||
@click.command()
|
||||
@click.argument('filepath')
|
||||
def deploy(filepath):
|
||||
print 'Deploying from file {}'.format(filepath)
|
||||
xd.deploy(filepath)
|
||||
|
||||
cli.add_command(deploy)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
init_cli_resource()
|
||||
init_cli_connect()
|
||||
init_cli_connections()
|
||||
init_cli_deployment_config()
|
||||
init_changes()
|
||||
|
||||
cli()
|
@ -46,4 +46,4 @@ setup(
|
||||
include_package_data=True,
|
||||
entry_points={
|
||||
'console_scripts': [
|
||||
'solar = solar.cli:main']})
|
||||
'solar = solar.cli:run']})
|
||||
|
@ -17,17 +17,22 @@
|
||||
On create "golden" resource should be moved to special place
|
||||
"""
|
||||
|
||||
import argparse
|
||||
import click
|
||||
import json
|
||||
import networkx as nx
|
||||
import os
|
||||
import sys
|
||||
import pprint
|
||||
|
||||
import textwrap
|
||||
import subprocess
|
||||
import yaml
|
||||
|
||||
from solar import utils
|
||||
from solar import operations
|
||||
from solar import state
|
||||
from solar.core import actions
|
||||
from solar.core import resource
|
||||
from solar.core.resource import assign_resources_to_nodes
|
||||
from solar.core.resource import connect_resources
|
||||
from solar.core import signals
|
||||
from solar.core.tags_set_parser import Expression
|
||||
from solar.interfaces.db import get_db
|
||||
|
||||
@ -36,98 +41,19 @@ from solar.interfaces.db import get_db
|
||||
from solar.extensions.modules.discovery import Discovery
|
||||
|
||||
|
||||
class Cmd(object):
|
||||
db = get_db()
|
||||
|
||||
def __init__(self):
|
||||
self.parser = argparse.ArgumentParser(
|
||||
description=textwrap.dedent(__doc__),
|
||||
formatter_class=argparse.RawDescriptionHelpFormatter)
|
||||
self.subparser = self.parser.add_subparsers(
|
||||
title='actions',
|
||||
description='Supported actions',
|
||||
help='Provide of one valid actions')
|
||||
self.register_actions()
|
||||
self.db = get_db()
|
||||
|
||||
def parse(self, args):
|
||||
parsed = self.parser.parse_args(args)
|
||||
return parsed.func(parsed)
|
||||
@click.group()
|
||||
def main():
|
||||
pass
|
||||
|
||||
def register_actions(self):
|
||||
|
||||
parser = self.subparser.add_parser('discover')
|
||||
parser.set_defaults(func=getattr(self, 'discover'))
|
||||
|
||||
# Profile actions
|
||||
parser = self.subparser.add_parser('profile')
|
||||
parser.set_defaults(func=getattr(self, 'profile'))
|
||||
parser.add_argument('-l', '--list', dest='list', action='store_true')
|
||||
group = parser.add_argument_group('create')
|
||||
group.add_argument('-c', '--create', dest='create', action='store_true')
|
||||
group.add_argument('-t', '--tags', nargs='+', default=['env/test_env'])
|
||||
group.add_argument('-i', '--id', default=utils.generate_uuid())
|
||||
|
||||
# Assign
|
||||
parser = self.subparser.add_parser('assign')
|
||||
parser.set_defaults(func=getattr(self, 'assign'))
|
||||
parser.add_argument('-n', '--nodes')
|
||||
parser.add_argument('-r', '--resources')
|
||||
|
||||
# Run action on tags
|
||||
parser = self.subparser.add_parser('run')
|
||||
parser.set_defaults(func=getattr(self, 'run'))
|
||||
parser.add_argument('-t', '--tags')
|
||||
parser.add_argument('-a', '--action')
|
||||
|
||||
# Perform resources connection
|
||||
parser = self.subparser.add_parser('connect')
|
||||
parser.set_defaults(func=getattr(self, 'connect'))
|
||||
parser.add_argument(
|
||||
'-p',
|
||||
'--profile')
|
||||
|
||||
def run(self, args):
|
||||
from solar.core import actions
|
||||
from solar.core import resource
|
||||
|
||||
resources = filter(
|
||||
lambda r: Expression(args.tags, r.get('tags', [])).evaluate(),
|
||||
self.db.get_list('resource'))
|
||||
|
||||
for resource in resources:
|
||||
resource_obj = resource.load(resource['id'])
|
||||
actions.resource_action(resource_obj, args.action)
|
||||
|
||||
def profile(self, args):
|
||||
if args.create:
|
||||
params = {'tags': args.tags, 'id': args.id}
|
||||
profile_template_path = os.path.join(
|
||||
utils.read_config()['template-dir'], 'profile.yml')
|
||||
data = yaml.load(utils.render_template(profile_template_path, params))
|
||||
self.db.store('profiles', data)
|
||||
else:
|
||||
pprint.pprint(self.db.get_list('profiles'))
|
||||
|
||||
def discover(self, args):
|
||||
Discovery({'id': 'discovery'}).discover()
|
||||
|
||||
def connect(self, args):
|
||||
profile = self.db.get_record('profiles', args.profile)
|
||||
connect_resources(profile)
|
||||
|
||||
def assign(self, args):
|
||||
nodes = filter(
|
||||
lambda n: Expression(args.nodes, n.get('tags', [])).evaluate(),
|
||||
self.db.get_list('nodes'))
|
||||
|
||||
resources = filter(
|
||||
lambda r: Expression(args.resources, r.get('tags', [])).evaluate(),
|
||||
self._get_resources_list())
|
||||
|
||||
print("For {0} nodes assign {1} resources".format(len(nodes), len(resources)))
|
||||
assign_resources_to_nodes(resources, nodes)
|
||||
|
||||
def _get_resources_list(self):
|
||||
@main.command()
|
||||
@click.option('-n', '--nodes')
|
||||
@click.option('-r', '--resources')
|
||||
def assign(resources, nodes):
|
||||
def _get_resources_list():
|
||||
result = []
|
||||
for path in utils.find_by_mask(utils.read_config()['resources-files-mask']):
|
||||
resource = utils.yaml_load(path)
|
||||
@ -137,11 +63,241 @@ class Cmd(object):
|
||||
|
||||
return result
|
||||
|
||||
nodes = filter(
|
||||
lambda n: Expression(nodes, n.get('tags', [])).evaluate(),
|
||||
db.get_list('nodes'))
|
||||
|
||||
def main():
|
||||
api = Cmd()
|
||||
api.parse(sys.argv[1:])
|
||||
resources = filter(
|
||||
lambda r: Expression(resources, r.get('tags', [])).evaluate(),
|
||||
_get_resources_list())
|
||||
|
||||
print("For {0} nodes assign {1} resources".format(len(nodes), len(resources)))
|
||||
assign_resources_to_nodes(resources, nodes)
|
||||
|
||||
|
||||
@main.command()
|
||||
@click.option('-p', '--profile')
|
||||
def connect(profile):
|
||||
profile_ = db.get_record('profiles', profile)
|
||||
connect_resources(profile_)
|
||||
|
||||
|
||||
@main.command()
|
||||
def discover():
|
||||
Discovery({'id': 'discovery'}).discover()
|
||||
|
||||
|
||||
@main.command()
|
||||
@click.option('-c', '--create', default=False, is_flag=True)
|
||||
@click.option('-t', '--tags', multiple=True)
|
||||
@click.option('-i', '--id')
|
||||
def profile(id, tags, create):
|
||||
if not id:
|
||||
id = utils.generate_uuid()
|
||||
if create:
|
||||
params = {'tags': tags, 'id': id}
|
||||
profile_template_path = os.path.join(
|
||||
utils.read_config()['template-dir'], 'profile.yml')
|
||||
data = yaml.load(utils.render_template(profile_template_path, params))
|
||||
db.store('profiles', data)
|
||||
else:
|
||||
pprint.pprint(db.get_list('profiles'))
|
||||
|
||||
|
||||
@main.command()
|
||||
@click.option('-t', '--tags')
|
||||
@click.option('-a', '--action')
|
||||
def run(action, tags):
|
||||
from solar.core import actions
|
||||
from solar.core import resource
|
||||
|
||||
resources = filter(
|
||||
lambda r: Expression(tags, r.get('tags', [])).evaluate(),
|
||||
db.get_list('resource'))
|
||||
|
||||
for resource in resources:
|
||||
resource_obj = resource.load(resource['id'])
|
||||
actions.resource_action(resource_obj, action)
|
||||
|
||||
|
||||
def init_cli_resource():
|
||||
@main.group()
|
||||
def resource():
|
||||
pass
|
||||
|
||||
@resource.command()
|
||||
@click.argument('resource_path')
|
||||
@click.argument('action_name')
|
||||
def action(action_name, resource_path):
|
||||
print 'action', resource_path, action_name
|
||||
r = resource.load(resource_path)
|
||||
actions.resource_action(r, action_name)
|
||||
|
||||
@resource.command()
|
||||
@click.argument('name')
|
||||
@click.argument('base_path')
|
||||
@click.argument('dest_path')
|
||||
@click.argument('args')
|
||||
def create(args, dest_path, base_path, name):
|
||||
print 'create', name, base_path, dest_path, args
|
||||
args = json.loads(args)
|
||||
resource.create(name, base_path, dest_path, args)
|
||||
|
||||
@resource.command()
|
||||
@click.argument('resource_path')
|
||||
@click.argument('tag_name')
|
||||
@click.option('--add/--delete', default=True)
|
||||
def tag(add, tag_name, resource_path):
|
||||
print 'Tag', resource_path, tag_name, add
|
||||
r = resource.load(resource_path)
|
||||
if add:
|
||||
r.add_tag(tag_name)
|
||||
else:
|
||||
r.remove_tag(tag_name)
|
||||
r.save()
|
||||
|
||||
@resource.command()
|
||||
@click.argument('path')
|
||||
@click.option('--all/--one', default=False)
|
||||
@click.option('--tag', default=None)
|
||||
@click.option('--use-json/--no-use-json', default=False)
|
||||
def show(use_json, tag, all, path):
|
||||
import json
|
||||
import six
|
||||
|
||||
printer = lambda r: six.print_(r)
|
||||
if use_json:
|
||||
printer = lambda r: six.print_(json.dumps(r.to_dict()))
|
||||
|
||||
if all or tag:
|
||||
for name, res in resource.load_all(path).items():
|
||||
show = True
|
||||
if tag:
|
||||
if tag not in res.tags:
|
||||
show = False
|
||||
|
||||
if show:
|
||||
printer(res)
|
||||
else:
|
||||
printer(resource.load(path))
|
||||
|
||||
@resource.command()
|
||||
@click.argument('name')
|
||||
@click.argument('args')
|
||||
def update(name, args):
|
||||
args = json.loads(args)
|
||||
all = resource.load_all()
|
||||
r = all[name]
|
||||
r.update(args)
|
||||
|
||||
|
||||
def init_cli_connect():
|
||||
@main.command()
|
||||
@click.argument('emitter')
|
||||
@click.argument('receiver')
|
||||
@click.option('--mapping', default=None)
|
||||
def connect(mapping, receiver, emitter):
|
||||
print 'Connect', emitter, receiver
|
||||
emitter = resource.load(emitter)
|
||||
receiver = resource.load(receiver)
|
||||
print emitter
|
||||
print receiver
|
||||
if mapping is not None:
|
||||
mapping = json.loads(mapping)
|
||||
signals.connect(emitter, receiver, mapping=mapping)
|
||||
|
||||
@main.command()
|
||||
@click.argument('emitter')
|
||||
@click.argument('receiver')
|
||||
def disconnect(receiver, emitter):
|
||||
print 'Disconnect', emitter, receiver
|
||||
emitter = resource.load(emitter)
|
||||
receiver = resource.load(receiver)
|
||||
print emitter
|
||||
print receiver
|
||||
signals.disconnect(emitter, receiver)
|
||||
|
||||
|
||||
def init_changes():
|
||||
@main.group()
|
||||
def changes():
|
||||
pass
|
||||
|
||||
@changes.command()
|
||||
def stage():
|
||||
log = operations.stage_changes()
|
||||
print log.show()
|
||||
|
||||
@changes.command()
|
||||
@click.option('--one', is_flag=True, default=False)
|
||||
def commit(one):
|
||||
if one:
|
||||
operations.commit_one()
|
||||
else:
|
||||
operations.commit_changes()
|
||||
|
||||
@changes.command()
|
||||
@click.option('--limit', default=5)
|
||||
def history(limit):
|
||||
print state.CL().show()
|
||||
|
||||
@changes.command()
|
||||
@click.option('--last', is_flag=True, default=False)
|
||||
@click.option('--all', is_flag=True, default=False)
|
||||
@click.option('--uid', default=None)
|
||||
def rollback(last, all, uid):
|
||||
if last:
|
||||
print operations.rollback_last()
|
||||
elif all:
|
||||
print operations.rollback_all()
|
||||
elif uid:
|
||||
print operations.rollback_uid(uid)
|
||||
|
||||
|
||||
def init_cli_connections():
|
||||
@main.group()
|
||||
def connections():
|
||||
pass
|
||||
|
||||
@connections.command()
|
||||
def show():
|
||||
print json.dumps(signals.CLIENTS, indent=2)
|
||||
|
||||
# TODO: this requires graphing libraries
|
||||
@connections.command()
|
||||
def graph():
|
||||
#g = xs.connection_graph()
|
||||
g = signals.detailed_connection_graph()
|
||||
|
||||
nx.write_dot(g, 'graph.dot')
|
||||
subprocess.call(['dot', '-Tpng', 'graph.dot', '-o', 'graph.png'])
|
||||
|
||||
# Matplotlib
|
||||
#pos = nx.spring_layout(g)
|
||||
#nx.draw_networkx_nodes(g, pos)
|
||||
#nx.draw_networkx_edges(g, pos, arrows=True)
|
||||
#nx.draw_networkx_labels(g, pos)
|
||||
#plt.axis('off')
|
||||
#plt.savefig('graph.png')
|
||||
|
||||
|
||||
def init_cli_deployment_config():
|
||||
@main.command()
|
||||
@click.argument('filepath')
|
||||
def deploy(filepath):
|
||||
print 'Deploying from file {}'.format(filepath)
|
||||
xd.deploy(filepath)
|
||||
|
||||
|
||||
def run():
|
||||
init_cli_resource()
|
||||
init_cli_connect()
|
||||
init_cli_connections()
|
||||
init_cli_deployment_config()
|
||||
init_changes()
|
||||
|
||||
main()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
run()
|
||||
|
@ -187,6 +187,8 @@ class ListObserver(BaseObserver):
|
||||
self.log('Unsubscribed emitter {}'.format(emitter))
|
||||
idx = self._emitter_idx(emitter)
|
||||
self.value.pop(idx)
|
||||
for receiver in self.receivers:
|
||||
receiver.notify(self)
|
||||
|
||||
def _emitter_idx(self, emitter):
|
||||
try:
|
||||
|
@ -329,6 +329,91 @@ input:
|
||||
(sample2.args['port'].attached_to.name, 'port')]
|
||||
)
|
||||
|
||||
# Test disconnect
|
||||
xs.disconnect(sample2, list_input_multi)
|
||||
self.assertEqual(
|
||||
[ip['value'] for ip in list_input_multi.args['ips'].value],
|
||||
[sample1.args['ip']]
|
||||
)
|
||||
self.assertEqual(
|
||||
[p['value'] for p in list_input_multi.args['ports'].value],
|
||||
[sample1.args['port']]
|
||||
)
|
||||
|
||||
def test_nested_list_input(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:
|
||||
""")
|
||||
list_input_meta_dir = self.make_resource_meta("""
|
||||
id: list-input
|
||||
handler: ansible
|
||||
version: 1.0.0
|
||||
input:
|
||||
ips:
|
||||
schema: [str]
|
||||
value: []
|
||||
ports:
|
||||
schema: [int]
|
||||
value: []
|
||||
""")
|
||||
list_input_nested_meta_dir = self.make_resource_meta("""
|
||||
id: list-input-nested
|
||||
handler: ansible
|
||||
version: 1.0.0
|
||||
input:
|
||||
ipss:
|
||||
schema: [[str]]
|
||||
value: []
|
||||
portss:
|
||||
schema: [[int]]
|
||||
value: []
|
||||
""")
|
||||
|
||||
sample1 = self.create_resource(
|
||||
'sample1', sample_meta_dir, {'ip': '10.0.0.1', 'port': '1000'}
|
||||
)
|
||||
sample2 = self.create_resource(
|
||||
'sample2', sample_meta_dir, {'ip': '10.0.0.2', 'port': '1001'}
|
||||
)
|
||||
list_input = self.create_resource(
|
||||
'list-input', list_input_meta_dir, {'ips': [], 'ports': []}
|
||||
)
|
||||
list_input_nested = self.create_resource(
|
||||
'list-input-nested', list_input_nested_meta_dir, {'ipss': [], 'portss': []}
|
||||
)
|
||||
|
||||
xs.connect(sample1, list_input, mapping={'ip': 'ips', 'port': 'ports'})
|
||||
xs.connect(sample2, list_input, mapping={'ip': 'ips', 'port': 'ports'})
|
||||
xs.connect(list_input, list_input_nested, mapping={'ips': 'ipss', 'ports': 'portss'})
|
||||
self.assertListEqual(
|
||||
[ips['value'] for ips in list_input_nested.args['ipss'].value],
|
||||
[list_input.args['ips'].value]
|
||||
)
|
||||
self.assertListEqual(
|
||||
[ps['value'] for ps in list_input_nested.args['portss'].value],
|
||||
[list_input.args['ports'].value]
|
||||
)
|
||||
|
||||
# Test disconnect
|
||||
xs.disconnect(sample1, list_input)
|
||||
self.assertListEqual(
|
||||
[[ip['value'] for ip in ips['value']] for ips in list_input_nested.args['ipss'].value],
|
||||
[[sample2.args['ip'].value]]
|
||||
)
|
||||
self.assertListEqual(
|
||||
[[p['value'] for p in ps['value']] for ps in list_input_nested.args['portss'].value],
|
||||
[[sample2.args['port'].value]]
|
||||
)
|
||||
|
||||
|
||||
'''
|
||||
class TestMultiInput(base.BaseResourceTest):
|
||||
|
Loading…
x
Reference in New Issue
Block a user