From b886e60354b5d957667a03fc4cda94b2e218a1ea Mon Sep 17 00:00:00 2001 From: Chris Bracken Date: Mon, 21 Oct 2024 13:35:35 -0700 Subject: [PATCH] iOS: Reduce rerun flakes by eliminating timeouts When run repeatedly, some of the iOS unit tests can relatively easily blow their test timeouts. Since we're testing behaviour and not performance in these tests there's no need to enforce a particular timeout. The bots will fail if the tests timeout, regardless. Issue: https://github.com/flutter/flutter/issues/157231 --- .../framework/Source/FlutterChannelsTest.m | 4 +-- .../Source/FlutterPlatformPluginTest.mm | 36 +++++++++---------- .../Source/FlutterPlatformViewsTest.mm | 2 +- .../Source/FlutterViewControllerTest.mm | 10 +++--- .../framework/Source/SemanticsObjectTest.mm | 4 ++- .../ios/platform_message_handler_ios_test.mm | 6 ++-- 6 files changed, 32 insertions(+), 30 deletions(-) diff --git a/shell/platform/darwin/common/framework/Source/FlutterChannelsTest.m b/shell/platform/darwin/common/framework/Source/FlutterChannelsTest.m index bb8af64ad460e..b14c7af0b9a72 100644 --- a/shell/platform/darwin/common/framework/Source/FlutterChannelsTest.m +++ b/shell/platform/darwin/common/framework/Source/FlutterChannelsTest.m @@ -91,7 +91,7 @@ - (void)testMethodInvokeWithReply { XCTAssertEqual(FlutterMethodNotImplemented, result); }]; OCMVerifyAll(binaryMessenger); - [self waitForExpectationsWithTimeout:1.0 handler:nil]; + [self waitForExpectations:@[ didCallReply ]]; } - (void)testMethodMessageHandler { @@ -141,7 +141,7 @@ - (void)testCallMethodHandler { [didCallReply fulfill]; XCTAssertEqual(replyEnvelopeData, reply); }); - [self waitForExpectationsWithTimeout:1.0 handler:nil]; + [self waitForExpectations:@[ didCallHandler, didCallReply ]]; } - (void)testResize { diff --git a/shell/platform/darwin/ios/framework/Source/FlutterPlatformPluginTest.mm b/shell/platform/darwin/ios/framework/Source/FlutterPlatformPluginTest.mm index b6259e120cced..a8c9f004d5aa3 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterPlatformPluginTest.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterPlatformPluginTest.mm @@ -59,7 +59,7 @@ - (void)testSearchWebInvokedWithEscapedTerm { }; [mockPlugin handleMethodCall:methodCall result:result]; - [self waitForExpectationsWithTimeout:1 handler:nil]; + [self waitForExpectations:@[ invokeExpectation ]]; [mockApplication stopMocking]; } @@ -90,7 +90,7 @@ - (void)testSearchWebInvokedWithNonEscapedTerm { }; [mockPlugin handleMethodCall:methodCall result:result]; - [self waitForExpectationsWithTimeout:1 handler:nil]; + [self waitForExpectations:@[ invokeExpectation ]]; [mockApplication stopMocking]; } @@ -119,7 +119,7 @@ - (void)testLookUpCallInitiated { [presentExpectation fulfill]; }; [mockPlugin handleMethodCall:methodCall result:result]; - [self waitForExpectationsWithTimeout:2 handler:nil]; + [self waitForExpectations:@[ presentExpectation ]]; } - (void)testShareScreenInvoked { @@ -151,7 +151,7 @@ - (void)testShareScreenInvoked { [presentExpectation fulfill]; }; [mockPlugin handleMethodCall:methodCall result:result]; - [self waitForExpectationsWithTimeout:1 handler:nil]; + [self waitForExpectations:@[ presentExpectation ]]; } - (void)testShareScreenInvokedOnIPad { @@ -186,7 +186,7 @@ - (void)testShareScreenInvokedOnIPad { [presentExpectation fulfill]; }; [mockPlugin handleMethodCall:methodCall result:result]; - [self waitForExpectationsWithTimeout:1 handler:nil]; + [self waitForExpectations:@[ presentExpectation ]]; } - (void)testClipboardHasCorrectStrings { @@ -202,7 +202,7 @@ - (void)testClipboardHasCorrectStrings { [FlutterMethodCall methodCallWithMethodName:@"Clipboard.setData" arguments:@{@"text" : @"some string"}]; [plugin handleMethodCall:methodCallSet result:resultSet]; - [self waitForExpectationsWithTimeout:1 handler:nil]; + [self waitForExpectations:@[ setStringExpectation ]]; XCTestExpectation* hasStringsExpectation = [self expectationWithDescription:@"hasStrings"]; FlutterResult result = ^(id result) { @@ -212,7 +212,7 @@ - (void)testClipboardHasCorrectStrings { FlutterMethodCall* methodCall = [FlutterMethodCall methodCallWithMethodName:@"Clipboard.hasStrings" arguments:nil]; [plugin handleMethodCall:methodCall result:result]; - [self waitForExpectationsWithTimeout:1 handler:nil]; + [self waitForExpectations:@[ hasStringsExpectation ]]; XCTestExpectation* getDataExpectation = [self expectationWithDescription:@"getData"]; FlutterResult getDataResult = ^(id result) { @@ -222,7 +222,7 @@ - (void)testClipboardHasCorrectStrings { FlutterMethodCall* methodCallGetData = [FlutterMethodCall methodCallWithMethodName:@"Clipboard.getData" arguments:@"text/plain"]; [plugin handleMethodCall:methodCallGetData result:getDataResult]; - [self waitForExpectationsWithTimeout:1 handler:nil]; + [self waitForExpectations:@[ getDataExpectation ]]; } - (void)testClipboardSetDataToNullDoNotCrash { @@ -247,7 +247,7 @@ - (void)testClipboardSetDataToNullDoNotCrash { FlutterMethodCall* methodCall = [FlutterMethodCall methodCallWithMethodName:@"Clipboard.getData" arguments:@"text/plain"]; [plugin handleMethodCall:methodCall result:result]; - [self waitForExpectationsWithTimeout:1 handler:nil]; + [self waitForExpectations:@[ setStringExpectation, getDataExpectation ]]; } - (void)testPopSystemNavigator { @@ -271,7 +271,7 @@ - (void)testPopSystemNavigator { FlutterMethodCall* methodCallSet = [FlutterMethodCall methodCallWithMethodName:@"SystemNavigator.pop" arguments:@(YES)]; [plugin handleMethodCall:methodCallSet result:resultSet]; - [self waitForExpectationsWithTimeout:1 handler:nil]; + [self waitForExpectations:@[ navigationPopCalled ]]; OCMVerify([navigationControllerMock popViewControllerAnimated:YES]); [flutterViewController deregisterNotifications]; @@ -291,7 +291,7 @@ - (void)testWhetherDeviceHasLiveTextInputInvokeCorrectly { [invokeExpectation fulfill]; }; [mockPlugin handleMethodCall:methodCall result:result]; - [self waitForExpectationsWithTimeout:1 handler:nil]; + [self waitForExpectations:@[ invokeExpectation ]]; } - (void)testViewControllerBasedStatusBarHiddenUpdate { @@ -318,7 +318,7 @@ - (void)testViewControllerBasedStatusBarHiddenUpdate { [FlutterMethodCall methodCallWithMethodName:@"SystemChrome.setEnabledSystemUIOverlays" arguments:@[ @"SystemUiOverlay.bottom" ]]; [plugin handleMethodCall:methodCallSet result:resultSet]; - [self waitForExpectationsWithTimeout:1 handler:nil]; + [self waitForExpectations:@[ enableSystemUIOverlaysCalled ]]; XCTAssertTrue(flutterViewController.prefersStatusBarHidden); // Update to shown. @@ -331,7 +331,7 @@ - (void)testViewControllerBasedStatusBarHiddenUpdate { [FlutterMethodCall methodCallWithMethodName:@"SystemChrome.setEnabledSystemUIOverlays" arguments:@[ @"SystemUiOverlay.top" ]]; [plugin handleMethodCall:methodCallSet2 result:resultSet2]; - [self waitForExpectationsWithTimeout:1 handler:nil]; + [self waitForExpectations:@[ enableSystemUIOverlaysCalled2 ]]; XCTAssertFalse(flutterViewController.prefersStatusBarHidden); [flutterViewController deregisterNotifications]; @@ -356,7 +356,7 @@ - (void)testViewControllerBasedStatusBarHiddenUpdate { [FlutterMethodCall methodCallWithMethodName:@"SystemChrome.setEnabledSystemUIMode" arguments:@"SystemUiMode.immersive"]; [plugin handleMethodCall:methodCallSet result:resultSet]; - [self waitForExpectationsWithTimeout:1 handler:nil]; + [self waitForExpectations:@[ enableSystemUIModeCalled ]]; XCTAssertTrue(flutterViewController.prefersStatusBarHidden); // Update to shown. @@ -369,7 +369,7 @@ - (void)testViewControllerBasedStatusBarHiddenUpdate { [FlutterMethodCall methodCallWithMethodName:@"SystemChrome.setEnabledSystemUIMode" arguments:@"SystemUiMode.edgeToEdge"]; [plugin handleMethodCall:methodCallSet2 result:resultSet2]; - [self waitForExpectationsWithTimeout:1 handler:nil]; + [self waitForExpectations:@[ enableSystemUIModeCalled2 ]]; XCTAssertFalse(flutterViewController.prefersStatusBarHidden); [flutterViewController deregisterNotifications]; @@ -402,7 +402,7 @@ - (void)testStatusBarHiddenUpdate { [FlutterMethodCall methodCallWithMethodName:@"SystemChrome.setEnabledSystemUIOverlays" arguments:@[ @"SystemUiOverlay.bottom" ]]; [plugin handleMethodCall:methodCallSet result:resultSet]; - [self waitForExpectationsWithTimeout:1 handler:nil]; + [self waitForExpectations:@[ enableSystemUIOverlaysCalled ]]; #if not APPLICATION_EXTENSION_API_ONLY OCMVerify([mockApplication setStatusBarHidden:YES]); #endif @@ -417,7 +417,7 @@ - (void)testStatusBarHiddenUpdate { [FlutterMethodCall methodCallWithMethodName:@"SystemChrome.setEnabledSystemUIOverlays" arguments:@[ @"SystemUiOverlay.top" ]]; [plugin handleMethodCall:methodCallSet2 result:resultSet2]; - [self waitForExpectationsWithTimeout:1 handler:nil]; + [self waitForExpectations:@[ enableSystemUIOverlaysCalled2 ]]; #if not APPLICATION_EXTENSION_API_ONLY OCMVerify([mockApplication setStatusBarHidden:NO]); #endif @@ -451,7 +451,7 @@ - (void)testStatusBarStyle { [FlutterMethodCall methodCallWithMethodName:@"SystemChrome.setSystemUIOverlayStyle" arguments:@{@"statusBarBrightness" : @"Brightness.dark"}]; [plugin handleMethodCall:methodCallSet result:resultSet]; - [self waitForExpectationsWithTimeout:1 handler:nil]; + [self waitForExpectations:@[ enableSystemUIModeCalled ]]; #if not APPLICATION_EXTENSION_API_ONLY OCMVerify([mockApplication setStatusBarStyle:UIStatusBarStyleLightContent]); diff --git a/shell/platform/darwin/ios/framework/Source/FlutterPlatformViewsTest.mm b/shell/platform/darwin/ios/framework/Source/FlutterPlatformViewsTest.mm index 904a3eace2564..97b5c49b86ddf 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterPlatformViewsTest.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterPlatformViewsTest.mm @@ -3587,7 +3587,7 @@ - (void)testDisposingViewInCompositionOrderDoNotCrash { flutterPlatformViewsController->OnMethodCall( [FlutterMethodCall methodCallWithMethodName:@"dispose" arguments:@0], disposeResult); - [self waitForExpectationsWithTimeout:30 handler:nil]; + [self waitForExpectations:@[ expectation ]]; const SkImageInfo image_info = SkImageInfo::MakeN32Premul(1000, 1000); sk_sp mock_sk_surface = SkSurfaces::Raster(image_info); diff --git a/shell/platform/darwin/ios/framework/Source/FlutterViewControllerTest.mm b/shell/platform/darwin/ios/framework/Source/FlutterViewControllerTest.mm index 0dede34e2e94a..6b7d9aafe4a4b 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterViewControllerTest.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterViewControllerTest.mm @@ -530,7 +530,7 @@ - (void)testKeyboardAnimationWillWaitUIThreadVsync { }; CFTimeInterval startTime = CACurrentMediaTime(); [viewController setUpKeyboardAnimationVsyncClient:callback]; - [self waitForExpectationsWithTimeout:5.0 handler:nil]; + [self waitForExpectations:@[ expectation ]]; XCTAssertTrue(fulfillTime - startTime > delayTime); } @@ -754,7 +754,7 @@ - (void)testHandleKeyboardNotification { [viewControllerMock handleKeyboardNotification:notification]; XCTAssertTrue(viewControllerMock.targetViewInsetBottom == 320 * screen.scale); OCMVerify([viewControllerMock startKeyBoardAnimation:0.25]); - [self waitForExpectationsWithTimeout:5.0 handler:nil]; + [self waitForExpectations:@[ expectation ]]; } - (void)testEnsureBottomInsetIsZeroWhenKeyboardDismissed { @@ -1661,7 +1661,7 @@ - (void)testWillDeallocNotification { XCTAssertNotNil(realVC); realVC = nil; } - [self waitForExpectations:@[ expectation ] timeout:1.0]; + [self waitForExpectations:@[ expectation ]]; } - (void)testReleasesKeyboardManagerOnDealloc { @@ -1943,7 +1943,7 @@ - (void)testLifeCycleNotificationBecameActive { OCMVerify([mockVC goToApplicationLifecycle:@"AppLifecycleState.resumed"]); [flutterViewController deregisterNotifications]; }); - [self waitForExpectationsWithTimeout:5.0 handler:nil]; + [self waitForExpectations:@[ timeoutApplicationLifeCycle ]]; } - (void)testLifeCycleNotificationWillResignActive { @@ -2088,7 +2088,7 @@ - (void)testLifeCycleNotificationCancelledInvalidResumed { [timeoutApplicationLifeCycle fulfill]; [flutterViewController deregisterNotifications]; }); - [self waitForExpectationsWithTimeout:5.0 handler:nil]; + [self waitForExpectations:@[ timeoutApplicationLifeCycle ]]; } - (void)testSetupKeyboardAnimationVsyncClientWillCreateNewVsyncClientForFlutterViewController { diff --git a/shell/platform/darwin/ios/framework/Source/SemanticsObjectTest.mm b/shell/platform/darwin/ios/framework/Source/SemanticsObjectTest.mm index e95078a419cd6..800d294bc8d1f 100644 --- a/shell/platform/darwin/ios/framework/Source/SemanticsObjectTest.mm +++ b/shell/platform/darwin/ios/framework/Source/SemanticsObjectTest.mm @@ -1149,7 +1149,9 @@ - (void)testTextInputSemanticsObject_editActions { [partialSemanticsObject selectAll:nil]; [partialSemanticsObject delete:nil]; - [self waitForExpectationsWithTimeout:1 handler:nil]; + [self waitForExpectations:@[ + copyExpectation, cutExpectation, pasteExpectation, selectAllExpectation, deleteExpectation + ]]; } @end diff --git a/shell/platform/darwin/ios/platform_message_handler_ios_test.mm b/shell/platform/darwin/ios/platform_message_handler_ios_test.mm index b1e59dd4ad157..6f22c4bafcf9a 100644 --- a/shell/platform/darwin/ios/platform_message_handler_ios_test.mm +++ b/shell/platform/darwin/ios/platform_message_handler_ios_test.mm @@ -72,7 +72,7 @@ TaskRunners task_runners( auto platform_message = std::make_unique(channel, response); handler->HandlePlatformMessage(std::move(platform_message)); }); - [self waitForExpectationsWithTimeout:1.0 handler:nil]; + [self waitForExpectations:@[ didCallReply ]]; XCTAssertTrue(response->is_complete()); } @@ -100,7 +100,7 @@ TaskRunners task_runners( handler->HandlePlatformMessage(std::move(platform_message)); [didCallMessage fulfill]; }); - [self waitForExpectationsWithTimeout:1.0 handler:nil]; + [self waitForExpectations:@[ didCallMessage ]]; XCTAssertTrue(response->is_complete()); } @@ -128,7 +128,7 @@ TaskRunners task_runners( auto platform_message = std::make_unique(channel, response); handler->HandlePlatformMessage(std::move(platform_message)); }); - [self waitForExpectationsWithTimeout:1.0 handler:nil]; + [self waitForExpectations:@[ didCallReply ]]; XCTAssertTrue(response->is_complete()); } @end