import 'dart:async'; import 'package:flutter/foundation.dart'; import 'package:mutex/mutex.dart'; import 'package:veilid/veilid.dart'; class DefaultFixture { DefaultFixture(); StreamSubscription? _veilidUpdateSubscription; Stream? _veilidUpdateStream; final StreamController _updateStreamController = StreamController.broadcast(); static final _fixtureMutex = Mutex(); Future setUp() async { await _fixtureMutex.acquire(); assert(_veilidUpdateStream == null, 'should not set up fixture twice'); final ignoreLogTargetsStr = // ignore: do_not_use_environment const String.fromEnvironment('IGNORE_LOG_TARGETS').trim(); final ignoreLogTargets = ignoreLogTargetsStr.isEmpty ? [] : ignoreLogTargetsStr.split(',').map((e) => e.trim()).toList(); final Map platformConfigJson; if (kIsWeb) { final platformConfig = VeilidWASMConfig( logging: VeilidWASMConfigLogging( performance: VeilidWASMConfigLoggingPerformance( enabled: true, level: VeilidConfigLogLevel.debug, logsInTimings: true, logsInConsole: false, ignoreLogTargets: ignoreLogTargets, ), api: VeilidWASMConfigLoggingApi( enabled: true, level: VeilidConfigLogLevel.info, ignoreLogTargets: ignoreLogTargets, ))); platformConfigJson = platformConfig.toJson(); } else { final platformConfig = VeilidFFIConfig( logging: VeilidFFIConfigLogging( terminal: VeilidFFIConfigLoggingTerminal( enabled: false, level: VeilidConfigLogLevel.debug, ignoreLogTargets: ignoreLogTargets, ), otlp: VeilidFFIConfigLoggingOtlp( enabled: false, level: VeilidConfigLogLevel.trace, grpcEndpoint: 'localhost:4317', serviceName: 'Veilid Tests', ignoreLogTargets: ignoreLogTargets, ), api: VeilidFFIConfigLoggingApi( enabled: true, // level: VeilidConfigLogLevel.debug, level: VeilidConfigLogLevel.info, ignoreLogTargets: ignoreLogTargets, ))); platformConfigJson = platformConfig.toJson(); } Veilid.instance.initializeVeilidCore(platformConfigJson); var config = await getDefaultVeilidConfig( isWeb: kIsWeb, programName: 'Veilid Tests', // ignore: avoid_redundant_argument_values, do_not_use_environment bootstrap: const String.fromEnvironment('BOOTSTRAP'), // ignore: avoid_redundant_argument_values, do_not_use_environment networkKeyPassword: const String.fromEnvironment('NETWORK_KEY'), ); config = config.copyWith(tableStore: config.tableStore.copyWith(delete: true)); config = config.copyWith( protectedStore: config.protectedStore.copyWith(delete: true)); config = config.copyWith(blockStore: config.blockStore.copyWith(delete: true)); final us = _veilidUpdateStream = await Veilid.instance.startupVeilidCore(config); _veilidUpdateSubscription = us.listen((update) { if (update is VeilidLog) { // print(update.message); } else if (update is VeilidUpdateAttachment) { } else if (update is VeilidUpdateConfig) { } else if (update is VeilidUpdateNetwork) { } else if (update is VeilidAppMessage) { } else if (update is VeilidAppCall) { } else if (update is VeilidUpdateValueChange) { } else if (update is VeilidUpdateRouteChange) { } else { throw Exception('unexpected update: $update'); } _updateStreamController.sink.add(update); }); } Stream get updateStream => _updateStreamController.stream; Future attach() async { await Veilid.instance.attach(); // Wait for attached state while (true) { final state = await Veilid.instance.getVeilidState(); var done = false; if (state.attachment.publicInternetReady) { switch (state.attachment.state) { case AttachmentState.detached: break; case AttachmentState.attaching: break; case AttachmentState.detaching: break; default: done = true; break; } } if (done) { break; } await Future.delayed(const Duration(seconds: 1)); } } Future detach() async { await Veilid.instance.detach(); } Future tearDown() async { assert(_veilidUpdateStream != null, 'should not tearDown without setUp'); final cancelFut = _veilidUpdateSubscription?.cancel(); await Veilid.instance.shutdownVeilidCore(); await cancelFut; _veilidUpdateSubscription = null; _veilidUpdateStream = null; _fixtureMutex.release(); } }