synapse 2.152.0__py311-none-any.whl → 2.154.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 +19 -16
- synapse/cortex.py +203 -15
- synapse/exc.py +0 -2
- synapse/lib/ast.py +42 -23
- synapse/lib/autodoc.py +2 -2
- synapse/lib/cache.py +16 -1
- synapse/lib/cell.py +5 -5
- synapse/lib/httpapi.py +198 -2
- synapse/lib/layer.py +5 -2
- synapse/lib/modelrev.py +36 -3
- synapse/lib/node.py +2 -5
- synapse/lib/parser.py +1 -1
- synapse/lib/schemas.py +51 -0
- synapse/lib/snap.py +10 -0
- synapse/lib/storm.lark +24 -4
- synapse/lib/storm.py +98 -19
- synapse/lib/storm_format.py +1 -1
- synapse/lib/stormhttp.py +11 -4
- synapse/lib/stormlib/auth.py +16 -2
- synapse/lib/stormlib/backup.py +1 -0
- synapse/lib/stormlib/basex.py +2 -0
- synapse/lib/stormlib/cell.py +7 -0
- synapse/lib/stormlib/compression.py +3 -0
- synapse/lib/stormlib/cortex.py +1168 -0
- synapse/lib/stormlib/ethereum.py +1 -0
- synapse/lib/stormlib/graph.py +2 -0
- synapse/lib/stormlib/hashes.py +5 -0
- synapse/lib/stormlib/hex.py +6 -0
- synapse/lib/stormlib/infosec.py +6 -1
- synapse/lib/stormlib/ipv6.py +1 -0
- synapse/lib/stormlib/iters.py +58 -1
- synapse/lib/stormlib/json.py +5 -0
- synapse/lib/stormlib/mime.py +1 -0
- synapse/lib/stormlib/model.py +19 -3
- synapse/lib/stormlib/modelext.py +1 -0
- synapse/lib/stormlib/notifications.py +2 -0
- synapse/lib/stormlib/pack.py +2 -0
- synapse/lib/stormlib/random.py +1 -0
- synapse/lib/stormlib/smtp.py +0 -7
- synapse/lib/stormlib/stats.py +223 -0
- synapse/lib/stormlib/stix.py +8 -0
- synapse/lib/stormlib/storm.py +1 -0
- synapse/lib/stormlib/version.py +3 -0
- synapse/lib/stormlib/xml.py +3 -0
- synapse/lib/stormlib/yaml.py +2 -0
- synapse/lib/stormtypes.py +250 -170
- synapse/lib/trigger.py +180 -4
- synapse/lib/types.py +1 -1
- synapse/lib/version.py +2 -2
- synapse/lib/view.py +55 -6
- synapse/models/inet.py +21 -6
- synapse/models/orgs.py +48 -2
- synapse/models/risk.py +126 -2
- synapse/models/syn.py +6 -0
- synapse/tests/files/stormpkg/badapidef.yaml +13 -0
- synapse/tests/files/stormpkg/storm/modules/apimod +10 -0
- synapse/tests/files/stormpkg/testpkg.yaml +23 -0
- synapse/tests/test_axon.py +7 -2
- synapse/tests/test_cortex.py +231 -35
- synapse/tests/test_lib_ast.py +138 -43
- synapse/tests/test_lib_autodoc.py +1 -1
- synapse/tests/test_lib_modelrev.py +9 -0
- synapse/tests/test_lib_node.py +55 -0
- synapse/tests/test_lib_storm.py +14 -1
- synapse/tests/test_lib_stormhttp.py +65 -6
- synapse/tests/test_lib_stormlib_auth.py +12 -3
- synapse/tests/test_lib_stormlib_cortex.py +1327 -0
- synapse/tests/test_lib_stormlib_iters.py +116 -0
- synapse/tests/test_lib_stormlib_stats.py +187 -0
- synapse/tests/test_lib_stormlib_storm.py +8 -0
- synapse/tests/test_lib_stormsvc.py +24 -1
- synapse/tests/test_lib_stormtypes.py +124 -69
- synapse/tests/test_lib_trigger.py +315 -0
- synapse/tests/test_lib_view.py +1 -2
- synapse/tests/test_model_base.py +26 -0
- synapse/tests/test_model_inet.py +22 -0
- synapse/tests/test_model_orgs.py +28 -0
- synapse/tests/test_model_risk.py +73 -0
- synapse/tests/test_tools_autodoc.py +25 -0
- synapse/tests/test_tools_genpkg.py +9 -3
- synapse/tests/utils.py +39 -0
- synapse/tools/autodoc.py +42 -2
- {synapse-2.152.0.dist-info → synapse-2.154.0.dist-info}/METADATA +2 -2
- {synapse-2.152.0.dist-info → synapse-2.154.0.dist-info}/RECORD +87 -79
- {synapse-2.152.0.dist-info → synapse-2.154.0.dist-info}/WHEEL +1 -1
- {synapse-2.152.0.dist-info → synapse-2.154.0.dist-info}/LICENSE +0 -0
- {synapse-2.152.0.dist-info → synapse-2.154.0.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
from unittest import mock
|
|
2
|
+
|
|
3
|
+
import synapse.exc as s_exc
|
|
4
|
+
|
|
5
|
+
import synapse.tests.utils as s_test
|
|
6
|
+
|
|
7
|
+
import synapse.lib.stormlib.iters as s_stormlib_iters
|
|
8
|
+
|
|
9
|
+
class StormLibItersTest(s_test.SynTest):
|
|
10
|
+
|
|
11
|
+
async def test_stormlib_iters_zip(self):
|
|
12
|
+
|
|
13
|
+
async with self.getTestCore() as core:
|
|
14
|
+
|
|
15
|
+
async with s_test.matchContexts(self):
|
|
16
|
+
|
|
17
|
+
q = '''
|
|
18
|
+
for $item in $lib.iters.zip((1,2,3), (4,5,6), (7,8,9)) {
|
|
19
|
+
$lib.print($item)
|
|
20
|
+
}
|
|
21
|
+
'''
|
|
22
|
+
msgs = await core.stormlist(q)
|
|
23
|
+
self.stormIsInPrint("['1', '4', '7']", msgs)
|
|
24
|
+
self.stormIsInPrint("['2', '5', '8']", msgs)
|
|
25
|
+
self.stormIsInPrint("['3', '6', '9']", msgs)
|
|
26
|
+
|
|
27
|
+
q = '''
|
|
28
|
+
for $item in $lib.iters.zip((1,2,3), (4,5,6), (7,8)) {
|
|
29
|
+
$lib.print($item)
|
|
30
|
+
}
|
|
31
|
+
'''
|
|
32
|
+
msgs = await core.stormlist(q)
|
|
33
|
+
self.stormIsInPrint("['1', '4', '7']", msgs)
|
|
34
|
+
self.stormIsInPrint("['2', '5', '8']", msgs)
|
|
35
|
+
self.stormNotInPrint("['3', '6']", msgs)
|
|
36
|
+
|
|
37
|
+
q = '''
|
|
38
|
+
function nodes() {
|
|
39
|
+
[ it:dev:str=4 it:dev:str=5 it:dev:str=6 ]
|
|
40
|
+
}
|
|
41
|
+
function emitter() {
|
|
42
|
+
emit 7
|
|
43
|
+
emit 8
|
|
44
|
+
emit 9
|
|
45
|
+
}
|
|
46
|
+
for ($a, $b, $c) in $lib.iters.zip((1,2,3), $nodes(), $emitter()) {
|
|
47
|
+
$lib.print(($a, $b.0.repr(), $c))
|
|
48
|
+
}
|
|
49
|
+
'''
|
|
50
|
+
msgs = await core.stormlist(q)
|
|
51
|
+
self.stormIsInPrint("['1', '4', '7']", msgs)
|
|
52
|
+
self.stormIsInPrint("['2', '5', '8']", msgs)
|
|
53
|
+
self.stormIsInPrint("['3', '6', '9']", msgs)
|
|
54
|
+
|
|
55
|
+
q = '''
|
|
56
|
+
function nodes() {
|
|
57
|
+
[ it:dev:str=4 it:dev:str=5 it:dev:str=6 ]
|
|
58
|
+
}
|
|
59
|
+
function emitter() {
|
|
60
|
+
emit 7
|
|
61
|
+
emit 8
|
|
62
|
+
emit 9
|
|
63
|
+
}
|
|
64
|
+
for ($a, $b, $c) in $lib.iters.zip((1,2,3), $nodes(), $emitter()) {
|
|
65
|
+
$lib.print(($a, $b.0.repr(), $c))
|
|
66
|
+
$lib.raise(foo, bar)
|
|
67
|
+
}
|
|
68
|
+
'''
|
|
69
|
+
msgs = await core.stormlist(q)
|
|
70
|
+
self.stormIsInPrint("['1', '4', '7']", msgs)
|
|
71
|
+
self.stormNotInPrint("['2', '5', '8']", msgs)
|
|
72
|
+
self.stormNotInPrint("['3', '6', '9']", msgs)
|
|
73
|
+
|
|
74
|
+
q = '''
|
|
75
|
+
function nodes() {
|
|
76
|
+
[ it:dev:str=4 it:dev:str=5 it:dev:str=6]
|
|
77
|
+
}
|
|
78
|
+
function emitter() {
|
|
79
|
+
emit 7
|
|
80
|
+
$lib.raise(foo, bar)
|
|
81
|
+
emit 8
|
|
82
|
+
emit 9
|
|
83
|
+
}
|
|
84
|
+
for ($a, $b, $c) in $lib.iters.zip((1,2,3), $nodes(), $emitter()) {
|
|
85
|
+
$lib.print(($a, $b.0.repr(), $c))
|
|
86
|
+
}
|
|
87
|
+
'''
|
|
88
|
+
msgs = await core.stormlist(q)
|
|
89
|
+
self.stormIsInPrint("['1', '4', '7']", msgs)
|
|
90
|
+
self.stormNotInPrint("['2', '5', '8']", msgs)
|
|
91
|
+
self.stormNotInPrint("['3', '6', '9']", msgs)
|
|
92
|
+
|
|
93
|
+
err = "$lib.iters.zip() encountered errors in 1 iterators during iteration: (foo: bar)"
|
|
94
|
+
self.stormIsInErr(err, msgs)
|
|
95
|
+
|
|
96
|
+
async def boom(self, genr):
|
|
97
|
+
print(newp)
|
|
98
|
+
yield True
|
|
99
|
+
|
|
100
|
+
with mock.patch.object(s_stormlib_iters.LibIters, 'enum', boom):
|
|
101
|
+
q = '''
|
|
102
|
+
function e1() {
|
|
103
|
+
$lib.raise(foo, bar)
|
|
104
|
+
}
|
|
105
|
+
function e2() {
|
|
106
|
+
$lib.print($newp)
|
|
107
|
+
}
|
|
108
|
+
for ($a, $b, $c) in $lib.iters.zip($e1(), $e2(), $lib.iters.enum($e2())) {
|
|
109
|
+
}
|
|
110
|
+
'''
|
|
111
|
+
msgs = await core.stormlist(q)
|
|
112
|
+
err = "$lib.iters.zip() encountered errors in 3 iterators during iteration: " \
|
|
113
|
+
"(foo: bar), " \
|
|
114
|
+
"(NoSuchVar: Missing variable: newp), " \
|
|
115
|
+
"(NameError: name 'newp' is not defined)"
|
|
116
|
+
self.stormIsInErr(err, msgs)
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
import synapse.exc as s_exc
|
|
2
|
+
import synapse.tests.utils as s_test
|
|
3
|
+
|
|
4
|
+
import synapse.lib.stormlib.stats as s_stormlib_stats
|
|
5
|
+
|
|
6
|
+
chartnorm = '''
|
|
7
|
+
40 | 5 | ##################################################
|
|
8
|
+
30 | 4 | ########################################
|
|
9
|
+
20 | 3 | ##############################
|
|
10
|
+
10 | 2 | ####################
|
|
11
|
+
0 | 1 | ##########
|
|
12
|
+
'''.strip()
|
|
13
|
+
|
|
14
|
+
chartrev = '''
|
|
15
|
+
0 | 1 | ##########
|
|
16
|
+
10 | 2 | ####################
|
|
17
|
+
20 | 3 | ##############################
|
|
18
|
+
30 | 4 | ########################################
|
|
19
|
+
40 | 5 | ##################################################
|
|
20
|
+
'''.strip()
|
|
21
|
+
|
|
22
|
+
chartsize = '''
|
|
23
|
+
40 | 5 | ##################################################
|
|
24
|
+
30 | 4 | ########################################
|
|
25
|
+
20 | 3 | ##############################
|
|
26
|
+
'''.strip()
|
|
27
|
+
|
|
28
|
+
chartsizerev = '''
|
|
29
|
+
0 | 1 | ##########
|
|
30
|
+
10 | 2 | ####################
|
|
31
|
+
20 | 3 | ##############################
|
|
32
|
+
'''.strip()
|
|
33
|
+
|
|
34
|
+
chartwidth = '''
|
|
35
|
+
40 | 5 | ##########
|
|
36
|
+
30 | 4 | ########
|
|
37
|
+
20 | 3 | ######
|
|
38
|
+
10 | 2 | ####
|
|
39
|
+
0 | 1 | ##
|
|
40
|
+
'''.strip()
|
|
41
|
+
|
|
42
|
+
chartlabelwidth = '''
|
|
43
|
+
4 | 5 | ##################################################
|
|
44
|
+
3 | 4 | ########################################
|
|
45
|
+
2 | 3 | ##############################
|
|
46
|
+
1 | 2 | ####################
|
|
47
|
+
0 | 1 | ##########
|
|
48
|
+
'''.strip()
|
|
49
|
+
|
|
50
|
+
chartchar = '''
|
|
51
|
+
40 | 5 | ++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
52
|
+
30 | 4 | ++++++++++++++++++++++++++++++++++++++++
|
|
53
|
+
20 | 3 | ++++++++++++++++++++++++++++++
|
|
54
|
+
10 | 2 | ++++++++++++++++++++
|
|
55
|
+
0 | 1 | ++++++++++
|
|
56
|
+
'''.strip()
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
class StatsTest(s_test.SynTest):
|
|
60
|
+
|
|
61
|
+
async def test_stormlib_stats_countby(self):
|
|
62
|
+
|
|
63
|
+
async with self.getTestCore() as core:
|
|
64
|
+
|
|
65
|
+
q = '''
|
|
66
|
+
$i = (0)
|
|
67
|
+
for $x in $lib.range(5) {
|
|
68
|
+
for $y in $lib.range(($x + 1)) {
|
|
69
|
+
[ inet:ipv4=$i :asn=($x * 10) ]
|
|
70
|
+
$i = ($i + 1)
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
'''
|
|
74
|
+
await core.nodes(q)
|
|
75
|
+
|
|
76
|
+
msgs = await core.stormlist('inet:ipv4 | stats.countby :asn')
|
|
77
|
+
self.stormIsInPrint(chartnorm, msgs)
|
|
78
|
+
|
|
79
|
+
msgs = await core.stormlist('inet:ipv4 -> inet:asn | stats.countby')
|
|
80
|
+
self.stormIsInPrint(chartnorm, msgs)
|
|
81
|
+
|
|
82
|
+
msgs = await core.stormlist('inet:ipv4 | stats.countby :asn --reverse')
|
|
83
|
+
self.stormIsInPrint(chartrev, msgs)
|
|
84
|
+
|
|
85
|
+
msgs = await core.stormlist('inet:ipv4 | stats.countby :asn --size 3')
|
|
86
|
+
self.stormIsInPrint(chartsize, msgs)
|
|
87
|
+
|
|
88
|
+
msgs = await core.stormlist('inet:ipv4 | stats.countby :asn --size 3 --reverse')
|
|
89
|
+
self.stormIsInPrint(chartsizerev, msgs)
|
|
90
|
+
|
|
91
|
+
msgs = await core.stormlist(f'inet:ipv4 | stats.countby :asn --bar-width 10')
|
|
92
|
+
self.stormIsInPrint(chartwidth, msgs)
|
|
93
|
+
|
|
94
|
+
msgs = await core.stormlist(f'inet:ipv4 | stats.countby :asn --label-max-width 1')
|
|
95
|
+
self.stormIsInPrint(chartlabelwidth, msgs)
|
|
96
|
+
|
|
97
|
+
msgs = await core.stormlist('inet:ipv4 | stats.countby :asn --char "+"')
|
|
98
|
+
self.stormIsInPrint(chartchar, msgs)
|
|
99
|
+
|
|
100
|
+
msgs = await core.stormlist('stats.countby foo')
|
|
101
|
+
self.stormIsInPrint('No values to display!', msgs)
|
|
102
|
+
|
|
103
|
+
self.len(0, await core.nodes('inet:ipv4 | stats.countby :asn'))
|
|
104
|
+
self.len(15, await core.nodes('inet:ipv4 | stats.countby :asn --yield'))
|
|
105
|
+
|
|
106
|
+
with self.raises(s_exc.BadArg):
|
|
107
|
+
self.len(15, await core.nodes('inet:ipv4 | stats.countby :asn --label-max-width "-1"'))
|
|
108
|
+
|
|
109
|
+
with self.raises(s_exc.BadArg):
|
|
110
|
+
self.len(15, await core.nodes('inet:ipv4 | stats.countby :asn --bar-width "-1"'))
|
|
111
|
+
|
|
112
|
+
with self.raises(s_exc.BadArg):
|
|
113
|
+
self.len(15, await core.nodes('inet:ipv4 | stats.countby ({})'))
|
|
114
|
+
|
|
115
|
+
async def test_stormlib_stats_tally(self):
|
|
116
|
+
|
|
117
|
+
async with self.getTestCore() as core:
|
|
118
|
+
|
|
119
|
+
q = '''
|
|
120
|
+
$tally = $lib.stats.tally()
|
|
121
|
+
|
|
122
|
+
$tally.inc(foo)
|
|
123
|
+
$tally.inc(foo)
|
|
124
|
+
|
|
125
|
+
$tally.inc(bar)
|
|
126
|
+
$tally.inc(bar, 3)
|
|
127
|
+
|
|
128
|
+
for ($name, $valu) in $tally {
|
|
129
|
+
[ test:comp=($valu, $name) ]
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
$lib.print('tally: foo={foo} baz={baz}', foo=$tally.get(foo), baz=$tally.get(baz))
|
|
133
|
+
$lib.print('tally.len()={v}', v=$lib.len($tally))
|
|
134
|
+
'''
|
|
135
|
+
mesgs = await core.stormlist(q)
|
|
136
|
+
nodes = [m[1] for m in mesgs if m[0] == 'node']
|
|
137
|
+
self.len(2, nodes)
|
|
138
|
+
self.eq(nodes[0][0], ('test:comp', (2, 'foo')))
|
|
139
|
+
self.eq(nodes[1][0], ('test:comp', (4, 'bar')))
|
|
140
|
+
self.stormIsInPrint('tally: foo=2 baz=0', mesgs)
|
|
141
|
+
self.stormIsInPrint('tally.len()=2', mesgs)
|
|
142
|
+
|
|
143
|
+
q = '''
|
|
144
|
+
$tally = $lib.stats.tally()
|
|
145
|
+
$tally.inc(foo, 1)
|
|
146
|
+
$tally.inc(bar, 2)
|
|
147
|
+
$tally.inc(baz, 3)
|
|
148
|
+
return($tally.sorted())
|
|
149
|
+
'''
|
|
150
|
+
vals = await core.callStorm(q)
|
|
151
|
+
self.eq(vals, [('foo', 1), ('bar', 2), ('baz', 3)])
|
|
152
|
+
|
|
153
|
+
q = '''
|
|
154
|
+
$tally = $lib.stats.tally()
|
|
155
|
+
$tally.inc(foo, 1)
|
|
156
|
+
$tally.inc(bar, 2)
|
|
157
|
+
$tally.inc(baz, 3)
|
|
158
|
+
return($tally.sorted(reverse=$lib.true))
|
|
159
|
+
'''
|
|
160
|
+
vals = await core.callStorm(q)
|
|
161
|
+
self.eq(vals, [('baz', 3), ('bar', 2), ('foo', 1)])
|
|
162
|
+
|
|
163
|
+
q = '''
|
|
164
|
+
$tally = $lib.stats.tally()
|
|
165
|
+
$tally.inc(foo, 1)
|
|
166
|
+
$tally.inc(bar, 2)
|
|
167
|
+
$tally.inc(baz, 3)
|
|
168
|
+
return($tally.sorted(byname=$lib.true))
|
|
169
|
+
'''
|
|
170
|
+
vals = await core.callStorm(q)
|
|
171
|
+
self.eq(vals, [('bar', 2), ('baz', 3), ('foo', 1)])
|
|
172
|
+
|
|
173
|
+
q = '''
|
|
174
|
+
$tally = $lib.stats.tally()
|
|
175
|
+
$tally.inc(foo, 1)
|
|
176
|
+
$tally.inc(bar, 2)
|
|
177
|
+
$tally.inc(baz, 3)
|
|
178
|
+
return($tally.sorted(byname=$lib.true, reverse=$lib.true))
|
|
179
|
+
'''
|
|
180
|
+
vals = await core.callStorm(q)
|
|
181
|
+
self.eq(vals, [('foo', 1), ('baz', 3), ('bar', 2)])
|
|
182
|
+
|
|
183
|
+
tally = s_stormlib_stats.StatTally()
|
|
184
|
+
await tally.inc('foo')
|
|
185
|
+
|
|
186
|
+
async for (name, valu) in tally:
|
|
187
|
+
self.eq((name, valu), ('foo', 1))
|
|
@@ -28,3 +28,11 @@ class LibStormTest(s_test.SynTest):
|
|
|
28
28
|
|
|
29
29
|
# for coverage of forked call...
|
|
30
30
|
self.nn(s_parser.parseEval('woot'))
|
|
31
|
+
|
|
32
|
+
# Readonly functionality is sane
|
|
33
|
+
msgs = await core.stormlist('$lib.print($lib.storm.eval( "{$lib.print(wow)}" ))')
|
|
34
|
+
self.stormIsInPrint('wow', msgs)
|
|
35
|
+
self.stormIsInPrint('$lib.null', msgs)
|
|
36
|
+
|
|
37
|
+
with self.raises(s_exc.IsReadOnly):
|
|
38
|
+
await core.callStorm('$lib.storm.eval( "{$lib.auth.users.add(readonly)}" )', opts={'readonly': True})
|
|
@@ -317,7 +317,30 @@ class StormvarService(s_cell.CellApi, s_stormsvc.StormSvc):
|
|
|
317
317
|
$lib.print('my foo var is {f}', f=$fooz)
|
|
318
318
|
''',
|
|
319
319
|
},
|
|
320
|
-
)
|
|
320
|
+
),
|
|
321
|
+
'modules': (
|
|
322
|
+
{
|
|
323
|
+
'name': 'testmod',
|
|
324
|
+
'storm': '',
|
|
325
|
+
},
|
|
326
|
+
{
|
|
327
|
+
'name': 'apimod',
|
|
328
|
+
'storm': 'function status() { return($lib.true) }',
|
|
329
|
+
'apidefs': (
|
|
330
|
+
{
|
|
331
|
+
'name': 'status',
|
|
332
|
+
'desc': 'Status of the foo.',
|
|
333
|
+
'type': {
|
|
334
|
+
'type': 'function',
|
|
335
|
+
'returns': {
|
|
336
|
+
'type': 'boolean',
|
|
337
|
+
'desc': 'Where foo is ok',
|
|
338
|
+
},
|
|
339
|
+
},
|
|
340
|
+
},
|
|
341
|
+
),
|
|
342
|
+
},
|
|
343
|
+
),
|
|
321
344
|
},
|
|
322
345
|
)
|
|
323
346
|
|
|
@@ -613,6 +613,14 @@ class StormTypesTest(s_test.SynTest):
|
|
|
613
613
|
'name': 'test',
|
|
614
614
|
'storm': '$valu=$modconf.valu function getvalu() { return($valu) }',
|
|
615
615
|
'modconf': {'valu': 'foo'},
|
|
616
|
+
},
|
|
617
|
+
{
|
|
618
|
+
'name': 'test.danger',
|
|
619
|
+
'storm': '''
|
|
620
|
+
init { $src=$lib.null }
|
|
621
|
+
function genSrc() { if $src { return ($src) } [meta:source=(s1,)] $src=$node return ($node) }
|
|
622
|
+
$genSrc()
|
|
623
|
+
'''
|
|
616
624
|
}
|
|
617
625
|
],
|
|
618
626
|
'commands': [
|
|
@@ -735,9 +743,13 @@ class StormTypesTest(s_test.SynTest):
|
|
|
735
743
|
|
|
736
744
|
await core.callStorm('$test = $lib.import(test) $test.modconf.valu=bar')
|
|
737
745
|
self.eq('foo', await core.callStorm('return($lib.import(test).getvalu())'))
|
|
746
|
+
self.eq('foo', await core.callStorm('return($lib.import(test).getvalu())', opts={'readonly': True}))
|
|
747
|
+
|
|
748
|
+
with self.raises(s_exc.IsReadOnly):
|
|
749
|
+
await core.callStorm('return($lib.import(test.danger).src)', opts={'readonly': True})
|
|
738
750
|
|
|
739
751
|
mods = await core.getStormMods()
|
|
740
|
-
self.len(
|
|
752
|
+
self.len(2, mods)
|
|
741
753
|
mods['test']['modconf']['valu'] = 'bar'
|
|
742
754
|
mods = await core.getStormMods()
|
|
743
755
|
self.eq('foo', mods['test']['modconf']['valu'])
|
|
@@ -1181,6 +1193,24 @@ class StormTypesTest(s_test.SynTest):
|
|
|
1181
1193
|
'''
|
|
1182
1194
|
self.eq(2, await core.callStorm(q))
|
|
1183
1195
|
|
|
1196
|
+
q = '''
|
|
1197
|
+
$q=${ return( $lib.auth.users.byname(root).name ) }
|
|
1198
|
+
return ( $q.exec() )
|
|
1199
|
+
'''
|
|
1200
|
+
self.eq('root', await core.callStorm(q, opts={'readonly': True}))
|
|
1201
|
+
|
|
1202
|
+
q = '''
|
|
1203
|
+
$q=${ test:int=1 }
|
|
1204
|
+
return ( $q.size() )
|
|
1205
|
+
'''
|
|
1206
|
+
self.eq(1, await core.callStorm(q, opts={'readonly': True}))
|
|
1207
|
+
|
|
1208
|
+
with self.raises(s_exc.IsReadOnly):
|
|
1209
|
+
await core.callStorm('$foo=${ [test:str=readonly] } return ( $foo.exec() )', opts={'readonly': True})
|
|
1210
|
+
|
|
1211
|
+
with self.raises(s_exc.IsReadOnly):
|
|
1212
|
+
await core.callStorm('$foo=${ [test:str=readonly] } return( $foo.size() )', opts={'readonly': True})
|
|
1213
|
+
|
|
1184
1214
|
async def test_storm_lib_node(self):
|
|
1185
1215
|
async with self.getTestCore() as core:
|
|
1186
1216
|
nodes = await core.nodes('[ test:str=woot :tick=2001] [ test:int=$node.isform(test:str) ] +test:int')
|
|
@@ -1514,6 +1544,72 @@ class StormTypesTest(s_test.SynTest):
|
|
|
1514
1544
|
q = '$foo=$lib.text(foo) $bar=$lib.text(bar) $v=($foo, aString, $bar,) $v.sort() return ($v)'
|
|
1515
1545
|
await core.callStorm(q)
|
|
1516
1546
|
|
|
1547
|
+
q = '$l = (1, 2, (3), 4, 1, (3), 3, asdf) return ( $l.unique() )'
|
|
1548
|
+
self.eq(['1', '2', 3, '4', '3', 'asdf'], await core.callStorm(q))
|
|
1549
|
+
|
|
1550
|
+
q = '$a=$lib.text(hehe) $b=$lib.text(haha) $c=$lib.text(hehe) $foo=($a, $b, $c) return ($foo.unique())'
|
|
1551
|
+
self.eq(['hehe', 'haha'], await core.callStorm(q))
|
|
1552
|
+
|
|
1553
|
+
await core.addUser('lowuser1')
|
|
1554
|
+
await core.addUser('lowuser2')
|
|
1555
|
+
q = '''
|
|
1556
|
+
$a=$lib.auth.users.byname(lowuser1) $b=$lib.auth.users.byname(lowuser2) $r=$lib.auth.users.byname(root)
|
|
1557
|
+
$l = ($a, $r, $b, $b, $a ) $l2 = $l.unique() $l3 = ()
|
|
1558
|
+
for $user in $l2 {
|
|
1559
|
+
$l3.append($user.name)
|
|
1560
|
+
}
|
|
1561
|
+
return ( $l3 )'''
|
|
1562
|
+
self.eq(['lowuser1', 'root', 'lowuser2'], await core.callStorm(q))
|
|
1563
|
+
|
|
1564
|
+
q = '$l=(1, 2, 3, 3, $lib.queue) return ( $lib.len($l.unique()) )'
|
|
1565
|
+
self.eq(4, await core.callStorm(q))
|
|
1566
|
+
|
|
1567
|
+
# funcs are different class instances here
|
|
1568
|
+
q = '$l = (1, 2, 2, $lib.inet.http.get, $lib.inet.http.get) return ($lib.len($l.unique()))'
|
|
1569
|
+
self.eq(4, await core.callStorm(q))
|
|
1570
|
+
|
|
1571
|
+
# funcs are the same class instance
|
|
1572
|
+
q = '$hehe = $lib.inet.http $l = (1, 2, 2, $hehe.get, $hehe.get) return ($lib.len($l.unique()))'
|
|
1573
|
+
self.eq(3, await core.callStorm(q))
|
|
1574
|
+
|
|
1575
|
+
q = '''
|
|
1576
|
+
function foo() {}
|
|
1577
|
+
function bar() {}
|
|
1578
|
+
$l = ($foo, $bar)
|
|
1579
|
+
return ($lib.len($l.unique()))
|
|
1580
|
+
'''
|
|
1581
|
+
self.eq(2, await core.callStorm(q))
|
|
1582
|
+
|
|
1583
|
+
q = '''
|
|
1584
|
+
function foo() {}
|
|
1585
|
+
function bar() {}
|
|
1586
|
+
$l = ($bar, $foo, $bar)
|
|
1587
|
+
return ($lib.len($l.unique()))
|
|
1588
|
+
'''
|
|
1589
|
+
self.eq(2, await core.callStorm(q))
|
|
1590
|
+
|
|
1591
|
+
q = '''
|
|
1592
|
+
$q1 = $lib.queue.gen(hehe)
|
|
1593
|
+
$q2 = $lib.queue.get(hehe)
|
|
1594
|
+
$l = ($q1, $q2)
|
|
1595
|
+
return ( $lib.len($l.unique()) ) '''
|
|
1596
|
+
self.eq(1, await core.callStorm(q))
|
|
1597
|
+
|
|
1598
|
+
q = '''
|
|
1599
|
+
$q1 = $lib.queue.gen(hehe)
|
|
1600
|
+
$q2 = $lib.queue.get(hehe)
|
|
1601
|
+
$l = ($q1, $q2, $q2)
|
|
1602
|
+
return ( $lib.len($l.unique()) ) '''
|
|
1603
|
+
self.eq(1, await core.callStorm(q))
|
|
1604
|
+
|
|
1605
|
+
q = '''
|
|
1606
|
+
$q1 = $lib.queue.gen(hehe)
|
|
1607
|
+
$q2 = $lib.queue.get(hehe)
|
|
1608
|
+
$q3 = $lib.queue.get(hehe)
|
|
1609
|
+
$l = ($q1, $q2, $q3)
|
|
1610
|
+
return ( $lib.len($l.unique()) ) '''
|
|
1611
|
+
self.eq(1, await core.callStorm(q))
|
|
1612
|
+
|
|
1517
1613
|
# Python Tuples can be treated like a List object for accessing via data inside of.
|
|
1518
1614
|
q = '[ test:comp=(10,lol) ] $x=$node.ndef().index(1).index(1) [ test:str=$x ]'
|
|
1519
1615
|
nodes = await core.nodes(q)
|
|
@@ -3265,74 +3361,6 @@ class StormTypesTest(s_test.SynTest):
|
|
|
3265
3361
|
errs = [m for m in msgs if m[0] == 'err']
|
|
3266
3362
|
self.len(0, errs)
|
|
3267
3363
|
|
|
3268
|
-
async def test_lib_stormtypes_stats(self):
|
|
3269
|
-
|
|
3270
|
-
async with self.getTestCore() as core:
|
|
3271
|
-
|
|
3272
|
-
q = '''
|
|
3273
|
-
$tally = $lib.stats.tally()
|
|
3274
|
-
|
|
3275
|
-
$tally.inc(foo)
|
|
3276
|
-
$tally.inc(foo)
|
|
3277
|
-
|
|
3278
|
-
$tally.inc(bar)
|
|
3279
|
-
$tally.inc(bar, 3)
|
|
3280
|
-
|
|
3281
|
-
for ($name, $valu) in $tally {
|
|
3282
|
-
[ test:comp=($valu, $name) ]
|
|
3283
|
-
}
|
|
3284
|
-
|
|
3285
|
-
$lib.print('tally: foo={foo} baz={baz}', foo=$tally.get(foo), baz=$tally.get(baz))
|
|
3286
|
-
$lib.print('tally.len()={v}', v=$lib.len($tally))
|
|
3287
|
-
'''
|
|
3288
|
-
mesgs = await core.stormlist(q)
|
|
3289
|
-
nodes = [m[1] for m in mesgs if m[0] == 'node']
|
|
3290
|
-
self.len(2, nodes)
|
|
3291
|
-
self.eq(nodes[0][0], ('test:comp', (2, 'foo')))
|
|
3292
|
-
self.eq(nodes[1][0], ('test:comp', (4, 'bar')))
|
|
3293
|
-
self.stormIsInPrint('tally: foo=2 baz=0', mesgs)
|
|
3294
|
-
self.stormIsInPrint('tally.len()=2', mesgs)
|
|
3295
|
-
|
|
3296
|
-
q = '''
|
|
3297
|
-
$tally = $lib.stats.tally()
|
|
3298
|
-
$tally.inc(foo, 1)
|
|
3299
|
-
$tally.inc(bar, 2)
|
|
3300
|
-
$tally.inc(baz, 3)
|
|
3301
|
-
return($tally.sorted())
|
|
3302
|
-
'''
|
|
3303
|
-
vals = await core.callStorm(q)
|
|
3304
|
-
self.eq(vals, [('foo', 1), ('bar', 2), ('baz', 3)])
|
|
3305
|
-
|
|
3306
|
-
q = '''
|
|
3307
|
-
$tally = $lib.stats.tally()
|
|
3308
|
-
$tally.inc(foo, 1)
|
|
3309
|
-
$tally.inc(bar, 2)
|
|
3310
|
-
$tally.inc(baz, 3)
|
|
3311
|
-
return($tally.sorted(reverse=$lib.true))
|
|
3312
|
-
'''
|
|
3313
|
-
vals = await core.callStorm(q)
|
|
3314
|
-
self.eq(vals, [('baz', 3), ('bar', 2), ('foo', 1)])
|
|
3315
|
-
|
|
3316
|
-
q = '''
|
|
3317
|
-
$tally = $lib.stats.tally()
|
|
3318
|
-
$tally.inc(foo, 1)
|
|
3319
|
-
$tally.inc(bar, 2)
|
|
3320
|
-
$tally.inc(baz, 3)
|
|
3321
|
-
return($tally.sorted(byname=$lib.true))
|
|
3322
|
-
'''
|
|
3323
|
-
vals = await core.callStorm(q)
|
|
3324
|
-
self.eq(vals, [('bar', 2), ('baz', 3), ('foo', 1)])
|
|
3325
|
-
|
|
3326
|
-
q = '''
|
|
3327
|
-
$tally = $lib.stats.tally()
|
|
3328
|
-
$tally.inc(foo, 1)
|
|
3329
|
-
$tally.inc(bar, 2)
|
|
3330
|
-
$tally.inc(baz, 3)
|
|
3331
|
-
return($tally.sorted(byname=$lib.true, reverse=$lib.true))
|
|
3332
|
-
'''
|
|
3333
|
-
vals = await core.callStorm(q)
|
|
3334
|
-
self.eq(vals, [('foo', 1), ('baz', 3), ('bar', 2)])
|
|
3335
|
-
|
|
3336
3364
|
async def test_storm_lib_layer(self):
|
|
3337
3365
|
|
|
3338
3366
|
async with self.getTestCoreAndProxy() as (core, prox):
|
|
@@ -3533,10 +3561,18 @@ class StormTypesTest(s_test.SynTest):
|
|
|
3533
3561
|
layrs0 = (layr0.iden, ldef1.get('iden'))
|
|
3534
3562
|
layrs1 = (ldef1.get('iden'), layr0.iden)
|
|
3535
3563
|
|
|
3564
|
+
# fork the default view to test editing the root view layers
|
|
3565
|
+
fork00 = await core.callStorm('return($lib.view.get().fork().iden)')
|
|
3566
|
+
self.eq(2, await core.callStorm('return($lib.view.get().layers.size())', opts={'view': fork00}))
|
|
3567
|
+
|
|
3536
3568
|
await core.callStorm('$lib.view.get().set(layers, $layers)', opts={'vars': {'layers': layrs0}})
|
|
3537
3569
|
ldefs = await core.callStorm('return($lib.view.get().get(layers))')
|
|
3538
3570
|
self.eq(layrs0, [x.get('iden') for x in ldefs])
|
|
3539
3571
|
|
|
3572
|
+
layers = await core.callStorm('return($lib.view.get().layers)', opts={'view': fork00})
|
|
3573
|
+
self.eq(layrs0, [layr['iden'] for layr in layers][-2:])
|
|
3574
|
+
self.len(3, layers)
|
|
3575
|
+
|
|
3540
3576
|
await core.callStorm('$lib.view.get().set(layers, $layers)', opts={'vars': {'layers': layrs1}})
|
|
3541
3577
|
ldefs = await core.callStorm('return($lib.view.get().get(layers))')
|
|
3542
3578
|
self.eq(layrs1, [x.get('iden') for x in ldefs])
|
|
@@ -6289,6 +6325,25 @@ words\tword\twrd'''
|
|
|
6289
6325
|
'size:bytes': 651,
|
|
6290
6326
|
}, await core.callStorm('return($lib.axon.metrics())'))
|
|
6291
6327
|
|
|
6328
|
+
bin_buf = b'\xbb/$\xc0A\xf1\xbf\xbc\x00_\x82v4\xf6\xbd\x1b'
|
|
6329
|
+
binsize, bin256 = await core.axon.put(bin_buf)
|
|
6330
|
+
|
|
6331
|
+
opts = {'vars': {'sha256': s_common.ehex(bin256)}}
|
|
6332
|
+
with self.raises(s_exc.BadDataValu):
|
|
6333
|
+
self.eq('', await core.callStorm('''
|
|
6334
|
+
$items = $lib.list()
|
|
6335
|
+
for $item in $lib.axon.readlines($sha256, errors=$lib.null) {
|
|
6336
|
+
$items.append($item)
|
|
6337
|
+
}
|
|
6338
|
+
return($items)
|
|
6339
|
+
''', opts=opts))
|
|
6340
|
+
|
|
6341
|
+
self.eq(('/$A\x00_v4\x1b',), await core.callStorm('''
|
|
6342
|
+
$items = $lib.list()
|
|
6343
|
+
for $item in $lib.axon.readlines($sha256, errors=ignore) { $items.append($item) }
|
|
6344
|
+
return($items)
|
|
6345
|
+
''', opts=opts))
|
|
6346
|
+
|
|
6292
6347
|
async def test_storm_lib_axon_perms(self):
|
|
6293
6348
|
|
|
6294
6349
|
async with self.getTestCore() as core:
|