Files
sdk/runtime/bin/ffi_unit_test/run_ffi_unit_tests.cc
T
Daco Harkes 9f96aeda6f [test/ffi] Add C++ unit tests for all target ABIs
This CL introduces unit tests for the Native* classes in compiler/ffi
that can run for all supported target ABIs on any host architecture.

The unit tests are compiled for all target ABIs with
`tools/build.py run_ffi_unit_tests` and run for all target ABIs with
`tools/test.py ffi_unit`.

The unit test and tested code do not conceptually depend on having a
DartVM. The tests are compiled with a custom `dart::Zone` and
`platform/`. This enables compiling for all `TARGET_ARCH_*` and
`TARGET_OS_*` on any host, and running unit tests for all target ABIs
on any host.

Because the `run_ffi_unit_tests` executables do not include the DartVM
their build is quick (<10seconds) and they are small (~6MB) when
compared to `run_vm_tests` (~250MB).

The tests are added to the existing FFI QEMU bot to prevent adding an
extra bot which would add checkout overhead.

The unit tests themselves are set up to be fairly similar to vm/cc
tests. The only difference is the NativeCallingConvention tests which
are set up with `.expect` files for easy inspection and updating.

TEST=runtime/vm/compiler/ffi/native_calling_convention_test.cc
TEST=runtime/vm/compiler/ffi/native_location_test.cc
TEST=runtime/vm/compiler/ffi/native_type_test.cc

Change-Id: I7b8bf4de9ef070e7546472217e571a60362b9639
Cq-Include-Trybots: luci.dart.try:vm-precomp-ffi-qemu-linux-release-arm-try
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/171725
Commit-Queue: Daco Harkes <dacoharkes@google.com>
Reviewed-by: Clement Skau <cskau@google.com>
Reviewed-by: Alexander Thomas <athom@google.com>
2020-11-16 16:10:55 +00:00

116 lines
3.0 KiB
C++

// 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.
// A slimmed down version of bin/run_vm_tests.cc that only runs C++ non-DartVM
// unit tests.
//
// By slimming it down to non-VM, we can run with the defines for all target
// architectures and operating systems.
#include "vm/compiler/ffi/unit_test.h"
#include "platform/assert.h"
#include "platform/syslog.h"
namespace dart {
namespace compiler {
namespace ffi {
static const char* const kNone = "No Test";
static const char* const kList = "List all Tests";
static const char* const kAll = "Run all Tests";
static const char* run_filter = kNone;
static const char* kCommandAll = "--all";
static const char* kCommandList = "--list";
static const char* kCommandUpdate = "--update";
static int run_matches = 0;
TestCaseBase* TestCaseBase::first_ = nullptr;
TestCaseBase* TestCaseBase::tail_ = nullptr;
bool TestCaseBase::update_expectations = false;
TestCaseBase::TestCaseBase(const char* name, const char* expectation)
: next_(nullptr), name_(name), expectation_(expectation) {
ASSERT(strlen(expectation) > 0);
if (first_ == nullptr) {
first_ = this;
} else {
tail_->next_ = this;
}
tail_ = this;
}
void TestCaseBase::RunAll() {
TestCaseBase* test = first_;
while (test != nullptr) {
test->RunTest();
test = test->next_;
}
}
void TestCaseBase::RunTest() {
if (run_filter == kList) {
Syslog::Print("%s %s\n", this->name(), this->expectation());
run_matches++;
} else if (run_filter == kAll) {
this->Run();
run_matches++;
} else if (strcmp(run_filter, this->name()) == 0) {
this->Run();
run_matches++;
}
}
void RawTestCase::Run() {
Syslog::Print("Running test: %s\n", name());
(*run_)();
Syslog::Print("Done: %s\n", name());
}
static int Main(int argc, const char** argv) {
if (argc == 2 && strcmp(argv[1], kCommandList) == 0) {
run_filter = kList;
// List all tests and benchmarks and exit.
TestCaseBase::RunAll();
fflush(stdout);
return 0;
}
if (argc > 1 && strcmp(argv[1], kCommandUpdate) == 0) {
TestCaseBase::update_expectations = true;
}
if (strcmp(argv[argc - 1], kCommandAll) == 0) {
// Run all tests.
run_filter = kAll;
} else if (argc > 1) {
// Run only test with specific name.
run_filter = argv[argc - 1];
}
TestCaseBase::RunAll();
// Print a warning message if no tests or benchmarks were matched.
if (run_matches == 0) {
Syslog::PrintErr("No tests matched: %s\n", run_filter);
return 1;
}
if (Expect::failed()) {
Syslog::PrintErr(
"Some tests failed. Run the following command to update "
"expectations.\ntools/test.py --vm-options=--update ffi_unit");
return 255;
}
return 0;
}
} // namespace ffi
} // namespace compiler
} // namespace dart
int main(int argc, const char** argv) {
return dart::compiler::ffi::Main(argc, argv);
}