Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion tools/engine_tool/lib/src/gn.dart
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ interface class Gn {
result = JsonObject.parse(process.stdout);
} on FormatException catch (e) {
_environment.logger.fatal(
'Failed to parse JSON output from `gn desc`:\n$e',
'Failed to parse JSON output from `gn desc`:\n$e\n${process.stdout}',
);
}

Expand Down Expand Up @@ -136,6 +136,10 @@ sealed class BuildTarget {
@mustBeOverridden
@override
int get hashCode;

@mustBeOverridden
@override
String toString();
}

/// A build target that produces a [shared library][] or [static library][].
Expand All @@ -158,6 +162,9 @@ final class LibraryBuildTarget extends BuildTarget {

@override
int get hashCode => Object.hash(label, testOnly);

@override
String toString() => 'LibraryBuildTarget($label, testOnly=$testOnly)';
}

/// A build target that produces an [executable][] program.
Expand All @@ -184,4 +191,7 @@ final class ExecutableBuildTarget extends BuildTarget {

@override
int get hashCode => Object.hash(label, testOnly, executable);

@override
String toString() => 'ExecutableBuildTarget($label, testOnly=$testOnly, executable=$executable)';
}
112 changes: 112 additions & 0 deletions tools/engine_tool/test/gn_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
// Copyright 2013 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:engine_tool/src/gn.dart';
import 'package:engine_tool/src/label.dart';
import 'package:litetest/litetest.dart';

import 'utils.dart';

void main() {
test('gn.desc handles a non-zero exit code', () async {
final TestEnvironment testEnv = TestEnvironment.withTestEngine(
cannedProcesses: <CannedProcess>[
CannedProcess(
(List<String> command) => command.contains('desc'),
exitCode: 1,
stdout: 'stdout',
stderr: 'stderr',
),
],
);
try {
final Gn gn = Gn.fromEnvironment(testEnv.environment);
await gn.desc('out/Release', TargetPattern('//foo', 'bar'));
fail('Expected an exception');
} catch (e) {
final String message = '$e';
expect(message, contains('Failed to run'));
expect(message, contains('exit code 1'));
expect(message, contains('STDOUT:\nstdout'));
expect(message, contains('STDERR:\nstderr'));
} finally {
testEnv.cleanup();
}
});

test('gn.desc handles unparseable stdout', () async {
final TestEnvironment testEnv = TestEnvironment.withTestEngine(
cannedProcesses: <CannedProcess>[
CannedProcess(
(List<String> command) => command.contains('desc'),
stdout: 'not json',
),
],
);
try {
final Gn gn = Gn.fromEnvironment(testEnv.environment);
await gn.desc('out/Release', TargetPattern('//foo', 'bar'));
fail('Expected an exception');
} catch (e) {
final String message = '$e';
expect(message, contains('Failed to parse JSON'));
expect(message, contains('not json'));
} finally {
testEnv.cleanup();
}
});

test('gn.desc parses build targets', () async {
final TestEnvironment testEnv = TestEnvironment.withTestEngine(
cannedProcesses: <CannedProcess>[
CannedProcess(
(List<String> command) => command.contains('desc'),
stdout: '''
{
"//foo/bar:baz_test": {
"outputs": ["//out/host_debug/foo/bar/baz_test"],
"testonly": true,
"type": "executable"
},
"//foo/bar:baz_shared_library": {
"testonly": false,
"type": "shared_library"
},
"//foo/bar:baz_static_library": {
"testonly": false,
"type": "static_library"
}
}
''',
),
],
);
try {
final Gn gn = Gn.fromEnvironment(testEnv.environment);
final List<BuildTarget> targets = await gn.desc('out/Release', TargetPattern('//foo', 'bar'));
expect(targets, hasLength(3));

// There should be exactly one binary test target and two library targets.
final ExecutableBuildTarget testTarget = targets.whereType<ExecutableBuildTarget>().single;
expect(testTarget, ExecutableBuildTarget(
label: Label('//foo/bar', 'baz_test'),
testOnly: true,
executable: 'out/host_debug/foo/bar/baz_test',
));

final List<LibraryBuildTarget> libraryTargets = targets.whereType<LibraryBuildTarget>().toList();
expect(libraryTargets, hasLength(2));
expect(libraryTargets.contains(LibraryBuildTarget(
label: Label('//foo/bar', 'baz_shared_library'),
testOnly: false,
)), isTrue);
expect(libraryTargets.contains(LibraryBuildTarget(
label: Label('//foo/bar', 'baz_static_library'),
testOnly: false,
)), isTrue);
} finally {
testEnv.cleanup();
}
});
}