Turned back on debug unit tests (#42261)
I refactored the `EXPECT_EXIT` tests since they are unsafe to execute in a process with multiple threads.
This leaves `flutter_desktop_darwin_unittests` disabled since it has existing issues.
fixes https://github.com/flutter/flutter/issues/103757
[C++, Objective-C, Java style guides]: https://github.com/flutter/engine/blob/main/CONTRIBUTING.md#style
diff --git a/ci/builders/mac_host_engine.json b/ci/builders/mac_host_engine.json
index 6b9c9c5..21d80f8 100644
--- a/ci/builders/mac_host_engine.json
+++ b/ci/builders/mac_host_engine.json
@@ -51,7 +51,7 @@
"--variant",
"host_debug",
"--type",
- "dart",
+ "dart,engine",
"--engine-capture-core-dump"
],
"script": "flutter/testing/run_tests.py"
diff --git a/flow/frame_timings.cc b/flow/frame_timings.cc
index 7b5c0f9..eed35fd 100644
--- a/flow/frame_timings.cc
+++ b/flow/frame_timings.cc
@@ -103,32 +103,75 @@
void FrameTimingsRecorder::RecordVsync(fml::TimePoint vsync_start,
fml::TimePoint vsync_target) {
- std::scoped_lock state_lock(state_mutex_);
- FML_DCHECK(state_ == State::kUninitialized);
- state_ = State::kVsync;
- vsync_start_ = vsync_start;
- vsync_target_ = vsync_target;
+ fml::Status status = RecordVsyncImpl(vsync_start, vsync_target);
+ FML_DCHECK(status.ok());
+ (void)status;
}
void FrameTimingsRecorder::RecordBuildStart(fml::TimePoint build_start) {
- std::scoped_lock state_lock(state_mutex_);
- FML_DCHECK(state_ == State::kVsync);
- state_ = State::kBuildStart;
- build_start_ = build_start;
+ fml::Status status = RecordBuildStartImpl(build_start);
+ FML_DCHECK(status.ok());
+ (void)status;
}
void FrameTimingsRecorder::RecordBuildEnd(fml::TimePoint build_end) {
- std::scoped_lock state_lock(state_mutex_);
- FML_DCHECK(state_ == State::kBuildStart);
- state_ = State::kBuildEnd;
- build_end_ = build_end;
+ fml::Status status = RecordBuildEndImpl(build_end);
+ FML_DCHECK(status.ok());
+ (void)status;
}
void FrameTimingsRecorder::RecordRasterStart(fml::TimePoint raster_start) {
+ fml::Status status = RecordRasterStartImpl(raster_start);
+ FML_DCHECK(status.ok());
+ (void)status;
+}
+
+fml::Status FrameTimingsRecorder::RecordVsyncImpl(fml::TimePoint vsync_start,
+ fml::TimePoint vsync_target) {
std::scoped_lock state_lock(state_mutex_);
- FML_DCHECK(state_ == State::kBuildEnd);
+ if (state_ != State::kUninitialized) {
+ return fml::Status(fml::StatusCode::kFailedPrecondition,
+ "Check failed: state_ == State::kUninitialized.");
+ }
+ state_ = State::kVsync;
+ vsync_start_ = vsync_start;
+ vsync_target_ = vsync_target;
+ return fml::Status();
+}
+
+fml::Status FrameTimingsRecorder::RecordBuildStartImpl(
+ fml::TimePoint build_start) {
+ std::scoped_lock state_lock(state_mutex_);
+ if (state_ != State::kVsync) {
+ return fml::Status(fml::StatusCode::kFailedPrecondition,
+ "Check failed: state_ == State::kVsync.");
+ }
+ state_ = State::kBuildStart;
+ build_start_ = build_start;
+ return fml::Status();
+}
+
+fml::Status FrameTimingsRecorder::RecordBuildEndImpl(fml::TimePoint build_end) {
+ std::scoped_lock state_lock(state_mutex_);
+ if (state_ != State::kBuildStart) {
+ return fml::Status(fml::StatusCode::kFailedPrecondition,
+ "Check failed: state_ == State::kBuildStart.");
+ }
+ state_ = State::kBuildEnd;
+ build_end_ = build_end;
+ return fml::Status();
+}
+
+fml::Status FrameTimingsRecorder::RecordRasterStartImpl(
+ fml::TimePoint raster_start) {
+ std::scoped_lock state_lock(state_mutex_);
+ if (state_ != State::kBuildEnd) {
+ return fml::Status(fml::StatusCode::kFailedPrecondition,
+ "Check failed: state_ == State::kBuildEnd.");
+ }
state_ = State::kRasterStart;
raster_start_ = raster_start;
+ return fml::Status();
}
FrameTiming FrameTimingsRecorder::RecordRasterEnd(const RasterCache* cache) {
diff --git a/flow/frame_timings.h b/flow/frame_timings.h
index 8d39bb6..76b9281 100644
--- a/flow/frame_timings.h
+++ b/flow/frame_timings.h
@@ -10,6 +10,7 @@
#include "flutter/common/settings.h"
#include "flutter/flow/raster_cache.h"
#include "flutter/fml/macros.h"
+#include "flutter/fml/status.h"
#include "flutter/fml/time/time_delta.h"
#include "flutter/fml/time/time_point.h"
@@ -114,6 +115,16 @@
FrameTiming GetRecordedTime() const;
private:
+ FML_FRIEND_TEST(FrameTimingsRecorderTest, ThrowWhenRecordBuildBeforeVsync);
+ FML_FRIEND_TEST(FrameTimingsRecorderTest,
+ ThrowWhenRecordRasterBeforeBuildEnd);
+
+ [[nodiscard]] fml::Status RecordVsyncImpl(fml::TimePoint vsync_start,
+ fml::TimePoint vsync_target);
+ [[nodiscard]] fml::Status RecordBuildStartImpl(fml::TimePoint build_start);
+ [[nodiscard]] fml::Status RecordBuildEndImpl(fml::TimePoint build_end);
+ [[nodiscard]] fml::Status RecordRasterStartImpl(fml::TimePoint raster_start);
+
static std::atomic<uint64_t> frame_number_gen_;
mutable std::mutex state_mutex_;
diff --git a/flow/frame_timings_recorder_unittests.cc b/flow/frame_timings_recorder_unittests.cc
index ab1ef1e..db3896c 100644
--- a/flow/frame_timings_recorder_unittests.cc
+++ b/flow/frame_timings_recorder_unittests.cc
@@ -2,21 +2,21 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <thread>
#include "flutter/flow/frame_timings.h"
#include "flutter/flow/testing/layer_test.h"
#include "flutter/flow/testing/mock_layer.h"
#include "flutter/flow/testing/mock_raster_cache.h"
#include "third_party/skia/include/core/SkPictureRecorder.h"
-#include <thread>
-
#include "flutter/fml/time/time_delta.h"
#include "flutter/fml/time/time_point.h"
#include "gtest/gtest.h"
namespace flutter {
-namespace testing {
+
+using testing::MockRasterCache;
TEST(FrameTimingsRecorderTest, RecordVsync) {
auto recorder = std::make_unique<FrameTimingsRecorder>();
@@ -130,9 +130,9 @@
auto recorder = std::make_unique<FrameTimingsRecorder>();
const auto build_start = fml::TimePoint::Now();
- EXPECT_EXIT(recorder->RecordBuildStart(build_start),
- ::testing::KilledBySignal(SIGABRT),
- "Check failed: state_ == State::kVsync.");
+ fml::Status status = recorder->RecordBuildStartImpl(build_start);
+ EXPECT_FALSE(status.ok());
+ EXPECT_EQ(status.message(), "Check failed: state_ == State::kVsync.");
}
TEST(FrameTimingsRecorderTest, ThrowWhenRecordRasterBeforeBuildEnd) {
@@ -143,9 +143,9 @@
recorder->RecordVsync(st, en);
const auto raster_start = fml::TimePoint::Now();
- EXPECT_EXIT(recorder->RecordRasterStart(raster_start),
- ::testing::KilledBySignal(SIGABRT),
- "Check failed: state_ == State::kBuildEnd.");
+ fml::Status status = recorder->RecordRasterStartImpl(raster_start);
+ EXPECT_FALSE(status.ok());
+ EXPECT_EQ(status.message(), "Check failed: state_ == State::kBuildEnd.");
}
#endif
@@ -297,5 +297,4 @@
ASSERT_EQ(actual_arg, expected_arg);
}
-} // namespace testing
} // namespace flutter
diff --git a/fml/macros.h b/fml/macros.h
index 0158d0e..7de4ddf 100644
--- a/fml/macros.h
+++ b/fml/macros.h
@@ -38,4 +38,7 @@
TypeName() = delete; \
FML_DISALLOW_COPY_ASSIGN_AND_MOVE(TypeName)
+#define FML_FRIEND_TEST(test_case_name, test_name) \
+ friend class test_case_name##_##test_name##_Test
+
#endif // FLUTTER_FML_MACROS_H_
diff --git a/testing/run_tests.py b/testing/run_tests.py
index 74ea48c..8fcf8b30 100755
--- a/testing/run_tests.py
+++ b/testing/run_tests.py
@@ -471,13 +471,16 @@
# flutter_desktop_darwin_unittests uses global state that isn't handled
# correctly by gtest-parallel.
# https://github.com/flutter/flutter/issues/104789
- run_engine_executable(
- build_dir,
- 'flutter_desktop_darwin_unittests',
- executable_filter,
- shuffle_flags,
- coverage=coverage
- )
+ if not os.path.basename(build_dir).startswith('host_debug'):
+ # Test is disabled for flaking in debug runs:
+ # https://github.com/flutter/flutter/issues/127441
+ run_engine_executable(
+ build_dir,
+ 'flutter_desktop_darwin_unittests',
+ executable_filter,
+ shuffle_flags,
+ coverage=coverage
+ )
extra_env = {
# pylint: disable=line-too-long
# See https://developer.apple.com/documentation/metal/diagnosing_metal_programming_issues_early?language=objc