synapse 2.173.1__py311-none-any.whl → 2.175.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/axon.py +1 -1
- synapse/common.py +19 -5
- synapse/cortex.py +46 -10
- synapse/daemon.py +11 -12
- synapse/lib/agenda.py +6 -0
- synapse/lib/ast.py +5 -1
- synapse/lib/cell.py +22 -13
- synapse/lib/jupyter.py +21 -0
- synapse/lib/layer.py +124 -30
- synapse/lib/link.py +3 -2
- synapse/lib/lmdbslab.py +11 -1
- synapse/lib/modelrev.py +31 -1
- synapse/lib/modules.py +1 -0
- synapse/lib/msgpack.py +25 -3
- synapse/lib/nexus.py +26 -22
- synapse/lib/schemas.py +31 -0
- synapse/lib/snap.py +13 -0
- synapse/lib/storm.py +103 -86
- synapse/lib/stormsvc.py +30 -11
- synapse/lib/stormtypes.py +23 -9
- synapse/lib/trigger.py +0 -4
- synapse/lib/types.py +1 -1
- synapse/lib/version.py +2 -2
- synapse/lib/view.py +2 -0
- synapse/models/crypto.py +22 -0
- synapse/models/economic.py +23 -2
- synapse/models/entity.py +16 -0
- synapse/models/files.py +4 -1
- synapse/models/geopol.py +3 -0
- synapse/models/orgs.py +3 -4
- synapse/tests/test_cortex.py +13 -0
- synapse/tests/test_daemon.py +36 -0
- synapse/tests/test_lib_agenda.py +129 -1
- synapse/tests/test_lib_ast.py +56 -0
- synapse/tests/test_lib_cell.py +11 -0
- synapse/tests/test_lib_grammar.py +4 -0
- synapse/tests/test_lib_httpapi.py +1 -0
- synapse/tests/test_lib_lmdbslab.py +16 -1
- synapse/tests/test_lib_modelrev.py +86 -0
- synapse/tests/test_lib_msgpack.py +58 -8
- synapse/tests/test_lib_nexus.py +44 -1
- synapse/tests/test_lib_storm.py +134 -18
- synapse/tests/test_lib_stormsvc.py +128 -51
- synapse/tests/test_lib_stormtypes.py +43 -4
- synapse/tests/test_lib_trigger.py +23 -4
- synapse/tests/test_model_crypto.py +6 -0
- synapse/tests/test_model_economic.py +14 -1
- synapse/tests/test_model_geopol.py +3 -0
- synapse/tools/changelog.py +256 -0
- {synapse-2.173.1.dist-info → synapse-2.175.0.dist-info}/METADATA +1 -1
- {synapse-2.173.1.dist-info → synapse-2.175.0.dist-info}/RECORD +54 -52
- {synapse-2.173.1.dist-info → synapse-2.175.0.dist-info}/WHEEL +1 -1
- {synapse-2.173.1.dist-info → synapse-2.175.0.dist-info}/LICENSE +0 -0
- {synapse-2.173.1.dist-info → synapse-2.175.0.dist-info}/top_level.txt +0 -0
synapse/models/economic.py
CHANGED
|
@@ -48,11 +48,11 @@ class EconModule(s_module.CoreModule):
|
|
|
48
48
|
'doc': 'An invoice issued requesting payment.'}),
|
|
49
49
|
|
|
50
50
|
('econ:price', ('hugenum', {'norm': False}), {
|
|
51
|
-
'doc': 'The amount of money expected, required, or given in payment for something',
|
|
51
|
+
'doc': 'The amount of money expected, required, or given in payment for something.',
|
|
52
52
|
'ex': '2.20'}),
|
|
53
53
|
|
|
54
54
|
('econ:currency', ('str', {'lower': True, 'strip': False}), {
|
|
55
|
-
'doc': 'The name of a system of money in general use',
|
|
55
|
+
'doc': 'The name of a system of money in general use.',
|
|
56
56
|
'ex': 'usd'}),
|
|
57
57
|
|
|
58
58
|
('econ:fin:exchange', ('guid', {}), {
|
|
@@ -99,6 +99,7 @@ class EconModule(s_module.CoreModule):
|
|
|
99
99
|
|
|
100
100
|
'forms': (
|
|
101
101
|
|
|
102
|
+
('econ:currency', {}, ()),
|
|
102
103
|
('econ:pay:iin', {}, (
|
|
103
104
|
|
|
104
105
|
('org', ('ou:org', {}), {
|
|
@@ -205,6 +206,9 @@ class EconModule(s_module.CoreModule):
|
|
|
205
206
|
('fee', ('econ:price', {}), {
|
|
206
207
|
'doc': 'The transaction fee paid by the recipient to the payment processor.'}),
|
|
207
208
|
|
|
209
|
+
('from:cash', ('bool', {}), {
|
|
210
|
+
'doc': 'Set to true if the payment input was in cash.'}),
|
|
211
|
+
|
|
208
212
|
('from:account', ('econ:bank:account', {}), {
|
|
209
213
|
'doc': 'The bank account which made the payment.'}),
|
|
210
214
|
|
|
@@ -220,6 +224,9 @@ class EconModule(s_module.CoreModule):
|
|
|
220
224
|
('from:contact', ('ps:contact', {}), {
|
|
221
225
|
'doc': 'Contact information for the entity making the payment.'}),
|
|
222
226
|
|
|
227
|
+
('to:cash', ('bool', {}), {
|
|
228
|
+
'doc': 'Set to true if the payment output was in cash.'}),
|
|
229
|
+
|
|
223
230
|
('to:account', ('econ:bank:account', {}), {
|
|
224
231
|
'doc': 'The bank account which received the payment.'}),
|
|
225
232
|
|
|
@@ -256,6 +263,20 @@ class EconModule(s_module.CoreModule):
|
|
|
256
263
|
('receipt', ('econ:acct:receipt', {}), {
|
|
257
264
|
'doc': 'The receipt that was issued for the payment.'}),
|
|
258
265
|
|
|
266
|
+
('place', ('geo:place', {}), {
|
|
267
|
+
'doc': 'The place where the payment occurred.'}),
|
|
268
|
+
|
|
269
|
+
('place:name', ('geo:name', {}), {
|
|
270
|
+
'doc': 'The name of the place where the payment occurred.'}),
|
|
271
|
+
|
|
272
|
+
('place:address', ('geo:address', {}), {
|
|
273
|
+
'doc': 'The address of the place where the payment occurred.'}),
|
|
274
|
+
|
|
275
|
+
('place:loc', ('loc', {}), {
|
|
276
|
+
'doc': 'The loc of the place where the payment occurred.'}),
|
|
277
|
+
|
|
278
|
+
('place:latlong', ('geo:latlong', {}), {
|
|
279
|
+
'doc': 'The latlong where the payment occurred.'}),
|
|
259
280
|
)),
|
|
260
281
|
|
|
261
282
|
('econ:acct:balance', {}, (
|
synapse/models/entity.py
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import synapse.lib.module as s_module
|
|
2
|
+
|
|
3
|
+
class EntityModule(s_module.CoreModule):
|
|
4
|
+
|
|
5
|
+
def getModelDefs(self):
|
|
6
|
+
return (('entity', {
|
|
7
|
+
|
|
8
|
+
'types': (
|
|
9
|
+
('entity:name', ('str', {'onespace': True, 'lower': True}), {
|
|
10
|
+
'doc': 'A name used to refer to an entity.'}),
|
|
11
|
+
),
|
|
12
|
+
|
|
13
|
+
'forms': (
|
|
14
|
+
('entity:name', {}, ()),
|
|
15
|
+
),
|
|
16
|
+
}),)
|
synapse/models/files.py
CHANGED
|
@@ -412,7 +412,10 @@ class FileModule(s_module.CoreModule):
|
|
|
412
412
|
'doc': 'The GUID of the metadata pulled from a Windows shortcut or LNK file.',
|
|
413
413
|
}),
|
|
414
414
|
),
|
|
415
|
-
|
|
415
|
+
'edges': (
|
|
416
|
+
(('file:bytes', 'refs', 'it:dev:str'), {
|
|
417
|
+
'doc': 'The source file contains the target string.'}),
|
|
418
|
+
),
|
|
416
419
|
'forms': (
|
|
417
420
|
|
|
418
421
|
('file:bytes', {}, (
|
synapse/models/geopol.py
CHANGED
|
@@ -88,6 +88,9 @@ class PolModule(s_module.CoreModule):
|
|
|
88
88
|
|
|
89
89
|
('vitals', ('pol:vitals', {}), {
|
|
90
90
|
'doc': 'The most recent known vitals for the country.'}),
|
|
91
|
+
|
|
92
|
+
('currencies', ('array', {'type': 'econ:currency', 'sorted': True, 'uniq': True}), {
|
|
93
|
+
'doc': 'The official currencies used in the country.'}),
|
|
91
94
|
)),
|
|
92
95
|
('pol:immigration:status:type:taxonomy', {}, ()),
|
|
93
96
|
('pol:immigration:status', {}, (
|
synapse/models/orgs.py
CHANGED
|
@@ -731,8 +731,7 @@ class OuModule(s_module.CoreModule):
|
|
|
731
731
|
('contact', ('ps:contact', {}), {
|
|
732
732
|
'doc': 'The contact info for the person who holds the position.',
|
|
733
733
|
}),
|
|
734
|
-
|
|
735
|
-
('title', ('str', {'lower': True, 'onespace': True}), {
|
|
734
|
+
('title', ('ou:jobtitle', {}), {
|
|
736
735
|
'doc': 'The title of the position.',
|
|
737
736
|
}),
|
|
738
737
|
('reports', ('array', {'type': 'ou:position', 'uniq': True, 'sorted': True}), {
|
|
@@ -1024,11 +1023,11 @@ class OuModule(s_module.CoreModule):
|
|
|
1024
1023
|
('sponsors', ('array', {'type': 'ps:contact', 'uniq': True, 'sorted': True}), {
|
|
1025
1024
|
'doc': 'An array of contacts which sponsored the conference.',
|
|
1026
1025
|
}),
|
|
1027
|
-
('name', ('
|
|
1026
|
+
('name', ('entity:name', {}), {
|
|
1028
1027
|
'doc': 'The full name of the conference.',
|
|
1029
1028
|
'ex': 'defcon 2017'}),
|
|
1030
1029
|
|
|
1031
|
-
('names', ('array', {'type': '
|
|
1030
|
+
('names', ('array', {'type': 'entity:name', 'uniq': True, 'sorted': True}), {
|
|
1032
1031
|
'doc': 'An array of alternate names for the conference.'}),
|
|
1033
1032
|
|
|
1034
1033
|
('desc', ('str', {'lower': True}), {
|
synapse/tests/test_cortex.py
CHANGED
|
@@ -269,6 +269,19 @@ class CortexTest(s_t_utils.SynTest):
|
|
|
269
269
|
self.eq(await core00.getJsonObj('foo/bar'), 'zoinks')
|
|
270
270
|
self.eq(await core01.getJsonObj('foo/bar'), 'zoinks')
|
|
271
271
|
|
|
272
|
+
# Test startup sequencing. We must create the child cells prior to
|
|
273
|
+
# the nexus recover() call from occuring :)
|
|
274
|
+
with self.getTestDir() as dirn:
|
|
275
|
+
async with self.getTestCore(dirn=dirn) as core:
|
|
276
|
+
await core.callStorm('$lib.jsonstor.set((path,), hehe)')
|
|
277
|
+
|
|
278
|
+
with self.getAsyncLoggerStream('synapse.lib.nexus') as stream:
|
|
279
|
+
async with self.getTestCore(dirn=dirn) as core:
|
|
280
|
+
q = 'return( $lib.jsonstor.get((path,)) )'
|
|
281
|
+
self.eq('hehe', await core.callStorm(q))
|
|
282
|
+
stream.seek(0)
|
|
283
|
+
self.notin('Exception while replaying log', stream.read())
|
|
284
|
+
|
|
272
285
|
async def test_cortex_layer_mirror(self):
|
|
273
286
|
|
|
274
287
|
# test a layer mirror from a layer
|
synapse/tests/test_daemon.py
CHANGED
|
@@ -75,6 +75,42 @@ class DaemonTest(s_t_utils.SynTest):
|
|
|
75
75
|
async with await s_telepath.openurl(f'tcp://127.0.0.1:{port}') as proxy:
|
|
76
76
|
self.eq(proxy._ahainfo, ahainfo)
|
|
77
77
|
|
|
78
|
+
async def test_dmon_errors(self):
|
|
79
|
+
|
|
80
|
+
async with self.getTestCell(s_cell.Cell, conf={'dmon:listen': 'tcp://0.0.0.0:0/', 'auth:anon': 'root'}) as cell:
|
|
81
|
+
host, port = cell.sockaddr
|
|
82
|
+
|
|
83
|
+
async with await s_telepath.openurl(f'tcp://127.0.0.1:{port}') as prox:
|
|
84
|
+
|
|
85
|
+
# Throw an exception when trying to handle mesg outright
|
|
86
|
+
async with await prox.getPoolLink() as link:
|
|
87
|
+
with self.getAsyncLoggerStream('synapse.daemon', 'Dmon.onLinkMesg Handler: mesg=') as stream:
|
|
88
|
+
await link.tx(31337)
|
|
89
|
+
self.true(await stream.wait(timeout=6))
|
|
90
|
+
|
|
91
|
+
# Valid format; do not know what the message is.
|
|
92
|
+
async with await prox.getPoolLink() as link:
|
|
93
|
+
mesg = ('newp', {})
|
|
94
|
+
emsg = "Dmon.onLinkMesg Invalid mesg: mesg=('newp', {})"
|
|
95
|
+
with self.getAsyncLoggerStream('synapse.daemon', emsg) as stream:
|
|
96
|
+
await link.tx(mesg)
|
|
97
|
+
self.true(await stream.wait(timeout=6))
|
|
98
|
+
|
|
99
|
+
# Invalid data casues a link to fail on rx
|
|
100
|
+
async with await prox.getPoolLink() as link:
|
|
101
|
+
with self.getAsyncLoggerStream('synapse.lib.link', 'rx error') as stream:
|
|
102
|
+
byts = b'\x16\x03\x01\x02\x00\x01\x00\x01\xfc\x03\x03\xa6\xa3D\xd5\xdf%\xac\xa9\x92\xc3'
|
|
103
|
+
await link.send(byts)
|
|
104
|
+
self.true(await stream.wait(timeout=6))
|
|
105
|
+
|
|
106
|
+
# bad t2:init message
|
|
107
|
+
async with await prox.getPoolLink() as link:
|
|
108
|
+
mesg = ('t2:init', {})
|
|
109
|
+
emsg = "Error on t2:init:"
|
|
110
|
+
with self.getAsyncLoggerStream('synapse.daemon', emsg) as stream:
|
|
111
|
+
await link.tx(mesg)
|
|
112
|
+
self.true(await stream.wait(timeout=6))
|
|
113
|
+
|
|
78
114
|
class SvcApi(s_cell.CellApi, s_stormsvc.StormSvc):
|
|
79
115
|
_storm_svc_name = 'foo'
|
|
80
116
|
_storm_svc_pkgs = ( # type: ignore
|
synapse/tests/test_lib_agenda.py
CHANGED
|
@@ -331,7 +331,17 @@ class AgendaTest(s_t_utils.SynTest):
|
|
|
331
331
|
appt = await agenda.get(guid)
|
|
332
332
|
self.eq(appt.isrunning, True)
|
|
333
333
|
self.eq(core.view.iden, appt.task.info.get('view'))
|
|
334
|
-
|
|
334
|
+
|
|
335
|
+
self.true(await core._killCronTask(guid))
|
|
336
|
+
|
|
337
|
+
events = [
|
|
338
|
+
{'event': 'cron:stop', 'info': {'iden': appt.iden}},
|
|
339
|
+
]
|
|
340
|
+
|
|
341
|
+
task = core.schedCoro(s_t_utils.waitForBehold(core, events))
|
|
342
|
+
await asyncio.wait_for(task, timeout=5)
|
|
343
|
+
|
|
344
|
+
self.false(await core._killCronTask(guid))
|
|
335
345
|
|
|
336
346
|
appt = await agenda.get(guid)
|
|
337
347
|
self.eq(appt.isrunning, False)
|
|
@@ -798,3 +808,121 @@ class AgendaTest(s_t_utils.SynTest):
|
|
|
798
808
|
stream.seek(0)
|
|
799
809
|
data = stream.read()
|
|
800
810
|
self.isin("_Appt.edits() Invalid attribute received: invalid = 'newp'", data)
|
|
811
|
+
|
|
812
|
+
async def test_cron_kill(self):
|
|
813
|
+
async with self.getTestCore() as core:
|
|
814
|
+
|
|
815
|
+
data = []
|
|
816
|
+
evt = asyncio.Event()
|
|
817
|
+
|
|
818
|
+
async def task():
|
|
819
|
+
async for mesg in core.behold():
|
|
820
|
+
data.append(mesg)
|
|
821
|
+
if mesg.get('event') == 'cron:stop':
|
|
822
|
+
evt.set()
|
|
823
|
+
|
|
824
|
+
core.schedCoro(task())
|
|
825
|
+
|
|
826
|
+
q = '$q=$lib.queue.gen(test) for $i in $lib.range(60) { $lib.time.sleep(0.1) $q.put($i) }'
|
|
827
|
+
guid = s_common.guid()
|
|
828
|
+
cdef = {
|
|
829
|
+
'creator': core.auth.rootuser.iden, 'iden': guid,
|
|
830
|
+
'storm': q,
|
|
831
|
+
'reqs': {'now': True}
|
|
832
|
+
}
|
|
833
|
+
await core.addCronJob(cdef)
|
|
834
|
+
|
|
835
|
+
q = '$q=$lib.queue.gen(test) for $valu in $q.get((0), wait=(true)) { return ($valu) }'
|
|
836
|
+
valu = await core.callStorm(q)
|
|
837
|
+
self.eq(valu, 0)
|
|
838
|
+
|
|
839
|
+
opts = {'vars': {'iden': guid}}
|
|
840
|
+
get_cron = 'return($lib.cron.get($iden).pack())'
|
|
841
|
+
cdef = await core.callStorm(get_cron, opts=opts)
|
|
842
|
+
self.true(cdef.get('isrunning'))
|
|
843
|
+
|
|
844
|
+
self.true(await core.callStorm('return($lib.cron.get($iden).kill())', opts=opts))
|
|
845
|
+
|
|
846
|
+
self.true(await asyncio.wait_for(evt.wait(), timeout=12))
|
|
847
|
+
|
|
848
|
+
cdef = await core.callStorm(get_cron, opts=opts)
|
|
849
|
+
self.false(cdef.get('isrunning'))
|
|
850
|
+
|
|
851
|
+
async def test_cron_kill_pool(self):
|
|
852
|
+
|
|
853
|
+
async with self.getTestAhaProv() as aha:
|
|
854
|
+
|
|
855
|
+
import synapse.cortex as s_cortex
|
|
856
|
+
import synapse.lib.base as s_base
|
|
857
|
+
|
|
858
|
+
async with await s_base.Base.anit() as base:
|
|
859
|
+
|
|
860
|
+
with self.getTestDir() as dirn:
|
|
861
|
+
|
|
862
|
+
dirn00 = s_common.genpath(dirn, 'cell00')
|
|
863
|
+
dirn01 = s_common.genpath(dirn, 'cell01')
|
|
864
|
+
|
|
865
|
+
core00 = await base.enter_context(self.addSvcToAha(aha, '00.core', s_cortex.Cortex, dirn=dirn00))
|
|
866
|
+
provinfo = {'mirror': '00.core'}
|
|
867
|
+
core01 = await base.enter_context(self.addSvcToAha(aha, '01.core', s_cortex.Cortex, dirn=dirn01, provinfo=provinfo))
|
|
868
|
+
|
|
869
|
+
self.len(1, await core00.nodes('[inet:asn=0]'))
|
|
870
|
+
await core01.sync()
|
|
871
|
+
self.len(1, await core01.nodes('inet:asn=0'))
|
|
872
|
+
|
|
873
|
+
msgs = await core00.stormlist('aha.pool.add pool00...')
|
|
874
|
+
self.stormHasNoWarnErr(msgs)
|
|
875
|
+
self.stormIsInPrint('Created AHA service pool: pool00.loop.vertex.link', msgs)
|
|
876
|
+
|
|
877
|
+
msgs = await core00.stormlist('aha.pool.svc.add pool00... 01.core...')
|
|
878
|
+
self.stormHasNoWarnErr(msgs)
|
|
879
|
+
self.stormIsInPrint('AHA service (01.core...) added to service pool (pool00.loop.vertex.link)', msgs)
|
|
880
|
+
|
|
881
|
+
msgs = await core00.stormlist('cortex.storm.pool.set --connection-timeout 1 --sync-timeout 1 aha://pool00...')
|
|
882
|
+
self.stormHasNoWarnErr(msgs)
|
|
883
|
+
self.stormIsInPrint('Storm pool configuration set.', msgs)
|
|
884
|
+
|
|
885
|
+
await core00.stormpool.waitready(timeout=12)
|
|
886
|
+
|
|
887
|
+
data = []
|
|
888
|
+
evt = asyncio.Event()
|
|
889
|
+
|
|
890
|
+
async def task():
|
|
891
|
+
async for mesg in core00.behold():
|
|
892
|
+
data.append(mesg)
|
|
893
|
+
if mesg.get('event') == 'cron:stop':
|
|
894
|
+
evt.set()
|
|
895
|
+
|
|
896
|
+
core00.schedCoro(task())
|
|
897
|
+
|
|
898
|
+
q = '$q=$lib.queue.gen(test) for $i in $lib.range(60) { $lib.time.sleep(0.1) $q.put($i) }'
|
|
899
|
+
guid = s_common.guid()
|
|
900
|
+
cdef = {
|
|
901
|
+
'creator': core00.auth.rootuser.iden, 'iden': guid,
|
|
902
|
+
'storm': q,
|
|
903
|
+
'reqs': {'NOW': True},
|
|
904
|
+
'pool': True,
|
|
905
|
+
}
|
|
906
|
+
await core00.addCronJob(cdef)
|
|
907
|
+
|
|
908
|
+
q = '$q=$lib.queue.gen(test) for $valu in $q.get((0), wait=(true)) { return ($valu) }'
|
|
909
|
+
valu = await core00.callStorm(q, opts={'mirror': False})
|
|
910
|
+
self.eq(valu, 0)
|
|
911
|
+
|
|
912
|
+
opts = {'vars': {'iden': guid}, 'mirror': False}
|
|
913
|
+
get_cron = 'return($lib.cron.get($iden).pack())'
|
|
914
|
+
cdef = await core00.callStorm(get_cron, opts=opts)
|
|
915
|
+
self.true(cdef.get('isrunning'))
|
|
916
|
+
|
|
917
|
+
self.true(await core00.callStorm('return($lib.cron.get($iden).kill())', opts=opts))
|
|
918
|
+
|
|
919
|
+
self.true(await asyncio.wait_for(evt.wait(), timeout=12))
|
|
920
|
+
|
|
921
|
+
cdef00 = await core00.callStorm(get_cron, opts=opts)
|
|
922
|
+
self.false(cdef00.get('isrunning'))
|
|
923
|
+
|
|
924
|
+
cdef01 = await core01.callStorm(get_cron, opts=opts)
|
|
925
|
+
self.false(cdef01.get('isrunning'))
|
|
926
|
+
self.eq(cdef01.get('lastresult'), 'cancelled')
|
|
927
|
+
self.gt(cdef00['laststarttime'], 0)
|
|
928
|
+
self.eq(cdef00['laststarttime'], cdef01['laststarttime'])
|
synapse/tests/test_lib_ast.py
CHANGED
|
@@ -356,6 +356,27 @@ class AstTest(s_test.SynTest):
|
|
|
356
356
|
self.len(1, nodes)
|
|
357
357
|
self.none(nodes[0].get('.seen'))
|
|
358
358
|
|
|
359
|
+
# array var filter
|
|
360
|
+
q = '''
|
|
361
|
+
[(test:arrayprop=* :strs=(neato, burrito))
|
|
362
|
+
(test:arrayprop=* :ints=(1,2,3,4,5))] |
|
|
363
|
+
$pvar = "strs"
|
|
364
|
+
+:$pvar*[=neato]
|
|
365
|
+
'''
|
|
366
|
+
nodes = await core.nodes(q)
|
|
367
|
+
self.len(1, nodes)
|
|
368
|
+
self.eq(('neato', 'burrito'), nodes[0].get('strs'))
|
|
369
|
+
|
|
370
|
+
q = '$pvar=ints $avar=4 test:arrayprop +:$pvar*[=$avar]'
|
|
371
|
+
nodes = await core.nodes(q)
|
|
372
|
+
self.len(1, nodes)
|
|
373
|
+
self.eq((1, 2, 3, 4, 5), nodes[0].get('ints'))
|
|
374
|
+
|
|
375
|
+
q = '$pvar=strs $avar=burr test:arrayprop +:$pvar*[^=$avar]'
|
|
376
|
+
nodes = await core.nodes(q)
|
|
377
|
+
self.len(1, nodes)
|
|
378
|
+
self.eq(('neato', 'burrito'), nodes[0].get('strs'))
|
|
379
|
+
|
|
359
380
|
# Sad paths
|
|
360
381
|
q = '[test:str=newp -.newp]'
|
|
361
382
|
await self.asyncraises(s_exc.NoSuchProp, core.nodes(q))
|
|
@@ -692,6 +713,41 @@ class AstTest(s_test.SynTest):
|
|
|
692
713
|
self.len(3, await core.nodes('test:str=ndefs :ndefs -> *'))
|
|
693
714
|
self.len(2, await core.nodes('test:str=ndefs :ndefs -> it:dev:int'))
|
|
694
715
|
|
|
716
|
+
await core.nodes('[ risk:technique:masquerade=* :node=(it:dev:int, 1) ]')
|
|
717
|
+
nodes = await core.nodes('it:dev:int=1 <- *')
|
|
718
|
+
self.len(2, nodes)
|
|
719
|
+
forms = [node.ndef[0] for node in nodes]
|
|
720
|
+
self.sorteq(forms, ['test:str', 'risk:technique:masquerade'])
|
|
721
|
+
|
|
722
|
+
await core.nodes('risk:technique:masquerade [ :target=(it:dev:int, 1) ]')
|
|
723
|
+
nodes = await core.nodes('it:dev:int=1 <- *')
|
|
724
|
+
self.len(2, nodes)
|
|
725
|
+
forms = [node.ndef[0] for node in nodes]
|
|
726
|
+
self.sorteq(forms, ['test:str', 'risk:technique:masquerade'])
|
|
727
|
+
|
|
728
|
+
await core.nodes('risk:technique:masquerade [ :target=(it:dev:int, 2) ]')
|
|
729
|
+
nodes = await core.nodes('it:dev:int=1 <- *')
|
|
730
|
+
self.len(2, nodes)
|
|
731
|
+
forms = [node.ndef[0] for node in nodes]
|
|
732
|
+
self.sorteq(forms, ['test:str', 'risk:technique:masquerade'])
|
|
733
|
+
|
|
734
|
+
await core.nodes('risk:technique:masquerade [ -:node ]')
|
|
735
|
+
nodes = await core.nodes('it:dev:int=1 <- *')
|
|
736
|
+
self.len(1, nodes)
|
|
737
|
+
self.eq('test:str', nodes[0].ndef[0])
|
|
738
|
+
|
|
739
|
+
await core.nodes('test:str=ndefs [ :ndefs-=(it:dev:int, 1) ]')
|
|
740
|
+
self.len(0, await core.nodes('it:dev:int=1 <- *'))
|
|
741
|
+
nodes = await core.nodes('it:dev:int=2 <- *')
|
|
742
|
+
self.len(2, nodes)
|
|
743
|
+
forms = [node.ndef[0] for node in nodes]
|
|
744
|
+
self.sorteq(forms, ['test:str', 'risk:technique:masquerade'])
|
|
745
|
+
|
|
746
|
+
await core.nodes('risk:technique:masquerade [ -:target ]')
|
|
747
|
+
await core.nodes('test:str=ndefs [ -:ndefs ]')
|
|
748
|
+
self.len(0, await core.nodes('it:dev:int=1 <- *'))
|
|
749
|
+
self.len(0, await core.nodes('it:dev:int=2 <- *'))
|
|
750
|
+
|
|
695
751
|
async def test_ast_pivot(self):
|
|
696
752
|
# a general purpose pivot test. come on in!
|
|
697
753
|
async with self.getTestCore() as core:
|
synapse/tests/test_lib_cell.py
CHANGED
|
@@ -503,6 +503,13 @@ class CellTest(s_t_utils.SynTest):
|
|
|
503
503
|
cell.COMMIT = 'mycommit'
|
|
504
504
|
cell.VERSION = (1, 2, 3)
|
|
505
505
|
cell.VERSTRING = '1.2.3'
|
|
506
|
+
|
|
507
|
+
http_info = []
|
|
508
|
+
host, port = await cell.addHttpsPort(0)
|
|
509
|
+
http_info.append({'host': host, 'port': port})
|
|
510
|
+
host, port = await cell.addHttpsPort(0, host='127.0.0.1')
|
|
511
|
+
http_info.append({'host': host, 'port': port})
|
|
512
|
+
|
|
506
513
|
async with cell.getLocalProxy() as prox:
|
|
507
514
|
info = await prox.getCellInfo()
|
|
508
515
|
# Cell information
|
|
@@ -527,6 +534,10 @@ class CellTest(s_t_utils.SynTest):
|
|
|
527
534
|
self.eq(snfo.get('verstring'), s_version.verstring),
|
|
528
535
|
self.eq(snfo.get('commit'), s_version.commit)
|
|
529
536
|
|
|
537
|
+
netw = cnfo.get('network')
|
|
538
|
+
https = netw.get('https')
|
|
539
|
+
self.eq(https, http_info)
|
|
540
|
+
|
|
530
541
|
async def test_cell_dyncall(self):
|
|
531
542
|
|
|
532
543
|
with self.getTestDir() as dirn:
|
|
@@ -721,6 +721,8 @@ Queries = [
|
|
|
721
721
|
'$foo=({"bar": null})',
|
|
722
722
|
'$p="names" ps:contact:name=foo [ :$p?+=bar ]',
|
|
723
723
|
'$p="names" ps:contact:name=foo [ :$p?-=bar ]',
|
|
724
|
+
'$pvar=stuff test:arrayprop +:$pvar*[=neato]',
|
|
725
|
+
'$pvar=ints test:arrayprop +:$pvar*[=$othervar]',
|
|
724
726
|
]
|
|
725
727
|
|
|
726
728
|
# Generated with print_parse_list below
|
|
@@ -1346,6 +1348,8 @@ _ParseResults = [
|
|
|
1346
1348
|
'Query: [SetVarOper: [Const: foo, DollarExpr: [ExprDict: [Const: bar, Const: None]]]]',
|
|
1347
1349
|
'Query: [SetVarOper: [Const: p, Const: names], LiftPropBy: [Const: ps:contact:name, Const: =, Const: foo], EditPropSet: [RelProp: [VarValue: [Const: p]], Const: ?+=, Const: bar]]',
|
|
1348
1350
|
'Query: [SetVarOper: [Const: p, Const: names], LiftPropBy: [Const: ps:contact:name, Const: =, Const: foo], EditPropSet: [RelProp: [VarValue: [Const: p]], Const: ?-=, Const: bar]]',
|
|
1351
|
+
'Query: [SetVarOper: [Const: pvar, Const: stuff], LiftProp: [Const: test:arrayprop], FiltOper: [Const: +, ArrayCond: [RelProp: [VarValue: [Const: pvar]], Const: =, Const: neato]]]',
|
|
1352
|
+
'Query: [SetVarOper: [Const: pvar, Const: ints], LiftProp: [Const: test:arrayprop], FiltOper: [Const: +, ArrayCond: [RelProp: [VarValue: [Const: pvar]], Const: =, VarValue: [Const: othervar]]]]',
|
|
1349
1353
|
]
|
|
1350
1354
|
|
|
1351
1355
|
class GrammarTest(s_t_utils.SynTest):
|
|
@@ -916,6 +916,7 @@ class HttpApiTest(s_tests.SynTest):
|
|
|
916
916
|
await core.callStorm('$c = $lib.cron.get($cron) $c.set("doc", "some docs")', opts=opts)
|
|
917
917
|
await core.callStorm('cron.del $cron', opts=opts)
|
|
918
918
|
|
|
919
|
+
await core.addStormPkg(spkg)
|
|
919
920
|
await core.addStormPkg(spkg)
|
|
920
921
|
await core.addStormSvc(ssvc)
|
|
921
922
|
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import os
|
|
2
|
+
import json
|
|
2
3
|
import asyncio
|
|
3
4
|
import pathlib
|
|
4
5
|
import multiprocessing
|
|
@@ -350,7 +351,7 @@ class LmdbSlabTest(s_t_utils.SynTest):
|
|
|
350
351
|
with self.getTestDir() as dirn, patch('synapse.lib.lmdbslab.Slab.WARN_COMMIT_TIME_MS', 1), \
|
|
351
352
|
patch('synapse.common.now', self.simplenow):
|
|
352
353
|
path = os.path.join(dirn, 'test.lmdb')
|
|
353
|
-
with self.
|
|
354
|
+
with self.getStructuredAsyncLoggerStream('synapse.lib.lmdbslab', 'Commit with') as stream:
|
|
354
355
|
async with await s_lmdbslab.Slab.anit(path, map_size=100000) as slab:
|
|
355
356
|
foo = slab.initdb('foo', dupsort=True)
|
|
356
357
|
byts = b'\x00' * 256
|
|
@@ -358,6 +359,20 @@ class LmdbSlabTest(s_t_utils.SynTest):
|
|
|
358
359
|
slab.put(b'\xff\xff\xff\xff' + s_common.guid(i).encode('utf8'), byts, db=foo)
|
|
359
360
|
self.true(await stream.wait(timeout=1))
|
|
360
361
|
|
|
362
|
+
data = stream.getvalue()
|
|
363
|
+
msgs = [json.loads(m) for m in data.split('\\n') if m]
|
|
364
|
+
self.gt(len(msgs), 0)
|
|
365
|
+
self.nn(msgs[0].get('delta'))
|
|
366
|
+
self.nn(msgs[0].get('path'))
|
|
367
|
+
self.nn(msgs[0].get('xactopslen'))
|
|
368
|
+
self.sorteq([
|
|
369
|
+
'vm.swappiness',
|
|
370
|
+
'vm.dirty_expire_centisecs',
|
|
371
|
+
'vm.dirty_writeback_centisecs',
|
|
372
|
+
'vm.dirty_background_ratio',
|
|
373
|
+
'vm.dirty_ratio',
|
|
374
|
+
], msgs[0].get('sysctls', {}).keys())
|
|
375
|
+
|
|
361
376
|
async def test_lmdbslab_max_replay(self):
|
|
362
377
|
with self.getTestDir() as dirn:
|
|
363
378
|
path = os.path.join(dirn, 'test.lmdb')
|
|
@@ -473,3 +473,89 @@ class ModelRevTest(s_tests.SynTest):
|
|
|
473
473
|
nodes = await core.nodes('it:mitre:attack:technique=T0100')
|
|
474
474
|
self.len(1, nodes)
|
|
475
475
|
self.eq('lockpicking', nodes[0].get('name'))
|
|
476
|
+
|
|
477
|
+
async def test_modelrev_0_2_25(self):
|
|
478
|
+
async with self.getRegrCore('model-0.2.25') as core:
|
|
479
|
+
|
|
480
|
+
self.len(1, await core.nodes('econ:currency=usd'))
|
|
481
|
+
|
|
482
|
+
nodes = await core.nodes('ou:conference')
|
|
483
|
+
self.len(3, nodes)
|
|
484
|
+
names = [n.get('name') for n in nodes]
|
|
485
|
+
self.sorteq(names, (
|
|
486
|
+
'sleuthcon',
|
|
487
|
+
'defcon',
|
|
488
|
+
'recon',
|
|
489
|
+
))
|
|
490
|
+
|
|
491
|
+
namess = [n.get('names') for n in nodes]
|
|
492
|
+
self.sorteq(namess, (
|
|
493
|
+
('defcon 2024',),
|
|
494
|
+
('recon 2024 conference',),
|
|
495
|
+
('sleuthcon 2024',),
|
|
496
|
+
))
|
|
497
|
+
|
|
498
|
+
connames = (
|
|
499
|
+
'sleuthcon', 'sleuthcon 2024',
|
|
500
|
+
'defcon', 'defcon 2024',
|
|
501
|
+
'recon', 'recon 2024 conference',
|
|
502
|
+
)
|
|
503
|
+
|
|
504
|
+
nodes = await core.nodes('entity:name')
|
|
505
|
+
self.len(6, nodes)
|
|
506
|
+
names = [n.ndef[1] for n in nodes]
|
|
507
|
+
self.sorteq(names, connames)
|
|
508
|
+
|
|
509
|
+
nodes = await core.nodes('ou:conference -> entity:name')
|
|
510
|
+
self.len(6, nodes)
|
|
511
|
+
names = [n.ndef[1] for n in nodes]
|
|
512
|
+
self.sorteq(names, connames)
|
|
513
|
+
|
|
514
|
+
positions = (
|
|
515
|
+
'president of the united states',
|
|
516
|
+
'vice president of the united states',
|
|
517
|
+
)
|
|
518
|
+
|
|
519
|
+
nodes = await core.nodes('ou:position')
|
|
520
|
+
self.len(2, nodes)
|
|
521
|
+
titles = [n.get('title') for n in nodes]
|
|
522
|
+
self.sorteq(titles, positions)
|
|
523
|
+
|
|
524
|
+
nodes = await core.nodes('ou:jobtitle')
|
|
525
|
+
self.len(2, nodes)
|
|
526
|
+
titles = [n.ndef[1] for n in nodes]
|
|
527
|
+
self.sorteq(titles, positions)
|
|
528
|
+
|
|
529
|
+
nodes = await core.nodes('ou:position -> ou:jobtitle')
|
|
530
|
+
self.len(2, nodes)
|
|
531
|
+
titles = [n.ndef[1] for n in nodes]
|
|
532
|
+
self.sorteq(titles, positions)
|
|
533
|
+
|
|
534
|
+
async def test_modelrev_0_2_26(self):
|
|
535
|
+
async with self.getRegrCore('model-0.2.26') as core:
|
|
536
|
+
|
|
537
|
+
nodes = await core.nodes('it:dev:int=1 <- *')
|
|
538
|
+
self.len(3, nodes)
|
|
539
|
+
forms = [node.ndef[0] for node in nodes]
|
|
540
|
+
self.sorteq(forms, ['risk:vulnerable', 'risk:vulnerable', 'inet:fqdn'])
|
|
541
|
+
|
|
542
|
+
nodes = await core.nodes('it:dev:int=2 <- *')
|
|
543
|
+
self.len(2, nodes)
|
|
544
|
+
forms = [node.ndef[0] for node in nodes]
|
|
545
|
+
self.sorteq(forms, ['inet:fqdn', 'inet:fqdn'])
|
|
546
|
+
|
|
547
|
+
nodes = await core.nodes('it:dev:int=3 <- *')
|
|
548
|
+
self.len(1, nodes)
|
|
549
|
+
self.eq(nodes[0].ndef[0], 'risk:vulnerable')
|
|
550
|
+
|
|
551
|
+
nodes = await core.nodes('it:dev:int=4 <- *')
|
|
552
|
+
self.len(1, nodes)
|
|
553
|
+
self.eq(nodes[0].ndef[0], 'inet:fqdn')
|
|
554
|
+
|
|
555
|
+
nodes = await core.nodes('risk:vulnerable:node=(it:dev:int, 1)')
|
|
556
|
+
self.len(2, nodes)
|
|
557
|
+
|
|
558
|
+
rnodes = await core.nodes('reverse(risk:vulnerable:node=(it:dev:int, 1))')
|
|
559
|
+
self.len(2, rnodes)
|
|
560
|
+
|
|
561
|
+
self.eq([node.ndef[0] for node in nodes], [node.ndef[0] for node in reversed(rnodes)])
|