Skip to content

Commit c52acad

Browse files
mkustermanncommit-bot@chromium.org
authored andcommitted
[vm/ffi] Split up some tests/ffi into vmspecific and non-vmspecific
The separation will allow flutter/flutter integration tests to run the non-vmspecific parts. Change-Id: I0e771f1247ec62d2f0c3faa95ee10560e62524f1 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/127144 Reviewed-by: Daco Harkes <dacoharkes@google.com> Commit-Queue: Martin Kustermann <kustermann@google.com>
1 parent 1bbbc9f commit c52acad

23 files changed

+187
-127
lines changed

runtime/bin/BUILD.gn

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1120,9 +1120,14 @@ shared_library("ffi_test_functions") {
11201120
deps = [
11211121
":dart",
11221122
]
1123+
1124+
# The two files here do not depend on each other.
1125+
# flutter/flutter integration tests will only use `ffi_test_functions.cc` -
1126+
# any test functionality using `dart_api.h` has to go into
1127+
# `ffi_test_functions_vmspecific.cc`.
11231128
sources = [
11241129
"ffi_test/ffi_test_functions.cc",
1125-
"ffi_test/ffi_test_functions_special.cc",
1130+
"ffi_test/ffi_test_functions_vmspecific.cc",
11261131
]
11271132
if (is_win && current_cpu == "x64") {
11281133
sources += [ "ffi_test/clobber_x64_win.S" ]

runtime/bin/ffi_test/ffi_test_functions.cc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@
33
// BSD-style license that can be found in the LICENSE file.
44

55
// This file contains test functions for the dart:ffi test cases.
6+
// This file is not allowed to depend on any symbols from the embedder and is
7+
// therefore not allowed to use `dart_api.h`. (The flutter/flutter integration
8+
// tests will run dart tests using this library only.)
69

710
#include <stddef.h>
811
#include <stdlib.h>

tests/ffi/ffi.status

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ function_callbacks_test/03: Skip
1717
*: Skip # "hardfp" calling convention is not yet supported (iOS is also supported but not tested): dartbug.com/36309
1818

1919
[ $compiler == dart2analyzer ]
20-
enable_ffi_test: SkipByDesign # This is a check for VM only.
20+
vmspecific_enable_ffi_test: SkipByDesign # This is a check for VM only.
2121

2222
[ $runtime != dart_precompiled && $runtime != vm && $compiler != dart2analyzer ]
2323
*: SkipByDesign # FFI is a VM-only feature. (This test suite is part of the default set.)

tests/ffi/function_callbacks_test.dart

Lines changed: 0 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,6 @@
22
// for details. All rights reserved. Use of this source code is governed by a
33
// BSD-style license that can be found in the LICENSE file.
44

5-
// VMOptions=--enable-testing-pragmas --enable-isolate-groups
6-
// VMOptions=--enable-testing-pragmas --no-enable-isolate-groups
7-
//
85
// Dart test program for testing dart:ffi function pointers with callbacks.
96
//
107
// VMOptions=--enable-testing-pragmas
@@ -19,7 +16,6 @@
1916

2017
import 'dart:io';
2118
import 'dart:ffi';
22-
import 'dart:isolate';
2319
import 'dylib_utils.dart';
2420

2521
import "package:expect/expect.dart";
@@ -176,19 +172,6 @@ Pointer<Void> throwExceptionPointer() {
176172
throw "Exception.";
177173
}
178174

179-
void testGC() {
180-
triggerGc();
181-
}
182-
183-
typedef WaitForHelperNative = Void Function(Pointer<Void>);
184-
typedef WaitForHelper = void Function(Pointer<Void>);
185-
186-
void waitForHelper(Pointer<Void> helper) {
187-
print("helper: $helper");
188-
testLibrary
189-
.lookupFunction<WaitForHelperNative, WaitForHelper>("WaitForHelper")(helper);
190-
}
191-
192175
final List<Test> testcases = [
193176
Test("SimpleAddition",
194177
Pointer.fromFunction<SimpleAdditionType>(simpleAddition, 0)),
@@ -213,65 +196,10 @@ final List<Test> testcases = [
213196
Pointer.fromFunction<ThrowExceptionPointer>(throwExceptionPointer)),
214197
Test("ThrowException",
215198
Pointer.fromFunction<ThrowExceptionInt>(throwExceptionInt, 42)),
216-
Test("GC", Pointer.fromFunction<ReturnVoid>(testGC)),
217-
Test("UnprotectCode", Pointer.fromFunction<WaitForHelperNative>(waitForHelper)),
218199
];
219200

220-
testCallbackWrongThread() =>
221-
Test("CallbackWrongThread", Pointer.fromFunction<ReturnVoid>(returnVoid))
222-
.run();
223-
224-
testCallbackOutsideIsolate() =>
225-
Test("CallbackOutsideIsolate", Pointer.fromFunction<ReturnVoid>(returnVoid))
226-
.run();
227-
228-
isolateHelper(int callbackPointer) {
229-
final Pointer<Void> ptr = Pointer.fromAddress(callbackPointer);
230-
final NativeCallbackTestFn tester =
231-
testLibrary.lookupFunction<NativeCallbackTest, NativeCallbackTestFn>(
232-
"TestCallbackWrongIsolate");
233-
Expect.equals(0, tester(ptr));
234-
}
235-
236-
testCallbackWrongIsolate() async {
237-
final int callbackPointer =
238-
Pointer.fromFunction<ReturnVoid>(returnVoid).address;
239-
final ReceivePort exitPort = ReceivePort();
240-
await Isolate.spawn(isolateHelper, callbackPointer,
241-
errorsAreFatal: true, onExit: exitPort.sendPort);
242-
await exitPort.first;
243-
}
244-
245-
const double zeroPointZero = 0.0;
246-
247-
// Correct type of exceptionalReturn argument to Pointer.fromFunction.
248-
double testExceptionalReturn() {
249-
Pointer.fromFunction<Double Function()>(testExceptionalReturn, 0.0);
250-
Pointer.fromFunction<Double Function()>(testExceptionalReturn, zeroPointZero);
251-
252-
Pointer.fromFunction<Double Function()>(returnVoid, null); //# 59: compile-time error
253-
Pointer.fromFunction<Void Function()>(returnVoid, 0); //# 60: compile-time error
254-
Pointer.fromFunction<Double Function()>(testExceptionalReturn, "abc"); //# 61: compile-time error
255-
Pointer.fromFunction<Double Function()>(testExceptionalReturn, 0); //# 62: compile-time error
256-
Pointer.fromFunction<Double Function()>(testExceptionalReturn); //# 63: compile-time error
257-
258-
return 0.0; // not used
259-
}
260-
261201
void main() async {
262202
testcases.forEach((t) => t.run()); //# 00: ok
263-
testExceptionalReturn(); //# 00: ok
264-
265-
// These tests terminate the process after successful completion, so we have
266-
// to run them separately.
267-
//
268-
// Since they use signal handlers they only run on Linux.
269-
if (Platform.isLinux && !const bool.fromEnvironment("dart.vm.product")) {
270-
testCallbackWrongThread(); //# 01: ok
271-
testCallbackOutsideIsolate(); //# 02: ok
272-
await testCallbackWrongIsolate(); //# 03: ok
273-
}
274-
275203
testManyCallbacks(); //# 04: ok
276204
}
277205

tests/ffi/function_test.dart

Lines changed: 1 addition & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -42,11 +42,10 @@ void main() {
4242
testVoidReturn();
4343
testNoArgs();
4444
testException();
45-
testLookupFunctionPointerNativeType();
4645
}
4746
}
4847

49-
DynamicLibrary ffiTestFunctions = dlopenPlatformSpecific("ffi_test_functions");
48+
final ffiTestFunctions = dlopenPlatformSpecific("ffi_test_functions");
5049

5150
typedef NativeBinaryOp = Int32 Function(Int32, Int32);
5251
typedef UnaryOp = int Function(int);
@@ -404,24 +403,12 @@ void testNoArgs() {
404403
Expect.approxEquals(1337.0, result);
405404
}
406405

407-
typedef NativeTypeNFT = Pointer<NativeType> Function(
408-
Pointer<Pointer<NativeType>>, Int8);
409-
typedef NativeTypeFT = Pointer<NativeType> Function(
410-
Pointer<Pointer<NativeType>>, int);
411-
412-
void testLookupFunctionPointerNativeType() {
413-
// The function signature does not match up, but that does not matter since
414-
// this test does not use the trampoline.
415-
ffiTestFunctions.lookupFunction<NativeTypeNFT, NativeTypeFT>("LargePointer");
416-
}
417-
418406
// Throw an exception from within the trampoline and collect a stacktrace
419407
// include its frame.
420408
void testException() {
421409
try {
422410
sumPlus42(null, null);
423411
} catch (e, s) {
424-
print("$e, $s");
425412
return;
426413
}
427414
throw "Didn't throw!";

tests/ffi/prepare_flutter_bundle.dart

Lines changed: 18 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -102,18 +102,12 @@ Future generateCLibs(String sdkRoot, String destDir, Set<String> allFiles,
102102
path.join(sdkRoot, 'runtime/bin/ffi_test/ffi_test_dynamic_library.cc');
103103
destinationFile =
104104
path.join(dir.path, path.basename(lib1)).replaceAll('.cc', '.cpp');
105-
File(destinationFile)
106-
.writeAsStringSync(cleanCC(File(lib1).readAsStringSync()));
105+
File(destinationFile).writeAsStringSync(File(lib1).readAsStringSync());
107106

108107
final lib2 = path.join(sdkRoot, 'runtime/bin/ffi_test/ffi_test_functions.cc');
109108
destinationFile =
110109
path.join(dir.path, path.basename(lib2)).replaceAll('.cc', '.cpp');
111-
File(destinationFile)
112-
.writeAsStringSync(cleanCC(File(lib2).readAsStringSync()));
113-
}
114-
115-
String cleanCC(String content) {
116-
return content.replaceAll('DART_EXPORT', 'extern "C" ');
110+
File(destinationFile).writeAsStringSync(File(lib2).readAsStringSync());
117111
}
118112

119113
String cleanDart(String content) {
@@ -125,21 +119,23 @@ Future generateDartTests(
125119
final dir = await generateCleanDir(destDir);
126120

127121
final sink = File(path.join(dir.path, 'all.dart')).openWrite();
122+
sink.writeln('import "dart:async";');
123+
sink.writeln('');
128124
for (int i = 0; i < testFiles.length; ++i) {
129125
sink.writeln('import "${path.basename(testFiles[i])}" as main$i;');
130126
}
131127
sink.writeln('');
132-
sink.writeln('invoke(fn) {');
133-
sink.writeln(' if (fn is void Function()) {');
134-
sink.writeln(' fn();');
128+
sink.writeln('Future invoke(dynamic fun) async {');
129+
sink.writeln(' if (fun is void Function() || fun is Future Function()) {');
130+
sink.writeln(' return await fun();');
135131
sink.writeln(' } else {');
136-
sink.writeln(' fn(<String>[]);');
132+
sink.writeln(' return await fun(<String>[]);');
137133
sink.writeln(' }');
138134
sink.writeln('}');
139135
sink.writeln('');
140-
sink.writeln('main() {');
136+
sink.writeln('dynamic main() async {');
141137
for (int i = 0; i < testFiles.length; ++i) {
142-
sink.writeln(' invoke(main$i.main);');
138+
sink.writeln(' await invoke(main$i.main);');
143139
}
144140
sink.writeln('}');
145141
await sink.close();
@@ -166,32 +162,19 @@ Stream<String> listTestFiles(
166162
await for (final file in Directory(path.join(sdkRoot, 'tests/ffi')).list()) {
167163
if (file is File && file.path.endsWith('_test.dart')) {
168164
// These tests are VM specific and cannot necessarily be run on Flutter.
169-
final blacklistedTests = const [
170-
'function_callbacks_test.dart',
171-
'function_callbacks_test.dart',
172-
'function_gc_test.dart',
173-
'function_test.dart',
174-
'object_gc_test.dart',
175-
'regress_37100_test.dart',
176-
'regress_37511_callbacks_test.dart',
177-
'regress_37511_test.dart',
178-
'regress_37780_test.dart',
179-
];
180-
if (blacklistedTests.contains(path.basename(file.path))) {
165+
if (path.basename(file.path).startsWith('vmspecific_')) {
181166
filteredTests.add(file.path);
182167
continue;
183168
}
169+
// These tests use special features which are hard to test on Flutter.
184170
final contents = file.readAsStringSync();
185-
if (!contents.contains('//#') &&
186-
!contents.contains('dart:async') &&
187-
!contents.contains('dart:isolate') &&
188-
!contents.contains('async') &&
189-
!contents.contains('Future') &&
190-
!contents.contains('DynamicLibrary.process') &&
191-
!contents.contains('DynamicLibrary.executable') &&
192-
!contents.contains('Future')) {
193-
yield file.path;
171+
if (contents.contains(RegExp('//# .* compile-time error')) ||
172+
contents.contains('DynamicLibrary.process') ||
173+
contents.contains('DynamicLibrary.executable')) {
174+
filteredTests.add(file.path);
175+
continue;
194176
}
177+
yield file.path;
195178
}
196179
}
197180
}

tests/ffi/sizeof_test.dart

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
//
5+
// SharedObjects=ffi_test_functions
6+
7+
import 'dart:ffi';
8+
9+
import "package:expect/expect.dart";
10+
11+
void main() async {
12+
Expect.equals(true, 4 == sizeOf<Pointer>() || 8 == sizeOf<Pointer>());
13+
}
File renamed without changes.

0 commit comments

Comments
 (0)