synapse 2.196.0__py311-none-any.whl → 2.198.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 +3 -0
- synapse/common.py +3 -0
- synapse/cortex.py +13 -11
- synapse/cryotank.py +2 -2
- synapse/lib/aha.py +3 -0
- synapse/lib/ast.py +277 -165
- synapse/lib/auth.py +39 -11
- synapse/lib/cell.py +24 -6
- synapse/lib/config.py +3 -3
- synapse/lib/hive.py +2 -1
- synapse/lib/hiveauth.py +10 -1
- synapse/lib/jsonstor.py +6 -5
- synapse/lib/layer.py +6 -5
- synapse/lib/multislabseqn.py +2 -2
- synapse/lib/node.py +10 -4
- synapse/lib/parser.py +46 -21
- synapse/lib/schemas.py +491 -1
- synapse/lib/snap.py +68 -26
- synapse/lib/storm.lark +13 -11
- synapse/lib/storm.py +13 -395
- synapse/lib/storm_format.py +3 -2
- synapse/lib/stormlib/graph.py +0 -61
- synapse/lib/stormlib/index.py +52 -0
- synapse/lib/stormtypes.py +16 -5
- synapse/lib/task.py +13 -2
- synapse/lib/urlhelp.py +1 -1
- synapse/lib/version.py +2 -2
- synapse/models/doc.py +62 -0
- synapse/models/infotech.py +18 -0
- synapse/models/orgs.py +6 -4
- synapse/models/risk.py +9 -0
- synapse/models/syn.py +18 -2
- synapse/tests/files/stormpkg/badendpoints.yaml +7 -0
- synapse/tests/files/stormpkg/testpkg.yaml +8 -0
- synapse/tests/test_cortex.py +108 -0
- synapse/tests/test_datamodel.py +7 -0
- synapse/tests/test_lib_aha.py +12 -42
- synapse/tests/test_lib_ast.py +57 -0
- synapse/tests/test_lib_auth.py +143 -2
- synapse/tests/test_lib_boss.py +15 -6
- synapse/tests/test_lib_cell.py +43 -0
- synapse/tests/test_lib_grammar.py +54 -2
- synapse/tests/test_lib_lmdbslab.py +24 -0
- synapse/tests/test_lib_storm.py +20 -0
- synapse/tests/test_lib_stormlib_index.py +39 -0
- synapse/tests/test_lib_stormlib_macro.py +3 -3
- synapse/tests/test_lib_stormtypes.py +14 -2
- synapse/tests/test_lib_task.py +31 -13
- synapse/tests/test_model_doc.py +38 -0
- synapse/tests/test_model_infotech.py +13 -0
- synapse/tests/test_model_orgs.py +7 -0
- synapse/tests/test_model_risk.py +6 -0
- synapse/tests/test_model_syn.py +58 -0
- synapse/tests/test_tools_genpkg.py +10 -0
- synapse/tools/genpkg.py +2 -2
- synapse/tools/hive/load.py +1 -0
- {synapse-2.196.0.dist-info → synapse-2.198.0.dist-info}/METADATA +1 -1
- {synapse-2.196.0.dist-info → synapse-2.198.0.dist-info}/RECORD +61 -58
- {synapse-2.196.0.dist-info → synapse-2.198.0.dist-info}/LICENSE +0 -0
- {synapse-2.196.0.dist-info → synapse-2.198.0.dist-info}/WHEEL +0 -0
- {synapse-2.196.0.dist-info → synapse-2.198.0.dist-info}/top_level.txt +0 -0
synapse/lib/stormtypes.py
CHANGED
|
@@ -3490,7 +3490,11 @@ class LibRegx(Lib):
|
|
|
3490
3490
|
lkey = (pattern, flags)
|
|
3491
3491
|
regx = self.compiled.get(lkey)
|
|
3492
3492
|
if regx is None:
|
|
3493
|
-
|
|
3493
|
+
try:
|
|
3494
|
+
regx = self.compiled[lkey] = regex.compile(pattern, flags=flags)
|
|
3495
|
+
except (regex.error, ValueError) as e:
|
|
3496
|
+
mesg = f'Error compiling regex pattern: {e}: pattern="{s_common.trimText(pattern)}"'
|
|
3497
|
+
raise s_exc.BadArg(mesg=mesg) from None
|
|
3494
3498
|
return regx
|
|
3495
3499
|
|
|
3496
3500
|
@stormfunc(readonly=True)
|
|
@@ -3500,7 +3504,12 @@ class LibRegx(Lib):
|
|
|
3500
3504
|
pattern = await tostr(pattern)
|
|
3501
3505
|
replace = await tostr(replace)
|
|
3502
3506
|
regx = await self._getRegx(pattern, flags)
|
|
3503
|
-
|
|
3507
|
+
|
|
3508
|
+
try:
|
|
3509
|
+
return regx.sub(replace, text)
|
|
3510
|
+
except (regex.error, IndexError) as e:
|
|
3511
|
+
mesg = f'$lib.regex.replace() error: {e}'
|
|
3512
|
+
raise s_exc.BadArg(mesg=mesg) from None
|
|
3504
3513
|
|
|
3505
3514
|
@stormfunc(readonly=True)
|
|
3506
3515
|
async def matches(self, pattern, text, flags=0):
|
|
@@ -6839,7 +6848,8 @@ class Layer(Prim):
|
|
|
6839
6848
|
Implements the Storm api for a layer instance.
|
|
6840
6849
|
'''
|
|
6841
6850
|
_storm_locals = (
|
|
6842
|
-
{'name': 'iden', 'desc': 'The iden of the Layer.', 'type': 'str'
|
|
6851
|
+
{'name': 'iden', 'desc': 'The iden of the Layer.', 'type': 'str'},
|
|
6852
|
+
{'name': 'name', 'desc': 'The name of the Layer.', 'type': 'str'},
|
|
6843
6853
|
{'name': 'set', 'desc': 'Set an arbitrary value in the Layer definition.',
|
|
6844
6854
|
'type': {'type': 'function', '_funcname': '_methLayerSet',
|
|
6845
6855
|
'args': (
|
|
@@ -7194,6 +7204,7 @@ class Layer(Prim):
|
|
|
7194
7204
|
|
|
7195
7205
|
self.locls.update(self.getObjLocals())
|
|
7196
7206
|
self.locls['iden'] = self.valu.get('iden')
|
|
7207
|
+
self.locls['name'] = self.valu.get('name')
|
|
7197
7208
|
|
|
7198
7209
|
def __hash__(self):
|
|
7199
7210
|
return hash((self._storm_typename, self.locls['iden']))
|
|
@@ -9866,7 +9877,7 @@ async def tostor(valu, isndef=False):
|
|
|
9866
9877
|
retn = []
|
|
9867
9878
|
for v in valu:
|
|
9868
9879
|
try:
|
|
9869
|
-
retn.append(await tostor(v))
|
|
9880
|
+
retn.append(await tostor(v, isndef=isndef))
|
|
9870
9881
|
except s_exc.NoSuchType:
|
|
9871
9882
|
pass
|
|
9872
9883
|
return tuple(retn)
|
|
@@ -9875,7 +9886,7 @@ async def tostor(valu, isndef=False):
|
|
|
9875
9886
|
retn = {}
|
|
9876
9887
|
for k, v in valu.items():
|
|
9877
9888
|
try:
|
|
9878
|
-
retn[k] = await tostor(v)
|
|
9889
|
+
retn[k] = await tostor(v, isndef=isndef)
|
|
9879
9890
|
except s_exc.NoSuchType:
|
|
9880
9891
|
pass
|
|
9881
9892
|
return retn
|
synapse/lib/task.py
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import copy
|
|
2
1
|
import asyncio
|
|
3
2
|
import logging
|
|
4
3
|
|
|
@@ -6,6 +5,7 @@ import synapse.exc as s_exc
|
|
|
6
5
|
import synapse.common as s_common
|
|
7
6
|
|
|
8
7
|
import synapse.lib.base as s_base
|
|
8
|
+
import synapse.lib.msgpack as s_msgpack
|
|
9
9
|
|
|
10
10
|
logger = logging.getLogger(__name__)
|
|
11
11
|
|
|
@@ -104,7 +104,7 @@ class Task(s_base.Base):
|
|
|
104
104
|
pask = {
|
|
105
105
|
'iden': self.iden,
|
|
106
106
|
'name': self.name,
|
|
107
|
-
'info':
|
|
107
|
+
'info': s_msgpack.deepcopy(self.info),
|
|
108
108
|
'tick': self.tick,
|
|
109
109
|
'user': 'root',
|
|
110
110
|
'kids': {i: k.pack() for i, k in self.kids.items()},
|
|
@@ -115,6 +115,17 @@ class Task(s_base.Base):
|
|
|
115
115
|
|
|
116
116
|
return pask
|
|
117
117
|
|
|
118
|
+
def packv2(self):
|
|
119
|
+
return {
|
|
120
|
+
'iden': self.iden,
|
|
121
|
+
'name': self.name,
|
|
122
|
+
'info': s_msgpack.deepcopy(self.info),
|
|
123
|
+
'tick': self.tick,
|
|
124
|
+
'user': self.user.iden,
|
|
125
|
+
'username': self.user.name,
|
|
126
|
+
'kids': {i: k.packv2() for i, k in self.kids.items()},
|
|
127
|
+
}
|
|
128
|
+
|
|
118
129
|
def loop():
|
|
119
130
|
try:
|
|
120
131
|
return asyncio.get_running_loop()
|
synapse/lib/urlhelp.py
CHANGED
|
@@ -13,7 +13,7 @@ def chopurl(url):
|
|
|
13
13
|
'''
|
|
14
14
|
ret = {}
|
|
15
15
|
if url.find('://') == -1:
|
|
16
|
-
raise s_exc.BadUrl(':// not found in [{}]!'.format(url))
|
|
16
|
+
raise s_exc.BadUrl(mesg=':// not found in [{}]!'.format(url))
|
|
17
17
|
|
|
18
18
|
scheme, remain = url.split('://', 1)
|
|
19
19
|
ret['scheme'] = scheme.lower()
|
synapse/lib/version.py
CHANGED
|
@@ -223,6 +223,6 @@ def reqVersion(valu, reqver,
|
|
|
223
223
|
##############################################################################
|
|
224
224
|
# The following are touched during the release process by bumpversion.
|
|
225
225
|
# Do not modify these directly.
|
|
226
|
-
version = (2,
|
|
226
|
+
version = (2, 198, 0)
|
|
227
227
|
verstring = '.'.join([str(x) for x in version])
|
|
228
|
-
commit = '
|
|
228
|
+
commit = '047e5e996d0bcaad4ada4ea390a726aca1abba9b'
|
synapse/models/doc.py
CHANGED
|
@@ -77,6 +77,30 @@ class DocModule(s_module.CoreModule):
|
|
|
77
77
|
'documents': 'standards',
|
|
78
78
|
'type': 'doc:standard:type:taxonomy'},
|
|
79
79
|
'doc': 'A group of requirements which define how to implement a policy or goal.'}),
|
|
80
|
+
|
|
81
|
+
('doc:requirement:type:taxonomy', ('taxonomy', {}), {
|
|
82
|
+
'interfaces': ('meta:taxonomy',),
|
|
83
|
+
'doc': 'A taxonomy of requirement types.'}),
|
|
84
|
+
|
|
85
|
+
('doc:requirement', ('guid', {}), {
|
|
86
|
+
'interfaces': ('doc:document',),
|
|
87
|
+
'template': {
|
|
88
|
+
'document': 'requirement',
|
|
89
|
+
'documents': 'requirements',
|
|
90
|
+
'type': 'doc:requirement:type:taxonomy'},
|
|
91
|
+
'doc': 'A single requirement, often defined by a standard.'}),
|
|
92
|
+
|
|
93
|
+
('doc:resume:type:taxonomy', ('taxonomy', {}), {
|
|
94
|
+
'interfaces': ('meta:taxonomy',),
|
|
95
|
+
'doc': 'A taxonomy of resume types.'}),
|
|
96
|
+
|
|
97
|
+
('doc:resume', ('guid', {}), {
|
|
98
|
+
'interfaces': ('doc:document',),
|
|
99
|
+
'template': {
|
|
100
|
+
'document': 'resume',
|
|
101
|
+
'documents': 'resumes',
|
|
102
|
+
'type': 'doc:resume:type:taxonomy'},
|
|
103
|
+
'doc': 'A CV/resume document.'}),
|
|
80
104
|
),
|
|
81
105
|
'forms': (
|
|
82
106
|
|
|
@@ -88,6 +112,44 @@ class DocModule(s_module.CoreModule):
|
|
|
88
112
|
('policy', ('doc:policy', {}), {
|
|
89
113
|
'doc': 'The policy which was used to derive the standard.'}),
|
|
90
114
|
)),
|
|
115
|
+
|
|
116
|
+
('doc:requirement:type:taxonomy', {}, ()),
|
|
117
|
+
('doc:requirement', {}, (
|
|
118
|
+
|
|
119
|
+
('summary', ('str', {}), {
|
|
120
|
+
'disp': {'hint': 'text'},
|
|
121
|
+
'doc': 'A summary of the requirement definition.'}),
|
|
122
|
+
|
|
123
|
+
('optional', ('bool', {}), {
|
|
124
|
+
'doc': 'Set to true if the requirement is optional as defined by the standard.'}),
|
|
125
|
+
|
|
126
|
+
('priority', ('meta:priority', {}), {
|
|
127
|
+
'doc': 'The priority of the requirement as defined by the standard.'}),
|
|
128
|
+
|
|
129
|
+
('standard', ('doc:standard', {}), {
|
|
130
|
+
'doc': 'The standard which defined the requirement.'}),
|
|
131
|
+
)),
|
|
132
|
+
|
|
133
|
+
('doc:resume:type:taxonomy', {}, ()),
|
|
134
|
+
('doc:resume', {}, (
|
|
135
|
+
|
|
136
|
+
('contact', ('ps:contact', {}), {
|
|
137
|
+
'doc': 'Contact information for subject of the resume.'}),
|
|
138
|
+
|
|
139
|
+
('summary', ('str', {}), {
|
|
140
|
+
'disp': {'hint': 'text'},
|
|
141
|
+
'doc': 'The summary of qualifications from the resume.'}),
|
|
142
|
+
|
|
143
|
+
('workhist', ('array', {'type': 'ps:workhist', 'sorted': True, 'uniq': True}), {
|
|
144
|
+
'doc': 'Work history described in the resume.'}),
|
|
145
|
+
|
|
146
|
+
('education', ('array', {'type': 'ps:education', 'sorted': True, 'uniq': True}), {
|
|
147
|
+
'doc': 'Education experience described in the resume.'}),
|
|
148
|
+
|
|
149
|
+
('achievements', ('array', {'type': 'ps:achievement', 'sorted': True, 'uniq': True}), {
|
|
150
|
+
'doc': 'Achievements described in the resume.'}),
|
|
151
|
+
|
|
152
|
+
)),
|
|
91
153
|
),
|
|
92
154
|
'edges': (),
|
|
93
155
|
}),)
|
synapse/models/infotech.py
CHANGED
|
@@ -1252,6 +1252,15 @@ class ItModule(s_module.CoreModule):
|
|
|
1252
1252
|
('product', ('it:prod:softver', {}), {
|
|
1253
1253
|
'doc': 'The software which produced the log entry.'}),
|
|
1254
1254
|
|
|
1255
|
+
('service:platform', ('inet:service:platform', {}), {
|
|
1256
|
+
'doc': 'The service platform which generated the log event.'}),
|
|
1257
|
+
|
|
1258
|
+
('service:instance', ('inet:service:instance', {}), {
|
|
1259
|
+
'doc': 'The service instance which generated the log event.'}),
|
|
1260
|
+
|
|
1261
|
+
('service:account', ('inet:service:account', {}), {
|
|
1262
|
+
'doc': 'The service account which generated the log event.'}),
|
|
1263
|
+
|
|
1255
1264
|
)),
|
|
1256
1265
|
('it:domain', {}, (
|
|
1257
1266
|
('name', ('str', {'lower': True, 'onespace': True}), {
|
|
@@ -2587,6 +2596,15 @@ class ItModule(s_module.CoreModule):
|
|
|
2587
2596
|
|
|
2588
2597
|
('synuser', ('syn:user', {}), {
|
|
2589
2598
|
'doc': 'The synapse user who executed the query.'}),
|
|
2599
|
+
|
|
2600
|
+
('service:platform', ('inet:service:platform', {}), {
|
|
2601
|
+
'doc': 'The service platform which was queried.'}),
|
|
2602
|
+
|
|
2603
|
+
('service:instance', ('inet:service:instance', {}), {
|
|
2604
|
+
'doc': 'The service instance which was queried.'}),
|
|
2605
|
+
|
|
2606
|
+
('service:account', ('inet:service:account', {}), {
|
|
2607
|
+
'doc': 'The service account which ran the query.'}),
|
|
2590
2608
|
)),
|
|
2591
2609
|
('it:exec:thread', {}, (
|
|
2592
2610
|
('proc', ('it:exec:proc', {}), {
|
synapse/models/orgs.py
CHANGED
|
@@ -93,9 +93,10 @@ class OuModule(s_module.CoreModule):
|
|
|
93
93
|
('ou:industryname', ('str', {'lower': True, 'onespace': True}), {
|
|
94
94
|
'doc': 'The name of an industry.',
|
|
95
95
|
}),
|
|
96
|
-
('ou:alias', ('str', {'lower': True, 'regex': r'^[
|
|
97
|
-
'
|
|
96
|
+
('ou:alias', ('str', {'lower': True, 'regex': r'^[\w0-9_]+$'}), {
|
|
97
|
+
'deprecated': True,
|
|
98
98
|
'ex': 'vertexproject',
|
|
99
|
+
'doc': 'Deprecated. Please use ou:name.',
|
|
99
100
|
}),
|
|
100
101
|
('ou:hasalias', ('comp', {'fields': (('org', 'ou:org'), ('alias', 'ou:alias'))}), {
|
|
101
102
|
'deprecated': True,
|
|
@@ -762,7 +763,8 @@ class OuModule(s_module.CoreModule):
|
|
|
762
763
|
'doc': 'A list of alternate names for the organization.',
|
|
763
764
|
}),
|
|
764
765
|
('alias', ('ou:alias', {}), {
|
|
765
|
-
'
|
|
766
|
+
'deprecated': True,
|
|
767
|
+
'doc': 'Deprecated. Please use ou:org:names.',
|
|
766
768
|
}),
|
|
767
769
|
('phone', ('tel:phone', {}), {
|
|
768
770
|
'doc': 'The primary phone number for the organization.',
|
|
@@ -1373,7 +1375,7 @@ class OuModule(s_module.CoreModule):
|
|
|
1373
1375
|
('org', ('ou:org', {}), {
|
|
1374
1376
|
'doc': 'The organization which is enacting the document.'}),
|
|
1375
1377
|
|
|
1376
|
-
('doc', ('ndef', {'forms': ('doc:policy', 'doc:standard')}), {
|
|
1378
|
+
('doc', ('ndef', {'forms': ('doc:policy', 'doc:standard', 'doc:requirement')}), {
|
|
1377
1379
|
'doc': 'The document enacted by the organization.'}),
|
|
1378
1380
|
|
|
1379
1381
|
('scope', ('ndef', {}), {
|
synapse/models/risk.py
CHANGED
|
@@ -810,6 +810,15 @@ class RiskModule(s_module.CoreModule):
|
|
|
810
810
|
|
|
811
811
|
('host', ('it:host', {}), {
|
|
812
812
|
'doc': 'The host which generated the alert.'}),
|
|
813
|
+
|
|
814
|
+
('service:platform', ('inet:service:platform', {}), {
|
|
815
|
+
'doc': 'The service platform which generated the alert.'}),
|
|
816
|
+
|
|
817
|
+
('service:instance', ('inet:service:instance', {}), {
|
|
818
|
+
'doc': 'The service instance which generated the alert.'}),
|
|
819
|
+
|
|
820
|
+
('service:account', ('inet:service:account', {}), {
|
|
821
|
+
'doc': 'The service account which generated the alert.'}),
|
|
813
822
|
)),
|
|
814
823
|
('risk:compromisetype', {}, ()),
|
|
815
824
|
('risk:compromise', {}, (
|
synapse/models/syn.py
CHANGED
|
@@ -23,7 +23,15 @@ class SynUser(s_types.Guid):
|
|
|
23
23
|
if user is not None:
|
|
24
24
|
return user.iden, {}
|
|
25
25
|
|
|
26
|
-
|
|
26
|
+
if text == '*':
|
|
27
|
+
mesg = f'{self.name} values must be a valid username or a guid.'
|
|
28
|
+
raise s_exc.BadTypeValu(mesg=mesg, name=self.name, valu=text)
|
|
29
|
+
|
|
30
|
+
try:
|
|
31
|
+
return s_types.Guid._normPyStr(self, text)
|
|
32
|
+
except s_exc.BadTypeValu:
|
|
33
|
+
mesg = f'No user named {text} and value is not a guid.'
|
|
34
|
+
raise s_exc.BadTypeValu(mesg=mesg, name=self.name, valu=text) from None
|
|
27
35
|
|
|
28
36
|
def repr(self, iden):
|
|
29
37
|
|
|
@@ -51,7 +59,15 @@ class SynRole(s_types.Guid):
|
|
|
51
59
|
if role is not None:
|
|
52
60
|
return role.iden, {}
|
|
53
61
|
|
|
54
|
-
|
|
62
|
+
if text == '*':
|
|
63
|
+
mesg = f'{self.name} values must be a valid rolename or a guid.'
|
|
64
|
+
raise s_exc.BadTypeValu(mesg=mesg, name=self.name, valu=text)
|
|
65
|
+
|
|
66
|
+
try:
|
|
67
|
+
return s_types.Guid._normPyStr(self, text)
|
|
68
|
+
except s_exc.BadTypeValu:
|
|
69
|
+
mesg = f'No role named {text} and value is not a guid.'
|
|
70
|
+
raise s_exc.BadTypeValu(mesg=mesg, name=self.name, valu=text) from None
|
|
55
71
|
|
|
56
72
|
def repr(self, iden):
|
|
57
73
|
|
|
@@ -113,6 +113,14 @@ commands:
|
|
|
113
113
|
- help: Help on foo opt
|
|
114
114
|
- - --bar
|
|
115
115
|
- help: Help on bar opt
|
|
116
|
+
storm: |
|
|
117
|
+
test:str
|
|
118
|
+
endpoints:
|
|
119
|
+
- path: /v1/test/one
|
|
120
|
+
- path: /v1/test/two
|
|
121
|
+
host: vertex.link
|
|
122
|
+
- path: /v1/test/three
|
|
123
|
+
desc: endpoint three
|
|
116
124
|
|
|
117
125
|
- name: testpkg.baz
|
|
118
126
|
descr: |
|
synapse/tests/test_cortex.py
CHANGED
|
@@ -1001,6 +1001,114 @@ class CortexTest(s_t_utils.SynTest):
|
|
|
1001
1001
|
self.eq(cm.exception.get('mesg'),
|
|
1002
1002
|
'walk operation expected a string or list. got: 0.')
|
|
1003
1003
|
|
|
1004
|
+
await core.nodes('[media:news=*]')
|
|
1005
|
+
|
|
1006
|
+
nodes = await core.nodes('$n = {[it:dev:str=foo]} media:news [ +(refs)> $n ]')
|
|
1007
|
+
self.len(1, nodes)
|
|
1008
|
+
self.eq(nodes[0].ndef[0], 'media:news')
|
|
1009
|
+
|
|
1010
|
+
nodes = await core.nodes('media:news -(refs)> it:dev:str')
|
|
1011
|
+
self.len(1, nodes)
|
|
1012
|
+
|
|
1013
|
+
q = '''
|
|
1014
|
+
function foo() {
|
|
1015
|
+
for $x in $lib.range(5) {
|
|
1016
|
+
[ it:dev:int=$x ]
|
|
1017
|
+
emit $node
|
|
1018
|
+
}
|
|
1019
|
+
}
|
|
1020
|
+
media:news [ +(refs)> $foo() ]
|
|
1021
|
+
'''
|
|
1022
|
+
nodes = await core.nodes(q)
|
|
1023
|
+
self.len(1, nodes)
|
|
1024
|
+
self.eq(nodes[0].ndef[0], 'media:news')
|
|
1025
|
+
|
|
1026
|
+
nodes = await core.nodes('media:news -(refs)> it:dev:int')
|
|
1027
|
+
self.len(5, nodes)
|
|
1028
|
+
|
|
1029
|
+
nodes = await core.nodes('$n = {[it:dev:str=foo]} media:news [ -(refs)> $n ]')
|
|
1030
|
+
self.len(1, nodes)
|
|
1031
|
+
self.eq(nodes[0].ndef[0], 'media:news')
|
|
1032
|
+
|
|
1033
|
+
nodes = await core.nodes('media:news -(refs)> it:dev:str')
|
|
1034
|
+
self.len(0, nodes)
|
|
1035
|
+
|
|
1036
|
+
q = '''
|
|
1037
|
+
function foo() {
|
|
1038
|
+
for $x in $lib.range(5) {
|
|
1039
|
+
[ it:dev:int=$x ]
|
|
1040
|
+
emit $node
|
|
1041
|
+
}
|
|
1042
|
+
}
|
|
1043
|
+
media:news [ -(refs)> $foo() ]
|
|
1044
|
+
'''
|
|
1045
|
+
nodes = await core.nodes(q)
|
|
1046
|
+
self.len(1, nodes)
|
|
1047
|
+
self.eq(nodes[0].ndef[0], 'media:news')
|
|
1048
|
+
|
|
1049
|
+
nodes = await core.nodes('media:news -(refs)> it:dev:int')
|
|
1050
|
+
self.len(0, nodes)
|
|
1051
|
+
|
|
1052
|
+
nodes = await core.nodes('$n = {[it:dev:str=foo]} media:news [ <(refs)+ $n ]')
|
|
1053
|
+
self.len(1, nodes)
|
|
1054
|
+
self.eq(nodes[0].ndef[0], 'media:news')
|
|
1055
|
+
|
|
1056
|
+
nodes = await core.nodes('media:news <(refs)- it:dev:str')
|
|
1057
|
+
self.len(1, nodes)
|
|
1058
|
+
|
|
1059
|
+
q = '''
|
|
1060
|
+
function foo() {
|
|
1061
|
+
for $x in $lib.range(5) {
|
|
1062
|
+
[ it:dev:int=$x ]
|
|
1063
|
+
emit $node
|
|
1064
|
+
}
|
|
1065
|
+
}
|
|
1066
|
+
media:news [ <(refs)+ $foo() ]
|
|
1067
|
+
'''
|
|
1068
|
+
nodes = await core.nodes(q)
|
|
1069
|
+
self.len(1, nodes)
|
|
1070
|
+
self.eq(nodes[0].ndef[0], 'media:news')
|
|
1071
|
+
|
|
1072
|
+
nodes = await core.nodes('media:news <(refs)- it:dev:int')
|
|
1073
|
+
self.len(5, nodes)
|
|
1074
|
+
|
|
1075
|
+
nodes = await core.nodes('$n = {[it:dev:str=foo]} media:news [ <(refs)- $n ]')
|
|
1076
|
+
self.len(1, nodes)
|
|
1077
|
+
self.eq(nodes[0].ndef[0], 'media:news')
|
|
1078
|
+
|
|
1079
|
+
nodes = await core.nodes('media:news <(refs)- it:dev:str')
|
|
1080
|
+
self.len(0, nodes)
|
|
1081
|
+
|
|
1082
|
+
q = '''
|
|
1083
|
+
function foo() {
|
|
1084
|
+
for $x in $lib.range(5) {
|
|
1085
|
+
[ it:dev:int=$x ]
|
|
1086
|
+
emit $node
|
|
1087
|
+
}
|
|
1088
|
+
}
|
|
1089
|
+
media:news [ <(refs)- $foo() ]
|
|
1090
|
+
'''
|
|
1091
|
+
nodes = await core.nodes(q)
|
|
1092
|
+
self.len(1, nodes)
|
|
1093
|
+
self.eq(nodes[0].ndef[0], 'media:news')
|
|
1094
|
+
|
|
1095
|
+
nodes = await core.nodes('media:news <(refs)- it:dev:int')
|
|
1096
|
+
self.len(0, nodes)
|
|
1097
|
+
|
|
1098
|
+
await core.nodes('[media:news=*]')
|
|
1099
|
+
|
|
1100
|
+
nodes = await core.nodes('$n = {[it:dev:str=foo]} $edge=refs media:news [ +($edge)> $n ]')
|
|
1101
|
+
self.len(2, nodes)
|
|
1102
|
+
|
|
1103
|
+
nodes = await core.nodes('media:news -(refs)> it:dev:str')
|
|
1104
|
+
self.len(2, nodes)
|
|
1105
|
+
|
|
1106
|
+
nodes = await core.nodes('$n = {[it:dev:str=foo]} $edge=refs media:news [ -($edge)> $n ]')
|
|
1107
|
+
self.len(2, nodes)
|
|
1108
|
+
|
|
1109
|
+
nodes = await core.nodes('media:news -(refs)> it:dev:str')
|
|
1110
|
+
self.len(0, nodes)
|
|
1111
|
+
|
|
1004
1112
|
async def test_cortex_callstorm(self):
|
|
1005
1113
|
|
|
1006
1114
|
async with self.getTestCore(conf={'auth:passwd': 'root'}) as core:
|
synapse/tests/test_datamodel.py
CHANGED
|
@@ -2,6 +2,7 @@ import synapse.exc as s_exc
|
|
|
2
2
|
import synapse.datamodel as s_datamodel
|
|
3
3
|
|
|
4
4
|
import synapse.lib.module as s_module
|
|
5
|
+
import synapse.lib.schemas as s_schemas
|
|
5
6
|
|
|
6
7
|
import synapse.cortex as s_cortex
|
|
7
8
|
|
|
@@ -342,3 +343,9 @@ class DataModelTest(s_t_utils.SynTest):
|
|
|
342
343
|
nodes = await core.nodes('[ it:prod:softver=* :semver=3.1.0 ]')
|
|
343
344
|
self.none(nodes[0].get('semver:major'))
|
|
344
345
|
self.eq(1, nodes[0].get('semver:minor'))
|
|
346
|
+
|
|
347
|
+
def test_datamodel_schema_basetypes(self):
|
|
348
|
+
# N.B. This test is to keep synapse.lib.schemas.datamodel_basetypes const
|
|
349
|
+
# in sync with the default s_datamodel.Datamodel().types
|
|
350
|
+
basetypes = list(s_datamodel.Model().types)
|
|
351
|
+
self.eq(s_schemas.datamodel_basetypes, basetypes)
|
synapse/tests/test_lib_aha.py
CHANGED
|
@@ -133,9 +133,14 @@ class AhaTest(s_test.SynTest):
|
|
|
133
133
|
with self.getTestDir() as dirn:
|
|
134
134
|
cryo0_dirn = s_common.gendir(dirn, 'cryo0')
|
|
135
135
|
async with self.getTestAha(dirn=dirn) as aha:
|
|
136
|
+
|
|
137
|
+
replaymult = 1
|
|
138
|
+
if s_common.envbool('SYNDEV_NEXUS_REPLAY'):
|
|
139
|
+
replaymult = 2
|
|
140
|
+
|
|
136
141
|
purl = await aha.addAhaSvcProv('0.cryo')
|
|
137
142
|
|
|
138
|
-
wait00 = aha.waiter(1, 'aha:svcadd')
|
|
143
|
+
wait00 = aha.waiter(1 * replaymult, 'aha:svcadd')
|
|
139
144
|
|
|
140
145
|
conf = {'aha:provision': purl}
|
|
141
146
|
async with self.getTestCryo(dirn=cryo0_dirn, conf=conf) as cryo:
|
|
@@ -444,8 +449,13 @@ class AhaTest(s_test.SynTest):
|
|
|
444
449
|
|
|
445
450
|
async with self.getTestAha() as aha:
|
|
446
451
|
|
|
452
|
+
replaymult = 1
|
|
453
|
+
if s_common.envbool('SYNDEV_NEXUS_REPLAY'):
|
|
454
|
+
replaymult = 2
|
|
455
|
+
|
|
447
456
|
aha.testerr = True
|
|
448
457
|
wait00 = aha.waiter(1, 'aha:svcadd')
|
|
458
|
+
|
|
449
459
|
conf = {'aha:provision': await aha.addAhaSvcProv('0.cryo')}
|
|
450
460
|
async with self.getTestCryo(conf=conf) as cryo:
|
|
451
461
|
|
|
@@ -454,7 +464,7 @@ class AhaTest(s_test.SynTest):
|
|
|
454
464
|
svc = await aha.getAhaSvc('0.cryo...')
|
|
455
465
|
self.none(svc)
|
|
456
466
|
|
|
457
|
-
wait01 = aha.waiter(1, 'aha:svcadd')
|
|
467
|
+
wait01 = aha.waiter(1 * replaymult, 'aha:svcadd')
|
|
458
468
|
aha.testerr = False
|
|
459
469
|
|
|
460
470
|
self.nn(await wait01.wait(timeout=2))
|
|
@@ -1434,46 +1444,6 @@ class AhaTest(s_test.SynTest):
|
|
|
1434
1444
|
self.len(nexsindx, items)
|
|
1435
1445
|
self.true(all(item[1][0] for item in items))
|
|
1436
1446
|
|
|
1437
|
-
# test some of the gather API implementations...
|
|
1438
|
-
purl00 = await aha.addAhaSvcProv('0.cell')
|
|
1439
|
-
purl01 = await aha.addAhaSvcProv('1.cell', provinfo={'mirror': '0.cell'})
|
|
1440
|
-
|
|
1441
|
-
cell00 = await aha.enter_context(self.getTestCell(conf={'aha:provision': purl00}))
|
|
1442
|
-
cell01 = await aha.enter_context(self.getTestCell(conf={'aha:provision': purl01}))
|
|
1443
|
-
|
|
1444
|
-
await cell01.sync()
|
|
1445
|
-
|
|
1446
|
-
async def sleep99(cell):
|
|
1447
|
-
await cell.boss.promote('sleep99', cell.auth.rootuser)
|
|
1448
|
-
await cell00.fire('sleep99')
|
|
1449
|
-
await asyncio.sleep(99)
|
|
1450
|
-
|
|
1451
|
-
async with cell00.waiter(2, 'sleep99', timeout=2):
|
|
1452
|
-
task00 = cell00.schedCoro(sleep99(cell00))
|
|
1453
|
-
task01 = cell01.schedCoro(sleep99(cell01))
|
|
1454
|
-
|
|
1455
|
-
proxy = await aha.enter_context(aha.getLocalProxy())
|
|
1456
|
-
tasks = [task async for task in cell00.getTasks(timeout=3)]
|
|
1457
|
-
self.len(2, tasks)
|
|
1458
|
-
self.eq(tasks[0]['service'], '0.cell.synapse')
|
|
1459
|
-
self.eq(tasks[1]['service'], '1.cell.synapse')
|
|
1460
|
-
|
|
1461
|
-
self.eq(tasks[0], await cell00.getTask(tasks[0].get('iden')))
|
|
1462
|
-
self.eq(tasks[1], await cell00.getTask(tasks[1].get('iden')))
|
|
1463
|
-
self.none(await cell00.getTask(tasks[1].get('iden'), peers=False))
|
|
1464
|
-
|
|
1465
|
-
self.true(await cell00.killTask(tasks[0].get('iden')))
|
|
1466
|
-
|
|
1467
|
-
task01 = tasks[1].get('iden')
|
|
1468
|
-
self.false(await cell00.killTask(task01, peers=False))
|
|
1469
|
-
|
|
1470
|
-
self.true(await cell00.killTask(task01))
|
|
1471
|
-
|
|
1472
|
-
self.none(await cell00.getTask(task01))
|
|
1473
|
-
self.false(await cell00.killTask(task01))
|
|
1474
|
-
|
|
1475
|
-
self.none(await cell00.getAhaProxy(feats=(('newp', 9),)))
|
|
1476
|
-
|
|
1477
1447
|
async def test_lib_aha_peer_api(self):
|
|
1478
1448
|
|
|
1479
1449
|
async with self.getTestAha() as aha:
|
synapse/tests/test_lib_ast.py
CHANGED
|
@@ -492,6 +492,63 @@ class AstTest(s_test.SynTest):
|
|
|
492
492
|
q = '$foo=newp [test:str=foo :hehe*$foo=heval]'
|
|
493
493
|
nodes = await core.nodes(q)
|
|
494
494
|
|
|
495
|
+
async def test_ast_setmultioper(self):
|
|
496
|
+
async with self.getTestCore() as core:
|
|
497
|
+
|
|
498
|
+
nodes = await core.nodes('[ test:arrayprop="*" :ints=(1,) ]')
|
|
499
|
+
self.eq(nodes[0].get('ints'), (1,))
|
|
500
|
+
|
|
501
|
+
nodes = await core.nodes('test:arrayprop [ :ints++=([3, 4]) ]')
|
|
502
|
+
self.eq(nodes[0].get('ints'), (1, 3, 4))
|
|
503
|
+
|
|
504
|
+
nodes = await core.nodes('test:arrayprop [ :ints++=(null) ]')
|
|
505
|
+
self.eq(nodes[0].get('ints'), (1, 3, 4))
|
|
506
|
+
|
|
507
|
+
nodes = await core.nodes('test:arrayprop [ :ints--=(null) ]')
|
|
508
|
+
self.eq(nodes[0].get('ints'), (1, 3, 4))
|
|
509
|
+
|
|
510
|
+
nodes = await core.nodes('test:arrayprop [ :strs++=(foo, bar, baz) ]')
|
|
511
|
+
self.eq(nodes[0].get('strs'), ('foo', 'bar', 'baz'))
|
|
512
|
+
|
|
513
|
+
with self.raises(s_exc.BadTypeValu):
|
|
514
|
+
await core.nodes('test:arrayprop [ :ints++=(["newp", 5, 6]) ]')
|
|
515
|
+
|
|
516
|
+
nodes = await core.nodes('test:arrayprop [ :ints?++=(["newp", 5, 6]) ]')
|
|
517
|
+
self.eq(nodes[0].get('ints'), (1, 3, 4, 5, 6))
|
|
518
|
+
|
|
519
|
+
with self.raises(s_exc.BadTypeValu):
|
|
520
|
+
await core.nodes('test:arrayprop [ :ints--=(["newp", 5, 6]) ]')
|
|
521
|
+
|
|
522
|
+
nodes = await core.nodes('test:arrayprop [ :ints?--=(["newp", 5, 6, 7]) ]')
|
|
523
|
+
self.eq(nodes[0].get('ints'), (1, 3, 4))
|
|
524
|
+
|
|
525
|
+
nodes = await core.nodes('[ test:str=foo :ndefs++={[ test:str=bar ]} ]')
|
|
526
|
+
self.eq(nodes[0].get('ndefs'), (('test:str', 'bar'),))
|
|
527
|
+
|
|
528
|
+
nodes = await core.nodes('test:str=foo [ :ndefs++={[ test:str=baz test:str=faz ]} ]')
|
|
529
|
+
self.eq(nodes[0].get('ndefs'), (('test:str', 'bar'), ('test:str', 'baz'), ('test:str', 'faz')))
|
|
530
|
+
|
|
531
|
+
nodes = await core.nodes('test:str=foo [ :ndefs--={ test:str=baz test:str=faz } ]')
|
|
532
|
+
self.eq(nodes[0].get('ndefs'), (('test:str', 'bar'),))
|
|
533
|
+
|
|
534
|
+
with self.raises(s_exc.NoSuchProp):
|
|
535
|
+
await core.nodes('test:arrayprop [ :newp++=(["newp", 5, 6]) ]')
|
|
536
|
+
|
|
537
|
+
badq = [
|
|
538
|
+
'test:str [ :hehe++=([3, 4]) ]',
|
|
539
|
+
'test:str [ :hehe?++=([3, 4]) ]',
|
|
540
|
+
'test:str [ :hehe--=([3, 4]) ]',
|
|
541
|
+
'test:str [ :hehe?--=([3, 4]) ]',
|
|
542
|
+
'test:arrayprop [ :ints++=(3) ]',
|
|
543
|
+
'test:arrayprop [ :ints?++=(3) ]',
|
|
544
|
+
'test:arrayprop [ :ints--=(3) ]',
|
|
545
|
+
'test:arrayprop [ :ints?--=(3) ]',
|
|
546
|
+
]
|
|
547
|
+
|
|
548
|
+
for q in badq:
|
|
549
|
+
with self.raises(s_exc.StormRuntimeError):
|
|
550
|
+
await core.nodes(q)
|
|
551
|
+
|
|
495
552
|
async def test_ast_editparens(self):
|
|
496
553
|
|
|
497
554
|
async with self.getTestCore() as core:
|