diff --git a/Split/Storage/Splits/SplitsStorage.swift b/Split/Storage/Splits/SplitsStorage.swift index 81acd939..e4b978f5 100644 --- a/Split/Storage/Splits/SplitsStorage.swift +++ b/Split/Storage/Splits/SplitsStorage.swift @@ -169,7 +169,6 @@ class DefaultSplitsStorage: SplitsStorage { segmentsInUse += 1 } else if inMemorySplits.value(forKey: splitName) != nil && !active { // If known Split and archived segmentsInUse -= 1 - } } diff --git a/SplitTests/Integration/streaming/MySegmentUpdateTest.swift b/SplitTests/Integration/streaming/MySegmentUpdateTest.swift index 66ea4532..fd1175c0 100644 --- a/SplitTests/Integration/streaming/MySegmentUpdateTest.swift +++ b/SplitTests/Integration/streaming/MySegmentUpdateTest.swift @@ -385,6 +385,97 @@ class MySegmentUpdateTest: XCTestCase { destroy(client) } } + + func testSdkRestartMembershipsSyncIfNewFlag() throws { + + var sdkReadyFired = false + var cacheReadyFired = true + let sdkReady = XCTestExpectation(description: "SDK should be ready") + let cacheReadyExp = XCTestExpectation(description: "Cache should be ready") + let segmentsHit = XCTestExpectation(description: "/memberships should be hit at least once") + var membershipsHit = 0 + + var json = IntegrationHelper.loadSplitChangeFileJson(name: "splitschanges_no_segments", sourceClass: IntegrationHelper()) // no Segments + + // 1. Configure dispatcher + let dispatcher: HttpClientTestDispatcher = { request in + if request.url.absoluteString.contains("/splitChanges") { + return TestDispatcherResponse(code: 200, data: Data(json!.utf8)) + } + + if request.url.absoluteString.contains("/memberships") { + segmentsHit.fulfill() + membershipsHit += 1 + return TestDispatcherResponse(code: 200, data: Data(IntegrationHelper.emptyMySegments.utf8)) + } + + return TestDispatcherResponse(code: 200) + } + + // 2. Setup Factory, Network & Client + let splitConfig: SplitClientConfig = SplitClientConfig() + splitConfig.featuresRefreshRate = 5 + splitConfig.segmentsRefreshRate = 5 + splitConfig.impressionRefreshRate = 30 + splitConfig.sdkReadyTimeOut = 60000 + splitConfig.eventsPerPush = 10 + splitConfig.streamingEnabled = false + splitConfig.eventsQueueSize = 100 + splitConfig.eventsPushRate = 999999 + splitConfig.eventsFirstPushWindow = 999 + splitConfig.impressionsMode = "DEBUG" + splitConfig.serviceEndpoints = ServiceEndpoints.builder() + .set(sdkEndpoint: "localhost").set(eventsEndpoint: "localhost").build() + + let splitDatabase = TestingHelper.createTestDatabase(name: "ready_from_cache_test") + splitDatabase.generalInfoDao.update(info: .flagsSpec, stringValue: "1.3") + + let userKey = "test-user-key" + let key: Key = Key(matchingKey: userKey, bucketingKey: nil) + let session = HttpSessionMock() + let reqManager = HttpRequestManagerTestDispatcher(dispatcher: dispatcher, streamingHandler: buildStreamingHandler()) + httpClient = DefaultHttpClient(session: session, requestManager: reqManager) + let builder = DefaultSplitFactoryBuilder() + + _ = builder.setTestDatabase(splitDatabase) + _ = builder.setHttpClient(httpClient) + var factory = builder.setApiKey(apiKey).setKey(key).setConfig(splitConfig).build() + let client = factory?.client + + client?.on(event: .sdkReady) { + sdkReadyFired = true + sdkReady.fulfill() + } + + client?.on(event: .sdkReadyFromCache) { + cacheReadyExp.fulfill() + cacheReadyFired = true + } + + wait(for: [segmentsHit], timeout: 3) + XCTAssertEqual(sdkReadyFired, false) + + wait(for: [cacheReadyExp, sdkReady], timeout: 4) + + // MARK: Key part + var waitExp = XCTestExpectation(description: "Just waiting") + waitExp.isInverted = true // Inverted expectation + wait(for: [waitExp], timeout: 10) + XCTAssertEqual(membershipsHit, 1, "After some time, if segments are not used, SDK shouldn't hit /memberships") + + // MARK: Key part 2 + json = IntegrationHelper.loadSplitChangeFileJson(name: "splitchanges_1", sourceClass: IntegrationHelper()) // splitChanges, now WITH Segments + + waitExp = XCTestExpectation(description: "Just waiting") + waitExp.isInverted = true // Inverted expectation + wait(for: [waitExp], timeout: 15) + XCTAssertGreaterThan(membershipsHit, 2, "If new flags with segments arrive, the mechanism should be restarted and SDK should hit /memberships many times again") + + // Cleanup + if let client = client { + destroy(client) + } + } func testMySegmentsUpdateBounded() throws { try mySegmentsUpdateBoundedTest(type: .mySegmentsUpdate) diff --git a/SplitTests/Resources/splitschanges_no_segments.json b/SplitTests/Resources/splitschanges_no_segments.json index 3544cb2f..6feaf780 100644 --- a/SplitTests/Resources/splitschanges_no_segments.json +++ b/SplitTests/Resources/splitschanges_no_segments.json @@ -2,7 +2,7 @@ "d":[ { "trafficTypeName":"account", - "name":"FACUNDO_TEST", + "name":"NEW_FACUNDO_TEST", "trafficAllocation":59, "trafficAllocationSeed":-2108186082, "seed":-1947050785, @@ -117,7 +117,7 @@ }, { "trafficTypeName":"account", - "name":"testing", + "name":"NEW_testing", "trafficAllocation":100, "trafficAllocationSeed":527505678, "seed":-1716462249, @@ -229,7 +229,7 @@ }, { "trafficTypeName":"account", - "name":"testing222", + "name":"NEW_testing222", "trafficAllocation":100, "trafficAllocationSeed":-397360967, "seed":1058132210, @@ -281,7 +281,7 @@ }, { "trafficTypeName":"account", - "name":"a_new_split_2", + "name":"NEW_a_new_split_2", "trafficAllocation":99, "trafficAllocationSeed":-1349440646, "seed":-1536389703, @@ -574,7 +574,7 @@ }, { "trafficTypeName":"account", - "name":"test_string_without_attr", + "name":"NEW_test_string_without_attr", "trafficAllocation":100, "trafficAllocationSeed":-782597068, "seed":-1682478887, @@ -643,7 +643,7 @@ }, { "trafficTypeName":"user", - "name":"OldTest", + "name":"NEW_OldTest", "trafficAllocation":100, "trafficAllocationSeed":217539832, "seed":52164426, @@ -826,7 +826,7 @@ }, { "trafficTypeName":"account", - "name":"Test_Save_1", + "name":"NEW_Test_Save_1", "trafficAllocation":100, "trafficAllocationSeed":-257595325, "seed":-665945237, @@ -975,7 +975,7 @@ }, { "trafficTypeName":"account", - "name":"TEST", + "name":"NEW_TEST", "trafficAllocation":100, "trafficAllocationSeed":-673356676, "seed":-511119211, @@ -1023,7 +1023,7 @@ }, { "trafficTypeName":"user", - "name":"benchmark_jw_1", + "name":"NEW_benchmark_jw_1", "trafficAllocation":100, "trafficAllocationSeed":987354894, "seed":1292874260, @@ -1109,7 +1109,7 @@ }, { "trafficTypeName":"user", - "name":"nico_tests", + "name":"NEW_nico_tests", "trafficAllocation":100, "trafficAllocationSeed":1409699192, "seed":-1997241870, @@ -1190,7 +1190,7 @@ }, { "trafficTypeName":"account", - "name":"testo2222", + "name":"NEW_testo2222", "trafficAllocation":100, "trafficAllocationSeed":1164474086, "seed":1270508512, @@ -1431,7 +1431,7 @@ }, { "trafficTypeName":"user", - "name":"Tagging", + "name":"NEW_Tagging", "trafficAllocation":100, "trafficAllocationSeed":1910132597, "seed":-311493896, @@ -1479,7 +1479,7 @@ }, { "trafficTypeName":"account", - "name":"Welcome_Page_UI", + "name":"NEW_Welcome_Page_UI", "trafficAllocation":100, "trafficAllocationSeed":1848523960, "seed":1608586361, @@ -1530,7 +1530,7 @@ }, { "trafficTypeName":"test", - "name":"pato_test_3", + "name":"NEW_pato_test_3", "trafficAllocation":100, "trafficAllocationSeed":458647735, "seed":95677506, @@ -1578,7 +1578,7 @@ }, { "trafficTypeName":"account", - "name":"testo23", + "name":"NEW_testo23", "trafficAllocation":100, "trafficAllocationSeed":-689658216, "seed":1711156051, @@ -1626,7 +1626,7 @@ }, { "trafficTypeName":"account", - "name":"testo909090", + "name":"NEW_testo909090", "trafficAllocation":100, "trafficAllocationSeed":-1196467266, "seed":-1998101827, @@ -1792,7 +1792,7 @@ }, { "trafficTypeName":"account", - "name":"testo22", + "name":"NEW_testo22", "trafficAllocation":100, "trafficAllocationSeed":1223277820, "seed":-1152948537, @@ -1840,7 +1840,7 @@ }, { "trafficTypeName":"user", - "name":"test-net", + "name":"NEW_test-net", "trafficAllocation":100, "trafficAllocationSeed":-2038196969, "seed":-862203077, @@ -1888,7 +1888,7 @@ }, { "trafficTypeName":"account", - "name":"test_dep_2", + "name":"NEW_test_dep_2", "trafficAllocation":100, "trafficAllocationSeed":-806171485, "seed":922684950, @@ -1980,7 +1980,7 @@ }, { "trafficTypeName":"account", - "name":"Definition_As_Of_Clickable_UI", + "name":"NEW_Definition_As_Of_Clickable_UI", "trafficAllocation":100, "trafficAllocationSeed":-198035199, "seed":-151947071, @@ -2060,7 +2060,7 @@ }, { "trafficTypeName":"account", - "name":"Identify_UI", + "name":"NEW_Identify_UI", "trafficAllocation":100, "trafficAllocationSeed":-139516103, "seed":1543172523, @@ -2108,7 +2108,7 @@ }, { "trafficTypeName":"account", - "name":"test_definition_as_of", + "name":"NEW_test_definition_as_of", "trafficAllocation":100, "trafficAllocationSeed":1025823325, "seed":-554248124, @@ -2156,7 +2156,7 @@ }, { "trafficTypeName":"user", - "name":"Test-jw-go", + "name":"NEW_Test-jw-go", "trafficAllocation":100, "trafficAllocationSeed":768122971, "seed":1539205707, @@ -2234,7 +2234,7 @@ }, { "trafficTypeName":"user", - "name":"benchmark_jw_7", + "name":"NEW_benchmark_jw_7", "trafficAllocation":100, "trafficAllocationSeed":-1340337178, "seed":-1091938685, @@ -2282,7 +2282,7 @@ }, { "trafficTypeName":"user", - "name":"benchmark_jw_6", + "name":"NEW_benchmark_jw_6", "trafficAllocation":100, "trafficAllocationSeed":-1202331834, "seed":-48445256, @@ -2330,7 +2330,7 @@ }, { "trafficTypeName":"user", - "name":"benchmark_jw_5", + "name":"NEW_benchmark_jw_5", "trafficAllocation":100, "trafficAllocationSeed":2119994290, "seed":-227092192, @@ -2378,7 +2378,7 @@ }, { "trafficTypeName":"user", - "name":"benchmark_jw_4", + "name":"NEW_benchmark_jw_4", "trafficAllocation":100, "trafficAllocationSeed":1066635158, "seed":-850704283, @@ -2426,7 +2426,7 @@ }, { "trafficTypeName":"user", - "name":"benchmark_jw_3", + "name":"NEW_benchmark_jw_3", "trafficAllocation":100, "trafficAllocationSeed":1252392550, "seed":971538037, @@ -2474,7 +2474,7 @@ }, { "trafficTypeName":"user", - "name":"benchmark_jw_2", + "name":"NEW_benchmark_jw_2", "trafficAllocation":100, "trafficAllocationSeed":-285565213, "seed":-1992295819, @@ -2522,7 +2522,7 @@ }, { "trafficTypeName":"user", - "name":"broken_split", + "name":"NEW_broken_split", "trafficAllocation":100, "trafficAllocationSeed":-285565213, "status":"ACTIVE", @@ -2532,7 +2532,7 @@ }, { "trafficTypeName":"account", - "name":"TEST_SETS_1", + "name":"NEW_TEST_SETS_1", "trafficAllocation":59, "trafficAllocationSeed":-2108186082, "seed":-1947050785, @@ -2648,7 +2648,7 @@ }, { "trafficTypeName":"account", - "name":"TEST_SETS_2", + "name":"NEW_TEST_SETS_2", "trafficAllocation":59, "trafficAllocationSeed":-2108186082, "seed":-1947050785, @@ -2767,7 +2767,7 @@ }, { "trafficTypeName":"account", - "name":"TEST_SETS_3", + "name":"NEW_TEST_SETS_3", "trafficAllocation":59, "trafficAllocationSeed":-2108186082, "seed":-1947050785,