import 'dart:convert'; import 'dart:io'; import 'package:flutter_test/flutter_test.dart'; import 'package:sm_mobile/models/server_profile.dart'; import 'package:sm_mobile/services/monitor.dart'; import 'package:sm_mobile/services/ssh_service.dart'; import 'package:sm_mobile/services/vault.dart'; import '../support.dart'; void main() { TestWidgetsFlutterBinding.ensureInitialized(); final enabled = Platform.environment['SM_LINUX_TEST'] == '1'; late Vault vault; late SshService ssh; setUpAll(() async { if (!enabled) return; vault = Vault(MemoryStore()); await vault.create('isolated linux test master password'); ssh = SshService(vault); }); tearDownAll(() { if (enabled) { ssh.dispose(); vault.lock(); } }); test( 'real Linux OpenSSH: password login and independently pinned host fingerprint', () async { final p = ServerProfile( name: 'Linux test', host: '127.0.0.1', port: 22239, username: 'smtest', ); await ssh.connect( p, credential: Platform.environment['SM_TEST_PASSWORD']!, prompt: (endpoint, type, fp) async { expect(fp, Platform.environment['SM_TEST_FINGERPRINT']); return true; }, ); expect(ssh.error, null); expect(ssh.connected, true); final marker = 'LINUX_PASSWORD_OK_${newId()}'; final result = await ssh.client.run('printf %s "$marker"'); expect(utf8.decode(result), marker); }, skip: !enabled, ); test('real Linux metrics, command RTT and cancellable refresh', () async { final adapter = LinuxMonitor(); final metrics = await adapter.sample(ssh.client); expect( metrics.keys, containsAll([ 'cpu', 'ram', 'disk', 'uptime', 'load', 'system', 'release', 'rtt', ]), ); expect(metrics['system'], startsWith('Linux')); expect( double.parse(metrics['cpu']!.replaceAll('%', '')), inInclusiveRange(0, 100), ); expect(double.parse(metrics['uptime']!), greaterThan(0)); expect(metrics['ram'], contains('MiB')); expect(metrics['disk'], contains('KiB')); final expectedLoad = utf8 .decode(await ssh.client.run('cut -d " " -f 1-3 /proc/loadavg')) .trim() .split(' '); final actualLoad = metrics['load']!.split(' '); for (var i = 0; i < 3; i++) { expect( double.parse(actualLoad[i]), closeTo(double.parse(expectedLoad[i]), .5), ); } expect(metrics['rtt'], matches(RegExp(r'^\d+ ms$'))); final pending = adapter.sample(ssh.client); adapter.cancel(); await expectLater(pending, throwsA(anything)); ssh.disconnect(); expect(ssh.connected, false); }, skip: !enabled); }