android_test.dart 6.76 KB
// Copyright 2014 The Flutter 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:flutter_tools/src/base/file_system.dart';
import 'package:flutter_tools/src/build_info.dart';
import 'package:flutter_tools/src/build_system/build_system.dart';
import 'package:flutter_tools/src/build_system/targets/android.dart';
import 'package:flutter_tools/src/build_system/targets/dart.dart';
import 'package:flutter_tools/src/globals.dart' as globals;
import 'package:flutter_tools/src/cache.dart';
import 'package:platform/platform.dart';

import '../../../src/common.dart';
import '../../../src/fake_process_manager.dart';
import '../../../src/testbed.dart';

void main() {
  FakeProcessManager fakeProcessManager;
  final Testbed testbed = Testbed(overrides: <Type, Generator>{
    Cache: () => FakeCache(),
    Platform: () => FakePlatform(operatingSystem: 'linux', environment: const <String, String>{}),
  });

  testbed.test('debug bundle contains expected resources', () async {
    final Environment environment = Environment.test(
      globals.fs.currentDirectory,
      outputDir: globals.fs.directory('out')..createSync(),
      defines: <String, String>{
        kBuildMode: 'debug',
      }
    );
    environment.buildDir.createSync(recursive: true);

    // create pre-requisites.
    environment.buildDir.childFile('app.dill')
      ..writeAsStringSync('abcd');
    final Directory hostDirectory = globals.fs.currentDirectory
      .childDirectory(getNameForHostPlatform(getCurrentHostPlatform()))
      ..createSync(recursive: true);
    hostDirectory.childFile('vm_isolate_snapshot.bin').createSync();
    hostDirectory.childFile('isolate_snapshot.bin').createSync();


    await const DebugAndroidApplication().build(environment);

    expect(globals.fs.file(globals.fs.path.join('out', 'flutter_assets', 'isolate_snapshot_data')).existsSync(), true);
    expect(globals.fs.file(globals.fs.path.join('out', 'flutter_assets', 'vm_snapshot_data')).existsSync(), true);
    expect(globals.fs.file(globals.fs.path.join('out', 'flutter_assets', 'kernel_blob.bin')).existsSync(), true);
  });

  testbed.test('profile bundle contains expected resources', () async {
    final Environment environment = Environment.test(
      globals.fs.currentDirectory,
      outputDir: globals.fs.directory('out')..createSync(),
      defines: <String, String>{
        kBuildMode: 'profile',
      }
    );
    environment.buildDir.createSync(recursive: true);

    // create pre-requisites.
    environment.buildDir.childFile('app.so')
      ..writeAsStringSync('abcd');

    await const ProfileAndroidApplication().build(environment);

    expect(globals.fs.file(globals.fs.path.join('out', 'app.so')).existsSync(), true);
  });

  testbed.test('release bundle contains expected resources', () async {
    final Environment environment = Environment.test(
      globals.fs.currentDirectory,
      outputDir: globals.fs.directory('out')..createSync(),
      defines: <String, String>{
        kBuildMode: 'release',
      }
    );
    environment.buildDir.createSync(recursive: true);

    // create pre-requisites.
    environment.buildDir.childFile('app.so')
      ..writeAsStringSync('abcd');

    await const ReleaseAndroidApplication().build(environment);

    expect(globals.fs.file(globals.fs.path.join('out', 'app.so')).existsSync(), true);
  });

  testbed.test('AndroidAot can build provided target platform', () async {
    final Environment environment = Environment.test(
      globals.fs.currentDirectory,
      outputDir: globals.fs.directory('out')..createSync(),
      defines: <String, String>{
        kBuildMode: 'release',
      }
    );
    fakeProcessManager = FakeProcessManager.list(<FakeCommand>[
      FakeCommand(command: <String>[
        globals.fs.path.absolute(globals.fs.path.join('android-arm64-release', 'linux-x64', 'gen_snapshot')),
        '--deterministic',
        '--snapshot_kind=app-aot-elf',
        '--elf=${environment.buildDir.childDirectory('arm64-v8a').childFile('app.so').path}',
        '--strip',
        '--no-causal-async-stacks',
        '--lazy-async-stacks',
        environment.buildDir.childFile('app.dill').path,
        ],
      )
    ]);
    environment.buildDir.createSync(recursive: true);
    environment.buildDir.childFile('app.dill').createSync();
    environment.projectDir.childFile('.packages').writeAsStringSync('\n');
    const AndroidAot androidAot = AndroidAot(TargetPlatform.android_arm64, BuildMode.release);

    await androidAot.build(environment);
  }, overrides: <Type, Generator>{
    ProcessManager: () => fakeProcessManager,
  });

  testbed.test('kExtraGenSnapshotOptions passes values to gen_snapshot', () async {
    final Environment environment = Environment.test(
      globals.fs.currentDirectory,
      outputDir: globals.fs.directory('out')..createSync(),
      defines: <String, String>{
        kBuildMode: 'release',
        kExtraGenSnapshotOptions: 'foo,bar,baz=2',
        kTargetPlatform: 'android-arm',
      }
    );
    fakeProcessManager = FakeProcessManager.list(<FakeCommand>[
      FakeCommand(command: <String>[
         globals.fs.path.absolute(globals.fs.path.join('android-arm64-release', 'linux-x64', 'gen_snapshot')),
        '--deterministic',
        'foo',
        'bar',
        'baz=2',
        '--snapshot_kind=app-aot-elf',
        '--elf=${environment.buildDir.childDirectory('arm64-v8a').childFile('app.so').path}',
        '--strip',
        '--no-causal-async-stacks',
        '--lazy-async-stacks',
        environment.buildDir.childFile('app.dill').path
      ])
    ]);
    environment.buildDir.createSync(recursive: true);
    environment.buildDir.childFile('app.dill').createSync();
    environment.projectDir.childFile('.packages').writeAsStringSync('\n');

    await const AndroidAot(TargetPlatform.android_arm64, BuildMode.release)
      .build(environment);
  }, overrides: <Type, Generator>{
    ProcessManager: () => fakeProcessManager,
  });

  testbed.test('android aot bundle copies so from abi directory', () async {
    final Environment environment = Environment.test(
      globals.fs.currentDirectory,
      outputDir: globals.fs.directory('out')..createSync(),
      defines: <String, String>{
        kBuildMode: 'release',
      }
    );
    environment.buildDir.createSync(recursive: true);
    const AndroidAot androidAot = AndroidAot(TargetPlatform.android_arm64, BuildMode.release);
    const AndroidAotBundle androidAotBundle = AndroidAotBundle(androidAot);
    // Create required files.
    environment.buildDir
      .childDirectory('arm64-v8a')
      .childFile('app.so')
      .createSync(recursive: true);

    await androidAotBundle.build(environment);

    expect(environment.outputDir
      .childDirectory('arm64-v8a')
      .childFile('app.so').existsSync(), true);
  });
}