Skip to content

Commit

Permalink
Merge branch 'master' into runtime-boundaries
Browse files Browse the repository at this point in the history
  • Loading branch information
Cisphyx authored Oct 18, 2024
2 parents e2d5c6f + 54455df commit 96f975d
Show file tree
Hide file tree
Showing 3 changed files with 99 additions and 3 deletions.
6 changes: 6 additions & 0 deletions changes/8b13b1e0805b28027205dcc2a9d507ba.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
desc: Fixed an issue where extended model forms which implemented interfaces could
not be removed due to inherited props.
prs: []
type: bug
...
44 changes: 41 additions & 3 deletions synapse/datamodel.py
Original file line number Diff line number Diff line change
Expand Up @@ -987,7 +987,17 @@ def delForm(self, formname):
if form is None:
return

formprops = [p for p in form.props.values() if p.univ is None]
ifaceprops = set()
for iface in form.ifaces.values():
for prop in iface.get('props', ()):
ifaceprops.add(prop[0])

formprops = []
for propname, prop in form.props.items():
if prop.univ is not None or propname in ifaceprops:
continue
formprops.append(prop)

if formprops:
propnames = ', '.join(prop.name for prop in formprops)
mesg = f'Form has extended properties: {propnames}'
Expand All @@ -996,8 +1006,8 @@ def delForm(self, formname):
if isinstance(form.type, s_types.Array):
self.arraysbytype[form.type.arraytype.name].pop(form.name, None)

for ifname in form.ifaces.keys():
self.formsbyiface[ifname].remove(formname)
for ifname in form.type.info.get('interfaces', ()):
self._delFormIface(form, ifname)

self.forms.pop(formname, None)
self.props.pop(formname, None)
Expand Down Expand Up @@ -1108,6 +1118,34 @@ def _addFormIface(self, form, name, subifaces=None):
for ifname in ifaces:
self._addFormIface(form, ifname, subifaces=subifaces)

def _delFormIface(self, form, name, subifaces=None):

if (iface := self.ifaces.get(name)) is None:
return

for propname, typedef, propinfo in iface.get('props', ()):
fullprop = f'{form.name}:{propname}'
self.delFormProp(form.name, propname)
self.ifaceprops[f'{name}:{propname}'].remove(fullprop)

if subifaces is not None:
for subi in subifaces:
self.ifaceprops[f'{subi}:{propname}'].remove(fullprop)

form.ifaces.pop(name, None)
self.formsbyiface[name].remove(form.name)

if (ifaces := iface.get('interfaces')) is not None:
if subifaces is None:
subifaces = []
else:
subifaces = list(subifaces)

subifaces.append(name)

for ifname in ifaces:
self._delFormIface(form, ifname, subifaces=subifaces)

def delTagProp(self, name):
return self.tagprops.pop(name)

Expand Down
52 changes: 52 additions & 0 deletions synapse/tests/test_lib_stormlib_modelext.py
Original file line number Diff line number Diff line change
Expand Up @@ -510,3 +510,55 @@ async def test_lib_stormlib_modelext_argtypes(self):
with self.raises(s_exc.BadArg) as exc:
await core.callStorm(query)
self.eq(err, exc.exception.get('mesg'))

async def test_lib_stormlib_modelext_interfaces(self):
async with self.getTestCore() as core:

await core.callStorm('''
$forminfo = ({"interfaces": ["test:interface"]})
$lib.model.ext.addForm(_test:iface, str, ({}), $forminfo)
$lib.model.ext.addFormProp(_test:iface, tick, (time, ({})), ({}))
''')

self.nn(core.model.form('_test:iface'))
self.nn(core.model.prop('_test:iface:flow'))
self.nn(core.model.prop('_test:iface:proc'))
self.nn(core.model.prop('_test:iface:tick'))
self.isin('_test:iface', core.model.formsbyiface['test:interface'])
self.isin('_test:iface', core.model.formsbyiface['inet:proto:request'])
self.isin('_test:iface', core.model.formsbyiface['it:host:activity'])
self.isin('_test:iface:flow', core.model.ifaceprops['inet:proto:request:flow'])
self.isin('_test:iface:proc', core.model.ifaceprops['test:interface:proc'])
self.isin('_test:iface:proc', core.model.ifaceprops['inet:proto:request:proc'])
self.isin('_test:iface:proc', core.model.ifaceprops['it:host:activity:proc'])

q = '$lib.model.ext.delForm(_test:iface)'
with self.raises(s_exc.CantDelForm) as exc:
await core.callStorm(q)
self.eq('Form has extended properties: tick', exc.exception.get('mesg'))

await core.callStorm('''
$lib.model.ext.delFormProp(_test:iface, tick)
$lib.model.ext.delForm(_test:iface)
''')

self.none(core.model.form('_test:iface'))
self.none(core.model.prop('_test:iface:flow'))
self.none(core.model.prop('_test:iface:proc'))
self.none(core.model.prop('_test:iface:tick'))
self.notin('_test:iface', core.model.formsbyiface['test:interface'])
self.notin('_test:iface', core.model.formsbyiface['inet:proto:request'])
self.notin('_test:iface', core.model.formsbyiface['it:host:activity'])
self.notin('_test:iface:flow', core.model.ifaceprops['inet:proto:request:flow'])
self.notin('_test:iface:proc', core.model.ifaceprops['test:interface:proc'])
self.notin('_test:iface:proc', core.model.ifaceprops['inet:proto:request:proc'])
self.notin('_test:iface:proc', core.model.ifaceprops['it:host:activity:proc'])

await core.stormlist('''
$forminfo = ({"interfaces": ["newp"]})
$lib.model.ext.addForm(_test:iface, str, ({}), $forminfo)
''')
self.nn(core.model.form('_test:iface'))

await core.callStorm('$lib.model.ext.delForm(_test:iface)')
self.none(core.model.form('_test:iface'))

0 comments on commit 96f975d

Please sign in to comment.