Rewrite `getExecutableForCommand` tests to test with an external process. (#4268)

diff --git a/test/embedding/embedding_test.dart b/test/embedding/embedding_test.dart
index 20c94d1..faeb17d 100644
--- a/test/embedding/embedding_test.dart
+++ b/test/embedding/embedding_test.dart
@@ -14,6 +14,7 @@
 import '../golden_file.dart';
 import '../test_pub.dart';
 import 'ensure_pubspec_resolved.dart';
+import 'get_executable_for_command.dart';
 
 const _commandRunner = 'tool/test-bin/pub_command_runner.dart';
 
@@ -374,6 +375,7 @@
   });
 
   testEnsurePubspecResolved();
+  testGetExecutableForCommand();
 }
 
 String _filter(String input) {
diff --git a/test/embedding/get_executable_for_command.dart b/test/embedding/get_executable_for_command.dart
new file mode 100644
index 0000000..de16271
--- /dev/null
+++ b/test/embedding/get_executable_for_command.dart
@@ -0,0 +1,563 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. 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:io';
+
+import 'package:path/path.dart' as p;
+import 'package:pub/pub.dart';
+import 'package:test/test.dart';
+
+import '../descriptor.dart' as d;
+import '../test_pub.dart';
+import 'embedding_test.dart';
+
+enum ResolutionAttempt {
+  resolution,
+  fastPath,
+  noResolution,
+}
+
+Future<void> testGetExecutable(
+  String command,
+  String root, {
+  bool allowSnapshot = true,
+  String? executable,
+  String? packageConfig,
+  Object? errorMessage,
+  required ResolutionAttempt resolution,
+  CommandResolutionIssue? issue,
+  Map<String, String>? environment,
+}) async {
+  final buffer = StringBuffer();
+  await runEmbeddingToBuffer(
+    [
+      'pub',
+      '--verbose',
+      'get-executable-for-command',
+      command,
+      if (allowSnapshot) '--allow-snapshot' else '--no-allow-snapshot',
+    ],
+    buffer,
+    workingDirectory: root,
+    exitCode: errorMessage == null ? 0 : isNot(0),
+    environment: environment,
+  );
+  final output = buffer.toString();
+  if (errorMessage != null) {
+    expect(output, errorMessage);
+    expect(output, contains('Issue: $issue'));
+  } else {
+    expect(output, contains(filterUnstableText('Executable: $executable\n')));
+    expect(
+      File(p.join(root, executable)).existsSync(),
+      true,
+      reason: '${p.join(root, executable)} should exist',
+    );
+    expect(
+      output,
+      contains(
+        'Package config: ${filterUnstableText(packageConfig ?? 'No package config')}\n',
+      ),
+    );
+  }
+  switch (resolution) {
+    case ResolutionAttempt.fastPath:
+      expect(output, contains('[e] FINE: Package Config up to date.'));
+    case ResolutionAttempt.noResolution:
+      expect(output, isNot(contains('[e] FINE: Package Config up to date.')));
+      expect(output, isNot(contains('MSG : Resolving dependencies')));
+    case ResolutionAttempt.resolution:
+      expect(output, contains('MSG : Resolving dependencies'));
+  }
+}
+
+void testGetExecutableForCommand() {
+  group('getExecutableForCommand', () {
+    test('Finds a direct dart-file without pub get', () async {
+      await servePackages();
+      await d.dir('foo', [
+        d.dir('bar', [d.file('bar.dart', 'main() {print(42);}')]),
+      ]).create();
+      final dir = d.path('foo');
+
+      await testGetExecutable(
+        'bar/bar.dart',
+        dir,
+        executable: p.join('bar', 'bar.dart'),
+        resolution: ResolutionAttempt.noResolution,
+      );
+
+      await testGetExecutable(
+        p.join('bar', 'bar.dart'),
+        dir,
+        executable: p.join('bar', 'bar.dart'),
+        resolution: ResolutionAttempt.noResolution,
+      );
+
+      await testGetExecutable(
+        '${p.toUri(dir)}/bar/bar.dart',
+        dir,
+        executable: p.join('bar', 'bar.dart'),
+        resolution: ResolutionAttempt.noResolution,
+      );
+    });
+
+    test('Looks for file when no pubspec.yaml', () async {
+      await servePackages();
+      await d.dir('foo', [
+        d.dir('bar', [d.file('bar.dart', 'main() {print(42);}')]),
+      ]).create();
+      final dir = d.path('foo');
+
+      await testGetExecutable(
+        'bar/m.dart',
+        dir,
+        errorMessage: contains('Could not find file `bar/m.dart`'),
+        issue: CommandResolutionIssue.fileNotFound,
+        resolution: ResolutionAttempt.noResolution,
+      );
+      await testGetExecutable(
+        p.join('bar', 'm.dart'),
+        dir,
+        errorMessage: contains('Could not find file `bar/m.dart`'),
+        issue: CommandResolutionIssue.fileNotFound,
+        resolution: ResolutionAttempt.noResolution,
+      );
+    });
+
+    test('Error message when pubspec is broken', () async {
+      await servePackages();
+      await d.dir('foo', [
+        d.pubspec({
+          'name': 'broken name',
+        }),
+      ]).create();
+
+      await d.dir(appPath, [
+        d.pubspec({
+          'name': 'myapp',
+          'dependencies': {
+            'foo': {
+              'path': '../foo',
+            },
+          },
+        }),
+      ]).create();
+      final dir = d.path(appPath);
+      await testGetExecutable(
+        'foo:app',
+        dir,
+        errorMessage: allOf(
+          contains(
+            'Error on line 1, column 9 of ../foo/pubspec.yaml: "name" field must be a valid Dart identifier.',
+          ),
+          contains(
+            '{"name":"broken name","environment":{"sdk":"$defaultSdkConstraint"}}',
+          ),
+        ),
+        issue: CommandResolutionIssue.pubGetFailed,
+        resolution: ResolutionAttempt.resolution,
+      );
+    });
+
+    test('Reports file not found if the path looks like a file', () async {
+      await servePackages();
+      await d.dir(appPath, [
+        d.pubspec({
+          'name': 'myapp',
+          'dependencies': {'foo': '^1.0.0'},
+        }),
+        d.dir('bin', [
+          d.file('myapp.dart', 'main() {print(42);}'),
+        ]),
+      ]).create();
+
+      await servePackages();
+      // The solver uses word-wrapping in its error message, so we use \s to
+      // accommodate.
+      await testGetExecutable(
+        'bar/m.dart',
+        d.path(appPath),
+        errorMessage: matches(r'Could not find file `bar/m.dart`'),
+        issue: CommandResolutionIssue.fileNotFound,
+        resolution: ResolutionAttempt.noResolution,
+      );
+    });
+
+    test('Reports parse failure', () async {
+      await servePackages();
+      await d.dir(appPath, [
+        d.pubspec({
+          'name': 'myapp',
+        }),
+      ]).create();
+      await testGetExecutable(
+        '::',
+        d.path(appPath),
+        errorMessage: contains(r'cannot contain multiple ":"'),
+        issue: CommandResolutionIssue.parseError,
+        resolution: ResolutionAttempt.resolution,
+      );
+    });
+
+    test('Reports compilation failure', () async {
+      await servePackages();
+      await d.dir(appPath, [
+        d.pubspec({
+          'name': 'myapp',
+        }),
+        d.dir('bin', [
+          d.file('foo.dart', 'main() {'),
+        ]),
+      ]).create();
+
+      await servePackages();
+      // The solver uses word-wrapping in its error message, so we use \s to
+      // accommodate.
+      await testGetExecutable(
+        ':foo',
+        d.path(appPath),
+        errorMessage: matches(r'foo.dart:1:8:'),
+        issue: CommandResolutionIssue.compilationFailed,
+        resolution: ResolutionAttempt.resolution,
+      );
+    });
+
+    test('Finds files', () async {
+      final server = await servePackages();
+      server.serve(
+        'foo',
+        '1.0.0',
+        deps: {
+          'transitive': {'hosted': globalServer.url},
+        },
+        contents: [
+          d.dir('bin', [
+            d.file('foo.dart', 'main() {print(42);}'),
+            d.file('tool.dart', 'main() {print(42);}'),
+          ]),
+        ],
+      );
+
+      server.serve(
+        'transitive',
+        '1.0.0',
+        contents: [
+          d.dir('bin', [d.file('transitive.dart', 'main() {print(42);}')]),
+        ],
+      );
+
+      await d.dir(appPath, [
+        d.pubspec({
+          'name': 'myapp',
+          'dependencies': {
+            'foo': {
+              'hosted': globalServer.url,
+              'version': '^1.0.0',
+            },
+          },
+        }),
+        d.dir('bin', [
+          d.file('myapp.dart', 'main() {print(42);}'),
+          d.file('tool.dart', 'main() {print(42);}'),
+        ]),
+      ]).create();
+      final dir = d.path(appPath);
+
+      await testGetExecutable(
+        'myapp',
+        dir,
+        executable: p.join(
+          '.dart_tool',
+          'pub',
+          'bin',
+          'myapp',
+          'myapp.dart-3.1.2+3.snapshot',
+        ),
+        packageConfig: p.join('.dart_tool', 'package_config.json'),
+        resolution: ResolutionAttempt.resolution,
+      );
+      await testGetExecutable(
+        'myapp:myapp',
+        dir,
+        executable: p.join(
+          '.dart_tool',
+          'pub',
+          'bin',
+          'myapp',
+          'myapp.dart-3.1.2+3.snapshot',
+        ),
+        packageConfig: p.join('.dart_tool', 'package_config.json'),
+        resolution: ResolutionAttempt.noResolution,
+      );
+      await testGetExecutable(
+        ':myapp',
+        dir,
+        executable: p.join(
+          '.dart_tool',
+          'pub',
+          'bin',
+          'myapp',
+          'myapp.dart-3.1.2+3.snapshot',
+        ),
+        packageConfig: p.join('.dart_tool', 'package_config.json'),
+        resolution: ResolutionAttempt.noResolution,
+      );
+      await testGetExecutable(
+        ':tool',
+        dir,
+        executable: p.join(
+          '.dart_tool',
+          'pub',
+          'bin',
+          'myapp',
+          'tool.dart-3.1.2+3.snapshot',
+        ),
+        packageConfig: p.join('.dart_tool', 'package_config.json'),
+        resolution: ResolutionAttempt.noResolution,
+      );
+      await testGetExecutable(
+        'foo',
+        dir,
+        allowSnapshot: false,
+        executable: p.join(
+          d.sandbox,
+          d.hostedCachePath(),
+          'foo-1.0.0',
+          'bin',
+          'foo.dart',
+        ),
+        packageConfig: p.join('.dart_tool', 'package_config.json'),
+        resolution: ResolutionAttempt.noResolution,
+      );
+      await testGetExecutable(
+        'foo',
+        dir,
+        executable: p.join(
+          '.dart_tool',
+          'pub',
+          'bin',
+          'foo',
+          'foo.dart-3.1.2+3.snapshot',
+        ),
+        packageConfig: p.join('.dart_tool', 'package_config.json'),
+        resolution: ResolutionAttempt.noResolution,
+      );
+      await testGetExecutable(
+        'foo:tool',
+        dir,
+        allowSnapshot: false,
+        executable: p.join(
+          d.sandbox,
+          d.hostedCachePath(),
+          'foo-1.0.0',
+          'bin',
+          'tool.dart',
+        ),
+        packageConfig: p.join('.dart_tool', 'package_config.json'),
+        resolution: ResolutionAttempt.noResolution,
+      );
+      await testGetExecutable(
+        'foo:tool',
+        dir,
+        executable: p.join(
+          '.dart_tool',
+          'pub',
+          'bin',
+          'foo',
+          'tool.dart-3.1.2+3.snapshot',
+        ),
+        packageConfig: p.join('.dart_tool', 'package_config.json'),
+        resolution: ResolutionAttempt.noResolution,
+      );
+      await testGetExecutable(
+        'unknown:tool',
+        dir,
+        errorMessage: contains(
+          'Could not find package `unknown` or file `unknown:tool`',
+        ),
+        issue: CommandResolutionIssue.packageNotFound,
+        resolution: ResolutionAttempt.noResolution,
+      );
+      await testGetExecutable(
+        'foo:unknown',
+        dir,
+        errorMessage: contains(
+          'Could not find `bin/unknown.dart` in package `foo`.',
+        ),
+        issue: CommandResolutionIssue.noBinaryFound,
+        resolution: ResolutionAttempt.noResolution,
+      );
+      await testGetExecutable(
+        'unknownTool',
+        dir,
+        errorMessage: contains(
+          'Could not find package `unknownTool` or file `unknownTool`',
+        ),
+        issue: CommandResolutionIssue.packageNotFound,
+        resolution: ResolutionAttempt.noResolution,
+      );
+      await testGetExecutable(
+        'transitive',
+        dir,
+        executable: p.join(
+          d.sandbox,
+          d.hostedCachePath(port: globalServer.port),
+          'transitive-1.0.0',
+          'bin',
+          'transitive.dart',
+        ),
+        allowSnapshot: false,
+        packageConfig: p.join('.dart_tool', 'package_config.json'),
+        resolution: ResolutionAttempt.noResolution,
+      );
+    });
+
+    test('works with workspace', () async {
+      final server = await servePackages();
+      server.serve(
+        'foo',
+        '1.0.0',
+        contents: [
+          d.dir('bin', [
+            d.file('foo.dart', 'main() {print(42);}'),
+            d.file('tool.dart', 'main() {print(42);}'),
+          ]),
+        ],
+      );
+
+      await d.dir(appPath, [
+        d.libPubspec(
+          'myapp',
+          '1.2.3',
+          deps: {
+            'a': 'any',
+            'foo': {
+              'hosted': globalServer.url,
+              'version': '^1.0.0',
+            },
+          },
+          extras: {
+            'workspace': ['pkgs/a', 'pkgs/b'],
+          },
+          sdk: '^3.5.0-0',
+        ),
+        d.dir('bin', [
+          d.file('myapp.dart', 'main() {print(42);}'),
+          d.file('tool.dart', 'main() {print(42);}'),
+        ]),
+        d.dir('pkgs', [
+          d.dir('a', [
+            d.libPubspec(
+              'a',
+              '1.0.0',
+              resolutionWorkspace: true,
+            ),
+            d.dir('bin', [
+              d.file('a.dart', 'main() {print(42);}'),
+              d.file('tool.dart', 'main() {print(42);}'),
+            ]),
+          ]),
+          d.dir('b', [
+            d.libPubspec(
+              'b',
+              '1.0.0',
+              resolutionWorkspace: true,
+            ),
+            d.dir('bin', [
+              d.file('b.dart', 'main() {print(42);}'),
+              d.file('tool.dart', 'main() {print(42);}'),
+            ]),
+          ]),
+        ]),
+      ]).create();
+      await pubGet(
+        environment: {'_PUB_TEST_SDK_VERSION': '3.5.0'},
+      );
+      await testGetExecutable(
+        'myapp',
+        p.join(d.sandbox, appPath, 'pkgs', 'a'),
+        executable: p.join(
+          '..',
+          '..',
+          '.dart_tool',
+          'pub',
+          'bin',
+          'myapp',
+          'myapp.dart-3.5.0.snapshot',
+        ),
+        environment: {'_PUB_TEST_SDK_VERSION': '3.5.0'},
+        packageConfig: p.join('..', '..', '.dart_tool', 'package_config.json'),
+        // TODO(sigurdm): Should be fast-path
+        resolution: ResolutionAttempt.resolution,
+      );
+
+      await testGetExecutable(
+        'a',
+        p.join(d.sandbox, appPath, 'pkgs'),
+        executable: p.join(
+          d.sandbox,
+          appPath,
+          'pkgs',
+          'a',
+          'bin',
+          'a.dart',
+        ),
+        allowSnapshot: false,
+        packageConfig: p.join('..', '.dart_tool', 'package_config.json'),
+        environment: {'_PUB_TEST_SDK_VERSION': '3.5.0'},
+        // TODO(sigurdm): Should be fast-path
+        resolution: ResolutionAttempt.resolution,
+      );
+      await testGetExecutable(
+        'b:tool',
+        p.join(d.sandbox, appPath),
+        allowSnapshot: false,
+        executable: p.join(
+          d.sandbox,
+          appPath,
+          'pkgs',
+          'b',
+          'bin',
+          'tool.dart',
+        ),
+        packageConfig: p.join('.dart_tool', 'package_config.json'),
+        environment: {'_PUB_TEST_SDK_VERSION': '3.5.0'},
+        resolution: ResolutionAttempt.noResolution,
+      );
+      await testGetExecutable(
+        'foo',
+        p.join(d.sandbox, appPath),
+        allowSnapshot: false,
+        executable: p.join(
+          d.sandbox,
+          d.hostedCachePath(),
+          'foo-1.0.0',
+          'bin',
+          'foo.dart',
+        ),
+        packageConfig: p.join('.dart_tool', 'package_config.json'),
+        environment: {'_PUB_TEST_SDK_VERSION': '3.5.0'},
+        resolution: ResolutionAttempt.noResolution,
+      );
+      await testGetExecutable(
+        ':tool',
+        p.join(d.sandbox, appPath, 'pkgs', 'a'),
+        allowSnapshot: false,
+        executable: p.join(
+          d.sandbox,
+          appPath,
+          'pkgs',
+          'a',
+          'bin',
+          'tool.dart',
+        ),
+        packageConfig: p.join('..', '..', '.dart_tool', 'package_config.json'),
+        environment: {'_PUB_TEST_SDK_VERSION': '3.5.0'},
+        // TODO(sigurdm): Should be fast-path
+        resolution: ResolutionAttempt.resolution,
+      );
+    });
+  });
+}
diff --git a/test/embedding/get_executable_for_command_test.dart b/test/embedding/get_executable_for_command_test.dart
deleted file mode 100644
index 5b07871..0000000
--- a/test/embedding/get_executable_for_command_test.dart
+++ /dev/null
@@ -1,494 +0,0 @@
-// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
-// for details. 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:io';
-
-import 'package:path/path.dart' show separator;
-import 'package:path/path.dart' as p;
-import 'package:pub/pub.dart';
-import 'package:pub/src/log.dart' as log;
-
-import 'package:test/test.dart';
-
-import '../descriptor.dart' as d;
-import '../test_pub.dart';
-
-Future<void> testGetExecutable(
-  String command,
-  String root, {
-  bool allowSnapshot = true,
-  Object? executable,
-  String? packageConfig,
-  Object? errorMessage,
-  CommandResolutionIssue? issue,
-}) async {
-  final cachePath = getPubTestEnvironment()['PUB_CACHE'];
-  final oldVerbosity = log.verbosity;
-  log.verbosity = log.Verbosity.none;
-  if (executable == null) {
-    expect(
-      () => getExecutableForCommand(
-        command,
-        root: root,
-        pubCacheDir: cachePath,
-        allowSnapshot: allowSnapshot,
-      ),
-      throwsA(
-        isA<CommandResolutionFailedException>()
-            .having((e) => e.message, 'message', errorMessage)
-            .having((e) => e.issue, 'issue', issue),
-      ),
-    );
-  } else {
-    final e = await getExecutableForCommand(
-      command,
-      root: root,
-      pubCacheDir: cachePath,
-      allowSnapshot: allowSnapshot,
-    );
-    expect(
-      e,
-      isA<DartExecutableWithPackageConfig>()
-          .having((e) => e.executable, 'executable', executable)
-          .having((e) => e.packageConfig, 'packageConfig', packageConfig),
-    );
-    expect(File(p.join(root, e.executable)).existsSync(), true);
-    log.verbosity = oldVerbosity;
-  }
-}
-
-Future<void> main() async {
-  test('Finds a direct dart-file without pub get', () async {
-    await d.dir('foo', [
-      d.dir('bar', [d.file('bar.dart', 'main() {print(42);}')]),
-    ]).create();
-    final dir = d.path('foo');
-
-    await testGetExecutable(
-      'bar/bar.dart',
-      dir,
-      executable: p.join('bar', 'bar.dart'),
-    );
-
-    await testGetExecutable(
-      p.join('bar', 'bar.dart'),
-      dir,
-      executable: p.join('bar', 'bar.dart'),
-    );
-
-    await testGetExecutable(
-      '${p.toUri(dir)}/bar/bar.dart',
-      dir,
-      executable: p.join('bar', 'bar.dart'),
-    );
-  });
-
-  test('Looks for file when no pubspec.yaml', () async {
-    await d.dir('foo', [
-      d.dir('bar', [d.file('bar.dart', 'main() {print(42);}')]),
-    ]).create();
-    final dir = d.path('foo');
-
-    await testGetExecutable(
-      'bar/m.dart',
-      dir,
-      errorMessage: contains('Could not find file `bar/m.dart`'),
-      issue: CommandResolutionIssue.fileNotFound,
-    );
-    await testGetExecutable(
-      p.join('bar', 'm.dart'),
-      dir,
-      errorMessage: contains('Could not find file `bar${separator}m.dart`'),
-      issue: CommandResolutionIssue.fileNotFound,
-    );
-  });
-
-  test('Error message when pubspec is broken', () async {
-    await d.dir('foo', [
-      d.pubspec({
-        'name': 'broken name',
-      }),
-    ]).create();
-
-    await d.dir(appPath, [
-      d.pubspec({
-        'name': 'myapp',
-        'environment': {'sdk': '^$_currentVersion'},
-        'dependencies': {
-          'foo': {
-            'path': '../foo',
-          },
-        },
-      }),
-    ]).create();
-    final dir = d.path(appPath);
-    await testGetExecutable(
-      'foo:app',
-      dir,
-      errorMessage: allOf(
-        contains(
-          'Error on line 1, column 9 of ${d.sandbox}${p.separator}foo${p.separator}pubspec.yaml: "name" field must be a valid Dart identifier.',
-        ),
-        contains(
-          '{"name":"broken name","environment":{"sdk":"$defaultSdkConstraint"}}',
-        ),
-      ),
-      issue: CommandResolutionIssue.pubGetFailed,
-    );
-  });
-
-  test('Reports file not found if the path looks like a file', () async {
-    await d.dir(appPath, [
-      d.pubspec({
-        'name': 'myapp',
-        'environment': {'sdk': '^$_currentVersion'},
-        'dependencies': {'foo': '^1.0.0'},
-      }),
-      d.dir('bin', [
-        d.file('myapp.dart', 'main() {print(42);}'),
-      ]),
-    ]).create();
-
-    await servePackages();
-    // The solver uses word-wrapping in its error message, so we use \s to
-    // accommodate.
-    await testGetExecutable(
-      'bar/m.dart',
-      d.path(appPath),
-      errorMessage: matches(r'Could not find file `bar/m.dart`'),
-      issue: CommandResolutionIssue.fileNotFound,
-    );
-  });
-
-  test('Reports parse failure', () async {
-    await d.dir(appPath, [
-      d.pubspec({
-        'name': 'myapp',
-        'environment': {'sdk': '^$_currentVersion'},
-      }),
-    ]).create();
-    await testGetExecutable(
-      '::',
-      d.path(appPath),
-      errorMessage: contains(r'cannot contain multiple ":"'),
-      issue: CommandResolutionIssue.parseError,
-    );
-  });
-
-  test('Reports compilation failure', () async {
-    await d.dir(appPath, [
-      d.pubspec({
-        'name': 'myapp',
-        'environment': {'sdk': '^$_currentVersion'},
-      }),
-      d.dir('bin', [
-        d.file('foo.dart', 'main() {'),
-      ]),
-    ]).create();
-
-    await servePackages();
-    // The solver uses word-wrapping in its error message, so we use \s to
-    // accommodate.
-    await testGetExecutable(
-      ':foo',
-      d.path(appPath),
-      errorMessage: matches(r'foo.dart:1:8:'),
-      issue: CommandResolutionIssue.compilationFailed,
-    );
-  });
-
-  test('Finds files', () async {
-    final server = await servePackages();
-    server.serve(
-      'foo',
-      '1.0.0',
-      pubspec: {
-        'environment': {'sdk': '^$_currentVersion'},
-      },
-      deps: {
-        'transitive': {'hosted': globalServer.url},
-      },
-      contents: [
-        d.dir('bin', [
-          d.file('foo.dart', 'main() {print(42);}'),
-          d.file('tool.dart', 'main() {print(42);}'),
-        ]),
-      ],
-    );
-
-    server.serve(
-      'transitive',
-      '1.0.0',
-      pubspec: {
-        'environment': {'sdk': '^$_currentVersion'},
-      },
-      contents: [
-        d.dir('bin', [d.file('transitive.dart', 'main() {print(42);}')]),
-      ],
-    );
-
-    await d.dir(appPath, [
-      d.pubspec({
-        'name': 'myapp',
-        'environment': {'sdk': '^$_currentVersion'},
-        'dependencies': {
-          'foo': {
-            'hosted': globalServer.url,
-            'version': '^1.0.0',
-          },
-        },
-      }),
-      d.dir('bin', [
-        d.file('myapp.dart', 'main() {print(42);}'),
-        d.file('tool.dart', 'main() {print(42);}'),
-      ]),
-    ]).create();
-    final dir = d.path(appPath);
-
-    await testGetExecutable(
-      'myapp',
-      dir,
-      executable: p.join(
-        '.dart_tool',
-        'pub',
-        'bin',
-        'myapp',
-        'myapp.dart-$_currentVersion.snapshot',
-      ),
-      packageConfig: p.join('.dart_tool', 'package_config.json'),
-    );
-    await testGetExecutable(
-      'myapp:myapp',
-      dir,
-      executable: p.join(
-        '.dart_tool',
-        'pub',
-        'bin',
-        'myapp',
-        'myapp.dart-$_currentVersion.snapshot',
-      ),
-      packageConfig: p.join('.dart_tool', 'package_config.json'),
-    );
-    await testGetExecutable(
-      ':myapp',
-      dir,
-      executable: p.join(
-        '.dart_tool',
-        'pub',
-        'bin',
-        'myapp',
-        'myapp.dart-$_currentVersion.snapshot',
-      ),
-      packageConfig: p.join('.dart_tool', 'package_config.json'),
-    );
-    await testGetExecutable(
-      ':tool',
-      dir,
-      executable: p.join(
-        '.dart_tool',
-        'pub',
-        'bin',
-        'myapp',
-        'tool.dart-$_currentVersion.snapshot',
-      ),
-      packageConfig: p.join('.dart_tool', 'package_config.json'),
-    );
-    await testGetExecutable(
-      'foo',
-      dir,
-      allowSnapshot: false,
-      executable: endsWith('foo-1.0.0${separator}bin${separator}foo.dart'),
-      packageConfig: p.join('.dart_tool', 'package_config.json'),
-    );
-    await testGetExecutable(
-      'foo',
-      dir,
-      executable:
-          '.dart_tool${separator}pub${separator}bin${separator}foo${separator}foo.dart-$_currentVersion.snapshot',
-      packageConfig: p.join('.dart_tool', 'package_config.json'),
-    );
-    await testGetExecutable(
-      'foo:tool',
-      dir,
-      allowSnapshot: false,
-      executable: endsWith('foo-1.0.0${separator}bin${separator}tool.dart'),
-      packageConfig: p.join('.dart_tool', 'package_config.json'),
-    );
-    await testGetExecutable(
-      'foo:tool',
-      dir,
-      executable:
-          '.dart_tool${separator}pub${separator}bin${separator}foo${separator}tool.dart-$_currentVersion.snapshot',
-      packageConfig: p.join('.dart_tool', 'package_config.json'),
-    );
-    await testGetExecutable(
-      'unknown:tool',
-      dir,
-      errorMessage: 'Could not find package `unknown` or file `unknown:tool`',
-      issue: CommandResolutionIssue.packageNotFound,
-    );
-    await testGetExecutable(
-      'foo:unknown',
-      dir,
-      errorMessage:
-          'Could not find `bin${separator}unknown.dart` in package `foo`.',
-      issue: CommandResolutionIssue.noBinaryFound,
-    );
-    await testGetExecutable(
-      'unknownTool',
-      dir,
-      errorMessage:
-          'Could not find package `unknownTool` or file `unknownTool`',
-      issue: CommandResolutionIssue.packageNotFound,
-    );
-    await testGetExecutable(
-      'transitive',
-      dir,
-      executable: p.join(
-        d.sandbox,
-        d.hostedCachePath(port: globalServer.port),
-        'transitive-1.0.0',
-        'bin',
-        'transitive.dart',
-      ),
-      allowSnapshot: false,
-      packageConfig: p.join('.dart_tool', 'package_config.json'),
-    );
-  });
-
-  test('works with workspace', () async {
-    final server = await servePackages();
-    server.serve(
-      'foo',
-      '1.0.0',
-      contents: [
-        d.dir('bin', [
-          d.file('foo.dart', 'main() {print(42);}'),
-          d.file('tool.dart', 'main() {print(42);}'),
-        ]),
-      ],
-    );
-
-    await d.dir(appPath, [
-      d.libPubspec(
-        'myapp',
-        '1.2.3',
-        deps: {
-          'a': 'any',
-          'foo': {
-            'hosted': globalServer.url,
-            'version': '^1.0.0',
-          },
-        },
-        extras: {
-          'workspace': ['pkgs/a', 'pkgs/b'],
-        },
-        sdk: '^3.5.0-0',
-      ),
-      d.dir('bin', [
-        d.file('myapp.dart', 'main() {print(42);}'),
-        d.file('tool.dart', 'main() {print(42);}'),
-      ]),
-      d.dir('pkgs', [
-        d.dir('a', [
-          d.libPubspec(
-            'a',
-            '1.0.0',
-            resolutionWorkspace: true,
-          ),
-          d.dir('bin', [
-            d.file('a.dart', 'main() {print(42);}'),
-            d.file('tool.dart', 'main() {print(42);}'),
-          ]),
-        ]),
-        d.dir('b', [
-          d.libPubspec(
-            'b',
-            '1.0.0',
-            resolutionWorkspace: true,
-          ),
-          d.dir('bin', [
-            d.file('b.dart', 'main() {print(42);}'),
-            d.file('tool.dart', 'main() {print(42);}'),
-          ]),
-        ]),
-      ]),
-    ]).create();
-    await pubGet(
-      environment: {'_PUB_TEST_SDK_VERSION': '3.5.0'},
-    );
-
-    await testGetExecutable(
-      'myapp',
-      p.join(d.sandbox, appPath, 'pkgs', 'a'),
-      executable: p.join(
-        '..',
-        '..',
-        '.dart_tool',
-        'pub',
-        'bin',
-        'myapp',
-        'myapp.dart-$_currentVersion.snapshot',
-      ),
-      packageConfig: p.join('..', '..', '.dart_tool', 'package_config.json'),
-    );
-    await testGetExecutable(
-      'a',
-      p.join(d.sandbox, appPath, 'pkgs'),
-      executable: p.join(
-        d.sandbox,
-        appPath,
-        'pkgs',
-        'a',
-        'bin',
-        'a.dart',
-      ),
-      allowSnapshot: false,
-      packageConfig: p.join('..', '.dart_tool', 'package_config.json'),
-    );
-    await testGetExecutable(
-      'b:tool',
-      p.join(d.sandbox, appPath),
-      allowSnapshot: false,
-      executable: p.join(
-        d.sandbox,
-        appPath,
-        'pkgs',
-        'b',
-        'bin',
-        'tool.dart',
-      ),
-      packageConfig: p.join('.dart_tool', 'package_config.json'),
-    );
-    await testGetExecutable(
-      'foo',
-      p.join(d.sandbox, appPath),
-      allowSnapshot: false,
-      executable: p.join(
-        d.sandbox,
-        d.hostedCachePath(),
-        'foo-1.0.0',
-        'bin',
-        'foo.dart',
-      ),
-      packageConfig: p.join('.dart_tool', 'package_config.json'),
-    );
-    await testGetExecutable(
-      ':tool',
-      p.join(d.sandbox, appPath, 'pkgs', 'a'),
-      allowSnapshot: false,
-      executable: p.join(
-        d.sandbox,
-        appPath,
-        'pkgs',
-        'a',
-        'bin',
-        'tool.dart',
-      ),
-      packageConfig: p.join('..', '..', '.dart_tool', 'package_config.json'),
-    );
-  });
-}
-
-final _currentVersion = Platform.version.split(' ').first;
diff --git a/tool/test-bin/pub_command_runner.dart b/tool/test-bin/pub_command_runner.dart
index 47dffd5..2665a7b 100644
--- a/tool/test-bin/pub_command_runner.dart
+++ b/tool/test-bin/pub_command_runner.dart
@@ -29,6 +29,41 @@
   }
 }
 
+/// A command for testing the [getExecutableForCommand] functionality.
+class GetExecutableForCommandCommand extends PubCommand {
+  @override
+  String get name => 'get-executable-for-command';
+
+  @override
+  String get description =>
+      'Finds the package config and executable given a command';
+
+  @override
+  bool get hidden => true;
+
+  GetExecutableForCommandCommand() {
+    argParser.addFlag('allow-snapshot');
+  }
+
+  @override
+  Future<void> runProtected() async {
+    try {
+      final result = await getExecutableForCommand(
+        argResults.rest[0],
+        allowSnapshot: argResults.flag('allow-snapshot'),
+      );
+      log.message('Executable: ${result.executable}');
+      log.message(
+        'Package config: ${result.packageConfig ?? 'No package config'}',
+      );
+    } on CommandResolutionFailedException catch (e) {
+      log.message('Error: ${e.message}');
+      log.message('Issue: ${e.issue}');
+      overrideExitCode(-1);
+    }
+  }
+}
+
 /// A command for testing the [ensurePubspecResolved] functionality.
 class EnsurePubspecResolvedCommand extends PubCommand {
   @override
@@ -81,7 +116,8 @@
         isVerbose: () => _results.flag('verbose'),
       )
         ..addSubcommand(ThrowingCommand())
-        ..addSubcommand(EnsurePubspecResolvedCommand()),
+        ..addSubcommand(EnsurePubspecResolvedCommand())
+        ..addSubcommand(GetExecutableForCommandCommand()),
     );
     addCommand(RunCommand());
     argParser.addFlag('verbose');