Skip to content

Commit

Permalink
Create a unique identifier for a test method execution
Browse files Browse the repository at this point in the history
This is currently being passed to

- uniqueChannelName(…) — to include the execution ID in the channel name
- createUserQueue(…) — to include the execution ID in the queue label
- commonAppSetup(…) — to include the execution ID in the
  channelNamePrefix

and the intention is that it will be a unique identifier eventually used
to link together everything to do with a given test method execution —
e.g. for tagging log messages, labelling dispatch queues etc.
  • Loading branch information
lawrence-forooghian committed May 2, 2023
1 parent 21c3cdd commit 11e469d
Show file tree
Hide file tree
Showing 20 changed files with 2,125 additions and 1,350 deletions.
8 changes: 8 additions & 0 deletions Ably.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,9 @@
21881E7A283BD08300CFD9E2 /* GCDTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5A22171266F526600C87C42 /* GCDTests.swift */; };
21881E7B283BD0DF00CFD9E2 /* StringifiableTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D520C4DD2680A1E3000012B2 /* StringifiableTests.swift */; };
21881E7C283BD0E100CFD9E2 /* StringifiableTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D520C4DD2680A1E3000012B2 /* StringifiableTests.swift */; };
21FD9F272A015BE400216482 /* Test.swift in Sources */ = {isa = PBXBuildFile; fileRef = 21FD9F262A015BE400216482 /* Test.swift */; };
21FD9F282A015BE400216482 /* Test.swift in Sources */ = {isa = PBXBuildFile; fileRef = 21FD9F262A015BE400216482 /* Test.swift */; };
21FD9F292A015BE400216482 /* Test.swift in Sources */ = {isa = PBXBuildFile; fileRef = 21FD9F262A015BE400216482 /* Test.swift */; };
560579D924AF1BA900A4D03D /* ARTDefaultTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 560579D824AF1BA900A4D03D /* ARTDefaultTests.swift */; };
560579DA24AF1BA900A4D03D /* ARTDefaultTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 560579D824AF1BA900A4D03D /* ARTDefaultTests.swift */; };
560579DB24AF1BA900A4D03D /* ARTDefaultTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 560579D824AF1BA900A4D03D /* ARTDefaultTests.swift */; };
Expand Down Expand Up @@ -1219,6 +1222,7 @@
21DCDA8229F818630073A211 /* Ably-iOS.xctestplan */ = {isa = PBXFileReference; lastKnownFileType = file; name = "Ably-iOS.xctestplan"; path = "Test/Ably-iOS.xctestplan"; sourceTree = SOURCE_ROOT; };
21DCDA8329F81B350073A211 /* Ably-macOS.xctestplan */ = {isa = PBXFileReference; lastKnownFileType = text; path = "Ably-macOS.xctestplan"; sourceTree = "<group>"; };
21DCDA8429F81B550073A211 /* Ably-tvOS.xctestplan */ = {isa = PBXFileReference; lastKnownFileType = text; path = "Ably-tvOS.xctestplan"; sourceTree = "<group>"; };
21FD9F262A015BE400216482 /* Test.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Test.swift; sourceTree = "<group>"; };
560579D824AF1BA900A4D03D /* ARTDefaultTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ARTDefaultTests.swift; sourceTree = "<group>"; };
56190953238C3D3200A862A6 /* CryptoTest.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CryptoTest.m; sourceTree = "<group>"; };
841134772722205400CFA837 /* ARTArchiveTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ARTArchiveTests.m; sourceTree = "<group>"; };
Expand Down Expand Up @@ -1733,6 +1737,7 @@
2147F03429E5872C0071CB94 /* MockInternalLogCore.swift */,
D50D86E829E9444600EA72EA /* JSON.swift */,
210F67B029E9DB62007B9345 /* TestProxyTransportFactory.swift */,
21FD9F262A015BE400216482 /* Test.swift */,
);
path = "Test Utilities";
sourceTree = "<group>";
Expand Down Expand Up @@ -3040,6 +3045,7 @@
2132C21629D20F69000C4355 /* ResumeRequestResponseTests.swift in Sources */,
EB7913A81C6E54C3000ABF9B /* CryptoTests.swift in Sources */,
2132C22229D233EB000C4355 /* DefaultErrorCheckerTests.swift in Sources */,
21FD9F272A015BE400216482 /* Test.swift in Sources */,
D777EEE820650ADF002EBA03 /* PushChannelTests.swift in Sources */,
217FCF3F29D626E4006E5F2D /* StaticJitterCoefficients.swift in Sources */,
D746AE2D1BBB625E003ECEF8 /* RestClientChannelsTests.swift in Sources */,
Expand Down Expand Up @@ -3229,6 +3235,7 @@
56190955238C3D3200A862A6 /* CryptoTest.m in Sources */,
D7093C1D219E466600723F17 /* AuthTests.swift in Sources */,
21276CC329F00BAA00107B5F /* ContinuousClockTests.swift in Sources */,
21FD9F282A015BE400216482 /* Test.swift in Sources */,
D7093C25219E466E00723F17 /* RealtimeClientConnectionTests.swift in Sources */,
217FCF4029D626E4006E5F2D /* StaticJitterCoefficients.swift in Sources */,
);
Expand Down Expand Up @@ -3285,6 +3292,7 @@
56190956238C3D3200A862A6 /* CryptoTest.m in Sources */,
D7093C7A219EE26400723F17 /* RestPaginatedTests.swift in Sources */,
21276CC429F00BAA00107B5F /* ContinuousClockTests.swift in Sources */,
21FD9F292A015BE400216482 /* Test.swift in Sources */,
D7093C81219EE26400723F17 /* UtilitiesTests.swift in Sources */,
217FCF4129D626E4006E5F2D /* StaticJitterCoefficients.swift in Sources */,
);
Expand Down
12 changes: 12 additions & 0 deletions Test/Test Utilities/Test.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/**
Represents an execution of a test case method.
*/
struct Test {
var id = UUID()
private var function: StaticString

init(function: StaticString = #function) {
self.function = function
NSLog("Created test \(id) for function \(function)")
}
}
50 changes: 25 additions & 25 deletions Test/Test Utilities/TestUtilities.swift
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,8 @@ let testTimeout = DispatchTimeInterval.seconds(20)
let testResourcesPath = "ably-common/test-resources/"
let echoServerAddress = "https://echo.ably.io/createJWT"

func uniqueChannelName(prefix: String = "",
testIdentifier: String = #function,
func uniqueChannelName(for test: Test,
prefix: String = "",
timestamp: TimeInterval = Date.timeIntervalSinceReferenceDate) -> String {
let platform: String
#if targetEnvironment(macCatalyst)
Expand All @@ -67,7 +67,7 @@ func uniqueChannelName(prefix: String = "",
#else
platform = "Unknown"
#endif
return "\(prefix)-\(platform)-\(testIdentifier.replacingOccurrences(of: "()", with: ""))-\(timestamp)-\(NSUUID().uuidString)"
return "\(prefix)-\(platform)-\(test.id)-\(timestamp)-\(NSUUID().uuidString)"
}

/// Common test utilities.
Expand Down Expand Up @@ -114,8 +114,8 @@ class AblyTests {
return queue
}()

static func createUserQueue() -> DispatchQueue {
let queue = DispatchQueue(label: "io.ably.tests.callbacks.\(UUID().uuidString)", qos: .userInitiated)
static func createUserQueue(for test: Test) -> DispatchQueue {
let queue = DispatchQueue(label: "io.ably.tests.callbacks.\(test.id).\(UUID().uuidString)", qos: .userInitiated)
queue.setSpecific(key: queueIdentityKey, value: QueueIdentity(label: queue.label))
return queue
}
Expand All @@ -124,9 +124,9 @@ class AblyTests {
return DispatchQueue.getSpecific(key: queueIdentityKey)?.label
}

class func commonAppSetup(debug: Bool = false, forceNewApp: Bool = false) throws -> ARTClientOptions {
let options = try AblyTests.clientOptions(debug: debug)
options.testOptions.channelNamePrefix = "test-\(UUID().uuidString)"
class func commonAppSetup(for test: Test, debug: Bool = false, forceNewApp: Bool = false) throws -> ARTClientOptions {
let options = try AblyTests.clientOptions(for: test, debug: debug)
options.testOptions.channelNamePrefix = "test-\(test.id)-\(UUID().uuidString)"

if forceNewApp {
testApplication = nil
Expand Down Expand Up @@ -161,7 +161,7 @@ class AblyTests {
return options
}

class func clientOptions(debug: Bool = false, key: String? = nil, requestToken: Bool = false) throws -> ARTClientOptions {
class func clientOptions(for test: Test, debug: Bool = false, key: String? = nil, requestToken: Bool = false) throws -> ARTClientOptions {
let options = ARTClientOptions()
options.environment = getEnvironment()
if debug {
Expand All @@ -171,7 +171,7 @@ class AblyTests {
options.key = key
}
if requestToken {
options.token = try getTestToken()
options.token = try getTestToken(for: test)
}
options.dispatchQueue = DispatchQueue.main
options.internalDispatchQueue = queue
Expand Down Expand Up @@ -518,22 +518,22 @@ class PublishTestMessage {
}

/// Access Token
func getTestToken(key: String? = nil, clientId: String? = nil, capability: String? = nil, ttl: TimeInterval? = nil, file: FileString = #file, line: UInt = #line) throws -> String {
return try getTestTokenDetails(key: key, clientId: clientId, capability: capability, ttl: ttl, file: file, line: line).token
func getTestToken(for test: Test, key: String? = nil, clientId: String? = nil, capability: String? = nil, ttl: TimeInterval? = nil, file: FileString = #file, line: UInt = #line) throws -> String {
return try getTestTokenDetails(for: test, key: key, clientId: clientId, capability: capability, ttl: ttl, file: file, line: line).token
}

func getTestToken(key: String? = nil, clientId: String? = nil, capability: String? = nil, ttl: TimeInterval? = nil, file: FileString = #file, line: UInt = #line, completion: @escaping (Swift.Result<String, Error>) -> Void) {
getTestTokenDetails(key: key, clientId: clientId, capability: capability, ttl: ttl) { result in
func getTestToken(for test: Test, key: String? = nil, clientId: String? = nil, capability: String? = nil, ttl: TimeInterval? = nil, file: FileString = #file, line: UInt = #line, completion: @escaping (Swift.Result<String, Error>) -> Void) {
getTestTokenDetails(for: test, key: key, clientId: clientId, capability: capability, ttl: ttl) { result in
completion(result.map(\.token))
}
}

/// Access TokenDetails
func getTestTokenDetails(key: String? = nil, clientId: String? = nil, capability: String? = nil, ttl: TimeInterval? = nil, queryTime: Bool? = nil, completion: @escaping (Swift.Result<ARTTokenDetails, Error>) -> Void) {
func getTestTokenDetails(for test: Test, key: String? = nil, clientId: String? = nil, capability: String? = nil, ttl: TimeInterval? = nil, queryTime: Bool? = nil, completion: @escaping (Swift.Result<ARTTokenDetails, Error>) -> Void) {
let options: ARTClientOptions
if let key = key {
do {
options = try AblyTests.clientOptions()
options = try AblyTests.clientOptions(for: test)
} catch {
completion(.failure(error))
return
Expand All @@ -542,7 +542,7 @@ func getTestTokenDetails(key: String? = nil, clientId: String? = nil, capability
}
else {
do {
options = try AblyTests.commonAppSetup()
options = try AblyTests.commonAppSetup(for: test)
} catch {
completion(.failure(error))
return
Expand Down Expand Up @@ -580,8 +580,8 @@ func getTestTokenDetails(key: String? = nil, clientId: String? = nil, capability
}
}

func getTestTokenDetails(key: String? = nil, clientId: String? = nil, capability: String? = nil, ttl: TimeInterval? = nil, queryTime: Bool? = nil, completion: @escaping (ARTTokenDetails?, Error?) -> Void) {
getTestTokenDetails(key: key, clientId: clientId, capability: capability, ttl: ttl, queryTime: queryTime) { result in
func getTestTokenDetails(for test: Test, key: String? = nil, clientId: String? = nil, capability: String? = nil, ttl: TimeInterval? = nil, queryTime: Bool? = nil, completion: @escaping (ARTTokenDetails?, Error?) -> Void) {
getTestTokenDetails(for: test, key: key, clientId: clientId, capability: capability, ttl: ttl, queryTime: queryTime) { result in
switch result {
case .success(let tokenDetails):
completion(tokenDetails, nil)
Expand All @@ -591,18 +591,18 @@ func getTestTokenDetails(key: String? = nil, clientId: String? = nil, capability
}
}

func getTestTokenDetails(key: String? = nil, clientId: String? = nil, capability: String? = nil, ttl: TimeInterval? = nil, queryTime: Bool? = nil, file: FileString = #file, line: UInt = #line) throws -> ARTTokenDetails {
func getTestTokenDetails(for test: Test, key: String? = nil, clientId: String? = nil, capability: String? = nil, ttl: TimeInterval? = nil, queryTime: Bool? = nil, file: FileString = #file, line: UInt = #line) throws -> ARTTokenDetails {
let result = try AblyTests.waitFor(timeout: testTimeout, file: file, line: line) { value in
getTestTokenDetails(key: key, clientId: clientId, capability: capability, ttl: ttl, queryTime: queryTime) { result in
getTestTokenDetails(for: test, key: key, clientId: clientId, capability: capability, ttl: ttl, queryTime: queryTime) { result in
value(result)
}
}

return try result.get()
}

func getJWTToken(invalid: Bool = false, expiresIn: Int = 3600, clientId: String = "testClientIDiOS", capability: String = "{\"*\":[\"*\"]}", jwtType: String = "", encrypted: Int = 0) throws -> String? {
let options = try AblyTests.commonAppSetup()
func getJWTToken(for test: Test, invalid: Bool = false, expiresIn: Int = 3600, clientId: String = "testClientIDiOS", capability: String = "{\"*\":[\"*\"]}", jwtType: String = "", encrypted: Int = 0) throws -> String? {
let options = try AblyTests.commonAppSetup(for: test)
guard let components = options.key?.components(separatedBy: ":"), let keyName = components.first, var keySecret = components.last else {
fail("Invalid API key: \(options.key ?? "nil")")
return nil
Expand All @@ -628,8 +628,8 @@ func getJWTToken(invalid: Bool = false, expiresIn: Int = 3600, clientId: String
return String(data: responseData, encoding: String.Encoding.utf8)
}

func getKeys() throws -> Dictionary<String, String> {
let options = try AblyTests.commonAppSetup()
func getKeys(for test: Test) throws -> Dictionary<String, String> {
let options = try AblyTests.commonAppSetup(for: test)
guard let components = options.key?.components(separatedBy: ":"), let keyName = components.first, let keySecret = components.last else {
fatalError("Invalid API key)")
}
Expand Down
Loading

0 comments on commit 11e469d

Please sign in to comment.