-
Notifications
You must be signed in to change notification settings - Fork 145
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add URL reachability checks to shorebird doctor (#2537)
- Loading branch information
1 parent
8f43bb5
commit cec1bf5
Showing
6 changed files
with
139 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
import 'package:scoped_deps/scoped_deps.dart'; | ||
import 'package:shorebird_cli/src/http_client/http_client.dart'; | ||
import 'package:shorebird_cli/src/logger.dart'; | ||
|
||
/// A reference to a [NetworkChecker] instance. | ||
final networkCheckerRef = create(NetworkChecker.new); | ||
|
||
/// The [NetworkChecker] instance available in the current zone. | ||
NetworkChecker get networkChecker => read(networkCheckerRef); | ||
|
||
/// {@template network_checker} | ||
/// Checks reachability of various Shorebird-related endpoints and logs the | ||
/// results. | ||
/// {@endtemplate} | ||
class NetworkChecker { | ||
/// The URLs to check for network reachability. | ||
static final urlsToCheck = [ | ||
'https://api.shorebird.dev', | ||
'https://console.shorebird.dev', | ||
'https://oauth2.googleapis.com', | ||
].map(Uri.parse).toList(); | ||
|
||
/// Verify that each of [urlsToCheck] responds to an HTTP GET request. | ||
Future<void> checkReachability() async { | ||
for (final url in urlsToCheck) { | ||
final progress = logger.progress('Checking reachability of $url'); | ||
|
||
try { | ||
await httpClient.get(url); | ||
progress.complete('$url OK'); | ||
} catch (e) { | ||
progress.fail('$url unreachable'); | ||
logger.detail('Failed to reach $url: $e'); | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
import 'dart:io'; | ||
|
||
import 'package:http/http.dart' as http; | ||
import 'package:mason_logger/mason_logger.dart'; | ||
import 'package:mocktail/mocktail.dart'; | ||
import 'package:scoped_deps/scoped_deps.dart'; | ||
import 'package:shorebird_cli/src/http_client/http_client.dart'; | ||
import 'package:shorebird_cli/src/logger.dart'; | ||
import 'package:shorebird_cli/src/network_checker.dart'; | ||
import 'package:test/test.dart'; | ||
|
||
import 'fakes.dart'; | ||
import 'mocks.dart'; | ||
|
||
void main() { | ||
group(NetworkChecker, () { | ||
late http.Client httpClient; | ||
late ShorebirdLogger logger; | ||
late Progress progress; | ||
late NetworkChecker networkChecker; | ||
|
||
R runWithOverrides<R>(R Function() body) { | ||
return runScoped( | ||
() => body(), | ||
values: { | ||
httpClientRef.overrideWith(() => httpClient), | ||
loggerRef.overrideWith(() => logger), | ||
}, | ||
); | ||
} | ||
|
||
setUpAll(() { | ||
registerFallbackValue(FakeBaseRequest()); | ||
registerFallbackValue(Uri()); | ||
}); | ||
|
||
setUp(() { | ||
httpClient = MockHttpClient(); | ||
logger = MockShorebirdLogger(); | ||
progress = MockProgress(); | ||
|
||
when(() => logger.progress(any())).thenReturn(progress); | ||
|
||
networkChecker = NetworkChecker(); | ||
}); | ||
|
||
group('checkReachability', () { | ||
group('when endpoints are reachable', () { | ||
setUp(() { | ||
when(() => httpClient.get(any())).thenAnswer( | ||
(_) async => http.Response('', HttpStatus.ok), | ||
); | ||
}); | ||
|
||
test('logs reachability for each checked url', () async { | ||
await runWithOverrides(networkChecker.checkReachability); | ||
|
||
verify( | ||
() => progress.complete(any(that: contains('OK'))), | ||
).called(NetworkChecker.urlsToCheck.length); | ||
}); | ||
}); | ||
|
||
group('when endpoints are not reachable', () { | ||
setUp(() { | ||
when(() => httpClient.send(any())).thenThrow(Exception('oops')); | ||
}); | ||
|
||
test('logs reachability for each checked url', () async { | ||
await runWithOverrides(networkChecker.checkReachability); | ||
|
||
verify( | ||
() => progress.fail(any(that: contains('unreachable'))), | ||
).called(NetworkChecker.urlsToCheck.length); | ||
}); | ||
}); | ||
}); | ||
}); | ||
} |