synapse 2.186.0__py311-none-any.whl → 2.187.1__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.
- synapse/cortex.py +2 -2
- synapse/lib/hive.py +1 -1
- synapse/lib/lmdbslab.py +2 -0
- synapse/lib/modelrev.py +794 -11
- synapse/lib/spooled.py +28 -4
- synapse/lib/storm.py +7 -0
- synapse/lib/stormlib/model.py +320 -250
- synapse/lib/stormtypes.py +36 -10
- synapse/lib/version.py +2 -2
- synapse/models/infotech.py +49 -22
- synapse/tests/test_lib_cell.py +1 -0
- synapse/tests/test_lib_lmdbslab.py +30 -0
- synapse/tests/test_lib_modelrev.py +918 -379
- synapse/tests/test_lib_spooled.py +36 -0
- synapse/tests/test_lib_stormlib_model.py +0 -270
- synapse/tests/test_lib_stormtypes.py +11 -0
- synapse/tests/test_model_infotech.py +14 -11
- synapse/tests/test_utils_getrefs.py +36 -29
- synapse/tools/changelog.py +11 -3
- synapse/utils/getrefs.py +18 -5
- {synapse-2.186.0.dist-info → synapse-2.187.1.dist-info}/METADATA +4 -3
- {synapse-2.186.0.dist-info → synapse-2.187.1.dist-info}/RECORD +25 -28
- {synapse-2.186.0.dist-info → synapse-2.187.1.dist-info}/WHEEL +1 -1
- synapse/assets/__init__.py +0 -35
- synapse/assets/storm/migrations/model-0.2.28.storm +0 -355
- synapse/tests/test_assets.py +0 -25
- {synapse-2.186.0.dist-info → synapse-2.187.1.dist-info/licenses}/LICENSE +0 -0
- {synapse-2.186.0.dist-info → synapse-2.187.1.dist-info}/top_level.txt +0 -0
synapse/lib/stormtypes.py
CHANGED
|
@@ -3816,13 +3816,13 @@ class Queue(StormType):
|
|
|
3816
3816
|
'args': (
|
|
3817
3817
|
{'name': 'item', 'type': 'prim', 'desc': 'The item being put into the queue.', },
|
|
3818
3818
|
),
|
|
3819
|
-
'returns': {'type': '
|
|
3819
|
+
'returns': {'type': 'int', 'desc': 'The queue offset of the item.'}}},
|
|
3820
3820
|
{'name': 'puts', 'desc': 'Put multiple items into the Queue.',
|
|
3821
3821
|
'type': {'type': 'function', '_funcname': '_methQueuePuts',
|
|
3822
3822
|
'args': (
|
|
3823
3823
|
{'name': 'items', 'type': 'list', 'desc': 'The items to put into the Queue.', },
|
|
3824
3824
|
),
|
|
3825
|
-
'returns': {'type': '
|
|
3825
|
+
'returns': {'type': 'int', 'desc': 'The queue offset of the first item.'}}},
|
|
3826
3826
|
{'name': 'gets', 'desc': 'Get multiple items from the Queue as a iterator.',
|
|
3827
3827
|
'type': {'type': 'function', '_funcname': '_methQueueGets',
|
|
3828
3828
|
'args': (
|
|
@@ -6130,14 +6130,14 @@ class Node(Prim):
|
|
|
6130
6130
|
'type': {'type': 'function', '_funcname': '_methNodeAddEdge',
|
|
6131
6131
|
'args': (
|
|
6132
6132
|
{'name': 'verb', 'type': 'str', 'desc': 'The edge verb to add.'},
|
|
6133
|
-
{'name': 'iden', 'type': 'str', 'desc': 'The node
|
|
6133
|
+
{'name': 'iden', 'type': 'str', 'desc': 'The node iden of the destination node.'},
|
|
6134
6134
|
),
|
|
6135
6135
|
'returns': {'type': 'null', }}},
|
|
6136
6136
|
{'name': 'delEdge', 'desc': 'Remove a light-weight edge.',
|
|
6137
6137
|
'type': {'type': 'function', '_funcname': '_methNodeDelEdge',
|
|
6138
6138
|
'args': (
|
|
6139
6139
|
{'name': 'verb', 'type': 'str', 'desc': 'The edge verb to remove.'},
|
|
6140
|
-
{'name': 'iden', 'type': 'str', 'desc': 'The node
|
|
6140
|
+
{'name': 'iden', 'type': 'str', 'desc': 'The node iden of the destination node to remove.'},
|
|
6141
6141
|
),
|
|
6142
6142
|
'returns': {'type': 'null', }}},
|
|
6143
6143
|
{'name': 'globtags', 'desc': 'Get a list of the tag components from a Node which match a tag glob expression.',
|
|
@@ -6827,11 +6827,11 @@ class Layer(Prim):
|
|
|
6827
6827
|
'returns': {'name': 'Yields', 'type': 'list',
|
|
6828
6828
|
'desc': 'Yields messages describing any index inconsistencies.', }}},
|
|
6829
6829
|
{'name': 'getStorNode', 'desc': '''
|
|
6830
|
-
Retrieve the raw storage node for the specified node
|
|
6830
|
+
Retrieve the raw storage node for the specified node iden.
|
|
6831
6831
|
''',
|
|
6832
6832
|
'type': {'type': 'function', '_funcname': 'getStorNode',
|
|
6833
6833
|
'args': (
|
|
6834
|
-
{'name': 'nodeid', 'type': 'str', 'desc': 'The hex string of the node
|
|
6834
|
+
{'name': 'nodeid', 'type': 'str', 'desc': 'The hex string of the node iden.'},
|
|
6835
6835
|
),
|
|
6836
6836
|
'returns': {'type': 'dict', 'desc': 'The storage node dictionary.', }}},
|
|
6837
6837
|
{'name': 'liftByProp', 'desc': '''
|
|
@@ -6897,7 +6897,7 @@ class Layer(Prim):
|
|
|
6897
6897
|
'desc': 'Yields (<n1iden>, <verb>, <n2iden>) tuples', }}},
|
|
6898
6898
|
|
|
6899
6899
|
{'name': 'getEdgesByN1', 'desc': '''
|
|
6900
|
-
Yield (verb, n2iden) tuples for any light edges in the layer for the source node
|
|
6900
|
+
Yield (verb, n2iden) tuples for any light edges in the layer for the source node iden.
|
|
6901
6901
|
|
|
6902
6902
|
Example:
|
|
6903
6903
|
Iterate the N1 edges for ``$node``::
|
|
@@ -6909,13 +6909,13 @@ class Layer(Prim):
|
|
|
6909
6909
|
''',
|
|
6910
6910
|
'type': {'type': 'function', '_funcname': 'getEdgesByN1',
|
|
6911
6911
|
'args': (
|
|
6912
|
-
{'name': 'nodeid', 'type': 'str', 'desc': 'The hex string of the node
|
|
6912
|
+
{'name': 'nodeid', 'type': 'str', 'desc': 'The hex string of the node iden.'},
|
|
6913
6913
|
),
|
|
6914
6914
|
'returns': {'name': 'Yields', 'type': 'list',
|
|
6915
6915
|
'desc': 'Yields (<verb>, <n2iden>) tuples', }}},
|
|
6916
6916
|
|
|
6917
6917
|
{'name': 'getEdgesByN2', 'desc': '''
|
|
6918
|
-
Yield (verb, n1iden) tuples for any light edges in the layer for the target node
|
|
6918
|
+
Yield (verb, n1iden) tuples for any light edges in the layer for the target node iden.
|
|
6919
6919
|
|
|
6920
6920
|
Example:
|
|
6921
6921
|
Iterate the N2 edges for ``$node``::
|
|
@@ -6926,10 +6926,26 @@ class Layer(Prim):
|
|
|
6926
6926
|
''',
|
|
6927
6927
|
'type': {'type': 'function', '_funcname': 'getEdgesByN2',
|
|
6928
6928
|
'args': (
|
|
6929
|
-
{'name': 'nodeid', 'type': 'str', 'desc': 'The hex string of the node
|
|
6929
|
+
{'name': 'nodeid', 'type': 'str', 'desc': 'The hex string of the node iden.'},
|
|
6930
6930
|
),
|
|
6931
6931
|
'returns': {'name': 'Yields', 'type': 'list',
|
|
6932
6932
|
'desc': 'Yields (<verb>, <n1iden>) tuples', }}},
|
|
6933
|
+
{'name': 'getNodeData', 'desc': '''
|
|
6934
|
+
Yield (name, valu) tuples for any node data in the layer for the target node iden.
|
|
6935
|
+
|
|
6936
|
+
Example:
|
|
6937
|
+
Iterate the node data for ``$node``::
|
|
6938
|
+
|
|
6939
|
+
for ($name, $valu) in $layer.getNodeData($node.iden()) {
|
|
6940
|
+
$lib.print(`{$name} = {$valu}`)
|
|
6941
|
+
}
|
|
6942
|
+
''',
|
|
6943
|
+
'type': {'type': 'function', '_funcname': 'getNodeData',
|
|
6944
|
+
'args': (
|
|
6945
|
+
{'name': 'nodeid', 'type': 'str', 'desc': 'The hex string of the node iden.'},
|
|
6946
|
+
),
|
|
6947
|
+
'returns': {'name': 'Yields', 'type': 'list',
|
|
6948
|
+
'desc': 'Yields (<name>, <valu>) tuples', }}},
|
|
6933
6949
|
)
|
|
6934
6950
|
_storm_typename = 'layer'
|
|
6935
6951
|
_ismutable = False
|
|
@@ -6986,6 +7002,7 @@ class Layer(Prim):
|
|
|
6986
7002
|
'getStorNodesByForm': self.getStorNodesByForm,
|
|
6987
7003
|
'getEdgesByN1': self.getEdgesByN1,
|
|
6988
7004
|
'getEdgesByN2': self.getEdgesByN2,
|
|
7005
|
+
'getNodeData': self.getNodeData,
|
|
6989
7006
|
'getMirrorStatus': self.getMirrorStatus,
|
|
6990
7007
|
}
|
|
6991
7008
|
|
|
@@ -7355,6 +7372,15 @@ class Layer(Prim):
|
|
|
7355
7372
|
async for item in layr.iterNodeEdgesN2(s_common.uhex(nodeid)):
|
|
7356
7373
|
yield item
|
|
7357
7374
|
|
|
7375
|
+
@stormfunc(readonly=True)
|
|
7376
|
+
async def getNodeData(self, nodeid):
|
|
7377
|
+
nodeid = await tostr(nodeid)
|
|
7378
|
+
layriden = self.valu.get('iden')
|
|
7379
|
+
await self.runt.reqUserCanReadLayer(layriden)
|
|
7380
|
+
layr = self.runt.snap.core.getLayer(layriden)
|
|
7381
|
+
async for item in layr.iterNodeData(s_common.uhex(nodeid)):
|
|
7382
|
+
yield item
|
|
7383
|
+
|
|
7358
7384
|
@stormfunc(readonly=True)
|
|
7359
7385
|
async def _methLayerGet(self, name, defv=None):
|
|
7360
7386
|
return self.valu.get(name, defv)
|
synapse/lib/version.py
CHANGED
|
@@ -223,6 +223,6 @@ def reqVersion(valu, reqver,
|
|
|
223
223
|
##############################################################################
|
|
224
224
|
# The following are touched during the release process by bumpversion.
|
|
225
225
|
# Do not modify these directly.
|
|
226
|
-
version = (2,
|
|
226
|
+
version = (2, 187, 1)
|
|
227
227
|
verstring = '.'.join([str(x) for x in version])
|
|
228
|
-
commit = '
|
|
228
|
+
commit = 'a75f7b990f6350f9d631f1f92ea5063542458aad'
|
synapse/models/infotech.py
CHANGED
|
@@ -18,10 +18,10 @@ import synapse.lib.version as s_version
|
|
|
18
18
|
|
|
19
19
|
logger = logging.getLogger(__name__)
|
|
20
20
|
|
|
21
|
-
# This is the regular expression pattern for
|
|
21
|
+
# This is the regular expression pattern for CPE 2.2. It's kind of a hybrid
|
|
22
22
|
# between compatible binding and preferred binding. Differences are here:
|
|
23
23
|
# - Use only the list of percent encoded values specified by preferred binding.
|
|
24
|
-
# This is to ensure it converts properly to
|
|
24
|
+
# This is to ensure it converts properly to CPE 2.3.
|
|
25
25
|
# - Add tilde (~) to the UNRESERVED list which removes the need to specify the
|
|
26
26
|
# PACKED encoding specifically.
|
|
27
27
|
ALPHA = '[A-Za-z]'
|
|
@@ -60,6 +60,14 @@ COMPONENT_LIST = f'''
|
|
|
60
60
|
cpe22_regex = regex.compile(f'cpe:/{COMPONENT_LIST}', regex.VERBOSE | regex.IGNORECASE)
|
|
61
61
|
cpe23_regex = regex.compile(s_scrape._cpe23_regex, regex.VERBOSE | regex.IGNORECASE)
|
|
62
62
|
|
|
63
|
+
def isValidCpe22(text):
|
|
64
|
+
rgx = cpe22_regex.fullmatch(text)
|
|
65
|
+
return rgx is not None
|
|
66
|
+
|
|
67
|
+
def isValidCpe23(text):
|
|
68
|
+
rgx = cpe23_regex.fullmatch(text)
|
|
69
|
+
return rgx is not None
|
|
70
|
+
|
|
63
71
|
def cpesplit(text):
|
|
64
72
|
part = ''
|
|
65
73
|
parts = []
|
|
@@ -251,9 +259,20 @@ class Cpe22Str(s_types.Str):
|
|
|
251
259
|
def _normPyStr(self, valu):
|
|
252
260
|
|
|
253
261
|
text = valu.lower()
|
|
262
|
+
|
|
254
263
|
if text.startswith('cpe:/'):
|
|
264
|
+
|
|
265
|
+
if not isValidCpe22(text):
|
|
266
|
+
mesg = 'CPE 2.2 string appears to be invalid.'
|
|
267
|
+
raise s_exc.BadTypeValu(mesg=mesg, valu=valu)
|
|
268
|
+
|
|
255
269
|
parts = chopCpe22(text)
|
|
256
270
|
elif text.startswith('cpe:2.3:'):
|
|
271
|
+
|
|
272
|
+
if not isValidCpe23(text):
|
|
273
|
+
mesg = 'CPE 2.3 string appears to be invalid.'
|
|
274
|
+
raise s_exc.BadTypeValu(mesg=mesg, valu=valu)
|
|
275
|
+
|
|
257
276
|
parts = cpesplit(text[8:])
|
|
258
277
|
else:
|
|
259
278
|
mesg = 'CPE 2.2 string is expected to start with "cpe:/"'
|
|
@@ -261,8 +280,7 @@ class Cpe22Str(s_types.Str):
|
|
|
261
280
|
|
|
262
281
|
v2_2 = zipCpe22(parts)
|
|
263
282
|
|
|
264
|
-
|
|
265
|
-
if rgx is None or rgx.group() != v2_2:
|
|
283
|
+
if not isValidCpe22(v2_2): # pragma: no cover
|
|
266
284
|
mesg = 'CPE 2.2 string appears to be invalid.'
|
|
267
285
|
raise s_exc.BadTypeValu(mesg=mesg, valu=valu)
|
|
268
286
|
|
|
@@ -330,6 +348,12 @@ class Cpe23Str(s_types.Str):
|
|
|
330
348
|
def _normPyStr(self, valu):
|
|
331
349
|
text = valu.lower()
|
|
332
350
|
if text.startswith('cpe:2.3:'):
|
|
351
|
+
|
|
352
|
+
# Validate the CPE 2.3 string immediately
|
|
353
|
+
if not isValidCpe23(text):
|
|
354
|
+
mesg = 'CPE 2.3 string appears to be invalid.'
|
|
355
|
+
raise s_exc.BadTypeValu(mesg=mesg, valu=valu)
|
|
356
|
+
|
|
333
357
|
parts = cpesplit(text[8:])
|
|
334
358
|
if len(parts) > 11:
|
|
335
359
|
mesg = f'CPE 2.3 string has {len(parts)} fields, expected up to 11.'
|
|
@@ -346,6 +370,10 @@ class Cpe23Str(s_types.Str):
|
|
|
346
370
|
v2_2[idx] = ''
|
|
347
371
|
continue
|
|
348
372
|
|
|
373
|
+
if idx in (PART_IDX_PART, PART_IDX_LANG) and part == '-':
|
|
374
|
+
v2_2[idx] = ''
|
|
375
|
+
continue
|
|
376
|
+
|
|
349
377
|
part = fsb_unescape(part)
|
|
350
378
|
v2_2[idx] = uri_quote(part)
|
|
351
379
|
|
|
@@ -357,12 +385,22 @@ class Cpe23Str(s_types.Str):
|
|
|
357
385
|
v2_2[PART_IDX_OTHER]
|
|
358
386
|
)
|
|
359
387
|
|
|
360
|
-
v2_2 = v2_2[:7]
|
|
388
|
+
v2_2 = zipCpe22(v2_2[:7])
|
|
389
|
+
|
|
390
|
+
# Now validate the downconvert
|
|
391
|
+
if not isValidCpe22(v2_2): # pragma: no cover
|
|
392
|
+
mesg = 'Invalid CPE 2.3 to CPE 2.2 conversion.'
|
|
393
|
+
raise s_exc.BadTypeValu(mesg=mesg, valu=valu, v2_2=v2_2)
|
|
361
394
|
|
|
362
395
|
parts = [fsb_unescape(k) for k in parts]
|
|
363
396
|
|
|
364
397
|
elif text.startswith('cpe:/'):
|
|
365
398
|
|
|
399
|
+
# Validate the CPE 2.2 string immediately
|
|
400
|
+
if not isValidCpe22(text):
|
|
401
|
+
mesg = 'CPE 2.2 string appears to be invalid.'
|
|
402
|
+
raise s_exc.BadTypeValu(mesg=mesg, valu=valu)
|
|
403
|
+
|
|
366
404
|
v2_2 = text
|
|
367
405
|
# automatically normalize CPE 2.2 format to CPE 2.3
|
|
368
406
|
parts = chopCpe22(text)
|
|
@@ -408,24 +446,15 @@ class Cpe23Str(s_types.Str):
|
|
|
408
446
|
|
|
409
447
|
v2_3 = 'cpe:2.3:' + ':'.join(escaped)
|
|
410
448
|
|
|
449
|
+
# Now validate the upconvert
|
|
450
|
+
if not isValidCpe23(v2_3): # pragma: no cover
|
|
451
|
+
mesg = 'Invalid CPE 2.2 to CPE 2.3 conversion.'
|
|
452
|
+
raise s_exc.BadTypeValu(mesg=mesg, valu=valu, v2_3=v2_3)
|
|
453
|
+
|
|
411
454
|
else:
|
|
412
455
|
mesg = 'CPE 2.3 string is expected to start with "cpe:2.3:"'
|
|
413
456
|
raise s_exc.BadTypeValu(valu=valu, mesg=mesg)
|
|
414
457
|
|
|
415
|
-
rgx = cpe23_regex.match(v2_3)
|
|
416
|
-
if rgx is None or rgx.group() != v2_3:
|
|
417
|
-
mesg = 'CPE 2.3 string appears to be invalid.'
|
|
418
|
-
raise s_exc.BadTypeValu(mesg=mesg, valu=valu)
|
|
419
|
-
|
|
420
|
-
if isinstance(v2_2, list):
|
|
421
|
-
cpe22 = zipCpe22(v2_2)
|
|
422
|
-
else:
|
|
423
|
-
cpe22 = v2_2
|
|
424
|
-
|
|
425
|
-
rgx = cpe22_regex.match(cpe22)
|
|
426
|
-
if rgx is None or rgx.group() != cpe22:
|
|
427
|
-
v2_2 = None
|
|
428
|
-
|
|
429
458
|
subs = {
|
|
430
459
|
'part': parts[PART_IDX_PART],
|
|
431
460
|
'vendor': parts[PART_IDX_VENDOR],
|
|
@@ -438,11 +467,9 @@ class Cpe23Str(s_types.Str):
|
|
|
438
467
|
'target_sw': parts[PART_IDX_TARGET_SW],
|
|
439
468
|
'target_hw': parts[PART_IDX_TARGET_HW],
|
|
440
469
|
'other': parts[PART_IDX_OTHER],
|
|
470
|
+
'v2_2': v2_2,
|
|
441
471
|
}
|
|
442
472
|
|
|
443
|
-
if v2_2 is not None:
|
|
444
|
-
subs['v2_2'] = v2_2
|
|
445
|
-
|
|
446
473
|
return v2_3, {'subs': subs}
|
|
447
474
|
|
|
448
475
|
class SemVer(s_types.Int):
|
synapse/tests/test_lib_cell.py
CHANGED
|
@@ -3019,6 +3019,7 @@ class CellTest(s_t_utils.SynTest):
|
|
|
3019
3019
|
self.eq(node.get('._woot'), 5)
|
|
3020
3020
|
self.nn(node.getTagProp('test', 'score'), 6)
|
|
3021
3021
|
|
|
3022
|
+
self.maxDiff = None
|
|
3022
3023
|
roles = s_t_utils.deguidify('[{"type": "role", "iden": "e1ef725990aa62ae3c4b98be8736d89f", "name": "all", "rules": [], "authgates": {"46cfde2c1682566602860f8df7d0cc83": {"rules": [[true, ["layer", "read"]]]}, "4d50eb257549436414643a71e057091a": {"rules": [[true, ["view", "read"]]]}}}]')
|
|
3023
3024
|
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}}}]')
|
|
3024
3025
|
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": []}]')
|
|
@@ -11,6 +11,7 @@ from unittest.mock import patch
|
|
|
11
11
|
|
|
12
12
|
import synapse.lib.base as s_base
|
|
13
13
|
import synapse.lib.const as s_const
|
|
14
|
+
import synapse.lib.msgpack as s_msgpack
|
|
14
15
|
import synapse.lib.lmdbslab as s_lmdbslab
|
|
15
16
|
import synapse.lib.thisplat as s_thisplat
|
|
16
17
|
|
|
@@ -1597,6 +1598,35 @@ class LmdbSlabTest(s_t_utils.SynTest):
|
|
|
1597
1598
|
subkv2 = subkv1.getSubKeyVal('pref2')
|
|
1598
1599
|
self.eq(list(subkv2.keys()), ['wow'])
|
|
1599
1600
|
|
|
1601
|
+
async def test_lmdbslab_scan_grow(self):
|
|
1602
|
+
with self.getTestDir() as dirn:
|
|
1603
|
+
|
|
1604
|
+
path = os.path.join(dirn, 'test.lmdb')
|
|
1605
|
+
|
|
1606
|
+
mapsize = s_const.kibibyte * 32
|
|
1607
|
+
async with await s_lmdbslab.Slab.anit(path, map_size=mapsize) as slab:
|
|
1608
|
+
|
|
1609
|
+
self.eq(slab.mapsize, mapsize)
|
|
1610
|
+
|
|
1611
|
+
def slabset(key, valu):
|
|
1612
|
+
slab.replace(s_msgpack.en(key), s_msgpack.en(valu))
|
|
1613
|
+
|
|
1614
|
+
def slabitems():
|
|
1615
|
+
for lkey, lval in slab.scanByFull():
|
|
1616
|
+
yield s_msgpack.un(lkey), s_msgpack.un(lval)
|
|
1617
|
+
|
|
1618
|
+
slabset('one', [1, 2, 3])
|
|
1619
|
+
slabset('two', [2, 3, 4])
|
|
1620
|
+
|
|
1621
|
+
seen = set()
|
|
1622
|
+
for key, valu in slabitems():
|
|
1623
|
+
self.notin(key, seen)
|
|
1624
|
+
seen.add(key)
|
|
1625
|
+
|
|
1626
|
+
valu += ('A' * mapsize,)
|
|
1627
|
+
slabset(key, valu)
|
|
1628
|
+
|
|
1629
|
+
self.gt(slab.mapsize, mapsize)
|
|
1600
1630
|
|
|
1601
1631
|
class LmdbSlabMemLockTest(s_t_utils.SynTest):
|
|
1602
1632
|
|