Skip to content

Commit 0fa6201

Browse files
authored
Renaming TestTools to TestHarness... (#51)
* Renaming TestTools to Testharness and moving them to the main library as a module. * Adding TestHarnessTests as a module in the TraceLog library.
1 parent 3dc095c commit 0fa6201

File tree

8 files changed

+483
-27
lines changed

8 files changed

+483
-27
lines changed

Package.swift

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,27 +24,27 @@ let package = Package(
2424
name: "TraceLog",
2525
targets: [
2626
/// Module targets
27-
.target(name: "TraceLog", dependencies: [], path: "Sources/TraceLog"),
28-
.target(name: "TraceLogTestTools", dependencies: ["TraceLog"], path: "Tests/TraceLogTestTools"),
27+
.target(name: "TraceLog", dependencies: [], path: "Sources/TraceLog"),
28+
.target(name: "TraceLogTestHarness", dependencies: ["TraceLog"], path: "Sources/TraceLogTestHarness"),
2929

3030
/// Tests
31-
.testTarget(name: "TraceLogTests", dependencies: ["TraceLog", "TraceLogTestTools"], path: "Tests/TraceLogTests")
31+
.testTarget(name: "TraceLogTests", dependencies: ["TraceLog", "TraceLogTestHarness"], path: "Tests/TraceLogTests"),
32+
.testTarget(name: "TraceLogTestHarnessTests", dependencies: ["TraceLog", "TraceLogTestHarness"], path: "Tests/TraceLogTestHarnessTests")
3233
],
3334
swiftLanguageVersions: [4]
3435
)
3536

36-
var productTargets = ["TraceLog"]
37+
var productTargets = ["TraceLog", "TraceLogTestHarness"]
3738

3839
///
3940
/// These platforms can also support Objective-C so we create a module for it.
4041
///
4142
#if os(iOS) || os(macOS) || os(watchOS) || os(tvOS)
42-
package.targets.append(.target(name: "TraceLogObjC", dependencies: ["TraceLog"], path: "Sources/TraceLogObjC"))
43+
package.targets.append(.target(name: "TraceLogObjC", dependencies: ["TraceLog"], path: "Sources/TraceLogObjC"))
4344
package.targets.append(.testTarget(name: "TraceLogObjCTests", dependencies: ["TraceLogObjC"], path: "Tests/TraceLogObjCTests"))
4445

4546
productTargets.append("TraceLogObjC")
4647
#endif
4748

4849
/// Main products section
4950
package.products.append(.library(name: "TraceLog", type: .dynamic, targets: productTargets))
50-
package.products.append(.library(name: "TraceLogTestTools", type: .dynamic, targets: ["TraceLogTestTools"]))
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
///
2+
/// BufferReader.swift
3+
///
4+
/// Copyright 2018 Tony Stone
5+
///
6+
/// Licensed under the Apache License, Version 2.0 (the "License");
7+
/// you may not use this file except in compliance with the License.
8+
/// You may obtain a copy of the License at
9+
///
10+
/// http://www.apache.org/licenses/LICENSE-2.0
11+
///
12+
/// Unless required by applicable law or agreed to in writing, software
13+
/// distributed under the License is distributed on an "AS IS" BASIS,
14+
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
/// See the License for the specific language governing permissions and
16+
/// limitations under the License.
17+
///
18+
/// Created by Tony Stone on 6/25/18.
19+
///
20+
import TraceLog
21+
22+
///
23+
/// A test `Reader` implementation that reads the `BufferWriter`s buffer for validating results.
24+
///
25+
public class BufferReader: Reader {
26+
27+
public func logEntry(for writer: BufferWriter, timestamp: Double, level: LogLevel, tag: String, message: String, runtimeContext: RuntimeContext, staticContext: StaticContext) -> LogEntry? {
28+
29+
guard let logEntry = writer.buffer[message]
30+
else { return nil }
31+
32+
return LogEntry(timestamp: logEntry.timestamp,
33+
level: logEntry.level,
34+
message: logEntry.message,
35+
tag: logEntry.tag,
36+
file: logEntry.staticContext.file,
37+
function: logEntry.staticContext.function,
38+
line: logEntry.staticContext.line,
39+
processName: logEntry.runtimeContext.processName,
40+
processIdentifier: logEntry.runtimeContext.processIdentifier,
41+
threadIdentifier: Int(logEntry.runtimeContext.threadIdentifier))
42+
}
43+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
///
2+
/// BufferWriter.swift
3+
///
4+
/// Copyright 2018 Tony Stone
5+
///
6+
/// Licensed under the Apache License, Version 2.0 (the "License");
7+
/// you may not use this file except in compliance with the License.
8+
/// You may obtain a copy of the License at
9+
///
10+
/// http://www.apache.org/licenses/LICENSE-2.0
11+
///
12+
/// Unless required by applicable law or agreed to in writing, software
13+
/// distributed under the License is distributed on an "AS IS" BASIS,
14+
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
/// See the License for the specific language governing permissions and
16+
/// limitations under the License.
17+
///
18+
/// Created by Tony Stone on 6/25/18.
19+
///
20+
import TraceLog
21+
22+
///
23+
/// A test `Writer` implementation that writes all logged messages to a buffer which can then be queried to analyze the results.
24+
///
25+
public class BufferWriter: Writer {
26+
27+
///
28+
/// A buffer to hold the values written to this writer.
29+
///
30+
public var buffer: [String: (timestamp: Double, level: LogLevel, tag: String, message: String, runtimeContext: RuntimeContext, staticContext: StaticContext)] = [:]
31+
32+
///
33+
/// Required log function for the `Writer`.
34+
///
35+
public func log(_ timestamp: Double, level: LogLevel, tag: String, message: String, runtimeContext: RuntimeContext, staticContext: StaticContext) {
36+
self.buffer[message] = (timestamp, level, tag, message, runtimeContext, staticContext)
37+
}
38+
}

Tests/TraceLogTestTools/TestHarness.swift renamed to Sources/TraceLogTestHarness/TestHarness.swift

Lines changed: 17 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -46,33 +46,26 @@ public class TestHarness<T: Reader> {
4646
///
4747
public let writer: T.WriterType
4848

49-
///
50-
/// Instance of a Reader to use for validating the results of the test.
51-
///
52-
public var reader: T {
53-
return _reader.reader
54-
}
55-
5649
///
5750
/// Boxed version of the reader so it can be stored.
5851
///
59-
private let _reader: _AnyReaderBox<T>
52+
private let reader: _AnyReaderBox<T>
6053

6154
///
6255
/// Initialize a test harness with the specified writer that is under test and a reader to search for the entry so it can be validated.
6356
///
6457
public init(writer: T.WriterType, reader: T) {
6558
self.writer = writer
66-
self._reader = _AnyReaderBox(reader)
59+
self.reader = _AnyReaderBox(reader)
6760
}
6861

6962
///
7063
/// Executes test block (that must contain a call one of TraceLogs log functions) and validates the results.
7164
///
72-
public func testLog(for level: LogLevel, tag tagOrNil: String? = nil, message messageOrNil: String? = nil, _ file: String = #file, _ function: String = #function, _ line: Int = #line,
65+
public func testLog(for level: LogLevel, tag tagOrNil: String? = nil, message messageOrNil: String? = nil, file: String = #file, function: String = #function, line: Int = #line,
7366
testBlock: (String, String, String, String, Int) -> Void, validationBlock: (_ writer: T.WriterType, _ result: LogEntry?, _ expected: LogEntry)-> Void) {
7467

75-
self._testLog(for: level, tag: tagOrNil, message: messageOrNil, file, function, line, testBlock: { (timestamp, level, tag, message, runtimeContext, staticContext) in
68+
self._testLog(for: level, tag: tagOrNil, message: messageOrNil, file: file, function: function, line: line, testBlock: { (timestamp, level, tag, message, runtimeContext, staticContext) in
7669

7770
testBlock(tag, message, file, function, line)
7871

@@ -82,10 +75,10 @@ public class TestHarness<T: Reader> {
8275
///
8376
/// Calls the writer directly with the given LogLevel and validates the results.
8477
///
85-
public func testLog(for level: LogLevel, tag tagOrNil: String? = nil, message messageOrNil: String? = nil, _ file: String = #file, _ function: String = #function, _ line: Int = #line,
78+
public func testLog(for level: LogLevel, tag tagOrNil: String? = nil, message messageOrNil: String? = nil, file: String = #file, function: String = #function, line: Int = #line,
8679
validationBlock: (_ writer: T.WriterType, _ result: LogEntry?, _ expected: LogEntry)-> Void) {
8780

88-
self._testLog(for: level, tag: tagOrNil, message: messageOrNil, file, function, line, testBlock: { (timestamp, level, tag, message, runtimeContext, staticContext) in
81+
self._testLog(for: level, tag: tagOrNil, message: messageOrNil, file: file, function: function, line: line, testBlock: { (timestamp, level, tag, message, runtimeContext, staticContext) in
8982

9083
/// Execute the test
9184
self.writer.log(timestamp, level: level, tag: tag, message: message, runtimeContext: runtimeContext, staticContext: staticContext)
@@ -96,7 +89,7 @@ public class TestHarness<T: Reader> {
9689
///
9790
/// Test a TraceLog log message to a writer.
9891
///
99-
private func _testLog(for level: LogLevel, tag tagOrNil: String? = nil, message messageOrNil: String? = nil, _ file: String = #file, _ function: String = #function, _ line: Int = #line,
92+
private func _testLog(for level: LogLevel, tag tagOrNil: String? = nil, message messageOrNil: String? = nil, file: String = #file, function: String = #function, line: Int = #line,
10093
testBlock: (Double, LogLevel, String, String, RuntimeContext, StaticContext) -> Void, validationBlock: (_ writer: T.WriterType, _ result: LogEntry?, _ expected: LogEntry)-> Void) {
10194

10295
/// This is the time in microseconds since the epoch UTC to match the journals time stamps.
@@ -111,7 +104,7 @@ public class TestHarness<T: Reader> {
111104
/// Execute the test
112105
testBlock(timestamp, level, tag, message, runtimeContext, staticContext)
113106

114-
let result = self._reader.logEntry(for: writer, timestamp: timestamp, level: level, tag: tag, message: message, runtimeContext: runtimeContext, staticContext: staticContext)
107+
let result = self.reader.logEntry(for: self.writer, timestamp: timestamp, level: level, tag: tag, message: message, runtimeContext: runtimeContext, staticContext: staticContext)
115108

116109
let expected = LogEntry(timestamp: timestamp, level: level, message: message, tag: tag, file: staticContext.file, function: staticContext.function, line: staticContext.line, processName: runtimeContext.processName, processIdentifier: runtimeContext.processIdentifier, threadIdentifier: Int(runtimeContext.threadIdentifier))
117110

@@ -177,10 +170,6 @@ private class _AnyReaderBox<ConcreteReader: Reader>: _AnyReaderBase<ConcreteRead
177170
/// Private boxing class base for use in storing our Reader which has an associated type.
178171
///
179172
private class _AnyReaderBase<T: Writer>: Reader {
180-
init() {
181-
guard type(of: self) != _AnyReaderBase.self
182-
else { fatalError("Cannot initialize, must be subclass") }
183-
}
184173

185174
func logEntry(for writer: T, timestamp: Double, level: LogLevel, tag: String, message: String, runtimeContext: RuntimeContext, staticContext: StaticContext) -> LogEntry? {
186175
fatalError("Must override")
@@ -218,6 +207,14 @@ private struct TestRuntimeContext: RuntimeContext {
218207
let process = ProcessInfo.processInfo
219208
self.processName = process.processName
220209
self.processIdentifier = Int(process.processIdentifier)
221-
self.threadIdentifier = threadIdentifier
210+
211+
#if os(iOS) || os(macOS) || os(watchOS) || os(tvOS)
212+
var threadID: UInt64 = 0
213+
214+
pthread_threadid_np(pthread_self(), &threadID)
215+
self.threadIdentifier = threadID
216+
#else // FIXME: Linux does not support the pthread_threadid_np function, gettid in s syscall must be used.
217+
self.threadIdentifier = 0
218+
#endif
222219
}
223220
}

Tests/TraceLogTestTools/TestUtilities.swift renamed to Sources/TraceLogTestHarness/TestUtilities.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@ import XCTest
2525
///
2626
/// Helper to run the shell and return the output
2727
///
28+
@available(iOS, unavailable)
29+
@available(tvOS, unavailable)
30+
@available(watchOS, unavailable)
2831
public func shell(_ command: String) -> Data {
2932
let task = Process()
3033
task.launchPath = "/bin/bash"

Tests/LinuxMain.swift

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,15 @@
55
import XCTest
66

77
@testable import TraceLogTests
8+
@testable import TraceLogTestHarnessTests
89

910
XCTMain([
1011
testCase(TraceLogPerformanceTestsSwift.allTests),
1112
testCase(TraceLogTestsSwift.allTests),
1213
testCase(EnvironmentTests.allTests),
13-
testCase(ConfigurationTests.allTests)
14+
testCase(ConfigurationTests.allTests),
15+
testCase(TestHarnessTests.allTests),
16+
testCase(TestUtilitiesTests.allTests)
1417
])
1518

1619
extension TraceLogPerformanceTestsSwift {
@@ -95,4 +98,48 @@ extension ConfigurationTests {
9598
}
9699
}
97100

101+
extension TestHarnessTests {
102+
103+
static var allTests: [(String, (TestHarnessTests) -> () throws -> Void)] {
104+
return [
105+
("testLogForError", testLogForError),
106+
("testLogForWarning", testLogForWarning),
107+
("testLogForInfo", testLogForInfo),
108+
("testLogForTrace1", testLogForTrace1),
109+
("testLogForTrace2", testLogForTrace2),
110+
("testLogForTrace3", testLogForTrace3),
111+
("testLogForTrace4", testLogForTrace4),
112+
113+
("testLogWithCustomMessage", testLogWithCustomMessage),
114+
("testLogWithCustomTag", testLogWithCustomTag),
115+
("testLogWithCustomFile", testLogWithCustomFile),
116+
("testLogWithCustomFunction", testLogWithCustomFunction),
117+
("testLogWithCustomLine", testLogWithCustomLine),
118+
119+
("testLogTestBlockForError", testLogTestBlockForError),
120+
("testLogTestBlockForWarning", testLogTestBlockForWarning),
121+
("testLogTestBlockForInfo", testLogTestBlockForInfo),
122+
("testLogTestBlockForTrace1", testLogTestBlockForTrace1),
123+
("testLogTestBlockForTrace2", testLogTestBlockForTrace2),
124+
("testLogTestBlockForTrace3", testLogTestBlockForTrace3),
125+
("testLogTestBlockForTrace4", testLogTestBlockForTrace4),
126+
127+
("testLogTestBlockWithCustomMessage", testLogTestBlockWithCustomMessage),
128+
("testLogTestBlockWithCustomTag", testLogTestBlockWithCustomTag),
129+
("testLogTestBlockWithCustomFile", testLogTestBlockWithCustomFile),
130+
("testLogTestBlockWithCustomFunction", testLogTestBlockWithCustomFunction),
131+
("testLogTestBlockWithCustomLine", testLogTestBlockWithCustomLine)
132+
]
133+
}
134+
}
135+
136+
extension TestUtilitiesTests {
137+
138+
static var allTests: [(String, (TestUtilitiesTests) -> () throws -> Void)] {
139+
return [
140+
("testShell", testShell)
141+
]
142+
}
143+
}
144+
98145
#endif

0 commit comments

Comments
 (0)