From 6c65b1863dffc90dec65f1ac33ac1f7111df8442 Mon Sep 17 00:00:00 2001 From: Sergey Krupov Date: Wed, 21 Nov 2018 14:42:10 +0500 Subject: [PATCH] =?UTF-8?q?=D0=A2=D0=B5=D1=81=D1=82=D1=8B=20=D0=B4=D0=BB?= =?UTF-8?q?=D1=8F=20=D0=B2=D0=BE=D1=81=D0=BF=D1=80=D0=BE=D0=B8=D0=B7=D0=B2?= =?UTF-8?q?=D0=B5=D0=B4=D0=B5=D0=BD=D0=B8=D1=8F=20=D0=BE=D1=88=D0=B8=D0=B1?= =?UTF-8?q?=D0=BA=D0=B8=20=D1=80=D0=B0=D0=B1=D0=BE=D1=82=D1=8B=20=D1=81=20?= =?UTF-8?q?=D0=BC=D0=BD=D0=BE=D0=B3=D0=BE=D0=BF=D0=BE=D1=82=D0=BE=D1=87?= =?UTF-8?q?=D0=BD=D0=BE=D1=81=D1=82=D1=8C=D1=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- EasyDi.xcodeproj/project.pbxproj | 4 ++ Tests/Test_Threadsafety.swift | 63 ++++++++++++++++++++++++++++++++ 2 files changed, 67 insertions(+) create mode 100644 Tests/Test_Threadsafety.swift diff --git a/EasyDi.xcodeproj/project.pbxproj b/EasyDi.xcodeproj/project.pbxproj index 3ffc147..dba275a 100644 --- a/EasyDi.xcodeproj/project.pbxproj +++ b/EasyDi.xcodeproj/project.pbxproj @@ -10,6 +10,7 @@ 8BEE13521F9A27C800A02331 /* EasyDi.h in Headers */ = {isa = PBXBuildFile; fileRef = 8BEE13501F9A27C800A02331 /* EasyDi.h */; settings = {ATTRIBUTES = (Public, ); }; }; 8BEE13561F9A27EA00A02331 /* EasyDi.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8BEE13551F9A27EA00A02331 /* EasyDi.swift */; }; 8BEE13571F9A27F200A02331 /* EasyDi.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8BEE13551F9A27EA00A02331 /* EasyDi.swift */; }; + A5ABB84321A5522400C96320 /* Test_Threadsafety.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5ABB84221A5522400C96320 /* Test_Threadsafety.swift */; }; C3614B541F1C8B6800B1F4A1 /* Test_Context.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3614B451F1C8B5F00B1F4A1 /* Test_Context.swift */; }; C3614B551F1C8B6800B1F4A1 /* Test_CrossAssemblyInjections.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3614B461F1C8B5F00B1F4A1 /* Test_CrossAssemblyInjections.swift */; }; C3614B561F1C8B6800B1F4A1 /* Test_Injections.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3614B471F1C8B5F00B1F4A1 /* Test_Injections.swift */; }; @@ -54,6 +55,7 @@ 8BEE13501F9A27C800A02331 /* EasyDi.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EasyDi.h; sourceTree = ""; }; 8BEE13511F9A27C800A02331 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 8BEE13551F9A27EA00A02331 /* EasyDi.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EasyDi.swift; sourceTree = ""; }; + A5ABB84221A5522400C96320 /* Test_Threadsafety.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Test_Threadsafety.swift; sourceTree = ""; }; C3614B3B1F1C8AE900B1F4A1 /* EasyDi-iOS-Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "EasyDi-iOS-Tests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; C3614B441F1C8B5F00B1F4A1 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = Tests/Info.plist; sourceTree = SOURCE_ROOT; }; C3614B451F1C8B5F00B1F4A1 /* Test_Context.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Test_Context.swift; path = Tests/Test_Context.swift; sourceTree = SOURCE_ROOT; }; @@ -137,6 +139,7 @@ D2B16C962123116500CF69E8 /* Test_ImplicitlyUnwrappedOptional.swift */, C3614B4A1F1C8B5F00B1F4A1 /* Test_Scope.swift */, C3614B4B1F1C8B5F00B1F4A1 /* Test_StructsInjection.swift */, + A5ABB84221A5522400C96320 /* Test_Threadsafety.swift */, ); path = Tests; sourceTree = ""; @@ -366,6 +369,7 @@ C3614B541F1C8B6800B1F4A1 /* Test_Context.swift in Sources */, C3614B561F1C8B6800B1F4A1 /* Test_Injections.swift in Sources */, C3614B5A1F1C8B6800B1F4A1 /* Test_StructsInjection.swift in Sources */, + A5ABB84321A5522400C96320 /* Test_Threadsafety.swift in Sources */, E6DCF5C61F2F62A600D9F8BC /* Test_CrossAssemblyInjections_SingletonCycle.swift in Sources */, C3614B581F1C8B6800B1F4A1 /* Test_ProtocolBasedInjection.swift in Sources */, ); diff --git a/Tests/Test_Threadsafety.swift b/Tests/Test_Threadsafety.swift new file mode 100644 index 0000000..a4f03bc --- /dev/null +++ b/Tests/Test_Threadsafety.swift @@ -0,0 +1,63 @@ +// +// Test_Threadsafety.swift +// EasyDi-iOS-Tests +// +// Created by Sergey V. Krupov on 21.11.2018. +// Copyright © 2018 AndreyZarembo. All rights reserved. +// + +import XCTest +import EasyDi + +fileprivate protocol SomeProtocol { +} + +fileprivate class SomeObject: SomeProtocol { + var values = Array(repeating: "", count: 4000) +} + +fileprivate class TestAssembly: Assembly { + + var someObject: SomeProtocol { + return define(init: SomeObject()) { + for i in 0 ..< $0.values.count { + $0.values[i] = self.getSomeValue(at: i) + } + return $0 + } + } + + // Сделано для того, чтобы стабильно воспроизводить падение. Вряд ли в реальном приложении будет такой код. + private func getSomeValue(at index: Int) -> String { + return define(key: "getSomeValue_\(index)", init: "value-\(index)") + } +} + +final class Test_Threadsafety: XCTestCase { + + func test_ThreadSafety() { + + let context = DIContext() + let assembly = TestAssembly.instance(from: context) + + // Явно создаю 2 потока, т.к. не известно на скольких потоках будет работать concurrent dispatch queue + + let expectation1 = expectation(description: "Thread-1") + Thread.detachNewThread { + for _ in 1 ..< 10 { + _ = assembly.someObject + } + expectation1.fulfill() + } + + let expectation2 = expectation(description: "Thread-2") + Thread.detachNewThread { + for _ in 1 ..< 10 { + _ = assembly.someObject + } + expectation2.fulfill() + } + + wait(for: [expectation1, expectation2], timeout: 10) + } +}