diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index ef3a7e025..c7b5201c3 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -39,11 +39,6 @@ jobs: cache: true flutter-version: ${{ matrix.sdk == 'min' && '2.8.0' || '' }} channel: ${{ matrix.sdk == 'min' && '' || matrix.channel }} - - run: | - chmod +x ./scripts/prepare_pinning_certs.sh - ./scripts/prepare_pinning_certs.sh - - name: Install proxy for tests - run: sudo apt-get update && sudo apt-get install -y squid - run: dart pub get - uses: bluefireteam/melos-action@v3 with: @@ -63,6 +58,30 @@ jobs: - name: '[Verify step] Publish dry-run' if: ${{ matrix.sdk == 'stable' }} run: melos run publish-dry-run + # Tests + - run: | + chmod +x ./scripts/prepare_pinning_certs.sh + ./scripts/prepare_pinning_certs.sh + - name: Install proxy for tests + run: sudo apt-get update && sudo apt-get install -y squid mkcert + - name: Start local httpbun + run: | + mkcert -install + mkcert -cert-file '/tmp/cert.pem' -key-file '/tmp/key.pem' httpbun.local + echo '127.0.0.1 httpbun.local' | sudo tee --append /etc/hosts + docker run \ + --name httpbun \ + --detach \ + --publish 443:443 \ + --volume /tmp:/tmp:ro \ + --env HTTPBUN_TLS_CERT=/tmp/cert.pem \ + --env HTTPBUN_TLS_KEY=/tmp/key.pem \ + --pull always \ + sharat87/httpbun + sleep 1 + curl --fail --silent --show-error https://httpbun.local/any + - name: Use local httpbun in tests + run: melos run httpbun:local - name: '[Verify step] Test Dart packages [VM]' run: melos run test:dart - name: '[Verify step] Test Dart packages [Chrome]' @@ -75,6 +94,7 @@ jobs: TEST_PLATFORM: firefox - name: '[Verify step] Test Flutter packages' run: melos run test:flutter + # Coverage - name: '[Coverage] Format & print test coverage' if: ${{ matrix.sdk == 'stable' }} run: melos run coverage:show diff --git a/dio/dart_test.yaml b/dio/dart_test.yaml index 4e6cd51e3..53189589b 100644 --- a/dio/dart_test.yaml +++ b/dio/dart_test.yaml @@ -18,3 +18,6 @@ override_platforms: settings: # headless argument has to be set explicitly for non-chrome browsers arguments: --headless + executable: + # https://github.com/dart-lang/test/pull/2195 + mac_os: '/Applications/Firefox.app/Contents/MacOS/firefox' \ No newline at end of file diff --git a/dio/test/download_test.dart b/dio/test/download_test.dart index b8fe20f7f..85025b696 100644 --- a/dio/test/download_test.dart +++ b/dio/test/download_test.dart @@ -178,7 +178,7 @@ void main() { expect(f.existsSync(), isTrue); final cancelToken = CancelToken(); - final dio = Dio()..options.baseUrl = 'https://httpbun.com'; + final dio = Dio()..options.baseUrl = httpbunBaseUrl; await expectLater( dio.download( diff --git a/dio/test/test_suite_test.dart b/dio/test/test_suite_test.dart index 750dbb552..1b341d3ca 100644 --- a/dio/test/test_suite_test.dart +++ b/dio/test/test_suite_test.dart @@ -3,6 +3,6 @@ import 'package:dio_test/tests.dart'; void main() { dioAdapterTestSuite( - () => Dio(BaseOptions(baseUrl: 'https://httpbun.com/')), + (baseUrl) => Dio(BaseOptions(baseUrl: baseUrl)), ); } diff --git a/dio/test/timeout_test.dart b/dio/test/timeout_test.dart index bb9e7e8e5..7cafe2288 100644 --- a/dio/test/timeout_test.dart +++ b/dio/test/timeout_test.dart @@ -2,6 +2,7 @@ import 'dart:io'; import 'package:dio/dio.dart'; import 'package:dio/io.dart'; +import 'package:dio_test/util.dart'; import 'package:test/test.dart'; void main() { @@ -9,7 +10,7 @@ void main() { setUp(() { dio = Dio(); - dio.options.baseUrl = 'https://httpbun.com/'; + dio.options.baseUrl = httpbunBaseUrl; }); group('Timeout exception of', () { @@ -17,7 +18,7 @@ void main() { test('update between calls', () async { final client = HttpClient(); final dio = Dio() - ..options.baseUrl = 'https://httpbun.com' + ..options.baseUrl = httpbunBaseUrl ..httpClientAdapter = IOHttpClientAdapter( createHttpClient: () => client, ); diff --git a/dio/test/upload_test.dart b/dio/test/upload_test.dart index 33ddfd183..b4055ccb0 100644 --- a/dio/test/upload_test.dart +++ b/dio/test/upload_test.dart @@ -4,13 +4,14 @@ import 'dart:io'; import 'dart:typed_data'; import 'package:dio/dio.dart'; +import 'package:dio_test/util.dart'; import 'package:test/test.dart'; void main() { late Dio dio; setUp(() { - dio = Dio()..options.baseUrl = 'https://httpbun.com/'; + dio = Dio()..options.baseUrl = httpbunBaseUrl; }); test('Uint8List should not be transformed', () async { diff --git a/dio_test/dart_test.yaml b/dio_test/dart_test.yaml deleted file mode 100644 index 52cfb59fa..000000000 --- a/dio_test/dart_test.yaml +++ /dev/null @@ -1,18 +0,0 @@ -file_reporters: - json: build/reports/test-results.json - -tags: - tls: - skip: "Skipping TLS test with specific setup requirements by default. Use '-P all' to run all tests." - presets: - all: - skip: false - -override_platforms: - chrome: - settings: - headless: true - firefox: - settings: - # headless argument has to be set explicitly for non-chrome browsers - arguments: --headless diff --git a/dio_test/lib/src/httpbun.dart b/dio_test/lib/src/httpbun.dart new file mode 100644 index 000000000..b2e435942 --- /dev/null +++ b/dio_test/lib/src/httpbun.dart @@ -0,0 +1 @@ +const httpbunBaseUrl = 'https://httpbun.com'; diff --git a/dio_test/lib/src/test/cors_tests.dart b/dio_test/lib/src/test/cors_tests.dart index e2da90672..a726a1e1c 100644 --- a/dio_test/lib/src/test/cors_tests.dart +++ b/dio_test/lib/src/test/cors_tests.dart @@ -6,12 +6,12 @@ import 'package:test/test.dart'; /// either "simple" or "preflighted". Reference: /// https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#simple_requests void corsTests( - Dio Function() create, + Dio Function(String baseUrl) create, ) { late Dio dio; setUp(() { - dio = create(); + dio = create(httpbunBaseUrl); }); group('CORS preflight', () { diff --git a/dio_test/lib/src/test/download_stream_tests.dart b/dio_test/lib/src/test/download_stream_tests.dart index e45fbf83c..f01b9d9e5 100644 --- a/dio_test/lib/src/test/download_stream_tests.dart +++ b/dio_test/lib/src/test/download_stream_tests.dart @@ -1,20 +1,19 @@ import 'dart:io'; import 'package:dio/dio.dart'; +import 'package:dio_test/util.dart'; import 'package:path/path.dart' as p; import 'package:test/test.dart'; -import '../../util.dart'; - void downloadStreamTests( - Dio Function() create, + Dio Function(String baseUrl) create, ) { group('download', () { late Dio dio; late Directory tmp; setUp(() { - dio = create(); + dio = create(httpbunBaseUrl); }); setUpAll(() { @@ -23,6 +22,7 @@ void downloadStreamTests( tmp.deleteSync(recursive: true); }); }); + test('bytes', () async { final path = p.join(tmp.path, 'bytes.txt'); @@ -93,7 +93,7 @@ void downloadStreamTests( test('cancels streamed response mid request', () async { final cancelToken = CancelToken(); final response = await dio.get( - 'bytes/${1024 * 1024 * 100}', + '/bytes/${1024 * 1024 * 100}', options: Options(responseType: ResponseType.stream), cancelToken: cancelToken, onReceiveProgress: (c, t) { @@ -118,7 +118,7 @@ void downloadStreamTests( await expectLater( dio.download( - 'bytes/${1024 * 1024 * 10}', + '/bytes/${1024 * 1024 * 10}', path, cancelToken: cancelToken, onReceiveProgress: (c, t) { diff --git a/dio_test/lib/src/test/headers_tests.dart b/dio_test/lib/src/test/headers_tests.dart index 8724dddae..8cb91a8a8 100644 --- a/dio_test/lib/src/test/headers_tests.dart +++ b/dio_test/lib/src/test/headers_tests.dart @@ -1,13 +1,14 @@ import 'package:dio/dio.dart'; +import 'package:dio_test/util.dart'; import 'package:test/test.dart'; void headerTests( - Dio Function() create, + Dio Function(String baseUrl) create, ) { late Dio dio; - setUpAll(() { - dio = create(); + setUp(() { + dio = create(httpbunBaseUrl); }); group('headers', () { diff --git a/dio_test/lib/src/test/http_method_tests.dart b/dio_test/lib/src/test/http_method_tests.dart index 2240f6503..415ad6f31 100644 --- a/dio_test/lib/src/test/http_method_tests.dart +++ b/dio_test/lib/src/test/http_method_tests.dart @@ -1,14 +1,16 @@ import 'package:dio/dio.dart'; +import 'package:dio_test/util.dart'; import 'package:test/test.dart'; void httpMethodTests( - Dio Function() create, + Dio Function(String baseUrl) create, ) { const data = {'content': 'I am payload'}; late Dio dio; - setUpAll(() { - dio = create(); + + setUp(() { + dio = create(httpbunBaseUrl); }); group('HTTP method', () { diff --git a/dio_test/lib/src/test/parameter_tests.dart b/dio_test/lib/src/test/parameter_tests.dart index 284956ffd..5eca0ad76 100644 --- a/dio_test/lib/src/test/parameter_tests.dart +++ b/dio_test/lib/src/test/parameter_tests.dart @@ -1,13 +1,14 @@ import 'package:dio/dio.dart'; +import 'package:dio_test/util.dart'; import 'package:test/test.dart'; void parameterTests( - Dio Function() create, + Dio Function(String baseUrl) create, ) { late Dio dio; - setUpAll(() { - dio = create(); + setUp(() { + dio = create(httpbunBaseUrl); }); group('parameters', () { diff --git a/dio_test/lib/src/test/redirect_tests.dart b/dio_test/lib/src/test/redirect_tests.dart index 6693a351a..6223cf9de 100644 --- a/dio_test/lib/src/test/redirect_tests.dart +++ b/dio_test/lib/src/test/redirect_tests.dart @@ -1,22 +1,21 @@ import 'package:dio/dio.dart'; +import 'package:dio_test/util.dart'; import 'package:test/test.dart'; -import '../utils.dart'; - void redirectTests( - Dio Function() create, + Dio Function(String baseUrl) create, ) { late Dio dio; - setUpAll(() { - dio = create(); + setUp(() { + dio = create(httpbunBaseUrl); }); group('redirects', () { test('single', () async { final response = await dio.get( '/redirect', - queryParameters: {'url': 'https://httpbun.com/get'}, + queryParameters: {'url': '$httpbunBaseUrl/get'}, onReceiveProgress: (received, total) { // ignore progress }, diff --git a/dio_test/lib/src/test/status_code_tests.dart b/dio_test/lib/src/test/status_code_tests.dart index 391313b51..7b5aa743b 100644 --- a/dio_test/lib/src/test/status_code_tests.dart +++ b/dio_test/lib/src/test/status_code_tests.dart @@ -1,16 +1,14 @@ import 'package:dio/dio.dart'; -import 'package:dio_test/src/utils.dart'; +import 'package:dio_test/util.dart'; import 'package:test/test.dart'; -import '../matcher.dart'; - void statusCodeTests( - Dio Function() create, + Dio Function(String baseUrl) create, ) { late Dio dio; - setUpAll(() { - dio = create(); + setUp(() { + dio = create(httpbunBaseUrl); }); group('status code', () { diff --git a/dio_test/lib/src/test/suite.dart b/dio_test/lib/src/test/suite.dart index 4abc37f8f..5fad692b9 100644 --- a/dio_test/lib/src/test/suite.dart +++ b/dio_test/lib/src/test/suite.dart @@ -2,7 +2,7 @@ import 'package:dio/dio.dart'; import 'package:dio_test/tests.dart'; typedef TestSuiteFunction = void Function( - Dio Function() create, + Dio Function(String baseUrl) create, ); const _tests = [ @@ -17,7 +17,7 @@ const _tests = [ ]; void dioAdapterTestSuite( - Dio Function() create, { + Dio Function(String baseUrl) create, { List tests = _tests, }) => tests.forEach((test) => test(create)); diff --git a/dio_test/lib/src/test/timeout_tests.dart b/dio_test/lib/src/test/timeout_tests.dart index 95e531eda..aab05d0e9 100644 --- a/dio_test/lib/src/test/timeout_tests.dart +++ b/dio_test/lib/src/test/timeout_tests.dart @@ -1,16 +1,16 @@ import 'dart:async'; import 'package:dio/dio.dart'; -import 'package:dio_test/src/matcher.dart'; +import 'package:dio_test/util.dart'; import 'package:test/test.dart'; void timeoutTests( - Dio Function() create, + Dio Function(String baseUrl) create, ) { late Dio dio; setUp(() { - dio = create(); + dio = create(httpbunBaseUrl); }); group('Timeout exception of', () { @@ -75,16 +75,13 @@ void timeoutTests( dio.options.receiveTimeout = Duration(seconds: 5); await dio.get('/drip?delay=1&numbytes=1'); + }); test('ignores zero duration timeouts', () async { - final dio = Dio( - BaseOptions( - baseUrl: 'https://httpbun.com/', - connectTimeout: Duration.zero, - receiveTimeout: Duration.zero, - ), - ); + dio.options + ..connectTimeout = Duration.zero + ..receiveTimeout = Duration.zero; // Ignores zero duration timeouts from the base options. await dio.get('/drip-lines?delay=1'); // Reset the base options. diff --git a/dio_test/lib/util.dart b/dio_test/lib/util.dart index d1e442026..f182df099 100644 --- a/dio_test/lib/util.dart +++ b/dio_test/lib/util.dart @@ -1,2 +1,3 @@ +export 'src/httpbun.dart'; export 'src/matcher.dart'; export 'src/utils.dart'; diff --git a/melos.yaml b/melos.yaml index 01b4cd139..17fb5c16f 100644 --- a/melos.yaml +++ b/melos.yaml @@ -41,6 +41,12 @@ scripts: exec: dart pub publish --dry-run packageFilters: noPrivate: true + httpbun:local: + description: Run httpbun locally + run: echo "const httpbunBaseUrl = 'https://httpbun.local';" > dio_test/lib/src/httpbun.dart + httpbun:com: + description: Run httpbun locally + run: echo "const httpbunBaseUrl = 'https://httpbun.com';" > dio_test/lib/src/httpbun.dart test: name: All tests run: | @@ -64,6 +70,7 @@ scripts: test:web: name: Dart Web tests exec: dart test --platform ${TEST_PLATFORM:-chrome} --coverage coverage/${TEST_PLATFORM:-chrome} --preset ${TEST_PRESET:-default} --chain-stack-traces + concurrency: 1 packageFilters: flutter: false dirExists: test diff --git a/plugins/compatibility_layer/dart_test.yaml b/plugins/compatibility_layer/dart_test.yaml index 454e43c22..e795a634b 100644 --- a/plugins/compatibility_layer/dart_test.yaml +++ b/plugins/compatibility_layer/dart_test.yaml @@ -11,3 +11,5 @@ override_platforms: settings: # headless argument has to be set explicitly for non-chrome browsers arguments: --headless + # https://github.com/dart-lang/test/pull/2195 + mac_os: '/Applications/Firefox.app/Contents/MacOS/firefox' diff --git a/plugins/http2_adapter/test/http2_test.dart b/plugins/http2_adapter/test/http2_test.dart index a936f962e..f37ea0093 100644 --- a/plugins/http2_adapter/test/http2_test.dart +++ b/plugins/http2_adapter/test/http2_test.dart @@ -1,11 +1,12 @@ import 'package:dio/dio.dart'; import 'package:dio_http2_adapter/dio_http2_adapter.dart'; +import 'package:dio_test/util.dart'; import 'package:test/test.dart'; void main() { test('works with non-TLS requests', () async { final dio = Dio()..httpClientAdapter = Http2Adapter(ConnectionManager()); - await dio.get('http://flutter.cn/'); + await dio.get('https://flutter.cn/'); await dio.get('https://flutter.cn/non-exist-destination'); }); @@ -56,7 +57,7 @@ void main() { test('adds one to input values', () async { final dio = Dio() - ..options.baseUrl = 'https://httpbun.com/' + ..options.baseUrl = httpbunBaseUrl ..httpClientAdapter = Http2Adapter( ConnectionManager( idleTimeout: Duration(milliseconds: 10), @@ -76,7 +77,7 @@ void main() { test('request with payload', () async { final dio = Dio() - ..options.baseUrl = 'https://httpbun.com/' + ..options.baseUrl = httpbunBaseUrl ..httpClientAdapter = Http2Adapter( ConnectionManager( idleTimeout: Duration(milliseconds: 10), @@ -91,7 +92,7 @@ void main() { 'request with payload via proxy', () async { final dio = Dio() - ..options.baseUrl = 'https://httpbun.com/' + ..options.baseUrl = httpbunBaseUrl ..httpClientAdapter = Http2Adapter(ConnectionManager( idleTimeout: Duration(milliseconds: 10), onClientCreate: (uri, settings) => @@ -107,7 +108,7 @@ void main() { test('request without network and restore', () async { bool needProxy = true; final dio = Dio() - ..options.baseUrl = 'https://httpbun.com/' + ..options.baseUrl = httpbunBaseUrl ..httpClientAdapter = Http2Adapter(ConnectionManager( idleTimeout: Duration(milliseconds: 10), onClientCreate: (uri, settings) { @@ -134,7 +135,7 @@ void main() { test('catch DioException when receiveTimeout', () { final dio = Dio( BaseOptions( - baseUrl: 'https://httpbun.com/', + baseUrl: httpbunBaseUrl, receiveTimeout: Duration(seconds: 5), ), ); @@ -159,7 +160,7 @@ void main() { test('no DioException when receiveTimeout > request duration', () async { final dio = Dio( BaseOptions( - baseUrl: 'https://httpbun.com/', + baseUrl: httpbunBaseUrl, receiveTimeout: Duration(seconds: 5), ), ); @@ -174,13 +175,13 @@ void main() { group('redirects', () { final dio = Dio() - ..options.baseUrl = 'https://httpbun.com/' + ..options.baseUrl = httpbunBaseUrl ..httpClientAdapter = Http2Adapter(ConnectionManager()); test('single', () async { final response = await dio.get( '/redirect', - queryParameters: {'url': 'https://httpbun.com/get'}, + queryParameters: {'url': '$httpbunBaseUrl/get'}, ); expect(response.isRedirect, isTrue); expect(response.redirects.length, 1); @@ -228,7 +229,7 @@ void main() { test('header value types implicit support', () async { final dio = Dio() - ..options.baseUrl = 'https://httpbun.com/' + ..options.baseUrl = httpbunBaseUrl ..httpClientAdapter = Http2Adapter(ConnectionManager()); final res = await dio.post( diff --git a/plugins/http2_adapter/test/test_suite_test.dart b/plugins/http2_adapter/test/test_suite_test.dart index fe6f76d2e..5c7e907ae 100644 --- a/plugins/http2_adapter/test/test_suite_test.dart +++ b/plugins/http2_adapter/test/test_suite_test.dart @@ -4,7 +4,7 @@ import 'package:dio_test/tests.dart'; void main() { dioAdapterTestSuite( - () => Dio(BaseOptions(baseUrl: 'https://httpbun.com/')) + (baseUrl) => Dio(BaseOptions(baseUrl: baseUrl)) ..httpClientAdapter = Http2Adapter(ConnectionManager()), ); }