diff --git a/Furious/Service/TrafficStatsManager.py b/Furious/Service/TrafficStatsManager.py index 9b10a53..b9f76ea 100644 --- a/Furious/Service/TrafficStatsManager.py +++ b/Furious/Service/TrafficStatsManager.py @@ -221,9 +221,11 @@ class TrafficStatsManager( self._monitor = None self._generation = 0 self._queryInFlight = False + self._previousCounters = None self._previousSampleTime = None self._usageAccumulator = _TrafficUsageAccumulator() + self._hasConnected = False self._connected = False self._collectionEnabled = AppSettings.isStateON_(METRICS_COLLECTION_SETTING) @@ -231,6 +233,7 @@ class TrafficStatsManager( self._sampleTimer = QtCore.QTimer(self) self._sampleTimer.setInterval(TRAFFIC_STATS_SAMPLE_INTERVAL) self._sampleTimer.timeout.connect(self._requestSample) + self._sampleReady.connect(self._consumeResult) def _resumeSampling(self): diff --git a/tests/benchmarks/benchmark_log_manager.py b/tests/benchmarks/benchmark_log_manager.py index 3a66705..886b31b 100644 --- a/tests/benchmarks/benchmark_log_manager.py +++ b/tests/benchmarks/benchmark_log_manager.py @@ -173,6 +173,7 @@ def main(argv=None): parser.add_argument('--entries', type=int, default=50_000) parser.add_argument('--output', type=Path) parser.add_argument('--baseline', type=Path) + arguments = parser.parse_args(argv) if arguments.entries < 10: @@ -185,6 +186,7 @@ def main(argv=None): baseline = validateReport( json.loads(arguments.baseline.read_text(encoding='utf-8')) ) + if baseline['entries'] != arguments.entries: raise ValueError('baseline entries must match --entries') except (OSError, ValueError) as error: diff --git a/tests/test_connection_startup_async.py b/tests/test_connection_startup_async.py index eb4545d..5951d25 100644 --- a/tests/test_connection_startup_async.py +++ b/tests/test_connection_startup_async.py @@ -293,6 +293,7 @@ class ConnectionStartupAsyncTest(TestCase): operation.failed.connect(lambda *_args: failures.append(_args)) processQtEvents() + runtime.fail(CoreRuntime.ExitCode.ConfigurationError.value) self.assertTrue(waitFor(lambda: bool(failures))) @@ -307,6 +308,7 @@ class ConnectionStartupAsyncTest(TestCase): 'reason=invalid-configuration', ) self.assertEqual(manager.lastStartError, 'Invalid server configuration') + self.assertEqual(runtime.stopCount, 1) self.assertEqual(runtime.disposeCount, 1) @@ -331,6 +333,7 @@ class ConnectionStartupAsyncTest(TestCase): operation.failed.connect(lambda *_args: failures.append(_args)) processQtEvents() + runtime.fail(CoreRuntime.ExitCode.ConfigurationError.value) operation._readinessProbe._finishFailed('core readiness check timed out') @@ -345,6 +348,7 @@ class ConnectionStartupAsyncTest(TestCase): 'reason=invalid-configuration', ) self.assertEqual(manager.lastStartError, 'Invalid server configuration') + self.assertEqual(runtime.stopCount, 1) self.assertEqual(runtime.disposeCount, 1) diff --git a/tests/test_log_manager_benchmark.py b/tests/test_log_manager_benchmark.py index 83bb661..cd13c45 100644 --- a/tests/test_log_manager_benchmark.py +++ b/tests/test_log_manager_benchmark.py @@ -103,10 +103,12 @@ class LogManagerBenchmarkTest(unittest.TestCase): (current, ['--baseline', str(baseline)]), ): arguments = ['--entries', '50', '--output', str(output), *extra] + result = runPythonChild( 'from tests.benchmarks.benchmark_log_manager import main\n' f'main({arguments!r})' ) + assertChildSucceeded(self, result, 'log benchmark CLI') self.assertEqual( json.loads(result.stdout), diff --git a/tests/test_log_manager_generation.py b/tests/test_log_manager_generation.py index acdc342..5928359 100644 --- a/tests/test_log_manager_generation.py +++ b/tests/test_log_manager_generation.py @@ -379,14 +379,18 @@ class GenerationLogManagerContractTest(unittest.TestCase): ('t', TUN2SOCKS_LOG_CATEGORY), ('c2', CORE_LOG_CATEGORY), ) + for message, categoryId in operations: self.appendBoth(manager, model, message, categoryId) manager.clear('runtime.extra') model.clear('runtime.extra') + _assertManagerInvariants(self, manager, model) + manager.clear(runtimeOnly=True) model.clear(runtimeOnly=True) + _assertManagerInvariants(self, manager, model) for index in range(9): @@ -394,13 +398,18 @@ class GenerationLogManagerContractTest(unittest.TestCase): manager.setAutoClearEnabled(False) model.setAutoClearEnabled(False) + manager.clear('other.extra') model.clear('other.extra') + self.appendBoth(manager, model, 'x' * 80, 'other.extra') self.appendBoth(manager, model, 'y' * 81, APPLICATION_LOG_CATEGORY) + manager.clear() model.clear() + _assertManagerInvariants(self, manager, model) + self.appendBoth(manager, model, 'after-clear', APPLICATION_LOG_CATEGORY) def testSeededModelBasedStateMachine(self): diff --git a/tests/test_models_and_services.py b/tests/test_models_and_services.py index d9bd078..8ddb47a 100644 --- a/tests/test_models_and_services.py +++ b/tests/test_models_and_services.py @@ -782,6 +782,7 @@ class LogManagerTest(unittest.TestCase): self.assertEqual(manager.retainedCharacters, 0) self.assertEqual(manager.retiredEntryCount, 301) self.assertEqual(manager.entries(), tuple()) + self.assertEqual( sum(index.iterationRequests for index in observedIndexes), 0, @@ -799,14 +800,17 @@ class LogManagerTest(unittest.TestCase): def testSnapshotsNeverTraverseRetiredGenerations(self): """Materialize only live streams after an immediate runtime rollover.""" manager = LogManager(maximumEntries=100, autoClearEnabled=False) + manager.append('application', APPLICATION_LOG_CATEGORY) manager.append('core', CORE_LOG_CATEGORY) manager.append('tun2socks', TUN2SOCKS_LOG_CATEGORY) + retiredGeneration = manager._runtimeGeneration observedGlobal = _ObservedEntryIndex(retiredGeneration.entries) observedCore = _ObservedEntryIndex( retiredGeneration.entriesByCategory[CORE_LOG_CATEGORY].entries ) + retiredGeneration.entries = observedGlobal retiredGeneration.entriesByCategory[CORE_LOG_CATEGORY].entries = observedCore @@ -817,6 +821,7 @@ class LogManagerTest(unittest.TestCase): tuple(entry.message for entry in manager.entries()), ('application',), ) + self.assertEqual(observedGlobal.iterationRequests, 0) self.assertEqual(observedCore.iterationRequests, 0) self.assertEqual(observedGlobal.oldestRemovals, 0) diff --git a/tests/test_profile_test_jobs.py b/tests/test_profile_test_jobs.py index 90e494a..3aa7ee9 100644 --- a/tests/test_profile_test_jobs.py +++ b/tests/test_profile_test_jobs.py @@ -621,8 +621,10 @@ class ProfileTestServiceTest(unittest.TestCase): running = self._profile('running', 'running.example') queued = self._profile('queued', 'queued.example') valid = self._profile('valid', 'valid.example') + manager = self._manager((running, queued, valid)) scheduler = manager._latencyScheduler + pool = _ControlledThreadPool() scheduler.threadPool = pool scheduler.pingWorkerFactory = _ControlledLatencyWorker @@ -648,6 +650,7 @@ class ProfileTestServiceTest(unittest.TestCase): self.assertEqual(len(pool.started), 2) second = pool.started[1] + second.finish('7ms') processQtEvents() diff --git a/tests/test_runtime_lifecycle.py b/tests/test_runtime_lifecycle.py index efab2e0..8aead3a 100644 --- a/tests/test_runtime_lifecycle.py +++ b/tests/test_runtime_lifecycle.py @@ -183,10 +183,12 @@ class RuntimeLifecycleTest(TestCase): """Keep one terminal authority after ownership has transferred.""" owner = _AttemptOwner() committed = [] + router = RuntimeEventRouter() runtime = _Runtime(exitCallback=router.publish) router.attach(runtime, owner) lease = RuntimeLease(runtime, router) + lease.commit(lambda current, event: committed.append((current, event))) runtime.publishCode(12) diff --git a/tests/test_subscription_manager.py b/tests/test_subscription_manager.py index 02a4793..7a2f5cf 100644 --- a/tests/test_subscription_manager.py +++ b/tests/test_subscription_manager.py @@ -280,6 +280,7 @@ class SubscriptionManagerTest(TestCase): ) self.assertEqual(metadataAfterFailure, (1024, 2048, 8192, 1893456000)) + self.assertEqual(group.subscriptionUpload, 0) self.assertEqual(group.subscriptionDownload, 0) self.assertEqual(group.subscriptionTotal, 0) @@ -1063,10 +1064,12 @@ class SubscriptionManagerTest(TestCase): self.assertIs(manager._autoUpdateTimers['group-a'], groupATimer) self.assertEqual(groupATimer.interval(), 10 * 60 * 1000) + self.assertIs(manager._autoUpdateTimers['group-b'], groupBTimer) self.assertEqual(groupBTimer.timerId(), groupBTimerId) self.assertLessEqual(groupBTimer.remainingTime(), groupBRemainingBefore + 5) self.assertEqual(len(manager._autoUpdateTimers), 2) + manager.deleteLater() def testRemovingSubscriptionDestroysOnlyItsTimerAndCancelsItsReply(self): @@ -1331,12 +1334,14 @@ class SubscriptionManagerTest(TestCase): """A synchronous abort observer must not lose the next generation's status.""" subscriptions = {'group-a': self._subscription(lastSyncStatus='syncing')} manager = self._manager() + context = {'unique': 'group-a', 'batchId': 1, 'requestVersion': 1} manager._nextBatchId = 1 manager._requestVersions['group-a'] = 1 manager._batches[1] = _SubscriptionBatchState( {('group-a', 1)}, False, [{'unique': 'completed-group'}], [] ) + reply = mock.Mock() manager._activeReplies[reply] = reply manager._replySubscriptions[reply] = 'group-a' @@ -1369,6 +1374,7 @@ class SubscriptionManagerTest(TestCase): ): try: manager.stopUpdates() + request.assert_called_once() self.assertTrue(manager._isCurrentRequest(request.call_args.kwargs))