@@ -2269,6 +2269,7 @@ - (void)doTestSubscriptionPoolWithSize:(NSInteger)subscriptionPoolSize deviceOnb
2269
2269
XCTAssertNotNil (factory);
2270
2270
2271
2271
__auto_type queue = dispatch_get_main_queue ();
2272
+ // __auto_type queue = dispatch_queue_create("test.subscription.pool", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL);
2272
2273
2273
2274
__auto_type * rootKeys = [[MTRTestKeys alloc ] init ];
2274
2275
XCTAssertNotNil (rootKeys);
@@ -2307,6 +2308,24 @@ - (void)doTestSubscriptionPoolWithSize:(NSInteger)subscriptionPoolSize deviceOnb
2307
2308
[self commissionWithController: controller newNodeID: deviceID onboardingPayload: deviceOnboardingPayloads[deviceID]];
2308
2309
}
2309
2310
2311
+ // Shutdown and restart, to reset all existing sessions, so that the subscriptions and base device usage start after
2312
+ [controller shutdown ];
2313
+ XCTAssertFalse ([controller isRunning ]);
2314
+
2315
+ controller = [self startControllerWithRootKeys: rootKeys
2316
+ operationalKeys: operationalKeys
2317
+ fabricID: fabricID
2318
+ nodeID: nodeID
2319
+ storage: storageDelegate
2320
+ error: &error
2321
+ certificateIssuer: &certificateIssuer
2322
+ concurrentSubscriptionPoolSize: subscriptionPoolSize];
2323
+ XCTAssertNil (error);
2324
+ XCTAssertNotNil (controller);
2325
+ XCTAssertTrue ([controller isRunning ]);
2326
+
2327
+ XCTAssertEqualObjects (controller.controllerNodeID , nodeID);
2328
+
2310
2329
// Set up expectations and delegates
2311
2330
2312
2331
NSDictionary <NSNumber *, XCTestExpectation *> * subscriptionExpectations = @{
@@ -2329,6 +2348,7 @@ - (void)doTestSubscriptionPoolWithSize:(NSInteger)subscriptionPoolSize deviceOnb
2329
2348
__block os_unfair_lock counterLock = OS_UNFAIR_LOCK_INIT;
2330
2349
__block NSUInteger subscriptionRunningCount = 0 ;
2331
2350
__block NSUInteger subscriptionDequeueCount = 0 ;
2351
+ __block BOOL baseDeviceReadCompleted = NO ;
2332
2352
2333
2353
for (NSNumber * deviceID in orderedDeviceIDs) {
2334
2354
MTRDeviceTestDelegate * delegate = deviceDelegates[deviceID];
@@ -2347,6 +2367,14 @@ - (void)doTestSubscriptionPoolWithSize:(NSInteger)subscriptionPoolSize deviceOnb
2347
2367
// Stop counting subscribing right before calling work item completion
2348
2368
os_unfair_lock_lock (&counterLock);
2349
2369
subscriptionRunningCount--;
2370
+
2371
+ // Given the base device read is happening on the 5th device, at the completion
2372
+ // time of the first [pool size] subscriptions, the BaseDevice's request to
2373
+ // read can't have completed, as it should be gated on its call to the
2374
+ // MTRDeviceController's getSessionForNode: call.
2375
+ if (subscriptionDequeueCount <= (orderedDeviceIDs.count - subscriptionPoolSize)) {
2376
+ XCTAssertFalse (baseDeviceReadCompleted);
2377
+ }
2350
2378
os_unfair_lock_unlock (&counterLock);
2351
2379
};
2352
2380
__weak __auto_type weakDelegate = delegate;
@@ -2363,8 +2391,26 @@ - (void)doTestSubscriptionPoolWithSize:(NSInteger)subscriptionPoolSize deviceOnb
2363
2391
[device setDelegate: deviceDelegates[deviceID] queue: queue];
2364
2392
}
2365
2393
2394
+ // Create the base device to attempt to read from the 5th device
2395
+ __auto_type * baseDeviceReadExpectation = [self expectationWithDescription: @" BaseDevice read" ];
2396
+ // Dispatch async to get around XCTest, so that this runs after the above devices queue their subscriptions
2397
+ dispatch_async (queue, ^{
2398
+ __auto_type * baseDevice = [MTRBaseDevice deviceWithNodeID: @(105 ) controller: controller];
2399
+ __auto_type * onOffCluster = [[MTRBaseClusterOnOff alloc ] initWithDevice: baseDevice endpointID: @(1 ) queue: queue];
2400
+ [onOffCluster readAttributeOnOffWithCompletion: ^(NSNumber * value, NSError * _Nullable error) {
2401
+ XCTAssertNil (error);
2402
+ // We expect the device to be off.
2403
+ XCTAssertEqualObjects (value, @(0 ));
2404
+ [baseDeviceReadExpectation fulfill ];
2405
+ os_unfair_lock_lock (&counterLock);
2406
+ baseDeviceReadCompleted = YES ;
2407
+ os_unfair_lock_unlock (&counterLock);
2408
+ }];
2409
+ });
2410
+
2366
2411
// Make the wait time depend on pool size and device count (can expand number of devices in the future)
2367
- [self waitForExpectations: subscriptionExpectations.allValues timeout: (kSubscriptionPoolBaseTimeoutInSeconds * orderedDeviceIDs.count / subscriptionPoolSize)];
2412
+ NSArray * expectationsToWait = [subscriptionExpectations.allValues arrayByAddingObject: baseDeviceReadExpectation];
2413
+ [self waitForExpectations: expectationsToWait timeout: (kSubscriptionPoolBaseTimeoutInSeconds * orderedDeviceIDs.count / subscriptionPoolSize)];
2368
2414
2369
2415
XCTAssertEqual (subscriptionDequeueCount, orderedDeviceIDs.count );
2370
2416
0 commit comments