synapse 2.212.0__py311-none-any.whl → 2.214.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 +37 -6
- synapse/daemon.py +6 -6
- synapse/exc.py +13 -1
- synapse/lib/aha.py +5 -0
- synapse/lib/ast.py +2 -6
- synapse/lib/boss.py +47 -2
- synapse/lib/cell.py +199 -6
- synapse/lib/certdir.py +44 -1
- synapse/lib/cmd.py +24 -0
- synapse/lib/coro.py +8 -2
- synapse/lib/drive.py +7 -2
- synapse/lib/link.py +11 -3
- synapse/lib/schemas.py +1 -1
- synapse/lib/scrape.py +3 -1
- synapse/lib/snap.py +89 -80
- synapse/lib/storm.py +2 -1
- synapse/lib/stormlib/imap.py +3 -2
- synapse/lib/stormlib/spooled.py +4 -0
- synapse/lib/stormtypes.py +18 -0
- synapse/lib/task.py +1 -0
- synapse/lib/types.py +36 -8
- synapse/lib/version.py +2 -2
- synapse/models/inet.py +5 -0
- synapse/telepath.py +4 -2
- synapse/tests/files/testpkg_build_docs/docs/bar.rst +15 -0
- synapse/tests/files/testpkg_build_docs/docs/foo.rst +4 -0
- synapse/tests/files/testpkg_build_docs/storm/commands/testcmd.storm +0 -0
- synapse/tests/files/testpkg_build_docs/storm/modules/apimod.storm +0 -0
- synapse/tests/files/testpkg_build_docs/storm/modules/testmod.storm +0 -0
- synapse/tests/files/testpkg_build_docs/storm/testcmd.storm +5 -0
- synapse/tests/files/testpkg_build_docs/testpkg.yaml +69 -0
- synapse/tests/test_cortex.py +20 -1
- synapse/tests/test_daemon.py +1 -1
- synapse/tests/test_exc.py +6 -0
- synapse/tests/test_lib_ast.py +69 -14
- synapse/tests/test_lib_boss.py +8 -0
- synapse/tests/test_lib_cell.py +119 -8
- synapse/tests/test_lib_certdir.py +8 -0
- synapse/tests/test_lib_coro.py +5 -0
- synapse/tests/test_lib_httpapi.py +10 -2
- synapse/tests/test_lib_link.py +1 -1
- synapse/tests/test_lib_scrape.py +6 -0
- synapse/tests/test_lib_storm.py +123 -1
- synapse/tests/test_lib_stormlib_spooled.py +31 -0
- synapse/tests/test_lib_stormtypes.py +11 -0
- synapse/tests/test_lib_types.py +137 -45
- synapse/tests/test_model_crypto.py +8 -0
- synapse/tests/test_model_inet.py +7 -0
- synapse/tests/test_telepath.py +50 -5
- synapse/tests/test_tools_axon.py +304 -0
- synapse/tests/test_tools_cortex_layer.py +419 -0
- synapse/tests/test_tools_demote.py +114 -0
- synapse/tests/test_tools_pkgs_gendocs.py +100 -0
- synapse/tests/test_tools_shutdown.py +95 -0
- synapse/tests/test_utils.py +22 -1
- synapse/tests/utils.py +44 -29
- synapse/tools/aha/easycert.py +2 -0
- synapse/tools/aha/enroll.py +3 -0
- synapse/tools/axon/__init__.py +0 -0
- synapse/tools/axon/dump.py +155 -0
- synapse/tools/axon/load.py +89 -0
- synapse/tools/cortex/__init__.py +0 -0
- synapse/tools/cortex/layer/__init__.py +0 -0
- synapse/tools/cortex/layer/dump.py +184 -0
- synapse/tools/cortex/layer/load.py +129 -0
- synapse/tools/demote.py +52 -0
- synapse/tools/healthcheck.py +1 -1
- synapse/tools/pkgs/gendocs.py +176 -0
- synapse/tools/pkgs/pandoc_filter.py +79 -0
- synapse/tools/shutdown.py +52 -0
- {synapse-2.212.0.dist-info → synapse-2.214.0.dist-info}/METADATA +1 -1
- {synapse-2.212.0.dist-info → synapse-2.214.0.dist-info}/RECORD +75 -52
- {synapse-2.212.0.dist-info → synapse-2.214.0.dist-info}/WHEEL +0 -0
- {synapse-2.212.0.dist-info → synapse-2.214.0.dist-info}/licenses/LICENSE +0 -0
- {synapse-2.212.0.dist-info → synapse-2.214.0.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,419 @@
|
|
|
1
|
+
import os
|
|
2
|
+
|
|
3
|
+
import synapse.common as s_common
|
|
4
|
+
|
|
5
|
+
import synapse.lib.msgpack as s_msgpack
|
|
6
|
+
import synapse.lib.version as s_version
|
|
7
|
+
|
|
8
|
+
import synapse.tests.utils as s_test
|
|
9
|
+
|
|
10
|
+
import synapse.tools.cortex.layer.dump as s_t_dump
|
|
11
|
+
import synapse.tools.cortex.layer.load as s_t_load
|
|
12
|
+
|
|
13
|
+
class LayerTest(s_test.SynTest):
|
|
14
|
+
|
|
15
|
+
async def test_tools_layer_dump(self):
|
|
16
|
+
|
|
17
|
+
async with self.getTestCore() as core:
|
|
18
|
+
|
|
19
|
+
url = core.getLocalUrl()
|
|
20
|
+
|
|
21
|
+
layr00 = await core.addLayer()
|
|
22
|
+
layr00iden = layr00.get('iden')
|
|
23
|
+
view00 = await core.addView({'layers': [layr00iden]})
|
|
24
|
+
|
|
25
|
+
soffs = await core.getNexsIndx()
|
|
26
|
+
|
|
27
|
+
opts = {'view': view00.get('iden'), 'vars': {'n': 256}}
|
|
28
|
+
nodes = await core.nodes('for $i in $lib.range($n) { [test:int=$i] }', opts=opts)
|
|
29
|
+
self.len(256, nodes)
|
|
30
|
+
|
|
31
|
+
eoffs = soffs + 256
|
|
32
|
+
|
|
33
|
+
chunksize = 10
|
|
34
|
+
|
|
35
|
+
with self.getTestDir() as dirn:
|
|
36
|
+
argv = (
|
|
37
|
+
'--url', url,
|
|
38
|
+
'--chunksize', str(chunksize),
|
|
39
|
+
'--offset', str(soffs),
|
|
40
|
+
layr00iden,
|
|
41
|
+
dirn,
|
|
42
|
+
)
|
|
43
|
+
|
|
44
|
+
outp = self.getTestOutp()
|
|
45
|
+
self.eq(0, await s_t_dump.main(argv, outp=outp))
|
|
46
|
+
outp.expect(f'Successfully exported layer {layr00iden}.')
|
|
47
|
+
|
|
48
|
+
for ii in range(soffs, eoffs - chunksize, chunksize):
|
|
49
|
+
path = s_common.genpath(dirn, f'{core.iden}.{layr00iden}.{ii}-{ii + chunksize - 1}.nodeedits')
|
|
50
|
+
self.true(os.path.exists(path))
|
|
51
|
+
|
|
52
|
+
# Open and inspect first file
|
|
53
|
+
filename = f'{core.iden}.{layr00iden}.{soffs}-{soffs + 9}.nodeedits'
|
|
54
|
+
msgs = list(s_msgpack.iterfile(s_common.genpath(dirn, filename)))
|
|
55
|
+
self.len(12, msgs)
|
|
56
|
+
|
|
57
|
+
self.eq(msgs[0][0], 'init')
|
|
58
|
+
self.eq(msgs[0][1].get('hdrvers'), 1)
|
|
59
|
+
self.eq(msgs[0][1].get('celliden'), core.iden)
|
|
60
|
+
self.eq(msgs[0][1].get('layriden'), layr00iden)
|
|
61
|
+
self.eq(msgs[0][1].get('offset'), soffs)
|
|
62
|
+
self.eq(msgs[0][1].get('chunksize'), chunksize)
|
|
63
|
+
self.nn(msgs[0][1].get('tick'))
|
|
64
|
+
self.isinstance(msgs[0][1].get('tick'), int)
|
|
65
|
+
self.eq(msgs[0][1].get('cellvers'), core.cellinfo.get('cell:version'))
|
|
66
|
+
|
|
67
|
+
for msg in msgs[1:-1]:
|
|
68
|
+
self.len(2, msg)
|
|
69
|
+
self.eq(msg[0], 'edit')
|
|
70
|
+
self.len(3, msg[1])
|
|
71
|
+
|
|
72
|
+
self.eq(msgs[11][0], 'fini')
|
|
73
|
+
self.eq(msgs[11][1].get('offset'), soffs + 9)
|
|
74
|
+
self.nn(msgs[11][1].get('tock'))
|
|
75
|
+
self.isinstance(msgs[11][1].get('tock'), int)
|
|
76
|
+
|
|
77
|
+
# Test state tracking
|
|
78
|
+
with self.getTestDir() as dirn:
|
|
79
|
+
# Check state file is written
|
|
80
|
+
argv = (
|
|
81
|
+
'--url', url,
|
|
82
|
+
'--chunksize', str(chunksize),
|
|
83
|
+
'--offset', str(soffs),
|
|
84
|
+
layr00iden,
|
|
85
|
+
dirn,
|
|
86
|
+
)
|
|
87
|
+
|
|
88
|
+
outp = self.getTestOutp()
|
|
89
|
+
self.eq(0, await s_t_dump.main(argv, outp=outp))
|
|
90
|
+
outp.expect(f'Successfully exported layer {layr00iden}.')
|
|
91
|
+
|
|
92
|
+
state = s_common.yamlload(dirn, f'{core.iden}.{layr00iden}.yaml')
|
|
93
|
+
self.eq(state, {'offset:next': eoffs})
|
|
94
|
+
|
|
95
|
+
# Check state file is read
|
|
96
|
+
opts = {'view': view00.get('iden'), 'vars': {'n': 256}}
|
|
97
|
+
nodes = await core.nodes('for $i in $lib.range($n) { [test:str=$i] }', opts=opts)
|
|
98
|
+
self.len(256, nodes)
|
|
99
|
+
|
|
100
|
+
state = {'offset:next': eoffs + 1}
|
|
101
|
+
statefile = s_common.genpath(dirn, 'state.yaml')
|
|
102
|
+
s_common.yamlsave(state, statefile)
|
|
103
|
+
|
|
104
|
+
argv = (
|
|
105
|
+
'--url', url,
|
|
106
|
+
'--statefile', statefile,
|
|
107
|
+
layr00iden,
|
|
108
|
+
s_common.genpath(dirn, 'next'),
|
|
109
|
+
)
|
|
110
|
+
|
|
111
|
+
outp = self.getTestOutp()
|
|
112
|
+
self.eq(0, await s_t_dump.main(argv, outp=outp))
|
|
113
|
+
outp.expect(f'Successfully exported layer {layr00iden}.')
|
|
114
|
+
|
|
115
|
+
state = s_common.yamlload(dirn, statefile)
|
|
116
|
+
self.eq(state, {'offset:next': eoffs + 256})
|
|
117
|
+
|
|
118
|
+
async def test_tools_layer_dump_errors(self):
|
|
119
|
+
|
|
120
|
+
# Non-cortex cell
|
|
121
|
+
async with self.getTestCell() as cell:
|
|
122
|
+
with self.getTestDir() as dirn:
|
|
123
|
+
with s_common.genfile(dirn, 'newp') as fd:
|
|
124
|
+
filename = fd.name
|
|
125
|
+
fd.write(s_msgpack.en(('init', {'offset': 0, 'cellvers': s_version.version})))
|
|
126
|
+
|
|
127
|
+
url = cell.getLocalUrl()
|
|
128
|
+
argv = ('--url', url, s_common.guid(), dirn)
|
|
129
|
+
outp = self.getTestOutp()
|
|
130
|
+
self.eq(1, await s_t_dump.main(argv, outp=outp))
|
|
131
|
+
outp.expect(f'ERROR: Layer dump tool only works on cortexes, not cell.')
|
|
132
|
+
|
|
133
|
+
async with self.getTestCore() as core:
|
|
134
|
+
|
|
135
|
+
url = core.getLocalUrl()
|
|
136
|
+
|
|
137
|
+
layr00 = await core.addLayer()
|
|
138
|
+
layr00iden = layr00.get('iden')
|
|
139
|
+
view00 = await core.addView({'layers': [layr00iden]})
|
|
140
|
+
|
|
141
|
+
soffs = await core.getNexsIndx()
|
|
142
|
+
|
|
143
|
+
opts = {'view': view00.get('iden'), 'vars': {'n': 256}}
|
|
144
|
+
nodes = await core.nodes('for $i in $lib.range($n) { [test:int=$i] }', opts=opts)
|
|
145
|
+
self.len(256, nodes)
|
|
146
|
+
|
|
147
|
+
eoffs = soffs + 256
|
|
148
|
+
|
|
149
|
+
chunksize = 10
|
|
150
|
+
|
|
151
|
+
with self.getTestDir() as dirn:
|
|
152
|
+
# Handle no edits from offset
|
|
153
|
+
argv = (
|
|
154
|
+
'--url', url,
|
|
155
|
+
'--chunksize', str(chunksize),
|
|
156
|
+
'--offset', '9000',
|
|
157
|
+
layr00iden,
|
|
158
|
+
dirn,
|
|
159
|
+
)
|
|
160
|
+
|
|
161
|
+
outp = self.getTestOutp()
|
|
162
|
+
self.eq(1, await s_t_dump.main(argv, outp=outp))
|
|
163
|
+
outp.expect(f'ERROR: No edits to export starting from offset (9000).')
|
|
164
|
+
|
|
165
|
+
# Handle outdir being an existing file
|
|
166
|
+
filename = s_common.genpath(dirn, 'newp')
|
|
167
|
+
s_common.genfile(filename).close()
|
|
168
|
+
|
|
169
|
+
argv = (
|
|
170
|
+
'--url', url,
|
|
171
|
+
'--chunksize', str(chunksize),
|
|
172
|
+
layr00iden,
|
|
173
|
+
filename,
|
|
174
|
+
)
|
|
175
|
+
|
|
176
|
+
outp = self.getTestOutp()
|
|
177
|
+
self.eq(1, await s_t_dump.main(argv, outp=outp))
|
|
178
|
+
outp.expect(f'ERROR: Specified output directory {filename} exists but is not a directory.')
|
|
179
|
+
|
|
180
|
+
# Invalid layer iden
|
|
181
|
+
newpiden = s_common.guid()
|
|
182
|
+
argv = (
|
|
183
|
+
'--url', url,
|
|
184
|
+
'--chunksize', str(chunksize),
|
|
185
|
+
newpiden,
|
|
186
|
+
dirn,
|
|
187
|
+
)
|
|
188
|
+
|
|
189
|
+
outp = self.getTestOutp()
|
|
190
|
+
self.eq(1, await s_t_dump.main(argv, outp=outp))
|
|
191
|
+
outp.expect(f'ERROR: No such layer {newpiden}.')
|
|
192
|
+
|
|
193
|
+
async def test_tools_layer_load(self):
|
|
194
|
+
async with self.getTestCore() as core:
|
|
195
|
+
|
|
196
|
+
url = core.getLocalUrl()
|
|
197
|
+
|
|
198
|
+
layr00 = await core.addLayer()
|
|
199
|
+
layr00iden = layr00.get('iden')
|
|
200
|
+
view00 = await core.addView({'layers': [layr00iden]})
|
|
201
|
+
|
|
202
|
+
layr01 = await core.addLayer()
|
|
203
|
+
layr01iden = layr01.get('iden')
|
|
204
|
+
view01 = await core.addView({'layers': [layr01iden]})
|
|
205
|
+
|
|
206
|
+
soffs = await core.getNexsIndx()
|
|
207
|
+
|
|
208
|
+
opts = {'view': view00.get('iden'), 'vars': {'n': 256}}
|
|
209
|
+
nodes = await core.nodes('for $i in $lib.range($n) { [test:int=$i] }', opts=opts)
|
|
210
|
+
self.len(256, nodes)
|
|
211
|
+
|
|
212
|
+
eoffs = soffs + 256
|
|
213
|
+
|
|
214
|
+
with self.getTestDir() as dirn:
|
|
215
|
+
# Export layr00
|
|
216
|
+
argv = (
|
|
217
|
+
'--url', url,
|
|
218
|
+
layr00iden,
|
|
219
|
+
dirn,
|
|
220
|
+
)
|
|
221
|
+
|
|
222
|
+
outp = self.getTestOutp()
|
|
223
|
+
self.eq(0, await s_t_dump.main(argv, outp=outp))
|
|
224
|
+
outp.expect(f'Successfully exported layer {layr00iden}.')
|
|
225
|
+
|
|
226
|
+
# Verify layr01 is empty
|
|
227
|
+
opts = {'view': view01.get('iden')}
|
|
228
|
+
nodes = await core.nodes('inet:ipv4', opts=opts)
|
|
229
|
+
self.len(0, nodes)
|
|
230
|
+
|
|
231
|
+
files = [os.path.join(dirn, k) for k in os.listdir(dirn) if k.endswith('.nodeedits')]
|
|
232
|
+
self.len(1, files)
|
|
233
|
+
|
|
234
|
+
# Import to layr01
|
|
235
|
+
argv = (
|
|
236
|
+
'--url', url,
|
|
237
|
+
'--dryrun',
|
|
238
|
+
layr01iden,
|
|
239
|
+
files[0],
|
|
240
|
+
)
|
|
241
|
+
|
|
242
|
+
outp = self.getTestOutp()
|
|
243
|
+
self.eq(0, await s_t_load.main(argv, outp=outp))
|
|
244
|
+
outp.expect('Processing the following nodeedits:')
|
|
245
|
+
outp.expect(f'{soffs:<16d} | {files[0]}')
|
|
246
|
+
outp.expect(f'Loading {files[0]}, offset={soffs}, tick=')
|
|
247
|
+
outp.expect(f'Successfully read {files[0]} as a dryrun test.')
|
|
248
|
+
|
|
249
|
+
# Verify layr01 is empty
|
|
250
|
+
opts = {'view': view01.get('iden')}
|
|
251
|
+
nodes = await core.nodes('inet:ipv4', opts=opts)
|
|
252
|
+
self.len(0, nodes)
|
|
253
|
+
|
|
254
|
+
# Import to layr01
|
|
255
|
+
argv = (
|
|
256
|
+
'--url', url,
|
|
257
|
+
layr01iden,
|
|
258
|
+
files[0],
|
|
259
|
+
)
|
|
260
|
+
|
|
261
|
+
outp = self.getTestOutp()
|
|
262
|
+
self.eq(0, await s_t_load.main(argv, outp=outp))
|
|
263
|
+
outp.expect('Processing the following nodeedits:')
|
|
264
|
+
outp.expect(f'{soffs:<16d} | {files[0]}')
|
|
265
|
+
outp.expect(f'Loading {files[0]}, offset={soffs}, tick=')
|
|
266
|
+
outp.expect(f'Successfully loaded {files[0]} with {eoffs - soffs} edits ({soffs} - {eoffs - 1}).')
|
|
267
|
+
|
|
268
|
+
# Verify layr01 has data now
|
|
269
|
+
opts = {'view': view01.get('iden')}
|
|
270
|
+
nodes = await core.nodes('test:int', opts=opts)
|
|
271
|
+
self.len(256, nodes)
|
|
272
|
+
|
|
273
|
+
async def test_tools_layer_load_errors(self):
|
|
274
|
+
|
|
275
|
+
iden = s_common.guid()
|
|
276
|
+
|
|
277
|
+
# Non-cortex cell
|
|
278
|
+
with self.getTestDir() as dirn:
|
|
279
|
+
with s_common.genfile(dirn, 'newp') as fd:
|
|
280
|
+
filename = fd.name
|
|
281
|
+
fd.write(s_msgpack.en(('init', {'offset': 0, 'cellvers': s_version.version})))
|
|
282
|
+
|
|
283
|
+
async with self.getTestCell() as cell:
|
|
284
|
+
url = cell.getLocalUrl()
|
|
285
|
+
argv = ('--url', url, iden, filename)
|
|
286
|
+
outp = self.getTestOutp()
|
|
287
|
+
self.eq(1, await s_t_load.main(argv, outp=outp))
|
|
288
|
+
outp.expect(f'ERROR: Layer load tool only works on cortexes, not cell.')
|
|
289
|
+
|
|
290
|
+
# Non-existent file
|
|
291
|
+
argv = (iden, 'newp')
|
|
292
|
+
outp = self.getTestOutp()
|
|
293
|
+
self.eq(1, await s_t_load.main(argv, outp=outp))
|
|
294
|
+
outp.expect('Invalid input file specified: newp.')
|
|
295
|
+
|
|
296
|
+
# Input file is a directory
|
|
297
|
+
with self.getTestDir() as dirn:
|
|
298
|
+
argv = (iden, dirn)
|
|
299
|
+
outp = self.getTestOutp()
|
|
300
|
+
self.eq(1, await s_t_load.main(argv, outp=outp))
|
|
301
|
+
outp.expect(f'Invalid input file specified: {dirn}.')
|
|
302
|
+
|
|
303
|
+
# Input file doesn't have an init message first
|
|
304
|
+
with self.getTestDir() as dirn:
|
|
305
|
+
with s_common.genfile(dirn, 'noinit.nodeedits') as fd:
|
|
306
|
+
filename = fd.name
|
|
307
|
+
fd.write(s_msgpack.en(('newp', {})))
|
|
308
|
+
|
|
309
|
+
argv = (iden, filename)
|
|
310
|
+
outp = self.getTestOutp()
|
|
311
|
+
self.eq(1, await s_t_load.main(argv, outp=outp))
|
|
312
|
+
outp.expect(f'Invalid header in {filename}.')
|
|
313
|
+
|
|
314
|
+
# Invalid/too high cell version
|
|
315
|
+
with self.getTestDir() as dirn:
|
|
316
|
+
version = (99, 99, 0)
|
|
317
|
+
verstr = '.'.join(map(str, version))
|
|
318
|
+
|
|
319
|
+
with s_common.genfile(dirn, 'cellvers00.nodeedits') as fd:
|
|
320
|
+
file00 = fd.name
|
|
321
|
+
fd.write(s_msgpack.en(('init', {'offset': 0, 'cellvers': s_version.version})))
|
|
322
|
+
|
|
323
|
+
with s_common.genfile(dirn, 'cellvers01.nodeedits') as fd:
|
|
324
|
+
file01 = fd.name
|
|
325
|
+
fd.write(s_msgpack.en(('init', {'offset': 0, 'cellvers': version})))
|
|
326
|
+
|
|
327
|
+
async with self.getTestCore() as core:
|
|
328
|
+
url = core.getLocalUrl()
|
|
329
|
+
argv = ('--url', url, iden, file00, file01)
|
|
330
|
+
outp = self.getTestOutp()
|
|
331
|
+
self.eq(1, await s_t_load.main(argv, outp=outp))
|
|
332
|
+
outp.expect(f'Synapse version mismatch ({s_version.verstring} < {verstr}).')
|
|
333
|
+
|
|
334
|
+
# Invalid message type
|
|
335
|
+
with self.getTestDir() as dirn:
|
|
336
|
+
with s_common.genfile(dirn, 'badtype.nodeedits') as fd:
|
|
337
|
+
filename = fd.name
|
|
338
|
+
fd.write(s_msgpack.en((
|
|
339
|
+
'init',
|
|
340
|
+
{
|
|
341
|
+
'hdrvers': 1,
|
|
342
|
+
'celliden': s_common.guid(),
|
|
343
|
+
'layriden': s_common.guid(),
|
|
344
|
+
'offset': 0,
|
|
345
|
+
'chunksize': 10000,
|
|
346
|
+
'tick': s_common.now(),
|
|
347
|
+
'cellvers': s_version.version,
|
|
348
|
+
}
|
|
349
|
+
)))
|
|
350
|
+
|
|
351
|
+
fd.write(s_msgpack.en(('newp', {})))
|
|
352
|
+
|
|
353
|
+
async with self.getTestCore() as core:
|
|
354
|
+
url = core.getLocalUrl()
|
|
355
|
+
layriden = core.getView().layers[0].iden
|
|
356
|
+
argv = ('--url', url, layriden, filename)
|
|
357
|
+
outp = self.getTestOutp()
|
|
358
|
+
self.eq(1, await s_t_load.main(argv, outp=outp))
|
|
359
|
+
outp.expect('Unexpected message type: newp.')
|
|
360
|
+
|
|
361
|
+
# Missing fini
|
|
362
|
+
with self.getTestDir() as dirn:
|
|
363
|
+
with s_common.genfile(dirn, 'badtype.nodeedits') as fd:
|
|
364
|
+
filename = fd.name
|
|
365
|
+
fd.write(s_msgpack.en((
|
|
366
|
+
'init',
|
|
367
|
+
{
|
|
368
|
+
'hdrvers': 1,
|
|
369
|
+
'celliden': s_common.guid(),
|
|
370
|
+
'layriden': s_common.guid(),
|
|
371
|
+
'offset': 0,
|
|
372
|
+
'chunksize': 10000,
|
|
373
|
+
'tick': s_common.now(),
|
|
374
|
+
'cellvers': s_version.version,
|
|
375
|
+
}
|
|
376
|
+
)))
|
|
377
|
+
|
|
378
|
+
async with self.getTestCore() as core:
|
|
379
|
+
url = core.getLocalUrl()
|
|
380
|
+
layriden = core.getView().layers[0].iden
|
|
381
|
+
argv = ('--url', url, layriden, filename)
|
|
382
|
+
outp = self.getTestOutp()
|
|
383
|
+
self.eq(1, await s_t_load.main(argv, outp=outp))
|
|
384
|
+
outp.expect(f'Incomplete/corrupt export: {filename}.')
|
|
385
|
+
|
|
386
|
+
# Fini offset mismatch
|
|
387
|
+
with self.getTestDir() as dirn:
|
|
388
|
+
soffs = 0
|
|
389
|
+
eoffs = 1000
|
|
390
|
+
with s_common.genfile(dirn, 'badtype.nodeedits') as fd:
|
|
391
|
+
filename = fd.name
|
|
392
|
+
fd.write(s_msgpack.en((
|
|
393
|
+
'init',
|
|
394
|
+
{
|
|
395
|
+
'hdrvers': 1,
|
|
396
|
+
'celliden': s_common.guid(),
|
|
397
|
+
'layriden': s_common.guid(),
|
|
398
|
+
'offset': soffs,
|
|
399
|
+
'chunksize': 10000,
|
|
400
|
+
'tick': s_common.now(),
|
|
401
|
+
'cellvers': s_version.version,
|
|
402
|
+
}
|
|
403
|
+
)))
|
|
404
|
+
|
|
405
|
+
fd.write(s_msgpack.en((
|
|
406
|
+
'fini',
|
|
407
|
+
{
|
|
408
|
+
'offset': eoffs,
|
|
409
|
+
'tock': s_common.now(),
|
|
410
|
+
}
|
|
411
|
+
)))
|
|
412
|
+
|
|
413
|
+
async with self.getTestCore() as core:
|
|
414
|
+
url = core.getLocalUrl()
|
|
415
|
+
layriden = core.getView().layers[0].iden
|
|
416
|
+
argv = ('--url', url, layriden, filename)
|
|
417
|
+
outp = self.getTestOutp()
|
|
418
|
+
self.eq(1, await s_t_load.main(argv, outp=outp))
|
|
419
|
+
outp.expect(f'Incomplete/corrupt export: {filename}. Expected offset {eoffs}, got {soffs}.')
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import unittest.mock as mock
|
|
2
|
+
|
|
3
|
+
import synapse.exc as s_exc
|
|
4
|
+
import synapse.common as s_common
|
|
5
|
+
|
|
6
|
+
import synapse.lib.cell as s_cell
|
|
7
|
+
|
|
8
|
+
import synapse.tools.demote as s_tools_demote
|
|
9
|
+
|
|
10
|
+
import synapse.tests.utils as s_test
|
|
11
|
+
|
|
12
|
+
async def boom(*args, **kwargs):
|
|
13
|
+
raise s_exc.SynErr(mesg='BOOM')
|
|
14
|
+
|
|
15
|
+
class DemoteToolTest(s_test.SynTest):
|
|
16
|
+
|
|
17
|
+
async def test_tool_demote_base(self):
|
|
18
|
+
|
|
19
|
+
async with self.getTestAha() as aha:
|
|
20
|
+
|
|
21
|
+
with self.getTestDir() as dirn:
|
|
22
|
+
|
|
23
|
+
dirn00 = s_common.genpath(dirn, '00.cell')
|
|
24
|
+
dirn01 = s_common.genpath(dirn, '01.cell')
|
|
25
|
+
|
|
26
|
+
cell00 = await aha.enter_context(self.addSvcToAha(aha, '00.cell', s_cell.Cell, dirn=dirn00))
|
|
27
|
+
cell01 = await aha.enter_context(self.addSvcToAha(aha, '01.cell', s_cell.Cell, dirn=dirn01,
|
|
28
|
+
provinfo={'mirror': 'cell'}))
|
|
29
|
+
self.true(cell00.isactive)
|
|
30
|
+
self.false(cell01.isactive)
|
|
31
|
+
|
|
32
|
+
await cell01.sync()
|
|
33
|
+
|
|
34
|
+
outp = self.getTestOutp()
|
|
35
|
+
argv = ['--url', cell00.getLocalUrl()]
|
|
36
|
+
|
|
37
|
+
self.eq(0, await s_tools_demote.main(argv, outp=outp))
|
|
38
|
+
outp.expect('Demoting leader: cell://')
|
|
39
|
+
|
|
40
|
+
self.false(cell00.isactive)
|
|
41
|
+
self.true(cell01.isactive)
|
|
42
|
+
|
|
43
|
+
await cell00.sync()
|
|
44
|
+
|
|
45
|
+
outp.clear()
|
|
46
|
+
self.eq(1, await s_tools_demote.main(argv, outp=outp))
|
|
47
|
+
outp.expect('Failed to demote service cell:')
|
|
48
|
+
|
|
49
|
+
# get some test coverage for the various levels of exception handlers...
|
|
50
|
+
|
|
51
|
+
with mock.patch.object(cell00, 'getNexsIndx', boom):
|
|
52
|
+
with self.getLoggerStream('synapse') as stream:
|
|
53
|
+
argv = ['--url', cell01.getLocalUrl(), '--timeout', '12']
|
|
54
|
+
self.eq(1, await s_tools_demote.main(argv, outp=outp))
|
|
55
|
+
stream.expect('...error retrieving nexus index for')
|
|
56
|
+
|
|
57
|
+
with mock.patch.object(cell00, 'promote', boom):
|
|
58
|
+
with self.getLoggerStream('synapse') as stream:
|
|
59
|
+
argv = ['--url', cell01.getLocalUrl(), '--timeout', '12']
|
|
60
|
+
self.eq(1, await s_tools_demote.main(argv, outp=outp))
|
|
61
|
+
stream.expect('...error promoting')
|
|
62
|
+
|
|
63
|
+
with mock.patch.object(cell01, '_getDemotePeers', boom):
|
|
64
|
+
with self.getLoggerStream('synapse') as stream:
|
|
65
|
+
argv = ['--url', cell01.getLocalUrl(), '--timeout', '12']
|
|
66
|
+
outp.clear()
|
|
67
|
+
self.eq(1, await s_tools_demote.main(argv, outp=outp))
|
|
68
|
+
outp.expect('Error while demoting service')
|
|
69
|
+
stream.expect('error during task: demote')
|
|
70
|
+
|
|
71
|
+
self.false(cell00.isactive)
|
|
72
|
+
self.true(cell01.isactive)
|
|
73
|
+
|
|
74
|
+
outp.clear()
|
|
75
|
+
self.eq(1, await s_tools_demote.main(['--url', 'newp://hehe'], outp=outp))
|
|
76
|
+
outp.expect('Error while demoting service newp://hehe')
|
|
77
|
+
|
|
78
|
+
self.true(await aha.schedCoro(cell01.shutdown(timeout=12)))
|
|
79
|
+
self.true(cell00.isactive)
|
|
80
|
+
self.false(cell01.isactive)
|
|
81
|
+
|
|
82
|
+
self.true(await cell01.waitfini(timeout=12))
|
|
83
|
+
|
|
84
|
+
# test demote with insufficient peers
|
|
85
|
+
with self.getLoggerStream('synapse') as stream:
|
|
86
|
+
argv = ['--url', cell00.getLocalUrl(), '--timeout', '12']
|
|
87
|
+
self.eq(1, await s_tools_demote.main(argv, outp=outp))
|
|
88
|
+
stream.expect('...no suitable services discovered.')
|
|
89
|
+
|
|
90
|
+
async def test_tool_demote_no_features(self):
|
|
91
|
+
|
|
92
|
+
async with self.getTestAha() as aha:
|
|
93
|
+
aha.features.pop('getAhaSvcsByIden')
|
|
94
|
+
|
|
95
|
+
with self.getTestDir() as dirn:
|
|
96
|
+
|
|
97
|
+
dirn00 = s_common.genpath(dirn, '00.cell')
|
|
98
|
+
dirn01 = s_common.genpath(dirn, '01.cell')
|
|
99
|
+
|
|
100
|
+
cell00 = await aha.enter_context(self.addSvcToAha(aha, '00.cell', s_cell.Cell, dirn=dirn00))
|
|
101
|
+
cell01 = await aha.enter_context(self.addSvcToAha(aha, '01.cell', s_cell.Cell, dirn=dirn01,
|
|
102
|
+
provinfo={'mirror': 'cell'}))
|
|
103
|
+
self.true(cell00.isactive)
|
|
104
|
+
self.false(cell01.isactive)
|
|
105
|
+
|
|
106
|
+
await cell01.sync()
|
|
107
|
+
|
|
108
|
+
outp = self.getTestOutp()
|
|
109
|
+
argv = ['--url', cell00.getLocalUrl()]
|
|
110
|
+
with self.getAsyncLoggerStream('synapse.daemon') as stream:
|
|
111
|
+
self.eq(1, await s_tools_demote.main(argv, outp=outp))
|
|
112
|
+
stream.expect('AHA server does not support feature: getAhaSvcsByIden >= 1')
|
|
113
|
+
outp.expect('Error while demoting service')
|
|
114
|
+
outp.expect('AHA server does not support feature: getAhaSvcsByIden')
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import io
|
|
2
|
+
import os
|
|
3
|
+
import sys
|
|
4
|
+
import json
|
|
5
|
+
|
|
6
|
+
import synapse.exc as s_exc
|
|
7
|
+
import synapse.common as s_common
|
|
8
|
+
|
|
9
|
+
import synapse.tests.utils as s_t_utils
|
|
10
|
+
|
|
11
|
+
import synapse.tools.pkgs.gendocs as s_t_gendocs
|
|
12
|
+
import synapse.tools.pkgs.pandoc_filter as s_t_pandoc_filter
|
|
13
|
+
|
|
14
|
+
class TestPkgBuildDocs(s_t_utils.SynTest):
|
|
15
|
+
|
|
16
|
+
def setUp(self):
|
|
17
|
+
if not s_t_gendocs.hasPandoc():
|
|
18
|
+
self.skip('pandoc is not available')
|
|
19
|
+
super().setUp()
|
|
20
|
+
|
|
21
|
+
async def test_pkg_builddocs(self):
|
|
22
|
+
|
|
23
|
+
with self.getTestDir(mirror='testpkg_build_docs') as dirn:
|
|
24
|
+
testpkgfp = os.path.join(dirn, 'testpkg.yaml')
|
|
25
|
+
self.true(os.path.isfile(testpkgfp))
|
|
26
|
+
argv = [testpkgfp, ]
|
|
27
|
+
r = await s_t_gendocs.main(argv)
|
|
28
|
+
self.eq(r, 0)
|
|
29
|
+
|
|
30
|
+
pkgdef = s_common.yamlload(testpkgfp)
|
|
31
|
+
efiles = set()
|
|
32
|
+
for dnfo in pkgdef.get('docs'):
|
|
33
|
+
bname = os.path.basename(dnfo.get('path'))
|
|
34
|
+
efiles.add(bname)
|
|
35
|
+
efiles.add(bname.rsplit('.', 1)[0] + '.rst')
|
|
36
|
+
builddir = os.path.join(dirn, 'docs', '_build')
|
|
37
|
+
self.eq(efiles, set(os.listdir(builddir)))
|
|
38
|
+
|
|
39
|
+
text = s_common.getbytes(os.path.join(builddir, 'bar.md')).decode()
|
|
40
|
+
self.isin('storm> [inet:asn=1]', text)
|
|
41
|
+
self.isin('inet:asn=1\n', text)
|
|
42
|
+
self.notin(':orphan:', text)
|
|
43
|
+
self.notin(':tocdepth:', text)
|
|
44
|
+
|
|
45
|
+
text = s_common.getbytes(os.path.join(builddir, 'stormpackage.md')).decode()
|
|
46
|
+
self.isin(': baz (str): The baz.', text)
|
|
47
|
+
self.isin(': Baz the bam:\n\n yield $lib.import(apimod).search(bam)', text)
|
|
48
|
+
|
|
49
|
+
with self.getTestDir(mirror='testpkg_build_docs') as dirn:
|
|
50
|
+
testpkgfp = os.path.join(dirn, 'testpkg.yaml')
|
|
51
|
+
self.true(os.path.isfile(testpkgfp))
|
|
52
|
+
argv = [testpkgfp, '--rst-only']
|
|
53
|
+
r = await s_t_gendocs.main(argv)
|
|
54
|
+
self.eq(r, 0)
|
|
55
|
+
|
|
56
|
+
pkgdef = s_common.yamlload(testpkgfp)
|
|
57
|
+
efiles = set()
|
|
58
|
+
for dnfo in pkgdef.get('docs'):
|
|
59
|
+
bname = os.path.basename(dnfo.get('path'))
|
|
60
|
+
efiles.add(bname)
|
|
61
|
+
efiles.add(bname.rsplit('.', 1)[0] + '.rst')
|
|
62
|
+
builddir = os.path.join(dirn, 'docs', '_build')
|
|
63
|
+
self.eq(efiles, set(os.listdir(builddir)))
|
|
64
|
+
|
|
65
|
+
text = s_common.getbytes(os.path.join(builddir, 'bar.md')).decode()
|
|
66
|
+
self.eq('', text)
|
|
67
|
+
text = s_common.getbytes(os.path.join(builddir, 'stormpackage.md')).decode()
|
|
68
|
+
self.eq('', text)
|
|
69
|
+
|
|
70
|
+
with self.getTestDir(mirror='testpkg_build_docs') as dirn:
|
|
71
|
+
|
|
72
|
+
# Missing input files
|
|
73
|
+
testpkgfp = os.path.join(dirn, 'newp.yaml')
|
|
74
|
+
self.false(os.path.isfile(testpkgfp))
|
|
75
|
+
argv = [testpkgfp, ]
|
|
76
|
+
with self.raises(s_exc.BadArg) as cm:
|
|
77
|
+
await s_t_gendocs.main(argv)
|
|
78
|
+
self.isin('Package does not exist or does not contain yaml', cm.exception.get('mesg'))
|
|
79
|
+
|
|
80
|
+
# pandoc api version check coverage
|
|
81
|
+
old_stdin = sys.stdin
|
|
82
|
+
try:
|
|
83
|
+
sys.stdin = io.StringIO(json.dumps({'pandoc-api-version': [2, 0, 0]}))
|
|
84
|
+
with self.raises(Exception) as cm:
|
|
85
|
+
s_t_pandoc_filter.main()
|
|
86
|
+
self.isin('does not match required version', str(cm.exception))
|
|
87
|
+
finally:
|
|
88
|
+
sys.stdin = old_stdin
|
|
89
|
+
|
|
90
|
+
# pandoc failure
|
|
91
|
+
outp = self.getTestOutp()
|
|
92
|
+
oldv = s_t_gendocs.PANDOC_FILTER
|
|
93
|
+
try:
|
|
94
|
+
s_t_gendocs.PANDOC_FILTER = os.path.join(dirn, 'newp.py')
|
|
95
|
+
with self.raises(s_exc.SynErr) as cm:
|
|
96
|
+
await s_t_gendocs.main([os.path.join(dirn, 'testpkg.yaml'),], outp=outp)
|
|
97
|
+
self.isin('Error converting', cm.exception.get('mesg'))
|
|
98
|
+
outp.expect('ERR: Error running filter')
|
|
99
|
+
finally:
|
|
100
|
+
s_t_gendocs.PANDOC_FILTER = oldv
|