mirror of https://gitlab.com/bashrc2/epicyon
Static analysis for thread function arguments
parent
12b112ae97
commit
0fddc2204d
|
@ -1633,9 +1633,10 @@ class PubServer(BaseHTTPRequestHandler):
|
|||
account_outbox_thread_name + '/' +
|
||||
str(self.server.outbox_thread_index[account_outbox_thread_name]))
|
||||
print('THREAD: _post_to_outbox')
|
||||
message_json_copy = message_json.copy()
|
||||
self.server.outboxThread[account_outbox_thread_name][index] = \
|
||||
thread_with_trace(target=self._post_to_outbox,
|
||||
args=(message_json.copy(),
|
||||
args=(message_json_copy,
|
||||
self.server.project_version, None,
|
||||
curr_session, proxy_type),
|
||||
daemon=True)
|
||||
|
@ -21111,12 +21112,15 @@ def run_daemon(check_actor_timeout: int,
|
|||
args=(base_dir, httpd.fitness), daemon=True)
|
||||
httpd.thrFitness.start()
|
||||
|
||||
httpd.recent_posts_cache = {}
|
||||
|
||||
print('THREAD: Creating cache expiry thread')
|
||||
httpd.thrCache = \
|
||||
thread_with_trace(target=expire_cache,
|
||||
args=(base_dir, httpd.person_cache,
|
||||
httpd.http_prefix,
|
||||
archive_dir,
|
||||
httpd.recent_posts_cache,
|
||||
httpd.maxPostsInBox), daemon=True)
|
||||
httpd.thrCache.start()
|
||||
|
||||
|
@ -21150,7 +21154,6 @@ def run_daemon(check_actor_timeout: int,
|
|||
else:
|
||||
httpd.thrSharesExpire.start()
|
||||
|
||||
httpd.recent_posts_cache = {}
|
||||
httpd.max_recent_posts = max_recent_posts
|
||||
httpd.iconsCache = {}
|
||||
httpd.fontsCache = {}
|
||||
|
|
17
posts.py
17
posts.py
|
@ -2495,14 +2495,16 @@ def send_post(signing_priv_key_pem: str, project_version: str,
|
|||
send_threads.pop(0)
|
||||
print('WARN: thread killed')
|
||||
print('THREAD: thread_send_post')
|
||||
signature_header_json_copy = signature_header_json.copy()
|
||||
signature_header_json_ld_copy = signature_header_json_ld.copy()
|
||||
thr = \
|
||||
thread_with_trace(target=thread_send_post,
|
||||
args=(session,
|
||||
post_json_str,
|
||||
federation_list,
|
||||
inbox_url, base_dir,
|
||||
signature_header_json.copy(),
|
||||
signature_header_json_ld.copy(),
|
||||
signature_header_json_copy,
|
||||
signature_header_json_ld_copy,
|
||||
post_log, debug, http_prefix,
|
||||
domain_full), daemon=True)
|
||||
send_threads.append(thr)
|
||||
|
@ -2905,14 +2907,16 @@ def send_signed_json(post_json_object: {}, session, base_dir: str,
|
|||
pprint(post_json_object)
|
||||
domain_full = get_full_domain(domain, port)
|
||||
print('THREAD: thread_send_post 2')
|
||||
signature_header_json_copy = signature_header_json.copy(),
|
||||
signature_header_json_ld_copy = signature_header_json_ld.copy(),
|
||||
thr = \
|
||||
thread_with_trace(target=thread_send_post,
|
||||
args=(session,
|
||||
post_json_str,
|
||||
federation_list,
|
||||
inbox_url, base_dir,
|
||||
signature_header_json.copy(),
|
||||
signature_header_json_ld.copy(),
|
||||
signature_header_json_copy,
|
||||
signature_header_json_ld_copy,
|
||||
post_log, debug,
|
||||
http_prefix, domain_full), daemon=True)
|
||||
send_threads.append(thr)
|
||||
|
@ -3488,6 +3492,7 @@ def send_to_followers_thread(server, session, session_onion, session_i2p,
|
|||
"""Returns a thread used to send a post to followers
|
||||
"""
|
||||
print('THREAD: send_to_followers')
|
||||
post_json_object_copy = post_json_object.copy()
|
||||
send_thread = \
|
||||
thread_with_trace(target=send_to_followers,
|
||||
args=(server, session, session_onion, session_i2p,
|
||||
|
@ -3496,7 +3501,7 @@ def send_to_followers_thread(server, session, session_onion, session_i2p,
|
|||
http_prefix, federation_list,
|
||||
send_threads, post_log,
|
||||
cached_webfingers, person_cache,
|
||||
post_json_object.copy(), debug,
|
||||
post_json_object_copy, debug,
|
||||
project_version,
|
||||
shared_items_federated_domains,
|
||||
shared_item_federation_tokens,
|
||||
|
@ -4118,7 +4123,7 @@ def _create_box_indexed(recent_posts_cache: {},
|
|||
def expire_cache(base_dir: str, person_cache: {},
|
||||
http_prefix: str, archive_dir: str,
|
||||
recent_posts_cache: {},
|
||||
max_posts_in_box=32000):
|
||||
max_posts_in_box: int):
|
||||
"""Thread used to expire actors from the cache and archive old posts
|
||||
"""
|
||||
while True:
|
||||
|
|
121
tests.py
121
tests.py
|
@ -678,7 +678,7 @@ def _test_cache():
|
|||
assert result['test'] == 'This is a test'
|
||||
|
||||
|
||||
def _test_threads_function(param: str):
|
||||
def _test_threads_function(param1: str, param2: str):
|
||||
for _ in range(10000):
|
||||
time.sleep(2)
|
||||
|
||||
|
@ -687,7 +687,7 @@ def _test_threads():
|
|||
print('test_threads')
|
||||
thr = \
|
||||
thread_with_trace(target=_test_threads_function,
|
||||
args=('test',),
|
||||
args=('test', 'test2'),
|
||||
daemon=True)
|
||||
thr.start()
|
||||
assert thr.is_alive() is True
|
||||
|
@ -4869,6 +4869,122 @@ def _test_post_field_names(source_file: str, fieldnames: []):
|
|||
assert False
|
||||
|
||||
|
||||
def _test_thread_functions():
|
||||
print('test_thread_functions')
|
||||
modules = {}
|
||||
threads_called_in_modules = []
|
||||
|
||||
# get the source for each module
|
||||
for _, _, files in os.walk('.'):
|
||||
for source_file in files:
|
||||
if not source_file.endswith('.py'):
|
||||
continue
|
||||
if source_file.startswith('.#'):
|
||||
continue
|
||||
if source_file.startswith('flycheck_'):
|
||||
continue
|
||||
mod_name = source_file.replace('.py', '')
|
||||
if mod_name == 'threads':
|
||||
# don't test the threads module itself
|
||||
continue
|
||||
modules[mod_name] = {
|
||||
'functions': []
|
||||
}
|
||||
source_str = ''
|
||||
with open(source_file, 'r') as fp_src:
|
||||
source_str = fp_src.read()
|
||||
modules[mod_name]['source'] = source_str
|
||||
if 'thread_with_trace(' in source_str:
|
||||
threads_called_in_modules.append(mod_name)
|
||||
with open(source_file, 'r') as fp_src:
|
||||
lines = fp_src.readlines()
|
||||
modules[mod_name]['lines'] = lines
|
||||
|
||||
for mod_name in threads_called_in_modules:
|
||||
thread_sections = \
|
||||
modules[mod_name]['source'].split('thread_with_trace(')
|
||||
ctr = 0
|
||||
for thread_str in thread_sections:
|
||||
if ctr == 0 or ',' not in thread_str:
|
||||
ctr += 1
|
||||
continue
|
||||
thread_function_args = thread_str.split(',')
|
||||
first_parameter = thread_function_args[0]
|
||||
if 'target=' not in first_parameter:
|
||||
ctr += 1
|
||||
continue
|
||||
thread_function_name = first_parameter.split('target=')[1].strip()
|
||||
if not thread_function_name:
|
||||
ctr += 1
|
||||
continue
|
||||
if thread_function_name.startswith('self.'):
|
||||
thread_function_name = thread_function_name.split('self.')[1]
|
||||
# is this function declared at the top of the module
|
||||
# or defined within the module?
|
||||
import_str = ' import ' + thread_function_name
|
||||
def_str = 'def ' + thread_function_name + '('
|
||||
if import_str not in modules[mod_name]['source']:
|
||||
if def_str not in modules[mod_name]['source']:
|
||||
print(mod_name + ' ' + first_parameter)
|
||||
print(import_str + ' not in ' + mod_name)
|
||||
assert(False)
|
||||
if def_str in modules[mod_name]['source']:
|
||||
defininition_module = mod_name
|
||||
else:
|
||||
# which module is the thread function defined within?
|
||||
test_str = modules[mod_name]['source'].split(import_str)[0]
|
||||
defininition_module = test_str.split('from ')[-1]
|
||||
print('Thread function ' + thread_function_name +
|
||||
' defined in ' + defininition_module)
|
||||
# check the function arguments
|
||||
second_parameter = thread_function_args[1]
|
||||
if 'args=' not in second_parameter:
|
||||
print('No args parameter in ' + thread_function_name +
|
||||
' module ' + mod_name)
|
||||
ctr += 1
|
||||
continue
|
||||
arg_ctr = 0
|
||||
calling_function_args_list = []
|
||||
for func_arg in thread_function_args:
|
||||
if arg_ctr == 0:
|
||||
arg_ctr += 1
|
||||
continue
|
||||
last_arg = False
|
||||
if '(' in func_arg:
|
||||
func_arg = func_arg.split('(')[1]
|
||||
|
||||
if func_arg.endswith(')'):
|
||||
func_arg = func_arg.split(')')[0]
|
||||
last_arg = True
|
||||
func_arg = func_arg.strip()
|
||||
calling_function_args_list.append(func_arg)
|
||||
if last_arg:
|
||||
break
|
||||
arg_ctr += 1
|
||||
# print(mod_name + ' ' + thread_function_name + ' ' +
|
||||
# str(calling_function_args_list))
|
||||
# get the function definition arguments
|
||||
test_str = \
|
||||
modules[defininition_module]['source'].split(def_str)[1]
|
||||
test_str = test_str.split(')')[0]
|
||||
definition_function_args_list = test_str.split(',')
|
||||
if len(definition_function_args_list) > 0:
|
||||
if definition_function_args_list[0] == 'self':
|
||||
definition_function_args_list = \
|
||||
definition_function_args_list[1:]
|
||||
if len(definition_function_args_list) != \
|
||||
len(calling_function_args_list):
|
||||
print('Thread function ' + thread_function_name +
|
||||
' has ' + str(len(definition_function_args_list)) +
|
||||
' arguments, but ' +
|
||||
str(len(calling_function_args_list)) +
|
||||
' were given in module ' + mod_name)
|
||||
print(str(definition_function_args_list))
|
||||
print(str(calling_function_args_list))
|
||||
assert(False)
|
||||
ctr += 1
|
||||
|
||||
|
||||
def _test_functions():
|
||||
print('test_functions')
|
||||
function = {}
|
||||
|
@ -6779,6 +6895,7 @@ def run_all_tests():
|
|||
['queue_json', 'post_json_object',
|
||||
'message_json', 'liked_post_json'])
|
||||
_test_checkbox_names()
|
||||
_test_thread_functions()
|
||||
_test_functions()
|
||||
_test_bold_reading()
|
||||
_test_published_to_local_timezone()
|
||||
|
|
Loading…
Reference in New Issue