Initial server source import
This commit is contained in:
@@ -0,0 +1,90 @@
|
||||
import ctypes
|
||||
import os
|
||||
from pathlib import Path
|
||||
import sys
|
||||
import tempfile
|
||||
import unittest
|
||||
from unittest import mock
|
||||
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[1]
|
||||
APP_DIR = ROOT / 'app'
|
||||
sys.path.insert(0, str(APP_DIR))
|
||||
|
||||
import console_runner
|
||||
import owned_process
|
||||
import process_identity
|
||||
import runtime_security
|
||||
|
||||
|
||||
@unittest.skipUnless(os.name == 'nt', 'Windows native binding stability')
|
||||
class NativeBindingStabilityTests(unittest.TestCase):
|
||||
def test_hot_native_paths_are_warm_stable(self):
|
||||
from ctypes import wintypes
|
||||
|
||||
kernel32 = ctypes.WinDLL('kernel32', use_last_error=True)
|
||||
pointer_dword = ctypes.POINTER(wintypes.DWORD)
|
||||
get_handle_count = kernel32.GetProcessHandleCount
|
||||
get_handle_count.argtypes = [wintypes.HANDLE, pointer_dword]
|
||||
get_handle_count.restype = wintypes.BOOL
|
||||
get_current_process = kernel32.GetCurrentProcess
|
||||
get_current_process.argtypes = []
|
||||
get_current_process.restype = wintypes.HANDLE
|
||||
|
||||
def handle_count():
|
||||
value = wintypes.DWORD()
|
||||
self.assertTrue(get_handle_count(get_current_process(), ctypes.byref(value)))
|
||||
return int(value.value)
|
||||
|
||||
type_ids = (
|
||||
id(runtime_security._OVERLAPPED),
|
||||
id(runtime_security._SECURITY_ATTRIBUTES),
|
||||
id(runtime_security._TOKEN_USER),
|
||||
id(process_identity._FILETIME),
|
||||
id(process_identity._UNICODE_STRING),
|
||||
id(console_runner._PROCESS_MEMORY_COUNTERS_EX),
|
||||
id(owned_process._JOBOBJECT_EXTENDED_LIMIT_INFORMATION),
|
||||
)
|
||||
with tempfile.TemporaryDirectory() as temp_dir:
|
||||
runtime_security.ensure_private_directory(temp_dir, reject_reparse=True)
|
||||
lock_path = os.path.join(temp_dir, 'warm.lock')
|
||||
|
||||
def exercise():
|
||||
lock = runtime_security.PrivateFileLock(lock_path).acquire()
|
||||
lock.release()
|
||||
self.assertTrue(runtime_security.private_file_ready(lock_path))
|
||||
process_identity.current_process_identity()
|
||||
console_runner.current_process_private_bytes()
|
||||
owned_process._windows_job_limit_information(1024 * 1024)
|
||||
|
||||
for _ in range(2000):
|
||||
exercise()
|
||||
memory_before = console_runner.current_process_private_bytes()
|
||||
handles_before = handle_count()
|
||||
with mock.patch.object(
|
||||
ctypes, 'POINTER', side_effect=AssertionError('hot ctypes.POINTER call'),
|
||||
), mock.patch.object(
|
||||
ctypes, 'WinDLL', side_effect=AssertionError('hot ctypes.WinDLL call'),
|
||||
):
|
||||
for _ in range(20000):
|
||||
exercise()
|
||||
memory_after = console_runner.current_process_private_bytes()
|
||||
handles_after = handle_count()
|
||||
|
||||
self.assertEqual(type_ids, (
|
||||
id(runtime_security._OVERLAPPED),
|
||||
id(runtime_security._SECURITY_ATTRIBUTES),
|
||||
id(runtime_security._TOKEN_USER),
|
||||
id(process_identity._FILETIME),
|
||||
id(process_identity._UNICODE_STRING),
|
||||
id(console_runner._PROCESS_MEMORY_COUNTERS_EX),
|
||||
id(owned_process._JOBOBJECT_EXTENDED_LIMIT_INFORMATION),
|
||||
))
|
||||
growth = max(0, memory_after - memory_before)
|
||||
self.assertLessEqual(growth, 16 * 1024 * 1024)
|
||||
self.assertLessEqual(growth / 20000, 256)
|
||||
self.assertLessEqual(abs(handles_after - handles_before), 8)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
Reference in New Issue
Block a user