Merge pull request #356 from pigmej/new_db_failing_case

Fixing too flat dicts
This commit is contained in:
Łukasz Oleś 2015-11-23 15:31:37 +01:00
commit d0a22c8d68
4 changed files with 88 additions and 11 deletions

View File

@ -10,7 +10,7 @@ input:
value: {src: /etc/solar/haproxy, dst: /etc/haproxy}
config:
schema: [{backends: [{server: str!, port: int!}], listen_port: int!, protocol: str!, name: str!}]
value: []
value: [{}]
# ssh_user:
# schema: str!
# value:

View File

@ -82,9 +82,10 @@ def backtrack_single(i):
@resource.command()
@click.option('-v', '--values', default=False, is_flag=True)
@click.option('-r', '--real_values', default=False, is_flag=True)
@click.option('-i', '--input', default=None)
@click.argument('resource')
def backtrack_inputs(resource, input, values):
def backtrack_inputs(resource, input, values, real_values):
r = sresource.load(resource)
db_obj = r.db_obj
@ -101,7 +102,7 @@ def backtrack_inputs(resource, input, values):
for (rname, rinput), _, meta in se:
l.append(dict(resource=resource, name=name))
val = single(rname, rinput, get_val)
if meta:
if meta and isinstance(val, dict):
val['meta'] = meta
l.append(val)
return l
@ -115,6 +116,8 @@ def backtrack_inputs(resource, input, values):
for name, values in inps.iteritems():
click.echo(yaml.safe_dump({name: values}, default_flow_style=False))
if real_values:
click.echo('! Real value: %r' % sresource.load(resource).db_obj.inputs[name] , nl=True)
@resource.command()
def compile_all():

View File

@ -185,6 +185,9 @@ class InputsFieldWrp(IndexFieldWrp):
def _connect_other_hash(self, my_resource, my_inp_name, other_resource, other_inp_name, my_type, other_type):
return self._connect_other_simple(my_resource, my_inp_name, other_resource, other_inp_name, my_type, other_type)
def _connect_other_list_hash(self, my_resource, my_inp_name, other_resource, other_inp_name, my_type, other_type):
return self._connect_other_simple(my_resource, my_inp_name, other_resource, other_inp_name, my_type, other_type)
def _connect_my_list(self, my_resource, my_inp_name, other_resource, other_inp_name, my_type, other_type):
ret = self._connect_my_simple(my_resource, my_inp_name, other_resource, other_inp_name, my_type, other_type)
return ret
@ -218,14 +221,17 @@ class InputsFieldWrp(IndexFieldWrp):
other_type = self._input_type(other_resource, other_inp_name)
my_type = self._input_type(my_resource, my_inp_name)
if my_type == other_type:
# if the type is the same map 1:1
if my_type == other_type and not ':' in my_inp_name:
# if the type is the same map 1:1, and flat
my_type = InputTypes.simple
other_type = InputTypes.simple
elif my_type == InputTypes.list_hash and other_type == InputTypes.hash:
# whole dict to list with dicts
# TODO: solve this problem
my_type = InputTypes.list
if ':' in my_inp_name:
my_type = InputTypes.hash
else:
my_type = InputTypes.list
# set my side
my_meth = getattr(self, '_connect_my_{}'.format(my_type.name))
@ -447,16 +453,17 @@ class InputsFieldWrp(IndexFieldWrp):
else:
_, _, emitter_key, emitter_inp, my_tag, my_val, mapping_type = splitted_val
cres = Resource.get(emitter_key).inputs._get_field_val(emitter_inp, other)
mapping_type = splitted_val[-1]
items.append((my_tag, my_val, cres))
tmp_res = {}
for my_tag, my_val, value in items:
for first, my_val, value in items:
if my_val is None:
tmp_res[my_tag] = value
tmp_res[first] = value
else:
try:
tmp_res[my_tag][my_val] = value
tmp_res[first][my_val] = value
except KeyError:
tmp_res[my_tag] = {my_val: value}
tmp_res[first] = {my_val: value}
res = tmp_res.values()
self._cache[name] = res
return res
@ -691,7 +698,6 @@ class Resource(Model):
# name there?
if not emitter[0] == self.key:
return False
# TODO: `delete_hash` test works with receiver[1], while lists works with emitter[1]
key = emitter[1]
if not key in converted:
return False

View File

@ -554,3 +554,71 @@ def test_delete_hash(rk):
if 'recv' in index[0] or 'emit' in index[0]:
recv_emit_bin.append(index)
assert recv_emit_bin == []
def test_nested_simple_listdict(rk):
k1 = next(rk)
k2 = next(rk)
k3 = next(rk)
k4 = next(rk)
k5 = next(rk)
r1 = create_resource(k1, {'name': 'first',
'inputs': {'config': [{"backends": [{}],
'listen_port': 1}]}})
r2 = create_resource(k2, {'name': 'second',
'inputs': {'backend': {}}})
r3 = create_resource(k3, {'name': 'third',
'inputs': {'backend': {}}})
r5 = create_resource(k5, {'name': 'fifth',
'inputs': {"port": 5,
"host": "fifth_host"}})
r4 = create_resource(k4, {'name': 'fourth',
'inputs': {"port": 4,
"host": "fourth_host"}})
r4.connect(r2, {'port': "backend:port",
'host': 'backend:host'})
r5.connect(r3, {'port': "backend:port",
'host': 'backend:host'})
assert r2.inputs['backend'] == {'host': 'fourth_host', 'port': 4}
assert r3.inputs['backend'] == {'host': 'fifth_host', 'port': 5}
r2.connect(r1, {'backend': 'config:backends'})
r3.connect(r1, {'backend': 'config:backends'})
Resource.save_all_lazy()
backends = next(x['backends'] for x in r1.inputs['config'] if 'backends' in x)
assert len(backends) == 2
def test_nested_two_listdict(rk):
k1 = next(rk)
k2 = next(rk)
k3 = next(rk)
r1 = create_resource(k1, {'name': 'first',
'inputs': {'config': [{"backends": [{}],
'something': 0}]}})
r2 = create_resource(k2, {'name': 'second',
'inputs': {"backends": [{"host": "second_host", "port": 2}],
'something': 1}})
r3 = create_resource(k3, {'name': 'third',
'inputs': {"backends": [{"host": "third_host", "port": 3}],
'something': 2}})
r2.connect(r1, {'backends': 'config:backends',
'something': 'config:something'})
r3.connect(r1, {'backends': 'config:backends',
'something': 'config:something'})
Resource.save_all_lazy()
for sc in r1.inputs['config']:
assert 'something' in sc
assert 'backends' in sc
assert isinstance(sc['backends'], list)
assert isinstance(sc['something'], int)