[vm/ffi] Migrate legacy multi-test files to Process.run
Migrates vmspecific_enable_ffi_test.dart and abi_specific_int_incomplete_aot_test.dart away from legacy multi-test markers. Since these tests verify VM/gen_snapshot compile-time errors (not CFE errors), they cannot use // [cfe] expectations. Instead, they now spawn a subprocess and verify the expected error is produced. - vmspecific_enable_ffi_test: Runs helper with --enable-ffi=false, checks for error - abi_specific_int_incomplete_aot_test: Compiles helper with `dart compile aot-snapshot`, checks for error Both tests self-spawn AOT tooling (gen_snapshot) or the JIT `dart` CLI, so they only run on the dartkp host bots and are skipped elsewhere (ia32, android, fuchsia, qemu) via tests/ffi/ffi.status. Fixes https://github.com/dart-lang/sdk/issues/60212 Change-Id: Ib2482c3172b20a4366f984da33544fc515b540c4 Cq-Include-Trybots: dart/try:vm-aot-android-debug-arm64c-try,vm-aot-android-debug-arm_x64-try,vm-aot-linux-debug-arm64-try,vm-aot-linux-debug-x64-try,vm-aot-linux-debug-x64c-try,vm-aot-mac-debug-arm64-try,vm-aot-mac-debug-x64-try,vm-aot-obfuscate-linux-release-x64-try,vm-aot-optimization-level-linux-release-x64-try,vm-aot-win-debug-arm64-try,vm-aot-win-debug-x64-try,vm-aot-win-debug-x64c-try,vm-asan-linux-release-arm64-try,vm-asan-linux-release-x64-try,vm-asan-mac-release-arm64-try,vm-asan-win-release-x64-try,vm-ffi-qemu-linux-release-arm-try,vm-ffi-qemu-linux-release-riscv64-try,vm-fuchsia-release-x64-try,vm-msan-linux-release-arm64-try,vm-msan-linux-release-x64-try,vm-tsan-linux-release-arm64-try,vm-tsan-linux-release-x64-try,vm-tsan-mac-release-arm64-try,vm-ubsan-linux-release-arm64-try,vm-ubsan-linux-release-x64-try,vm-ubsan-mac-release-arm64-try,vm-ubsan-win-release-x64-try Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/508020 Commit-Queue: Samuel Rawlins <srawlins@google.com> Auto-Submit: Ankit Ranjan <ankitranjandev@gmail.com> Reviewed-by: Daco Harkes <dacoharkes@google.com> Reviewed-by: Samuel Rawlins <srawlins@google.com>
This commit is contained in:
committed by
dart-scoped@luci-project-accounts.iam.gserviceaccount.com
parent
e171e636d5
commit
6de2588d56
@@ -1,26 +1,91 @@
|
||||
// Copyright (c) 2021, 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.
|
||||
//
|
||||
// Tests that using an AbiSpecificInteger with an incomplete mapping produces
|
||||
// a compile-time error during AOT compilation.
|
||||
//
|
||||
// Uses pkg/vm/tool/gen_kernel and the build directory's gen_snapshot rather
|
||||
// than `dart compile aot-snapshot`, because the test bots do not build the
|
||||
// full SDK (gen_kernel_aot.dart.snapshot).
|
||||
|
||||
// Formatting can break multitests, so don't format them.
|
||||
// dart format off
|
||||
import 'dart:io';
|
||||
|
||||
// SharedObjects=ffi_test_functions
|
||||
import 'package:expect/expect.dart';
|
||||
import 'package:path/path.dart' as path;
|
||||
|
||||
import 'dart:ffi';
|
||||
final _execSuffix = Platform.isWindows ? '.exe' : '';
|
||||
final _batSuffix = Platform.isWindows ? '.bat' : '';
|
||||
|
||||
// We want at least 1 mapping to satisfy the static checks.
|
||||
const notTestingOn = Abi.fuchsiaArm64;
|
||||
|
||||
@AbiSpecificIntegerMapping({
|
||||
notTestingOn: Int8(),
|
||||
})
|
||||
final class Incomplete extends AbiSpecificInteger {
|
||||
const Incomplete();
|
||||
String _findGenSnapshot(String buildDir) {
|
||||
final possiblePaths = [
|
||||
// No cross compilation.
|
||||
path.join(buildDir, 'gen_snapshot$_execSuffix'),
|
||||
// ${MODE}SIMARM_X64 for X64->SIMARM cross compilation.
|
||||
path.join('${buildDir}_X64', 'gen_snapshot$_execSuffix'),
|
||||
// ${MODE}XARM64/clang_x64 for X64->ARM64 cross compilation.
|
||||
path.join(buildDir, 'clang_x64', 'gen_snapshot$_execSuffix'),
|
||||
];
|
||||
for (final p in possiblePaths) {
|
||||
if (File(p).existsSync()) {
|
||||
return p;
|
||||
}
|
||||
}
|
||||
throw 'Could not find gen_snapshot for build directory $buildDir';
|
||||
}
|
||||
|
||||
void main() {
|
||||
// Any use that causes the class to be used, causes a compile-time error
|
||||
// during loading of the class.
|
||||
nullptr.cast<Incomplete>(); //# 1: compile-time error
|
||||
final buildDir = path.dirname(Platform.executable);
|
||||
final sdkDir = path.dirname(path.dirname(buildDir));
|
||||
final genKernel = path.join(
|
||||
sdkDir,
|
||||
'pkg',
|
||||
'vm',
|
||||
'tool',
|
||||
'gen_kernel$_batSuffix',
|
||||
);
|
||||
final genSnapshot = _findGenSnapshot(buildDir);
|
||||
final platformDill = path.join(buildDir, 'vm_platform.dill');
|
||||
final helperPath = path.join(
|
||||
sdkDir,
|
||||
'tests',
|
||||
'ffi',
|
||||
'abi_specific_int_incomplete_aot_test_helper.dart',
|
||||
);
|
||||
|
||||
final tempDir = Directory.systemTemp.createTempSync('abi_incomplete_aot');
|
||||
try {
|
||||
final dillPath = path.join(tempDir.path, 'out.dill');
|
||||
|
||||
// Compiling the helper to kernel should succeed; the incomplete ABI
|
||||
// mapping is only detected by the VM precompiler.
|
||||
final kernelResult = Process.runSync(genKernel, [
|
||||
'--aot',
|
||||
'--platform=$platformDill',
|
||||
'-o',
|
||||
dillPath,
|
||||
helperPath,
|
||||
]);
|
||||
Expect.equals(
|
||||
0,
|
||||
kernelResult.exitCode,
|
||||
'gen_kernel failed: ${kernelResult.stdout}\n${kernelResult.stderr}',
|
||||
);
|
||||
|
||||
// AOT compiling the kernel file should fail with a compile-time error
|
||||
// about the incomplete ABI mapping.
|
||||
final snapshotResult = Process.runSync(genSnapshot, [
|
||||
'--snapshot-kind=app-aot-elf',
|
||||
'--elf=${path.join(tempDir.path, 'out.so')}',
|
||||
dillPath,
|
||||
]);
|
||||
Expect.notEquals(0, snapshotResult.exitCode);
|
||||
final stderr = snapshotResult.stderr.toString();
|
||||
Expect.isTrue(
|
||||
stderr.contains("AbiSpecificInteger 'Incomplete' is missing mapping for"),
|
||||
'Expected error about missing ABI mapping, got: $stderr',
|
||||
);
|
||||
} finally {
|
||||
tempDir.deleteSync(recursive: true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
// Copyright (c) 2026, 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.
|
||||
//
|
||||
// Helper for abi_specific_int_incomplete_aot_test.dart.
|
||||
// This file has an AbiSpecificInteger with an incomplete mapping.
|
||||
// During AOT compilation for any ABI other than fuchsiaArm64, gen_snapshot
|
||||
// should fail with an error about the missing mapping.
|
||||
|
||||
import 'dart:ffi';
|
||||
|
||||
// We want at least 1 mapping to satisfy the static checks.
|
||||
const notTestingOn = Abi.fuchsiaArm64;
|
||||
|
||||
@AbiSpecificIntegerMapping({notTestingOn: Int8()})
|
||||
final class Incomplete extends AbiSpecificInteger {
|
||||
const Incomplete();
|
||||
}
|
||||
|
||||
void main() {
|
||||
// Any use that causes the class to be used, causes a compile-time error
|
||||
// during loading of the class.
|
||||
nullptr.cast<Incomplete>();
|
||||
}
|
||||
+13
-7
@@ -12,6 +12,9 @@ function_structs_by_value_generated_ret_leaf_test: Pass, Slow # https://dartbug.
|
||||
function_structs_by_value_generated_ret_test: Pass, Slow # https://dartbug.com/47303 https://dartbug.com/45007
|
||||
native_assets/asset_*: Pass, Slow # https://dartbug.com/56330
|
||||
|
||||
[ $arch == ia32 ]
|
||||
abi_specific_int_incomplete_aot_test: SkipByDesign # No AOT mode on IA32.
|
||||
|
||||
[ $arch == simarm64_arm64 ]
|
||||
function_structs_by_value_generated_args_native_test: Pass, Slow
|
||||
|
||||
@@ -41,6 +44,10 @@ native_assets/asset_*: SkipByDesign # Only intended to run from source. https://
|
||||
native_assets/infer_native_assets_yaml_*: SkipByDesign # Only intended to run from source. https://dartbug.com/51265
|
||||
vmspecific_leaf_call_test: Skip # https://dartbug.com/46125: Snapshot fails to generate.
|
||||
|
||||
[ $compiler != dartkp ]
|
||||
abi_specific_int_incomplete_aot_test: SkipByDesign # Self-spawns gen_kernel/gen_snapshot, which are only built on AOT (dartkp) bots.
|
||||
vmspecific_enable_ffi_test: SkipByDesign # Self-spawns the JIT dart executable, so the harness compiler is irrelevant; runs once on the dartkp bots.
|
||||
|
||||
[ $mode == debug ]
|
||||
function_callbacks_structs_by_value_generated_test: Pass, Slow
|
||||
|
||||
@@ -49,10 +56,13 @@ regress_47594_test: Skip # Profiler is not available in Product.
|
||||
|
||||
[ $system == android ]
|
||||
*: Pass, Slow # https://github.com/dart-lang/sdk/issues/38489
|
||||
abi_specific_int_incomplete_aot_test: Skip # Needs gen_kernel and gen_snapshot.
|
||||
regress_47594_test: Skip # DartDev is not available on Android.
|
||||
vmspecific_enable_ffi_test: Skip # Needs access to Dart executable.
|
||||
vmspecific_native_finalizer_isolate_groups_test: Skip # SpawnUri not available on Android tester.
|
||||
|
||||
[ $system == fuchsia ]
|
||||
abi_specific_int_incomplete_aot_test: SkipByDesign # Needs gen_kernel and gen_snapshot.
|
||||
async_void_function_callbacks_test/*: Skip # Test harness doesn't support multitest with Fuchsia
|
||||
exceptional_return_const_test/*: Skip # Test harness doesn't support multitest with Fuchsia
|
||||
ffi_induce_a_crash_test/*: Skip # Test harness doesn't support multitest with Fuchsia
|
||||
@@ -72,7 +82,7 @@ run_isolate_group_run_test: Skip # gen_snapshot requires experimental-shared-dat
|
||||
static_checks/*: SkipByDesign # Expecting compile time failures in multi tests doesn't work on the Fuchsia test runner.
|
||||
threading_test: Skip # gen_snapshot requires experimental-shared-data flag
|
||||
unaligned_test/*: Skip # Test harness doesn't support multitest with Fuchsia
|
||||
vmspecific_enable_ffi_test/*: Skip # Test harness doesn't support multitest with Fuchsia
|
||||
vmspecific_enable_ffi_test: SkipByDesign # Needs access to Dart executable.
|
||||
vmspecific_function_callbacks_exit_test/*: Skip # Test harness doesn't support multitest with Fuchsia
|
||||
vmspecific_highmem_32bit_test/*: Skip # Test harness doesn't support multitest with Fuchsia
|
||||
vmspecific_leaf_call_test/*: Skip # Test harness doesn't support multitest with Fuchsia
|
||||
@@ -85,8 +95,10 @@ regress_47594_test: Skip # DynamicLibrary.process() is not available on Windows.
|
||||
ffi_induce_a_crash_test: SkipByDesign
|
||||
|
||||
[ $qemu ]
|
||||
abi_specific_int_incomplete_aot_test: SkipByDesign # Needs gen_kernel and gen_snapshot.
|
||||
function_callbacks_leaf_test: SkipByDesign # Needs access to Dart executable
|
||||
native_assets/*: SkipByDesign # Only intended to run on host oses with AOT binaries available, not available on QEMU.
|
||||
vmspecific_enable_ffi_test: SkipByDesign # Needs access to Dart executable.
|
||||
|
||||
[ $arch != simarm64_arm64 && $simulator ]
|
||||
*: Skip # FFI not yet supported on the arm simulator.
|
||||
@@ -103,9 +115,6 @@ many_listener_callbacks_test: Pass, Slow
|
||||
[ $compiler == app_jitk || $sanitizer == asan ]
|
||||
vmspecific_function_callbacks_exit_test: SkipByDesign
|
||||
|
||||
[ $compiler == dart2analyzer || $compiler == fasta ]
|
||||
vmspecific_enable_ffi_test: SkipByDesign # This is a check for VM only.
|
||||
|
||||
[ $compiler == dartk || $system == android ]
|
||||
native_assets/asset_*: SkipByDesign # Only intended to run on host oses with AOT binaries available.
|
||||
|
||||
@@ -115,9 +124,6 @@ native_assets/infer_native_assets_yaml_*: SkipByDesign # Only intended to run fr
|
||||
[ $compiler == dartkp || $arch == arm64 && $system == fuchsia ]
|
||||
abi_specific_int_incomplete_jit_test: SkipByDesign # Only intended to run in JIT mode.
|
||||
|
||||
[ $compiler != dartkp || $arch == arm64 && $system == fuchsia ]
|
||||
abi_specific_int_incomplete_aot_test: SkipByDesign # Only intended to run in AOT mode.
|
||||
|
||||
[ $runtime == dart_precompiled || $runtime == vm ]
|
||||
callback_unwind_error_test: Crash # https://github.com/dart-lang/sdk/issues/39487
|
||||
|
||||
|
||||
@@ -3,19 +3,36 @@
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
//
|
||||
// Dart test program for testing the --enable-ffi=false flag.
|
||||
//
|
||||
// VMOptions=--enable-ffi=false
|
||||
|
||||
// Formatting can break multitests, so don't format them.
|
||||
// dart format off
|
||||
import 'dart:io';
|
||||
|
||||
import 'dart:ffi'; //# 01: compile-time error
|
||||
import 'package:expect/expect.dart';
|
||||
import 'package:path/path.dart' as path;
|
||||
|
||||
import 'package:ffi/ffi.dart'; //# 01: compile-time error
|
||||
final _execSuffix = Platform.isWindows ? '.exe' : '';
|
||||
|
||||
void main() {
|
||||
Pointer<Int8> p = //# 01: compile-time error
|
||||
calloc(); //# 01: compile-time error
|
||||
print(p.address); //# 01: compile-time error
|
||||
calloc.free(p); //# 01: compile-time error
|
||||
final buildDir = path.dirname(Platform.executable);
|
||||
final sdkDir = path.dirname(path.dirname(buildDir));
|
||||
// Use the JIT `dart` executable from the build directory rather than
|
||||
// `Platform.executable`, which is the AOT runtime under dartkp and cannot run
|
||||
// the source helper.
|
||||
final dartExecutable = path.join(buildDir, 'dart$_execSuffix');
|
||||
final helperPath = path.join(
|
||||
sdkDir,
|
||||
'tests',
|
||||
'ffi',
|
||||
'vmspecific_enable_ffi_test_helper.dart',
|
||||
);
|
||||
|
||||
final result = Process.runSync(dartExecutable, [
|
||||
'--enable-ffi=false',
|
||||
helperPath,
|
||||
]);
|
||||
|
||||
Expect.equals(254, result.exitCode);
|
||||
Expect.contains(
|
||||
'import of dart:ffi is not supported in the current Dart runtime',
|
||||
result.stderr,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
// Copyright (c) 2026, 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.
|
||||
//
|
||||
// Helper for vmspecific_enable_ffi_test.dart.
|
||||
// This file imports dart:ffi and should fail to load when --enable-ffi=false.
|
||||
|
||||
import 'dart:ffi';
|
||||
|
||||
import 'package:ffi/ffi.dart';
|
||||
|
||||
void main() {
|
||||
Pointer<Int8> p = calloc();
|
||||
print(p.address);
|
||||
calloc.free(p);
|
||||
}
|
||||
Reference in New Issue
Block a user