synapse 2.155.0__py311-none-any.whl → 2.156.0__py311-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of synapse might be problematic. Click here for more details.
- synapse/cmds/cortex.py +2 -14
- synapse/common.py +1 -28
- synapse/cortex.py +10 -510
- synapse/lib/ast.py +60 -1
- synapse/lib/cell.py +33 -8
- synapse/lib/certdir.py +11 -0
- synapse/lib/cmdr.py +0 -5
- synapse/lib/gis.py +2 -2
- synapse/lib/httpapi.py +1 -43
- synapse/lib/layer.py +64 -201
- synapse/lib/lmdbslab.py +11 -0
- synapse/lib/node.py +1 -3
- synapse/lib/parser.py +10 -0
- synapse/lib/snap.py +121 -21
- synapse/lib/storm.lark +23 -6
- synapse/lib/storm.py +15 -338
- synapse/lib/storm_format.py +5 -0
- synapse/lib/stormlib/gen.py +1 -2
- synapse/lib/stormlib/gis.py +41 -0
- synapse/lib/stormlib/stats.py +21 -2
- synapse/lib/stormlib/storm.py +16 -1
- synapse/lib/stormtypes.py +225 -12
- synapse/lib/version.py +2 -2
- synapse/lib/view.py +96 -21
- synapse/models/inet.py +60 -30
- synapse/models/infotech.py +56 -1
- synapse/models/orgs.py +3 -0
- synapse/models/risk.py +15 -0
- synapse/models/syn.py +0 -38
- synapse/tests/test_cmds_cortex.py +1 -1
- synapse/tests/test_cortex.py +32 -336
- synapse/tests/test_lib_agenda.py +19 -54
- synapse/tests/test_lib_aha.py +97 -0
- synapse/tests/test_lib_ast.py +402 -0
- synapse/tests/test_lib_grammar.py +30 -10
- synapse/tests/test_lib_httpapi.py +0 -46
- synapse/tests/test_lib_layer.py +19 -234
- synapse/tests/test_lib_lmdbslab.py +22 -0
- synapse/tests/test_lib_snap.py +9 -0
- synapse/tests/test_lib_storm.py +16 -309
- synapse/tests/test_lib_stormlib_gis.py +21 -0
- synapse/tests/test_lib_stormlib_stats.py +107 -20
- synapse/tests/test_lib_stormlib_storm.py +25 -0
- synapse/tests/test_lib_stormtypes.py +231 -8
- synapse/tests/test_lib_view.py +6 -13
- synapse/tests/test_model_base.py +1 -1
- synapse/tests/test_model_inet.py +15 -0
- synapse/tests/test_model_infotech.py +60 -0
- synapse/tests/test_model_orgs.py +10 -0
- synapse/tests/test_model_person.py +0 -3
- synapse/tests/test_model_risk.py +20 -0
- synapse/tests/test_model_syn.py +20 -34
- synapse/tests/test_tools_csvtool.py +2 -1
- synapse/tests/test_tools_feed.py +4 -30
- synapse/tools/csvtool.py +2 -1
- {synapse-2.155.0.dist-info → synapse-2.156.0.dist-info}/METADATA +3 -3
- {synapse-2.155.0.dist-info → synapse-2.156.0.dist-info}/RECORD +60 -62
- {synapse-2.155.0.dist-info → synapse-2.156.0.dist-info}/WHEEL +1 -1
- synapse/cmds/cron.py +0 -726
- synapse/cmds/trigger.py +0 -319
- synapse/tests/test_cmds_cron.py +0 -453
- synapse/tests/test_cmds_trigger.py +0 -176
- {synapse-2.155.0.dist-info → synapse-2.156.0.dist-info}/LICENSE +0 -0
- {synapse-2.155.0.dist-info → synapse-2.156.0.dist-info}/top_level.txt +0 -0
synapse/tests/test_lib_agenda.py
CHANGED
|
@@ -496,51 +496,6 @@ class AgendaTest(s_t_utils.SynTest):
|
|
|
496
496
|
|
|
497
497
|
self.len(0, [appt for (iden, appt) in appts if iden == badguid2])
|
|
498
498
|
|
|
499
|
-
async def test_cron_perms(self):
|
|
500
|
-
|
|
501
|
-
async with self.getTestCore() as core:
|
|
502
|
-
|
|
503
|
-
visi = await core.auth.addUser('visi')
|
|
504
|
-
newb = await core.auth.addUser('newb')
|
|
505
|
-
async with core.getLocalProxy(user='visi') as proxy:
|
|
506
|
-
|
|
507
|
-
cdef = {'storm': 'inet:ipv4', 'reqs': {'hour': 2}}
|
|
508
|
-
with self.raises(s_exc.AuthDeny):
|
|
509
|
-
await proxy.addCronJob(cdef)
|
|
510
|
-
|
|
511
|
-
await visi.addRule((True, ('cron', 'add')))
|
|
512
|
-
cron0 = await proxy.addCronJob(cdef)
|
|
513
|
-
cron0_iden = cron0.get('iden')
|
|
514
|
-
|
|
515
|
-
cdef = {'storm': 'inet:ipv6', 'reqs': {'hour': 2}}
|
|
516
|
-
cron1 = await proxy.addCronJob(cdef)
|
|
517
|
-
cron1_iden = cron1.get('iden')
|
|
518
|
-
|
|
519
|
-
await proxy.delCronJob(cron0_iden)
|
|
520
|
-
|
|
521
|
-
cdef = {'storm': '[test:str=foo]', 'reqs': {'now': True},
|
|
522
|
-
'incunit': 'month',
|
|
523
|
-
'incvals': 1}
|
|
524
|
-
await self.asyncraises(s_exc.BadConfValu, proxy.addCronJob(cdef))
|
|
525
|
-
|
|
526
|
-
async with core.getLocalProxy(user='newb') as proxy:
|
|
527
|
-
|
|
528
|
-
with self.raises(s_exc.AuthDeny):
|
|
529
|
-
await proxy.delCronJob(cron1_iden)
|
|
530
|
-
|
|
531
|
-
self.eq(await proxy.listCronJobs(), ())
|
|
532
|
-
await newb.addRule((True, ('cron', 'get')))
|
|
533
|
-
self.len(1, await proxy.listCronJobs())
|
|
534
|
-
|
|
535
|
-
with self.raises(s_exc.AuthDeny):
|
|
536
|
-
await proxy.disableCronJob(cron1_iden)
|
|
537
|
-
|
|
538
|
-
await newb.addRule((True, ('cron', 'set')))
|
|
539
|
-
self.none(await proxy.disableCronJob(cron1_iden))
|
|
540
|
-
|
|
541
|
-
await newb.addRule((True, ('cron', 'del')))
|
|
542
|
-
await proxy.delCronJob(cron1_iden)
|
|
543
|
-
|
|
544
499
|
async def test_agenda_stop(self):
|
|
545
500
|
|
|
546
501
|
async with self.getTestCore() as core:
|
|
@@ -727,7 +682,8 @@ class AgendaTest(s_t_utils.SynTest):
|
|
|
727
682
|
|
|
728
683
|
async with self.getTestCore() as core:
|
|
729
684
|
|
|
730
|
-
|
|
685
|
+
lowuser = await core.addUser('lowuser')
|
|
686
|
+
lowuser = lowuser.get('iden')
|
|
731
687
|
|
|
732
688
|
msgs = await core.stormlist('cron.add --hourly 32 { $lib.print(woot) }')
|
|
733
689
|
self.stormHasNoWarnErr(msgs)
|
|
@@ -735,14 +691,23 @@ class AgendaTest(s_t_utils.SynTest):
|
|
|
735
691
|
cdef = await core.callStorm('for $cron in $lib.cron.list() { return($cron) }')
|
|
736
692
|
self.eq(cdef['creator'], core.auth.rootuser.iden)
|
|
737
693
|
|
|
738
|
-
opts = {'vars': {'
|
|
739
|
-
cdef = await core.callStorm('for $cron in $lib.cron.list() { return($cron.set(creator, $
|
|
740
|
-
|
|
741
|
-
self.eq(cdef['creator'],
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
694
|
+
opts = {'vars': {'lowuser': lowuser}}
|
|
695
|
+
cdef = await core.callStorm('for $cron in $lib.cron.list() { return($cron.set(creator, $lowuser)) }',
|
|
696
|
+
opts=opts)
|
|
697
|
+
self.eq(cdef['creator'], lowuser)
|
|
698
|
+
|
|
699
|
+
opts = {'user': lowuser, 'vars': {'iden': cdef.get('iden'), 'lowuser': lowuser}}
|
|
700
|
+
q = '$cron = $lib.cron.get($iden) return ( $cron.set(creator, $lowuser) )'
|
|
701
|
+
msgs = await core.stormlist(q, opts=opts)
|
|
702
|
+
# XXX FIXME - This is an odd message since the new creator does not implicitly have
|
|
703
|
+
# access to the cronjob that is running as them.
|
|
704
|
+
self.stormIsInErr('Provided iden does not match any valid authorized cron job.', msgs)
|
|
705
|
+
|
|
706
|
+
await core.addUserRule(lowuser, (True, ('cron', 'get')))
|
|
707
|
+
opts = {'user': lowuser, 'vars': {'iden': cdef.get('iden'), 'lowuser': lowuser}}
|
|
708
|
+
q = '$cron = $lib.cron.get($iden) return ( $cron.set(creator, $lowuser) )'
|
|
709
|
+
msgs = await core.stormlist(q, opts=opts)
|
|
710
|
+
self.stormIsInErr('must have permission cron.set.creator', msgs)
|
|
746
711
|
|
|
747
712
|
async def test_agenda_fatal_run(self):
|
|
748
713
|
|
synapse/tests/test_lib_aha.py
CHANGED
|
@@ -1115,3 +1115,100 @@ class AhaTest(s_test.SynTest):
|
|
|
1115
1115
|
online = svcinfo.get('online')
|
|
1116
1116
|
self.nn(online)
|
|
1117
1117
|
self.true(ready)
|
|
1118
|
+
|
|
1119
|
+
async def test_aha_reprovision(self):
|
|
1120
|
+
with self.withNexusReplay() as stack:
|
|
1121
|
+
with self.getTestDir() as dirn:
|
|
1122
|
+
aha00dirn = s_common.gendir(dirn, 'aha00')
|
|
1123
|
+
aha01dirn = s_common.gendir(dirn, 'aha01')
|
|
1124
|
+
svc0dirn = s_common.gendir(dirn, 'svc00')
|
|
1125
|
+
svc1dirn = s_common.gendir(dirn, 'svc01')
|
|
1126
|
+
async with await s_base.Base.anit() as cm:
|
|
1127
|
+
aconf = {
|
|
1128
|
+
'aha:name': 'aha',
|
|
1129
|
+
'aha:network': 'loop.vertex.link',
|
|
1130
|
+
'provision:listen': 'ssl://aha.loop.vertex.link:0'
|
|
1131
|
+
}
|
|
1132
|
+
name = aconf.get('aha:name')
|
|
1133
|
+
netw = aconf.get('aha:network')
|
|
1134
|
+
dnsname = f'{name}.{netw}'
|
|
1135
|
+
|
|
1136
|
+
aha = await s_aha.AhaCell.anit(aha00dirn, conf=aconf)
|
|
1137
|
+
await cm.enter_context(aha)
|
|
1138
|
+
|
|
1139
|
+
addr, port = aha.provdmon.addr
|
|
1140
|
+
# update the config to reflect the dynamically bound port
|
|
1141
|
+
aha.conf['provision:listen'] = f'ssl://{dnsname}:{port}'
|
|
1142
|
+
|
|
1143
|
+
# do this config ex-post-facto due to port binding...
|
|
1144
|
+
host, ahaport = await aha.dmon.listen(f'ssl://0.0.0.0:0?hostname={dnsname}&ca={netw}')
|
|
1145
|
+
aha.conf['aha:urls'] = (f'ssl://{dnsname}:{ahaport}',)
|
|
1146
|
+
|
|
1147
|
+
onetime = await aha.addAhaSvcProv('00.svc', provinfo=None)
|
|
1148
|
+
sconf = {'aha:provision': onetime}
|
|
1149
|
+
s_common.yamlsave(sconf, svc0dirn, 'cell.yaml')
|
|
1150
|
+
svc0 = await s_cell.Cell.anit(svc0dirn, conf=sconf)
|
|
1151
|
+
await cm.enter_context(svc0)
|
|
1152
|
+
|
|
1153
|
+
onetime = await aha.addAhaSvcProv('01.svc', provinfo={'mirror': 'svc'})
|
|
1154
|
+
sconf = {'aha:provision': onetime}
|
|
1155
|
+
s_common.yamlsave(sconf, svc1dirn, 'cell.yaml')
|
|
1156
|
+
svc1 = await s_cell.Cell.anit(svc1dirn, conf=sconf)
|
|
1157
|
+
await cm.enter_context(svc1)
|
|
1158
|
+
|
|
1159
|
+
# Ensure that services have connected
|
|
1160
|
+
await asyncio.wait_for(svc1.nexsroot._mirready.wait(), timeout=6)
|
|
1161
|
+
await svc1.sync()
|
|
1162
|
+
|
|
1163
|
+
# Get Aha services
|
|
1164
|
+
snfo = await aha.getAhaSvc('01.svc.loop.vertex.link')
|
|
1165
|
+
svcinfo = snfo.get('svcinfo')
|
|
1166
|
+
ready = svcinfo.get('ready')
|
|
1167
|
+
self.true(ready)
|
|
1168
|
+
|
|
1169
|
+
await aha.fini()
|
|
1170
|
+
|
|
1171
|
+
# Now re-deploy the AHA Service and re-provision the two cells
|
|
1172
|
+
# with the same AHA configuration
|
|
1173
|
+
async with await s_base.Base.anit() as cm:
|
|
1174
|
+
aconf = {
|
|
1175
|
+
'aha:name': 'aha',
|
|
1176
|
+
'aha:network': 'loop.vertex.link',
|
|
1177
|
+
'provision:listen': 'ssl://aha.loop.vertex.link:0'
|
|
1178
|
+
}
|
|
1179
|
+
name = aconf.get('aha:name')
|
|
1180
|
+
netw = aconf.get('aha:network')
|
|
1181
|
+
dnsname = f'{name}.{netw}'
|
|
1182
|
+
|
|
1183
|
+
aha = await s_aha.AhaCell.anit(aha01dirn, conf=aconf)
|
|
1184
|
+
await cm.enter_context(aha)
|
|
1185
|
+
|
|
1186
|
+
addr, port = aha.provdmon.addr
|
|
1187
|
+
# update the config to reflect the dynamically bound port
|
|
1188
|
+
aha.conf['provision:listen'] = f'ssl://{dnsname}:{port}'
|
|
1189
|
+
|
|
1190
|
+
# do this config ex-post-facto due to port binding...
|
|
1191
|
+
host, ahaport = await aha.dmon.listen(f'ssl://0.0.0.0:0?hostname={dnsname}&ca={netw}')
|
|
1192
|
+
aha.conf['aha:urls'] = (f'ssl://{dnsname}:{ahaport}',)
|
|
1193
|
+
|
|
1194
|
+
onetime = await aha.addAhaSvcProv('00.svc', provinfo=None)
|
|
1195
|
+
sconf = {'aha:provision': onetime}
|
|
1196
|
+
s_common.yamlsave(sconf, svc0dirn, 'cell.yaml')
|
|
1197
|
+
svc0 = await s_cell.Cell.anit(svc0dirn, conf=sconf)
|
|
1198
|
+
await cm.enter_context(svc0)
|
|
1199
|
+
|
|
1200
|
+
onetime = await aha.addAhaSvcProv('01.svc', provinfo={'mirror': 'svc'})
|
|
1201
|
+
sconf = {'aha:provision': onetime}
|
|
1202
|
+
s_common.yamlsave(sconf, svc1dirn, 'cell.yaml')
|
|
1203
|
+
svc1 = await s_cell.Cell.anit(svc1dirn, conf=sconf)
|
|
1204
|
+
await cm.enter_context(svc1)
|
|
1205
|
+
|
|
1206
|
+
# Ensure that services have connected
|
|
1207
|
+
await asyncio.wait_for(svc1.nexsroot._mirready.wait(), timeout=6)
|
|
1208
|
+
await svc1.sync()
|
|
1209
|
+
|
|
1210
|
+
# Get Aha services
|
|
1211
|
+
snfo = await aha.getAhaSvc('01.svc.loop.vertex.link')
|
|
1212
|
+
svcinfo = snfo.get('svcinfo')
|
|
1213
|
+
ready = svcinfo.get('ready')
|
|
1214
|
+
self.true(ready)
|
synapse/tests/test_lib_ast.py
CHANGED
|
@@ -656,6 +656,109 @@ class AstTest(s_test.SynTest):
|
|
|
656
656
|
self.len(0, await core.nodes('[ inet:ipv4=1.2.3.4 ] :foo -> *'))
|
|
657
657
|
self.len(0, await core.nodes('[ inet:ipv4=1.2.3.4 ] :asn -> inet:asn'))
|
|
658
658
|
|
|
659
|
+
async def test_ast_edge_walknjoin(self):
|
|
660
|
+
|
|
661
|
+
async with self.getTestCore() as core:
|
|
662
|
+
|
|
663
|
+
await core.nodes('[test:str=foo :hehe=bar +(foobar)> { [ test:str=baz ] }]')
|
|
664
|
+
|
|
665
|
+
nodes = await core.nodes('test:str=foo --+> *')
|
|
666
|
+
self.len(2, nodes)
|
|
667
|
+
self.eq(('test:str', 'foo'), nodes[0].ndef)
|
|
668
|
+
self.eq(('test:str', 'baz'), nodes[1].ndef)
|
|
669
|
+
|
|
670
|
+
nodes = await core.nodes('test:str=baz <+-- *')
|
|
671
|
+
self.len(2, nodes)
|
|
672
|
+
self.eq(('test:str', 'baz'), nodes[0].ndef)
|
|
673
|
+
self.eq(('test:str', 'foo'), nodes[1].ndef)
|
|
674
|
+
|
|
675
|
+
nodes = await core.nodes('test:str=foo -(foobar)+> *')
|
|
676
|
+
self.len(2, nodes)
|
|
677
|
+
self.eq(('test:str', 'foo'), nodes[0].ndef)
|
|
678
|
+
self.eq(('test:str', 'baz'), nodes[1].ndef)
|
|
679
|
+
|
|
680
|
+
nodes = await core.nodes('test:str=baz <+(foobar)- *')
|
|
681
|
+
self.len(2, nodes)
|
|
682
|
+
self.eq(('test:str', 'baz'), nodes[0].ndef)
|
|
683
|
+
self.eq(('test:str', 'foo'), nodes[1].ndef)
|
|
684
|
+
|
|
685
|
+
await core.nodes('test:str=foo [ +(coffeeone)> { [ test:str=arabica ] } ]')
|
|
686
|
+
await core.nodes('test:str=foo [ +(coffeetwo)> { [ test:str=robusta ] } ]')
|
|
687
|
+
await core.nodes('[ test:int=28 +(coffeethree)> { test:str=arabica } ]')
|
|
688
|
+
|
|
689
|
+
nodes = await core.nodes('test:str=foo -((coffeeone, coffeetwo))+> *')
|
|
690
|
+
self.len(3, nodes)
|
|
691
|
+
self.eq(('test:str', 'foo'), nodes[0].ndef)
|
|
692
|
+
self.eq(('test:str', 'arabica'), nodes[1].ndef)
|
|
693
|
+
self.eq(('test:str', 'robusta'), nodes[2].ndef)
|
|
694
|
+
|
|
695
|
+
await core.nodes('[test:str=neato :hehe=haha +(stuff)> { [inet:ipv4=1.2.3.0/24] }]')
|
|
696
|
+
await core.nodes('[test:str=burrito :hehe=stuff <(stuff)+ { test:str=baz }]')
|
|
697
|
+
await core.nodes('test:str=neato [ <(other)+ { test:str=foo } ]')
|
|
698
|
+
|
|
699
|
+
nodes = await core.nodes('$edge=stuff test:str=neato -($edge)+> *')
|
|
700
|
+
self.len(257, nodes)
|
|
701
|
+
self.eq(('test:str', 'neato'), nodes[0].ndef)
|
|
702
|
+
for n in nodes[1:]:
|
|
703
|
+
self.eq('inet:ipv4', n.ndef[0])
|
|
704
|
+
|
|
705
|
+
nodes = await core.nodes('test:str=neato | tee { --+> * } { <+(other)- * }')
|
|
706
|
+
self.len(259, nodes)
|
|
707
|
+
self.eq(('test:str', 'neato'), nodes[0].ndef)
|
|
708
|
+
self.eq(('test:str', 'foo'), nodes[-1].ndef)
|
|
709
|
+
self.eq(('test:str', 'neato'), nodes[-2].ndef)
|
|
710
|
+
|
|
711
|
+
for n in nodes[1:257]:
|
|
712
|
+
self.eq('inet:ipv4', n.ndef[0])
|
|
713
|
+
|
|
714
|
+
await core.nodes('test:str=foo [ +(wat)> {[test:int=12]}]')
|
|
715
|
+
|
|
716
|
+
nodes = await core.nodes('test:str=foo -(other)+> test:str')
|
|
717
|
+
self.len(2, nodes)
|
|
718
|
+
self.eq(('test:str', 'foo'), nodes[0].ndef)
|
|
719
|
+
self.eq(('test:str', 'neato'), nodes[1].ndef)
|
|
720
|
+
|
|
721
|
+
with self.raises(s_exc.BadSyntax):
|
|
722
|
+
await core.nodes('test:str=neato --+> test:str')
|
|
723
|
+
|
|
724
|
+
with self.raises(s_exc.BadSyntax):
|
|
725
|
+
await core.nodes('test:str <+-- test:str')
|
|
726
|
+
|
|
727
|
+
nodes = await core.nodes('test:str=foo -(*)+> test:str')
|
|
728
|
+
self.len(5, nodes)
|
|
729
|
+
self.eq(('test:str', 'foo'), nodes[0].ndef)
|
|
730
|
+
ndefs = [n.ndef for n in nodes[1:]]
|
|
731
|
+
self.isin(('test:str', 'arabica'), ndefs)
|
|
732
|
+
self.isin(('test:str', 'robusta'), ndefs)
|
|
733
|
+
self.isin(('test:str', 'baz'), ndefs)
|
|
734
|
+
self.isin(('test:str', 'neato'), ndefs)
|
|
735
|
+
self.notin(('test:int', 12), ndefs)
|
|
736
|
+
|
|
737
|
+
nodes = await core.nodes('test:str=foo -(*)+> *')
|
|
738
|
+
self.len(6, nodes)
|
|
739
|
+
self.eq(('test:str', 'foo'), nodes[0].ndef)
|
|
740
|
+
ndefs = [n.ndef for n in nodes[1:]]
|
|
741
|
+
self.isin(('test:int', 12), ndefs)
|
|
742
|
+
|
|
743
|
+
nodes = await core.nodes('test:str=arabica <+(*)- test:str')
|
|
744
|
+
self.len(2, nodes)
|
|
745
|
+
self.eq(('test:str', 'arabica'), nodes[0].ndef)
|
|
746
|
+
self.eq(('test:str', 'foo'), nodes[1].ndef)
|
|
747
|
+
|
|
748
|
+
nodes = await core.nodes('test:str=arabica <+(*)- *')
|
|
749
|
+
self.len(3, nodes)
|
|
750
|
+
self.eq(('test:str', 'arabica'), nodes[0].ndef)
|
|
751
|
+
ndefs = [n.ndef for n in nodes[1:]]
|
|
752
|
+
self.isin(('test:str', 'foo'), ndefs)
|
|
753
|
+
self.isin(('test:int', 28), ndefs)
|
|
754
|
+
|
|
755
|
+
await core.nodes('test:str=arabica [ <(place)+ { [ test:str=coffeebar] } ]')
|
|
756
|
+
nodes = await core.nodes('test:str=arabica <+((place, coffeeone))- *')
|
|
757
|
+
self.len(3, nodes)
|
|
758
|
+
self.eq(('test:str', 'arabica'), nodes[0].ndef)
|
|
759
|
+
self.eq(('test:str', 'coffeebar'), nodes[1].ndef)
|
|
760
|
+
self.eq(('test:str', 'foo'), nodes[2].ndef)
|
|
761
|
+
|
|
659
762
|
async def test_ast_lift_filt_array(self):
|
|
660
763
|
|
|
661
764
|
async with self.getTestCore() as core:
|
|
@@ -1738,6 +1841,243 @@ class AstTest(s_test.SynTest):
|
|
|
1738
1841
|
evnt = firs[0]
|
|
1739
1842
|
self.eq(evnt[1].get('data'), {'total': 3})
|
|
1740
1843
|
|
|
1844
|
+
async def test_ast_emptyblock(self):
|
|
1845
|
+
|
|
1846
|
+
async with self.getTestCore() as core:
|
|
1847
|
+
q = '''
|
|
1848
|
+
empty {
|
|
1849
|
+
$lib.print("a fancy but empty block")
|
|
1850
|
+
}
|
|
1851
|
+
'''
|
|
1852
|
+
msgs = await core.stormlist(q)
|
|
1853
|
+
self.stormIsInPrint('a fancy but empty block', msgs)
|
|
1854
|
+
|
|
1855
|
+
q = '''
|
|
1856
|
+
empty {
|
|
1857
|
+
[test:str=neato]
|
|
1858
|
+
}
|
|
1859
|
+
[ :hehe=stuff ]
|
|
1860
|
+
'''
|
|
1861
|
+
msgs = await core.stormlist(q)
|
|
1862
|
+
nodes = [m[1] for m in msgs if m[0] == 'node']
|
|
1863
|
+
self.len(1, nodes)
|
|
1864
|
+
props = nodes[0][1]['props']
|
|
1865
|
+
self.eq('stuff', props.get('hehe'))
|
|
1866
|
+
|
|
1867
|
+
q = '''
|
|
1868
|
+
empty {
|
|
1869
|
+
$lib.print("some empty block")
|
|
1870
|
+
}
|
|
1871
|
+
[test:str=synapse]
|
|
1872
|
+
'''
|
|
1873
|
+
msgs = await core.stormlist(q)
|
|
1874
|
+
nodes = [m[1] for m in msgs if m[0] == 'node']
|
|
1875
|
+
self.len(1, nodes)
|
|
1876
|
+
self.stormIsInPrint('some empty block', msgs)
|
|
1877
|
+
|
|
1878
|
+
q = '''
|
|
1879
|
+
for $i in $lib.range(10) {
|
|
1880
|
+
if ($i > 5) {
|
|
1881
|
+
[test:int=$i]
|
|
1882
|
+
}
|
|
1883
|
+
} | empty { $lib.print(`count is {$i}`) }
|
|
1884
|
+
'''
|
|
1885
|
+
msgs = await core.stormlist(q)
|
|
1886
|
+
self.stormNotInPrint('count is', msgs)
|
|
1887
|
+
|
|
1888
|
+
q = '''
|
|
1889
|
+
for $i in $lib.range(10) {
|
|
1890
|
+
$lib.print(`count is {$i}`)
|
|
1891
|
+
} | empty { $lib.print(`pipeline is empty`) }
|
|
1892
|
+
'''
|
|
1893
|
+
msgs = await core.stormlist(q)
|
|
1894
|
+
self.stormIsInPrint('count is', msgs)
|
|
1895
|
+
self.stormIsInPrint('pipeline is empty', msgs)
|
|
1896
|
+
|
|
1897
|
+
q = '''
|
|
1898
|
+
[test:str=burrito]
|
|
1899
|
+
empty {
|
|
1900
|
+
[test:str=awesome]
|
|
1901
|
+
}
|
|
1902
|
+
'''
|
|
1903
|
+
msgs = await core.stormlist(q)
|
|
1904
|
+
nodes = [m[1] for m in msgs if m[0] == 'node']
|
|
1905
|
+
self.len(1, nodes)
|
|
1906
|
+
self.eq(('test:str', 'burrito'), nodes[0][0])
|
|
1907
|
+
|
|
1908
|
+
q = '''
|
|
1909
|
+
$lib.print("OH YEA")
|
|
1910
|
+
empty {
|
|
1911
|
+
[test:str=possum]
|
|
1912
|
+
}
|
|
1913
|
+
'''
|
|
1914
|
+
msgs = await core.stormlist(q)
|
|
1915
|
+
nodes = [m[1] for m in msgs if m[0] == 'node']
|
|
1916
|
+
self.len(1, nodes)
|
|
1917
|
+
self.eq(('test:str', 'possum'), nodes[0][0])
|
|
1918
|
+
self.stormIsInPrint('OH YEA', msgs)
|
|
1919
|
+
|
|
1920
|
+
q = '''
|
|
1921
|
+
empty {
|
|
1922
|
+
[test:str=foo]
|
|
1923
|
+
}
|
|
1924
|
+
|
|
1925
|
+
empty {
|
|
1926
|
+
[test:bstr=bar]
|
|
1927
|
+
}
|
|
1928
|
+
'''
|
|
1929
|
+
msgs = await core.stormlist(q)
|
|
1930
|
+
nodes = [m[1] for m in msgs if m[0] == 'node']
|
|
1931
|
+
self.len(1, nodes)
|
|
1932
|
+
self.eq(('test:str', 'foo'), nodes[0][0])
|
|
1933
|
+
|
|
1934
|
+
q = '''
|
|
1935
|
+
empty {
|
|
1936
|
+
$lib.print('call me')
|
|
1937
|
+
}
|
|
1938
|
+
|
|
1939
|
+
$lib.print('ishmael')
|
|
1940
|
+
|
|
1941
|
+
empty {
|
|
1942
|
+
$lib.print('some years ago')
|
|
1943
|
+
}
|
|
1944
|
+
|
|
1945
|
+
[test:str="moby dick"]
|
|
1946
|
+
|
|
1947
|
+
empty {
|
|
1948
|
+
$lib.print('never mind')
|
|
1949
|
+
}
|
|
1950
|
+
|
|
1951
|
+
empty {
|
|
1952
|
+
$lib.print('how long')
|
|
1953
|
+
}
|
|
1954
|
+
|
|
1955
|
+
[ :hehe=haha ]
|
|
1956
|
+
'''
|
|
1957
|
+
msgs = await core.stormlist(q)
|
|
1958
|
+
self.stormIsInPrint('call me', msgs)
|
|
1959
|
+
self.stormIsInPrint('ishmael', msgs)
|
|
1960
|
+
self.stormIsInPrint('some years ago', msgs)
|
|
1961
|
+
nodes = [m[1] for m in msgs if m[0] == 'node']
|
|
1962
|
+
self.len(1, nodes)
|
|
1963
|
+
self.eq(('test:str', 'moby dick'), nodes[0][0])
|
|
1964
|
+
self.eq('haha', nodes[0][1]['props']['hehe'])
|
|
1965
|
+
self.stormNotInPrint('never mind', msgs)
|
|
1966
|
+
self.stormNotInPrint('how long', msgs)
|
|
1967
|
+
|
|
1968
|
+
q = '''
|
|
1969
|
+
function foo(x) {
|
|
1970
|
+
empty {
|
|
1971
|
+
$lib.print($x)
|
|
1972
|
+
}
|
|
1973
|
+
|
|
1974
|
+
return()
|
|
1975
|
+
}
|
|
1976
|
+
|
|
1977
|
+
[test:str=biz :hehe=baz]
|
|
1978
|
+
$foo(:hehe)
|
|
1979
|
+
'''
|
|
1980
|
+
msgs = await core.stormlist(q)
|
|
1981
|
+
self.stormIsInPrint("baz", msgs)
|
|
1982
|
+
nodes = [m[1] for m in msgs if m[0] == 'node']
|
|
1983
|
+
self.len(1, nodes)
|
|
1984
|
+
self.eq(('test:str', 'biz'), nodes[0][0])
|
|
1985
|
+
|
|
1986
|
+
q = '''
|
|
1987
|
+
[test:str=coffee :hehe=pourover] $beep=:hehe | spin | empty { $lib.print("blorp") }
|
|
1988
|
+
'''
|
|
1989
|
+
msgs = await core.stormlist(q)
|
|
1990
|
+
nodes = [m[1] for m in msgs if m[0] == 'node']
|
|
1991
|
+
self.len(0, nodes)
|
|
1992
|
+
self.stormIsInPrint('blorp', msgs)
|
|
1993
|
+
|
|
1994
|
+
q = '''
|
|
1995
|
+
[test:str=latte :hehe=milk] $beep=:hehe | spin | empty { $lib.print($beep) }
|
|
1996
|
+
'''
|
|
1997
|
+
msgs = await core.stormlist(q)
|
|
1998
|
+
nodes = [m[1] for m in msgs if m[0] == 'node']
|
|
1999
|
+
self.len(0, nodes)
|
|
2000
|
+
self.stormIsInErr('Empty block query must be runtsafe', msgs)
|
|
2001
|
+
|
|
2002
|
+
q = '''
|
|
2003
|
+
function foo() {
|
|
2004
|
+
for $x in $lib.range(10) {
|
|
2005
|
+
emit $x
|
|
2006
|
+
}
|
|
2007
|
+
}
|
|
2008
|
+
|
|
2009
|
+
for $data in $foo() {
|
|
2010
|
+
if ($data > 10000) {
|
|
2011
|
+
[test:int=$data]
|
|
2012
|
+
}
|
|
2013
|
+
}
|
|
2014
|
+
|
|
2015
|
+
empty {
|
|
2016
|
+
[test:int=1000]
|
|
2017
|
+
}
|
|
2018
|
+
'''
|
|
2019
|
+
msgs = await core.stormlist(q)
|
|
2020
|
+
nodes = [m[1] for m in msgs if m[0] == 'node']
|
|
2021
|
+
self.len(1, nodes)
|
|
2022
|
+
self.eq(('test:int', 1000), nodes[0][0])
|
|
2023
|
+
|
|
2024
|
+
q = '''
|
|
2025
|
+
empty {
|
|
2026
|
+
[test:int=12345]
|
|
2027
|
+
}
|
|
2028
|
+
'''
|
|
2029
|
+
idens = [nodes[0][1]['iden'],]
|
|
2030
|
+
msgs = await core.stormlist(q, opts={'idens': idens})
|
|
2031
|
+
nodes = [m[1] for m in msgs if m[0] == 'node']
|
|
2032
|
+
self.len(1, nodes)
|
|
2033
|
+
self.eq(('test:int', 1000), nodes[0][0])
|
|
2034
|
+
|
|
2035
|
+
q = '''
|
|
2036
|
+
function foo() {
|
|
2037
|
+
empty {
|
|
2038
|
+
$lib.print('foobarbaz')
|
|
2039
|
+
}
|
|
2040
|
+
[test:int=12]
|
|
2041
|
+
}
|
|
2042
|
+
|
|
2043
|
+
yield $foo()
|
|
2044
|
+
empty {
|
|
2045
|
+
$lib.print('neato')
|
|
2046
|
+
}
|
|
2047
|
+
'''
|
|
2048
|
+
msgs = await core.stormlist(q)
|
|
2049
|
+
nodes = [m[1] for m in msgs if m[0] == 'node']
|
|
2050
|
+
self.len(1, nodes)
|
|
2051
|
+
self.eq(('test:int', 12), nodes[0][0])
|
|
2052
|
+
self.stormIsInPrint('foobarbaz', msgs)
|
|
2053
|
+
self.stormNotInPrint('neato', msgs)
|
|
2054
|
+
|
|
2055
|
+
q = '''
|
|
2056
|
+
function foo() {
|
|
2057
|
+
for $x in $lib.range(2) {
|
|
2058
|
+
emit $x
|
|
2059
|
+
empty {
|
|
2060
|
+
$lib.print(`count is {$x}`)
|
|
2061
|
+
}
|
|
2062
|
+
}
|
|
2063
|
+
}
|
|
2064
|
+
for $x in $foo() {
|
|
2065
|
+
[test:int=$x]
|
|
2066
|
+
}
|
|
2067
|
+
'''
|
|
2068
|
+
msgs = await core.stormlist(q)
|
|
2069
|
+
order = [m[0] for m in msgs]
|
|
2070
|
+
nodes = [m[1] for m in msgs if m[0] == 'node']
|
|
2071
|
+
ndefs = [n[0] for n in nodes]
|
|
2072
|
+
|
|
2073
|
+
self.len(2, nodes)
|
|
2074
|
+
self.eq(order, ['init', 'node:edits', 'node', 'print', 'node:edits', 'node', 'print', 'fini'])
|
|
2075
|
+
self.isin(('test:int', 0), ndefs)
|
|
2076
|
+
self.isin(('test:int', 1), ndefs)
|
|
2077
|
+
|
|
2078
|
+
self.stormIsInPrint('count is 0', msgs)
|
|
2079
|
+
self.stormIsInPrint('count is 1', msgs)
|
|
2080
|
+
|
|
1741
2081
|
async def test_ast_cmdargs(self):
|
|
1742
2082
|
|
|
1743
2083
|
async with self.getTestCore() as core:
|
|
@@ -2778,8 +3118,11 @@ class AstTest(s_test.SynTest):
|
|
|
2778
3118
|
self.len(2, await core.nodes('test:str +#taga*:score'))
|
|
2779
3119
|
self.len(1, await core.nodes('test:str +#tagaa:score=5'))
|
|
2780
3120
|
self.len(1, await core.nodes('test:str +#tagaa:score<(2+4)'))
|
|
3121
|
+
self.len(0, await core.nodes('test:str +#tagaa:score<-5'))
|
|
2781
3122
|
self.len(1, await core.nodes('test:str +#tagaa:score*range=(4,6)'))
|
|
3123
|
+
self.len(0, await core.nodes('test:str +#taga*:score <- *'))
|
|
2782
3124
|
self.len(1, await core.nodes('test:str +#taga*:score <(*)- *'))
|
|
3125
|
+
self.len(3, await core.nodes('test:str +#taga*:score <+(*)- *'))
|
|
2783
3126
|
self.len(2, await core.nodes('$tag=taga* test:str +#$tag:score'))
|
|
2784
3127
|
self.len(1, await core.nodes('$tag=tagaa test:str +#$tag:score=5'))
|
|
2785
3128
|
self.len(1, await core.nodes('$tag=tagaa test:str +#$tag:score*range=(4,6)'))
|
|
@@ -2850,3 +3193,62 @@ class AstTest(s_test.SynTest):
|
|
|
2850
3193
|
nodes = await core.nodes('test:type10 $foobar=:int2 +(:intprop = $foobar)')
|
|
2851
3194
|
self.len(1, nodes)
|
|
2852
3195
|
self.eq(nodes[0].ndef, ('test:type10', 'one'))
|
|
3196
|
+
|
|
3197
|
+
async def test_ast_propvalue(self):
|
|
3198
|
+
async with self.getTestCore() as core:
|
|
3199
|
+
|
|
3200
|
+
# Create node with data prop, assign data prop to var, update var
|
|
3201
|
+
q = '[ it:exec:query=(test1,) :opts=({"foo": "bar"}) ] $opts=:opts $opts.bar = "baz"'
|
|
3202
|
+
nodes = await core.nodes(q)
|
|
3203
|
+
self.len(1, nodes)
|
|
3204
|
+
self.eq(nodes[0].props.get('opts'), {'foo': 'bar'})
|
|
3205
|
+
|
|
3206
|
+
q = '[ it:exec:query=(test1,) :opts=({"foo": "bar"}) ] $opts=:opts $opts.bar = "baz" [ :opts=$opts ]'
|
|
3207
|
+
nodes = await core.nodes(q)
|
|
3208
|
+
self.len(1, nodes)
|
|
3209
|
+
self.eq(nodes[0].props.get('opts'), {'foo': 'bar', 'bar': 'baz'})
|
|
3210
|
+
|
|
3211
|
+
q = '''
|
|
3212
|
+
'''
|
|
3213
|
+
msgs = await core.stormlist('[ it:exec:query=(test2,) :opts=({"foo": "bar"}) ]')
|
|
3214
|
+
self.stormHasNoWarnErr(msgs)
|
|
3215
|
+
|
|
3216
|
+
# Lift node with data prop, assign data prop to var, update var
|
|
3217
|
+
q = 'it:exec:query=(test2,) $opts=:opts $opts.bar = "baz"'
|
|
3218
|
+
nodes = await core.nodes(q)
|
|
3219
|
+
self.len(1, nodes)
|
|
3220
|
+
self.eq(nodes[0].props.get('opts'), {'foo': 'bar'})
|
|
3221
|
+
|
|
3222
|
+
q = 'it:exec:query=(test2,) $opts=:opts $opts.bar = "baz" [ :opts=$opts ]'
|
|
3223
|
+
nodes = await core.nodes(q)
|
|
3224
|
+
self.len(1, nodes)
|
|
3225
|
+
self.eq(nodes[0].props.get('opts'), {'foo': 'bar', 'bar': 'baz'})
|
|
3226
|
+
|
|
3227
|
+
# Create node for the lift below
|
|
3228
|
+
q = '''
|
|
3229
|
+
[ it:app:snort:hit=*
|
|
3230
|
+
:flow={[ inet:flow=* :raw=({"foo": "bar"}) ]}
|
|
3231
|
+
]
|
|
3232
|
+
'''
|
|
3233
|
+
nodes = await core.nodes(q)
|
|
3234
|
+
self.len(1, nodes)
|
|
3235
|
+
|
|
3236
|
+
# Lift node, get prop via implicit pivot, assign data prop to var, update var
|
|
3237
|
+
q = f'it:app:snort:hit $raw = :flow::raw $raw.baz="box" | spin | inet:flow'
|
|
3238
|
+
nodes = await core.nodes(q)
|
|
3239
|
+
self.len(1, nodes)
|
|
3240
|
+
self.eq(nodes[0].props.get('raw'), {'foo': 'bar'})
|
|
3241
|
+
|
|
3242
|
+
q = f'it:app:snort:hit $raw = :flow::raw $raw.baz="box" | spin | inet:flow [ :raw=$raw ]'
|
|
3243
|
+
nodes = await core.nodes(q)
|
|
3244
|
+
self.len(1, nodes)
|
|
3245
|
+
self.eq(nodes[0].props.get('raw'), {'foo': 'bar', 'baz': 'box'})
|
|
3246
|
+
|
|
3247
|
+
async def test_ast_subq_runtsafety(self):
|
|
3248
|
+
|
|
3249
|
+
async with self.getTestCore() as core:
|
|
3250
|
+
msgs = await core.stormlist('$foo={[test:str=foo] return($node.value())} $lib.print($foo)')
|
|
3251
|
+
self.stormIsInPrint('foo', msgs)
|
|
3252
|
+
|
|
3253
|
+
msgs = await core.stormlist('$lib.print({[test:str=foo] return($node.value())})')
|
|
3254
|
+
self.stormIsInPrint('foo', msgs)
|