Unverified Commit d9bdb76f authored by Chris Bracken's avatar Chris Bracken Committed by GitHub

Eliminate unused retry.dart from flutter_driver (#13161)

parent 78e044f5
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'dart:async';
/// Performs an action and returns either the result of the action or a [Future]
/// that evaluates to the result.
typedef dynamic Action();
/// Determines if [value] is acceptable. For good style an implementation should
/// be idempotent.
typedef bool Predicate(dynamic value);
/// Performs [action] repeatedly until it either succeeds or [timeout] limit is
/// reached.
///
/// When the retry time out, the last seen error and stack trace are returned in
/// an error [Future].
Future<dynamic> retry(
Action action,
Duration timeout,
Duration pauseBetweenRetries, {
Predicate predicate,
}) async {
assert(action != null);
assert(timeout != null);
assert(pauseBetweenRetries != null);
final Stopwatch sw = stopwatchFactory()..start();
dynamic result;
dynamic lastError;
dynamic lastStackTrace;
bool success = false;
while (!success && sw.elapsed < timeout) {
try {
result = await action();
if (predicate == null || predicate(result))
success = true;
lastError = null;
lastStackTrace = null;
} catch(error, stackTrace) {
lastError = error;
lastStackTrace = stackTrace;
}
if (!success && sw.elapsed < timeout)
await new Future<Null>.delayed(pauseBetweenRetries);
}
if (success)
return result;
else if (lastError != null)
return new Future<Null>.error(lastError, lastStackTrace);
else
return new Future<Null>.error('Retry timed out');
}
/// A function that produces a [Stopwatch].
typedef Stopwatch StopwatchFactory();
/// Restores [stopwatchFactory] to the default implementation.
void restoreStopwatchFactory() {
stopwatchFactory = () => new Stopwatch();
}
/// Used by [retry] as a source of [Stopwatch] implementation.
StopwatchFactory stopwatchFactory = () => new Stopwatch();
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'package:test/test.dart';
import 'package:quiver/time.dart';
import 'package:quiver/testing/async.dart';
import 'package:quiver/testing/time.dart';
import 'package:flutter_driver/src/retry.dart';
void main() {
group('retry', () {
FakeAsync fakeAsync;
setUp(() {
fakeAsync = new FakeAsync();
final Clock fakeClock = fakeAsync.getClock(new DateTime.now());
stopwatchFactory = () {
return new FakeStopwatch(
() => fakeClock.now().millisecondsSinceEpoch,
1000
);
};
});
test('retries until succeeds', () {
fakeAsync.run((_) {
int retryCount = 0;
expect(
retry(
() async {
retryCount++;
if (retryCount < 2) {
throw 'error';
} else {
return retryCount;
}
},
const Duration(milliseconds: 30),
const Duration(milliseconds: 10)
),
completion(2)
);
fakeAsync.elapse(const Duration(milliseconds: 50));
// Check that we didn't retry more times than necessary
expect(retryCount, 2);
});
});
test('obeys predicates', () {
fakeAsync.run((_) {
int retryCount = 0;
expect(
// The predicate requires that the returned value is 2, so we expect
// that `retry` keeps trying until the counter reaches 2.
retry(
() async => retryCount++,
const Duration(milliseconds: 30),
const Duration(milliseconds: 10),
predicate: (int value) => value == 2
),
completion(2)
);
fakeAsync.elapse(const Duration(milliseconds: 50));
});
});
test('times out returning last error', () async {
fakeAsync.run((_) {
bool timedOut = false;
int retryCount = 0;
dynamic lastError;
dynamic lastStackTrace;
retry(
() {
retryCount++;
throw 'error';
},
const Duration(milliseconds: 7),
const Duration(milliseconds: 2)
).catchError((dynamic error, dynamic stackTrace) {
timedOut = true;
lastError = error;
lastStackTrace = stackTrace;
});
fakeAsync.elapse(const Duration(milliseconds: 10));
expect(timedOut, isTrue);
expect(lastError, 'error');
expect(lastStackTrace, isNotNull);
expect(retryCount, 4);
});
});
});
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment