Test that timeout should cancel EventChannel and throw TimeoutException - unit-testing

I am the maintainer of the open source Geolocator plugin for Flutter and working on refactoring the plugin. On popular request I am trying to add a timeout option to the plugin method which retrieved the current location.
The getCurrentLocation method basically listens to a stream of location updates, graps the first element and then cancels the stream. Now I would like to offer the option to supply a timeLimit which when reached should cancel the stream and throw a TimeoutException. Before I start implementing this in my code base I decided to start with a small proof-of-concept to see if I understand everything. Turns out I don't ;)
I have the following code:
import 'dart:async';
import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart';
void main() {
TestWidgetsFlutterBinding.ensureInitialized();
final eventChannel = EventChannel('demo');
final log = <MethodCall>[];
setUp(() async {
log.clear();
MethodChannel(eventChannel.name)
.setMockMethodCallHandler((methodCall) async {
log.add(methodCall);
switch (methodCall.method) {
case 'listen':
await Future.delayed(Duration(milliseconds: 10));
await ServicesBinding.instance.defaultBinaryMessenger
.handlePlatformMessage(eventChannel.name,
eventChannel.codec.encodeSuccessEnvelope('one'), (_) {});
await ServicesBinding.instance.defaultBinaryMessenger
.handlePlatformMessage(eventChannel.name,
eventChannel.codec.encodeSuccessEnvelope('two'), (_) {});
await ServicesBinding.instance.defaultBinaryMessenger
.handlePlatformMessage(eventChannel.name,
eventChannel.codec.encodeSuccessEnvelope('three'), (_) {});
break;
case 'cancel':
default:
return null;
}
});
});
test('EventChannel returns the first value and cancels the stream', () async {
final one = await eventChannel.receiveBroadcastStream().first;
expect(one, 'one');
expect(log, <Matcher>[
isMethodCall('listen', arguments: null),
isMethodCall('cancel', arguments: null),
]);
});
test('Timeout should cancel the stream', () async {
final future = eventChannel
.receiveBroadcastStream()
.timeout(Duration(milliseconds: 5), onTimeout: (s) {
s.close();
throw TimeoutException('Timeout expired');
}).first;
expect(
future,
throwsA(predicate((e) {
final isTimeout = e is Timeout;
final streamCancelled = log.contains('cancel');
return isTimeout && streamCancelled;
})),
);
});
}
The first test (called "") works as expected, it retrieves the first value "one" and then cancels the stream.
In the second test (called "") I am trying to test that the stream is cancelled and a TimeoutException is thrown when the timeout is reached. This is where I am struggling, it seems I am not understanding how to accomplish this. Probably I am not understanding the inner workings correctly. The future variable in the second test seems to return the last value from the stream and not timeout at all. See the following output:
00:00 +1: Timeout should cancel the stream [E]
Expected: throws satisfies function
Actual: <Instance of '_Future<dynamic>'>
Which: emitted 'two'
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/dart_sdk.js 6327:7 DartError
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/dart_sdk.js 4773:11 throw_
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/flutter_web.js 353347:17 fail
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/flutter_web.js 353325:18 _expect.<fn>
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/flutter_web.js 359718:140 <fn>
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/flutter_web.js 359765:16 [_run]
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/flutter_web.js 359718:108 <fn>
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/dart_sdk.js 35912:56 _rootRunUnary
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/dart_sdk.js 35234:14 runUnary
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/dart_sdk.js 30956:29 handleValue
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/dart_sdk.js 31466:49 handleValueCallback
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/dart_sdk.js 31498:17 _propagateToListeners
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/dart_sdk.js 31348:25 [_complete]
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/dart_sdk.js 35874:24 _cancelAndValue
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/dart_sdk.js 18161:17 get first.<fn>
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/flutter_web.js 359718:140 <fn>
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/flutter_web.js 359765:16 [_run]
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/flutter_web.js 359718:108 <fn>
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/dart_sdk.js 35912:56 _rootRunUnary
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/dart_sdk.js 35234:14 runUnary
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/dart_sdk.js 35153:14 runUnaryGuarded
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/dart_sdk.js 29621:22 [_sendData]
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/dart_sdk.js 29569:26 [_add]
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/dart_sdk.js 30263:29 [_sendData]
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/dart_sdk.js 30067:24 add
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/dart_sdk.js 18357:22 onData
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/flutter_web.js 359718:140 <fn>
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/flutter_web.js 359765:16 [_run]
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/flutter_web.js 359718:108 <fn>
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/dart_sdk.js 35912:56 _rootRunUnary
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/dart_sdk.js 35234:14 runUnary
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/dart_sdk.js 35153:14 runUnaryGuarded
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/dart_sdk.js 29621:22 [_sendData]
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/dart_sdk.js 32758:28 perform
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/dart_sdk.js 32861:15 handleNext
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/dart_sdk.js 32621:16 schedule.<fn>
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/flutter_web.js 359765:16 [_run]
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/flutter_web.js 359713:86 <fn>
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/dart_sdk.js 35903:56 _rootRun
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/dart_sdk.js 35227:14 run
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/dart_sdk.js 35144:14 runGuarded
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/dart_sdk.js 35183:33 bindCallbackGuarded.<fn>
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/flutter_web.js 359765:16 [_run]
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/flutter_web.js 359713:86 <fn>
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/dart_sdk.js 35906:14 _rootRun
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/dart_sdk.js 35227:14 run
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/dart_sdk.js 35144:14 runGuarded
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/dart_sdk.js 35183:33 bindCallbackGuarded.<fn>
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/dart_sdk.js 35756:13 _microtaskLoop
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/dart_sdk.js 35762:13 _startMicrotaskLoop
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/dart_sdk.js 31704:9 _scheduleImmediateWithPromise.<fn>
===== asynchronous gap ===========================
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/dart_sdk.js 35255:14 registerUnaryCallback
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/dart_sdk.js 31164:27 then
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/flutter_web.js 353323:23 _expect
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/flutter_web.js 353277:12 expect$0
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/flutter_web.js 343286:12 expect$
frame_dark.html#/%20line%2038%20%3E%20scriptElement 119:21 main$0.<fn>.<fn>
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/dart_sdk.js 35674:34 runBody
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/dart_sdk.js 35702:7 _async
frame_dark.html#/%20line%2038%20%3E%20scriptElement 114:78 main$0.<fn>
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/flutter_web.js 347466:17 test.<fn>.<fn>.<fn>.<fn>.<fn>
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/dart_sdk.js 35655:33 onValue
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/flutter_web.js 359718:140 <fn>
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/flutter_web.js 359765:16 [_run]
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/flutter_web.js 359718:108 <fn>
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/dart_sdk.js 35912:56 _rootRunUnary
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/dart_sdk.js 35234:14 runUnary
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/dart_sdk.js 30956:29 handleValue
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/dart_sdk.js 31466:49 handleValueCallback
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/dart_sdk.js 31498:17 _propagateToListeners
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/dart_sdk.js 31348:25 [_complete]
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/dart_sdk.js 30714:32 doWhile.<fn>
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/flutter_web.js 359718:140 <fn>
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/flutter_web.js 359765:16 [_run]
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/flutter_web.js 359718:108 <fn>
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/dart_sdk.js 35912:56 _rootRunUnary
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/dart_sdk.js 35234:14 runUnary
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/dart_sdk.js 35153:14 runUnaryGuarded
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/dart_sdk.js 35187:34 bindUnaryCallbackGuarded.<fn>
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/flutter_web.js 359718:140 <fn>
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/flutter_web.js 359765:16 [_run]
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/flutter_web.js 359718:108 <fn>
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/dart_sdk.js 35912:56 _rootRunUnary
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/dart_sdk.js 35234:14 runUnary
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/dart_sdk.js 30956:29 handleValue
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/dart_sdk.js 31466:49 handleValueCallback
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/dart_sdk.js 31498:17 _propagateToListeners
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/dart_sdk.js 31357:23 [_completeWithValue]
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/dart_sdk.js 31377:35 <fn>
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/flutter_web.js 359765:16 [_run]
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/flutter_web.js 359713:86 <fn>
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/dart_sdk.js 35906:14 _rootRun
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/dart_sdk.js 35227:14 run
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/dart_sdk.js 35144:14 runGuarded
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/dart_sdk.js 35183:33 bindCallbackGuarded.<fn>
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/dart_sdk.js 35756:13 _microtaskLoop
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/dart_sdk.js 35762:13 _startMicrotaskLoop
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/dart_sdk.js 31704:9 _scheduleImmediateWithPromise.<fn>
===== asynchronous gap ===========================
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/dart_sdk.js 35255:14 registerUnaryCallback
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/dart_sdk.js 35666:22 _async
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/flutter_web.js 347464:134 test.<fn>.<fn>.<fn>.<fn>
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/flutter_web.js 348487:15 waitForOutstandingCallbacks.<fn>.<fn>
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/dart_sdk.js 35674:34 runBody
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/dart_sdk.js 35702:7 _async
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/flutter_web.js 348484:60 waitForOutstandingCallbacks.<fn>
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/dart_sdk.js 35906:14 _rootRun
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/dart_sdk.js 35227:14 run
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/dart_sdk.js 36041:92 _runZoned
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/dart_sdk.js 36006:18 runZoned
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/flutter_web.js 348484:13 waitForOutstandingCallbacks
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/flutter_web.js 347464:86 test.<fn>.<fn>.<fn>
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/dart_sdk.js 35906:14 _rootRun
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/dart_sdk.js 35227:14 run
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/dart_sdk.js 36041:92 _runZoned
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/dart_sdk.js 36006:18 runZoned
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/flutter_web.js 347464:21 test.<fn>.<fn>
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/dart_sdk.js 35674:34 runBody
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/dart_sdk.js 35702:7 _async
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/flutter_web.js 347454:109 test.<fn>
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/flutter_web.js 348572:40 <fn>
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/dart_sdk.js 35674:34 runBody
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/dart_sdk.js 35702:7 _async
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/flutter_web.js 348571:70 <fn>
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/dart_sdk.js 30523:31 new.<fn>
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/flutter_web.js 359765:16 [_run]
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/flutter_web.js 359713:86 <fn>
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/dart_sdk.js 35903:56 _rootRun
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/dart_sdk.js 35227:14 run
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/dart_sdk.js 35144:14 runGuarded
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/dart_sdk.js 35183:33 bindCallbackGuarded.<fn>
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/flutter_web.js 359765:16 [_run]
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/flutter_web.js 359713:86 <fn>
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/dart_sdk.js 35906:14 _rootRun
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/dart_sdk.js 35227:14 run
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/dart_sdk.js 35171:33 bindCallback.<fn>
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/dart_sdk.js 22859:11 internalCallback
===== asynchronous gap ===========================
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/dart_sdk.js 35248:14 registerCallback
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/dart_sdk.js 35182:29 bindCallbackGuarded
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/dart_sdk.js 34399:74 new
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/dart_sdk.js 34409:19 run
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/dart_sdk.js 30521:21 new
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/flutter_web.js 348571:46 <fn>
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/dart_sdk.js 35674:34 runBody
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/dart_sdk.js 35702:7 _async
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/flutter_web.js 348568:64 <fn>
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/dart_sdk.js 35906:14 _rootRun
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/dart_sdk.js 35227:14 run
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/dart_sdk.js 36041:92 _runZoned
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/dart_sdk.js 36006:18 runZoned
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/flutter_web.js 348568:17 <fn>
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/flutter_web.js 348593:9 [_guardIfGuarded]
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/flutter_web.js 348567:30 <fn>
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/flutter_web.js 354673:18 capture.<fn>
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/dart_sdk.js 35906:14 _rootRun
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/dart_sdk.js 35227:14 run
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/dart_sdk.js 36041:92 _runZoned
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/dart_sdk.js 36006:18 runZoned
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/flutter_web.js 354671:20 capture
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/flutter_web.js 348566:20 [_onRun]
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/dart_sdk.js 4978:16 _checkAndCall
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/dart_sdk.js 5021:17 callMethod
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/dart_sdk.js 5024:17 dsend
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/flutter_web.js 356872:12 [_run]
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/flutter_web.js 356792:41 run
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/dart_sdk.js 30536:31 microtask.<fn>
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/dart_sdk.js 35903:56 _rootRun
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/dart_sdk.js 35227:14 run
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/dart_sdk.js 35144:14 runGuarded
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/dart_sdk.js 35183:33 bindCallbackGuarded.<fn>
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/dart_sdk.js 35906:14 _rootRun
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/dart_sdk.js 35227:14 run
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/dart_sdk.js 35144:14 runGuarded
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/dart_sdk.js 35183:33 bindCallbackGuarded.<fn>
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/dart_sdk.js 35756:13 _microtaskLoop
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/dart_sdk.js 35762:13 _startMicrotaskLoop
https://storage.googleapis.com/compilation_artifacts/2.9.0-8.2.beta/dart_sdk.js 31704:9 _scheduleImmediateWithPromise.<fn>
What am I doing wrong? Is it possible to write such a test? Any help is greatly appreciated.
UPDATE: I have removed the link to DartPad since it will not run the code in a test environment (like flutter test), potentially resulting in false negatives.

With some solid help from the Flutter Community (and Simon Lightfoot in particular) I was able to solve the problem.
I had two mistakes in my code.
Since I am dealing with a stream, I should not throw an TimeoutException but rather add an error to the sink;
To simulate the a long running task I was blocking the event channel with a delay of 10 milliseconds. This means that after the timeout is thrown I still should wait for the remaining 5 milliseconds before the cancel method call is processed.
So after some refactoring I ended up with the following working solution:
test('Timeout should cancel the stream', () async {
final future = eventChannel
.receiveBroadcastStream()
.timeout(Duration(milliseconds: 5), onTimeout: (s) {
s.addError(TimeoutException('Timeout expired'));
s.close();
}).first;
expect(
future,
throwsA(isA<TimeoutException>()),
);
await Future.delayed(Duration(milliseconds: 5));
expect(log, <Matcher>[
isMethodCall('listen', arguments: null),
isMethodCall('cancel', arguments: null),
]);
});

Related

Private Ethereum Node is unable to add peers

My genesis file (used same for both nodes)
"config": {
"chainId": 42,
"homesteadBlock": 0,
"eip150Block": 0,
"eip150Hash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"eip155Block": 0,
"eip158Block": 0,
"byzantiumBlock": 0,
"constantinopleBlock": 0,
"petersburgBlock": 0,
"istanbulBlock": 0,
"ethash": {}
},
"nonce": "0x0",
"timestamp": "0x62c17562",
"extraData": "0x0000000000000000000000000000000000000000000000000000000000000000",
"gasLimit": "0x47b760",
"difficulty": "0x80000",
"mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"coinbase": "0x0000000000000000000000000000000000000000",
"alloc": {
"0000000000000000000000000000000000000000": {
"balance": "0x1"
},
"0000000000000000000000000000000000000001": {
"balance": "0x1"
},
"0000000000000000000000000000000000000002": {
"balance": "0x1"
},
"0000000000000000000000000000000000000003": {
"balance": "0x1"
},
"0000000000000000000000000000000000000004": {
"balance": "0x1"
},
My .sh file for node 1
geth --identity "miner1" --networkid 42 --mine --datadir "~/RPI/miner1" --nodiscover --http --http.port "8042" --port "30303" --http.corsdomain "*" --nat "any" --http.api db,eth,web,web3,private,miner,admin,txpool,debug,personal,net --allow-insecure-unlock --unlock 0 --password ~/RPI/password.sec --ipcpath "~/.ethereum/geth.ipc"
for node 2:
geth --identity "miner2" --networkid 42 --datadir "~/RPI/miner2" --mine --nodiscover --http --http.port "8043" --port "30304" --http.corsdomain "*" --nat "any" --http.api db,eth,web,web3,private,miner,admin,txpool,debug,personal,net --allow-insecure-unlock --unlock 0 --password ~/RPI/password.sec --ipcpath "~/.ethereum/geth.ipc"
I have tried using admin.addPeer but always returns [] tried another method by adding static-nodes.json file but didn't work either.
content of my static-nodes.json:
[
“enode://f9d48547c373fd61124d110791168572382298979d18ab5d6314cd399538ef77b8ff826b870a3474ad351f175b6d4d6f03c09ab4382b4d075e6a3c7fdeee58aa#35.247.47.68:30303?discport=0”,
“enode://991f8279ae27e665151621a9940b42e208bb7cda0108c3cda219059bed28fbb7ec869b04db84d173fbb1cecdce5fef222d010f02a90238e7d8a53b163f6b0a2a#34.105.65.4:30304?discport=0”
]
One thing that I noticed which was very peculiar was mode info:
id: "1fdd33dee80b18a109b51e083ab05fe70d98a2c80d55da9c8679b412a438e180",
ip: "127.0.0.1",
listenAddr: "[::]:30303",
name: "Geth/miner1/v1.10.20-stable-8f2416a8/linux-amd64/go1.18.1",
ports: {
discovery: 0,
listener: 30303
},
protocols: {
eth: {
config: {
byzantiumBlock: 0,
chainId: 42,
constantinopleBlock: 0,
eip150Block: 0,
eip150Hash: "0x0000000000000000000000000000000000000000000000000000000000000000",
eip155Block: 0,
eip158Block: 0,
ethash: {},
homesteadBlock: 0,
istanbulBlock: 0,
petersburgBlock: 0
},
difficulty: 147322604,
genesis: "0xd3ad0f15c44cf0543e7cccce24ce94024026b14a547428f1df6d9d89ab1d6fe7",
head: "0x82714efde94e31b659b232a62a88beb9be1d1cc9a8846f7bde6781276b35ec89",
network: 42
},
snap: {}
}
For some reason in both nodes my discovery ports is set to 0 I feel like that could be the issue but have not been able to find the way to change it. I was under the impression when you set ports both discovery and listener are set to that value.
If that is not the issue then I have no idea what it could be.

How to I fix these errors not import some modules in qarsar testing with jest?

I am trying to implement testing for my quasar project with jest.
But I have some issues to not import modules.
When I run testing project, It can not import modules.
How to fix it?
I am beginner so please share about this correctly and deeply.
I am very thanks to help me to fix it.
These my errors.
E:\workplace\unittesting\webboid\node_modules\#babel\runtime-corejs2\helpers\esm\asyncToGenerator.js:1
({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,global,jest){import _Promise from "../../core-js/promise";
^^^^^^^^
SyntaxError: Unexpected identifier
17 | q-icon.on-right(name="show_chart")
18 | q-btn( v-if="local" flat style="margin-right:10px;" #click="ipcRenderer.send('openURL','https://app.boid.com')")
> 19 | q-icon(name="home")
| ^
20 | q-btn( v-else flat style="margin-right:10px;" #click="$router.push('/')")
21 | q-icon(name="home")
22 | q-btn.text-black(#click='' flat v-if="authenticated", color='light')
at ScriptTransformer._transformAndBuildScript (node_modules/#jest/transform/build/ScriptTransformer.js:471:17)
at ScriptTransformer.transform (node_modules/#jest/transform/build/ScriptTransformer.js:513:25)
at src/App.vue:19:49
at Object.<anonymous> (src/App.vue:535:3)
My jest.config.js File is following.
module.exports = {
globals: {
__DEV__: true,
},
verbose: false, // false since we want to see console.logs inside tests
bail: false,
testURL: 'http://localhost/',
testEnvironment: 'jsdom',
testRegex: './src/__unit__/.*.js$',
rootDir: '.',
testPathIgnorePatterns: [
'<rootDir>/components/coverage/',
'<rootDir>/test/cypress/',
'<rootDir>/test/coverage/',
'<rootDir>/dist/',
'<rootDir>/node_modules/',
],
moduleFileExtensions: ['js', 'json', 'vue'],
moduleNameMapper: {
'^vue$': 'vue/dist/vue.common.js',
'quasar': 'quasar-framework/dist/umd/quasar.mat.umd.js',
},
resolver: null,
transformIgnorePatterns: [
'node_modules/core-js',
'node_modules/babel-runtime',
'node_modules/vue',
],
transform: {
'^.+\\.js$': '<rootDir>/node_modules/babel-jest',
'.*\\.(vue)$': '<rootDir>/node_modules/vue-jest',
}
}
My package.json is following.
"devDependencies": {
"#babel/core": "^7.4.5",
"#babel/plugin-proposal-class-properties": "^7.0.0",
"#babel/plugin-proposal-decorators": "^7.0.0",
"#babel/plugin-proposal-export-namespace-from": "^7.0.0",
"#babel/plugin-proposal-function-sent": "^7.0.0",
"#babel/plugin-proposal-json-strings": "^7.0.0",
"#babel/plugin-proposal-numeric-separator": "^7.0.0",
"#babel/plugin-proposal-throw-expressions": "^7.0.0",
"#babel/plugin-syntax-dynamic-import": "^7.0.0",
"#babel/plugin-syntax-import-meta": "^7.0.0",
"#babel/plugin-transform-runtime": "^7.0.0",
"#babel/preset-env": "^7.0.0",
"autoprefixer": "^6.4.0",
"babel-core": "^7.0.0-bridge.0",
"babel-jest": "^24.8.0",
"babel-loader": "^8.0.0",
"babel-plugin-add-module-exports": "^1.0.0",
"colors": "^1.1.2",
"connect-history-api-fallback": "^1.1.0",
"css-loader": "^0.28.7",
"es6-promise": "^4.1.1",
"eslint": "^4.8.0",
"eslint-config-standard": "^10.2.1",
"eslint-friendly-formatter": "^3.0.0",
"eslint-loader": "^1.9.0",
"eslint-plugin-html": "^3.2.2",
"eslint-plugin-import": "^2.7.0",
"eslint-plugin-node": "^5.2.0",
"eslint-plugin-promise": "^3.5.0",
"eslint-plugin-standard": "^3.0.1",
"eventsource-polyfill": "^0.9.6",
"express": "^4.16.1",
"extract-text-webpack-plugin": "^3.0.0",
"file-loader": "^0.11.1",
"friendly-errors-webpack-plugin": "^1.1.3",
"glob": "^7.1.2",
"html-webpack-plugin": "^2.30.1",
"http-proxy-middleware": "^0.17.0",
"jest": "^24.8.0",
"json-loader": "^0.5.7",
"opn": "^5.0.0",
"optimize-css-assets-webpack-plugin": "^3.2.0",
"postcss-loader": "^1.0.0",
"progress-bar-webpack-plugin": "^1.10.0",
"purify-css": "^1.2.6",
"shelljs": "^0.7.0",
"stylus": "^0.54.5",
"stylus-loader": "^3.0.1",
"url-loader": "^0.5.7",
"vue-jest": "^3.0.4",
"vue-loader": "^13.0.5",
"vue-style-loader": "^3.0.3",
"vue-template-compiler": "^2.5.0",
"webpack": "^3.10.0",
"webpack-bundle-analyzer": "^3.1.0",
"webpack-dev-middleware": "^1.12.0",
"webpack-hot-middleware": "^2.19.1",
"webpack-merge": "^4.1.0"

Packer Unable to attach EBS Volume

I am trying to attach additional volume to my ami, this is my builder section,
"launch_block_device_mappings": [
{
"device_name": "/dev/sda1",
"volume_size": 8,
"volume_type": "gp2",
"delete_on_termination": true
},
{
"device_name": "/dev/sdb",
"volume_size": 10,
"volume_type": "gp2",
"delete_on_termination": true
}
],
"ami_block_device_mappings": [
{
"device_name": "/dev/sdb",
"virtual_name": "ephemeral0"
}
]
Please help.
This gives you and additional 10Gb disk available for provisioning:
{
"builders" : [
{
"type" : "amazon-ebs",
"instance_type" : "t2.micro",
"ssh_username" : "ubuntu",
"ami_name" : "packer-ES-{{timestamp}}",
"source_ami_filter": {
"filters": {
"virtualization-type": "hvm",
"name": "ubuntu/images/*ubuntu-xenial-16.04-amd64-server-*",
"root-device-type": "ebs"
},
"owners": ["099720109477"],
"most_recent": true
},
"launch_block_device_mappings" : [
{
"device_name" : "/dev/sdb",
"delete_on_termination" : true,
"volume_size" : 10,
"volume_type" : "gp2"
}
],
"ami_block_device_mappings" : [
{
"device_name" : "/dev/sdb",
"delete_on_termination" : true,
"volume_type" : "gp2"
}
]
}
],
"provisioners": [
{
"type": "shell",
"inline": [
"lsblk",
"df -h"
]
}
]
}
Running this you will see:
==> amazon-ebs: Connected to SSH!
==> amazon-ebs: Provisioning with shell script: /var/folders/_t/lsk64yf93xs3slvvtc6b_6mr0000gn/T/packer-shell591343041
amazon-ebs: NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
amazon-ebs: xvda 202:0 0 8G 0 disk
amazon-ebs: └─xvda1 202:1 0 8G 0 part /
amazon-ebs: xvdb 202:16 0 10G 0 disk
amazon-ebs: Filesystem Size Used Avail Use% Mounted on
amazon-ebs: udev 488M 0 488M 0% /dev
amazon-ebs: tmpfs 100M 3.0M 97M 3% /run
amazon-ebs: /dev/xvda1 7.7G 956M 6.8G 13% /
amazon-ebs: tmpfs 496M 0 496M 0% /dev/shm
amazon-ebs: tmpfs 5.0M 0 5.0M 0% /run/lock
amazon-ebs: tmpfs 496M 0 496M 0% /sys/fs/cgroup
amazon-ebs: tmpfs 100M 0 100M 0% /run/user/1000
==> amazon-ebs: Stopping the source instance...
amazon-ebs: Stopping instance, attempt 1
Verifying the results:
env AWS_PROFILE=packer-demo AWS_DEFAULT_REGION=eu-west-1 aws ec2 describe-images --image-ids ami-0a53
cb1f4541b55d4
{
"Images": [
{
"Architecture": "x86_64",
"CreationDate": "2018-07-19T09:52:53.000Z",
"ImageId": "ami-0a53cb1f4541b55d4",
"ImageLocation": "965990659467/packer-ES-1531993870",
"ImageType": "machine",
"Public": false,
"OwnerId": "965990659467",
"State": "available",
"BlockDeviceMappings": [
{
"DeviceName": "/dev/sda1",
"Ebs": {
"Encrypted": false,
"DeleteOnTermination": true,
"SnapshotId": "snap-0e622d809cf0e148a",
"VolumeSize": 8,
"VolumeType": "gp2"
}
},
{
"DeviceName": "/dev/sdb",
"Ebs": {
"Encrypted": false,
"DeleteOnTermination": false,
"SnapshotId": "snap-0c65cdcdb579f21b4",
"VolumeSize": 10,
"VolumeType": "standard"
}
},
{
"DeviceName": "/dev/sdc",
"VirtualName": "ephemeral1"
}
],
"EnaSupport": true,
"Hypervisor": "xen",
"Name": "packer-ES-1531993870",
"RootDeviceName": "/dev/sda1",
"RootDeviceType": "ebs",
"SriovNetSupport": "simple",
"VirtualizationType": "hvm"
}
]
}
If you don't need to provision anything on sdb you can remove the launch_device_mappings section completely and move the volume_size into the ami_device_mappings.

Cannot run tests (jasmine, karma, webpack)

I've been trying for a couple of days now to get some tests to run.
I've two environments, one very "empty" and another with a full project.
The 'empty' one does run a very simple test (but doesn't contain the Person object that is unable to be constructed in the full project).
I migrated the full project to a very similar environment in terms of installed dev packages, karma, jasmine versions and such. I also copied the tsconfig.json, karma.conf files across. Those are below.
For the life of me I cannot figure out why the karma tests will not run.
With previous versions of Karma I would get an error along the lines of 'scheduler_person.b' is not a constructor.
Digging a little deeper, it's failing on this line of test.store.ts:
let neil: Person = new Person("Neil Clayton");
the constructor of this object is:
constructor(name: string = "put name here") {
super();
this.name = name;
this.primary_roles = new Map<Role, number>();
this.specific_roles = new Map<string, Array<Role>>();
this.secondary_action_list = [];
this.condition_rules = [];
this.unavailable = [];
this.prefs = new SchedulePrefs();
}
So, the Person class has a constructor, and this code does run within the app itself.
I have since upgraded all of karma/jasmine and the error now changes to:
VM105 karma-test-shim.js:629 Uncaught TypeError: $f.b is not a constructor
Looking at the generated code, it's essentially exactly the same inability to call a constructor.
I feel I must be doing something very simple, very stupid, but I cannot see it.
Any ideas?
(btw: this project is at https://github.com/scornflake/scheduler)
tsconfig.json
{
"compilerOptions": {
"allowSyntheticDefaultImports": true,
"declaration": false,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"noImplicitThis": true,
"lib": [
"dom",
"es2015",
"esnext.asynciterable"
],
"module": "es2015",
"moduleResolution": "node",
"sourceMap": true,
"target": "es5"
},
"include": [
"src/**/*.ts"
],
"exclude": [
"node_modules",
"src/**/*.spec.ts"
],
"typeAcquisition": {
"enable": true,
"include": [
"./src/common/fix.broken.gapi.types.d.ts"
]
},
"compileOnSave": false,
"atom": {
"rewriteTsconfig": false
}
}
karma.config.json
const webpackConfig = require('./webpack.test.js');
module.exports = function (config) {
const _config = {
basePath: '',
frameworks: [
'jasmine'
// 'jasmine-matchers'
],
files: [
{
pattern: './karma-test-shim.js',
watched: true
}
],
preprocessors: {
'./karma-test-shim.js': ['webpack', 'sourcemap']
},
webpack: webpackConfig,
webpackMiddleware: {
stats: 'errors-only'
},
webpackServer: {
noInfo: true
},
browserConsoleLogOptions: {
level: 'log',
format: '%b %T: %m',
terminal: true
},
// reporters: ['kjhtml', 'dots'],
reporters: ['dots'],
// reporters: ['kjhtml'],
port: 9876,
colors: true,
logLevel: config.LOG_INFO,
autoWatch: true,
browsers: ['Chrome'],
singleRun: false
};
config.set(_config);
};
karma-test-shim.js
Error.stackTraceLimit = Infinity;
require('core-js/es6');
require('core-js/es7/reflect');
require('zone.js/dist/zone');
require('zone.js/dist/long-stack-trace-zone');
require('zone.js/dist/proxy');
require('zone.js/dist/sync-test');
require('zone.js/dist/jasmine-patch');
require('zone.js/dist/async-test');
require('zone.js/dist/fake-async-test');
var appContext = require.context('../src', true, /\.spec\.ts/);
appContext.keys().forEach(appContext);
var testing = require('#angular/core/testing');
var browser = require('#angular/platform-browser-dynamic/testing');
testing.TestBed.initTestEnvironment(browser.BrowserDynamicTestingModule, browser.platformBrowserDynamicTesting());
package.json
{
"name": "scheduler",
"version": "0.0.1",
"author": "Neil Clayton",
"homepage": "http://ionicframework.com/",
"private": true,
"scripts": {
"clean": "ionic-app-scripts clean",
"build": "ionic-app-scripts build --copy ./config/copy.config.js",
"lint": "ionic-app-scripts lint",
"ionic:build": "ionic-app-scripts build --copy ./config/copy.config.js",
"ionic:serve": "ionic-app-scripts serve --copy ./config/copy.config.js",
"test-coverage": "ng test --code-coverage",
"test": "ng test"
},
"dependencies": {
"#angular/common": "5.0.3",
"#angular/compiler": "5.0.3",
"#angular/compiler-cli": "5.0.3",
"#angular/core": "5.0.3",
"#angular/forms": "5.0.3",
"#angular/http": "5.0.3",
"#angular/platform-browser": "5.0.3",
"#angular/platform-browser-dynamic": "5.0.3",
"#ionic-native/core": "4.3.2",
"#ionic-native/splash-screen": "4.3.2",
"#ionic-native/status-bar": "4.3.2",
"#ionic/storage": "2.1.3",
"#types/gapi": "^0.0.35",
"#types/gapi.auth2": "^0.0.47",
"#types/gapi.client": "^1.0.0",
"#types/gapi.client.drive": "^3.0.1",
"#types/gapi.client.sheets": "^4.0.0",
"angular-pipes": "^6.5.3",
"apollo-angular": "^1.0.1",
"apollo-angular-link-http": "^1.0.2",
"apollo-cache-inmemory": "^1.1.12",
"apollo-client": "^2.2.8",
"apollo-link": "^1.2.2",
"cordova-browser": "5.0.1",
"cordova-plugin-device": "^1.1.4",
"cordova-plugin-ionic-webview": "^1.1.16",
"cordova-plugin-splashscreen": "^4.0.3",
"cordova-plugin-whitelist": "^1.3.1",
"file-saver": "^1.3.8",
"google-auth-library": "^1.4.0",
"googleapis": "^28.1.0",
"graphql": "^0.13.2",
"graphql-tag": "^2.8.0",
"ionic-angular": "3.9.2",
"ionic-configuration-service": "^6.0.0",
"ionic-logging-service": "^5.0.0",
"ionic-plugin-keyboard": "^2.2.1",
"ionicons": "3.0.0",
"json2csv": "^3.11.5",
"lodash": "^4.17.4",
"mobx": "^4.1.1",
"mobx-angular": "^3.0.1",
"moment": "^2.20.1",
"ng-circle-progress": "^0.9.9",
"rxjs": "5.5.2",
"short-unique-id": "^1.1.0",
"sw-toolbox": "3.6.0",
"to-case": "^2.0.0",
"zone.js": "^0.8.26"
},
"devDependencies": {
"#ionic/app-scripts": "3.1.6",
"#types/jasmine": "2.8.4",
"#types/node": "8.5.8",
"angular2-template-loader": "^0.6.2",
"file-save": "^0.2.0",
"html-loader": "^0.5.5",
"jasmine-core": "3.1.0",
"jasmine-expect": "^3.8.3",
"jasmine-spec-reporter": "^4.1.0",
"karma": "^2.0.2",
"karma-chrome-launcher": "^2.2.0",
"karma-jasmine": "^1.1.1",
"karma-sourcemap-loader": "^0.3.7",
"karma-webpack": "^3.0.0",
"null-loader": "^0.1.1",
"protractor": "5.3.0",
"ts-loader": "^4.2.0",
"ts-node": "4.1.0",
"typescript": "2.4.2",
"webpack": "^4.6.0"
},
"description": "Scheduler",
"cordova": {
"plugins": {
"ionic-plugin-keyboard": {},
"cordova-plugin-whitelist": {},
"cordova-plugin-device": {},
"cordova-plugin-splashscreen": {},
"cordova-plugin-ionic-webview": {}
},
"platforms": [
"browser"
]
}
}
Finally, some pics of the browser errors:
In src/providers/store/test.store.ts you need to move all of your global constants (and subsequent method calls) into the SetupStore method of the NPBCStoreConstruction class. When I do this I can run the test suite properly.
The cause of issue is that when Webpack/Typescript/something compiles everything, it picks an arbitrary order to include all the files and if you look at the generated code you can see that the global invocation of the person Person constructor happens before it is defined.

AWS SNS - Subscribe to topic fails - "Application endpoint arn invalid"

I want to register an appe-push-token to a topic on AWS SNS (Java / AmazonSDK).
Somewhere is a problem, but I cannot really spot it.
Following are the 3 required parameters (modified, so not valid):
enpoint (Apple Device Token): 6aae03b55912819b69dXXXXXXc75aab27716850XXXXXXe19e2710XXXX4983788
TopicArn: "arn:aws:sns:eu-central-1:1XXXXXXXX4:All_TrXXXXXXt"
Protocol: application
I try to subscribe to my topic like this:
public String subscribeToTopicWithTheNewToken(String pushToken) {
final String topicAllTXXXXXXXt = "arn:aws:sns:eu-central-1:14xxxxxx4:All_TXXXXXXXXt";
//***The following line brings up the exception***
final SubscribeResult application = snsClient.subscribe(topicAllTrXXXXXXt, "application", pushToken);
return application.getSubscriptionArn();
}
I subscribe using the raw topicArn, the raw string "application" and the raw apple device token.
Exception:
com.amazonaws.services.sns.model.InvalidParameterException: Invalid parameter: Application endpoint arn invalid:6aae03b5591281XXXXXX1d6ec75aab2XXXXXXXXXXXXXXXXXXXXXXXc4983788 (Service: AmazonSNS; Status Code: 400; Error Code: InvalidParameter; Request ID: 3a6dbe8a-9a4e-5177-97f5-ef88f12d2150)
at com.amazonaws.http.AmazonHttpClient$RequestExecutor.handleErrorResponse(AmazonHttpClient.java:1586) ~[aws-java-sdk-core-1.11.80.jar:na]
at com.amazonaws.http.AmazonHttpClient$RequestExecutor.executeOneRequest(AmazonHttpClient.java:1254) ~[aws-java-sdk-core-1.11.80.jar:na]
at com.amazonaws.http.AmazonHttpClient$RequestExecutor.executeHelper(AmazonHttpClient.java:1035) ~[aws-java-sdk-core-1.11.80.jar:na]
at com.amazonaws.http.AmazonHttpClient$RequestExecutor.doExecute(AmazonHttpClient.java:747) ~[aws-java-sdk-core-1.11.80.jar:na]
at com.amazonaws.http.AmazonHttpClient$RequestExecutor.executeWithTimer(AmazonHttpClient.java:721) ~[aws-java-sdk-core-1.11.80.jar:na]
at com.amazonaws.http.AmazonHttpClient$RequestExecutor.execute(AmazonHttpClient.java:704) ~[aws-java-sdk-core-1.11.80.jar:na]
at com.amazonaws.http.AmazonHttpClient$RequestExecutor.access$500(AmazonHttpClient.java:672) ~[aws-java-sdk-core-1.11.80.jar:na]
at com.amazonaws.http.AmazonHttpClient$RequestExecutionBuilderImpl.execute(AmazonHttpClient.java:654) ~[aws-java-sdk-core-1.11.80.jar:na]
at com.amazonaws.http.AmazonHttpClient.execute(AmazonHttpClient.java:518) ~[aws-java-sdk-core-1.11.80.jar:na]
at com.amazonaws.services.sns.AmazonSNSClient.doInvoke(AmazonSNSClient.java:2065) ~[aws-java-sdk-sns-1.11.80.jar:na]
at com.amazonaws.services.sns.AmazonSNSClient.invoke(AmazonSNSClient.java:2041) ~[aws-java-sdk-sns-1.11.80.jar:na]
at com.amazonaws.services.sns.AmazonSNSClient.subscribe(AmazonSNSClient.java:1941) ~[aws-java-sdk-sns-1.11.80.jar:na]
at com.amazonaws.services.sns.AmazonSNSClient.subscribe(AmazonSNSClient.java:1953) ~[aws-java-sdk-sns-1.11.80.jar:na]
at application.push_messages.PushMessageService.subscribeToTopicWithTheNewToken(PushMessageService.java:76) ~[main/:na]
at application.user.UserService.updateTokenForUser(UserService.java:159) ~[main/:na]
at application.user.UserService$$FastClassBySpringCGLIB$$b712c385.invoke(<generated>) ~[main/:na]
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204) ~[spring-core-4.3.3.RELEASE.jar:4.3.3.RELEASE]
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:651) ~[spring-aop-4.3.3.RELEASE.jar:4.3.3.RELEASE]
at application.user.UserService$$EnhancerBySpringCGLIB$$4de312b8.updateTokenForUser(<generated>) ~[main/:na]
at application.user.UserController.updatePushMessageToken(UserController.java:86) ~[main/:na]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_111]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_111]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_111]
at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_111]
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:221) ~[spring-web-4.3.3.RELEASE.jar:4.3.3.RELEASE]
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:136) ~[spring-web-4.3.3.RELEASE.jar:4.3.3.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:114) ~[spring-webmvc-4.3.3.RELEASE.jar:4.3.3.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:827) ~[spring-webmvc-4.3.3.RELEASE.jar:4.3.3.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:738) ~[spring-webmvc-4.3.3.RELEASE.jar:4.3.3.RELEASE]
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85) ~[spring-webmvc-4.3.3.RELEASE.jar:4.3.3.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:963) ~[spring-webmvc-4.3.3.RELEASE.jar:4.3.3.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:897) ~[spring-webmvc-4.3.3.RELEASE.jar:4.3.3.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970) ~[spring-webmvc-4.3.3.RELEASE.jar:4.3.3.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.doPut(FrameworkServlet.java:883) ~[spring-webmvc-4.3.3.RELEASE.jar:4.3.3.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:651) ~[tomcat-embed-core-8.5.5.jar:8.5.5]
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846) ~[spring-webmvc-4.3.3.RELEASE.jar:4.3.3.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:729) ~[tomcat-embed-core-8.5.5.jar:8.5.5]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:230) ~[tomcat-embed-core-8.5.5.jar:8.5.5]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165) ~[tomcat-embed-core-8.5.5.jar:8.5.5]
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) ~[tomcat-embed-websocket-8.5.5.jar:8.5.5]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192) ~[tomcat-embed-core-8.5.5.jar:8.5.5]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165) ~[tomcat-embed-core-8.5.5.jar:8.5.5]
at application.security.CorsFilter.doFilterInternal(CorsFilter.java:25) ~[main/:na]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.3.3.RELEASE.jar:4.3.3.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192) ~[tomcat-embed-core-8.5.5.jar:8.5.5]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165) ~[tomcat-embed-core-8.5.5.jar:8.5.5]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:317) ~[spring-security-web-4.1.3.RELEASE.jar:4.1.3.RELEASE]
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:127) ~[spring-security-web-4.1.3.RELEASE.jar:4.1.3.RELEASE]
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:91) ~[spring-security-web-4.1.3.RELEASE.jar:4.1.3.RELEASE]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) ~[spring-security-web-4.1.3.RELEASE.jar:4.1.3.RELEASE]
at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:115) ~[spring-security-web-4.1.3.RELEASE.jar:4.1.3.RELEASE]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) ~[spring-security-web-4.1.3.RELEASE.jar:4.1.3.RELEASE]
at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:137) ~[spring-security-web-4.1.3.RELEASE.jar:4.1.3.RELEASE]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) ~[spring-security-web-4.1.3.RELEASE.jar:4.1.3.RELEASE]
at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:111) ~[spring-security-web-4.1.3.RELEASE.jar:4.1.3.RELEASE]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) ~[spring-security-web-4.1.3.RELEASE.jar:4.1.3.RELEASE]
at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:169) ~[spring-security-web-4.1.3.RELEASE.jar:4.1.3.RELEASE]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) ~[spring-security-web-4.1.3.RELEASE.jar:4.1.3.RELEASE]
at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:63) ~[spring-security-web-4.1.3.RELEASE.jar:4.1.3.RELEASE]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) ~[spring-security-web-4.1.3.RELEASE.jar:4.1.3.RELEASE]
at org.springframework.security.web.authentication.www.BasicAuthenticationFilter.doFilterInternal(BasicAuthenticationFilter.java:215) ~[spring-security-web-4.1.3.RELEASE.jar:4.1.3.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.3.3.RELEASE.jar:4.3.3.RELEASE]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) ~[spring-security-web-4.1.3.RELEASE.jar:4.1.3.RELEASE]
at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:121) ~[spring-security-web-4.1.3.RELEASE.jar:4.1.3.RELEASE]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) ~[spring-security-web-4.1.3.RELEASE.jar:4.1.3.RELEASE]
at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:66) ~[spring-security-web-4.1.3.RELEASE.jar:4.1.3.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.3.3.RELEASE.jar:4.3.3.RELEASE]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) ~[spring-security-web-4.1.3.RELEASE.jar:4.1.3.RELEASE]
at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:105) ~[spring-security-web-4.1.3.RELEASE.jar:4.1.3.RELEASE]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) ~[spring-security-web-4.1.3.RELEASE.jar:4.1.3.RELEASE]
at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:56) ~[spring-security-web-4.1.3.RELEASE.jar:4.1.3.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.3.3.RELEASE.jar:4.3.3.RELEASE]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) ~[spring-security-web-4.1.3.RELEASE.jar:4.1.3.RELEASE]
at application.security.CorsFilter.doFilterInternal(CorsFilter.java:25) ~[main/:na]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.3.3.RELEASE.jar:4.3.3.RELEASE]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) ~[spring-security-web-4.1.3.RELEASE.jar:4.1.3.RELEASE]
at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:214) ~[spring-security-web-4.1.3.RELEASE.jar:4.1.3.RELEASE]
at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:177) ~[spring-security-web-4.1.3.RELEASE.jar:4.1.3.RELEASE]
at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346) ~[spring-web-4.3.3.RELEASE.jar:4.3.3.RELEASE]
at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:262) ~[spring-web-4.3.3.RELEASE.jar:4.3.3.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192) ~[tomcat-embed-core-8.5.5.jar:8.5.5]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165) ~[tomcat-embed-core-8.5.5.jar:8.5.5]
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99) ~[spring-web-4.3.3.RELEASE.jar:4.3.3.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.3.3.RELEASE.jar:4.3.3.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192) ~[tomcat-embed-core-8.5.5.jar:8.5.5]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165) ~[tomcat-embed-core-8.5.5.jar:8.5.5]
at org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:89) ~[spring-web-4.3.3.RELEASE.jar:4.3.3.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.3.3.RELEASE.jar:4.3.3.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192) ~[tomcat-embed-core-8.5.5.jar:8.5.5]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165) ~[tomcat-embed-core-8.5.5.jar:8.5.5]
at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:77) ~[spring-web-4.3.3.RELEASE.jar:4.3.3.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.3.3.RELEASE.jar:4.3.3.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192) ~[tomcat-embed-core-8.5.5.jar:8.5.5]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165) ~[tomcat-embed-core-8.5.5.jar:8.5.5]
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:197) ~[spring-web-4.3.3.RELEASE.jar:4.3.3.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.3.3.RELEASE.jar:4.3.3.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192) ~[tomcat-embed-core-8.5.5.jar:8.5.5]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165) ~[tomcat-embed-core-8.5.5.jar:8.5.5]
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:198) ~[tomcat-embed-core-8.5.5.jar:8.5.5]
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:108) [tomcat-embed-core-8.5.5.jar:8.5.5]
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472) [tomcat-embed-core-8.5.5.jar:8.5.5]
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140) [tomcat-embed-core-8.5.5.jar:8.5.5]
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79) [tomcat-embed-core-8.5.5.jar:8.5.5]
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87) [tomcat-embed-core-8.5.5.jar:8.5.5]
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:349) [tomcat-embed-core-8.5.5.jar:8.5.5]
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:784) [tomcat-embed-core-8.5.5.jar:8.5.5]
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66) [tomcat-embed-core-8.5.5.jar:8.5.5]
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:802) [tomcat-embed-core-8.5.5.jar:8.5.5]
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1410) [tomcat-embed-core-8.5.5.jar:8.5.5]
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) [tomcat-embed-core-8.5.5.jar:8.5.5]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [na:1.8.0_111]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [na:1.8.0_111]
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-embed-core-8.5.5.jar:8.5.5]
at java.lang.Thread.run(Thread.java:745) [na:1.8.0_111]
What am I doing wrong? Is my endpoint formatted wrongly? Did I misunderstood some other point? I would really appreciate any kind of hint/help you can provide me with.
I found the problem with the help of #DaveMaple:
I didn't know about "Endpoints". You first need to create an SNS endpoint and subscribe to a topic using this endpoint and NOT the device-token!
So here are the steps:
Create an `AWS - Topic`
Create an `AWS - Application`
Connect to the `AWS - Application` and get an endpoint from there for each device.
Use this endpoint `ARN` to subsribe to you `AWS - Topic`.
From here, you can publish messages over the topic and all connected devices will receive it.
See this link for further information.