symbolize_test.dart 5.13 KB
Newer Older
1 2 3 4
// 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.

5 6
// @dart = 2.8

7
import 'dart:async';
8 9 10
import 'dart:typed_data';

import 'package:file/memory.dart';
11
import 'package:file_testing/file_testing.dart';
12
import 'package:flutter_tools/src/base/common.dart';
13
import 'package:flutter_tools/src/base/file_system.dart';
14
import 'package:flutter_tools/src/base/terminal.dart';
15 16 17
import 'package:flutter_tools/src/cache.dart';
import 'package:flutter_tools/src/commands/symbolize.dart';
import 'package:flutter_tools/src/convert.dart';
18 19
import 'package:meta/meta.dart';
import 'package:test/fake.dart';
20 21 22

import '../../src/common.dart';
import '../../src/context.dart';
23
import '../../src/fakes.dart';
24
import '../../src/test_flutter_command_runner.dart';
25 26 27

void main() {
  MemoryFileSystem fileSystem;
28
  FakeStdio stdio;
29 30 31 32 33 34 35

  setUpAll(() {
    Cache.disableLocking();
  });

  setUp(() {
    fileSystem = MemoryFileSystem.test();
36
    stdio = FakeStdio();
37 38
  });

39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
  testUsingContext('Regression test for type error in codec', () async {
    final DwarfSymbolizationService symbolizationService = DwarfSymbolizationService.test();
    final StreamController<List<int>> output = StreamController<List<int>>();

    unawaited(symbolizationService.decode(
      input: Stream<Uint8List>.fromIterable(<Uint8List>[
        utf8.encode('Hello, World\n') as Uint8List,
      ]),
      symbols: Uint8List(0),
      output: IOSink(output.sink),
    ));

    await expectLater(
      output.stream.transform(utf8.decoder),
      emits('Hello, World'),
    );
  });

57 58

  testUsingContext('symbolize exits when --debug-info argument is missing', () async {
59 60 61 62 63
    final SymbolizeCommand command = SymbolizeCommand(
      stdio: stdio,
      fileSystem: fileSystem,
      dwarfSymbolizationService: DwarfSymbolizationService.test(),
    );
64 65 66
    final Future<void> result = createTestCommandRunner(command)
      .run(const <String>['symbolize']);

67
    expect(result, throwsToolExit(message: '"--debug-info" is required to symbolize stack traces.'));
68 69
  }, overrides: <Type, Generator>{
    OutputPreferences: () => OutputPreferences.test(),
70 71 72
  });

  testUsingContext('symbolize exits when --debug-info file is missing', () async {
73 74 75 76 77
    final SymbolizeCommand command = SymbolizeCommand(
      stdio: stdio,
      fileSystem: fileSystem,
      dwarfSymbolizationService: DwarfSymbolizationService.test(),
    );
78 79 80 81
    final Future<void> result = createTestCommandRunner(command)
      .run(const <String>['symbolize', '--debug-info=app.debug']);

    expect(result, throwsToolExit(message: 'app.debug does not exist.'));
82 83
  }, overrides: <Type, Generator>{
    OutputPreferences: () => OutputPreferences.test(),
84 85 86
  });

  testUsingContext('symbolize exits when --input file is missing', () async {
87 88 89 90 91
    final SymbolizeCommand command = SymbolizeCommand(
      stdio: stdio,
      fileSystem: fileSystem,
      dwarfSymbolizationService: DwarfSymbolizationService.test(),
    );
92 93 94 95 96
    fileSystem.file('app.debug').createSync();
    final Future<void> result = createTestCommandRunner(command)
      .run(const <String>['symbolize', '--debug-info=app.debug', '--input=foo.stack', '--output=results/foo.result']);

    expect(result, throwsToolExit(message: ''));
97 98
  }, overrides: <Type, Generator>{
    OutputPreferences: () => OutputPreferences.test(),
99 100
  });

101
  testUsingContext('symbolize succeeds when DwarfSymbolizationService does not throw', () async {
102 103 104 105 106
    final SymbolizeCommand command = SymbolizeCommand(
      stdio: stdio,
      fileSystem: fileSystem,
      dwarfSymbolizationService: DwarfSymbolizationService.test(),
    );
107 108 109 110 111
    fileSystem.file('app.debug').writeAsBytesSync(<int>[1, 2, 3]);
    fileSystem.file('foo.stack').writeAsStringSync('hello');

    await createTestCommandRunner(command)
      .run(const <String>['symbolize', '--debug-info=app.debug', '--input=foo.stack', '--output=results/foo.result']);
112 113 114

    expect(fileSystem.file('results/foo.result'), exists);
    expect(fileSystem.file('results/foo.result').readAsBytesSync(), <int>[104, 101, 108, 108, 111, 10]); // hello
115 116
  }, overrides: <Type, Generator>{
    OutputPreferences: () => OutputPreferences.test(),
117 118 119
  });

  testUsingContext('symbolize throws when DwarfSymbolizationService throws', () async {
120
    final SymbolizeCommand command = SymbolizeCommand(
121 122 123 124 125
      stdio: stdio,
      fileSystem: fileSystem,
      dwarfSymbolizationService: ThrowingDwarfSymbolizationService(),
    );

126 127 128 129 130 131 132 133
    fileSystem.file('app.debug').writeAsBytesSync(<int>[1, 2, 3]);
    fileSystem.file('foo.stack').writeAsStringSync('hello');

    expect(
      createTestCommandRunner(command).run(const <String>[
        'symbolize', '--debug-info=app.debug', '--input=foo.stack', '--output=results/foo.result']),
      throwsToolExit(message: 'test'),
    );
134 135
  }, overrides: <Type, Generator>{
    OutputPreferences: () => OutputPreferences.test(),
136 137 138
  });
}

139 140 141 142 143 144 145 146 147 148
class ThrowingDwarfSymbolizationService extends Fake implements DwarfSymbolizationService {
  @override
  Future<void> decode({
    @required Stream<List<int>> input,
    @required IOSink output,
    @required Uint8List symbols,
  }) async {
    throwToolExit('test');
  }
}