synapse 2.222.0__py311-none-any.whl → 2.224.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.

Files changed (49) hide show
  1. synapse/common.py +2 -2
  2. synapse/cortex.py +159 -31
  3. synapse/cryotank.py +1 -1
  4. synapse/datamodel.py +1 -1
  5. synapse/lib/ast.py +5 -3
  6. synapse/lib/layer.py +6 -6
  7. synapse/lib/nexus.py +1 -1
  8. synapse/lib/schemas.py +2 -0
  9. synapse/lib/snap.py +15 -9
  10. synapse/lib/storm.py +35 -191
  11. synapse/lib/stormlib/auth.py +1 -1
  12. synapse/lib/stormlib/imap.py +12 -4
  13. synapse/lib/stormlib/mime.py +15 -5
  14. synapse/lib/stormlib/pkg.py +598 -0
  15. synapse/lib/stormlib/task.py +114 -0
  16. synapse/lib/stormtypes.py +43 -175
  17. synapse/lib/trigger.py +16 -14
  18. synapse/lib/version.py +2 -2
  19. synapse/lib/view.py +17 -14
  20. synapse/models/files.py +1 -1
  21. synapse/models/inet.py +25 -0
  22. synapse/models/proj.py +3 -0
  23. synapse/models/risk.py +6 -0
  24. synapse/models/syn.py +8 -0
  25. synapse/tests/test_common.py +4 -0
  26. synapse/tests/test_cortex.py +52 -1
  27. synapse/tests/test_lib_aha.py +68 -53
  28. synapse/tests/test_lib_ast.py +3 -0
  29. synapse/tests/test_lib_cell.py +12 -12
  30. synapse/tests/test_lib_storm.py +128 -248
  31. synapse/tests/test_lib_stormlib_imap.py +14 -0
  32. synapse/tests/test_lib_stormlib_mime.py +24 -0
  33. synapse/tests/test_lib_stormlib_pkg.py +456 -0
  34. synapse/tests/test_lib_stormlib_task.py +98 -0
  35. synapse/tests/test_lib_stormtypes.py +12 -100
  36. synapse/tests/test_lib_trigger.py +66 -3
  37. synapse/tests/test_lib_view.py +53 -0
  38. synapse/tests/test_model_files.py +11 -0
  39. synapse/tests/test_model_inet.py +23 -0
  40. synapse/tests/test_model_proj.py +3 -1
  41. synapse/tests/test_model_risk.py +10 -0
  42. synapse/tests/test_model_syn.py +54 -2
  43. synapse/tools/cryo/cat.py +2 -1
  44. synapse/tools/cryo/list.py +2 -0
  45. {synapse-2.222.0.dist-info → synapse-2.224.0.dist-info}/METADATA +1 -1
  46. {synapse-2.222.0.dist-info → synapse-2.224.0.dist-info}/RECORD +49 -45
  47. {synapse-2.222.0.dist-info → synapse-2.224.0.dist-info}/WHEEL +0 -0
  48. {synapse-2.222.0.dist-info → synapse-2.224.0.dist-info}/licenses/LICENSE +0 -0
  49. {synapse-2.222.0.dist-info → synapse-2.224.0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,456 @@
1
+ import synapse.exc as s_exc
2
+ import synapse.common as s_common
3
+
4
+ import synapse.lib.httpapi as s_httpapi
5
+ import synapse.lib.version as s_version
6
+
7
+ import synapse.tests.utils as s_test
8
+
9
+ class StormLibPkgTest(s_test.SynTest):
10
+
11
+ async def test_stormlib_pkg_basic(self):
12
+
13
+ async with self.getTestCore() as core:
14
+
15
+ pkg0 = {'name': 'hehe', 'version': '1.2.3'}
16
+ await core.addStormPkg(pkg0)
17
+ self.eq('1.2.3', await core.callStorm('return($lib.pkg.get(hehe).version)'))
18
+
19
+ self.eq(None, await core.callStorm('return($lib.pkg.get(nopkg))'))
20
+
21
+ pkg1 = {'name': 'haha', 'version': '1.2.3'}
22
+ await core.addStormPkg(pkg1)
23
+ msgs = await core.stormlist('pkg.list')
24
+ self.stormIsInPrint('haha', msgs)
25
+ self.stormIsInPrint('hehe', msgs)
26
+
27
+ self.true(await core.callStorm('return($lib.pkg.has(haha))'))
28
+
29
+ await core.delStormPkg('haha')
30
+ self.none(await core.callStorm('return($lib.pkg.get(haha))'))
31
+ self.false(await core.callStorm('return($lib.pkg.has(haha))'))
32
+
33
+ msgs = await core.stormlist('pkg.list --verbose')
34
+ self.stormIsInPrint('not available', msgs)
35
+
36
+ pkg2 = {'name': 'hoho', 'version': '4.5.6', 'build': {'time': 1732017600000}}
37
+ await core.addStormPkg(pkg2)
38
+ self.eq('4.5.6', await core.callStorm('return($lib.pkg.get(hoho).version)'))
39
+ msgs = await core.stormlist('pkg.list --verbose')
40
+ self.stormIsInPrint('2024-11-19 12:00:00', msgs)
41
+
42
+ pkgdef = {
43
+ 'name': 'foobar',
44
+ 'version': '1.2.3',
45
+ }
46
+
47
+ await core.addStormPkg(pkgdef)
48
+
49
+ deps = await core.callStorm('return($lib.pkg.deps($pkgdef))', opts={'vars': {'pkgdef': pkgdef}})
50
+ self.eq({
51
+ 'requires': (),
52
+ 'conflicts': (),
53
+ }, deps)
54
+
55
+ pkgdef = {
56
+ 'name': 'bazfaz',
57
+ 'version': '2.2.2',
58
+ 'depends': {
59
+ 'conflicts': (
60
+ {'name': 'foobar'},
61
+ ),
62
+ }
63
+ }
64
+
65
+ with self.raises(s_exc.StormPkgConflicts):
66
+ await core.addStormPkg(pkgdef)
67
+
68
+ deps = await core.callStorm('return($lib.pkg.deps($pkgdef))', opts={'vars': {'pkgdef': pkgdef}})
69
+ self.eq({
70
+ 'requires': (),
71
+ 'conflicts': (
72
+ {'name': 'foobar', 'version': None, 'desc': None, 'ok': False, 'actual': '1.2.3'},
73
+ )
74
+ }, deps)
75
+
76
+ pkgdef = {
77
+ 'name': 'bazfaz',
78
+ 'version': '2.2.2',
79
+ 'depends': {
80
+ 'conflicts': (
81
+ {'name': 'foobar', 'version': '>=1.0.0', 'desc': 'foo'},
82
+ ),
83
+ }
84
+ }
85
+
86
+ with self.raises(s_exc.StormPkgConflicts):
87
+ await core.addStormPkg(pkgdef)
88
+
89
+ deps = await core.callStorm('return($lib.pkg.deps($pkgdef))', opts={'vars': {'pkgdef': pkgdef}})
90
+ self.eq({
91
+ 'requires': (),
92
+ 'conflicts': (
93
+ {'name': 'foobar', 'version': '>=1.0.0', 'desc': 'foo', 'ok': False, 'actual': '1.2.3'},
94
+ )
95
+ }, deps)
96
+
97
+ pkgdef = {
98
+ 'name': 'bazfaz',
99
+ 'version': '2.2.2',
100
+ 'depends': {
101
+ 'requires': (
102
+ {'name': 'foobar', 'version': '>=2.0.0,<3.0.0'},
103
+ ),
104
+ }
105
+ }
106
+
107
+ with self.getAsyncLoggerStream('synapse.cortex', 'bazfaz requirement') as stream:
108
+ await core.addStormPkg(pkgdef)
109
+ self.true(await stream.wait(timeout=1))
110
+
111
+ pkgdef = {
112
+ 'name': 'bazfaz',
113
+ 'version': '2.2.2',
114
+ 'depends': {
115
+ 'requires': (
116
+ {'name': 'foobar', 'version': '>=2.0.0,<3.0.0', 'optional': True},
117
+ ),
118
+ }
119
+ }
120
+
121
+ with self.getAsyncLoggerStream('synapse.cortex', 'bazfaz optional requirement') as stream:
122
+ await core.addStormPkg(pkgdef)
123
+ self.true(await stream.wait(timeout=1))
124
+
125
+ deps = await core.callStorm('return($lib.pkg.deps($pkgdef))', opts={'vars': {'pkgdef': pkgdef}})
126
+ self.eq({
127
+ 'requires': (
128
+ {'name': 'foobar', 'version': '>=2.0.0,<3.0.0', 'desc': None,
129
+ 'ok': False, 'actual': '1.2.3', 'optional': True},
130
+ ),
131
+ 'conflicts': ()
132
+ }, deps)
133
+
134
+ pkgdef = {
135
+ 'name': 'lolzlolz',
136
+ 'version': '1.2.3',
137
+ }
138
+
139
+ await core.addStormPkg(pkgdef)
140
+
141
+ deps = await core.callStorm('return($lib.pkg.deps($pkgdef))', opts={'vars': {'pkgdef': pkgdef}})
142
+ self.eq({
143
+ 'requires': (),
144
+ 'conflicts': (),
145
+ }, deps)
146
+
147
+ pkgdef = {
148
+ 'name': 'bazfaz',
149
+ 'version': '2.2.2',
150
+ 'depends': {
151
+ 'requires': (
152
+ {'name': 'lolzlolz', 'version': '>=1.0.0,<2.0.0', 'desc': 'lol'},
153
+ ),
154
+ 'conflicts': (
155
+ {'name': 'foobar', 'version': '>=3.0.0'},
156
+ ),
157
+ }
158
+ }
159
+
160
+ await core.addStormPkg(pkgdef)
161
+
162
+ deps = await core.callStorm('return($lib.pkg.deps($pkgdef))', opts={'vars': {'pkgdef': pkgdef}})
163
+ self.eq({
164
+ 'requires': (
165
+ {'name': 'lolzlolz', 'version': '>=1.0.0,<2.0.0', 'desc': 'lol', 'ok': True, 'actual': '1.2.3'},
166
+ ),
167
+ 'conflicts': (
168
+ {'name': 'foobar', 'version': '>=3.0.0', 'desc': None, 'ok': True, 'actual': '1.2.3'},
169
+ )
170
+ }, deps)
171
+
172
+ pkgdef = {
173
+ 'name': 'zoinkszoinks',
174
+ 'version': '2.2.2',
175
+ 'depends': {
176
+ 'requires': (
177
+ {'name': 'newpnewp', 'version': '1.2.3'},
178
+ ),
179
+ 'conflicts': (
180
+ {'name': 'newpnewp'},
181
+ ),
182
+ }
183
+ }
184
+
185
+ await core.addStormPkg(pkgdef)
186
+
187
+ deps = await core.callStorm('return($lib.pkg.deps($pkgdef))', opts={'vars': {'pkgdef': pkgdef}})
188
+ self.eq({
189
+ 'requires': (
190
+ {'name': 'newpnewp', 'version': '1.2.3', 'desc': None, 'ok': False, 'actual': None},
191
+ ),
192
+ 'conflicts': (
193
+ {'name': 'newpnewp', 'version': None, 'desc': None, 'ok': True, 'actual': None},
194
+ )
195
+ }, deps)
196
+
197
+ async def test_stormlib_pkg_load(self):
198
+ cont = s_common.guid()
199
+ pkg = {
200
+ 'name': 'testload',
201
+ 'version': '0.3.0',
202
+ 'modules': (
203
+ {
204
+ 'name': 'testload',
205
+ 'storm': 'function x() { return((0)) }',
206
+ },
207
+ ),
208
+ 'onload': f'[ ps:contact={cont} ] $lib.print(teststring) $lib.warn(testwarn, key=valu) return($path.vars.newp)'
209
+ }
210
+ class PkgHandler(s_httpapi.Handler):
211
+
212
+ async def get(self, name):
213
+ assert self.request.headers.get('X-Synapse-Version') == s_version.verstring
214
+
215
+ if name == 'notok':
216
+ self.sendRestErr('FooBar', 'baz faz')
217
+ return
218
+
219
+ self.sendRestRetn(pkg)
220
+
221
+ class PkgHandlerRaw(s_httpapi.Handler):
222
+ async def get(self, name):
223
+ assert self.request.headers.get('X-Synapse-Version') == s_version.verstring
224
+
225
+ self.set_header('Content-Type', 'application/json')
226
+ return self.write(pkg)
227
+
228
+ async with self.getTestCore() as core:
229
+ core.addHttpApi('/api/v1/pkgtest/(.*)', PkgHandler, {'cell': core})
230
+ core.addHttpApi('/api/v1/pkgtestraw/(.*)', PkgHandlerRaw, {'cell': core})
231
+ port = (await core.addHttpsPort(0, host='127.0.0.1'))[1]
232
+
233
+ msgs = await core.stormlist(f'pkg.load --ssl-noverify https://127.0.0.1:{port}/api/v1/newp/newp')
234
+ self.stormIsInWarn('pkg.load got HTTP code: 404', msgs)
235
+
236
+ msgs = await core.stormlist(f'pkg.load --ssl-noverify https://127.0.0.1:{port}/api/v1/pkgtest/notok')
237
+ self.stormIsInWarn('pkg.load got JSON error: FooBar', msgs)
238
+
239
+ # onload will on fire once. all other pkg.load events will effectively bounce
240
+ # because the pkg hasn't changed so no loading occurs
241
+ waiter = core.waiter(1, 'core:pkg:onload:complete')
242
+
243
+ with self.getAsyncLoggerStream('synapse.cortex') as stream:
244
+ msgs = await core.stormlist(f'pkg.load --ssl-noverify https://127.0.0.1:{port}/api/v1/pkgtest/yep')
245
+ self.stormIsInPrint('testload @0.3.0', msgs)
246
+
247
+ msgs = await core.stormlist(f'pkg.load --ssl-noverify --raw https://127.0.0.1:{port}/api/v1/pkgtestraw/yep')
248
+ self.stormIsInPrint('testload @0.3.0', msgs)
249
+
250
+ stream.seek(0)
251
+ buf = stream.read()
252
+ self.isin("testload onload output: teststring", buf)
253
+ self.isin("testload onload output: testwarn", buf)
254
+ self.isin("No var with name: newp", buf)
255
+ self.len(1, await core.nodes(f'ps:contact={cont}'))
256
+
257
+ evnts = await waiter.wait(timeout=4)
258
+ exp = [
259
+ ('core:pkg:onload:complete', {'pkg': 'testload'})
260
+ ]
261
+ self.eq(exp, evnts)
262
+
263
+ async def test_stormlib_pkg_vars(self):
264
+ with self.getTestDir() as dirn:
265
+
266
+ async with self.getTestCore(dirn=dirn) as core:
267
+
268
+ lowuser = await core.addUser('lowuser')
269
+ aslow = {'user': lowuser.get('iden')}
270
+ await core.callStorm('auth.user.addrule lowuser node')
271
+
272
+ # basic crud
273
+
274
+ self.none(await core.callStorm('return($lib.pkg.vars(pkg0).bar)'))
275
+ self.none(await core.callStorm('$varz=$lib.pkg.vars(pkg0) $varz.baz=$lib.undef return($varz.baz)'))
276
+ self.eq([], await core.callStorm('''
277
+ $kvs = ([])
278
+ for $kv in $lib.pkg.vars(pkg0) { $kvs.append($kv) }
279
+ return($kvs)
280
+ '''))
281
+
282
+ await core.callStorm('$lib.pkg.vars(pkg0).bar = cat')
283
+ await core.callStorm('$lib.pkg.vars(pkg0).baz = dog')
284
+
285
+ await core.callStorm('$lib.pkg.vars(pkg1).bar = emu')
286
+ await core.callStorm('$lib.pkg.vars(pkg1).baz = groot')
287
+
288
+ self.eq('cat', await core.callStorm('return($lib.pkg.vars(pkg0).bar)'))
289
+ self.eq('dog', await core.callStorm('return($lib.pkg.vars(pkg0).baz)'))
290
+ self.eq('emu', await core.callStorm('return($lib.pkg.vars(pkg1).bar)'))
291
+ self.eq('groot', await core.callStorm('return($lib.pkg.vars(pkg1).baz)'))
292
+
293
+ self.sorteq([('bar', 'cat'), ('baz', 'dog')], await core.callStorm('''
294
+ $kvs = ([])
295
+ for $kv in $lib.pkg.vars(pkg0) { $kvs.append($kv) }
296
+ return($kvs)
297
+ '''))
298
+ self.sorteq([('bar', 'emu'), ('baz', 'groot')], await core.callStorm('''
299
+ $kvs = ([])
300
+ for $kv in $lib.pkg.vars(pkg1) { $kvs.append($kv) }
301
+ return($kvs)
302
+ '''))
303
+
304
+ await core.callStorm('$lib.pkg.vars(pkg0).baz = $lib.undef')
305
+ self.none(await core.callStorm('return($lib.pkg.vars(pkg0).baz)'))
306
+
307
+ # perms
308
+
309
+ await self.asyncraises(s_exc.AuthDeny, core.callStorm('$lib.print($lib.pkg.vars(pkg0))', opts=aslow))
310
+ await self.asyncraises(s_exc.AuthDeny, core.callStorm('return($lib.pkg.vars(pkg0).baz)', opts=aslow))
311
+ await self.asyncraises(s_exc.AuthDeny, core.callStorm('$lib.pkg.vars(pkg0).baz = cool', opts=aslow))
312
+ await self.asyncraises(s_exc.AuthDeny, core.callStorm('$lib.pkg.vars(pkg0).baz = $lib.undef', opts=aslow))
313
+ await self.asyncraises(s_exc.AuthDeny, core.callStorm('''
314
+ $kvs = ([])
315
+ for $kv in $lib.pkg.vars(pkg0) { $kvs.append($kv) }
316
+ return($kvs)
317
+ ''', opts=aslow))
318
+ await self.asyncraises(s_exc.AuthDeny, core.callStorm('''
319
+ [ test:str=foo ]
320
+ $kvs = ([])
321
+ for $kv in $lib.pkg.vars(pkg0) { $kvs.append($kv) }
322
+ fini { return($kvs) }
323
+ ''', opts=aslow))
324
+
325
+ await core.callStorm('auth.user.addrule lowuser "power-ups.pkg0.admin"')
326
+
327
+ self.stormHasNoWarnErr(await core.nodes('$lib.print($lib.pkg.vars(pkg0))', opts=aslow))
328
+ await core.callStorm('$lib.pkg.vars(pkg0).baz = cool', opts=aslow)
329
+ self.eq('cool', await core.callStorm('return($lib.pkg.vars(pkg0).baz)', opts=aslow))
330
+ await core.callStorm('$lib.pkg.vars(pkg0).baz = $lib.undef', opts=aslow)
331
+ self.eq([('bar', 'cat')], await core.callStorm('''
332
+ $kvs = ([])
333
+ for $kv in $lib.pkg.vars(pkg0) { $kvs.append($kv) }
334
+ return($kvs)
335
+ ''', opts=aslow))
336
+ self.eq([('bar', 'cat')], await core.callStorm('''
337
+ [ test:str=foo ]
338
+ $kvs = ([])
339
+ for $kv in $lib.pkg.vars(pkg0) { $kvs.append($kv) }
340
+ fini { return($kvs) }
341
+ ''', opts=aslow))
342
+
343
+ async with self.getTestCore(dirn=dirn) as core:
344
+
345
+ # data persists
346
+
347
+ self.eq('cat', await core.callStorm('return($lib.pkg.vars(pkg0).bar)'))
348
+ self.none(await core.callStorm('return($lib.pkg.vars(pkg0).baz)'))
349
+ self.eq('emu', await core.callStorm('return($lib.pkg.vars(pkg1).bar)'))
350
+ self.eq('groot', await core.callStorm('return($lib.pkg.vars(pkg1).baz)'))
351
+
352
+ self.sorteq([('bar', 'cat')], await core.callStorm('''
353
+ $kvs = ([])
354
+ for $kv in $lib.pkg.vars(pkg0) { $kvs.append($kv) }
355
+ return($kvs)
356
+ '''))
357
+ self.sorteq([('bar', 'emu'), ('baz', 'groot')], await core.callStorm('''
358
+ $kvs = ([])
359
+ for $kv in $lib.pkg.vars(pkg1) { $kvs.append($kv) }
360
+ return($kvs)
361
+ '''))
362
+
363
+ async def test_stormlib_pkg_queues(self):
364
+ with self.getTestDir() as dirn:
365
+
366
+ async with self.getTestCore(dirn=dirn) as core:
367
+
368
+ self.eq(1, await core.callStorm('$q = $lib.pkg.queues(pkg0).add(stuff) $q.put(5) return($q.size())'))
369
+ self.eq(2, await core.callStorm('$q = $lib.pkg.queues(pkg0).get(stuff) $q.put(6) return($q.size())'))
370
+ self.eq(3, await core.callStorm('$q = $lib.pkg.queues(pkg0).gen(stuff) $q.put(7) return($q.size())'))
371
+ self.eq(1, await core.callStorm('$q = $lib.pkg.queues(pkg0).gen(other) $q.put(8) return($q.size())'))
372
+ self.eq(1, await core.callStorm('$q = $lib.pkg.queues(pkg1).gen(stuff) $q.put(9) return($q.size())'))
373
+
374
+ # Replay coverage
375
+ await core._addStormPkgQueue('pkg1', 'stuff', {})
376
+ await core._delStormPkgQueue('pkg1', 'newp')
377
+
378
+ q = '$qs = () for $q in $lib.pkg.queues(pkg0).list() { $qs.append($q) } return($qs)'
379
+ self.len(2, await core.callStorm(q))
380
+
381
+ q = '$qs = () for $q in $lib.pkg.queues(pkg1).list() { $qs.append($q) } return($qs)'
382
+ self.len(1, await core.callStorm(q))
383
+
384
+ await core.callStorm('$q = $lib.pkg.queues(pkg0).del(other)')
385
+
386
+ q = '$qs = () for $q in $lib.pkg.queues(pkg0).list() { $qs.append($q) } return($qs)'
387
+ self.len(1, await core.callStorm(q))
388
+
389
+ await core.callStorm('$lib.pkg.queues(pkg0).get(stuff).puts((10, 11))')
390
+
391
+ self.eq((0, '5'), await core.callStorm('return($lib.pkg.queues(pkg0).get(stuff).get())'))
392
+
393
+ q = '''
394
+ $retn = ()
395
+ for ($_, $v) in $lib.pkg.queues(pkg0).get(stuff).gets(1, wait=(false)) { $retn.append($v) }
396
+ return($retn)
397
+ '''
398
+ self.eq(('6', '7', '10', '11'), await core.callStorm(q))
399
+
400
+ q = '''
401
+ $retn = ()
402
+ for ($_, $v) in $lib.pkg.queues(pkg0).get(stuff).gets(1, size=(2)) { $retn.append($v) }
403
+ return($retn)
404
+ '''
405
+ self.eq(('6', '7'), await core.callStorm(q))
406
+
407
+ self.eq((1, '6'), await core.callStorm('return($lib.pkg.queues(pkg0).get(stuff).get(1))'))
408
+
409
+ q = '''
410
+ $retn = ()
411
+ for ($_, $v) in $lib.pkg.queues(pkg0).get(stuff).gets(2, wait=(false)) { $retn.append($v) }
412
+ return($retn)
413
+ '''
414
+ self.eq(('7', '10', '11'), await core.callStorm(q))
415
+
416
+ await core.callStorm('$lib.pkg.queues(pkg0).get(stuff).cull(2)')
417
+ self.eq((3, '10'), await core.callStorm('return($lib.pkg.queues(pkg0).get(stuff).pop())'))
418
+
419
+ q = 'return(`{$lib.pkg.queues(pkg0).get(stuff)}`)'
420
+ self.eq('pkg:queue: pkg0 - stuff', await core.callStorm(q))
421
+
422
+ q = 'return(($lib.pkg.queues(pkg0).get(stuff) = $lib.pkg.queues(pkg0).get(stuff)))'
423
+ self.true(await core.callStorm(q))
424
+
425
+ q = 'return(($lib.pkg.queues(pkg0).get(stuff) = $lib.pkg.queues(pkg1).get(stuff)))'
426
+ self.false(await core.callStorm(q))
427
+
428
+ q = 'return(($lib.pkg.queues(pkg0).get(stuff) = "newp"))'
429
+ self.false(await core.callStorm(q))
430
+
431
+ q = '$set = $lib.set() $p = $lib.pkg.queues(pkg0).get(stuff) $set.add($p) $set.add($p) return($set)'
432
+ self.len(1, await core.callStorm(q))
433
+
434
+ with self.raises(s_exc.DupName):
435
+ await core.callStorm('$lib.pkg.queues(pkg1).add(stuff)')
436
+
437
+ with self.raises(s_exc.NoSuchName):
438
+ await core.callStorm('$lib.pkg.queues(pkg1).del(newp)')
439
+
440
+ lowuser = await core.addUser('lowuser')
441
+ aslow = {'user': lowuser.get('iden')}
442
+ await core.callStorm('auth.user.addrule lowuser "power-ups.pkg0.admin"')
443
+
444
+ self.eq(1, await core.callStorm('return($lib.pkg.queues(pkg0).get(stuff).size())', opts=aslow))
445
+
446
+ with self.raises(s_exc.AuthDeny):
447
+ await core.callStorm('$lib.print($lib.pkg.queues(pkg1))', opts=aslow)
448
+
449
+ with self.raises(s_exc.AuthDeny):
450
+ await core.callStorm('$lib.pkg.queues(pkg1).get(stuff)', opts=aslow)
451
+
452
+ async with self.getTestCore(dirn=dirn) as core:
453
+ self.eq(1, await core.callStorm('return($lib.pkg.queues(pkg0).get(stuff).size())', opts=aslow))
454
+
455
+ self.eq((4, '11'), await core.callStorm('return($lib.pkg.queues(pkg0).get(stuff).pop(4))'))
456
+ self.none(await core.callStorm('return($lib.pkg.queues(pkg0).get(stuff).pop())'))
@@ -0,0 +1,98 @@
1
+ import asyncio
2
+
3
+ import synapse.exc as s_exc
4
+ import synapse.common as s_common
5
+ import synapse.cortex as s_cortex
6
+ import synapse.lib.base as s_base
7
+ import synapse.tests.utils as s_test
8
+
9
+ class TaskLibTest(s_test.SynTest):
10
+
11
+ async def test_lib_task_basics(self):
12
+
13
+ async with self.getTestAha() as aha:
14
+
15
+ conf = {'aha:provision': await aha.addAhaSvcProv('00.cortex')}
16
+ core00 = await aha.enter_context(self.getTestCore(conf=conf))
17
+
18
+ conf = {'aha:provision': await aha.addAhaSvcProv('01.cortex', {'mirror': 'cortex'})}
19
+ core01 = await aha.enter_context(self.getTestCore(conf=conf))
20
+
21
+ iden0 = 'c7fc6d4ced5759fe6fcc047b6bd3374a'
22
+ task0 = aha.schedCoro(core01.stormlist('$lib.print(root) $lib.time.sleep(10)', opts={'task': iden0}))
23
+
24
+ msgs = await core00.stormlist('task.list')
25
+ self.stormIsInPrint('00.cortex.synapse', msgs)
26
+ self.stormIsInPrint('task.list', msgs)
27
+ self.stormIsInPrint('01.cortex.synapse', msgs)
28
+ self.stormIsInPrint('$lib.print(root)', msgs)
29
+ self.stormIsInPrint('2 tasks', msgs)
30
+
31
+ msgs = await core01.stormlist('task.list')
32
+ self.stormIsInPrint('00.cortex.synapse', msgs)
33
+ self.stormIsInPrint('task.list', msgs)
34
+ self.stormIsInPrint('01.cortex.synapse', msgs)
35
+ self.stormIsInPrint('$lib.print(root)', msgs)
36
+ self.stormIsInPrint('2 tasks', msgs)
37
+
38
+ user = await core01.auth.addUser('someuser')
39
+
40
+ async with core00.getLocalProxy(user='someuser') as prox00:
41
+ iden1 = s_common.guid()
42
+ task1 = aha.schedCoro(prox00.callStorm('$lib.print(on00) $lib.time.sleep(10)', opts={'task': iden1}))
43
+
44
+ async with core01.getLocalProxy(user='someuser') as prox01:
45
+ msgs = await s_test.alist(prox01.storm('task.list'))
46
+ self.stormIsInPrint('00.cortex.synapse', msgs)
47
+ self.stormIsInPrint('$lib.print(on00)', msgs)
48
+ self.stormIsInPrint('01.cortex.synapse', msgs)
49
+ self.stormIsInPrint('task.list', msgs)
50
+ self.stormIsInPrint('2 tasks', msgs)
51
+
52
+ await user.addRule((True, ('task', 'get')))
53
+
54
+ msgs = await s_test.alist(prox00.storm('task.list'))
55
+ self.stormIsInPrint('4 tasks', msgs)
56
+
57
+ msgs = await s_test.alist(prox01.storm('task.list'))
58
+ self.stormIsInPrint('4 tasks', msgs)
59
+
60
+ # We can kill our own task
61
+ await prox01.callStorm(f'task.kill {iden1}')
62
+ with self.raises(s_exc.SynErr):
63
+ await task1
64
+
65
+ # No task matches
66
+ with self.raises(s_exc.StormRuntimeError) as exc:
67
+ await prox01.callStorm('task.kill newp')
68
+ self.isin('does not match any tasks', exc.exception.get('mesg'))
69
+
70
+ with self.raises(s_exc.StormRuntimeError) as exc:
71
+ await prox01.callStorm('task.kill ""')
72
+ self.isin('empty task iden prefix', exc.exception.get('mesg'))
73
+
74
+ iden2 = 'c7fc6d4ced5759fe6fcc047b6bd3374b'
75
+ task2 = aha.schedCoro(core00.stormlist('$lib.print(root) $lib.time.sleep(10)', opts={'task': iden2}))
76
+
77
+ # Matches exist but we don't have perms to see them
78
+ with self.raises(s_exc.StormRuntimeError) as exc:
79
+ await prox01.callStorm('task.kill c7fc')
80
+ self.isin('does not match any tasks', exc.exception.get('mesg'))
81
+
82
+ await user.addRule((True, ('task', 'del')))
83
+
84
+ # Multiple matches
85
+ with self.raises(s_exc.StormRuntimeError) as exc:
86
+ await prox01.callStorm('task.kill c7fc')
87
+ self.isin('more than one task', exc.exception.get('mesg'))
88
+
89
+ await prox01.callStorm(f'task.kill {iden0}')
90
+ with self.raises(asyncio.CancelledError):
91
+ await task0
92
+
93
+ await prox01.callStorm(f'task.kill {iden2}')
94
+ with self.raises(asyncio.CancelledError):
95
+ await task2
96
+
97
+ msgs = await s_test.alist(core00.storm('task.list'))
98
+ self.stormIsInPrint('1 task', msgs)
@@ -3297,6 +3297,18 @@ class StormTypesTest(s_test.SynTest):
3297
3297
  self.false(mesgs[0])
3298
3298
  self.isin('Ambiguous time', mesgs[1]['errinfo']['mesg'])
3299
3299
 
3300
+ valu = await core.callStorm('return($lib.time.format($lib.cast(time, 20251002), $lib.time.formats.iso8601))')
3301
+ self.eq(valu, '2025-10-02T00:00:00Z')
3302
+
3303
+ valu = await core.callStorm('return($lib.time.format($lib.cast(time, 20251002), $lib.time.formats.iso8601us))')
3304
+ self.eq(valu, '2025-10-02T00:00:00.000000Z')
3305
+
3306
+ valu = await core.callStorm('return($lib.time.format($lib.cast(time, 20251002), $lib.time.formats.rfc2822))')
3307
+ self.eq(valu, '02 Oct 2025 00:00:00 UT')
3308
+
3309
+ valu = await core.callStorm('return($lib.time.format($lib.cast(time, 20251002), $lib.time.formats.synapse))')
3310
+ self.eq(valu, '2025/10/02 00:00:00.000000')
3311
+
3300
3312
  async def test_storm_lib_time_ticker(self):
3301
3313
 
3302
3314
  async with self.getTestCore() as core:
@@ -8005,103 +8017,3 @@ words\tword\twrd'''
8005
8017
 
8006
8018
  q = 'return($lib.axon.unpack($sha256, fmt=">Q", offs=24))'
8007
8019
  await self.asyncraises(s_exc.BadDataValu, core.callStorm(q, opts=opts))
8008
-
8009
- async def test_storm_pkg_vars(self):
8010
- with self.getTestDir() as dirn:
8011
-
8012
- async with self.getTestCore(dirn=dirn) as core:
8013
-
8014
- lowuser = await core.addUser('lowuser')
8015
- aslow = {'user': lowuser.get('iden')}
8016
- await core.callStorm('auth.user.addrule lowuser node')
8017
-
8018
- # basic crud
8019
-
8020
- self.none(await core.callStorm('return($lib.pkg.vars(pkg0).bar)'))
8021
- self.none(await core.callStorm('$varz=$lib.pkg.vars(pkg0) $varz.baz=$lib.undef return($varz.baz)'))
8022
- self.eq([], await core.callStorm('''
8023
- $kvs = ([])
8024
- for $kv in $lib.pkg.vars(pkg0) { $kvs.append($kv) }
8025
- return($kvs)
8026
- '''))
8027
-
8028
- await core.callStorm('$lib.pkg.vars(pkg0).bar = cat')
8029
- await core.callStorm('$lib.pkg.vars(pkg0).baz = dog')
8030
-
8031
- await core.callStorm('$lib.pkg.vars(pkg1).bar = emu')
8032
- await core.callStorm('$lib.pkg.vars(pkg1).baz = groot')
8033
-
8034
- self.eq('cat', await core.callStorm('return($lib.pkg.vars(pkg0).bar)'))
8035
- self.eq('dog', await core.callStorm('return($lib.pkg.vars(pkg0).baz)'))
8036
- self.eq('emu', await core.callStorm('return($lib.pkg.vars(pkg1).bar)'))
8037
- self.eq('groot', await core.callStorm('return($lib.pkg.vars(pkg1).baz)'))
8038
-
8039
- self.sorteq([('bar', 'cat'), ('baz', 'dog')], await core.callStorm('''
8040
- $kvs = ([])
8041
- for $kv in $lib.pkg.vars(pkg0) { $kvs.append($kv) }
8042
- return($kvs)
8043
- '''))
8044
- self.sorteq([('bar', 'emu'), ('baz', 'groot')], await core.callStorm('''
8045
- $kvs = ([])
8046
- for $kv in $lib.pkg.vars(pkg1) { $kvs.append($kv) }
8047
- return($kvs)
8048
- '''))
8049
-
8050
- await core.callStorm('$lib.pkg.vars(pkg0).baz = $lib.undef')
8051
- self.none(await core.callStorm('return($lib.pkg.vars(pkg0).baz)'))
8052
-
8053
- # perms
8054
-
8055
- await self.asyncraises(s_exc.AuthDeny, core.callStorm('$lib.print($lib.pkg.vars(pkg0))', opts=aslow))
8056
- await self.asyncraises(s_exc.AuthDeny, core.callStorm('return($lib.pkg.vars(pkg0).baz)', opts=aslow))
8057
- await self.asyncraises(s_exc.AuthDeny, core.callStorm('$lib.pkg.vars(pkg0).baz = cool', opts=aslow))
8058
- await self.asyncraises(s_exc.AuthDeny, core.callStorm('$lib.pkg.vars(pkg0).baz = $lib.undef', opts=aslow))
8059
- await self.asyncraises(s_exc.AuthDeny, core.callStorm('''
8060
- $kvs = ([])
8061
- for $kv in $lib.pkg.vars(pkg0) { $kvs.append($kv) }
8062
- return($kvs)
8063
- ''', opts=aslow))
8064
- await self.asyncraises(s_exc.AuthDeny, core.callStorm('''
8065
- [ test:str=foo ]
8066
- $kvs = ([])
8067
- for $kv in $lib.pkg.vars(pkg0) { $kvs.append($kv) }
8068
- fini { return($kvs) }
8069
- ''', opts=aslow))
8070
-
8071
- await core.callStorm('auth.user.addrule lowuser "power-ups.pkg0.admin"')
8072
-
8073
- self.stormHasNoWarnErr(await core.nodes('$lib.print($lib.pkg.vars(pkg0))', opts=aslow))
8074
- await core.callStorm('$lib.pkg.vars(pkg0).baz = cool', opts=aslow)
8075
- self.eq('cool', await core.callStorm('return($lib.pkg.vars(pkg0).baz)', opts=aslow))
8076
- await core.callStorm('$lib.pkg.vars(pkg0).baz = $lib.undef', opts=aslow)
8077
- self.eq([('bar', 'cat')], await core.callStorm('''
8078
- $kvs = ([])
8079
- for $kv in $lib.pkg.vars(pkg0) { $kvs.append($kv) }
8080
- return($kvs)
8081
- ''', opts=aslow))
8082
- self.eq([('bar', 'cat')], await core.callStorm('''
8083
- [ test:str=foo ]
8084
- $kvs = ([])
8085
- for $kv in $lib.pkg.vars(pkg0) { $kvs.append($kv) }
8086
- fini { return($kvs) }
8087
- ''', opts=aslow))
8088
-
8089
- async with self.getTestCore(dirn=dirn) as core:
8090
-
8091
- # data persists
8092
-
8093
- self.eq('cat', await core.callStorm('return($lib.pkg.vars(pkg0).bar)'))
8094
- self.none(await core.callStorm('return($lib.pkg.vars(pkg0).baz)'))
8095
- self.eq('emu', await core.callStorm('return($lib.pkg.vars(pkg1).bar)'))
8096
- self.eq('groot', await core.callStorm('return($lib.pkg.vars(pkg1).baz)'))
8097
-
8098
- self.sorteq([('bar', 'cat')], await core.callStorm('''
8099
- $kvs = ([])
8100
- for $kv in $lib.pkg.vars(pkg0) { $kvs.append($kv) }
8101
- return($kvs)
8102
- '''))
8103
- self.sorteq([('bar', 'emu'), ('baz', 'groot')], await core.callStorm('''
8104
- $kvs = ([])
8105
- for $kv in $lib.pkg.vars(pkg1) { $kvs.append($kv) }
8106
- return($kvs)
8107
- '''))