Improve logical block spacing

Signed-off-by: Loren Eteval <loren.eteval@proton.me>
This commit is contained in:
Loren Eteval
2026-09-19 11:21:23 +08:00
parent 67c76a48b9
commit 5b1699c9d0
9 changed files with 111 additions and 0 deletions
+1
View File
@@ -221,6 +221,7 @@ class GuiHy1ItemTLSInsecure(GuiEditorItemTextSwitch):
config['insecure'] = False
return True
if oldChecked is False:
return False
+1
View File
@@ -61,6 +61,7 @@ def fixLogObjectPath(config, attr: str, value: str, log=True):
config['log'][attr] = absolutePath(path)
result = config['log'][attr]
if result:
try:
with open(result, 'x', encoding='utf-8'):
+4
View File
@@ -133,6 +133,7 @@ def configureXrayStats(
config['api'] = currentApi
configuredServer = currentApi.get('listen')
if not isinstance(configuredServer, str) or not configuredServer.strip():
configuredServer = None
@@ -143,6 +144,7 @@ def configureXrayStats(
currentApi['listen'] = apiServer
services = currentApi.get('services', [])
if not isinstance(services, list):
services = []
@@ -159,11 +161,13 @@ def configureXrayStats(
config['stats'] = generated['stats']
policy = config.get('policy')
if not isinstance(policy, dict):
policy = {}
config['policy'] = policy
systemPolicy = policy.get('system')
if not isinstance(systemPolicy, dict):
systemPolicy = {}
policy['system'] = systemPolicy
+1
View File
@@ -420,6 +420,7 @@ class PluginRegistry:
for configType in configurationTypes:
self._configurationFactories[configType] = entry
for runtimeType in runtimeTypes:
self._runtimeFactories[runtimeType] = entry
elif isinstance(capability, TrafficStatsProvider):
+43
View File
@@ -272,6 +272,7 @@ class _RequestPayload:
def runNetworkProbe(iterations=100):
"""Verify native teardown releases both reply registries under compilation."""
application()
result = {}
for managerType, contextAttribute in (
@@ -286,8 +287,10 @@ def runNetworkProbe(iterations=100):
manager = managerType()
payload = _RequestPayload()
reply = _PendingReply(manager)
references.extend((weakref.ref(payload), weakref.ref(reply)))
reply.destroyed.connect(lambda *_args: destroyed.append(True))
manager.get = lambda _request: reply
if isinstance(manager, HttpGetManager):
@@ -306,6 +309,7 @@ def runNetworkProbe(iterations=100):
manager.deleteLater()
processQtEvents()
assert not isValid(reply)
assert not getattr(manager, contextAttribute)
@@ -317,6 +321,7 @@ def runNetworkProbe(iterations=100):
assert len(destroyed) == iterations
assert all(reference() is None for reference in references)
result[managerType.__name__ + ':' + terminal] = iterations
return result
@@ -325,18 +330,22 @@ def runNetworkProbe(iterations=100):
def runInfrastructureProbe(iterations=100):
"""Check signal, mask, and animation ownership under real Qt destruction."""
application()
result = {}
for closeMethod in CLOSE_METHODS:
destroyed = []
for _ in range(iterations):
dialog = AppQDialog()
dialog.destroyed.connect(lambda *_args: destroyed.append(True))
reference = weakref.ref(dialog)
key = dialog._lifetimeKey
dialog.open()
getattr(dialog, closeMethod)()
dialog.open()
del dialog
processQtEvents()
@@ -346,37 +355,49 @@ def runInfrastructureProbe(iterations=100):
getattr(reference(), closeMethod)()
processQtEvents()
assert reference() is None
assert key not in AppQDialog._openDialogs
assert len(destroyed) == iterations
result['reopenAfter' + closeMethod.title()] = iterations
routingReferences = []
routingDestroyed = []
for _ in range(iterations):
dialog = RoutingRulesDialog({'rules': [{'ruleTag': 'keep'}]})
dialog.open()
dialog.listView.setCurrentIndex(dialog.listView.rulesModel.index(0, 0))
dialog.deleteRule()
confirmation = next(
item
for item in AppQDialog._openDialogs.values()
if isinstance(item, AppQMessageBox)
)
for item in (dialog, confirmation):
routingReferences.append(weakref.ref(item))
item.destroyed.connect(lambda *_args: routingDestroyed.append(True))
del item
dialog.deleteLater()
processQtEvents()
assert not isValid(dialog) and not isValid(confirmation)
del dialog, confirmation
collectAtBoundary()
assert len(routingDestroyed) == iterations * 2
assert all(reference() is None for reference in routingReferences)
assert not AppQDialog._openDialogs
result['routingOwnerFirst'] = iterations
for senderFirst in (True, False):
@@ -403,6 +424,7 @@ def runInfrastructureProbe(iterations=100):
counts.append(survivor.receivers(QtCore.SIGNAL('destroyed(QObject*)')))
assert counts == [counts[0]] * iterations, counts
result['senderFirst' if senderFirst else 'receiverFirst'] = iterations
survivor.deleteLater()
@@ -421,6 +443,7 @@ def runInfrastructureProbe(iterations=100):
)
transition.apply(lambda: None)
animation = next(iter(transition._animations))
overlay = window.findChild(QWidget, transition.OverlayObjectName)
@@ -435,6 +458,7 @@ def runInfrastructureProbe(iterations=100):
else:
transition.deleteLater()
processQtEvents()
window.deleteLater()
processQtEvents()
@@ -463,6 +487,7 @@ def runInfrastructureProbe(iterations=100):
assert not isValid(mask)
assert not AppQDialog._openDialogs
result['messageBoxDeleted'] = iterations
finally:
owner.deleteLater()
@@ -474,63 +499,81 @@ def runInfrastructureProbe(iterations=100):
def runConfirmationProbe(iterations=100):
"""Check native menu ownership and representative view-owned prompts."""
application()
result = {}
for explicitOwner in (False, True):
references = []
destroyed = []
for _ in range(iterations):
owner = QWidget()
menu = AppQMenu(parent=owner if explicitOwner else None)
action = AppQAction('Menu fixture', menu=menu, parent=owner)
references.append(weakref.ref(menu))
menu.destroyed.connect(lambda *_args: destroyed.append(True))
action.deleteLater()
processQtEvents()
assert not isValid(action)
assert isValid(menu) == explicitOwner
owner.deleteLater()
processQtEvents()
del action, menu, owner
assert len(destroyed) == iterations
assert all(reference() is None for reference in references)
result['widgetOwnedMenu' if explicitOwner else 'actionOwnedMenu'] = iterations
originalAssetDirectory = assetModule.XRAY_ASSET_DIR
try:
with tempfile.TemporaryDirectory() as directory:
assetModule.XRAY_ASSET_DIR = Path(directory)
asset = Path(directory) / 'fixture.dat'
asset.write_bytes(b'keep')
for overwrite in (False, True):
references = []
destroyed = []
for _ in range(iterations):
owner = QWidget()
view = XrayAssetListView(parent=owner)
view.setCurrentIndex(view.model().index(0, 0))
if overwrite:
view.appendNewItem(str(asset))
else:
view.deleteSelectedItem()
confirmation = next(iter(AppQDialog._openDialogs.values()))
references.append(weakref.ref(confirmation))
confirmation.destroyed.connect(
lambda *_args: destroyed.append(True)
)
view.deleteLater()
processQtEvents()
assert not isValid(view) and not isValid(confirmation)
assert isValid(owner)
assert asset.read_bytes() == b'keep'
owner.deleteLater()
processQtEvents()
del confirmation, view, owner
assert len(destroyed) == iterations
assert all(reference() is None for reference in references)
assert not AppQDialog._openDialogs
result[
'assetOverwriteOwnerFirst' if overwrite else 'assetDeleteOwnerFirst'
] = iterations
+41
View File
@@ -1528,6 +1528,7 @@ class VeryHeavyGenerationLogManagerTest(unittest.TestCase):
return time.perf_counter_ns() - started
matrix = []
for size in (100, 1_000, 10_000):
samples = {
name: []
@@ -1544,13 +1545,16 @@ class VeryHeavyGenerationLogManagerTest(unittest.TestCase):
'oldest_eviction',
)
}
for _repetition in range(5):
manager = LogManager(
maximumEntries=size * 2 + 10,
autoClearMaximumEntries=size,
)
for index in range(size):
manager.append(str(index), CORE_LOG_CATEGORY)
samples['normal_append'].append(
elapsed(lambda: manager.append('ordinary'))
)
@@ -1559,22 +1563,27 @@ class VeryHeavyGenerationLogManagerTest(unittest.TestCase):
)
manager = LogManager(maximumEntries=size + 10, autoClearEnabled=False)
for index in range(size):
manager.append(str(index), CORE_LOG_CATEGORY)
samples['category_snapshot'].append(
elapsed(lambda: manager.snapshot(CORE_LOG_CATEGORY))
)
samples['runtime_clear'].append(
elapsed(lambda: manager.clear(runtimeOnly=True))
)
with manager._lock:
samples['cleanup_64'].append(
elapsed(lambda: manager._cleanupRetiredLocked())
)
manager = LogManager(maximumEntries=size + 10, autoClearEnabled=False)
for index in range(size):
manager.append(str(index), APPLICATION_LOG_CATEGORY)
samples['sole_category_clear'].append(
elapsed(lambda: manager.clear(APPLICATION_LOG_CATEGORY))
)
@@ -1583,14 +1592,17 @@ class VeryHeavyGenerationLogManagerTest(unittest.TestCase):
maximumEntries=size * 2 + 10,
autoClearEnabled=False,
)
for index in range(size):
manager.append(str(index), CORE_LOG_CATEGORY)
manager.append('shared', TUN2SOCKS_LOG_CATEGORY)
samples['shared_category_clear'].append(
elapsed(lambda: manager.clear(CORE_LOG_CATEGORY))
)
manager = LogManager(maximumEntries=size + 10, autoClearEnabled=False)
for index in range(size):
manager.append(
str(index),
@@ -1600,10 +1612,12 @@ class VeryHeavyGenerationLogManagerTest(unittest.TestCase):
TUN2SOCKS_LOG_CATEGORY,
)[index % 3],
)
samples['global_snapshot'].append(elapsed(lambda: manager.snapshot()))
samples['clear_all'].append(elapsed(lambda: manager.clear()))
manager = LogManager(maximumEntries=size, autoClearEnabled=False)
for index in range(size):
manager.append(
str(index),
@@ -1613,6 +1627,7 @@ class VeryHeavyGenerationLogManagerTest(unittest.TestCase):
TUN2SOCKS_LOG_CATEGORY,
)[index % 3],
)
samples['oldest_eviction'].append(
elapsed(lambda: manager.append('evict'))
)
@@ -1632,6 +1647,7 @@ class VeryHeavyGenerationLogManagerTest(unittest.TestCase):
for name in matrix[0]
if name != 'n'
}
for name in (
'normal_append_us',
'core_rollover_us',
@@ -1642,6 +1658,7 @@ class VeryHeavyGenerationLogManagerTest(unittest.TestCase):
'oldest_eviction_us',
):
self.assertLess(ratios[name], 50)
self.report('operation-scaling-matrix', samples=matrix, ratios=ratios)
def testAppendLatencyWithRolloverRetentionAndBacklog(self):
@@ -1715,8 +1732,10 @@ class VeryHeavyGenerationLogManagerTest(unittest.TestCase):
def testCleanupLatencyDoesNotScaleWithBacklog(self):
"""Keep append cleanup capped at one for geometrically larger queues."""
results = []
for backlog in (64, 1_000, 10_000):
samples = []
for _repetition in range(9):
manager = LogManager(
maximumEntries=backlog + 10,
@@ -1726,17 +1745,25 @@ class VeryHeavyGenerationLogManagerTest(unittest.TestCase):
)
manager.RetiredCleanupBudget = 64
manager.AppendRetiredCleanupBudget = 1
for index in range(backlog):
manager.append(str(index), CORE_LOG_CATEGORY)
manager.clear(runtimeOnly=True)
before = manager.retiredEntryCount
started = time.perf_counter_ns()
manager.append('new')
samples.append(time.perf_counter_ns() - started)
self.assertEqual(manager.retiredEntryCount, max(0, before - 1))
results.append({'backlog': backlog, 'median_us': median(samples) / 1_000})
ratio = results[-1]['median_us'] / max(results[0]['median_us'], 0.001)
self.assertLess(ratio, 20)
self.report('cleanup-backlog-latency', samples=results, endpoint_ratio=ratio)
def testAdversarialClearRateCannotGrowPhysicalBacklog(self):
@@ -1942,6 +1969,7 @@ class VeryHeavyGenerationLogManagerTest(unittest.TestCase):
capture_output=True,
text=True,
).stdout
baselineModule = types.ModuleType('tests._baseline_log_manager')
previousModule = sys.modules.get(baselineModule.__name__)
sys.modules[baselineModule.__name__] = baselineModule
@@ -1959,47 +1987,60 @@ class VeryHeavyGenerationLogManagerTest(unittest.TestCase):
def benchmark(managerClass):
results = {}
manager = managerClass(maximumEntries=50_000, autoClearEnabled=False)
started = time.perf_counter_ns()
for index in range(50_000):
manager.append(str(index), APPLICATION_LOG_CATEGORY)
results['steady_append_ms'] = (time.perf_counter_ns() - started) / 1e6
manager = managerClass(
maximumEntries=50_000,
autoClearMaximumEntries=20_000,
)
for index in range(20_000):
manager.append(str(index), CORE_LOG_CATEGORY)
for index in range(20_000):
manager.append(str(index), TUN2SOCKS_LOG_CATEGORY)
started = time.perf_counter_ns()
manager.append('trigger', CORE_LOG_CATEGORY)
results['core_rollover_us'] = (time.perf_counter_ns() - started) / 1e3
manager = managerClass(maximumEntries=50_000, autoClearEnabled=False)
for index in range(30_000):
manager.append(
str(index),
CORE_LOG_CATEGORY if index % 5 == 0 else APPLICATION_LOG_CATEGORY,
)
started = time.perf_counter_ns()
manager.snapshot(CORE_LOG_CATEGORY)
results['category_snapshot_us'] = (time.perf_counter_ns() - started) / 1e3
started = time.perf_counter_ns()
manager.snapshot()
results['global_snapshot_us'] = (time.perf_counter_ns() - started) / 1e3
manager = managerClass(maximumEntries=1_000, autoClearEnabled=False)
started = time.perf_counter_ns()
for index in range(50_000):
manager.append(str(index), APPLICATION_LOG_CATEGORY)
results['retention_heavy_ms'] = (time.perf_counter_ns() - started) / 1e6
return results
current = benchmark(LogManager)
baseline = benchmark(baselineModule.LogManager)
self.assertEqual(LogManager(maximumEntries=1).entries(), tuple())
self.report(
'baseline-comparison',
baseline_revision=revision,
+9
View File
@@ -238,6 +238,7 @@ class QtLifetimeTest(unittest.TestCase):
owner = QWidget()
menu = AppQMenu(parent=owner if explicitOwner else None)
action = AppQAction('Menu fixture', menu=menu, parent=owner)
references.append(weakref.ref(menu))
menu.destroyed.connect(lambda *_args: destroyed.append(True))
@@ -245,11 +246,13 @@ class QtLifetimeTest(unittest.TestCase):
processQtEvents()
self.assertFalse(isValid(action))
try:
self.assertEqual(isValid(menu), explicitOwner)
finally:
if isValid(menu):
menu.deleteLater()
owner.deleteLater()
processQtEvents()
@@ -290,8 +293,10 @@ class QtLifetimeTest(unittest.TestCase):
with self.subTest(platform=platform, family=family):
references = []
destroyed = []
for _ in range(20):
parent = QWidget()
if family == 'servers':
view = ServerTableView(
parent=parent,
@@ -308,6 +313,7 @@ class QtLifetimeTest(unittest.TestCase):
view.setCurrentIndex(view.model().index(0, 0))
module = type(view).__module__
with mock.patch(module + '.PLATFORM', platform):
if family == 'assetOverwrite':
view.appendNewItem(str(asset))
@@ -327,9 +333,11 @@ class QtLifetimeTest(unittest.TestCase):
try:
view.deleteLater()
processQtEvents()
self.assertFalse(isValid(view))
self.assertFalse(isValid(confirmation))
self.assertTrue(isValid(parent))
self.assertEqual(profiles, [profile])
self.assertIn('fixture', subscriptions)
self.assertIn('fixture', routings)
@@ -337,6 +345,7 @@ class QtLifetimeTest(unittest.TestCase):
finally:
if isValid(confirmation):
confirmation.reject()
parent.deleteLater()
processQtEvents()
+5
View File
@@ -186,6 +186,7 @@ class HttpGetManagerLifetimeTest(unittest.TestCase):
for _ in range(30):
payload = _ResponseBody(b'fixture')
references.append(weakref.ref(payload))
reply = _ManagedReply(manager)
references.append(weakref.ref(reply))
reply.destroyed.connect(lambda *_args: destroyed.append(True))
@@ -202,6 +203,7 @@ class HttpGetManagerLifetimeTest(unittest.TestCase):
self.assertFalse(isValid(reply))
self.assertFalse(getattr(manager, contextAttribute))
del reply
self.assertEqual(len(destroyed), 30)
@@ -238,6 +240,7 @@ class HttpGetManagerLifetimeTest(unittest.TestCase):
"""A completed reply cannot invoke hooks again before deferred deletion."""
manager = _CapturingHttpGetManager()
self.addCleanup(manager.deleteLater)
reply = manager.webGET('https://invalid.test', marker='fixture')
with patch.object(manager, 'successCallback') as completed:
@@ -245,7 +248,9 @@ class HttpGetManagerLifetimeTest(unittest.TestCase):
reply.finished.emit()
completed.assert_called_once_with(reply, marker='fixture')
processQtEvents()
self.assertFalse(isValid(reply))
capabilityId = 'fixture.navigation'
+6
View File
@@ -1655,20 +1655,26 @@ class UnifiedLogPageTest(unittest.TestCase):
with isolatedSettings():
stack = QStackedWidget()
pages = [LogPage(manager=LogManager(maximumEntries=3)) for _ in range(2)]
for page in pages:
stack.addWidget(page)
self.addCleanup(stack.deleteLater)
self.addCleanup(stack.close)
self.addCleanup(QTest.keyRelease, stack, QtCore.Qt.Key_Control)
stack.show()
stack.activateWindow()
for page in (pages[0], pages[1], pages[0]):
stack.setCurrentWidget(page)
page.textBrowser.setFocus()
processQtEvents()
QTest.keyClick(
page.textBrowser, QtCore.Qt.Key_F, QtCore.Qt.ControlModifier
)
self.assertTrue(waitFor(page.searchLineEdit.hasFocus))
def testLabelsOwnTheirDynamicTranslation(self):