From d96e5fe05cce114bc6f9540a48b4816e8899e24e Mon Sep 17 00:00:00 2001 From: Jeff Tung <100387939+jtung-apple@users.noreply.github.com> Date: Fri, 1 Sep 2023 15:25:43 -0700 Subject: [PATCH] Fix unit tests --- .../Framework/CHIPTests/MTRDeviceTests.m | 48 +++++++++++-------- 1 file changed, 29 insertions(+), 19 deletions(-) diff --git a/src/darwin/Framework/CHIPTests/MTRDeviceTests.m b/src/darwin/Framework/CHIPTests/MTRDeviceTests.m index 0d9b693296bc2d..1b3eb277d5133d 100644 --- a/src/darwin/Framework/CHIPTests/MTRDeviceTests.m +++ b/src/darwin/Framework/CHIPTests/MTRDeviceTests.m @@ -118,19 +118,19 @@ - (void)controller:(MTRDeviceController *)controller commissioningComplete:(NSEr typedef void (^MTRDeviceTestDelegateDataHandler)(NSArray *> *); @interface MTRDeviceTestDelegate : NSObject -@property (nonatomic) dispatch_block_t onSubscriptionEstablished; +@property (nonatomic) dispatch_block_t onReachable; +@property (nonatomic, nullable) dispatch_block_t onNotReachable; @property (nonatomic, nullable) MTRDeviceTestDelegateDataHandler onAttributeDataReceived; @property (nonatomic, nullable) MTRDeviceTestDelegateDataHandler onEventDataReceived; -@property (nonatomic, nullable) dispatch_block_t onSubscriptionDropped; @end @implementation MTRDeviceTestDelegate - (void)device:(MTRDevice *)device stateChanged:(MTRDeviceState)state { if (state == MTRDeviceStateReachable) { - self.onSubscriptionEstablished(); - } else if (state == MTRDeviceStateUnknown && self.onSubscriptionDropped != nil) { - self.onSubscriptionDropped(); + self.onReachable(); + } else if (state != MTRDeviceStateReachable && self.onNotReachable != nil) { + self.onNotReachable(); } } @@ -1423,10 +1423,11 @@ - (void)test017_TestMTRDeviceBasics __auto_type * device = [MTRDevice deviceWithNodeID:kDeviceId deviceController:sController]; dispatch_queue_t queue = dispatch_get_main_queue(); + // Given reachable state becomes true before XCTestExpectation * subscriptionExpectation = [self expectationWithDescription:@"Subscription has been set up"]; __auto_type * delegate = [[MTRDeviceTestDelegate alloc] init]; - delegate.onSubscriptionEstablished = ^() { + delegate.onReachable = ^() { [subscriptionExpectation fulfill]; }; @@ -1435,6 +1436,10 @@ - (void)test017_TestMTRDeviceBasics attributeReportsReceived += data.count; }; + // This is dependent on current implementation that priming reports send attributes and events in that order, and also that + // events in this test would fit in one report. So receiving events would mean all attributes and events have been received, and + // can satisfy the test below. + XCTestExpectation * gotReportsExpectation = [self expectationWithDescription:@"Attribute and Event reports have been received"]; __block unsigned eventReportsReceived = 0; delegate.onEventDataReceived = ^(NSArray *> * eventReport) { eventReportsReceived += eventReport.count; @@ -1451,6 +1456,7 @@ - (void)test017_TestMTRDeviceBasics XCTAssertNotNil(eventDict[MTREventTimestampDateKey]); } } + [gotReportsExpectation fulfill]; }; [device setDelegate:delegate queue:queue]; @@ -1481,7 +1487,7 @@ - (void)test017_TestMTRDeviceBasics [device readAttributeWithEndpointID:@(1) clusterID:@(MTRClusterIDTypeLevelControlID) attributeID:@(4) params:nil]; [device readAttributeWithEndpointID:@(1) clusterID:@(MTRClusterIDTypeLevelControlID) attributeID:@(4) params:nil]; - [self waitForExpectations:@[ subscriptionExpectation ] timeout:60]; + [self waitForExpectations:@[ subscriptionExpectation, gotReportsExpectation ] timeout:60]; XCTAssertNotEqual(attributeReportsReceived, 0); XCTAssertNotEqual(eventReportsReceived, 0); @@ -1489,16 +1495,6 @@ - (void)test017_TestMTRDeviceBasics attributeReportsReceived = 0; eventReportsReceived = 0; - XCTestExpectation * resubscriptionExpectation = [self expectationWithDescription:@"Resubscription has happened"]; - delegate.onSubscriptionEstablished = ^() { - [resubscriptionExpectation fulfill]; - }; - - XCTestExpectation * subscriptionDroppedExpectation = [self expectationWithDescription:@"Subscription has dropped"]; - delegate.onSubscriptionDropped = ^() { - [subscriptionDroppedExpectation fulfill]; - }; - // Before resubscribe, first test write failure and expected value effects NSNumber * testEndpointID = @(1); NSNumber * testClusterID = @(8); @@ -1547,11 +1543,25 @@ - (void)test017_TestMTRDeviceBasics [device readAttributeWithEndpointID:testEndpointID clusterID:testClusterID attributeID:testAttributeID params:nil]; [self waitForExpectations:@[ attributeReportErrorExpectation ] timeout:10]; + // Resubscription test setup + XCTestExpectation * subscriptionDroppedExpectation = [self expectationWithDescription:@"Subscription has dropped"]; + delegate.onNotReachable = ^() { + [subscriptionDroppedExpectation fulfill]; + }; + XCTestExpectation * resubscriptionExpectation = [self expectationWithDescription:@"Resubscription has happened"]; + delegate.onReachable = ^() { + [resubscriptionExpectation fulfill]; + }; + // reset the onAttributeDataReceived to validate the following resubscribe test delegate.onAttributeDataReceived = ^(NSArray *> * data) { attributeReportsReceived += data.count; }; + delegate.onEventDataReceived = ^(NSArray *> * eventReport) { + eventReportsReceived += eventReport.count; + }; + // Now trigger another subscription which will cause ours to drop; we should re-subscribe after that. MTRBaseDevice * baseDevice = GetConnectedDevice(); __auto_type params = [[MTRSubscribeParams alloc] initWithMinInterval:@(1) maxInterval:@(10)]; @@ -1580,9 +1590,9 @@ - (void)test017_TestMTRDeviceBasics // Now make sure we ignore later tests. Ideally we would just unsubscribe // or remove the delegate, but there's no good way to do that. - delegate.onSubscriptionEstablished = ^() { + delegate.onReachable = ^() { }; - delegate.onSubscriptionDropped = nil; + delegate.onNotReachable = nil; delegate.onAttributeDataReceived = nil; delegate.onEventDataReceived = nil;