synapse 2.192.0__py311-none-any.whl → 2.194.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 (77) hide show
  1. synapse/common.py +15 -0
  2. synapse/cortex.py +19 -25
  3. synapse/datamodel.py +6 -3
  4. synapse/exc.py +6 -1
  5. synapse/lib/agenda.py +17 -6
  6. synapse/lib/ast.py +242 -97
  7. synapse/lib/auth.py +1 -0
  8. synapse/lib/cell.py +31 -85
  9. synapse/lib/cli.py +20 -11
  10. synapse/lib/parser.py +5 -1
  11. synapse/lib/snap.py +44 -15
  12. synapse/lib/storm.lark +16 -1
  13. synapse/lib/storm.py +40 -21
  14. synapse/lib/storm_format.py +1 -0
  15. synapse/lib/stormctrl.py +88 -6
  16. synapse/lib/stormlib/cache.py +6 -2
  17. synapse/lib/stormlib/json.py +5 -2
  18. synapse/lib/stormlib/scrape.py +1 -1
  19. synapse/lib/stormlib/stix.py +8 -8
  20. synapse/lib/stormtypes.py +32 -5
  21. synapse/lib/version.py +2 -2
  22. synapse/lib/view.py +20 -3
  23. synapse/models/geopol.py +1 -0
  24. synapse/models/geospace.py +1 -0
  25. synapse/models/inet.py +20 -1
  26. synapse/models/infotech.py +24 -6
  27. synapse/models/orgs.py +7 -2
  28. synapse/models/person.py +15 -4
  29. synapse/models/risk.py +19 -2
  30. synapse/models/telco.py +10 -3
  31. synapse/tests/test_axon.py +6 -6
  32. synapse/tests/test_cortex.py +133 -14
  33. synapse/tests/test_exc.py +4 -0
  34. synapse/tests/test_lib_agenda.py +282 -2
  35. synapse/tests/test_lib_aha.py +13 -6
  36. synapse/tests/test_lib_ast.py +301 -10
  37. synapse/tests/test_lib_auth.py +6 -7
  38. synapse/tests/test_lib_cell.py +71 -1
  39. synapse/tests/test_lib_grammar.py +14 -0
  40. synapse/tests/test_lib_layer.py +1 -1
  41. synapse/tests/test_lib_lmdbslab.py +3 -3
  42. synapse/tests/test_lib_storm.py +273 -55
  43. synapse/tests/test_lib_stormctrl.py +65 -0
  44. synapse/tests/test_lib_stormhttp.py +5 -5
  45. synapse/tests/test_lib_stormlib_auth.py +5 -5
  46. synapse/tests/test_lib_stormlib_cache.py +38 -6
  47. synapse/tests/test_lib_stormlib_json.py +20 -0
  48. synapse/tests/test_lib_stormlib_modelext.py +3 -3
  49. synapse/tests/test_lib_stormlib_scrape.py +6 -6
  50. synapse/tests/test_lib_stormlib_spooled.py +1 -1
  51. synapse/tests/test_lib_stormlib_xml.py +5 -5
  52. synapse/tests/test_lib_stormtypes.py +54 -57
  53. synapse/tests/test_lib_view.py +1 -1
  54. synapse/tests/test_model_base.py +1 -2
  55. synapse/tests/test_model_geopol.py +4 -0
  56. synapse/tests/test_model_geospace.py +6 -0
  57. synapse/tests/test_model_inet.py +43 -5
  58. synapse/tests/test_model_infotech.py +10 -1
  59. synapse/tests/test_model_orgs.py +17 -2
  60. synapse/tests/test_model_person.py +23 -1
  61. synapse/tests/test_model_risk.py +13 -0
  62. synapse/tests/test_tools_healthcheck.py +4 -4
  63. synapse/tests/test_tools_storm.py +95 -0
  64. synapse/tests/test_utils.py +17 -18
  65. synapse/tests/test_utils_getrefs.py +1 -1
  66. synapse/tests/utils.py +0 -35
  67. synapse/tools/changelog.py +6 -4
  68. synapse/tools/storm.py +1 -1
  69. synapse/utils/getrefs.py +14 -3
  70. synapse/vendor/cpython/lib/http/__init__.py +0 -0
  71. synapse/vendor/cpython/lib/http/cookies.py +59 -0
  72. synapse/vendor/cpython/lib/test/test_http_cookies.py +49 -0
  73. {synapse-2.192.0.dist-info → synapse-2.194.0.dist-info}/METADATA +6 -6
  74. {synapse-2.192.0.dist-info → synapse-2.194.0.dist-info}/RECORD +77 -73
  75. {synapse-2.192.0.dist-info → synapse-2.194.0.dist-info}/WHEEL +1 -1
  76. {synapse-2.192.0.dist-info → synapse-2.194.0.dist-info}/LICENSE +0 -0
  77. {synapse-2.192.0.dist-info → synapse-2.194.0.dist-info}/top_level.txt +0 -0
@@ -131,7 +131,7 @@ class AstTest(s_test.SynTest):
131
131
  self.stormIsInWarn('Storm search interface is not enabled!', msgs)
132
132
 
133
133
  async with self.getTestCore() as core:
134
- await core.loadStormPkg({
134
+ core.loadStormPkg({
135
135
  'name': 'testsearch',
136
136
  'modules': [
137
137
  {'name': 'testsearch', 'interfaces': ['search'], 'storm': '''
@@ -292,11 +292,11 @@ class AstTest(s_test.SynTest):
292
292
  async with self.getTestCore() as core:
293
293
  q = '''
294
294
  [test:str=another :hehe=asdf]
295
- $s = $lib.text("Foo")
295
+ $s = ("Foo",)
296
296
  $newvar=:hehe
297
297
  -.created
298
- $s.add("yar {x}", x=$newvar)
299
- $lib.print($s.str())
298
+ $s.append("yar {x}", x=$newvar)
299
+ $lib.print($lib.str.join('', $s))
300
300
  '''
301
301
  mesgs = await core.stormlist(q)
302
302
  prints = [m[1]['mesg'] for m in mesgs if m[0] == 'print']
@@ -405,6 +405,93 @@ class AstTest(s_test.SynTest):
405
405
  q = 'test:str=foo $newp=($node.repr(), bar) [*$newp=foo]'
406
406
  await self.asyncraises(s_exc.StormRuntimeError, core.nodes(q))
407
407
 
408
+ async def test_ast_condsetoper(self):
409
+ async with self.getTestCore() as core:
410
+
411
+ q = '$var=hehe $foo=unset [test:str=foo :$var*unset=heval]'
412
+ nodes = await core.nodes(q)
413
+ self.len(1, nodes)
414
+ self.eq('heval', nodes[0].get('hehe'))
415
+
416
+ q = '$var=hehe $foo=unset [test:str=foo :$var*unset=newp]'
417
+ nodes = await core.nodes(q)
418
+ self.len(1, nodes)
419
+ self.eq('heval', nodes[0].get('hehe'))
420
+
421
+ q = '$var=hehe $foo=unset [test:str=foo :$var*$foo=newp]'
422
+ nodes = await core.nodes(q)
423
+ self.len(1, nodes)
424
+ self.eq('heval', nodes[0].get('hehe'))
425
+
426
+ q = '$var=hehe $foo=always [test:str=foo :$var*$foo=yep]'
427
+ nodes = await core.nodes(q)
428
+ self.len(1, nodes)
429
+ self.eq('yep', nodes[0].get('hehe'))
430
+
431
+ q = '[test:str=foo -:hehe]'
432
+ nodes = await core.nodes(q)
433
+ self.len(1, nodes)
434
+ self.none(nodes[0].get('hehe'))
435
+
436
+ q = '$var=hehe $foo=never [test:str=foo :$var*$foo=yep]'
437
+ nodes = await core.nodes(q)
438
+ self.len(1, nodes)
439
+ self.none(nodes[0].get('hehe'))
440
+
441
+ q = '$var=hehe $foo=unset [test:str=foo :$var*$foo=heval]'
442
+ nodes = await core.nodes(q)
443
+ self.len(1, nodes)
444
+ self.eq('heval', nodes[0].get('hehe'))
445
+
446
+ with self.raises(s_exc.BadTypeValu):
447
+ q = '$var=tick $foo=always [test:str=foo :$var*$foo=heval]'
448
+ nodes = await core.nodes(q)
449
+
450
+ q = '$var=tick $foo=always [test:str=foo :$var*$foo?=heval]'
451
+ nodes = await core.nodes(q)
452
+ self.len(1, nodes)
453
+ self.none(nodes[0].get('tick'))
454
+
455
+ q = '''
456
+ $opts=({"tick": "unset", "hehe": "always"})
457
+ [ test:str=foo
458
+ :hehe*$opts.hehe=newv
459
+ :tick*$opts.tick?=2020]
460
+ '''
461
+ nodes = await core.nodes(q)
462
+ self.len(1, nodes)
463
+ self.eq('newv', nodes[0].get('hehe'))
464
+ tick = nodes[0].get('tick')
465
+ self.nn(tick)
466
+
467
+ q = '''
468
+ $opts=({"tick": "never", "hehe": "unset"})
469
+ [ test:str=foo
470
+ :hehe*$opts.hehe=newp
471
+ :tick*$opts.tick?=2020]
472
+ '''
473
+ nodes = await core.nodes(q)
474
+ self.len(1, nodes)
475
+ self.eq('newv', nodes[0].get('hehe'))
476
+ self.eq(tick, nodes[0].get('tick'))
477
+
478
+ q = '$foo=always [test:str=foo :tick*$foo?=2021]'
479
+ nodes = await core.nodes(q)
480
+ self.len(1, nodes)
481
+ self.ne(tick, nodes[0].get('tick'))
482
+
483
+ with self.raises(s_exc.IsReadOnly):
484
+ q = '[test:str=foo :hehe*unset=heval]'
485
+ nodes = await core.nodes(q, opts={'readonly': True})
486
+
487
+ with self.raises(s_exc.NoSuchProp):
488
+ q = '[test:str=foo :newp*unset=heval]'
489
+ nodes = await core.nodes(q)
490
+
491
+ with self.raises(s_exc.StormRuntimeError):
492
+ q = '$foo=newp [test:str=foo :hehe*$foo=heval]'
493
+ nodes = await core.nodes(q)
494
+
408
495
  async def test_ast_editparens(self):
409
496
 
410
497
  async with self.getTestCore() as core:
@@ -1070,10 +1157,10 @@ class AstTest(s_test.SynTest):
1070
1157
 
1071
1158
  nodes = await core.nodes('[ test:arrayprop="*" :ints=(1, 2, 3) ]')
1072
1159
  nodes = await core.nodes('[ test:arrayprop="*" :ints=(100, 101, 102) ]')
1073
- nodes = await core.nodes('test:arrayprop +:ints=$lib.list(1,2,3)')
1160
+ nodes = await core.nodes('test:arrayprop +:ints=([1,2,3])')
1074
1161
  self.len(1, nodes)
1075
1162
 
1076
- nodes = await core.nodes('test:arrayprop:ints=$lib.list(1,2,3)')
1163
+ nodes = await core.nodes('test:arrayprop:ints=([1,2,3])')
1077
1164
  self.len(1, nodes)
1078
1165
 
1079
1166
  with self.raises(s_exc.NoSuchProp):
@@ -1232,7 +1319,7 @@ class AstTest(s_test.SynTest):
1232
1319
  nodes = await core.nodes(q)
1233
1320
  self.len(1, nodes)
1234
1321
 
1235
- nodes = await core.nodes('[ test:arrayprop=* :strs={return ($lib.list(a,b,c,d))} ]')
1322
+ nodes = await core.nodes('[ test:arrayprop=* :strs={return ((a,b,c,d))} ]')
1236
1323
  self.len(1, nodes)
1237
1324
  self.len(4, nodes[0].get('strs'))
1238
1325
 
@@ -1870,7 +1957,7 @@ class AstTest(s_test.SynTest):
1870
1957
  self.len(0, await core.nodes('init { function x() { return((0)) } }'))
1871
1958
 
1872
1959
  # Can't use a mutable variable as a default
1873
- q = '$var=$lib.list(1,2,3) function badargs(x=foo, y=$var) {} $badargs()'
1960
+ q = '$var=([1,2,3]) function badargs(x=foo, y=$var) {} $badargs()'
1874
1961
  msgs = await core.stormlist(q)
1875
1962
  erfo = [m for m in msgs if m[0] == 'err'][0]
1876
1963
  self.eq(erfo[1][0], 'StormRuntimeError')
@@ -2648,12 +2735,12 @@ class AstTest(s_test.SynTest):
2648
2735
 
2649
2736
  q = 'function func(arg) { auth.user.addrule root $arg | return () } $func(hehe.haha)'
2650
2737
  msgs = await core.stormlist(q, opts={'readonly': True})
2651
- self.stormIsInErr('Function (_methUserAddRule) is not marked readonly safe.', msgs)
2738
+ self.stormIsInErr('auth:user.addRule() is not marked readonly safe.', msgs)
2652
2739
 
2653
2740
  async def test_ast_yield(self):
2654
2741
 
2655
2742
  async with self.getTestCore() as core:
2656
- q = '$nodes = $lib.list() [ inet:asn=10 inet:asn=20 ] $nodes.append($node) | spin | yield $nodes'
2743
+ q = '$nodes = () [ inet:asn=10 inet:asn=20 ] $nodes.append($node) | spin | yield $nodes'
2657
2744
  nodes = await core.nodes(q)
2658
2745
  self.len(2, nodes)
2659
2746
 
@@ -3119,6 +3206,48 @@ class AstTest(s_test.SynTest):
3119
3206
  off, end = errm[1][1]['highlight']['offsets']
3120
3207
  self.eq('newp', text[off:end])
3121
3208
 
3209
+ visi = (await core.addUser('visi'))['iden']
3210
+ text = '$users=$lib.auth.users.list() $lib.print($users.0.profile)'
3211
+ msgs = await core.stormlist(text, opts={'user': visi})
3212
+ errm = [m for m in msgs if m[0] == 'err'][0]
3213
+ off, end = errm[1][1]['highlight']['offsets']
3214
+ self.eq('lib.print($users.0.profile)', text[off:end])
3215
+
3216
+ text = '$lib.len(foo, bar)'
3217
+ msgs = await core.stormlist(text)
3218
+ errm = [m for m in msgs if m[0] == 'err'][0]
3219
+ off, end = errm[1][1]['highlight']['offsets']
3220
+ self.eq('lib.len(foo, bar)', text[off:end])
3221
+ self.stormIsInErr('$lib.len()', msgs)
3222
+
3223
+ text = '$foo=$lib.pkg.get $foo()'
3224
+ msgs = await core.stormlist(text)
3225
+ errm = [m for m in msgs if m[0] == 'err'][0]
3226
+ off, end = errm[1][1]['highlight']['offsets']
3227
+ self.eq('foo()', text[off:end])
3228
+ self.stormIsInErr('$lib.pkg.get()', msgs)
3229
+
3230
+ text = '$obj = $lib.pipe.gen(${ $obj.put() }) $obj.put(foo, bar, baz)'
3231
+ msgs = await core.stormlist(text)
3232
+ errm = [m for m in msgs if m[0] == 'err'][0]
3233
+ off, end = errm[1][1]['highlight']['offsets']
3234
+ self.eq('obj.put(foo, bar, baz)', text[off:end])
3235
+ self.stormIsInErr('pipe.put()', msgs)
3236
+
3237
+ text = '$lib.gen.campaign(foo, bar, baz)'
3238
+ msgs = await core.stormlist(text)
3239
+ errm = [m for m in msgs if m[0] == 'err'][0]
3240
+ off, end = errm[1][1]['highlight']['offsets']
3241
+ self.eq('lib.gen.campaign(foo, bar, baz)', text[off:end])
3242
+ self.stormIsInErr('$lib.gen.campaign()', msgs)
3243
+
3244
+ text = '$gen = $lib.gen.campaign $gen(foo, bar, baz)'
3245
+ msgs = await core.stormlist(text)
3246
+ errm = [m for m in msgs if m[0] == 'err'][0]
3247
+ off, end = errm[1][1]['highlight']['offsets']
3248
+ self.eq('gen(foo, bar, baz)', text[off:end])
3249
+ self.stormIsInErr('$lib.gen.campaign()', msgs)
3250
+
3122
3251
  async def test_ast_bulkedges(self):
3123
3252
 
3124
3253
  async with self.getTestCore() as core:
@@ -4395,3 +4524,165 @@ class AstTest(s_test.SynTest):
4395
4524
  text = '($x, $y) = (1)'
4396
4525
  with self.raises(s_exc.StormRuntimeError):
4397
4526
  await core.nodes(text)
4527
+
4528
+ async def test_ast_functypes(self):
4529
+
4530
+ async with self.getTestCore() as core:
4531
+
4532
+ async def verify(q, isin=False):
4533
+ msgs = await core.stormlist(q)
4534
+ if isin:
4535
+ self.stormIsInPrint('yep', msgs)
4536
+ else:
4537
+ self.stormNotInPrint('newp', msgs)
4538
+ self.len(1, [m for m in msgs if m[0] == 'node'])
4539
+ self.stormHasNoErr(msgs)
4540
+
4541
+ q = '''
4542
+ function foo() {
4543
+ for $n in { return((newp,)) } { $lib.print($n) }
4544
+ }
4545
+ [ it:dev:str=test ]
4546
+ $foo()
4547
+ '''
4548
+ await verify(q)
4549
+
4550
+ q = '''
4551
+ function foo() {
4552
+ while { return((newp,)) } { $lib.print(newp) break }
4553
+ }
4554
+ [ it:dev:str=test ]
4555
+ $foo()
4556
+ '''
4557
+ await verify(q)
4558
+
4559
+ q = '''
4560
+ function foo() {
4561
+ switch $lib.print({ return(newp) }) { *: { $lib.print(newp) } }
4562
+ }
4563
+ [ it:dev:str=test ]
4564
+ $foo()
4565
+ '''
4566
+ await verify(q)
4567
+
4568
+ q = '''
4569
+ function foo() {
4570
+ switch $foo { *: { $lib.print(yep) return() } }
4571
+ }
4572
+ [ it:dev:str=test ]
4573
+ $foo()
4574
+ '''
4575
+ await verify(q, isin=True)
4576
+
4577
+ q = '''
4578
+ function foo() {
4579
+ if { return(newp) } { $lib.print(newp) }
4580
+ }
4581
+ [ it:dev:str=test ]
4582
+ $foo()
4583
+ '''
4584
+ await verify(q)
4585
+
4586
+ q = '''
4587
+ function foo() {
4588
+ if (false) { $lib.print(newp) }
4589
+ elif { return(newp) } { $lib.print(newp) }
4590
+ }
4591
+ [ it:dev:str=test ]
4592
+ $foo()
4593
+ '''
4594
+ await verify(q)
4595
+
4596
+ q = '''
4597
+ function foo() {
4598
+ if (false) { $lib.print(newp) }
4599
+ elif (true) { $lib.print(yep) return() }
4600
+ }
4601
+ [ it:dev:str=test ]
4602
+ $foo()
4603
+ '''
4604
+ await verify(q)
4605
+
4606
+ q = '''
4607
+ function foo() {
4608
+ if (false) { $lib.print(newp) }
4609
+ elif (false) { $lib.print(newp) }
4610
+ else { $lib.print(yep) return() }
4611
+ }
4612
+ [ it:dev:str=test ]
4613
+ $foo()
4614
+ '''
4615
+ await verify(q, isin=True)
4616
+
4617
+ q = '''
4618
+ function foo() {
4619
+ [ it:dev:str=foo +(refs)> { $lib.print(newp) return() } ]
4620
+ }
4621
+ [ it:dev:str=test ]
4622
+ $foo()
4623
+ '''
4624
+ await verify(q)
4625
+
4626
+ q = '''
4627
+ function foo() {
4628
+ $lib.print({ return(newp) })
4629
+ }
4630
+ [ it:dev:str=test ]
4631
+ $foo()
4632
+ '''
4633
+ await verify(q)
4634
+
4635
+ q = '''
4636
+ function foo() {
4637
+ $x = { $lib.print(newp) return() }
4638
+ }
4639
+ [ it:dev:str=test ]
4640
+ $foo()
4641
+ '''
4642
+ await verify(q)
4643
+
4644
+ q = '''
4645
+ function foo() {
4646
+ ($x, $y) = { $lib.print(newp) return((foo, bar)) }
4647
+ }
4648
+ [ it:dev:str=test ]
4649
+ $foo()
4650
+ '''
4651
+ await verify(q)
4652
+
4653
+ q = '''
4654
+ function foo() {
4655
+ $x = ({})
4656
+ $x.y = { $lib.print(newp) return((foo, bar)) }
4657
+ }
4658
+ [ it:dev:str=test ]
4659
+ $foo()
4660
+ '''
4661
+ await verify(q)
4662
+
4663
+ q = '''
4664
+ function foo() {
4665
+ .created -({$lib.print(newp) return(refs)})> *
4666
+ }
4667
+ [ it:dev:str=test ]
4668
+ $foo()
4669
+ '''
4670
+ await verify(q)
4671
+
4672
+ q = '''
4673
+ function foo() {
4674
+ try { $lib.raise(boom) } catch { $lib.print(newp) return(newp) } as e {}
4675
+ }
4676
+ [ it:dev:str=test ]
4677
+ $foo()
4678
+ '''
4679
+ await verify(q)
4680
+
4681
+ q = '''
4682
+ function foo() {
4683
+ it:dev:str={ $lib.print(newp) return(test) }
4684
+ }
4685
+ [ it:dev:str=test ]
4686
+ $foo()
4687
+ '''
4688
+ await verify(q)
@@ -495,7 +495,7 @@ class AuthTest(s_test.SynTest):
495
495
  ])
496
496
 
497
497
  # Check sequences
498
- seqmsg = f'Password must not contain forward/reverse sequences longer than 3 characters.'
498
+ seqmsg = 'Password must not contain forward/reverse sequences longer than 3 characters.'
499
499
  passwords = [
500
500
  # letters
501
501
  'abcA', 'dcbA', 'Abcd', 'Acba',
@@ -531,12 +531,8 @@ class AuthTest(s_test.SynTest):
531
531
  'Password must contain at least 2 digit characters, 0 found.'
532
532
  ])
533
533
 
534
- with self.raises(s_exc.BadArg) as exc:
535
- await core.setUserPasswd(user.iden, None)
536
- self.isin(
537
- 'Password must be at least 12 characters.',
538
- exc.exception.get('failures')
539
- )
534
+ # Setting password to None should work also
535
+ await core.setUserPasswd(user.iden, None)
540
536
 
541
537
  # Attempting to add a user with a bad passwd will add the user and fail to set the password
542
538
  with self.raises(s_exc.BadArg):
@@ -582,6 +578,9 @@ class AuthTest(s_test.SynTest):
582
578
  await core.setUserPasswd(user.iden, pass2)
583
579
  await core.setUserPasswd(user.iden, pass3)
584
580
 
581
+ # Setting password to None should work also
582
+ await core.setUserPasswd(user.iden, None)
583
+
585
584
  with self.raises(s_exc.BadArg) as exc:
586
585
  await core.setUserPasswd(user.iden, pass1)
587
586
  self.eq(exc.exception.get('failures'), [
@@ -1433,6 +1433,11 @@ class CellTest(s_t_utils.SynTest):
1433
1433
  with mock.patch('os.stat', diffdev):
1434
1434
  await self.asyncraises(s_exc.LowSpace, proxy.runBackup())
1435
1435
 
1436
+ user = await core.auth.getUserByName('root')
1437
+ with self.raises(s_exc.SynErr) as cm:
1438
+ await core.iterNewBackupArchive(user)
1439
+ self.isin('This API must be called via a CellApi', cm.exception.get('mesg'))
1440
+
1436
1441
  async def err(*args, **kwargs):
1437
1442
  raise RuntimeError('boom')
1438
1443
 
@@ -2298,11 +2303,13 @@ class CellTest(s_t_utils.SynTest):
2298
2303
  # Backup the mirror (core01) which points to the core00
2299
2304
  async with await axon00.upload() as upfd:
2300
2305
  async with core01.getLocalProxy() as prox:
2306
+ tot_chunks = 0
2301
2307
  async for chunk in prox.iterNewBackupArchive():
2302
2308
  await upfd.write(chunk)
2309
+ tot_chunks += len(chunk)
2303
2310
 
2304
2311
  size, sha256 = await upfd.save()
2305
- await asyncio.sleep(0)
2312
+ self.eq(size, tot_chunks)
2306
2313
 
2307
2314
  furl = f'{url}{s_common.ehex(sha256)}'
2308
2315
  purl = await aha.addAhaSvcProv('00.mynewcortex')
@@ -3276,3 +3283,66 @@ class CellTest(s_t_utils.SynTest):
3276
3283
  with self.raises(s_exc.BadState) as cm:
3277
3284
  await cell00.promote(graceful=True)
3278
3285
  self.isin('02.cell is not the current leader', cm.exception.get('mesg'))
3286
+
3287
+ async def test_stream_backup_exception(self):
3288
+
3289
+ with self.getTestDir() as dirn:
3290
+ backdirn = os.path.join(dirn, 'backups')
3291
+ coredirn = os.path.join(dirn, 'cortex')
3292
+
3293
+ conf = {'backup:dir': backdirn}
3294
+ s_common.yamlsave(conf, coredirn, 'cell.yaml')
3295
+
3296
+ async with self.getTestCore(dirn=coredirn) as core:
3297
+ async with core.getLocalProxy() as proxy:
3298
+
3299
+ await proxy.runBackup(name='bkup')
3300
+
3301
+ mock_proc = mock.Mock()
3302
+ mock_proc.join = mock.Mock()
3303
+
3304
+ async def mock_executor(func, *args, **kwargs):
3305
+ if isinstance(func, mock.Mock) and func is mock_proc.join:
3306
+ raise Exception('boom')
3307
+ return mock_proc
3308
+
3309
+ with mock.patch('synapse.lib.cell.s_coro.executor', mock_executor):
3310
+ with self.getAsyncLoggerStream('synapse.lib.cell', 'Error during backup streaming') as stream:
3311
+ with self.raises(Exception) as cm:
3312
+ async for _ in proxy.iterBackupArchive('bkup'):
3313
+ pass
3314
+ self.true(await stream.wait(timeout=6))
3315
+
3316
+ async def test_iter_new_backup_archive(self):
3317
+
3318
+ with self.getTestDir() as dirn:
3319
+ backdirn = os.path.join(dirn, 'backups')
3320
+ coredirn = os.path.join(dirn, 'cortex')
3321
+
3322
+ conf = {'backup:dir': backdirn}
3323
+ s_common.yamlsave(conf, coredirn, 'cell.yaml')
3324
+
3325
+ async with self.getTestCore(dirn=coredirn) as core:
3326
+ async with core.getLocalProxy() as proxy:
3327
+
3328
+ async def mock_runBackup(*args, **kwargs):
3329
+ raise Exception('backup failed')
3330
+
3331
+ with mock.patch.object(s_cell.Cell, 'runBackup', mock_runBackup):
3332
+ with self.getAsyncLoggerStream('synapse.lib.cell', 'Removing') as stream:
3333
+ with self.raises(s_exc.SynErr) as cm:
3334
+ async for _ in proxy.iterNewBackupArchive('failedbackup', remove=True):
3335
+ pass
3336
+
3337
+ self.isin('backup failed', str(cm.exception))
3338
+ self.true(await stream.wait(timeout=6))
3339
+
3340
+ path = os.path.join(backdirn, 'failedbackup')
3341
+ self.false(os.path.exists(path))
3342
+
3343
+ self.false(core.backupstreaming)
3344
+
3345
+ core.backupstreaming = True
3346
+ with self.raises(s_exc.BackupAlreadyRunning):
3347
+ async for _ in proxy.iterNewBackupArchive('newbackup', remove=True):
3348
+ pass
@@ -728,6 +728,13 @@ Queries = [
728
728
  '$pvar=stuff test:arrayprop +:$pvar*[=neato]',
729
729
  '$pvar=ints test:arrayprop +:$pvar*[=$othervar]',
730
730
  '$foo = ({"foo": ${ inet:fqdn }})',
731
+ '[test:str=foo :hehe*unset=heval]',
732
+ '[test:str=foo :hehe*$foo=heval]',
733
+ '[test:str=foo :$foo*unset=heval]',
734
+ '[test:str=foo :$foo*$bar=heval]',
735
+ '[test:str=foo :$foo*$bar.baz=heval]',
736
+ '[test:str=foo :$foo*$bar.("baz")=heval]',
737
+ '[test:str=foo :$foo*$bar.baz()=heval]',
731
738
  ]
732
739
 
733
740
  # Generated with print_parse_list below
@@ -1358,6 +1365,13 @@ _ParseResults = [
1358
1365
  'Query: [SetVarOper: [Const: pvar, Const: stuff], LiftProp: [Const: test:arrayprop], FiltOper: [Const: +, ArrayCond: [RelProp: [VarValue: [Const: pvar]], Const: =, Const: neato]]]',
1359
1366
  'Query: [SetVarOper: [Const: pvar, Const: ints], LiftProp: [Const: test:arrayprop], FiltOper: [Const: +, ArrayCond: [RelProp: [VarValue: [Const: pvar]], Const: =, VarValue: [Const: othervar]]]]',
1360
1367
  'Query: [SetVarOper: [Const: foo, DollarExpr: [ExprDict: [Const: foo, EmbedQuery: inet:fqdn]]]]',
1368
+ 'Query: [EditNodeAdd: [FormName: [Const: test:str], Const: =, Const: foo], EditCondPropSet: [RelProp: [Const: hehe], CondSetOper: [Const: unset], Const: heval]]',
1369
+ 'Query: [EditNodeAdd: [FormName: [Const: test:str], Const: =, Const: foo], EditCondPropSet: [RelProp: [Const: hehe], CondSetOper: [VarValue: [Const: foo]], Const: heval]]',
1370
+ 'Query: [EditNodeAdd: [FormName: [Const: test:str], Const: =, Const: foo], EditCondPropSet: [RelProp: [VarValue: [Const: foo]], CondSetOper: [Const: unset], Const: heval]]',
1371
+ 'Query: [EditNodeAdd: [FormName: [Const: test:str], Const: =, Const: foo], EditCondPropSet: [RelProp: [VarValue: [Const: foo]], CondSetOper: [VarValue: [Const: bar]], Const: heval]]',
1372
+ 'Query: [EditNodeAdd: [FormName: [Const: test:str], Const: =, Const: foo], EditCondPropSet: [RelProp: [VarValue: [Const: foo]], CondSetOper: [VarDeref: [VarValue: [Const: bar], Const: baz]], Const: heval]]',
1373
+ 'Query: [EditNodeAdd: [FormName: [Const: test:str], Const: =, Const: foo], EditCondPropSet: [RelProp: [VarValue: [Const: foo]], CondSetOper: [VarDeref: [VarValue: [Const: bar], DollarExpr: [Const: baz]]], Const: heval]]',
1374
+ 'Query: [EditNodeAdd: [FormName: [Const: test:str], Const: =, Const: foo], EditCondPropSet: [RelProp: [VarValue: [Const: foo]], CondSetOper: [FuncCall: [VarDeref: [VarValue: [Const: bar], Const: baz], CallArgs: [], CallKwargs: []]], Const: heval]]',
1361
1375
  ]
1362
1376
 
1363
1377
  class GrammarTest(s_t_utils.SynTest):
@@ -54,7 +54,7 @@ class LayerTest(s_t_utils.SynTest):
54
54
  self.eq(errors[1][0], 'NoPropIndex')
55
55
 
56
56
  errors = await core.callStorm('''
57
- $retn = $lib.list()
57
+ $retn = ()
58
58
  for $mesg in $lib.layer.get().verify() {
59
59
  $retn.append($mesg)
60
60
  }
@@ -338,9 +338,9 @@ class LmdbSlabTest(s_t_utils.SynTest):
338
338
 
339
339
  # Ensure that our envar override for memory locking is acknowledged
340
340
  with self.setTstEnvars(SYN_LOCKMEM_DISABLE='1'):
341
- slab = await s_lmdbslab.Slab.anit(path, map_size=1000000, lockmemory=True)
342
- self.false(slab.lockmemory)
343
- self.none(slab.memlocktask)
341
+ async with await s_lmdbslab.Slab.anit(path, map_size=1000000, lockmemory=True) as slab:
342
+ self.false(slab.lockmemory)
343
+ self.none(slab.memlocktask)
344
344
 
345
345
  def simplenow(self):
346
346
  self._nowtime += 1000