Skip to content

Commit baa344c

Browse files
committed
Fix crash on concurrent RetrieveProductsInfo test. Wait for async retrieveProductsInfo execution before fireCallbacks() by DispatchGroup - groupFire
1 parent 219a4c7 commit baa344c

1 file changed

Lines changed: 22 additions & 9 deletions

File tree

Tests/SwiftyStoreKitTests/ProductsInfoControllerTests.swift

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -54,19 +54,29 @@ class TestInAppProductRequest: InAppProductRequest {
5454

5555
class TestInAppProductRequestBuilder: InAppProductRequestBuilder {
5656

57-
var requests: [ TestInAppProductRequest ] = []
57+
private var _requests: [TestInAppProductRequest] = []
58+
private let requestsQueue = DispatchQueue(label: "builderRequestsQueue", attributes: .concurrent)
59+
var requests: [ TestInAppProductRequest ] {
60+
get {
61+
requestsQueue.sync {
62+
_requests
63+
}
64+
}
65+
}
5866

5967
func request(productIds: Set<String>, callback: @escaping InAppProductRequestCallback) -> InAppProductRequest {
6068
let request = TestInAppProductRequest(productIds: productIds, callback: callback)
61-
requests.append(request)
69+
requestsQueue.sync(flags: .barrier) {
70+
_requests.append(request)
71+
}
6272
return request
6373
}
6474

6575
func fireCallbacks() {
6676
requests.forEach {
6777
$0.fireCallback()
6878
}
69-
requests = []
79+
_requests = []
7080
}
7181
}
7282

@@ -143,25 +153,28 @@ class ProductsInfoControllerTests: XCTestCase {
143153
// Create the expectation not to let the test finishes before the other threads complete
144154
let expectation = XCTestExpectation(description: "Expect downloads of product informations")
145155

146-
// Create the dispatch group to let the test verifies the assert only when
156+
// Create the dispatch groups to let the test verifies the assert only when
147157
// everything else finishes.
148-
let group = DispatchGroup()
158+
let groupCompletion = DispatchGroup()
159+
let groupFire = DispatchGroup()
149160

150161
// Dispatch a request for every product in a different thread
151162
for product in testProducts {
163+
groupCompletion.enter()
164+
groupFire.enter()
152165
DispatchQueue.global().async {
153-
group.enter()
154166
productInfoController.retrieveProductsInfo([product]) { _ in
155167
completionCallbackCount += 1
156-
group.leave()
168+
groupCompletion.leave()
157169
}
170+
groupFire.leave()
158171
}
159172
}
160-
DispatchQueue.global().asyncAfter(deadline: .now()+0.1) {
173+
groupFire.notify(queue: DispatchQueue.global()) {
161174
requestBuilder.fireCallbacks()
162175
}
163176
// Fullfil the expectation when every thread finishes
164-
group.notify(queue: DispatchQueue.global()) {
177+
groupCompletion.notify(queue: DispatchQueue.global()) {
165178

166179
XCTAssertEqual(completionCallbackCount, self.testProducts.count)
167180
expectation.fulfill()

0 commit comments

Comments
 (0)