|
25 | 25 | #import <Matter/Matter.h>
|
26 | 26 |
|
27 | 27 | #import "MTRCommandPayloadExtensions_Internal.h"
|
| 28 | +#import "MTRDeviceControllerLocalTestStorage.h" |
28 | 29 | #import "MTRDeviceTestDelegate.h"
|
29 | 30 | #import "MTRErrorTestUtils.h"
|
| 31 | +#import "MTRTestDeclarations.h" |
30 | 32 | #import "MTRTestKeys.h"
|
31 | 33 | #import "MTRTestResetCommissioneeHelper.h"
|
32 | 34 | #import "MTRTestStorage.h"
|
@@ -74,19 +76,6 @@ static void WaitForCommissionee(XCTestExpectation * expectation)
|
74 | 76 | return mConnectedDevice;
|
75 | 77 | }
|
76 | 78 |
|
77 |
| -#ifdef DEBUG |
78 |
| -@interface MTRBaseDevice (Test) |
79 |
| -- (void)failSubscribers:(dispatch_queue_t)queue completion:(void (^)(void))completion; |
80 |
| - |
81 |
| -// Test function for whitebox testing |
82 |
| -+ (id)CHIPEncodeAndDecodeNSObject:(id)object; |
83 |
| -@end |
84 |
| - |
85 |
| -@interface MTRDevice (Test) |
86 |
| -- (void)unitTestInjectEventReport:(NSArray<NSDictionary<NSString *, id> *> *)eventReport; |
87 |
| -@end |
88 |
| -#endif |
89 |
| - |
90 | 79 | @interface MTRDeviceTestDeviceControllerDelegate : NSObject <MTRDeviceControllerDelegate>
|
91 | 80 | @property (nonatomic, strong) XCTestExpectation * expectation;
|
92 | 81 | @end
|
@@ -129,10 +118,19 @@ @interface MTRDeviceTests : XCTestCase
|
129 | 118 |
|
130 | 119 | @implementation MTRDeviceTests
|
131 | 120 |
|
| 121 | +#if MTR_PER_CONTROLLER_STORAGE_ENABLED |
| 122 | +static BOOL slocalTestStorageEnabledBeforeUnitTest; |
| 123 | +#endif // MTR_PER_CONTROLLER_STORAGE_ENABLED |
| 124 | + |
132 | 125 | + (void)setUp
|
133 | 126 | {
|
134 | 127 | XCTestExpectation * pairingExpectation = [[XCTestExpectation alloc] initWithDescription:@"Pairing Complete"];
|
135 | 128 |
|
| 129 | +#if MTR_PER_CONTROLLER_STORAGE_ENABLED |
| 130 | + slocalTestStorageEnabledBeforeUnitTest = MTRDeviceControllerLocalTestStorage.localTestStorageEnabled; |
| 131 | + MTRDeviceControllerLocalTestStorage.localTestStorageEnabled = YES; |
| 132 | +#endif // MTR_PER_CONTROLLER_STORAGE_ENABLED |
| 133 | + |
136 | 134 | __auto_type * factory = [MTRDeviceControllerFactory sharedInstance];
|
137 | 135 | XCTAssertNotNil(factory);
|
138 | 136 |
|
@@ -182,6 +180,14 @@ + (void)tearDown
|
182 | 180 | {
|
183 | 181 | ResetCommissionee(GetConnectedDevice(), dispatch_get_main_queue(), nil, kTimeoutInSeconds);
|
184 | 182 |
|
| 183 | +#if MTR_PER_CONTROLLER_STORAGE_ENABLED |
| 184 | + // Restore testing setting to previous state, and remove all persisted attributes |
| 185 | + MTRDeviceControllerLocalTestStorage.localTestStorageEnabled = slocalTestStorageEnabledBeforeUnitTest; |
| 186 | + [sController.controllerDataStore clearAllStoredAttributes]; |
| 187 | + NSArray * storedAttributesAfterClear = [sController.controllerDataStore getStoredAttributesForNodeID:@(kDeviceId)]; |
| 188 | + XCTAssertEqual(storedAttributesAfterClear.count, 0); |
| 189 | +#endif // MTR_PER_CONTROLLER_STORAGE_ENABLED |
| 190 | + |
185 | 191 | MTRDeviceController * controller = sController;
|
186 | 192 | XCTAssertNotNil(controller);
|
187 | 193 | [controller shutdown];
|
@@ -1236,7 +1242,7 @@ - (void)test015_FailedSubscribeWithQueueAcrossShutdown
|
1236 | 1242 | __auto_type * params = [[MTRSubscribeParams alloc] init];
|
1237 | 1243 | params.resubscribeAutomatically = NO;
|
1238 | 1244 | params.replaceExistingSubscriptions = NO; // Not strictly needed, but checking that doing this does not
|
1239 |
| - // affect this subscription erroring out correctly. |
| 1245 | + // affect this subscription erroring out correctly. |
1240 | 1246 | [device subscribeWithQueue:queue
|
1241 | 1247 | minInterval:1
|
1242 | 1248 | maxInterval:2
|
@@ -1344,6 +1350,11 @@ - (void)test016_FailedSubscribeWithCacheReadDuringFailure
|
1344 | 1350 |
|
1345 | 1351 | - (void)test017_TestMTRDeviceBasics
|
1346 | 1352 | {
|
| 1353 | + // Ensure the test starts with clean slate, even with MTRDeviceControllerLocalTestStorage enabled |
| 1354 | + [sController.controllerDataStore clearAllStoredAttributes]; |
| 1355 | + NSArray * storedAttributesAfterClear = [sController.controllerDataStore getStoredAttributesForNodeID:@(kDeviceId)]; |
| 1356 | + XCTAssertEqual(storedAttributesAfterClear.count, 0); |
| 1357 | + |
1347 | 1358 | __auto_type * device = [MTRDevice deviceWithNodeID:kDeviceId deviceController:sController];
|
1348 | 1359 | dispatch_queue_t queue = dispatch_get_main_queue();
|
1349 | 1360 |
|
@@ -1526,6 +1537,7 @@ - (void)test017_TestMTRDeviceBasics
|
1526 | 1537 |
|
1527 | 1538 | // Resubscription test setup
|
1528 | 1539 | XCTestExpectation * subscriptionDroppedExpectation = [self expectationWithDescription:@"Subscription has dropped"];
|
| 1540 | + |
1529 | 1541 | delegate.onNotReachable = ^() {
|
1530 | 1542 | [subscriptionDroppedExpectation fulfill];
|
1531 | 1543 | };
|
@@ -1600,7 +1612,7 @@ - (void)test018_SubscriptionErrorWhenNotResubscribing
|
1600 | 1612 | MTRSubscribeParams * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(1) maxInterval:@(10)];
|
1601 | 1613 | params.resubscribeAutomatically = NO;
|
1602 | 1614 | params.replaceExistingSubscriptions = NO; // Not strictly needed, but checking that doing this does not
|
1603 |
| - // affect this subscription erroring out correctly. |
| 1615 | + // affect this subscription erroring out correctly. |
1604 | 1616 | __block BOOL subscriptionEstablished = NO;
|
1605 | 1617 | [device subscribeToAttributesWithEndpointID:@1
|
1606 | 1618 | clusterID:@6
|
@@ -2826,6 +2838,65 @@ - (void)test030_DeviceAndClusterProperties
|
2826 | 2838 | XCTAssertEqualObjects(cluster.endpointID, @(0));
|
2827 | 2839 | }
|
2828 | 2840 |
|
| 2841 | +#if MTR_PER_CONTROLLER_STORAGE_ENABLED |
| 2842 | +- (void)test031_MTRDeviceAttributeCacheLocalTestStorage |
| 2843 | +{ |
| 2844 | + dispatch_queue_t queue = dispatch_get_main_queue(); |
| 2845 | + |
| 2846 | + // First start with clean slate and |
| 2847 | + __auto_type * device = [MTRDevice deviceWithNodeID:@(kDeviceId) controller:sController]; |
| 2848 | + [sController removeDevice:device]; |
| 2849 | + [sController.controllerDataStore clearAllStoredAttributes]; |
| 2850 | + NSArray * storedAttributesAfterClear = [sController.controllerDataStore getStoredAttributesForNodeID:@(kDeviceId)]; |
| 2851 | + XCTAssertEqual(storedAttributesAfterClear.count, 0); |
| 2852 | + |
| 2853 | + // Now recreate device and get subscription primed |
| 2854 | + device = [MTRDevice deviceWithNodeID:@(kDeviceId) controller:sController]; |
| 2855 | + XCTestExpectation * gotReportsExpectation = [self expectationWithDescription:@"Attribute and Event reports have been received"]; |
| 2856 | + __auto_type * delegate = [[MTRDeviceTestDelegate alloc] init]; |
| 2857 | + __weak __auto_type weakDelegate = delegate; |
| 2858 | + delegate.onReportEnd = ^{ |
| 2859 | + [gotReportsExpectation fulfill]; |
| 2860 | + __strong __auto_type strongDelegate = weakDelegate; |
| 2861 | + strongDelegate.onReportEnd = nil; |
| 2862 | + }; |
| 2863 | + [device setDelegate:delegate queue:queue]; |
| 2864 | + |
| 2865 | + [self waitForExpectations:@[ gotReportsExpectation ] timeout:60]; |
| 2866 | + |
| 2867 | + NSUInteger attributesReportedWithFirstSubscription = [device unitTestAttributesReportedSinceLastCheck]; |
| 2868 | + |
| 2869 | + NSArray * dataStoreValuesAfterFirstSubscription = [sController.controllerDataStore getStoredAttributesForNodeID:@(kDeviceId)]; |
| 2870 | + XCTAssertTrue(dataStoreValuesAfterFirstSubscription.count > 0); |
| 2871 | + |
| 2872 | + // Now remove device, resubscribe, and see that it succeeds |
| 2873 | + [sController removeDevice:device]; |
| 2874 | + device = [MTRDevice deviceWithNodeID:@(kDeviceId) controller:sController]; |
| 2875 | + |
| 2876 | + XCTestExpectation * resubGotReportsExpectation = [self expectationWithDescription:@"Attribute and Event reports have been received for resubscription"]; |
| 2877 | + delegate.onReportEnd = ^{ |
| 2878 | + [resubGotReportsExpectation fulfill]; |
| 2879 | + __strong __auto_type strongDelegate = weakDelegate; |
| 2880 | + strongDelegate.onReportEnd = nil; |
| 2881 | + }; |
| 2882 | + [device setDelegate:delegate queue:queue]; |
| 2883 | + |
| 2884 | + [self waitForExpectations:@[ resubGotReportsExpectation ] timeout:60]; |
| 2885 | + |
| 2886 | + NSUInteger attributesReportedWithSecondSubscription = [device unitTestAttributesReportedSinceLastCheck]; |
| 2887 | + |
| 2888 | + XCTAssertTrue(attributesReportedWithSecondSubscription < attributesReportedWithFirstSubscription); |
| 2889 | + |
| 2890 | + // 1) MTRDevice actually gets some attributes reported more than once |
| 2891 | + // 2) Some attributes do change on resubscribe |
| 2892 | + // * With all-clusts-app as of 2024-02-10, out of 1287 persisted attributes, still 450 attributes were reported with filter |
| 2893 | + // And so conservatively, assert that data version filters save at least 300 entries. |
| 2894 | + NSArray * dataStoreValuesAfterSecondSubscription = [sController.controllerDataStore getStoredAttributesForNodeID:@(kDeviceId)]; |
| 2895 | + NSUInteger storedAttributeCountDifferenceFromMTRDeviceReport = dataStoreValuesAfterSecondSubscription.count - attributesReportedWithSecondSubscription; |
| 2896 | + XCTAssertTrue(storedAttributeCountDifferenceFromMTRDeviceReport > 300); |
| 2897 | +} |
| 2898 | +#endif // MTR_PER_CONTROLLER_STORAGE_ENABLED |
| 2899 | + |
2829 | 2900 | @end
|
2830 | 2901 |
|
2831 | 2902 | @interface MTRDeviceEncoderTests : XCTestCase
|
|
0 commit comments