compile_batch_test.dart 8.35 KB
Newer Older
Ian Hickson's avatar
Ian Hickson committed
1
// Copyright 2014 The Flutter Authors. All rights reserved.
2 3 4 5 6 7 8 9
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'dart:async';

import 'package:flutter_tools/src/base/io.dart';
import 'package:flutter_tools/src/base/platform.dart';
import 'package:flutter_tools/src/base/terminal.dart';
10
import 'package:flutter_tools/src/build_info.dart';
11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
import 'package:flutter_tools/src/compile.dart';
import 'package:flutter_tools/src/convert.dart';
import 'package:mockito/mockito.dart';
import 'package:process/process.dart';

import '../src/common.dart';
import '../src/context.dart';
import '../src/mocks.dart';

void main() {
  ProcessManager mockProcessManager;
  MockProcess mockFrontendServer;
  MockStdIn mockFrontendServerStdIn;
  MockStream mockFrontendServerStdErr;

26 27
  List<String> latestCommand;

28 29 30 31 32 33 34 35 36 37 38 39 40
  setUp(() {
    mockProcessManager = MockProcessManager();
    mockFrontendServer = MockProcess();
    mockFrontendServerStdIn = MockStdIn();
    mockFrontendServerStdErr = MockStream();

    when(mockFrontendServer.stderr)
        .thenAnswer((Invocation invocation) => mockFrontendServerStdErr);
    final StreamController<String> stdErrStreamController = StreamController<String>();
    when(mockFrontendServerStdErr.transform<String>(any)).thenAnswer((_) => stdErrStreamController.stream);
    when(mockFrontendServer.stdin).thenReturn(mockFrontendServerStdIn);
    when(mockProcessManager.canRun(any)).thenReturn(true);
    when(mockProcessManager.start(any)).thenAnswer(
41
        (Invocation invocation) {
42
          latestCommand = invocation.positionalArguments.first as List<String>;
43 44
          return Future<Process>.value(mockFrontendServer);
        });
45 46 47 48 49 50 51 52 53 54 55 56 57
    when(mockFrontendServer.exitCode).thenAnswer((_) async => 0);
  });

  testUsingContext('batch compile single dart successful compilation', () async {
    when(mockFrontendServer.stdout)
        .thenAnswer((Invocation invocation) => Stream<List<int>>.fromFuture(
          Future<List<int>>.value(utf8.encode(
            'result abc\nline1\nline2\nabc\nabc /path/to/main.dart.dill 0'
          ))
        ));
    final KernelCompiler kernelCompiler = await kernelCompilerFactory.create(null);
    final CompilerOutput output = await kernelCompiler.compile(sdkRoot: '/path/to/sdkroot',
      mainPath: '/path/to/main.dart',
58
      buildMode: BuildMode.debug,
59
      trackWidgetCreation: false,
60
      dartDefines: const <String>[],
61 62 63
    );

    expect(mockFrontendServerStdIn.getAndClear(), isEmpty);
64
    expect(testLogger.errorText, equals('\nCompiler message:\nline1\nline2\n'));
65 66 67 68 69 70 71
    expect(output.outputFilename, equals('/path/to/main.dart.dill'));
  }, overrides: <Type, Generator>{
    ProcessManager: () => mockProcessManager,
    OutputPreferences: () => OutputPreferences(showColor: false),
    Platform: kNoColorTerminalPlatform,
  });

72 73 74 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 100 101 102 103 104
  testUsingContext('passes correct AOT config to kernel compiler in aot/profile mode', () async {
    when(mockFrontendServer.stdout)
      .thenAnswer((Invocation invocation) => Stream<List<int>>.fromFuture(
        Future<List<int>>.value(utf8.encode(
          'result abc\nline1\nline2\nabc\nabc /path/to/main.dart.dill 0'
        ))
      ));
    final KernelCompiler kernelCompiler = await kernelCompilerFactory.create(null);
    await kernelCompiler.compile(sdkRoot: '/path/to/sdkroot',
      mainPath: '/path/to/main.dart',
      buildMode: BuildMode.profile,
      trackWidgetCreation: false,
      aot: true,
      dartDefines: const <String>[],
    );

    expect(mockFrontendServerStdIn.getAndClear(), isEmpty);
    final VerificationResult argVerification = verify(mockProcessManager.start(captureAny));
    expect(argVerification.captured.single, containsAll(<String>[
      '--aot',
      '--tfa',
      '-Ddart.vm.profile=true',
      '-Ddart.vm.product=false',
      '--bytecode-options=source-positions',
    ]));
  }, overrides: <Type, Generator>{
    ProcessManager: () => mockProcessManager,
    OutputPreferences: () => OutputPreferences(showColor: false),
    Platform: kNoColorTerminalPlatform,
  });


  testUsingContext('passes correct AOT config to kernel compiler in aot/release mode', () async {
105 106 107 108 109 110 111 112 113 114 115 116
    when(mockFrontendServer.stdout)
      .thenAnswer((Invocation invocation) => Stream<List<int>>.fromFuture(
        Future<List<int>>.value(utf8.encode(
          'result abc\nline1\nline2\nabc\nabc /path/to/main.dart.dill 0'
        ))
      ));
    final KernelCompiler kernelCompiler = await kernelCompilerFactory.create(null);
    await kernelCompiler.compile(sdkRoot: '/path/to/sdkroot',
      mainPath: '/path/to/main.dart',
      buildMode: BuildMode.release,
      trackWidgetCreation: false,
      aot: true,
117
      dartDefines: const <String>[],
118 119 120 121
    );

    expect(mockFrontendServerStdIn.getAndClear(), isEmpty);
    final VerificationResult argVerification = verify(mockProcessManager.start(captureAny));
122 123 124 125 126 127 128
    expect(argVerification.captured.single, containsAll(<String>[
      '--aot',
      '--tfa',
      '-Ddart.vm.profile=false',
      '-Ddart.vm.product=true',
      '--bytecode-options=source-positions',
    ]));
129 130 131 132 133 134
  }, overrides: <Type, Generator>{
    ProcessManager: () => mockProcessManager,
    OutputPreferences: () => OutputPreferences(showColor: false),
    Platform: kNoColorTerminalPlatform,
  });

135 136 137 138 139 140 141 142 143 144
  testUsingContext('batch compile single dart failed compilation', () async {
    when(mockFrontendServer.stdout)
        .thenAnswer((Invocation invocation) => Stream<List<int>>.fromFuture(
          Future<List<int>>.value(utf8.encode(
            'result abc\nline1\nline2\nabc\nabc'
          ))
        ));
    final KernelCompiler kernelCompiler = await kernelCompilerFactory.create(null);
    final CompilerOutput output = await kernelCompiler.compile(sdkRoot: '/path/to/sdkroot',
      mainPath: '/path/to/main.dart',
145
      buildMode: BuildMode.debug,
146
      trackWidgetCreation: false,
147
      dartDefines: const <String>[],
148 149 150
    );

    expect(mockFrontendServerStdIn.getAndClear(), isEmpty);
151
    expect(testLogger.errorText, equals('\nCompiler message:\nline1\nline2\n'));
152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171
    expect(output, equals(null));
  }, overrides: <Type, Generator>{
    ProcessManager: () => mockProcessManager,
    OutputPreferences: () => OutputPreferences(showColor: false),
    Platform: kNoColorTerminalPlatform,
  });

  testUsingContext('batch compile single dart abnormal compiler termination', () async {
    when(mockFrontendServer.exitCode).thenAnswer((_) async => 255);

    when(mockFrontendServer.stdout)
        .thenAnswer((Invocation invocation) => Stream<List<int>>.fromFuture(
        Future<List<int>>.value(utf8.encode(
            'result abc\nline1\nline2\nabc\nabc'
        ))
    ));
    final KernelCompiler kernelCompiler = await kernelCompilerFactory.create(null);
    final CompilerOutput output = await kernelCompiler.compile(
      sdkRoot: '/path/to/sdkroot',
      mainPath: '/path/to/main.dart',
172
      buildMode: BuildMode.debug,
173
      trackWidgetCreation: false,
174
      dartDefines: const <String>[],
175 176
    );
    expect(mockFrontendServerStdIn.getAndClear(), isEmpty);
177
    expect(testLogger.errorText, equals('\nCompiler message:\nline1\nline2\n'));
178 179 180 181 182 183
    expect(output, equals(null));
  }, overrides: <Type, Generator>{
    ProcessManager: () => mockProcessManager,
    OutputPreferences: () => OutputPreferences(showColor: false),
    Platform: kNoColorTerminalPlatform,
  });
184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204

  testUsingContext('passes dartDefines to the kernel compiler', () async {
    // Use unsuccessful result because it's easier to setup in test. We only care about arguments passed to the compiler.
    when(mockFrontendServer.exitCode).thenAnswer((_) async => 255);
    when(mockFrontendServer.stdout).thenAnswer((Invocation invocation) => Stream<List<int>>.fromFuture(
      Future<List<int>>.value(<int>[])
    ));
    final KernelCompiler kernelCompiler = await kernelCompilerFactory.create(null);
    await kernelCompiler.compile(sdkRoot: '/path/to/sdkroot',
      mainPath: '/path/to/main.dart',
      buildMode: BuildMode.debug,
      trackWidgetCreation: false,
      dartDefines: const <String>['FOO=bar', 'BAZ=qux'],
    );

    expect(latestCommand, containsAllInOrder(<String>['-DFOO=bar', '-DBAZ=qux']));
  }, overrides: <Type, Generator>{
    ProcessManager: () => mockProcessManager,
    OutputPreferences: () => OutputPreferences(showColor: false),
    Platform: kNoColorTerminalPlatform,
  });
205 206 207 208
}

class MockProcess extends Mock implements Process {}
class MockProcessManager extends Mock implements ProcessManager {}