gradle_plugin_light_apk_test.dart 8.9 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
// Copyright (c) 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';
import 'dart:io';

import 'package:flutter_devicelab/framework/apk_utils.dart';
import 'package:flutter_devicelab/framework/framework.dart';
import 'package:flutter_devicelab/framework/utils.dart';

Future<void> main() async {
  await task(() async {
    try {
      await runPluginProjectTest((FlutterPluginProject pluginProject) async {
        section('APK content for task assembleDebug with target platform = android-arm');
        await pluginProject.runGradleTask('assembleDebug',
            options: <String>['-Ptarget-platform=android-arm']);

20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
        final Iterable<String> apkFiles = await getFilesInApk(pluginProject.debugApkPath);

        checkItContains<String>(<String>[
          'AndroidManifest.xml',
          'classes.dex',
          'assets/flutter_assets/isolate_snapshot_data',
          'assets/flutter_assets/kernel_blob.bin',
          'assets/flutter_assets/vm_snapshot_data',
          'lib/armeabi-v7a/libflutter.so',
          // Debug mode intentionally includes `x86` and `x86_64`.
          'lib/x86/libflutter.so',
          'lib/x86_64/libflutter.so',
        ], apkFiles);

        checkItDoesNotContain<String>(<String>[
          'lib/armeabi-v7a/libapp.so',
          'lib/x86/libapp.so',
          'lib/x86_64/libapp.so',
        ], apkFiles);
      });

      await runPluginProjectTest((FlutterPluginProject pluginProject) async {
        section('APK content for task assembleDebug with target platform = android-x86');
        // This is used by `flutter run`
        await pluginProject.runGradleTask('assembleDebug',
            options: <String>['-Ptarget-platform=android-x86']);

        final Iterable<String> apkFiles = await getFilesInApk(pluginProject.debugApkPath);

        checkItContains<String>(<String>[
          'AndroidManifest.xml',
          'classes.dex',
          'assets/flutter_assets/isolate_snapshot_data',
          'assets/flutter_assets/kernel_blob.bin',
          'assets/flutter_assets/vm_snapshot_data',
          'lib/armeabi-v7a/libflutter.so',
          // Debug mode intentionally includes `x86` and `x86_64`.
          'lib/x86/libflutter.so',
          'lib/x86_64/libflutter.so',
        ], apkFiles);
60

61 62 63 64 65 66 67 68 69 70 71 72 73 74
        checkItDoesNotContain<String>(<String>[
          'lib/armeabi-v7a/libapp.so',
          'lib/x86/libapp.so',
          'lib/x86_64/libapp.so',
        ], apkFiles);
      });

      await runPluginProjectTest((FlutterPluginProject pluginProject) async {
        section('APK content for task assembleDebug with target platform = android-x64');
        // This is used by `flutter run`
        await pluginProject.runGradleTask('assembleDebug',
            options: <String>['-Ptarget-platform=android-x64']);

        final Iterable<String> apkFiles = await getFilesInApk(pluginProject.debugApkPath);
75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99

        checkItContains<String>(<String>[
          'AndroidManifest.xml',
          'classes.dex',
          'assets/flutter_assets/isolate_snapshot_data',
          'assets/flutter_assets/kernel_blob.bin',
          'assets/flutter_assets/vm_snapshot_data',
          'lib/armeabi-v7a/libflutter.so',
          // Debug mode intentionally includes `x86` and `x86_64`.
          'lib/x86/libflutter.so',
          'lib/x86_64/libflutter.so',
        ], apkFiles);

        checkItDoesNotContain<String>(<String>[
          'lib/armeabi-v7a/libapp.so',
          'lib/x86/libapp.so',
          'lib/x86_64/libapp.so',
        ], apkFiles);
      });

      await runPluginProjectTest((FlutterPluginProject pluginProject) async {
        section('APK content for task assembleRelease with target platform = android-arm');
        await pluginProject.runGradleTask('assembleRelease',
            options: <String>['-Ptarget-platform=android-arm']);

100
        final Iterable<String> apkFiles = await getFilesInApk(pluginProject.releaseApkPath);
101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122

        checkItContains<String>(<String>[
          'AndroidManifest.xml',
          'classes.dex',
          'lib/armeabi-v7a/libflutter.so',
          'lib/armeabi-v7a/libapp.so',
        ], apkFiles);

        checkItDoesNotContain<String>(<String>[
          'lib/arm64-v8a/libflutter.so',
          'lib/arm64-v8a/libapp.so',
          'assets/flutter_assets/isolate_snapshot_data',
          'assets/flutter_assets/kernel_blob.bin',
          'assets/flutter_assets/vm_snapshot_data',
        ], apkFiles);
      });

      await runPluginProjectTest((FlutterPluginProject pluginProject) async {
        section('APK content for task assembleRelease with target platform = android-arm64');
        await pluginProject.runGradleTask('assembleRelease',
            options: <String>['-Ptarget-platform=android-arm64']);

123
        final Iterable<String> apkFiles = await getFilesInApk(pluginProject.releaseApkPath);
124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168

        checkItContains<String>(<String>[
          'AndroidManifest.xml',
          'classes.dex',
          'lib/arm64-v8a/libflutter.so',
          'lib/arm64-v8a/libapp.so',
        ], apkFiles);

        checkItDoesNotContain<String>(<String>[
          'lib/armeabi-v7a/libflutter.so',
          'lib/armeabi-v7a/libapp.so',
          'assets/flutter_assets/isolate_snapshot_data',
          'assets/flutter_assets/kernel_blob.bin',
          'assets/flutter_assets/vm_snapshot_data',
        ], apkFiles);
      });

      await runProjectTest((FlutterProject project) async {
        section('gradlew assembleDebug');
        await project.runGradleTask('assembleDebug');
        final String errorMessage = validateSnapshotDependency(project, 'build/app.dill');
        if (errorMessage != null) {
          throw TaskResult.failure(errorMessage);
        }
      });

      await runProjectTest((FlutterProject project) async {
        section('gradlew assembleProfile');
        await project.runGradleTask('assembleProfile');
      });

      await runProjectTest((FlutterProject project) async {
        section('gradlew assembleLocal (custom debug build)');
        await project.addCustomBuildType('local', initWith: 'debug');
        await project.runGradleTask('assembleLocal');
      });

      await runProjectTest((FlutterProject project) async {
        section('gradlew assembleBeta (custom release build)');
        await project.addCustomBuildType('beta', initWith: 'release');
        await project.runGradleTask('assembleBeta');
      });

      await runProjectTest((FlutterProject project) async {
        section('gradlew assembleFreeDebug (product flavor)');
169
        await project.addProductFlavors(<String>['free']);
170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213
        await project.runGradleTask('assembleFreeDebug');
      });

      await runProjectTest((FlutterProject project) async {
        section('gradlew on build script with error');
        await project.introduceError();
        final ProcessResult result =
            await project.resultOfGradleTask('assembleRelease');
        if (result.exitCode == 0)
          throw failure(
              'Gradle did not exit with error as expected', result);
        final String output = result.stdout + '\n' + result.stderr;
        if (output.contains('GradleException') ||
            output.contains('Failed to notify') ||
            output.contains('at org.gradle'))
          throw failure(
              'Gradle output should not contain stacktrace', result);
        if (!output.contains('Build failed') || !output.contains('builTypes'))
          throw failure(
              'Gradle output should contain a readable error message',
              result);
      });

      await runProjectTest((FlutterProject project) async {
        section('flutter build apk on build script with error');
        await project.introduceError();
        final ProcessResult result = await project.resultOfFlutterCommand('build', <String>['apk']);
        if (result.exitCode == 0)
          throw failure(
              'flutter build apk should fail when Gradle does', result);
        final String output = result.stdout + '\n' + result.stderr;
        if (!output.contains('Build failed') || !output.contains('builTypes'))
          throw failure(
              'flutter build apk output should contain a readable Gradle error message',
              result);
        if (hasMultipleOccurrences(output, 'builTypes'))
          throw failure(
              'flutter build apk should not invoke Gradle repeatedly on error',
              result);
      });

      await runPluginProjectTest((FlutterPluginProject pluginProject) async {
        section('gradlew assembleDebug on plugin example');
        await pluginProject.runGradleTask('assembleDebug');
214
        if (!File(pluginProject.debugApkPath).existsSync())
215 216 217 218 219 220 221 222 223 224 225 226
          throw TaskResult.failure(
              'Gradle did not produce an apk file at the expected place');
      });

      return TaskResult.success(null);
    } on TaskResult catch (taskResult) {
      return taskResult;
    } catch (e) {
      return TaskResult.failure(e.toString());
    }
  });
}