secator 0.0.1__py3-none-any.whl → 0.3.6__py3-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 secator might be problematic. Click here for more details.
- secator/.gitignore +162 -0
- secator/celery.py +7 -67
- secator/cli.py +631 -274
- secator/decorators.py +54 -11
- secator/definitions.py +104 -33
- secator/exporters/csv.py +1 -2
- secator/exporters/gdrive.py +1 -1
- secator/exporters/json.py +1 -2
- secator/exporters/txt.py +1 -2
- secator/hooks/mongodb.py +12 -12
- secator/installer.py +335 -0
- secator/report.py +2 -14
- secator/rich.py +3 -10
- secator/runners/_base.py +105 -34
- secator/runners/_helpers.py +18 -17
- secator/runners/command.py +91 -55
- secator/runners/scan.py +2 -1
- secator/runners/task.py +5 -4
- secator/runners/workflow.py +12 -11
- secator/tasks/_categories.py +14 -19
- secator/tasks/cariddi.py +2 -1
- secator/tasks/dalfox.py +2 -0
- secator/tasks/dirsearch.py +5 -7
- secator/tasks/dnsx.py +1 -0
- secator/tasks/dnsxbrute.py +1 -0
- secator/tasks/feroxbuster.py +6 -7
- secator/tasks/ffuf.py +4 -7
- secator/tasks/gau.py +1 -4
- secator/tasks/gf.py +2 -1
- secator/tasks/gospider.py +1 -0
- secator/tasks/grype.py +47 -47
- secator/tasks/h8mail.py +5 -6
- secator/tasks/httpx.py +24 -18
- secator/tasks/katana.py +11 -15
- secator/tasks/maigret.py +3 -3
- secator/tasks/mapcidr.py +1 -0
- secator/tasks/msfconsole.py +3 -1
- secator/tasks/naabu.py +2 -1
- secator/tasks/nmap.py +14 -17
- secator/tasks/nuclei.py +4 -3
- secator/tasks/searchsploit.py +3 -2
- secator/tasks/subfinder.py +1 -0
- secator/tasks/wpscan.py +11 -13
- secator/utils.py +64 -82
- secator/utils_test.py +3 -2
- secator-0.3.6.dist-info/METADATA +411 -0
- secator-0.3.6.dist-info/RECORD +100 -0
- {secator-0.0.1.dist-info → secator-0.3.6.dist-info}/WHEEL +1 -2
- secator-0.0.1.dist-info/METADATA +0 -199
- secator-0.0.1.dist-info/RECORD +0 -114
- secator-0.0.1.dist-info/top_level.txt +0 -2
- tests/__init__.py +0 -0
- tests/integration/__init__.py +0 -0
- tests/integration/inputs.py +0 -42
- tests/integration/outputs.py +0 -392
- tests/integration/test_scans.py +0 -82
- tests/integration/test_tasks.py +0 -103
- tests/integration/test_workflows.py +0 -163
- tests/performance/__init__.py +0 -0
- tests/performance/loadtester.py +0 -56
- tests/unit/__init__.py +0 -0
- tests/unit/test_celery.py +0 -39
- tests/unit/test_scans.py +0 -0
- tests/unit/test_serializers.py +0 -51
- tests/unit/test_tasks.py +0 -348
- tests/unit/test_workflows.py +0 -96
- {secator-0.0.1.dist-info → secator-0.3.6.dist-info}/entry_points.txt +0 -0
- {secator-0.0.1.dist-info → secator-0.3.6.dist-info/licenses}/LICENSE +0 -0
tests/unit/test_tasks.py
DELETED
|
@@ -1,348 +0,0 @@
|
|
|
1
|
-
import copy
|
|
2
|
-
import json
|
|
3
|
-
import logging
|
|
4
|
-
import unittest
|
|
5
|
-
import unittest.mock
|
|
6
|
-
import warnings
|
|
7
|
-
|
|
8
|
-
from secator.definitions import (DEBUG, DELAY, FOLLOW_REDIRECT, HEADER, HOST,
|
|
9
|
-
MATCH_CODES, OPT_NOT_SUPPORTED, RATE_LIMIT,
|
|
10
|
-
THREADS, TIMEOUT, DEFAULT_HTTPX_FLAGS)
|
|
11
|
-
from secator.rich import console
|
|
12
|
-
from secator.runners import Command
|
|
13
|
-
from secator.tasks import httpx
|
|
14
|
-
from secator.utils import setup_logging
|
|
15
|
-
from secator.utils_test import (FIXTURES_TASKS, FIXTURES_DIR, INPUTS_TASKS, META_OPTS,
|
|
16
|
-
TEST_TASKS, CommandOutputTester, load_fixture,
|
|
17
|
-
mock_command, mock_subprocess_popen)
|
|
18
|
-
|
|
19
|
-
level = logging.DEBUG if DEBUG > 0 else logging.ERROR
|
|
20
|
-
setup_logging(level)
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
class FakeCmd(Command):
|
|
24
|
-
opts = {
|
|
25
|
-
'opt1': {'type': int, 'default': 10},
|
|
26
|
-
'opt2': {'type': str, 'default': '1,2,3'},
|
|
27
|
-
'opt3': {'is_flag': True, 'default': False}, # optional
|
|
28
|
-
'opt_with_underscore': {'type': str}, # optional
|
|
29
|
-
'opt-with-hyphen': {'type': str}
|
|
30
|
-
}
|
|
31
|
-
opt_prefix = '-' # all options have '-' as option char
|
|
32
|
-
opt_key_map = {
|
|
33
|
-
'opt3': '--opt3', # but opt3 has '--' prefix
|
|
34
|
-
'opt4': OPT_NOT_SUPPORTED
|
|
35
|
-
}
|
|
36
|
-
opt_value_map = {
|
|
37
|
-
'opt1': lambda x: float(x) # actually opt1 value should be cast to a float
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
class TestCommandProcessOpts(unittest.TestCase):
|
|
42
|
-
|
|
43
|
-
def setUp(self):
|
|
44
|
-
self.maxDiff = None
|
|
45
|
-
|
|
46
|
-
def test_process_opts_defaults(self):
|
|
47
|
-
run_opts = {}
|
|
48
|
-
opts_str = FakeCmd._process_opts(
|
|
49
|
-
run_opts,
|
|
50
|
-
FakeCmd.opts,
|
|
51
|
-
FakeCmd.opt_key_map,
|
|
52
|
-
FakeCmd.opt_value_map)
|
|
53
|
-
self.assertEqual(opts_str, '-opt1 10.0 -opt2 1,2,3')
|
|
54
|
-
|
|
55
|
-
def test_process_opts(self):
|
|
56
|
-
run_opts = {
|
|
57
|
-
'opt1': 41,
|
|
58
|
-
'opt2': False, # intentionally omit arg, overriding default value
|
|
59
|
-
'opt3': True
|
|
60
|
-
}
|
|
61
|
-
opts_str = FakeCmd._process_opts(
|
|
62
|
-
run_opts,
|
|
63
|
-
FakeCmd.opts,
|
|
64
|
-
FakeCmd.opt_key_map,
|
|
65
|
-
FakeCmd.opt_value_map)
|
|
66
|
-
self.assertEqual(opts_str, '-opt1 41.0 --opt3')
|
|
67
|
-
|
|
68
|
-
def test_process_opts_with_prefix(self):
|
|
69
|
-
run_opts = {
|
|
70
|
-
'fakecmd_opt1': 41, # should override opt1 below
|
|
71
|
-
'opt1': 45,
|
|
72
|
-
'opt2': False, # intentionally omit arg, overriding default value
|
|
73
|
-
'opt3': True
|
|
74
|
-
}
|
|
75
|
-
opts_str = FakeCmd._process_opts(
|
|
76
|
-
run_opts,
|
|
77
|
-
FakeCmd.opts,
|
|
78
|
-
FakeCmd.opt_key_map,
|
|
79
|
-
FakeCmd.opt_value_map,
|
|
80
|
-
command_name='fakecmd')
|
|
81
|
-
self.assertEqual(opts_str, '-opt1 41.0 --opt3')
|
|
82
|
-
|
|
83
|
-
def test_process_opts_with_unsupported(self):
|
|
84
|
-
run_opts = {
|
|
85
|
-
'fakecmd_opt1': 41, # should override opt1 below
|
|
86
|
-
'opt1': 45,
|
|
87
|
-
'opt2': False, # intentionally omit arg, overriding default value
|
|
88
|
-
'opt3': True,
|
|
89
|
-
'opt4': 'test_unsupported'
|
|
90
|
-
}
|
|
91
|
-
opts_str = FakeCmd._process_opts(
|
|
92
|
-
run_opts,
|
|
93
|
-
FakeCmd.opts,
|
|
94
|
-
FakeCmd.opt_key_map,
|
|
95
|
-
FakeCmd.opt_value_map,
|
|
96
|
-
command_name='fakecmd')
|
|
97
|
-
self.assertEqual(opts_str, '-opt1 41.0 --opt3')
|
|
98
|
-
|
|
99
|
-
def test_process_opts_with_convert_underscore(self):
|
|
100
|
-
run_opts = {
|
|
101
|
-
'fakecmd_opt1': 41, # should override opt1 below
|
|
102
|
-
'opt1': 45,
|
|
103
|
-
'opt2': False, # intentionally omit arg, overriding default value
|
|
104
|
-
'opt3': True,
|
|
105
|
-
'opt4': 'test_unsupported',
|
|
106
|
-
'opt_with_underscore': 'test'
|
|
107
|
-
}
|
|
108
|
-
opts_str = FakeCmd._process_opts(
|
|
109
|
-
run_opts,
|
|
110
|
-
FakeCmd.opts,
|
|
111
|
-
FakeCmd.opt_key_map,
|
|
112
|
-
FakeCmd.opt_value_map,
|
|
113
|
-
command_name='fakecmd')
|
|
114
|
-
self.assertEqual(opts_str, '-opt1 41.0 --opt3 -opt-with-underscore test')
|
|
115
|
-
|
|
116
|
-
def test_get_opt_value(self):
|
|
117
|
-
run_opts = {
|
|
118
|
-
'fakecmd_opt1': 41,
|
|
119
|
-
'opt1': 45
|
|
120
|
-
}
|
|
121
|
-
opt_value = FakeCmd._get_opt_value(
|
|
122
|
-
run_opts,
|
|
123
|
-
opt_name='opt1',
|
|
124
|
-
opt_prefix='fakecmd',
|
|
125
|
-
default=10)
|
|
126
|
-
self.assertEqual(opt_value, 41)
|
|
127
|
-
|
|
128
|
-
def test_get_opt_value_false(self):
|
|
129
|
-
run_opts = {
|
|
130
|
-
'fakecmd_opt1': False,
|
|
131
|
-
'opt1': 45
|
|
132
|
-
}
|
|
133
|
-
opt_value = FakeCmd._get_opt_value(
|
|
134
|
-
run_opts,
|
|
135
|
-
opt_name='opt1',
|
|
136
|
-
opt_prefix='fakecmd',
|
|
137
|
-
default=10)
|
|
138
|
-
self.assertEqual(opt_value, False)
|
|
139
|
-
|
|
140
|
-
def test_get_opt_value_not_supported(self):
|
|
141
|
-
run_opts = {
|
|
142
|
-
'fakecmd_opt1': False,
|
|
143
|
-
'opt1': 45,
|
|
144
|
-
'opt4': OPT_NOT_SUPPORTED
|
|
145
|
-
}
|
|
146
|
-
opt_value = FakeCmd._get_opt_value(
|
|
147
|
-
run_opts,
|
|
148
|
-
opt_name='opt4',
|
|
149
|
-
opt_prefix='fakecmd',
|
|
150
|
-
default=10)
|
|
151
|
-
self.assertEqual(opt_value, None)
|
|
152
|
-
|
|
153
|
-
def test_httpx_build_cmd_defaults(self):
|
|
154
|
-
if not httpx in TEST_TASKS:
|
|
155
|
-
return
|
|
156
|
-
run_opts = {}
|
|
157
|
-
host = 'test.synology.me'
|
|
158
|
-
cls = httpx(host, **run_opts)
|
|
159
|
-
default_threads = cls.meta_opts[THREADS]['default']
|
|
160
|
-
expected_cmd = f'httpx {DEFAULT_HTTPX_FLAGS} -u {host} -json -threads {default_threads}'
|
|
161
|
-
self.assertEqual(cls.cmd, expected_cmd)
|
|
162
|
-
self.assertEqual(cls.print_line, False)
|
|
163
|
-
self.assertEqual(cls.print_item, False)
|
|
164
|
-
self.assertEqual(cls.print_item_count, False)
|
|
165
|
-
self.assertEqual(cls.print_cmd, False)
|
|
166
|
-
self.assertEqual(cls.print_cmd_prefix, False)
|
|
167
|
-
self.assertEqual(cls.output_json, True)
|
|
168
|
-
|
|
169
|
-
def test_httpx_build_cmd_with_opts(self):
|
|
170
|
-
if not httpx in TEST_TASKS:
|
|
171
|
-
return
|
|
172
|
-
run_opts = {
|
|
173
|
-
FOLLOW_REDIRECT: False,
|
|
174
|
-
DELAY: 1,
|
|
175
|
-
RATE_LIMIT: 120,
|
|
176
|
-
THREADS: 10,
|
|
177
|
-
TIMEOUT: 1,
|
|
178
|
-
HEADER: 'Content-Type: application/xml',
|
|
179
|
-
MATCH_CODES: False, # intentionally omit arg, overriding default value
|
|
180
|
-
'filter_codes': '500',
|
|
181
|
-
'filter_size': '23,33'
|
|
182
|
-
}
|
|
183
|
-
host = 'test.synology.me'
|
|
184
|
-
cls = httpx(host, **run_opts)
|
|
185
|
-
expected_cmd = f"httpx {DEFAULT_HTTPX_FLAGS} -u {host} -json -header 'Content-Type: application/xml' -delay 1s -rate-limit 120 -threads 10 -timeout 1 -filter-code 500 -filter-length 23,33"
|
|
186
|
-
self.assertEqual(cls.cmd, expected_cmd)
|
|
187
|
-
self.assertEqual(cls.print_line, False)
|
|
188
|
-
self.assertEqual(cls.print_item, False)
|
|
189
|
-
self.assertEqual(cls.print_item_count, False)
|
|
190
|
-
self.assertEqual(cls.print_cmd, False)
|
|
191
|
-
self.assertEqual(cls.print_cmd_prefix, False)
|
|
192
|
-
self.assertEqual(cls.output_json, True)
|
|
193
|
-
|
|
194
|
-
def test_httpx_build_cmd_with_opts_with_prefix(self):
|
|
195
|
-
if not httpx in TEST_TASKS:
|
|
196
|
-
return
|
|
197
|
-
run_opts = {
|
|
198
|
-
FOLLOW_REDIRECT: False,
|
|
199
|
-
DELAY: 1,
|
|
200
|
-
RATE_LIMIT: 120,
|
|
201
|
-
THREADS: 10,
|
|
202
|
-
TIMEOUT: 1,
|
|
203
|
-
HEADER: 'Content-Type: application/xml',
|
|
204
|
-
MATCH_CODES: False, # intentionally omit arg, overriding default value
|
|
205
|
-
'filter_code': '200',
|
|
206
|
-
'filter_length': 50,
|
|
207
|
-
'httpx.filter_codes': '500', # prefixed option keys should override
|
|
208
|
-
'httpx_filter_size': '23,33' # prefixed option keys should override
|
|
209
|
-
}
|
|
210
|
-
host = 'test.synology.me'
|
|
211
|
-
cls = httpx(host, **run_opts)
|
|
212
|
-
expected_cmd = f"httpx {DEFAULT_HTTPX_FLAGS} -u {host} -json -header 'Content-Type: application/xml' -delay 1s -rate-limit 120 -threads 10 -timeout 1 -filter-code 500 -filter-length 23,33"
|
|
213
|
-
self.assertEqual(cls.cmd, expected_cmd)
|
|
214
|
-
self.assertEqual(cls.print_line, False)
|
|
215
|
-
self.assertEqual(cls.print_item, False)
|
|
216
|
-
self.assertEqual(cls.print_item_count, False)
|
|
217
|
-
self.assertEqual(cls.print_cmd, False)
|
|
218
|
-
self.assertEqual(cls.print_cmd_prefix, False)
|
|
219
|
-
self.assertEqual(cls.output_json, True)
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
class TestCommandRun(unittest.TestCase, CommandOutputTester):
|
|
223
|
-
|
|
224
|
-
def setUp(self):
|
|
225
|
-
warnings.simplefilter('ignore', category=ResourceWarning)
|
|
226
|
-
warnings.simplefilter('ignore', category=DeprecationWarning)
|
|
227
|
-
|
|
228
|
-
def _valid_fixture(self, cls, fixture):
|
|
229
|
-
if not fixture:
|
|
230
|
-
if len(FIXTURES_TASKS.keys()) == 1: # make test fail.
|
|
231
|
-
raise AssertionError(f'No fixture for {cls.__name__}! Add one to the tests/fixtures directory (must not be an empty file / empty json / empty list).')
|
|
232
|
-
console.print(f'[dim gold3] skipped (no fixture)[/]')
|
|
233
|
-
return False
|
|
234
|
-
return True
|
|
235
|
-
|
|
236
|
-
def test_cmd_converted_schema(self):
|
|
237
|
-
console.print('')
|
|
238
|
-
|
|
239
|
-
for cls, fixture in FIXTURES_TASKS.items():
|
|
240
|
-
console.print(f'\t[bold grey35]{cls.__name__} ...[/] ', end='')
|
|
241
|
-
with self.subTest(name=cls.__name__):
|
|
242
|
-
|
|
243
|
-
# Validate fixture
|
|
244
|
-
if not self._valid_fixture(cls, fixture):
|
|
245
|
-
continue
|
|
246
|
-
|
|
247
|
-
# Run command
|
|
248
|
-
targets = INPUTS_TASKS[cls.input_type]
|
|
249
|
-
|
|
250
|
-
with mock_command(cls, targets, META_OPTS, fixture, 'run') as results:
|
|
251
|
-
self._test_task_output(
|
|
252
|
-
results,
|
|
253
|
-
expected_output_types=cls.output_types)
|
|
254
|
-
|
|
255
|
-
def test_cmd_original_schema(self):
|
|
256
|
-
console.print('')
|
|
257
|
-
for cls, fixture in FIXTURES_TASKS.items():
|
|
258
|
-
|
|
259
|
-
with self.subTest(name=cls.__name__):
|
|
260
|
-
console.print(f'\t[bold grey35]{cls.__name__} ...[/]', end='')
|
|
261
|
-
|
|
262
|
-
# Validate fixture
|
|
263
|
-
if not self._valid_fixture(cls, fixture):
|
|
264
|
-
continue
|
|
265
|
-
|
|
266
|
-
# Get expected output keys from fixture
|
|
267
|
-
expected_output_keys = None
|
|
268
|
-
if isinstance(fixture, dict):
|
|
269
|
-
if 'results' in fixture: # fix for JSON files having a 'results' key
|
|
270
|
-
expected_output_keys = fixture['results'][0].keys()
|
|
271
|
-
else:
|
|
272
|
-
expected_output_keys = fixture.keys()
|
|
273
|
-
|
|
274
|
-
# Run command
|
|
275
|
-
targets = INPUTS_TASKS[cls.input_type]
|
|
276
|
-
opts = copy.deepcopy(META_OPTS)
|
|
277
|
-
opts.update({
|
|
278
|
-
'orig': True,
|
|
279
|
-
'raw': isinstance(fixture, str)
|
|
280
|
-
})
|
|
281
|
-
with mock_command(cls, targets, opts, fixture, 'run') as results:
|
|
282
|
-
if not len(cls.output_types) == 1:
|
|
283
|
-
console.print(f'[dim gold3] skipped (multi-output task with single schema)[/]')
|
|
284
|
-
return
|
|
285
|
-
self._test_task_output(
|
|
286
|
-
results,
|
|
287
|
-
expected_output_keys=expected_output_keys)
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
class TestCommandHooks(unittest.TestCase):
|
|
291
|
-
|
|
292
|
-
def test_cmd_hooks(self):
|
|
293
|
-
if not httpx in TEST_TASKS:
|
|
294
|
-
return
|
|
295
|
-
|
|
296
|
-
def on_item_pre_convert(self, item):
|
|
297
|
-
item['url'] = 'test_changed_url'
|
|
298
|
-
return item
|
|
299
|
-
|
|
300
|
-
def on_item(self, item):
|
|
301
|
-
item.status_code = 500
|
|
302
|
-
return item
|
|
303
|
-
|
|
304
|
-
def on_end(self):
|
|
305
|
-
self.results = [{'url': 'test_changed_result'}]
|
|
306
|
-
|
|
307
|
-
def on_init(self):
|
|
308
|
-
self.cmd = 'test_changed_cmd_init'
|
|
309
|
-
self.run_opts = {}
|
|
310
|
-
|
|
311
|
-
def on_start(self):
|
|
312
|
-
self.cmd = 'test_changed_cmd_start'
|
|
313
|
-
|
|
314
|
-
hooks = {
|
|
315
|
-
'on_init': [on_init],
|
|
316
|
-
'on_start': [on_start],
|
|
317
|
-
'on_end': [on_end],
|
|
318
|
-
'on_item_pre_convert': [on_item_pre_convert],
|
|
319
|
-
'on_item': [on_item],
|
|
320
|
-
'on_end': [on_end],
|
|
321
|
-
}
|
|
322
|
-
fixture = load_fixture('httpx_output', FIXTURES_DIR)
|
|
323
|
-
with mock_subprocess_popen([json.dumps(fixture)]):
|
|
324
|
-
input = INPUTS_TASKS[HOST]
|
|
325
|
-
cls = httpx(input, hooks=hooks)
|
|
326
|
-
self.assertEqual(cls.cmd.split(' ')[0], 'test_changed_cmd_init')
|
|
327
|
-
items = cls.run()
|
|
328
|
-
item = items[0]
|
|
329
|
-
self.assertEqual(item.status_code, 500)
|
|
330
|
-
self.assertEqual(item.url, 'test_changed_url')
|
|
331
|
-
self.assertEqual(cls.cmd.split(' ')[0], 'test_changed_cmd_start')
|
|
332
|
-
self.assertEqual(cls.results, [{'url': 'test_changed_result'}])
|
|
333
|
-
|
|
334
|
-
def test_cmd_failed_hook(self):
|
|
335
|
-
if not httpx in TEST_TASKS:
|
|
336
|
-
return
|
|
337
|
-
|
|
338
|
-
def on_init(self):
|
|
339
|
-
raise Exception('Test passed')
|
|
340
|
-
|
|
341
|
-
hooks = {
|
|
342
|
-
'on_init': [on_init]
|
|
343
|
-
}
|
|
344
|
-
fixture = FIXTURES_TASKS[httpx]
|
|
345
|
-
with mock_subprocess_popen([json.dumps(fixture)]):
|
|
346
|
-
with self.assertRaises(Exception, msg='Test passed'):
|
|
347
|
-
input = INPUTS_TASKS[HOST]
|
|
348
|
-
httpx(input, hooks=hooks)
|
tests/unit/test_workflows.py
DELETED
|
@@ -1,96 +0,0 @@
|
|
|
1
|
-
from celery import chain
|
|
2
|
-
from secator.celery import app
|
|
3
|
-
from secator.tasks import httpx
|
|
4
|
-
import unittest
|
|
5
|
-
import json
|
|
6
|
-
from secator.definitions import DEBUG
|
|
7
|
-
from secator.utils_test import mock_command, FIXTURES_TASKS, TEST_TASKS
|
|
8
|
-
from secator.celery import forward_results
|
|
9
|
-
from secator.rich import console
|
|
10
|
-
|
|
11
|
-
TARGETS = ['bing.com', 'google.com', 'wikipedia.org', 'ibm.com', 'cnn.com', 'karate.com']
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
class TestAdHocWorkflow(unittest.TestCase):
|
|
15
|
-
|
|
16
|
-
def test_chain(self):
|
|
17
|
-
if not httpx in TEST_TASKS:
|
|
18
|
-
return
|
|
19
|
-
|
|
20
|
-
with mock_command(httpx, fixture=[FIXTURES_TASKS[httpx]] * len(TARGETS)):
|
|
21
|
-
sigs = [forward_results.si([])] + [httpx.s(target) for target in TARGETS]
|
|
22
|
-
workflow = chain(*sigs)
|
|
23
|
-
result = workflow.apply()
|
|
24
|
-
results = result.get()
|
|
25
|
-
if DEBUG > 1:
|
|
26
|
-
console.print_json(json.dumps(results))
|
|
27
|
-
urls = [r.url for r in results]
|
|
28
|
-
self.assertEqual(len(urls), len(TARGETS))
|
|
29
|
-
|
|
30
|
-
# def test_chain_with_results(self):
|
|
31
|
-
# existing_results = [{
|
|
32
|
-
# "url": "https://example.synology.me",
|
|
33
|
-
# "method": "GET",
|
|
34
|
-
# "status_code": 200,
|
|
35
|
-
# "words": 438,
|
|
36
|
-
# "lines": 136,
|
|
37
|
-
# "content_type":
|
|
38
|
-
# "text/html",
|
|
39
|
-
# "content_length": 11577,
|
|
40
|
-
# "host": "82.66.157.114",
|
|
41
|
-
# "time": 0.16246860100000002,
|
|
42
|
-
# "_source": "httpx",
|
|
43
|
-
# "_type": "url"
|
|
44
|
-
# }]
|
|
45
|
-
# with mock_command(httpx, fixture=[FIXTURES_TASKS[httpx]] * len(TARGETS)):
|
|
46
|
-
# sigs = [httpx.s(target) for target in TARGETS]
|
|
47
|
-
# sigs = [forward_results.si(existing_results)] + sigs
|
|
48
|
-
# workflow = chain(*sigs)
|
|
49
|
-
# result = workflow.apply()
|
|
50
|
-
# results = result.get()
|
|
51
|
-
# if DEBUG:
|
|
52
|
-
# console.print_json(json.dumps(results))
|
|
53
|
-
# urls = [r['url'] for r in results]
|
|
54
|
-
# self.assertEqual(len(urls), len(TARGETS))
|
|
55
|
-
# self.assertIn(existing_results[0], results)
|
|
56
|
-
|
|
57
|
-
# def test_complex_workflow():
|
|
58
|
-
# targets = ['bing.com', 'google.com', 'wikipedia.org', 'ibm.com', 'cnn.com', 'karate.com']
|
|
59
|
-
# task = chain(
|
|
60
|
-
# forward_results.s([]),
|
|
61
|
-
# httpx().s(targets[0]),
|
|
62
|
-
# chord((
|
|
63
|
-
# httpx().s(targets[1]),
|
|
64
|
-
# httpx().s(targets[2]),
|
|
65
|
-
# ), forward_results.s()),
|
|
66
|
-
# httpx().s(targets[3]),
|
|
67
|
-
# chord((
|
|
68
|
-
# httpx().s(targets[4]),
|
|
69
|
-
# httpx().s(targets[5]),
|
|
70
|
-
# ), forward_results.s())
|
|
71
|
-
# )
|
|
72
|
-
# workflow = task.delay()
|
|
73
|
-
# results = workflow.get()
|
|
74
|
-
# urls = [r['url'] for r in results]
|
|
75
|
-
# print(urls)
|
|
76
|
-
# return workflow
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
# def test_nested_collect():
|
|
80
|
-
# console.log(task)
|
|
81
|
-
# workflow = task.delay()
|
|
82
|
-
# results = workflow.get()
|
|
83
|
-
# console.print_item(json.dumps(results))
|
|
84
|
-
# # results = get_results(workflow)
|
|
85
|
-
# # console.log(results)
|
|
86
|
-
# # console.log([r['url'] for r in results])
|
|
87
|
-
# # urls = [r['url'] for r in results]
|
|
88
|
-
# # for target in targets:
|
|
89
|
-
# # assert any(target in url for url in urls)
|
|
90
|
-
# return workflow
|
|
91
|
-
|
|
92
|
-
# # Polling approach
|
|
93
|
-
# # for task_id, name, result in poll_task(find_root_task(workflow), seen):
|
|
94
|
-
# # print(task_id, name, result)
|
|
95
|
-
# # results.append(result)
|
|
96
|
-
# # print([r for r in results if r._type == 'url'])
|
|
File without changes
|
|
File without changes
|