synapse 2.201.0__py311-none-any.whl → 2.203.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 (106) hide show
  1. synapse/axon.py +4 -4
  2. synapse/cmds/cortex.py +4 -6
  3. synapse/cmds/hive.py +10 -10
  4. synapse/common.py +17 -58
  5. synapse/cortex.py +36 -29
  6. synapse/data/__init__.py +3 -2
  7. synapse/data/iana.uris.mpk +1 -0
  8. synapse/lib/autodoc.py +3 -3
  9. synapse/lib/base.py +2 -12
  10. synapse/lib/cell.py +9 -13
  11. synapse/lib/cli.py +2 -2
  12. synapse/lib/config.py +2 -2
  13. synapse/lib/encoding.py +4 -3
  14. synapse/lib/httpapi.py +7 -11
  15. synapse/lib/json.py +224 -0
  16. synapse/lib/lmdbslab.py +1 -1
  17. synapse/lib/oauth.py +176 -54
  18. synapse/lib/parser.py +2 -1
  19. synapse/lib/rstorm.py +18 -14
  20. synapse/lib/schemas.py +87 -1
  21. synapse/lib/scrape.py +35 -13
  22. synapse/lib/snap.py +2 -1
  23. synapse/lib/storm.lark +5 -4
  24. synapse/lib/storm.py +2 -2
  25. synapse/lib/storm_format.py +2 -1
  26. synapse/lib/stormhttp.py +11 -13
  27. synapse/lib/stormlib/aha.py +4 -4
  28. synapse/lib/stormlib/auth.py +1 -1
  29. synapse/lib/stormlib/cache.py +2 -2
  30. synapse/lib/stormlib/cortex.py +5 -5
  31. synapse/lib/stormlib/graph.py +1 -1
  32. synapse/lib/stormlib/imap.py +1 -1
  33. synapse/lib/stormlib/json.py +8 -11
  34. synapse/lib/stormlib/model.py +1 -1
  35. synapse/lib/stormlib/notifications.py +2 -2
  36. synapse/lib/stormlib/oauth.py +105 -2
  37. synapse/lib/stormlib/stats.py +4 -0
  38. synapse/lib/stormlib/stix.py +3 -4
  39. synapse/lib/stormlib/vault.py +6 -6
  40. synapse/lib/stormlib/xml.py +2 -2
  41. synapse/lib/stormtypes.py +19 -28
  42. synapse/lib/structlog.py +3 -3
  43. synapse/lib/types.py +2 -1
  44. synapse/lib/version.py +2 -2
  45. synapse/lib/view.py +7 -3
  46. synapse/models/base.py +51 -2
  47. synapse/telepath.py +79 -18
  48. synapse/tests/files/__init__.py +0 -1
  49. synapse/tests/test_axon.py +1 -1
  50. synapse/tests/test_cmds_cortex.py +3 -2
  51. synapse/tests/test_cmds_hive.py +4 -4
  52. synapse/tests/test_common.py +29 -19
  53. synapse/tests/test_cortex.py +28 -8
  54. synapse/tests/test_lib_ast.py +3 -3
  55. synapse/tests/test_lib_autodoc.py +5 -5
  56. synapse/tests/test_lib_base.py +1 -1
  57. synapse/tests/test_lib_cell.py +24 -7
  58. synapse/tests/test_lib_config.py +2 -2
  59. synapse/tests/test_lib_encoding.py +2 -2
  60. synapse/tests/test_lib_grammar.py +68 -64
  61. synapse/tests/test_lib_httpapi.py +13 -13
  62. synapse/tests/test_lib_json.py +219 -0
  63. synapse/tests/test_lib_multislabseqn.py +2 -1
  64. synapse/tests/test_lib_node.py +2 -2
  65. synapse/tests/test_lib_scrape.py +50 -0
  66. synapse/tests/test_lib_storm.py +12 -6
  67. synapse/tests/test_lib_stormhttp.py +4 -4
  68. synapse/tests/test_lib_stormlib_auth.py +3 -2
  69. synapse/tests/test_lib_stormlib_cortex.py +10 -12
  70. synapse/tests/test_lib_stormlib_infosec.py +2 -3
  71. synapse/tests/test_lib_stormlib_json.py +18 -21
  72. synapse/tests/test_lib_stormlib_log.py +1 -1
  73. synapse/tests/test_lib_stormlib_oauth.py +603 -1
  74. synapse/tests/test_lib_stormlib_stats.py +13 -3
  75. synapse/tests/test_lib_stormlib_stix.py +5 -5
  76. synapse/tests/test_lib_stormtypes.py +4 -4
  77. synapse/tests/test_lib_structlog.py +5 -6
  78. synapse/tests/test_lib_view.py +8 -0
  79. synapse/tests/test_model_base.py +32 -0
  80. synapse/tests/test_model_infotech.py +2 -2
  81. synapse/tests/test_telepath.py +56 -35
  82. synapse/tests/test_tools_cryo_cat.py +4 -3
  83. synapse/tests/test_tools_docker_validate.py +4 -2
  84. synapse/tests/test_tools_feed.py +30 -2
  85. synapse/tests/test_tools_genpkg.py +1 -1
  86. synapse/tests/test_tools_healthcheck.py +8 -7
  87. synapse/tests/test_utils.py +2 -2
  88. synapse/tests/test_utils_getrefs.py +35 -28
  89. synapse/tests/utils.py +3 -3
  90. synapse/tools/autodoc.py +3 -3
  91. synapse/tools/changelog.py +2 -2
  92. synapse/tools/cryo/cat.py +3 -3
  93. synapse/tools/csvtool.py +2 -3
  94. synapse/tools/docker/validate.py +5 -5
  95. synapse/tools/feed.py +2 -1
  96. synapse/tools/genpkg.py +3 -2
  97. synapse/tools/healthcheck.py +2 -3
  98. synapse/tools/json2mpk.py +2 -2
  99. synapse/utils/getrefs.py +10 -8
  100. synapse/vendor/cpython/lib/json.py +35 -0
  101. synapse/vendor/cpython/lib/test/test_json.py +22 -0
  102. {synapse-2.201.0.dist-info → synapse-2.203.0.dist-info}/METADATA +2 -1
  103. {synapse-2.201.0.dist-info → synapse-2.203.0.dist-info}/RECORD +106 -101
  104. {synapse-2.201.0.dist-info → synapse-2.203.0.dist-info}/WHEEL +1 -1
  105. {synapse-2.201.0.dist-info → synapse-2.203.0.dist-info}/LICENSE +0 -0
  106. {synapse-2.201.0.dist-info → synapse-2.203.0.dist-info}/top_level.txt +0 -0
synapse/telepath.py CHANGED
@@ -31,6 +31,8 @@ televers = (3, 0)
31
31
 
32
32
  aha_clients = {}
33
33
 
34
+ LINK_CULL_INTERVAL = 10
35
+
34
36
  async def addAhaUrl(url):
35
37
  '''
36
38
  Add (incref) an aha registry URL.
@@ -392,7 +394,7 @@ class Share(s_base.Base):
392
394
  This should never be used by synapse core code. This is for sync client code convenience only.
393
395
  '''
394
396
  if s_threads.iden() == self.tid:
395
- raise s_exc.SynErr('Use of synchronous context manager in async code')
397
+ raise s_exc.SynErr(mesg='Use of synchronous context manager in async code')
396
398
 
397
399
  self._ctxobj = self.schedCoroSafePend(self.__aenter__())
398
400
  return self
@@ -590,6 +592,10 @@ class Proxy(s_base.Base):
590
592
  valu = proxy.getFooValu(x, y)
591
593
 
592
594
  '''
595
+ _link_task = None
596
+ _link_event = None
597
+ _all_proxies = set()
598
+
593
599
  async def __anit__(self, link, name):
594
600
 
595
601
  await s_base.Base.__anit__(self)
@@ -608,11 +614,15 @@ class Proxy(s_base.Base):
608
614
  self.methinfo = {}
609
615
 
610
616
  self.sess = None
617
+
611
618
  self.links = collections.deque()
612
- self._link_poolsize = 4
619
+ self.alllinks = collections.deque()
620
+
621
+ self._link_add = 0 # counter for pending links being connected
622
+ self._links_min = 4 # low water mark for the link pool
623
+ self._links_max = 12 # high water mark for the link pool
613
624
 
614
625
  self.synack = None
615
- self.syndone = asyncio.Event()
616
626
 
617
627
  self.handlers = {
618
628
  'task:fini': self._onTaskFini,
@@ -626,19 +636,54 @@ class Proxy(s_base.Base):
626
636
  await item.fini()
627
637
 
628
638
  mesg = ('task:fini', {'retn': (False, ('IsFini', {}))})
629
- for name, task in list(self.tasks.items()):
639
+ for iden, task in list(self.tasks.items()): # pragma: no cover
630
640
  task.reply(mesg)
631
- del self.tasks[name]
641
+ del self.tasks[iden]
632
642
 
633
- for link in self.links:
634
- await link.fini()
643
+ # fini all the links from a different task to prevent
644
+ # delaying the proxy shutdown...
645
+ s_coro.create_task(self._finiAllLinks())
635
646
 
636
- del self.syndone
637
- await self.link.fini()
647
+ if self in self._all_proxies:
648
+ self._all_proxies.remove(self)
649
+
650
+ if not Proxy._all_proxies and Proxy._link_task is not None:
651
+ Proxy._link_task.cancel()
652
+ Proxy._link_task = None
653
+ Proxy._link_event = None
654
+
655
+ Proxy._all_proxies.add(self)
638
656
 
639
657
  self.onfini(fini)
640
658
  self.link.onfini(self.fini)
641
659
 
660
+ if Proxy._link_task is None:
661
+ Proxy._link_event = asyncio.Event()
662
+ Proxy._link_task = s_coro.create_task(Proxy._linkLoopTask())
663
+
664
+ @classmethod
665
+ async def _linkLoopTask(clas):
666
+ while True:
667
+ try:
668
+ await s_coro.event_wait(Proxy._link_event, timeout=LINK_CULL_INTERVAL)
669
+
670
+ for proxy in list(Proxy._all_proxies):
671
+
672
+ if proxy.isfini:
673
+ continue
674
+
675
+ # close one link per proxy per period if the number of
676
+ # available links is greater than _links_max...
677
+ if len(proxy.links) > proxy._links_max:
678
+ link = proxy.links.popleft()
679
+ await link.fini()
680
+ await proxy.fire('pool:link:fini', link=link)
681
+
682
+ Proxy._link_event.clear()
683
+
684
+ except Exception: # pragma: no cover
685
+ logger.exception('synapse.telepath.Proxy.linkLoopTask()')
686
+
642
687
  def _hasTeleFeat(self, name, vers=1):
643
688
  return self._features.get(name, 0) >= vers
644
689
 
@@ -692,6 +737,12 @@ class Proxy(s_base.Base):
692
737
 
693
738
  link = self.links.popleft()
694
739
 
740
+ # fire a task to replace the link if we are
741
+ # below the low-water mark for link count.
742
+ if len(self.links) + self._link_add < self._links_min:
743
+ self._link_add += 1
744
+ self.schedCoro(self._addPoolLink())
745
+
695
746
  if link.isfini:
696
747
  continue
697
748
 
@@ -700,6 +751,11 @@ class Proxy(s_base.Base):
700
751
  # we need a new one...
701
752
  return await self._initPoolLink()
702
753
 
754
+ async def _addPoolLink(self):
755
+ link = await self._initPoolLink()
756
+ self.links.append(link)
757
+ self._link_add -= 1
758
+
703
759
  async def getPipeline(self, genr, name=None):
704
760
  '''
705
761
  Construct a proxy API call pipeline in order to make
@@ -724,8 +780,6 @@ class Proxy(s_base.Base):
724
780
 
725
781
  async def _initPoolLink(self):
726
782
 
727
- # TODO loop / backoff
728
-
729
783
  if self.link.get('unix'):
730
784
 
731
785
  path = self.link.get('path')
@@ -739,19 +793,26 @@ class Proxy(s_base.Base):
739
793
 
740
794
  link = await s_link.connect(host, port, ssl=ssl)
741
795
 
742
- self.onfini(link)
796
+ self.alllinks.append(link)
797
+ async def fini():
798
+ self.alllinks.remove(link)
799
+ if link in self.links:
800
+ self.links.remove(link)
801
+
802
+ link.onfini(fini)
743
803
 
744
804
  return link
745
805
 
806
+ async def _finiAllLinks(self):
807
+ for link in list(self.alllinks):
808
+ await link.fini()
809
+ await self.link.fini()
810
+
746
811
  async def _putPoolLink(self, link):
747
812
 
748
813
  if link.isfini:
749
814
  return
750
815
 
751
- # If we've exceeded our poolsize, discard the current link.
752
- if len(self.links) >= self._link_poolsize:
753
- return await link.fini()
754
-
755
816
  self.links.append(link)
756
817
 
757
818
  def __enter__(self):
@@ -762,7 +823,7 @@ class Proxy(s_base.Base):
762
823
  This must not be used from async code, and it should never be used in core synapse code.
763
824
  '''
764
825
  if s_threads.iden() == self.tid:
765
- raise s_exc.SynErr('Use of synchronous context manager in async code')
826
+ raise s_exc.SynErr(mesg='Use of synchronous context manager in async code')
766
827
  self._ctxobj = self.schedCoroSafePend(self.__aenter__())
767
828
  return self
768
829
 
@@ -862,6 +923,7 @@ class Proxy(s_base.Base):
862
923
 
863
924
  except GeneratorExit:
864
925
  # if they bail early on the genr, fini the link
926
+ # TODO: devise a tx/rx strategy to recover these links...
865
927
  await link.fini()
866
928
 
867
929
  return s_coro.GenrHelp(genrloop())
@@ -1321,7 +1383,6 @@ class Client(s_base.Base):
1321
1383
  info.update(self._t_opts)
1322
1384
  self._t_proxy = await openinfo(info)
1323
1385
  self._t_methinfo = self._t_proxy.methinfo
1324
- self._t_proxy._link_poolsize = self._t_conf.get('link_poolsize', 4)
1325
1386
 
1326
1387
  async def fini():
1327
1388
  if self._t_named_meths:
@@ -1,7 +1,6 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  # Stdlib
3
3
  import os
4
- import json
5
4
  import logging
6
5
 
7
6
  log = logging.getLogger(__name__)
@@ -103,7 +103,7 @@ class HttpPushFile(s_httpapi.StreamHandler):
103
103
  assert item['filename'] == 'bytes'
104
104
 
105
105
  assert args.get('zip_password') == [b'test']
106
- assert args.get('dict') == [b'{"foo": "bar"}']
106
+ assert args.get('dict') == [b'{"foo":"bar"}']
107
107
  self.sendRestRetn(self.gotsize)
108
108
 
109
109
  class AxonTest(s_t_utils.SynTest):
@@ -4,6 +4,7 @@ import asyncio
4
4
  import synapse.common as s_common
5
5
 
6
6
  import synapse.lib.cmdr as s_cmdr
7
+ import synapse.lib.json as s_json
7
8
  import synapse.lib.encoding as s_encoding
8
9
  import synapse.lib.lmdbslab as s_lmdbslab
9
10
 
@@ -352,7 +353,7 @@ class CmdCoreTest(s_t_utils.SynTest):
352
353
  await cmdr.runCmdLine(f'storm --save-nodes {path} test:int')
353
354
  outp.expect('2 nodes')
354
355
 
355
- jsdata = [item for item in s_common.jslines(path)]
356
+ jsdata = [item for item in s_json.jslines(path)]
356
357
  self.len(2, jsdata)
357
358
  self.eq({tuple(n[0]) for n in jsdata},
358
359
  {('test:int', 20), ('test:int', 30)})
@@ -371,7 +372,7 @@ class CmdCoreTest(s_t_utils.SynTest):
371
372
  with s_common.genfile(stormfile) as fd:
372
373
  fd.write(b'[ inet:fqdn=$hehe ]')
373
374
 
374
- s_common.jssave(test_opts, optsfile)
375
+ s_json.jssave(test_opts, optsfile)
375
376
  s_common.yamlsave(test_opts, optsfile_yaml)
376
377
 
377
378
  outp = self.getTestOutp()
@@ -5,10 +5,10 @@ import synapse.lib.cmdr as s_cmdr
5
5
  import synapse.tests.utils as s_t_utils
6
6
 
7
7
  _json_output = '''[
8
- 1,
9
- 2,
10
- 3,
11
- 4
8
+ 1,
9
+ 2,
10
+ 3,
11
+ 4
12
12
  ]'''
13
13
 
14
14
  class CmdHiveTest(s_t_utils.SynTest):
@@ -1,12 +1,17 @@
1
1
  import os
2
+ import http
2
3
  import asyncio
3
4
  import logging
4
5
  import subprocess
5
6
 
6
7
  import yaml
8
+ import aiohttp
7
9
 
8
10
  import synapse.exc as s_exc
9
11
  import synapse.common as s_common
12
+
13
+ import synapse.lib.httpapi as s_httpapi
14
+
10
15
  import synapse.tests.utils as s_t_utils
11
16
 
12
17
  logger = logging.getLogger(__name__)
@@ -426,25 +431,6 @@ class CommonTest(s_t_utils.SynTest):
426
431
  retn = s_common.merggenr2([asyncl(lt) for lt in (l3, l2, l1)], reverse=True)
427
432
  self.eq((9, 8, 7, 6, 5, 4, 3, 2, 1), await alist(retn))
428
433
 
429
- def test_jsonsafe(self):
430
- items = (
431
- (None, None),
432
- (1234, None),
433
- ('1234', None),
434
- ({'asdf': 'haha'}, None),
435
- ({'a': (1,), 'b': [{'': 4}, 56, None, {'t': True, 'f': False}, 'oh my']}, None),
436
- (b'1234', s_exc.BadArg),
437
- ({'a': 'a', 2: 2}, s_exc.BadArg),
438
- ({'a', 'b', 'c'}, s_exc.BadArg),
439
- (s_common.novalu, s_exc.BadArg),
440
- )
441
- for (item, eret) in items:
442
- if eret is None:
443
- self.none(s_common.reqJsonSafeStrict(item))
444
- else:
445
- with self.raises(eret):
446
- s_common.reqJsonSafeStrict(item)
447
-
448
434
  def test_sslctx(self):
449
435
  with self.getTestDir(mirror='certdir') as dirn:
450
436
  cadir = s_common.genpath(dirn, 'cas')
@@ -481,3 +467,27 @@ class CommonTest(s_t_utils.SynTest):
481
467
  v = s_common.trimText(iv, n=n)
482
468
  self.le(len(v), n)
483
469
  self.eq(v, ev)
470
+
471
+ async def test_tornado_monkeypatch(self):
472
+ class JsonHandler(s_httpapi.Handler):
473
+ async def get(self):
474
+ resp = {
475
+ 'foo': 'bar',
476
+ 'html': '<html></html>'
477
+ }
478
+ self.write(resp)
479
+
480
+ async with self.getTestCore() as core:
481
+ core.addHttpApi('/api/v1/test_tornado/', JsonHandler, {'cell': core})
482
+ _, port = await core.addHttpsPort(0)
483
+ url = f'https://127.0.0.1:{port}/api/v1/test_tornado/'
484
+
485
+ async with aiohttp.ClientSession() as session:
486
+ async with session.get(url, ssl=False) as resp:
487
+ self.eq(resp.status, http.HTTPStatus.OK)
488
+
489
+ text = await resp.text()
490
+ self.eq(text, '{"foo":"bar","html":"<html><\\/html>"}')
491
+
492
+ json = await resp.json()
493
+ self.eq(json, {'foo': 'bar', 'html': '<html></html>'})
@@ -1559,8 +1559,8 @@ class CortexTest(s_t_utils.SynTest):
1559
1559
  self.eq(refs.get('fqdn'), ('inet:fqdn', 'woot.com'))
1560
1560
  self.eq(refs.get('ipv4'), ('inet:ipv4', 0x01020304))
1561
1561
 
1562
- self.len(1, await core.nodes('[meta:seen=($sorc, $valu)]',
1563
- opts={'vars': {'sorc': sorc, 'valu': node.ndef}}))
1562
+ self.len(1, await core.nodes('[test:str=testndef :somestr=$somestr :bar=$valu]',
1563
+ opts={'vars': {'somestr': sorc, 'valu': node.ndef}}))
1564
1564
 
1565
1565
  # test un-populated properties
1566
1566
  nodes = await core.nodes('[ps:contact="*"]')
@@ -1592,13 +1592,13 @@ class CortexTest(s_t_utils.SynTest):
1592
1592
  self.eq(ints, (('test:int', 1), ('test:int', 2), ('test:int', 3)))
1593
1593
 
1594
1594
  opts = {'vars': {'sorc': sorc}}
1595
- nodes = await core.nodes('meta:seen:source=$sorc -> *', opts=opts)
1595
+ nodes = await core.nodes('test:str:somestr=$sorc -> *', opts=opts)
1596
1596
 
1597
1597
  self.len(2, nodes)
1598
1598
  self.isin('inet:dns:a', {n.ndef[0] for n in nodes})
1599
1599
 
1600
1600
  opts = {'vars': {'sorc': sorc}}
1601
- nodes = await core.nodes('meta:seen:source=$sorc :node -> *', opts=opts)
1601
+ nodes = await core.nodes('test:str:somestr=$sorc :bar -> *', opts=opts)
1602
1602
 
1603
1603
  self.len(1, nodes)
1604
1604
  self.eq('inet:dns:a', nodes[0].ndef[0])
@@ -3955,7 +3955,7 @@ class CortexBasicTest(s_t_utils.SynTest):
3955
3955
  'refs': True,
3956
3956
  'edges': False,
3957
3957
  'forms': {},
3958
- 'pivots': ['<- meta:seen'],
3958
+ 'pivots': ['<(seen)- meta:source'],
3959
3959
  'degrees': 3,
3960
3960
  'filters': ['+#nope'],
3961
3961
  'filterinput': False,
@@ -8504,6 +8504,26 @@ class CortexBasicTest(s_t_utils.SynTest):
8504
8504
  self.notin('Timeout waiting for pool mirror', data)
8505
8505
  self.notin('Timeout waiting for query mirror', data)
8506
8506
 
8507
+ orig = s_telepath.ClientV2.proxy
8508
+ async def finidproxy(self, timeout=None):
8509
+ prox = await orig(self, timeout=timeout)
8510
+ await prox.fini()
8511
+ return prox
8512
+
8513
+ with patch('synapse.telepath.ClientV2.proxy', finidproxy):
8514
+ with self.getLoggerStream('synapse') as stream:
8515
+ msgs = await alist(core00.storm('inet:asn=0'))
8516
+ self.len(1, [m for m in msgs if m[0] == 'node'])
8517
+
8518
+ stream.seek(0)
8519
+ data = stream.read()
8520
+ self.isin('Proxy for pool mirror [01.core.synapse] was shutdown. Skipping.', data)
8521
+
8522
+ msgs = await core00.stormlist('cortex.storm.pool.set --connection-timeout 1 --sync-timeout 1 aha://pool00...')
8523
+ self.stormHasNoWarnErr(msgs)
8524
+ self.stormIsInPrint('Storm pool configuration set.', msgs)
8525
+ await core00.stormpool.waitready(timeout=12)
8526
+
8507
8527
  core01.nexsroot.nexslog.indx = 0
8508
8528
 
8509
8529
  with patch('synapse.cortex.MAX_NEXUS_DELTA', 1):
@@ -8516,8 +8536,7 @@ class CortexBasicTest(s_t_utils.SynTest):
8516
8536
 
8517
8537
  stream.seek(0)
8518
8538
  data = stream.read()
8519
- explog = (f'Pool mirror [01.core.synapse] Nexus offset delta too large '
8520
- f'({nexsoffs} > 1), running query locally')
8539
+ explog = ('Pool mirror [01.core.synapse] is too far out of sync. Skipping.')
8521
8540
  self.isin(explog, data)
8522
8541
  self.notin('Offloading Storm query', data)
8523
8542
 
@@ -8575,7 +8594,8 @@ class CortexBasicTest(s_t_utils.SynTest):
8575
8594
 
8576
8595
  stream.seek(0)
8577
8596
  data = stream.read()
8578
- self.isin('Timeout waiting for pool mirror, running query locally', data)
8597
+ self.isin('Timeout waiting for pool mirror proxy.', data)
8598
+ self.isin('Pool members exhausted. Running query locally.', data)
8579
8599
 
8580
8600
  await core01.fini()
8581
8601
 
@@ -1,4 +1,3 @@
1
- import json
2
1
  import math
3
2
  import asyncio
4
3
 
@@ -9,6 +8,7 @@ import synapse.common as s_common
9
8
  import synapse.datamodel as s_datamodel
10
9
 
11
10
  import synapse.lib.ast as s_ast
11
+ import synapse.lib.json as s_json
12
12
  import synapse.lib.snap as s_snap
13
13
 
14
14
  import synapse.tests.utils as s_test
@@ -1523,7 +1523,7 @@ class AstTest(s_test.SynTest):
1523
1523
  self.stormIsInPrint('stormpkg', msgs)
1524
1524
 
1525
1525
  # Make sure a JSON package loads
1526
- jsonpkg = json.loads(json.dumps(jsonpkg))
1526
+ jsonpkg = s_json.loads(s_json.dumps(jsonpkg))
1527
1527
  await core.stormlist('$lib.pkg.add($pkg)',
1528
1528
  opts={'vars': {'pkg': jsonpkg}})
1529
1529
  msgs = await core.stormlist('pkg.list')
@@ -1731,7 +1731,7 @@ class AstTest(s_test.SynTest):
1731
1731
  prints = list(filter(lambda m: m[0] == 'print', msgs))
1732
1732
  self.eq(len(prints), 3)
1733
1733
 
1734
- jmsgs = list(map(lambda m: json.loads(m[1]['mesg']), prints))
1734
+ jmsgs = list(map(lambda m: s_json.loads(m[1]['mesg']), prints))
1735
1735
  omsgs = sorted(jmsgs, key=lambda m: m[0])
1736
1736
  self.eq(omsgs[0][1], 'this should be first')
1737
1737
  self.eq(omsgs[1][1], 'toreturn called')
@@ -56,7 +56,7 @@ shave'''
56
56
  )
57
57
  }
58
58
  callsig = s_autodoc.genCallsig(rtype)
59
- self.eq(callsig, '(foo, bar=$lib.null, **kwargs)')
59
+ self.eq(callsig, '(foo, bar=(null), **kwargs)')
60
60
  self.eq(s_autodoc.genCallsig({}), '()')
61
61
  self.eq(s_autodoc.genCallsig({'args': ({'name': 'beep'},)}), '(beep)')
62
62
 
@@ -176,8 +176,8 @@ Returns:
176
176
 
177
177
  .. _test-lib-test-someargs:
178
178
 
179
- someargs(valu, bar=$lib.true, faz=$lib.null)
180
- ============================================
179
+ someargs(valu, bar=(true), faz=(null))
180
+ ======================================
181
181
 
182
182
  .. warning::
183
183
  ``$lib.test.someargs`` has been deprecated and will be removed in version v3.0.0.
@@ -252,8 +252,8 @@ Returns:
252
252
 
253
253
  .. _test-lib-test-someargs:
254
254
 
255
- $lib.test.someargs(valu, bar=$lib.true, faz=$lib.null)
256
- ======================================================
255
+ $lib.test.someargs(valu, bar=(true), faz=(null))
256
+ ================================================
257
257
 
258
258
  .. warning::
259
259
  ``$lib.test.someargs`` has been deprecated and will be removed in version v3.0.0.
@@ -483,7 +483,7 @@ class BaseTest(s_t_utils.SynTest):
483
483
  async def badgenr():
484
484
  yield 'foo'
485
485
  await asyncio.sleep(0)
486
- raise s_exc.SynErr('rando')
486
+ raise s_exc.SynErr(mesg='rando')
487
487
 
488
488
  async def slowgenr():
489
489
  yield 'foo'
@@ -1,7 +1,6 @@
1
1
  import os
2
2
  import ssl
3
3
  import sys
4
- import json
5
4
  import time
6
5
  import base64
7
6
  import signal
@@ -26,6 +25,7 @@ import synapse.lib.auth as s_auth
26
25
  import synapse.lib.base as s_base
27
26
  import synapse.lib.cell as s_cell
28
27
  import synapse.lib.coro as s_coro
28
+ import synapse.lib.json as s_json
29
29
  import synapse.lib.link as s_link
30
30
  import synapse.lib.drive as s_drive
31
31
  import synapse.lib.nexus as s_nexus
@@ -1817,8 +1817,19 @@ class CellTest(s_t_utils.SynTest):
1817
1817
 
1818
1818
  with open(bkuppath3, 'wb') as bkup3:
1819
1819
  async for msg in proxy.iterNewBackupArchive('bkup3', remove=True):
1820
+ self.true(core.backupstreaming)
1820
1821
  bkup3.write(msg)
1821
1822
 
1823
+ async def streamdone():
1824
+ while core.backupstreaming:
1825
+ await asyncio.sleep(0.1)
1826
+
1827
+ task = core.schedCoro(streamdone())
1828
+ try:
1829
+ await asyncio.wait_for(task, 5)
1830
+ except TimeoutError:
1831
+ raise TimeoutError('Timeout waiting for streaming backup cleanup of bkup3 to complete.')
1832
+
1822
1833
  self.eq(('bkup', 'bkup2'), sorted(await proxy.getBackups()))
1823
1834
  self.false(os.path.isdir(os.path.join(backdirn, 'bkup3')))
1824
1835
 
@@ -1830,6 +1841,12 @@ class CellTest(s_t_utils.SynTest):
1830
1841
  async for msg in proxy.iterNewBackupArchive(remove=True):
1831
1842
  bkup4.write(msg)
1832
1843
 
1844
+ task = core.schedCoro(streamdone())
1845
+ try:
1846
+ await asyncio.wait_for(task, 5)
1847
+ except TimeoutError:
1848
+ raise TimeoutError('Timeout waiting for streaming backup cleanup of bkup4 to complete.')
1849
+
1833
1850
  self.eq(('bkup', 'bkup2'), sorted(await proxy.getBackups()))
1834
1851
 
1835
1852
  # Start another backup while one is already running
@@ -3117,13 +3134,13 @@ class CellTest(s_t_utils.SynTest):
3117
3134
  self.nn(node.getTagProp('test', 'score'), 6)
3118
3135
 
3119
3136
  self.maxDiff = None
3120
- roles = s_t_utils.deguidify('[{"type": "role", "iden": "e1ef725990aa62ae3c4b98be8736d89f", "name": "all", "rules": [], "authgates": {"46cfde2c1682566602860f8df7d0cc83": {"rules": [[true, ["layer", "read"]]]}, "4d50eb257549436414643a71e057091a": {"rules": [[true, ["view", "read"]]]}}}]')
3121
- users = s_t_utils.deguidify('[{"type": "user", "iden": "a357138db50780b62093a6ce0d057fd8", "name": "root", "rules": [], "roles": [], "admin": true, "email": null, "locked": false, "archived": false, "authgates": {"46cfde2c1682566602860f8df7d0cc83": {"admin": true}, "4d50eb257549436414643a71e057091a": {"admin": true}}}, {"type": "user", "iden": "f77ac6744671a845c27e571071877827", "name": "visi", "rules": [[true, ["cron", "add"]], [true, ["dmon", "add"]], [true, ["trigger", "add"]]], "roles": [{"type": "role", "iden": "e1ef725990aa62ae3c4b98be8736d89f", "name": "all", "rules": [], "authgates": {"46cfde2c1682566602860f8df7d0cc83": {"rules": [[true, ["layer", "read"]]]}, "4d50eb257549436414643a71e057091a": {"rules": [[true, ["view", "read"]]]}}}], "admin": false, "email": null, "locked": false, "archived": false, "authgates": {"f21b7ae79c2dacb89484929a8409e5d8": {"admin": true}, "d7d0380dd4e743e35af31a20d014ed48": {"admin": true}}}]')
3122
- gates = s_t_utils.deguidify('[{"iden": "46cfde2c1682566602860f8df7d0cc83", "type": "layer", "users": [{"iden": "a357138db50780b62093a6ce0d057fd8", "rules": [], "admin": true}], "roles": [{"iden": "e1ef725990aa62ae3c4b98be8736d89f", "rules": [[true, ["layer", "read"]]], "admin": false}]}, {"iden": "d7d0380dd4e743e35af31a20d014ed48", "type": "trigger", "users": [{"iden": "f77ac6744671a845c27e571071877827", "rules": [], "admin": true}], "roles": []}, {"iden": "f21b7ae79c2dacb89484929a8409e5d8", "type": "cronjob", "users": [{"iden": "f77ac6744671a845c27e571071877827", "rules": [], "admin": true}], "roles": []}, {"iden": "4d50eb257549436414643a71e057091a", "type": "view", "users": [{"iden": "a357138db50780b62093a6ce0d057fd8", "rules": [], "admin": true}], "roles": [{"iden": "e1ef725990aa62ae3c4b98be8736d89f", "rules": [[true, ["view", "read"]]], "admin": false}]}, {"iden": "cortex", "type": "cortex", "users": [], "roles": []}]')
3137
+ roles = s_t_utils.deguidify('[{"type":"role","iden":"e1ef725990aa62ae3c4b98be8736d89f","name":"all","rules":[],"authgates":{"46cfde2c1682566602860f8df7d0cc83":{"rules":[[true,["layer","read"]]]},"4d50eb257549436414643a71e057091a":{"rules":[[true,["view","read"]]]}}}]')
3138
+ users = s_t_utils.deguidify('[{"type":"user","iden":"a357138db50780b62093a6ce0d057fd8","name":"root","rules":[],"roles":[],"admin":true,"email":null,"locked":false,"archived":false,"authgates":{"46cfde2c1682566602860f8df7d0cc83":{"admin":true},"4d50eb257549436414643a71e057091a":{"admin":true}}},{"type":"user","iden":"f77ac6744671a845c27e571071877827","name":"visi","rules":[[true,["cron","add"]],[true,["dmon","add"]],[true,["trigger","add"]]],"roles":[{"type":"role","iden":"e1ef725990aa62ae3c4b98be8736d89f","name":"all","rules":[],"authgates":{"46cfde2c1682566602860f8df7d0cc83":{"rules":[[true,["layer","read"]]]},"4d50eb257549436414643a71e057091a":{"rules":[[true,["view","read"]]]}}}],"admin":false,"email":null,"locked":false,"archived":false,"authgates":{"f21b7ae79c2dacb89484929a8409e5d8":{"admin":true},"d7d0380dd4e743e35af31a20d014ed48":{"admin":true}}}]')
3139
+ gates = s_t_utils.deguidify('[{"iden":"46cfde2c1682566602860f8df7d0cc83","type":"layer","users":[{"iden":"a357138db50780b62093a6ce0d057fd8","rules":[],"admin":true}],"roles":[{"iden":"e1ef725990aa62ae3c4b98be8736d89f","rules":[[true,["layer","read"]]],"admin":false}]},{"iden":"d7d0380dd4e743e35af31a20d014ed48","type":"trigger","users":[{"iden":"f77ac6744671a845c27e571071877827","rules":[],"admin":true}],"roles":[]},{"iden":"f21b7ae79c2dacb89484929a8409e5d8","type":"cronjob","users":[{"iden":"f77ac6744671a845c27e571071877827","rules":[],"admin":true}],"roles":[]},{"iden":"4d50eb257549436414643a71e057091a","type":"view","users":[{"iden":"a357138db50780b62093a6ce0d057fd8","rules":[],"admin":true}],"roles":[{"iden":"e1ef725990aa62ae3c4b98be8736d89f","rules":[[true,["view","read"]]],"admin":false}]},{"iden":"cortex","type":"cortex","users":[],"roles":[]}]')
3123
3140
 
3124
- self.eq(roles, s_t_utils.deguidify(json.dumps(await core.callStorm('return($lib.auth.roles.list())'))))
3125
- self.eq(users, s_t_utils.deguidify(json.dumps(await core.callStorm('return($lib.auth.users.list())'))))
3126
- self.eq(gates, s_t_utils.deguidify(json.dumps(await core.callStorm('return($lib.auth.gates.list())'))))
3141
+ self.eq(roles, s_t_utils.deguidify(s_json.dumps(await core.callStorm('return($lib.auth.roles.list())')).decode()))
3142
+ self.eq(users, s_t_utils.deguidify(s_json.dumps(await core.callStorm('return($lib.auth.users.list())')).decode()))
3143
+ self.eq(gates, s_t_utils.deguidify(s_json.dumps(await core.callStorm('return($lib.auth.gates.list())')).decode()))
3127
3144
 
3128
3145
  with self.raises(s_exc.BadTypeValu):
3129
3146
  await core.nodes('[ it:dev:str=foo +#test.newp ]')
@@ -1,5 +1,4 @@
1
1
  import copy
2
- import json
3
2
  import regex
4
3
  import pathlib
5
4
  import argparse
@@ -11,6 +10,7 @@ import synapse.data as s_data
11
10
  import synapse.common as s_common
12
11
 
13
12
  import synapse.lib.cell as s_cell
13
+ import synapse.lib.json as s_json
14
14
  import synapse.lib.config as s_config
15
15
 
16
16
  import synapse.tests.utils as s_test
@@ -396,7 +396,7 @@ class ConfTest(s_test.SynTest):
396
396
  self.true(filename.exists())
397
397
 
398
398
  with filename.open() as fp:
399
- schema = json.load(fp)
399
+ schema = s_json.load(fp)
400
400
 
401
401
  self.eq(schema, s_config.localSchemaRefHandler(
402
402
  "http://raw.githubusercontent.com/oasis-open/cti-stix2-json-schemas/stix2.1/schemas/common/core.json"
@@ -1,8 +1,8 @@
1
1
  import io
2
- import json
3
2
 
4
3
  import synapse.common as s_common
5
4
 
5
+ import synapse.lib.json as s_json
6
6
  import synapse.lib.msgpack as s_msgpack
7
7
  import synapse.lib.encoding as s_encoding
8
8
 
@@ -190,7 +190,7 @@ class EncTest(s_t_utils.SynTest):
190
190
 
191
191
  }
192
192
 
193
- buf = io.BytesIO(json.dumps(data).encode())
193
+ buf = io.BytesIO(s_json.dumps(data))
194
194
 
195
195
  lines = list(s_encoding.iterdata(buf, format='json'))
196
196
  self.len(1, lines)