synapse 2.154.1__py311-none-any.whl → 2.156.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 (74) hide show
  1. synapse/cmds/cortex.py +2 -14
  2. synapse/common.py +13 -36
  3. synapse/cortex.py +15 -508
  4. synapse/lib/ast.py +215 -22
  5. synapse/lib/cell.py +35 -8
  6. synapse/lib/certdir.py +11 -0
  7. synapse/lib/cmdr.py +0 -5
  8. synapse/lib/gis.py +2 -2
  9. synapse/lib/httpapi.py +14 -43
  10. synapse/lib/layer.py +64 -201
  11. synapse/lib/lmdbslab.py +11 -0
  12. synapse/lib/node.py +1 -3
  13. synapse/lib/parser.py +10 -0
  14. synapse/lib/slabseqn.py +2 -1
  15. synapse/lib/snap.py +121 -21
  16. synapse/lib/spooled.py +9 -0
  17. synapse/lib/storm.lark +23 -6
  18. synapse/lib/storm.py +16 -339
  19. synapse/lib/storm_format.py +5 -0
  20. synapse/lib/stormhttp.py +10 -1
  21. synapse/lib/stormlib/gen.py +1 -2
  22. synapse/lib/stormlib/gis.py +41 -0
  23. synapse/lib/stormlib/graph.py +2 -1
  24. synapse/lib/stormlib/stats.py +21 -2
  25. synapse/lib/stormlib/storm.py +16 -1
  26. synapse/lib/stormtypes.py +244 -16
  27. synapse/lib/types.py +16 -2
  28. synapse/lib/version.py +2 -2
  29. synapse/lib/view.py +118 -25
  30. synapse/models/base.py +2 -2
  31. synapse/models/inet.py +60 -30
  32. synapse/models/infotech.py +130 -8
  33. synapse/models/orgs.py +3 -0
  34. synapse/models/proj.py +3 -0
  35. synapse/models/risk.py +24 -6
  36. synapse/models/syn.py +0 -38
  37. synapse/tests/test_cmds_cortex.py +1 -1
  38. synapse/tests/test_cortex.py +70 -338
  39. synapse/tests/test_lib_agenda.py +19 -54
  40. synapse/tests/test_lib_aha.py +97 -0
  41. synapse/tests/test_lib_ast.py +596 -0
  42. synapse/tests/test_lib_grammar.py +30 -10
  43. synapse/tests/test_lib_httpapi.py +33 -49
  44. synapse/tests/test_lib_layer.py +19 -234
  45. synapse/tests/test_lib_lmdbslab.py +22 -0
  46. synapse/tests/test_lib_snap.py +9 -0
  47. synapse/tests/test_lib_spooled.py +4 -0
  48. synapse/tests/test_lib_storm.py +16 -309
  49. synapse/tests/test_lib_stormlib_gis.py +21 -0
  50. synapse/tests/test_lib_stormlib_stats.py +107 -20
  51. synapse/tests/test_lib_stormlib_storm.py +25 -0
  52. synapse/tests/test_lib_stormtypes.py +253 -8
  53. synapse/tests/test_lib_types.py +40 -0
  54. synapse/tests/test_lib_view.py +6 -13
  55. synapse/tests/test_model_base.py +1 -1
  56. synapse/tests/test_model_inet.py +15 -0
  57. synapse/tests/test_model_infotech.py +110 -0
  58. synapse/tests/test_model_orgs.py +10 -0
  59. synapse/tests/test_model_person.py +0 -3
  60. synapse/tests/test_model_proj.py +2 -1
  61. synapse/tests/test_model_risk.py +24 -0
  62. synapse/tests/test_model_syn.py +20 -34
  63. synapse/tests/test_tools_csvtool.py +2 -1
  64. synapse/tests/test_tools_feed.py +4 -30
  65. synapse/tools/csvtool.py +2 -1
  66. {synapse-2.154.1.dist-info → synapse-2.156.0.dist-info}/METADATA +9 -9
  67. {synapse-2.154.1.dist-info → synapse-2.156.0.dist-info}/RECORD +70 -72
  68. {synapse-2.154.1.dist-info → synapse-2.156.0.dist-info}/WHEEL +1 -1
  69. synapse/cmds/cron.py +0 -726
  70. synapse/cmds/trigger.py +0 -319
  71. synapse/tests/test_cmds_cron.py +0 -453
  72. synapse/tests/test_cmds_trigger.py +0 -176
  73. {synapse-2.154.1.dist-info → synapse-2.156.0.dist-info}/LICENSE +0 -0
  74. {synapse-2.154.1.dist-info → synapse-2.156.0.dist-info}/top_level.txt +0 -0
@@ -463,6 +463,17 @@ class StormTest(s_t_utils.SynTest):
463
463
  ''')
464
464
  self.stormIsInPrint('caught err=', msgs)
465
465
 
466
+ # Non-runtsafe Storm works without inbound nodes
467
+ msgs = await core.stormlist('''
468
+ try {
469
+ [ inet:ipv4=0 ]
470
+ $lib.raise(foo, $node.repr())
471
+ } catch * as err {
472
+ $lib.print($err.mesg)
473
+ }
474
+ ''')
475
+ self.stormIsInPrint('0.0.0.0', msgs)
476
+
466
477
  # info must be json safe
467
478
  with self.raises(s_exc.MustBeJsonSafe):
468
479
  await core.callStorm('$x="foo" $x=$x.encode() $lib.raise(foo, test, bar=$x)')
@@ -559,7 +570,7 @@ class StormTest(s_t_utils.SynTest):
559
570
  self.true(all([n.get('name') == 'foo' for n in nodes]))
560
571
 
561
572
  # Runtsafety test
562
- q = '[ inet:fqdn=www.vertex.link ] $q={ :domain -> inet:fqdn } | parallel $q'
573
+ q = '[ inet:fqdn=www.vertex.link ] $q=:domain | parallel $q'
563
574
  await self.asyncraises(s_exc.StormRuntimeError, core.nodes(q))
564
575
 
565
576
  # test $lib.exit() and the StormExit handlers
@@ -2070,7 +2081,7 @@ class StormTest(s_t_utils.SynTest):
2070
2081
  await self.asyncraises(s_exc.StormRuntimeError, core.nodes(q))
2071
2082
 
2072
2083
  # Runtsafety test
2073
- q = '[ inet:fqdn=www.vertex.link ] $q={ :domain -> inet:fqdn } | tree $q'
2084
+ q = '[ inet:fqdn=www.vertex.link ] $q=:domain | tree $q'
2074
2085
  await self.asyncraises(s_exc.StormRuntimeError, core.nodes(q))
2075
2086
 
2076
2087
  async def test_storm_movetag(self):
@@ -2324,16 +2335,6 @@ class StormTest(s_t_utils.SynTest):
2324
2335
  self.len(0, await core.nodes('[ test:str=foo test:str=bar ] | spin'))
2325
2336
  self.len(2, await core.nodes('test:str=foo test:str=bar'))
2326
2337
 
2327
- async def test_storm_reindex_sudo(self):
2328
-
2329
- async with self.getTestCore() as core:
2330
-
2331
- mesgs = await core.stormlist('reindex')
2332
- self.stormIsInWarn('reindex currently does nothing', mesgs)
2333
-
2334
- msgs = await core.stormlist('.created | sudo')
2335
- self.stormIsInWarn('sudo command is deprecated and will be removed on 2023-10-01', msgs)
2336
-
2337
2338
  async def test_storm_count(self):
2338
2339
 
2339
2340
  async with self.getTestCore() as core:
@@ -2864,7 +2865,7 @@ class StormTest(s_t_utils.SynTest):
2864
2865
  await core.nodes(q)
2865
2866
 
2866
2867
  # Runtsafety test
2867
- q = '[ inet:fqdn=www.vertex.link ] $q={ :domain -> inet:fqdn } | tee $q'
2868
+ q = '[ inet:fqdn=www.vertex.link ] $q=:domain | tee $q'
2868
2869
  await self.asyncraises(s_exc.StormRuntimeError, core.nodes(q))
2869
2870
 
2870
2871
  async def test_storm_yieldvalu(self):
@@ -2969,300 +2970,6 @@ class StormTest(s_t_utils.SynTest):
2969
2970
  nodes = await core.nodes(q, opts={'view': fork, 'vars': {'view': view}})
2970
2971
  self.len(1, nodes)
2971
2972
 
2972
- async def test_storm_splicelist(self):
2973
-
2974
- async with self.getTestCoreAndProxy() as (core, prox):
2975
-
2976
- mesgs = await core.stormlist('[ test:str=foo ]')
2977
- await asyncio.sleep(0.01)
2978
-
2979
- mesgs = await core.stormlist('[ test:str=bar ]')
2980
-
2981
- tick = mesgs[0][1]['tick']
2982
- tickdt = datetime.datetime.fromtimestamp(tick / 1000.0, datetime.UTC)
2983
- tickstr = tickdt.strftime('%Y/%m/%d %H:%M:%S.%f')
2984
-
2985
- tock = mesgs[-1][1]['tock']
2986
- tockdt = datetime.datetime.fromtimestamp(tock / 1000.0, datetime.UTC)
2987
- tockstr = tockdt.strftime('%Y/%m/%d %H:%M:%S.%f')
2988
-
2989
- await asyncio.sleep(0.01)
2990
- mesgs = await core.stormlist('[ test:str=baz ]')
2991
-
2992
- nodes = await core.nodes(f'splice.list')
2993
- self.len(9, nodes)
2994
-
2995
- nodes = await core.nodes(f'splice.list --mintimestamp {tick}')
2996
- self.len(4, nodes)
2997
-
2998
- nodes = await core.nodes(f'splice.list --mintime "{tickstr}"')
2999
- self.len(4, nodes)
3000
-
3001
- nodes = await core.nodes(f'splice.list --maxtimestamp {tock}')
3002
- self.len(7, nodes)
3003
-
3004
- nodes = await core.nodes(f'splice.list --maxtime "{tockstr}"')
3005
- self.len(7, nodes)
3006
-
3007
- nodes = await core.nodes(f'splice.list --mintimestamp {tick} --maxtimestamp {tock}')
3008
- self.len(2, nodes)
3009
-
3010
- nodes = await core.nodes(f'splice.list --mintime "{tickstr}" --maxtime "{tockstr}"')
3011
- self.len(2, nodes)
3012
-
3013
- await self.asyncraises(s_exc.StormRuntimeError, core.nodes('splice.list --mintime badtime'))
3014
- await self.asyncraises(s_exc.StormRuntimeError, core.nodes('splice.list --maxtime nope'))
3015
-
3016
- visi = await prox.addUser('visi', passwd='secret')
3017
-
3018
- await prox.addUserRule(visi['iden'], (True, ('node', 'add')))
3019
- await prox.addUserRule(visi['iden'], (True, ('node', 'prop', 'set')))
3020
-
3021
- async with core.getLocalProxy(user='visi') as asvisi:
3022
-
3023
- # make sure a normal user only gets their own splices
3024
- nodes = await alist(asvisi.eval("[ test:str=hehe ]"))
3025
-
3026
- nodes = await alist(asvisi.eval("splice.list"))
3027
- self.len(2, nodes)
3028
-
3029
- # should get all splices now as an admin
3030
- await prox.setUserAdmin(visi['iden'], True)
3031
-
3032
- nodes = await alist(asvisi.eval("splice.list"))
3033
- self.len(11, nodes)
3034
-
3035
- msgs = await core.stormlist('splice.undo')
3036
- self.stormIsInWarn('deprecated', msgs)
3037
-
3038
- async def test_storm_spliceundo(self):
3039
-
3040
- self.skip('order is different and this is deprecated')
3041
- async with self.getTestCoreAndProxy() as (core, prox):
3042
-
3043
- await core.addTagProp('risk', ('int', {'min': 0, 'max': 100}), {'doc': 'risk score'})
3044
-
3045
- visi = await prox.addUser('visi', passwd='secret')
3046
-
3047
- await prox.addUserRule(visi['iden'], (True, ('node', 'add')))
3048
- await prox.addUserRule(visi['iden'], (True, ('node', 'prop', 'set')))
3049
- await prox.addUserRule(visi['iden'], (True, ('node', 'tag', 'add')))
3050
-
3051
- async with core.getLocalProxy(user='visi') as asvisi:
3052
-
3053
- nodes = await alist(asvisi.eval("[ test:str=foo ]"))
3054
- await asyncio.sleep(0.01)
3055
-
3056
- mesgs = await alist(asvisi.storm("[ test:str=bar ]"))
3057
- tick = mesgs[0][1]['tick']
3058
- tock = mesgs[-1][1]['tock']
3059
-
3060
- mesgs = await alist(asvisi.storm("test:str=bar [ +#test.tag ]"))
3061
-
3062
- # undo a node add
3063
-
3064
- nodes = await alist(asvisi.eval("test:str=bar"))
3065
- self.len(1, nodes)
3066
-
3067
- # undo adding a node fails without tag:del perms if is it tagged
3068
- q = f'splice.list --mintimestamp {tick} --maxtimestamp {tock} | splice.undo'
3069
- await self.agenraises(s_exc.AuthDeny, asvisi.eval(q))
3070
-
3071
- await prox.addUserRule(visi['iden'], (True, ('node', 'tag', 'del')))
3072
-
3073
- # undo adding a node fails without node:del perms
3074
- q = f'splice.list --mintimestamp {tick} --maxtimestamp {tock} | splice.undo'
3075
- await self.agenraises(s_exc.AuthDeny, asvisi.eval(q))
3076
-
3077
- await prox.addUserRule(visi['iden'], (True, ('node', 'del')))
3078
- nodes = await alist(asvisi.eval(q))
3079
-
3080
- nodes = await alist(asvisi.eval("test:str=bar"))
3081
- self.len(0, nodes)
3082
-
3083
- # undo a node delete
3084
-
3085
- # undo deleting a node fails without node:add perms
3086
- await prox.delUserRule(visi['iden'], (True, ('node', 'add')))
3087
-
3088
- q = 'splice.list | limit 2 | splice.undo'
3089
- await self.agenraises(s_exc.AuthDeny, asvisi.eval(q))
3090
-
3091
- await prox.addUserRule(visi['iden'], (True, ('node', 'add')))
3092
- nodes = await alist(asvisi.eval(q))
3093
-
3094
- nodes = await alist(asvisi.eval("test:str=bar"))
3095
- self.len(1, nodes)
3096
-
3097
- # undo adding a prop
3098
-
3099
- nodes = await alist(asvisi.eval("test:str=foo [ :tick=2000 ]"))
3100
- self.nn(nodes[0][1]['props'].get('tick'))
3101
-
3102
- # undo adding a prop fails without prop:del perms
3103
- q = 'splice.list | limit 1 | splice.undo'
3104
- await self.agenraises(s_exc.AuthDeny, asvisi.eval(q))
3105
-
3106
- await prox.addUserRule(visi['iden'], (True, ('node', 'prop', 'del',)))
3107
- nodes = await alist(asvisi.eval(q))
3108
-
3109
- nodes = await alist(asvisi.eval("test:str=foo"))
3110
- self.none(nodes[0][1]['props'].get('tick'))
3111
-
3112
- # undo updating a prop
3113
-
3114
- nodes = await alist(asvisi.eval("test:str=foo [ :tick=2000 ]"))
3115
- oldv = nodes[0][1]['props']['tick']
3116
- self.nn(oldv)
3117
-
3118
- nodes = await alist(asvisi.eval("test:str=foo [ :tick=3000 ]"))
3119
- self.ne(oldv, nodes[0][1]['props']['tick'])
3120
-
3121
- # undo updating a prop fails without prop:set perms
3122
- await prox.delUserRule(visi['iden'], (True, ('node', 'prop', 'set')))
3123
-
3124
- q = 'splice.list | limit 1 | splice.undo'
3125
- await self.agenraises(s_exc.AuthDeny, asvisi.eval(q))
3126
-
3127
- await prox.addUserRule(visi['iden'], (True, ('node', 'prop', 'set',)))
3128
- nodes = await alist(asvisi.eval(q))
3129
-
3130
- nodes = await alist(asvisi.eval("test:str=foo"))
3131
- self.eq(oldv, nodes[0][1]['props']['tick'])
3132
-
3133
- # undo deleting a prop
3134
-
3135
- nodes = await alist(asvisi.eval("test:str=foo [ -:tick ]"))
3136
- self.none(nodes[0][1]['props'].get('tick'))
3137
-
3138
- # undo deleting a prop fails without prop:set perms
3139
- await prox.delUserRule(visi['iden'], (True, ('node', 'prop', 'set')))
3140
-
3141
- q = 'splice.list | limit 1 | splice.undo'
3142
- await self.agenraises(s_exc.AuthDeny, asvisi.eval(q))
3143
-
3144
- await prox.addUserRule(visi['iden'], (True, ('node', 'prop', 'set')))
3145
- nodes = await alist(asvisi.eval(q))
3146
-
3147
- nodes = await alist(asvisi.eval("test:str=foo"))
3148
- self.eq(oldv, nodes[0][1]['props']['tick'])
3149
-
3150
- # undo adding a tag
3151
-
3152
- nodes = await alist(asvisi.eval("test:str=foo [ +#rep=2000 ]"))
3153
- tagv = nodes[0][1]['tags'].get('rep')
3154
- self.nn(tagv)
3155
-
3156
- # undo adding a tag fails without tag:del perms
3157
- await prox.delUserRule(visi['iden'], (True, ('node', 'tag', 'del',)))
3158
-
3159
- q = 'splice.list | limit 1 | splice.undo'
3160
- await self.agenraises(s_exc.AuthDeny, asvisi.eval(q))
3161
-
3162
- await prox.addUserRule(visi['iden'], (True, ('node', 'tag', 'del',)))
3163
- nodes = await alist(asvisi.eval(q))
3164
-
3165
- nodes = await alist(asvisi.eval("test:str=foo"))
3166
- self.none(nodes[0][1]['tags'].get('rep'))
3167
-
3168
- # undo deleting a tag
3169
-
3170
- # undo deleting a tag fails without tag:add perms
3171
- await prox.delUserRule(visi['iden'], (True, ('node', 'tag', 'add')))
3172
-
3173
- q = 'splice.list | limit 1 | splice.undo'
3174
- await self.agenraises(s_exc.AuthDeny, asvisi.eval(q))
3175
-
3176
- await prox.addUserRule(visi['iden'], (True, ('node', 'tag', 'add')))
3177
- nodes = await alist(asvisi.eval(q))
3178
-
3179
- nodes = await alist(asvisi.eval("test:str=foo"))
3180
- self.eq(tagv, nodes[0][1]['tags'].get('rep'))
3181
-
3182
- # undo updating a tag
3183
- nodes = await alist(asvisi.eval("test:str=foo [ +#rep=2000 ]"))
3184
- oldv = nodes[0][1]['tags'].get('rep')
3185
- nodes = await alist(asvisi.eval("test:str=foo [ +#rep=3000 ]"))
3186
- self.ne(oldv, nodes[0][1]['tags'].get('rep'))
3187
-
3188
- q = 'splice.list | limit 1 | splice.undo'
3189
- await alist(asvisi.eval(q))
3190
-
3191
- nodes = await alist(asvisi.eval("test:str=foo"))
3192
- self.eq(oldv, nodes[0][1]['tags'].get('rep'))
3193
-
3194
- # undo adding a tagprop
3195
-
3196
- nodes = await alist(asvisi.eval("test:str=foo [ +#rep:risk=50 ]"))
3197
- tagv = nodes[0][1]['tagprops']['rep'].get('risk')
3198
- self.nn(tagv)
3199
-
3200
- # undo adding a tagprop fails without tag:del perms
3201
- await prox.delUserRule(visi['iden'], (True, ('node', 'tag', 'del')))
3202
-
3203
- q = 'splice.list | limit 1 | splice.undo'
3204
- await self.agenraises(s_exc.AuthDeny, asvisi.eval(q))
3205
-
3206
- await prox.addUserRule(visi['iden'], (True, ('node', 'tag', 'del')))
3207
- nodes = await alist(asvisi.eval(q))
3208
-
3209
- nodes = await alist(asvisi.eval("test:str=foo"))
3210
- self.none(nodes[0][1]['tagprops'].get('rep'))
3211
-
3212
- # undo deleting a tagprop
3213
-
3214
- # undo deleting a tagprop fails without tag:add perms
3215
- await prox.delUserRule(visi['iden'], (True, ('node', 'tag', 'add')))
3216
-
3217
- q = 'splice.list | limit 1 | splice.undo'
3218
- await self.agenraises(s_exc.AuthDeny, asvisi.eval(q))
3219
-
3220
- await prox.addUserRule(visi['iden'], (True, ('node', 'tag', 'add')))
3221
- nodes = await alist(asvisi.eval(q))
3222
-
3223
- nodes = await alist(asvisi.eval("test:str=foo"))
3224
- self.eq(tagv, nodes[0][1]['tagprops']['rep'].get('risk'))
3225
-
3226
- # undo updating a tagprop
3227
-
3228
- nodes = await alist(asvisi.eval("test:str=foo [ +#rep:risk=0 ]"))
3229
- self.ne(tagv, nodes[0][1]['tagprops']['rep'].get('risk'))
3230
-
3231
- # undo updating a tagprop fails without prop:set perms
3232
- await prox.delUserRule(visi['iden'], (True, ('node', 'tag', 'add')))
3233
-
3234
- q = 'splice.list | limit 1 | splice.undo'
3235
- await self.agenraises(s_exc.AuthDeny, asvisi.eval(q))
3236
-
3237
- await prox.addUserRule(visi['iden'], (True, ('node', 'tag', 'add')))
3238
- nodes = await alist(asvisi.eval(q))
3239
-
3240
- nodes = await alist(asvisi.eval("test:str=foo"))
3241
- self.eq(tagv, nodes[0][1]['tagprops']['rep'].get('risk'))
3242
-
3243
- # sending nodes of form other than syn:splice doesn't work
3244
- q = 'test:str | limit 1 | splice.undo'
3245
- await self.agenraises(s_exc.StormRuntimeError, asvisi.eval(q))
3246
-
3247
- # must be admin to use --force for node deletion
3248
- await alist(asvisi.eval('[ test:cycle0=foo :cycle1=bar ]'))
3249
- await alist(asvisi.eval('[ test:cycle1=bar :cycle0=foo ]'))
3250
-
3251
- nodes = await alist(asvisi.eval("test:cycle0"))
3252
- self.len(1, nodes)
3253
-
3254
- q = 'splice.list | +:type="node:add" +:form="test:cycle0" | limit 1 | splice.undo'
3255
- await self.agenraises(s_exc.CantDelNode, asvisi.eval(q))
3256
-
3257
- q = 'splice.list | +:type="node:add" +:form="test:cycle0" | limit 1 | splice.undo --force'
3258
- await self.agenraises(s_exc.AuthDeny, asvisi.eval(q))
3259
-
3260
- await prox.setUserAdmin(visi['iden'], True)
3261
-
3262
- nodes = await alist(asvisi.eval(q))
3263
- nodes = await alist(asvisi.eval("test:cycle0"))
3264
- self.len(0, nodes)
3265
-
3266
2973
  async def test_storm_argv_parser(self):
3267
2974
 
3268
2975
  pars = s_storm.Parser(prog='hehe')
@@ -4353,12 +4060,12 @@ class StormTest(s_t_utils.SynTest):
4353
4060
  await core.nodes('runas visi { [ inet:fqdn=bar.com ] }')
4354
4061
 
4355
4062
  items = await alist(core.syncLayersEvents({}, wait=False))
4356
- self.len(4, [item for item in items if item[-1]['user'] == visi.iden])
4063
+ self.len(2, [item for item in items if item[-1]['user'] == visi.iden])
4357
4064
 
4358
4065
  await core.nodes(f'runas {visi.iden} {{ [ inet:fqdn=baz.com ] }}')
4359
4066
 
4360
4067
  items = await alist(core.syncLayersEvents({}, wait=False))
4361
- self.len(8, [item for item in items if item[-1]['user'] == visi.iden])
4068
+ self.len(4, [item for item in items if item[-1]['user'] == visi.iden])
4362
4069
 
4363
4070
  q = 'inet:fqdn $n=$node runas visi { yield $n [ +#atag ] }'
4364
4071
  await self.asyncraises(s_exc.AuthDeny, core.nodes(q))
@@ -0,0 +1,21 @@
1
+ import synapse.exc as s_exc
2
+
3
+ import synapse.tests.utils as s_test
4
+
5
+ class StormLibGisTest(s_test.SynTest):
6
+
7
+ async def test_stormlib_gis_bbox(self):
8
+
9
+ async with self.getTestCore() as core:
10
+
11
+ lbox = await core.callStorm('return($lib.gis.bbox(-2.0783, 51.8994, $lib.cast(geo:dist, 1km)))')
12
+ self.eq(lbox, (-2.0928746526154747,
13
+ -2.0637253473845254,
14
+ 51.890406796362754,
15
+ 51.908393203637246))
16
+
17
+ with self.raises(s_exc.BadArg):
18
+ lbox = await core.callStorm('return($lib.gis.bbox(newp, -2.0783, 1))')
19
+
20
+ with self.raises(s_exc.BadArg):
21
+ lbox = await core.callStorm('return($lib.gis.bbox(51.2, -2.0783, newp))')
@@ -4,57 +4,116 @@ import synapse.tests.utils as s_test
4
4
  import synapse.lib.stormlib.stats as s_stormlib_stats
5
5
 
6
6
  chartnorm = '''
7
- 40 | 5 | ##################################################
8
- 30 | 4 | ########################################
9
- 20 | 3 | ##############################
7
+ 6 | 5 | ##################################################
8
+ 13 | 4 | ########################################
9
+ 3 | 3 | ##############################
10
10
  10 | 2 | ####################
11
11
  0 | 1 | ##########
12
12
  '''.strip()
13
13
 
14
+ chartnorm_byname = '''
15
+ 13 | 4 | ########################################
16
+ 10 | 2 | ####################
17
+ 6 | 5 | ##################################################
18
+ 3 | 3 | ##############################
19
+ 0 | 1 | ##########
20
+ '''.strip()
21
+
14
22
  chartrev = '''
15
23
  0 | 1 | ##########
16
24
  10 | 2 | ####################
17
- 20 | 3 | ##############################
18
- 30 | 4 | ########################################
19
- 40 | 5 | ##################################################
25
+ 3 | 3 | ##############################
26
+ 13 | 4 | ########################################
27
+ 6 | 5 | ##################################################
28
+ '''.strip()
29
+
30
+ chartrev_byname = '''
31
+ 0 | 1 | ##########
32
+ 3 | 3 | ##############################
33
+ 6 | 5 | ##################################################
34
+ 10 | 2 | ####################
35
+ 13 | 4 | ########################################
20
36
  '''.strip()
21
37
 
22
38
  chartsize = '''
23
- 40 | 5 | ##################################################
24
- 30 | 4 | ########################################
25
- 20 | 3 | ##############################
39
+ 6 | 5 | ##################################################
40
+ 13 | 4 | ########################################
41
+ 3 | 3 | ##############################
42
+ '''.strip()
43
+
44
+ chartsize_byname = '''
45
+ 13 | 4 | ########################################
46
+ 10 | 2 | ####################
47
+ 6 | 5 | ##################################################
26
48
  '''.strip()
27
49
 
28
50
  chartsizerev = '''
29
51
  0 | 1 | ##########
30
52
  10 | 2 | ####################
31
- 20 | 3 | ##############################
53
+ 3 | 3 | ##############################
54
+ '''.strip()
55
+
56
+ chartsizerev_byname = '''
57
+ 0 | 1 | ##########
58
+ 3 | 3 | ##############################
59
+ 6 | 5 | ##################################################
32
60
  '''.strip()
33
61
 
34
62
  chartwidth = '''
35
- 40 | 5 | ##########
36
- 30 | 4 | ########
37
- 20 | 3 | ######
63
+ 6 | 5 | ##########
64
+ 13 | 4 | ########
65
+ 3 | 3 | ######
38
66
  10 | 2 | ####
39
67
  0 | 1 | ##
40
68
  '''.strip()
41
69
 
70
+ chartwidth_byname = '''
71
+ 13 | 4 | ########
72
+ 10 | 2 | ####
73
+ 6 | 5 | ##########
74
+ 3 | 3 | ######
75
+ 0 | 1 | ##
76
+ '''.strip()
77
+
42
78
  chartlabelwidth = '''
43
- 4 | 5 | ##################################################
44
- 3 | 4 | ########################################
45
- 2 | 3 | ##############################
79
+ 6 | 5 | ##################################################
80
+ 1 | 4 | ########################################
81
+ 3 | 3 | ##############################
46
82
  1 | 2 | ####################
47
83
  0 | 1 | ##########
48
84
  '''.strip()
49
85
 
86
+ chartlabelwidth_byname = '''
87
+ 1 | 4 | ########################################
88
+ 1 | 2 | ####################
89
+ 6 | 5 | ##################################################
90
+ 3 | 3 | ##############################
91
+ 0 | 1 | ##########
92
+ '''.strip()
93
+
50
94
  chartchar = '''
51
- 40 | 5 | ++++++++++++++++++++++++++++++++++++++++++++++++++
52
- 30 | 4 | ++++++++++++++++++++++++++++++++++++++++
53
- 20 | 3 | ++++++++++++++++++++++++++++++
95
+ 6 | 5 | ++++++++++++++++++++++++++++++++++++++++++++++++++
96
+ 13 | 4 | ++++++++++++++++++++++++++++++++++++++++
97
+ 3 | 3 | ++++++++++++++++++++++++++++++
54
98
  10 | 2 | ++++++++++++++++++++
55
99
  0 | 1 | ++++++++++
56
100
  '''.strip()
57
101
 
102
+ chartchar_byname = '''
103
+ 13 | 4 | ++++++++++++++++++++++++++++++++++++++++
104
+ 10 | 2 | ++++++++++++++++++++
105
+ 6 | 5 | ++++++++++++++++++++++++++++++++++++++++++++++++++
106
+ 3 | 3 | ++++++++++++++++++++++++++++++
107
+ 0 | 1 | ++++++++++
108
+ '''.strip()
109
+
110
+ chartipv4_byname = '''
111
+ 0.0.0.6 | 1 | ##################################################
112
+ 0.0.0.2 | 1 | ##################################################
113
+ 0.0.0.10 | 1 | ##################################################
114
+ 0.0.0.1 | 1 | ##################################################
115
+ '''.strip()
116
+
58
117
 
59
118
  class StatsTest(s_test.SynTest):
60
119
 
@@ -66,7 +125,7 @@ class StatsTest(s_test.SynTest):
66
125
  $i = (0)
67
126
  for $x in $lib.range(5) {
68
127
  for $y in $lib.range(($x + 1)) {
69
- [ inet:ipv4=$i :asn=($x * 10) ]
128
+ [ inet:ipv4=$i :asn=(($x * 10) % 17) ]
70
129
  $i = ($i + 1)
71
130
  }
72
131
  }
@@ -76,27 +135,55 @@ class StatsTest(s_test.SynTest):
76
135
  msgs = await core.stormlist('inet:ipv4 | stats.countby :asn')
77
136
  self.stormIsInPrint(chartnorm, msgs)
78
137
 
138
+ msgs = await core.stormlist('inet:ipv4 | stats.countby :asn --by-name')
139
+ self.stormIsInPrint(chartnorm_byname, msgs)
140
+
79
141
  msgs = await core.stormlist('inet:ipv4 -> inet:asn | stats.countby')
80
142
  self.stormIsInPrint(chartnorm, msgs)
81
143
 
144
+ msgs = await core.stormlist('inet:ipv4 -> inet:asn | stats.countby --by-name')
145
+ self.stormIsInPrint(chartnorm_byname, msgs)
146
+
82
147
  msgs = await core.stormlist('inet:ipv4 | stats.countby :asn --reverse')
83
148
  self.stormIsInPrint(chartrev, msgs)
84
149
 
150
+ msgs = await core.stormlist('inet:ipv4 | stats.countby :asn --reverse --by-name')
151
+ self.stormIsInPrint(chartrev_byname, msgs)
152
+
85
153
  msgs = await core.stormlist('inet:ipv4 | stats.countby :asn --size 3')
86
154
  self.stormIsInPrint(chartsize, msgs)
87
155
 
156
+ msgs = await core.stormlist('inet:ipv4 | stats.countby :asn --size 3 --by-name')
157
+ self.stormIsInPrint(chartsize_byname, msgs)
158
+
88
159
  msgs = await core.stormlist('inet:ipv4 | stats.countby :asn --size 3 --reverse')
89
160
  self.stormIsInPrint(chartsizerev, msgs)
90
161
 
162
+ msgs = await core.stormlist('inet:ipv4 | stats.countby :asn --size 3 --reverse --by-name')
163
+ self.stormIsInPrint(chartsizerev_byname, msgs)
164
+
91
165
  msgs = await core.stormlist(f'inet:ipv4 | stats.countby :asn --bar-width 10')
92
166
  self.stormIsInPrint(chartwidth, msgs)
93
167
 
168
+ msgs = await core.stormlist(f'inet:ipv4 | stats.countby :asn --bar-width 10 --by-name')
169
+ self.stormIsInPrint(chartwidth_byname, msgs)
170
+
94
171
  msgs = await core.stormlist(f'inet:ipv4 | stats.countby :asn --label-max-width 1')
95
172
  self.stormIsInPrint(chartlabelwidth, msgs)
96
173
 
174
+ msgs = await core.stormlist(f'inet:ipv4 | stats.countby :asn --label-max-width 1 --by-name')
175
+ self.stormIsInPrint(chartlabelwidth_byname, msgs)
176
+
97
177
  msgs = await core.stormlist('inet:ipv4 | stats.countby :asn --char "+"')
98
178
  self.stormIsInPrint(chartchar, msgs)
99
179
 
180
+ msgs = await core.stormlist('inet:ipv4 | stats.countby :asn --char "+" --by-name')
181
+ self.stormIsInPrint(chartchar_byname, msgs)
182
+
183
+ msgs = await core.stormlist(
184
+ 'inet:ipv4=0.0.0.1 inet:ipv4=0.0.0.2 inet:ipv4=0.0.0.6 inet:ipv4=0.0.0.10 | stats.countby --by-name')
185
+ self.stormIsInPrint(chartipv4_byname, msgs)
186
+
100
187
  msgs = await core.stormlist('stats.countby foo')
101
188
  self.stormIsInPrint('No values to display!', msgs)
102
189
 
@@ -36,3 +36,28 @@ class LibStormTest(s_test.SynTest):
36
36
 
37
37
  with self.raises(s_exc.IsReadOnly):
38
38
  await core.callStorm('$lib.storm.eval( "{$lib.auth.users.add(readonly)}" )', opts={'readonly': True})
39
+
40
+ with self.getLoggerStream('synapse.storm') as stream:
41
+ q = '''{
42
+ $lib.log.info(hehe)
43
+ [test:str=omg]
44
+ $lib.log.info($node)
45
+ fini { return(wow) }
46
+ }
47
+ '''
48
+
49
+ core.stormlog = True
50
+ opts = {'vars': {'q': q}}
51
+ ret = await core.callStorm('return( $lib.storm.eval($q) )', opts=opts)
52
+ self.eq(ret, 'wow')
53
+ self.len(1, await core.nodes('test:str=omg'))
54
+
55
+ # Check that we saw the logs
56
+ stream.seek(0)
57
+ data = stream.read()
58
+
59
+ mesg = 'Executing storm query {return( $lib.storm.eval($q) )} as [root]'
60
+ self.isin(mesg, data)
61
+
62
+ mesg = f'Executing storm query via $lib.storm.eval() {{{q}}} as [root]'
63
+ self.isin(mesg, data)