synapse 2.195.1__py311-none-any.whl → 2.197.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 (60) hide show
  1. synapse/axon.py +72 -5
  2. synapse/common.py +23 -0
  3. synapse/cortex.py +13 -8
  4. synapse/cryotank.py +2 -2
  5. synapse/daemon.py +1 -0
  6. synapse/lib/aha.py +159 -4
  7. synapse/lib/cell.py +133 -8
  8. synapse/lib/config.py +3 -3
  9. synapse/lib/jsonstor.py +2 -1
  10. synapse/lib/modelrev.py +5 -1
  11. synapse/lib/multislabseqn.py +2 -2
  12. synapse/lib/nexus.py +4 -1
  13. synapse/lib/reflect.py +4 -5
  14. synapse/lib/schemas.py +478 -1
  15. synapse/lib/snap.py +14 -7
  16. synapse/lib/storm.py +12 -394
  17. synapse/lib/stormlib/aha.py +351 -1
  18. synapse/lib/stormlib/graph.py +0 -61
  19. synapse/lib/stormlib/index.py +52 -0
  20. synapse/lib/stormlib/utils.py +37 -0
  21. synapse/lib/stormtypes.py +121 -1
  22. synapse/lib/task.py +13 -2
  23. synapse/lib/urlhelp.py +1 -1
  24. synapse/lib/version.py +2 -2
  25. synapse/models/base.py +3 -0
  26. synapse/models/doc.py +62 -0
  27. synapse/models/infotech.py +55 -16
  28. synapse/models/orgs.py +20 -14
  29. synapse/models/risk.py +23 -10
  30. synapse/models/transport.py +8 -3
  31. synapse/telepath.py +12 -0
  32. synapse/tests/test_axon.py +23 -0
  33. synapse/tests/test_common.py +28 -0
  34. synapse/tests/test_datamodel.py +15 -0
  35. synapse/tests/test_lib_aha.py +201 -0
  36. synapse/tests/test_lib_boss.py +15 -6
  37. synapse/tests/test_lib_cell.py +104 -0
  38. synapse/tests/test_lib_jsonstor.py +1 -0
  39. synapse/tests/test_lib_modelrev.py +6 -0
  40. synapse/tests/test_lib_stormlib_aha.py +188 -0
  41. synapse/tests/test_lib_stormlib_index.py +39 -0
  42. synapse/tests/test_lib_stormlib_utils.py +14 -0
  43. synapse/tests/test_lib_stormtypes.py +90 -3
  44. synapse/tests/test_lib_task.py +31 -13
  45. synapse/tests/test_model_base.py +2 -0
  46. synapse/tests/test_model_doc.py +38 -0
  47. synapse/tests/test_model_infotech.py +28 -1
  48. synapse/tests/test_model_orgs.py +9 -0
  49. synapse/tests/test_model_risk.py +2 -0
  50. synapse/tests/test_model_transport.py +1 -0
  51. synapse/tests/test_telepath.py +26 -0
  52. synapse/tests/test_tools_aha.py +192 -0
  53. synapse/tools/aha/mirror.py +193 -0
  54. synapse/tools/changelog.py +32 -27
  55. synapse/tools/genpkg.py +2 -2
  56. {synapse-2.195.1.dist-info → synapse-2.197.0.dist-info}/METADATA +1 -1
  57. {synapse-2.195.1.dist-info → synapse-2.197.0.dist-info}/RECORD +60 -55
  58. {synapse-2.195.1.dist-info → synapse-2.197.0.dist-info}/LICENSE +0 -0
  59. {synapse-2.195.1.dist-info → synapse-2.197.0.dist-info}/WHEEL +0 -0
  60. {synapse-2.195.1.dist-info → synapse-2.197.0.dist-info}/top_level.txt +0 -0
@@ -6,6 +6,8 @@ import synapse.lib.cell as s_cell
6
6
 
7
7
  import synapse.tests.utils as s_test
8
8
 
9
+ import unittest.mock as mock
10
+
9
11
  class AhaLibTest(s_test.SynTest):
10
12
 
11
13
  async def test_stormlib_aha_basics(self):
@@ -193,3 +195,189 @@ Connection information:
193
195
 
194
196
  with self.raises(s_exc.NoSuchName):
195
197
  await core00.callStorm('$lib.aha.del(axon...)')
198
+
199
+ async def test_stormlib_aha_mirror(self):
200
+
201
+ async with self.getTestAha() as aha:
202
+
203
+ with self.getTestDir() as dirn:
204
+
205
+ dirn00 = s_common.genpath(dirn, 'cell00')
206
+ dirn01 = s_common.genpath(dirn, 'cell01')
207
+ dirn02 = s_common.genpath(dirn, 'cell02')
208
+
209
+ async with aha.waiter(3, 'aha:svcadd', timeout=10):
210
+
211
+ cell00 = await aha.enter_context(self.addSvcToAha(aha, '00.cell', s_cell.Cell, dirn=dirn00))
212
+ cell01 = await aha.enter_context(self.addSvcToAha(aha, '01.cell', s_cell.Cell, dirn=dirn01,
213
+ provinfo={'mirror': 'cell'}))
214
+ core00 = await aha.enter_context(self.addSvcToAha(aha, 'core', s_cortex.Cortex, dirn=dirn02))
215
+ await cell01.sync()
216
+
217
+ # PeerGenr
218
+ resp = await core00.callStorm('''
219
+ $resps = $lib.list()
220
+ $todo = $lib.utils.todo('getTasks')
221
+ for ($name, $info) in $lib.aha.callPeerGenr(cell..., $todo) {
222
+ $resps.append(($name, $info))
223
+ }
224
+ return($resps)
225
+ ''')
226
+ self.len(0, resp)
227
+
228
+ resp = await core00.callStorm('''
229
+ $resps = $lib.list()
230
+ $todo = $lib.utils.todo('getNexusChanges', (0), wait=(false))
231
+ for ($name, $info) in $lib.aha.callPeerGenr(cell..., $todo) {
232
+ $resps.append(($name, $info))
233
+ }
234
+ return($resps)
235
+ ''')
236
+ self.len(4, resp)
237
+
238
+ cell00_rid = (await cell00.getCellInfo())['cell']['run']
239
+ resp = await core00.callStorm('''
240
+ $resps = $lib.list()
241
+ $todo = $lib.utils.todo('getNexusChanges', (0), wait=(false))
242
+ for $info in $lib.aha.callPeerGenr(cell..., $todo, skiprun=$skiprun) {
243
+ $resps.append($info)
244
+ }
245
+ return($resps)
246
+ ''', opts={'vars': {'skiprun': cell00_rid}})
247
+ self.len(2, resp)
248
+
249
+ await self.asyncraises(s_exc.NoSuchName, core00.callStorm('''
250
+ $todo = $lib.utils.todo('getTasks')
251
+ $lib.aha.callPeerGenr(null, $todo)
252
+ '''))
253
+
254
+ # PeerApi
255
+ resp = await core00.callStorm('''
256
+ $resps = $lib.list()
257
+ $todo = $lib.utils.todo('getCellInfo')
258
+ for ($name, $info) in $lib.aha.callPeerApi(cell..., $todo) {
259
+ $resps.append(($name, $info))
260
+ }
261
+ return($resps)
262
+ ''')
263
+ self.len(2, resp)
264
+ self.eq(resp[0][0], '00.cell.synapse')
265
+ self.eq(resp[0][1][0], True)
266
+ self.isinstance(resp[0][1][1], dict)
267
+
268
+ resp = await core00.callStorm('''
269
+ $resps = $lib.list()
270
+ $todo = $lib.utils.todo(getCellInfo)
271
+ for ($name, $info) in $lib.aha.callPeerApi(cell..., $todo) {
272
+ $resps.append(($name, $info))
273
+ }
274
+ return($resps)
275
+ ''')
276
+ self.len(2, resp)
277
+
278
+ resp = await core00.callStorm('''
279
+ $resps = $lib.list()
280
+ $todo = $lib.utils.todo(getCellInfo)
281
+ for ($name, $info) in $lib.aha.callPeerApi(cell..., $todo, skiprun=$skiprun) {
282
+ $resps.append(($name, $info))
283
+ }
284
+ return($resps)
285
+ ''', opts={'vars': {'skiprun': cell00_rid}})
286
+ self.len(1, resp)
287
+
288
+ resp = await core00.callStorm('''
289
+ $resps = $lib.list()
290
+ $todo = $lib.utils.todo('getCellInfo')
291
+ for ($name, $info) in $lib.aha.callPeerApi(cell..., $todo, timeout=(10)) {
292
+ $resps.append(($name, $info))
293
+ }
294
+ return($resps)
295
+ ''')
296
+ self.len(2, resp)
297
+
298
+ await self.asyncraises(s_exc.NoSuchName, core00.callStorm('''
299
+ $todo = $lib.utils.todo('getCellInfo')
300
+ $lib.aha.callPeerApi(newp..., $todo)
301
+ '''))
302
+
303
+ await self.asyncraises(s_exc.NoSuchName, core00.callStorm('''
304
+ $todo = $lib.utils.todo('getCellInfo')
305
+ $lib.aha.callPeerApi(null, $todo)
306
+ '''))
307
+
308
+ await self.asyncraises(s_exc.NoSuchMeth, core00.callStorm('''
309
+ $todo = $lib.utils.todo('bogusMethod')
310
+ for $info in $lib.aha.callPeerApi(cell..., $todo) {
311
+ ($ok, $info) = $info.1
312
+ if (not $ok) {
313
+ $lib.raise($info.err, $info.errmsg)
314
+ }
315
+ }
316
+ '''))
317
+
318
+ await aha.addAhaSvc('noiden.cell', info={'urlinfo': {'scheme': 'tcp',
319
+ 'host': '0.0.0.0',
320
+ 'port': '3030'}},
321
+ network='synapse')
322
+ await self.asyncraises(s_exc.NoSuchName, core00.callStorm('''
323
+ $todo = $lib.utils.todo('getTasks')
324
+ $lib.aha.callPeerGenr(noiden.cell..., $todo)
325
+ '''))
326
+ await self.asyncraises(s_exc.NoSuchName, core00.callStorm('''
327
+ $todo = $lib.utils.todo('getCellInfo')
328
+ $lib.aha.callPeerApi(noiden.cell..., $todo)
329
+ '''))
330
+
331
+ msgs = await core00.stormlist('aha.svc.mirror')
332
+ self.stormIsInPrint('Service Mirror Groups:', msgs)
333
+ self.stormIsInPrint('cell.synapse', msgs)
334
+ self.stormIsInPrint('00.cell.synapse', msgs)
335
+ self.stormIsInPrint('01.cell.synapse', msgs)
336
+ self.stormIsInPrint('Group Status: In Sync', msgs)
337
+
338
+ msgs = await core00.stormlist('aha.svc.mirror --timeout 30')
339
+ self.stormIsInPrint('Service Mirror Groups:', msgs)
340
+ self.stormIsInPrint('Group Status: In Sync', msgs)
341
+
342
+ async def mockCellInfo():
343
+ return {
344
+ 'cell': {'ready': True, 'nexsindx': 10, 'uplink': None},
345
+ 'synapse': {'verstring': '2.190.0'},
346
+ }
347
+
348
+ async def mockOutOfSyncCellInfo():
349
+ return {
350
+ 'cell': {'ready': True, 'nexsindx': 5, 'uplink': cell00.iden},
351
+ 'synapse': {'verstring': '2.190.0'},
352
+ }
353
+
354
+ with mock.patch.object(cell00, 'getCellInfo', mockCellInfo):
355
+ with mock.patch.object(cell01, 'getCellInfo', mockOutOfSyncCellInfo):
356
+ async def mock_call_aha(*args, **kwargs):
357
+ todo = args[1]
358
+ if todo[0] == 'waitNexsOffs':
359
+ yield ('00.cell.synapse', (True, True))
360
+ yield ('01.cell.synapse', (True, True))
361
+ elif todo[0] == 'getCellInfo':
362
+ if not hasattr(mock_call_aha, 'called'):
363
+ mock_call_aha.called = True
364
+ yield ('00.cell.synapse', (True, await mockCellInfo()))
365
+ yield ('01.cell.synapse', (True, await mockOutOfSyncCellInfo()))
366
+ else:
367
+ yield ('00.cell.synapse', (True, await mockCellInfo()))
368
+ yield ('01.cell.synapse', (True, await mockCellInfo()))
369
+
370
+ with mock.patch.object(aha, 'callAhaPeerApi', mock_call_aha):
371
+ msgs = await core00.stormlist('aha.svc.mirror --wait')
372
+ self.stormIsInPrint('Group Status: Out of Sync', msgs)
373
+ self.stormIsInPrint('Updated status:', msgs)
374
+ self.stormIsInPrint('Group Status: In Sync', msgs)
375
+
376
+ with mock.patch.object(cell00, 'getCellInfo', mockCellInfo):
377
+ with mock.patch.object(cell01, 'getCellInfo', mockOutOfSyncCellInfo):
378
+ msgs = await core00.stormlist('aha.svc.mirror --timeout 1')
379
+ self.stormIsInPrint('Group Status: Out of Sync', msgs)
380
+
381
+ await aha.delAhaSvc('00.cell', network='synapse')
382
+ msgs = await core00.stormlist('aha.svc.mirror')
383
+ self.stormNotInPrint('Service Mirror Groups:', msgs)
@@ -0,0 +1,39 @@
1
+ import synapse.tests.utils as s_test
2
+
3
+ count_prop_00 = '''
4
+ Count | Layer Iden | Layer Name
5
+ ==============|==================================|============
6
+ 16 | 5cc56afbb22fad9b96c51110812af8f7 |
7
+ 16 | 2371390b1fd0162ba6820f85a863e7b2 | default
8
+ Total: 32
9
+ '''
10
+
11
+ count_prop_01 = '''
12
+ Count | Layer Iden | Layer Name
13
+ ==============|==================================|============
14
+ 16 | 9782c920718d3059b8806fddaf917bd8 |
15
+ 0 | 511122a9b2d576c5be2cdfcaef541bb9 | default
16
+ Total: 16
17
+ '''
18
+
19
+ class StormIndexTest(s_test.SynTest):
20
+
21
+ async def test_lib_stormlib_index(self):
22
+
23
+ async with self.getTestCore() as core:
24
+ viewiden = await core.callStorm('return($lib.view.get().fork().iden)')
25
+ viewopts = {'view': viewiden}
26
+ await core.nodes('[ inet:ipv4=1.2.3.0/28 :asn=19 ]')
27
+ await core.nodes('[ inet:ipv4=1.2.4.0/28 :asn=42 ]', opts=viewopts)
28
+
29
+ msgs = await core.stormlist('index.count.prop inet:ipv4', opts=viewopts)
30
+ self.stormIsInPrint(count_prop_00, msgs, deguid=True, whitespace=False)
31
+
32
+ msgs = await core.stormlist('index.count.prop inet:ipv4:asn', opts=viewopts)
33
+ self.stormIsInPrint(count_prop_00, msgs, deguid=True, whitespace=False)
34
+
35
+ msgs = await core.stormlist('index.count.prop inet:ipv4:asn --value 42', opts=viewopts)
36
+ self.stormIsInPrint(count_prop_01, msgs, deguid=True, whitespace=False)
37
+
38
+ msgs = await core.stormlist('index.count.prop inet:ipv4:newp', opts=viewopts)
39
+ self.stormIsInErr('No property named inet:ipv4:newp', msgs)
@@ -0,0 +1,14 @@
1
+ import synapse.exc as s_exc
2
+ import synapse.tests.utils as s_test
3
+
4
+ class UtilsTest(s_test.SynTest):
5
+
6
+ async def test_lib_stormlib_utils_todo(self):
7
+
8
+ async with self.getTestCore() as core:
9
+
10
+ valu = await core.callStorm('return($lib.utils.todo(foo))')
11
+ self.eq(valu, ('foo', (), {}))
12
+
13
+ valu = await core.callStorm('return($lib.utils.todo(fooName, arg1, arg2, keyword=bar, anotherkeyword=hehe))')
14
+ self.eq(valu, ('fooName', ('arg1', 'arg2'), {'keyword': 'bar', 'anotherkeyword': 'hehe'}))
@@ -3,6 +3,7 @@ import bz2
3
3
  import gzip
4
4
  import json
5
5
  import base64
6
+ import struct
6
7
  import asyncio
7
8
  import hashlib
8
9
  import binascii
@@ -6467,13 +6468,29 @@ words\tword\twrd'''
6467
6468
  async with self.getTestCore() as core:
6468
6469
 
6469
6470
  viewiden = await core.callStorm('return($lib.view.get().fork().iden)')
6470
- await core.nodes('[ ou:org=* :name=foobar +#hehe ]')
6471
+ q = '[ ou:org=* :name=foobar +#hehe ] $node.data.set(foo, bar) return($node.iden())'
6472
+ basenode = await core.callStorm(q)
6471
6473
 
6472
6474
  opts = {'view': viewiden}
6473
- nodeiden = await core.callStorm('[ ou:org=* :name=foobar +#hehe ] return($node.iden())', opts=opts)
6475
+ nodeiden = await core.callStorm('''
6476
+ [ ou:org=* :name=foobar +#hehe ]
6477
+ $node.data.set(foo, bar)
6478
+ return($node.iden())
6479
+ ''', opts=opts)
6480
+
6481
+ nodeiden2 = await core.callStorm('[test:str=yup] $node.data.set(foo, yup) return ($node.iden())',
6482
+ opts=opts)
6474
6483
 
6475
6484
  self.len(2, await core.nodes('ou:org +:name=foobar +#hehe', opts=opts))
6476
6485
 
6486
+ nodes = await core.nodes('yield $lib.layer.get().liftByNodeData(foo)', opts=opts)
6487
+ self.len(2, nodes)
6488
+ self.eq(set((nodeiden, nodeiden2)), {node.iden() for node in nodes})
6489
+
6490
+ nodes = await core.nodes('yield $lib.layer.get().liftByNodeData(foo)')
6491
+ self.len(1, nodes)
6492
+ self.eq(nodes[0].iden(), basenode)
6493
+
6477
6494
  nodes = await core.nodes('yield $lib.layer.get().liftByProp(ou:org)', opts=opts)
6478
6495
  self.len(1, nodes)
6479
6496
  self.eq(nodes[0].iden(), nodeiden)
@@ -6487,7 +6504,7 @@ words\tword\twrd'''
6487
6504
  self.eq(nodes[0].iden(), nodeiden)
6488
6505
 
6489
6506
  nodes = await core.nodes('yield $lib.layer.get().liftByProp(".created")', opts=opts)
6490
- self.len(1, nodes)
6507
+ self.len(2, nodes)
6491
6508
  self.eq(nodes[0].iden(), nodeiden)
6492
6509
 
6493
6510
  nodes = await core.nodes('yield $lib.layer.get().liftByTag(hehe)', opts=opts)
@@ -7084,3 +7101,73 @@ words\tword\twrd'''
7084
7101
 
7085
7102
  with self.raises(s_exc.BadState):
7086
7103
  await core.callStorm(merging)
7104
+
7105
+ async def test_storm_lib_axon_read_unpack(self):
7106
+
7107
+ async with self.getTestCore() as core:
7108
+
7109
+ visi = await core.auth.addUser('visi')
7110
+
7111
+ orig_axoninfo = core.axoninfo
7112
+ core.axoninfo = {'features': {}}
7113
+ data = struct.pack('>Q', 1)
7114
+ size, sha256 = await core.axon.put(data)
7115
+ sha256_s = s_common.ehex(sha256)
7116
+ q = 'return($lib.axon.unpack($sha256, fmt=">Q"))'
7117
+ await self.asyncraises(s_exc.FeatureNotSupported,
7118
+ core.callStorm(q, opts={'vars': {'sha256': sha256_s}}))
7119
+ core.axoninfo = orig_axoninfo
7120
+
7121
+ data = b'vertex.link'
7122
+ size, sha256 = await core.axon.put(data)
7123
+ sha256_s = s_common.ehex(sha256)
7124
+
7125
+ _, emptyhash = await core.axon.put(b'')
7126
+ emptyhash = s_common.ehex(emptyhash)
7127
+
7128
+ opts = {'user': visi.iden, 'vars': {'sha256': sha256_s, 'emptyhash': emptyhash}}
7129
+ await self.asyncraises(s_exc.AuthDeny,
7130
+ core.callStorm('return($lib.axon.read($sha256, offs=3, size=3))', opts=opts))
7131
+ await visi.addRule((True, ('storm', 'lib', 'axon', 'get')))
7132
+
7133
+ q = 'return($lib.axon.read($sha256, offs=3, size=3))'
7134
+ self.eq(b'tex', await core.callStorm(q, opts=opts))
7135
+ q = 'return($lib.axon.read($sha256, offs=7, size=4))'
7136
+ self.eq(b'link', await core.callStorm(q, opts=opts))
7137
+ q = 'return($lib.axon.read($sha256, offs=11, size=1))'
7138
+ self.eq(b'', await core.callStorm(q, opts=opts))
7139
+
7140
+ q = 'return($lib.axon.read($emptyhash))'
7141
+ self.eq(b'', await core.callStorm(q, opts=opts))
7142
+
7143
+ q = 'return($lib.axon.read($sha256, size=0))'
7144
+ await self.asyncraises(s_exc.BadArg, core.callStorm(q, opts=opts))
7145
+ q = 'return($lib.axon.read($sha256, offs=-1, size=1))'
7146
+ await self.asyncraises(s_exc.BadArg, core.callStorm(q, opts=opts))
7147
+ q = 'return($lib.axon.read($sha256, size=2097152))'
7148
+ await self.asyncraises(s_exc.BadArg, core.callStorm(q, opts=opts))
7149
+
7150
+ intdata = struct.pack('>QQQ', 1, 2, 3)
7151
+ size, sha256 = await core.axon.put(intdata)
7152
+ sha256_s = s_common.ehex(sha256)
7153
+ opts = {'user': visi.iden, 'vars': {'sha256': sha256_s}}
7154
+
7155
+ await visi.delRule((True, ('storm', 'lib', 'axon', 'get')))
7156
+ q = 'return($lib.axon.unpack($sha256, fmt=">Q"))'
7157
+ await self.asyncraises(s_exc.AuthDeny, core.callStorm(q, opts=opts))
7158
+ await visi.addRule((True, ('storm', 'lib', 'axon', 'get')))
7159
+
7160
+ q = 'return($lib.axon.unpack($sha256, fmt=">Q"))'
7161
+ self.eq((1,), await core.callStorm(q, opts=opts))
7162
+ q = 'return($lib.axon.unpack($sha256, fmt=">Q", offs=8))'
7163
+ self.eq((2,), await core.callStorm(q, opts=opts))
7164
+ q = 'return($lib.axon.unpack($sha256, fmt=">Q", offs=16))'
7165
+ self.eq((3,), await core.callStorm(q, opts=opts))
7166
+ q = 'return($lib.axon.unpack($sha256, fmt=">QQ", offs=8))'
7167
+ self.eq((2, 3), await core.callStorm(q, opts=opts))
7168
+
7169
+ q = 'return($lib.axon.unpack($sha256, fmt="not a valid format"))'
7170
+ await self.asyncraises(s_exc.BadArg, core.callStorm(q, opts=opts))
7171
+
7172
+ q = 'return($lib.axon.unpack($sha256, fmt=">Q", offs=24))'
7173
+ await self.asyncraises(s_exc.BadDataValu, core.callStorm(q, opts=opts))
@@ -2,12 +2,14 @@ import asyncio
2
2
 
3
3
  import synapse.exc as s_exc
4
4
  import synapse.lib.boss as s_boss
5
+ import synapse.lib.cell as s_cell
5
6
  import synapse.lib.task as s_task
6
7
  import synapse.tests.utils as s_test
7
8
 
8
- class FakeUser:
9
- def __init__(self, name):
10
- self.name = name
9
+ class BossCell(s_cell.Cell):
10
+ async def initServiceRuntime(self):
11
+ self.cboss = await s_boss.Boss.anit()
12
+ self.onfini(self.cboss)
11
13
 
12
14
  class TaskTest(s_test.SynTest):
13
15
 
@@ -19,15 +21,27 @@ class TaskTest(s_test.SynTest):
19
21
 
20
22
  async def test_task_module(self):
21
23
 
22
- async with await s_boss.Boss.anit() as boss:
24
+ async with self.getTestCell(BossCell) as bcell:
25
+ boss = bcell.cboss
26
+ root = await bcell.auth.getUserByName('root')
23
27
 
24
- user = FakeUser('visi')
28
+ synt = await boss.promote('test', root, info={'hehe': 'haha'})
25
29
 
26
- synt = await boss.promote('test', user, info={'hehe': 'haha'})
27
-
28
- self.eq(s_task.user(), user)
30
+ self.eq(s_task.user(), root)
29
31
  self.eq(s_task.current(), synt)
30
- self.eq(s_task.username(), 'visi')
32
+ self.eq(s_task.username(), 'root')
33
+
34
+ ret = synt.pack()
35
+ self.nn(ret.pop('iden'))
36
+ self.nn(ret.pop('tick'))
37
+ self.eq(ret, {'name': 'test', 'info': {'hehe': 'haha'},
38
+ 'user': 'root', 'kids': {}})
39
+
40
+ ret = synt.packv2()
41
+ self.nn(ret.pop('iden'))
42
+ self.nn(ret.pop('tick'))
43
+ self.eq(ret, {'name': 'test', 'info': {'hehe': 'haha'},
44
+ 'user': root.iden, 'username': 'root', 'kids': {}})
31
45
 
32
46
  async def test_taskvars(self):
33
47
  s_task.varset('test', 'foo')
@@ -51,7 +65,11 @@ class TaskTest(s_test.SynTest):
51
65
  self.eq(s_task.varget('test'), 'foo')
52
66
 
53
67
  async def test_task_iden(self):
54
- with self.raises(s_exc.BadArg):
55
- await s_task.Task.anit(None, asyncio.current_task(), None, None, iden=10)
56
- with self.raises(s_exc.BadArg):
57
- await s_task.Task.anit(None, asyncio.current_task(), None, None, iden='woot')
68
+ async with self.getTestCell(BossCell) as bcell:
69
+ root = await bcell.auth.getUserByName('root')
70
+ boss = bcell.cboss
71
+
72
+ with self.raises(s_exc.BadArg):
73
+ await s_task.Task.anit(boss, asyncio.current_task(), None, root, iden=10)
74
+ with self.raises(s_exc.BadArg):
75
+ await s_task.Task.anit(boss, asyncio.current_task(), None, root, iden='woot')
@@ -227,6 +227,7 @@ class BaseTest(s_t_utils.SynTest):
227
227
  :name="FOO Bar"
228
228
  :type=osint
229
229
  :url="https://foo.bar/index.html"
230
+ :ingest:cursor="Woot Woot "
230
231
  :ingest:latest=20241205
231
232
  :ingest:offset=17
232
233
  ]
@@ -238,6 +239,7 @@ class BaseTest(s_t_utils.SynTest):
238
239
  self.eq(sorc.get('name'), 'foo bar')
239
240
  self.eq(sorc.get('url'), 'https://foo.bar/index.html')
240
241
  self.eq(sorc.get('ingest:offset'), 17)
242
+ self.eq(sorc.get('ingest:cursor'), 'Woot Woot ')
241
243
  self.eq(sorc.get('ingest:latest'), 1733356800000)
242
244
 
243
245
  valu = (sorc.ndef[1], ('inet:fqdn', 'woot.com'))
@@ -49,3 +49,41 @@ class DocModelTest(s_tests.SynTest):
49
49
  self.eq('V-99', nodes[0].get('id'))
50
50
  self.nn(nodes[0].get('policy'))
51
51
  self.len(1, await core.nodes('doc:standard -> doc:policy'))
52
+
53
+ nodes = await core.nodes('''
54
+ [ doc:requirement=*
55
+ :id=V-99
56
+ :priority=low
57
+ :optional=(false)
58
+ :summary="Some requirement text."
59
+ :standard={doc:standard}
60
+ ]
61
+ ''')
62
+ self.eq('V-99', nodes[0].get('id'))
63
+ self.eq('Some requirement text.', nodes[0].get('summary'))
64
+ self.eq(20, nodes[0].get('priority'))
65
+ self.false(nodes[0].get('optional'))
66
+ self.nn(nodes[0].get('standard'))
67
+ self.len(1, await core.nodes('doc:requirement -> doc:standard'))
68
+
69
+ nodes = await core.nodes('''
70
+ [ doc:resume=*
71
+ :id=V-99
72
+ :contact={[ ps:contact=* :name=visi ]}
73
+ :summary="Thought leader seeks..."
74
+ :workhist={[ ps:workhist=* ]}
75
+ :education={[ ps:education=* ]}
76
+ :achievements={[ ps:achievement=* ]}
77
+ ]
78
+ ''')
79
+ self.eq('V-99', nodes[0].get('id'))
80
+ self.eq('Thought leader seeks...', nodes[0].get('summary'))
81
+ self.nn(nodes[0].get('contact'))
82
+ self.len(1, nodes[0].get('workhist'))
83
+ self.len(1, nodes[0].get('education'))
84
+ self.len(1, nodes[0].get('achievements'))
85
+
86
+ self.len(1, await core.nodes('doc:resume :contact -> ps:contact'))
87
+ self.len(1, await core.nodes('doc:resume :workhist -> ps:workhist'))
88
+ self.len(1, await core.nodes('doc:resume :education -> ps:education'))
89
+ self.len(1, await core.nodes('doc:resume :achievements -> ps:achievement'))
@@ -342,6 +342,7 @@ class InfotechModelTest(s_t_utils.SynTest):
342
342
  :verdict=suspicious
343
343
  :scanner={[ it:prod:softver=* :name="visi scan" ]}
344
344
  :scanner:name="visi scan"
345
+ :categories=("Foo Bar", "baz faz")
345
346
  :signame=omgwtfbbq
346
347
  :target:file=*
347
348
  :target:proc={[ it:exec:proc=* :cmd="foo.exe --bar" ]}
@@ -367,6 +368,7 @@ class InfotechModelTest(s_t_utils.SynTest):
367
368
  self.eq(0x01020304, nodes[0].get('target:ipv4'))
368
369
  self.eq('::1', nodes[0].get('target:ipv6'))
369
370
  self.eq('omgwtfbbq', nodes[0].get('signame'))
371
+ self.eq(('baz faz', 'foo bar'), nodes[0].get('categories'))
370
372
 
371
373
  self.len(1, await core.nodes('it:av:scan:result:scanner:name="visi scan" -> it:host'))
372
374
  self.len(1, await core.nodes('it:av:scan:result:scanner:name="visi scan" -> inet:url'))
@@ -617,11 +619,36 @@ class InfotechModelTest(s_t_utils.SynTest):
617
619
  node = nodes[0]
618
620
  self.eq(node.ndef, ('it:dev:int', 1640531528))
619
621
 
620
- nodes = await core.nodes('[it:sec:cve=CVE-2013-9999 :desc="Some words."]')
622
+ nodes = await core.nodes('''[
623
+ it:sec:cve=CVE-2013-9999
624
+ :desc="Some words."
625
+
626
+ :nist:nvd:source=NistSource
627
+ :nist:nvd:published=2021-10-11
628
+ :nist:nvd:modified=2021-10-11
629
+
630
+ :cisa:kev:name=KevName
631
+ :cisa:kev:desc=KevDesc
632
+ :cisa:kev:action=KevAction
633
+ :cisa:kev:vendor=KevVendor
634
+ :cisa:kev:product=KevProduct
635
+ :cisa:kev:added=2022-01-02
636
+ :cisa:kev:duedate=2022-01-02
637
+ ]''')
621
638
  self.len(1, nodes)
622
639
  node = nodes[0]
623
640
  self.eq(node.ndef, ('it:sec:cve', 'cve-2013-9999'))
624
641
  self.eq(node.get('desc'), 'Some words.')
642
+ self.eq(node.get('nist:nvd:source'), 'nistsource')
643
+ self.eq(node.get('nist:nvd:published'), 1633910400000)
644
+ self.eq(node.get('nist:nvd:modified'), 1633910400000)
645
+ self.eq(node.get('cisa:kev:name'), 'KevName')
646
+ self.eq(node.get('cisa:kev:desc'), 'KevDesc')
647
+ self.eq(node.get('cisa:kev:action'), 'KevAction')
648
+ self.eq(node.get('cisa:kev:vendor'), 'kevvendor')
649
+ self.eq(node.get('cisa:kev:product'), 'kevproduct')
650
+ self.eq(node.get('cisa:kev:added'), 1641081600000)
651
+ self.eq(node.get('cisa:kev:duedate'), 1641081600000)
625
652
 
626
653
  nodes = await core.nodes('[it:sec:cve=$valu]', opts={'vars': {'valu': 'CVE\u20122013\u20131138'}})
627
654
  self.len(1, nodes)
@@ -183,6 +183,13 @@ class OuModelTest(s_t_utils.SynTest):
183
183
  self.eq(t.norm('HAHA1')[0], 'haha1')
184
184
  self.eq(t.norm('GOV_MFA')[0], 'gov_mfa')
185
185
 
186
+ # ou:org:alias (unicode test)
187
+ nodes = await core.nodes('''
188
+ [ ou:org=* :alias="ÅÆØåæø" ]
189
+ ''')
190
+ self.len(1, nodes)
191
+ self.eq(t.norm('ÅÆØåæø')[0], 'åæøåæø')
192
+
186
193
  # ou:position / ou:org:subs
187
194
  orgiden = s_common.guid()
188
195
  contact = s_common.guid()
@@ -640,6 +647,7 @@ class OuModelTest(s_t_utils.SynTest):
640
647
  ou:contest:result=(*, *)
641
648
  :rank=1
642
649
  :score=20
650
+ :period=(20250101, 20250102)
643
651
  :url=http://vertex.link/contest/result
644
652
  ]''')
645
653
  self.len(1, nodes)
@@ -647,6 +655,7 @@ class OuModelTest(s_t_utils.SynTest):
647
655
  self.nn(nodes[0].get('participant'))
648
656
  self.eq(1, nodes[0].get('rank'))
649
657
  self.eq(20, nodes[0].get('score'))
658
+ self.eq((1735689600000, 1735776000000), nodes[0].get('period'))
650
659
  self.eq('http://vertex.link/contest/result', nodes[0].get('url'))
651
660
  self.len(1, await core.nodes('ou:contest:result -> ps:contact'))
652
661
  self.len(1, await core.nodes('ou:contest:result -> ou:contest'))
@@ -111,12 +111,14 @@ class RiskModelTest(s_t_utils.SynTest):
111
111
  :cvss:v3 ?= "newp3.1"
112
112
  :priority=high
113
113
  :severity=high
114
+ :tag=cno.vuln.woot
114
115
  ]''')
115
116
 
116
117
  self.none(node.get('cvss:v2'))
117
118
  self.none(node.get('cvss:v3'))
118
119
  self.eq(40, node.get('severity'))
119
120
  self.eq(40, node.get('priority'))
121
+ self.eq('cno.vuln.woot', node.get('tag'))
120
122
 
121
123
  with self.raises(s_exc.BadTypeValu):
122
124
  node = await addNode(f'''[
@@ -110,6 +110,7 @@ class TransportTest(s_test.SynTest):
110
110
  self.nn(vessel.get('operator'))
111
111
 
112
112
  self.len(1, await core.nodes('transport:sea:vessel:imo^="IMO 123"'))
113
+ self.len(1, await core.nodes('transport:sea:vessel :name -> entity:name'))
113
114
  self.len(1, await core.nodes('transport:sea:vessel -> transport:sea:vessel:type:taxonomy'))
114
115
 
115
116
  seatelem = (await core.nodes('''[