From 6f95b7065193ff54b05b6a4aaf7346ca802e911f Mon Sep 17 00:00:00 2001 From: Naveed Jooma Date: Tue, 25 Jul 2023 11:40:12 -0400 Subject: [PATCH] Add a tailLogs method (#69) --- lib/src/app/app.dart | 11 ++++++++ lib/src/viam_sdk_impl.dart | 2 +- test/unit_test/app/app_client_test.dart | 13 +++++++++ .../unit_test/mocks/mock_response_future.dart | 27 +++++++++++++++++++ 4 files changed, 52 insertions(+), 1 deletion(-) diff --git a/lib/src/app/app.dart b/lib/src/app/app.dart index d9b6c8904a..898375dd56 100644 --- a/lib/src/app/app.dart +++ b/lib/src/app/app.dart @@ -1,3 +1,5 @@ +import 'dart:async'; + import '../gen/app/v1/app.pbgrpc.dart'; class AppClient { @@ -52,4 +54,13 @@ class AppClient { final response = await _client.getRobotPart(getRobotPartRequest); return response.part; } + + Stream> tailLogs(RobotPart part, {bool errorsOnly = false}) { + final request = TailRobotPartLogsRequest() + ..id = part.id + ..errorsOnly = errorsOnly; + final response = _client.tailRobotPartLogs(request); + final stream = response.map((event) => event.logs); + return stream.asBroadcastStream(onCancel: (_) => response.cancel()); + } } diff --git a/lib/src/viam_sdk_impl.dart b/lib/src/viam_sdk_impl.dart index 60718196bd..352a0aea6f 100644 --- a/lib/src/viam_sdk_impl.dart +++ b/lib/src/viam_sdk_impl.dart @@ -13,7 +13,7 @@ class ViamImpl implements Viam { late AppClient _appClient; late DataClient _dataClient; - ViamImpl(); + ViamImpl._(); ViamImpl.withAccessToken(String accessToken) : _clientChannelBase = AuthenticatedChannel('app.viam.com', 443, accessToken, false) { _appClient = AppClient(AppServiceClient(_clientChannelBase!)); diff --git a/test/unit_test/app/app_client_test.dart b/test/unit_test/app/app_client_test.dart index a542534932..4da4361ba9 100644 --- a/test/unit_test/app/app_client_test.dart +++ b/test/unit_test/app/app_client_test.dart @@ -104,5 +104,18 @@ void main() { final response = await appClient.getRobotPart('robot part'); expect(response, equals(expected)); }); + + test('tailLogs', () async { + final expected = LogEntry()..message = 'My log entry'; + final response = TailRobotPartLogsResponse()..logs.add(expected); + when(serviceClient.tailRobotPartLogs(any)).thenAnswer((_) => MockResponseStream.list([response])); + final stream = appClient.tailLogs(RobotPart()); + expect( + stream, + emitsInOrder([ + emits([expected]), + emitsDone + ])); + }); }); } diff --git a/test/unit_test/mocks/mock_response_future.dart b/test/unit_test/mocks/mock_response_future.dart index ea74b8dbf7..e4ea400cf2 100644 --- a/test/unit_test/mocks/mock_response_future.dart +++ b/test/unit_test/mocks/mock_response_future.dart @@ -15,3 +15,30 @@ class MockResponseFuture extends Mock implements ResponseFuture { @override Future then(FutureOr Function(T) onValue, {Function? onError}) => future.then(onValue, onError: onError); } + +class MockResponseStream extends Mock implements ResponseStream { + final Stream stream; + + MockResponseStream.stream(this.stream); + + MockResponseStream.list(List list) : stream = Stream.fromIterable(list); + + MockResponseStream.future(Future future) : stream = Stream.fromFuture(future); + + MockResponseStream.futures(List> futures) : stream = Stream.fromFutures(futures); + + @override + StreamSubscription listen(void Function(T value)? onData, {Function? onError, void Function()? onDone, bool? cancelOnError}) { + return stream.listen(onData, onError: onError, onDone: onDone, cancelOnError: cancelOnError); + } + + @override + Future cancel() { + return Future.value(); + } + + @override + Stream map(S Function(T event) convert) { + return stream.map(convert); + } +}