synapse 2.177.0__py311-none-any.whl → 2.179.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.
- synapse/cortex.py +170 -31
- synapse/datamodel.py +47 -1
- synapse/exc.py +1 -0
- synapse/lib/aha.py +362 -88
- synapse/lib/ast.py +26 -22
- synapse/lib/base.py +39 -12
- synapse/lib/cell.py +315 -119
- synapse/lib/config.py +15 -11
- synapse/lib/coro.py +27 -0
- synapse/lib/drive.py +551 -0
- synapse/lib/layer.py +0 -5
- synapse/lib/link.py +1 -1
- synapse/lib/lmdbslab.py +3 -3
- synapse/lib/nexus.py +24 -12
- synapse/lib/schemas.py +39 -0
- synapse/lib/snap.py +17 -7
- synapse/lib/storm.py +3 -1
- synapse/lib/stormhttp.py +1 -0
- synapse/lib/stormlib/imap.py +6 -2
- synapse/lib/stormlib/modelext.py +29 -3
- synapse/lib/stormlib/smtp.py +12 -2
- synapse/lib/stormlib/stix.py +40 -17
- synapse/lib/stormlib/vault.py +2 -2
- synapse/lib/stormtypes.py +1 -1
- synapse/lib/types.py +9 -0
- synapse/lib/version.py +2 -2
- synapse/lookup/pe.py +303 -38
- synapse/models/dns.py +24 -1
- synapse/models/geospace.py +4 -1
- synapse/models/infotech.py +26 -1
- synapse/telepath.py +32 -17
- synapse/tests/files/aha/certs/cas/synapse.crt +28 -0
- synapse/tests/files/aha/certs/cas/synapse.key +51 -0
- synapse/tests/files/aha/certs/hosts/00.aha.loop.vertex.link.crt +30 -0
- synapse/tests/files/aha/certs/hosts/00.aha.loop.vertex.link.key +51 -0
- synapse/tests/files/aha/certs/users/root@synapse.crt +29 -0
- synapse/tests/files/aha/certs/users/root@synapse.key +51 -0
- synapse/tests/files/rstorm/testsvc.py +1 -1
- synapse/tests/test_axon.py +1 -1
- synapse/tests/test_cortex.py +67 -60
- synapse/tests/test_lib_agenda.py +3 -3
- synapse/tests/test_lib_aha.py +353 -490
- synapse/tests/test_lib_base.py +20 -0
- synapse/tests/test_lib_cell.py +273 -22
- synapse/tests/test_lib_config.py +4 -3
- synapse/tests/test_lib_coro.py +12 -0
- synapse/tests/test_lib_nexus.py +8 -0
- synapse/tests/test_lib_stormhttp.py +40 -0
- synapse/tests/test_lib_stormlib_aha.py +35 -35
- synapse/tests/test_lib_stormlib_cell.py +4 -15
- synapse/tests/test_lib_stormlib_imap.py +14 -3
- synapse/tests/test_lib_stormlib_modelext.py +55 -3
- synapse/tests/test_lib_stormlib_smtp.py +51 -0
- synapse/tests/test_lib_stormlib_stix.py +15 -0
- synapse/tests/test_lib_stormlib_vault.py +11 -1
- synapse/tests/test_lib_stormtypes.py +5 -0
- synapse/tests/test_lib_types.py +9 -0
- synapse/tests/test_model_dns.py +8 -0
- synapse/tests/test_model_geospace.py +3 -1
- synapse/tests/test_model_infotech.py +47 -0
- synapse/tests/test_model_syn.py +11 -0
- synapse/tests/test_tools_aha.py +78 -101
- synapse/tests/test_utils_stormcov.py +1 -1
- synapse/tests/utils.py +86 -120
- synapse/tools/aha/clone.py +50 -0
- synapse/tools/aha/enroll.py +2 -1
- synapse/tools/backup.py +2 -2
- synapse/tools/changelog.py +31 -1
- {synapse-2.177.0.dist-info → synapse-2.179.0.dist-info}/METADATA +48 -48
- {synapse-2.177.0.dist-info → synapse-2.179.0.dist-info}/RECORD +73 -65
- {synapse-2.177.0.dist-info → synapse-2.179.0.dist-info}/WHEEL +1 -1
- {synapse-2.177.0.dist-info → synapse-2.179.0.dist-info}/LICENSE +0 -0
- {synapse-2.177.0.dist-info → synapse-2.179.0.dist-info}/top_level.txt +0 -0
synapse/tests/test_lib_base.py
CHANGED
|
@@ -60,6 +60,21 @@ class BaseTest(s_t_utils.SynTest):
|
|
|
60
60
|
event = await base.fire('woot', x=3, y=5, ret=[])
|
|
61
61
|
self.eq(event[1]['ret'], 8)
|
|
62
62
|
|
|
63
|
+
base00 = await s_base.Base.anit()
|
|
64
|
+
base01 = await s_base.Base.anit()
|
|
65
|
+
data = {}
|
|
66
|
+
async def onfini():
|
|
67
|
+
data['woot'] = True
|
|
68
|
+
|
|
69
|
+
await base00.fini()
|
|
70
|
+
base00.onfini(onfini)
|
|
71
|
+
await asyncio.sleep(0)
|
|
72
|
+
self.true(data.get('woot'))
|
|
73
|
+
|
|
74
|
+
base00.onfini(base01)
|
|
75
|
+
await asyncio.sleep(0)
|
|
76
|
+
self.true(base01.isfini)
|
|
77
|
+
|
|
63
78
|
async def test_base_anit(self):
|
|
64
79
|
|
|
65
80
|
afoo = await Hehe.anit(20)
|
|
@@ -201,6 +216,7 @@ class BaseTest(s_t_utils.SynTest):
|
|
|
201
216
|
self.eq(data['count'], 1)
|
|
202
217
|
|
|
203
218
|
async def test_base_waiter(self):
|
|
219
|
+
|
|
204
220
|
base0 = await s_base.Base.anit()
|
|
205
221
|
|
|
206
222
|
wait0 = base0.waiter(3, 'foo:bar')
|
|
@@ -224,6 +240,10 @@ class BaseTest(s_t_utils.SynTest):
|
|
|
224
240
|
evts = await wait2.wait(1)
|
|
225
241
|
self.len(2, evts)
|
|
226
242
|
|
|
243
|
+
with self.raises(s_exc.TimeOut):
|
|
244
|
+
async with base0.waiter(1, 'newp', 'nuuh', timeout=0.01):
|
|
245
|
+
pass
|
|
246
|
+
|
|
227
247
|
async def test_baseref(self):
|
|
228
248
|
|
|
229
249
|
bref = await s_base.BaseRef.anit()
|
synapse/tests/test_lib_cell.py
CHANGED
|
@@ -28,6 +28,7 @@ import synapse.lib.base as s_base
|
|
|
28
28
|
import synapse.lib.cell as s_cell
|
|
29
29
|
import synapse.lib.coro as s_coro
|
|
30
30
|
import synapse.lib.link as s_link
|
|
31
|
+
import synapse.lib.drive as s_drive
|
|
31
32
|
import synapse.lib.nexus as s_nexus
|
|
32
33
|
import synapse.lib.certdir as s_certdir
|
|
33
34
|
import synapse.lib.msgpack as s_msgpack
|
|
@@ -155,8 +156,217 @@ async def altAuthCtor(cell):
|
|
|
155
156
|
cell.onfini(auth.fini)
|
|
156
157
|
return auth
|
|
157
158
|
|
|
159
|
+
testDataSchema_v0 = {
|
|
160
|
+
'type': 'object',
|
|
161
|
+
'properties': {
|
|
162
|
+
'type': {'type': 'string'},
|
|
163
|
+
'size': {'type': 'number'},
|
|
164
|
+
},
|
|
165
|
+
'required': ['type', 'size'],
|
|
166
|
+
'additionalProperties': False,
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
testDataSchema_v1 = {
|
|
170
|
+
'type': 'object',
|
|
171
|
+
'properties': {
|
|
172
|
+
'type': {'type': 'string'},
|
|
173
|
+
'size': {'type': 'number'},
|
|
174
|
+
'woot': {'type': 'string'},
|
|
175
|
+
},
|
|
176
|
+
'required': ['type', 'size', 'woot'],
|
|
177
|
+
'additionalProperties': False,
|
|
178
|
+
}
|
|
179
|
+
|
|
158
180
|
class CellTest(s_t_utils.SynTest):
|
|
159
181
|
|
|
182
|
+
async def test_cell_drive(self):
|
|
183
|
+
|
|
184
|
+
async with self.getTestCell() as cell:
|
|
185
|
+
|
|
186
|
+
with self.raises(s_exc.BadName):
|
|
187
|
+
s_drive.reqValidName('A' * 512)
|
|
188
|
+
|
|
189
|
+
info = {'name': 'users'}
|
|
190
|
+
pathinfo = await cell.addDriveItem(info)
|
|
191
|
+
|
|
192
|
+
info = {'name': 'root'}
|
|
193
|
+
pathinfo = await cell.addDriveItem(info, path='users')
|
|
194
|
+
|
|
195
|
+
with self.raises(s_exc.DupIden):
|
|
196
|
+
await cell.drive.addItemInfo(pathinfo[-1], path='users')
|
|
197
|
+
|
|
198
|
+
rootdir = pathinfo[-1].get('iden')
|
|
199
|
+
self.eq(0, pathinfo[-1].get('kids'))
|
|
200
|
+
|
|
201
|
+
info = {'name': 'win32k.sys', 'type': 'hehe'}
|
|
202
|
+
with self.raises(s_exc.NoSuchType):
|
|
203
|
+
info = await cell.addDriveItem(info, reldir=rootdir)
|
|
204
|
+
|
|
205
|
+
infos = [i async for i in cell.getDriveKids(s_drive.rootdir)]
|
|
206
|
+
self.len(1, infos)
|
|
207
|
+
self.eq(1, infos[0].get('kids'))
|
|
208
|
+
self.eq('users', infos[0].get('name'))
|
|
209
|
+
|
|
210
|
+
# TODO how to handle iden match with additional property mismatch
|
|
211
|
+
|
|
212
|
+
await cell.drive.setTypeSchema('woot', testDataSchema_v0)
|
|
213
|
+
|
|
214
|
+
info = {'name': 'win32k.sys', 'type': 'woot'}
|
|
215
|
+
info = await cell.addDriveItem(info, reldir=rootdir)
|
|
216
|
+
|
|
217
|
+
iden = info[-1].get('iden')
|
|
218
|
+
|
|
219
|
+
tick = s_common.now()
|
|
220
|
+
rootuser = cell.auth.rootuser.iden
|
|
221
|
+
|
|
222
|
+
with self.raises(s_exc.SchemaViolation):
|
|
223
|
+
versinfo = {'version': (1, 0, 0), 'updated': tick, 'updater': rootuser}
|
|
224
|
+
await cell.setDriveData(iden, versinfo, {'newp': 'newp'})
|
|
225
|
+
|
|
226
|
+
versinfo = {'version': (1, 1, 0), 'updated': tick + 10, 'updater': rootuser}
|
|
227
|
+
info, versinfo = await cell.setDriveData(iden, versinfo, {'type': 'haha', 'size': 20})
|
|
228
|
+
self.eq(info.get('version'), (1, 1, 0))
|
|
229
|
+
self.eq(versinfo.get('version'), (1, 1, 0))
|
|
230
|
+
|
|
231
|
+
versinfo = {'version': (1, 0, 0), 'updated': tick, 'updater': rootuser}
|
|
232
|
+
info, versinfo = await cell.setDriveData(iden, versinfo, {'type': 'hehe', 'size': 0})
|
|
233
|
+
self.eq(info.get('version'), (1, 1, 0))
|
|
234
|
+
self.eq(versinfo.get('version'), (1, 0, 0))
|
|
235
|
+
|
|
236
|
+
versinfo10, data10 = await cell.getDriveData(iden, vers=(1, 0, 0))
|
|
237
|
+
self.eq(versinfo10.get('updated'), tick)
|
|
238
|
+
self.eq(versinfo10.get('updater'), rootuser)
|
|
239
|
+
self.eq(versinfo10.get('version'), (1, 0, 0))
|
|
240
|
+
|
|
241
|
+
versinfo11, data11 = await cell.getDriveData(iden, vers=(1, 1, 0))
|
|
242
|
+
self.eq(versinfo11.get('updated'), tick + 10)
|
|
243
|
+
self.eq(versinfo11.get('updater'), rootuser)
|
|
244
|
+
self.eq(versinfo11.get('version'), (1, 1, 0))
|
|
245
|
+
|
|
246
|
+
versions = [vers async for vers in cell.getDriveDataVersions(iden)]
|
|
247
|
+
self.len(2, versions)
|
|
248
|
+
self.eq(versions[0], versinfo11)
|
|
249
|
+
self.eq(versions[1], versinfo10)
|
|
250
|
+
|
|
251
|
+
info = await cell.delDriveData(iden, vers=(0, 0, 0))
|
|
252
|
+
|
|
253
|
+
versions = [vers async for vers in cell.getDriveDataVersions(iden)]
|
|
254
|
+
self.len(2, versions)
|
|
255
|
+
self.eq(versions[0], versinfo11)
|
|
256
|
+
self.eq(versions[1], versinfo10)
|
|
257
|
+
|
|
258
|
+
info = await cell.delDriveData(iden, vers=(1, 1, 0))
|
|
259
|
+
self.eq(info.get('updated'), tick)
|
|
260
|
+
self.eq(info.get('version'), (1, 0, 0))
|
|
261
|
+
|
|
262
|
+
info = await cell.delDriveData(iden, vers=(1, 0, 0))
|
|
263
|
+
self.eq(info.get('size'), 0)
|
|
264
|
+
self.eq(info.get('version'), (0, 0, 0))
|
|
265
|
+
self.none(info.get('updated'))
|
|
266
|
+
self.none(info.get('updater'))
|
|
267
|
+
|
|
268
|
+
# repopulate a couple data versions to test migration and delete
|
|
269
|
+
versinfo = {'version': (1, 0, 0), 'updated': tick, 'updater': rootuser}
|
|
270
|
+
info, versinfo = await cell.setDriveData(iden, versinfo, {'type': 'hehe', 'size': 0})
|
|
271
|
+
versinfo = {'version': (1, 1, 0), 'updated': tick + 10, 'updater': rootuser}
|
|
272
|
+
info, versinfo = await cell.setDriveData(iden, versinfo, {'type': 'haha', 'size': 17})
|
|
273
|
+
self.eq(versinfo, (await cell.getDriveData(iden))[0])
|
|
274
|
+
|
|
275
|
+
# This will be done by the cell in a cell storage version migration...
|
|
276
|
+
async def migrate_v1(info, versinfo, data):
|
|
277
|
+
data['woot'] = 'woot'
|
|
278
|
+
return data
|
|
279
|
+
|
|
280
|
+
await cell.drive.setTypeSchema('woot', testDataSchema_v1, migrate_v1)
|
|
281
|
+
|
|
282
|
+
versinfo, data = await cell.getDriveData(iden, vers=(1, 0, 0))
|
|
283
|
+
self.eq('woot', data.get('woot'))
|
|
284
|
+
|
|
285
|
+
versinfo, data = await cell.getDriveData(iden, vers=(1, 1, 0))
|
|
286
|
+
self.eq('woot', data.get('woot'))
|
|
287
|
+
|
|
288
|
+
self.nn(await cell.getDriveInfo(iden))
|
|
289
|
+
self.len(2, [vers async for vers in cell.getDriveDataVersions(iden)])
|
|
290
|
+
|
|
291
|
+
await cell.delDriveData(iden)
|
|
292
|
+
self.len(1, [vers async for vers in cell.getDriveDataVersions(iden)])
|
|
293
|
+
|
|
294
|
+
await cell.delDriveInfo(iden)
|
|
295
|
+
|
|
296
|
+
self.none(await cell.getDriveInfo(iden))
|
|
297
|
+
self.len(0, [vers async for vers in cell.getDriveDataVersions(iden)])
|
|
298
|
+
|
|
299
|
+
with self.raises(s_exc.NoSuchPath):
|
|
300
|
+
await cell.getDrivePath('users/root/win32k.sys')
|
|
301
|
+
|
|
302
|
+
pathinfo = await cell.addDrivePath('foo/bar/baz')
|
|
303
|
+
self.len(3, pathinfo)
|
|
304
|
+
self.eq('foo', pathinfo[0].get('name'))
|
|
305
|
+
self.eq(1, pathinfo[0].get('kids'))
|
|
306
|
+
self.eq('bar', pathinfo[1].get('name'))
|
|
307
|
+
self.eq(1, pathinfo[1].get('kids'))
|
|
308
|
+
self.eq('baz', pathinfo[2].get('name'))
|
|
309
|
+
self.eq(0, pathinfo[2].get('kids'))
|
|
310
|
+
|
|
311
|
+
self.eq(pathinfo, await cell.addDrivePath('foo/bar/baz'))
|
|
312
|
+
|
|
313
|
+
baziden = pathinfo[2].get('iden')
|
|
314
|
+
self.eq(pathinfo, await cell.drive.getItemPath(baziden))
|
|
315
|
+
|
|
316
|
+
info = await cell.setDriveInfoPerm(baziden, {'users': {rootuser: 3}, 'roles': {}})
|
|
317
|
+
self.eq(3, info['perm']['users'][rootuser])
|
|
318
|
+
|
|
319
|
+
with self.raises(s_exc.NoSuchIden):
|
|
320
|
+
# s_drive.rootdir is all 00s... ;)
|
|
321
|
+
await cell.setDriveInfoPerm(s_drive.rootdir, {'users': {}, 'roles': {}})
|
|
322
|
+
|
|
323
|
+
await cell.addDrivePath('hehe/haha')
|
|
324
|
+
pathinfo = await cell.setDriveInfoPath(baziden, 'hehe/haha/hoho')
|
|
325
|
+
|
|
326
|
+
self.eq('hoho', pathinfo[-1].get('name'))
|
|
327
|
+
self.eq(baziden, pathinfo[-1].get('iden'))
|
|
328
|
+
|
|
329
|
+
self.true(await cell.drive.hasPathInfo('hehe/haha/hoho'))
|
|
330
|
+
self.false(await cell.drive.hasPathInfo('foo/bar/baz'))
|
|
331
|
+
|
|
332
|
+
pathinfo = await cell.getDrivePath('foo/bar')
|
|
333
|
+
self.eq(0, pathinfo[-1].get('kids'))
|
|
334
|
+
|
|
335
|
+
pathinfo = await cell.getDrivePath('hehe/haha')
|
|
336
|
+
self.eq(1, pathinfo[-1].get('kids'))
|
|
337
|
+
|
|
338
|
+
with self.raises(s_exc.DupName):
|
|
339
|
+
iden = pathinfo[-2].get('iden')
|
|
340
|
+
name = pathinfo[-1].get('name')
|
|
341
|
+
cell.drive.reqFreeStep(iden, name)
|
|
342
|
+
|
|
343
|
+
walks = [item async for item in cell.drive.walkPathInfo('hehe')]
|
|
344
|
+
self.len(3, walks)
|
|
345
|
+
# confirm walked paths are yielded depth first...
|
|
346
|
+
self.eq('hoho', walks[0].get('name'))
|
|
347
|
+
self.eq('haha', walks[1].get('name'))
|
|
348
|
+
self.eq('hehe', walks[2].get('name'))
|
|
349
|
+
|
|
350
|
+
iden = walks[2].get('iden')
|
|
351
|
+
walks = [item async for item in cell.drive.walkItemInfo(iden)]
|
|
352
|
+
self.len(3, walks)
|
|
353
|
+
self.eq('hoho', walks[0].get('name'))
|
|
354
|
+
self.eq('haha', walks[1].get('name'))
|
|
355
|
+
self.eq('hehe', walks[2].get('name'))
|
|
356
|
+
|
|
357
|
+
self.none(cell.drive.getTypeSchema('newp'))
|
|
358
|
+
|
|
359
|
+
cell.drive.validators.pop('woot')
|
|
360
|
+
self.nn(cell.drive.getTypeValidator('woot'))
|
|
361
|
+
|
|
362
|
+
# move to root dir
|
|
363
|
+
pathinfo = await cell.setDriveInfoPath(baziden, 'zipzop')
|
|
364
|
+
self.len(1, pathinfo)
|
|
365
|
+
self.eq(s_drive.rootdir, pathinfo[-1].get('parent'))
|
|
366
|
+
|
|
367
|
+
pathinfo = await cell.setDriveInfoPath(baziden, 'hehe/haha/hoho')
|
|
368
|
+
self.len(3, pathinfo)
|
|
369
|
+
|
|
160
370
|
async def test_cell_auth(self):
|
|
161
371
|
|
|
162
372
|
with self.getTestDir() as dirn:
|
|
@@ -635,7 +845,6 @@ class CellTest(s_t_utils.SynTest):
|
|
|
635
845
|
async with self.getTestCell(s_cell.Cell, dirn=dir0, conf=conf) as cell00, \
|
|
636
846
|
cell00.getLocalProxy() as prox00:
|
|
637
847
|
|
|
638
|
-
self.true(cell00.nexsroot.map_async)
|
|
639
848
|
self.true(cell00.nexsroot.donexslog)
|
|
640
849
|
|
|
641
850
|
await prox00.addUser('test')
|
|
@@ -932,7 +1141,7 @@ class CellTest(s_t_utils.SynTest):
|
|
|
932
1141
|
pass
|
|
933
1142
|
stream.seek(0)
|
|
934
1143
|
buf = stream.read()
|
|
935
|
-
self.isin(f'...cell API (telepath):
|
|
1144
|
+
self.isin(f'...cell API (telepath): tcp://0.0.0.0:27492', buf)
|
|
936
1145
|
self.isin('...cell API (https): disabled', buf)
|
|
937
1146
|
|
|
938
1147
|
async def test_cell_initargv_conf(self):
|
|
@@ -954,11 +1163,11 @@ class CellTest(s_t_utils.SynTest):
|
|
|
954
1163
|
# 1) cmdline
|
|
955
1164
|
# 2) envars
|
|
956
1165
|
# 3) cell.yaml
|
|
957
|
-
self.true(cell.conf.
|
|
958
|
-
self.true(cell.conf.
|
|
959
|
-
self.none(cell.conf.
|
|
960
|
-
self.none(cell.conf.
|
|
961
|
-
self.eq(cell.conf.
|
|
1166
|
+
self.true(cell.conf.req('nexslog:en'))
|
|
1167
|
+
self.true(cell.conf.req('nexslog:async'))
|
|
1168
|
+
self.none(cell.conf.req('dmon:listen'))
|
|
1169
|
+
self.none(cell.conf.req('https:port'))
|
|
1170
|
+
self.eq(cell.conf.req('aha:name'), 'some:cell')
|
|
962
1171
|
root = cell.auth.rootuser
|
|
963
1172
|
self.true(await root.tryPasswd('secret'))
|
|
964
1173
|
|
|
@@ -966,7 +1175,7 @@ class CellTest(s_t_utils.SynTest):
|
|
|
966
1175
|
with self.getTestDir() as dirn:
|
|
967
1176
|
s_common.yamlsave({'nexslog:en': False}, dirn, 'cell.mods.yaml')
|
|
968
1177
|
async with await s_cell.Cell.initFromArgv([dirn]) as cell:
|
|
969
|
-
self.false(cell.conf.
|
|
1178
|
+
self.false(cell.conf.req('nexslog:en'))
|
|
970
1179
|
# We can remove the valu from the overrides file with the pop API
|
|
971
1180
|
# This is NOT reactive API which causes the whole behavior
|
|
972
1181
|
# of the cell to suddenly change. This is intended to be used with
|
|
@@ -1038,6 +1247,7 @@ class CellTest(s_t_utils.SynTest):
|
|
|
1038
1247
|
errinfo = info.get('lastexception')
|
|
1039
1248
|
laststart1 = info['laststart']
|
|
1040
1249
|
self.eq(errinfo['err'], 'SynErr')
|
|
1250
|
+
self.eq(errinfo['errinfo']['mesg'], 'backup subprocess start timed out')
|
|
1041
1251
|
|
|
1042
1252
|
# Test runners can take an unusually long time to spawn a process
|
|
1043
1253
|
with mock.patch.object(s_cell.Cell, 'BACKUP_SPAWN_TIMEOUT', 8.0):
|
|
@@ -1050,15 +1260,17 @@ class CellTest(s_t_utils.SynTest):
|
|
|
1050
1260
|
self.ne(laststart1, laststart2)
|
|
1051
1261
|
errinfo = info.get('lastexception')
|
|
1052
1262
|
self.eq(errinfo['err'], 'SynErr')
|
|
1263
|
+
self.eq(errinfo['errinfo']['mesg'], 'backup subprocess start timed out')
|
|
1053
1264
|
|
|
1054
|
-
|
|
1055
|
-
|
|
1265
|
+
with mock.patch.object(s_cell.Cell, '_backupProc', staticmethod(_exiterProc)):
|
|
1266
|
+
await self.asyncraises(s_exc.SpawnExit, proxy.runBackup('_exiterProc'))
|
|
1056
1267
|
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1268
|
+
info = await proxy.getBackupInfo()
|
|
1269
|
+
laststart3 = info['laststart']
|
|
1270
|
+
self.ne(laststart2, laststart3)
|
|
1271
|
+
errinfo = info.get('lastexception')
|
|
1272
|
+
self.eq(errinfo['err'], 'SpawnExit')
|
|
1273
|
+
self.eq(errinfo['errinfo']['code'], 1)
|
|
1062
1274
|
|
|
1063
1275
|
# Create rando slabs inside cell dir
|
|
1064
1276
|
slabpath = s_common.genpath(coredirn, 'randoslab')
|
|
@@ -1741,7 +1953,7 @@ class CellTest(s_t_utils.SynTest):
|
|
|
1741
1953
|
'has different iden') as stream:
|
|
1742
1954
|
async with self.getTestCell(s_cell.Cell, dirn=path01, conf=conf01) as cell01:
|
|
1743
1955
|
await stream.wait(timeout=2)
|
|
1744
|
-
self.true(await cell01.waitfini(6))
|
|
1956
|
+
self.true(await cell01.nexsroot.waitfini(6))
|
|
1745
1957
|
|
|
1746
1958
|
async def test_backup_restore_base(self):
|
|
1747
1959
|
|
|
@@ -1836,15 +2048,42 @@ class CellTest(s_t_utils.SynTest):
|
|
|
1836
2048
|
self.true(s_common.isguid(second_doneiden))
|
|
1837
2049
|
self.ne(doneiden, second_doneiden)
|
|
1838
2050
|
|
|
2051
|
+
async def test_cell_mirrorboot_failure(self):
|
|
2052
|
+
async with self.getTestAha() as aha: # type: s_aha.AhaCell
|
|
2053
|
+
|
|
2054
|
+
with self.getTestDir() as dirn:
|
|
2055
|
+
cdr0 = s_common.genpath(dirn, 'cell00')
|
|
2056
|
+
cdr1 = s_common.genpath(dirn, 'cell01')
|
|
2057
|
+
|
|
2058
|
+
async with self.addSvcToAha(aha, '00.cell', s_cell.Cell, dirn=cdr0) as cell00:
|
|
2059
|
+
|
|
2060
|
+
conf = {'mirror': 'aha://cell...'}
|
|
2061
|
+
with self.raises(s_exc.FatalErr) as cm:
|
|
2062
|
+
async with self.getTestCell(conf=conf, dirn=cdr1) as cell01:
|
|
2063
|
+
self.fail('Cell01 should never boot')
|
|
2064
|
+
self.isin('No aha:provision configuration has been provided to allow the service to bootstrap',
|
|
2065
|
+
cm.exception.get('mesg'))
|
|
2066
|
+
|
|
2067
|
+
provurl = await aha.addAhaSvcProv('01.cell', provinfo={'mirror': 'cell'})
|
|
2068
|
+
conf = self.getCellConf({'aha:provision': provurl})
|
|
2069
|
+
async with self.getTestCell(conf=conf, dirn=cdr1) as cell01:
|
|
2070
|
+
await cell01.sync()
|
|
2071
|
+
os.unlink(s_common.genpath(cdr1, 'cell.guid'))
|
|
2072
|
+
|
|
2073
|
+
conf = self.getCellConf({'aha:provision': provurl})
|
|
2074
|
+
with self.raises(s_exc.FatalErr) as cm:
|
|
2075
|
+
async with self.getTestCell(conf=conf, dirn=cdr1) as cell01:
|
|
2076
|
+
self.fail('Cell01 should never boot')
|
|
2077
|
+
self.isin('The aha:provision URL guid matches the service prov.done guid',
|
|
2078
|
+
cm.exception.get('mesg'))
|
|
2079
|
+
|
|
1839
2080
|
async def test_backup_restore_aha(self):
|
|
1840
2081
|
# do a mirror provisioning of a Cell
|
|
1841
2082
|
# promote the mirror to being a leader
|
|
1842
2083
|
# ensure the mirror has a
|
|
1843
2084
|
# backup the mirror
|
|
1844
2085
|
# restore the backup
|
|
1845
|
-
async with self.
|
|
1846
|
-
root = await aha.auth.getUserByName('root')
|
|
1847
|
-
self.true(await root.tryPasswd('secret'))
|
|
2086
|
+
async with self.getTestAha() as aha: # type: s_aha.AhaCell
|
|
1848
2087
|
|
|
1849
2088
|
with self.getTestDir() as dirn:
|
|
1850
2089
|
cdr0 = s_common.genpath(dirn, 'core00')
|
|
@@ -1927,9 +2166,7 @@ class CellTest(s_t_utils.SynTest):
|
|
|
1927
2166
|
# ensure the mirror has a
|
|
1928
2167
|
# backup the mirror
|
|
1929
2168
|
# restore the backup
|
|
1930
|
-
async with self.
|
|
1931
|
-
root = await aha.auth.getUserByName('root')
|
|
1932
|
-
self.true(await root.tryPasswd('secret'))
|
|
2169
|
+
async with self.getTestAha() as aha: # type: s_aha.AhaCell
|
|
1933
2170
|
|
|
1934
2171
|
with self.getTestDir() as dirn:
|
|
1935
2172
|
cdr0 = s_common.genpath(dirn, 'core00')
|
|
@@ -2887,3 +3124,17 @@ class CellTest(s_t_utils.SynTest):
|
|
|
2887
3124
|
|
|
2888
3125
|
async with self.getTestCell(s_cell.Cell, dirn=dirn):
|
|
2889
3126
|
pass
|
|
3127
|
+
|
|
3128
|
+
async def test_cell_initslab_fini(self):
|
|
3129
|
+
class SlabCell(s_cell.Cell):
|
|
3130
|
+
async def initServiceStorage(self):
|
|
3131
|
+
self.long_lived_slab = await self._initSlabFile(os.path.join(self.dirn, 'slabs', 'long.lmdb'))
|
|
3132
|
+
short_slab = await self._initSlabFile(os.path.join(self.dirn, 'slabs', 'short.lmdb'), ephemeral=True)
|
|
3133
|
+
self.short_slab_path = short_slab.lenv.path()
|
|
3134
|
+
await short_slab.fini()
|
|
3135
|
+
|
|
3136
|
+
async with self.getTestCell(SlabCell) as cell:
|
|
3137
|
+
self.true(os.path.isdir(cell.short_slab_path))
|
|
3138
|
+
self.isin(cell.long_lived_slab.fini, cell._fini_funcs)
|
|
3139
|
+
slabs = [s for s in cell.tofini if isinstance(s, s_lmdbslab.Slab) and s.lenv.path() == cell.short_slab_path]
|
|
3140
|
+
self.len(0, slabs)
|
synapse/tests/test_lib_config.py
CHANGED
|
@@ -31,7 +31,7 @@ class SchemaCell(s_cell.Cell):
|
|
|
31
31
|
await s_cell.Cell.__anit__(self, dirn, conf, readonly, *args, **kwargs)
|
|
32
32
|
# This captures a design pattern that reduces boilerplate
|
|
33
33
|
# code used by Cell implementators.
|
|
34
|
-
self.conf.
|
|
34
|
+
self.conf.req('apikey')
|
|
35
35
|
|
|
36
36
|
|
|
37
37
|
class ConfTest(s_test.SynTest):
|
|
@@ -162,7 +162,7 @@ class ConfTest(s_test.SynTest):
|
|
|
162
162
|
})
|
|
163
163
|
|
|
164
164
|
# We can ensure that certain vars are loaded
|
|
165
|
-
self.eq('Funky string time!', conf.
|
|
165
|
+
self.eq('Funky string time!', conf.req('key:string'))
|
|
166
166
|
# And throw if they are not, or if the requested key isn't even schema valid
|
|
167
167
|
self.raises(s_exc.NeedConfValu, conf.reqConfValu, 'key:bool:nodefval')
|
|
168
168
|
self.raises(s_exc.BadArg, conf.reqConfValu, 'key:newp')
|
|
@@ -286,7 +286,8 @@ class ConfTest(s_test.SynTest):
|
|
|
286
286
|
# Trying to make a cell with a missing key it wants fails
|
|
287
287
|
async with await SchemaCell.anit(dirn, conf={}) as cell:
|
|
288
288
|
pass
|
|
289
|
-
|
|
289
|
+
|
|
290
|
+
self.eq(cm.exception.get('name'), 'apikey')
|
|
290
291
|
|
|
291
292
|
def test_hideconf(self):
|
|
292
293
|
hide_schema = {
|
synapse/tests/test_lib_coro.py
CHANGED
|
@@ -41,6 +41,18 @@ def nopickle():
|
|
|
41
41
|
|
|
42
42
|
class CoroTest(s_t_utils.SynTest):
|
|
43
43
|
|
|
44
|
+
async def test_coro_chunks(self):
|
|
45
|
+
async def agen():
|
|
46
|
+
for i in range(101):
|
|
47
|
+
yield i
|
|
48
|
+
|
|
49
|
+
chunks = []
|
|
50
|
+
async for chunk in s_coro.chunks(agen()):
|
|
51
|
+
chunks.append(chunk)
|
|
52
|
+
|
|
53
|
+
self.len(1, chunks[1])
|
|
54
|
+
self.len(100, chunks[0])
|
|
55
|
+
|
|
44
56
|
async def test_coro_event(self):
|
|
45
57
|
|
|
46
58
|
evnt = s_coro.Event()
|
synapse/tests/test_lib_nexus.py
CHANGED
|
@@ -111,6 +111,14 @@ class NexusTest(s_t_utils.SynTest):
|
|
|
111
111
|
stream.seek(0)
|
|
112
112
|
self.isin('while replaying log', stream.read())
|
|
113
113
|
|
|
114
|
+
async def test_nexus_modroot(self):
|
|
115
|
+
|
|
116
|
+
async with self.getTestCell() as cell:
|
|
117
|
+
await cell.sync()
|
|
118
|
+
async with cell.nexslock:
|
|
119
|
+
await cell.modNexsRoot(cell._ctorNexsRoot)
|
|
120
|
+
await cell.sync()
|
|
121
|
+
|
|
114
122
|
async def test_nexus_mixin(self):
|
|
115
123
|
with self.getTestDir() as dirn:
|
|
116
124
|
dir1 = s_common.genpath(dirn, 'nexus1')
|
|
@@ -692,6 +692,9 @@ class StormHttpTest(s_test.SynTest):
|
|
|
692
692
|
tlscadir = s_common.gendir(dirn, 'cadir')
|
|
693
693
|
cacertpath = shutil.copyfile(os.path.join(cadir, 'somelocalca.crt'), os.path.join(tlscadir, 'somelocalca.crt'))
|
|
694
694
|
|
|
695
|
+
with s_common.genfile(cacertpath) as fd:
|
|
696
|
+
ca_cert = fd.read().decode()
|
|
697
|
+
|
|
695
698
|
pkey, cert = tdir.genUserCert('someuser', signas='somelocalca')
|
|
696
699
|
user_pkey = tdir._pkeyToByts(pkey).decode()
|
|
697
700
|
user_cert = tdir._certToByts(cert).decode()
|
|
@@ -835,3 +838,40 @@ class StormHttpTest(s_test.SynTest):
|
|
|
835
838
|
## bad cert
|
|
836
839
|
sslopts['client_cert'] = 'not-gonna-work'
|
|
837
840
|
await self.asyncraises(s_exc.BadArg, core.callStorm(q, opts=opts))
|
|
841
|
+
|
|
842
|
+
# Provide a CA certificate directly
|
|
843
|
+
async with self.getTestCore(dirn=dirn) as core:
|
|
844
|
+
|
|
845
|
+
sslctx = core.initSslCtx(certpath, pkeypath)
|
|
846
|
+
sslctx.load_verify_locations(cafile=cacertpath)
|
|
847
|
+
|
|
848
|
+
addr, port = await core.addHttpsPort(0, sslctx=sslctx)
|
|
849
|
+
root = await core.auth.getUserByName('root')
|
|
850
|
+
await root.setPasswd('root')
|
|
851
|
+
|
|
852
|
+
core.addHttpApi('/api/v0/test', s_test.HttpReflector, {'cell': core})
|
|
853
|
+
|
|
854
|
+
sslopts = {}
|
|
855
|
+
|
|
856
|
+
opts = {
|
|
857
|
+
'vars': {
|
|
858
|
+
'url': f'https://root:root@localhost:{port}/api/v0/test',
|
|
859
|
+
'verify': True,
|
|
860
|
+
'sslopts': sslopts,
|
|
861
|
+
},
|
|
862
|
+
}
|
|
863
|
+
|
|
864
|
+
q = 'return($lib.inet.http.get($url, ssl_verify=$verify, ssl_opts=$sslopts))'
|
|
865
|
+
|
|
866
|
+
size, sha256 = await core.callStorm('return($lib.bytes.put($lib.base64.decode(Zm9v)))')
|
|
867
|
+
opts['vars']['sha256'] = sha256
|
|
868
|
+
|
|
869
|
+
## no cert provided
|
|
870
|
+
resp = await core.callStorm(q, opts=opts)
|
|
871
|
+
self.eq(-1, resp['code'])
|
|
872
|
+
self.isin('certificate verify failed', resp['reason'])
|
|
873
|
+
|
|
874
|
+
## provide just the CA Certificate
|
|
875
|
+
sslopts['ca_cert'] = ca_cert
|
|
876
|
+
resp = await core.callStorm(q, opts=opts)
|
|
877
|
+
self.eq(200, resp['code'])
|