Skip to content

Commit 55fab7c

Browse files
committed
=singleton harden multinode test for singleton
1 parent 737a5d1 commit 55fab7c

File tree

7 files changed

+18
-34
lines changed

7 files changed

+18
-34
lines changed

MultiNodeTests/DistributedActorsMultiNodeTests/MultiNode+ClusterSingletonTests.swift

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ public final class MultiNodeClusterSingletonTests: MultiNodeTestSuite {
2626
}
2727

2828
public static func configureMultiNodeTest(settings: inout MultiNodeTestSettings) {
29-
settings.initialJoinTimeout = .seconds(5)
3029
settings.dumpNodeLogs = .always
3130

3231
settings.logCapture.excludeGrep = [
@@ -61,9 +60,12 @@ public final class MultiNodeClusterSingletonTests: MultiNodeTestSuite {
6160
}
6261

6362
try await multiNode.checkPoint("Hosted singleton") // ----------------------------------------------------------
64-
6563
let reply = try await ref.greet(name: "Hello from \(multiNode.system.name)")
6664
print("[ON: \(multiNode.system.name)] Got reply: \(reply)")
65+
66+
try await multiNode.checkPoint("Got reply from singleton") // --------------------------------------------------
67+
// Since now all nodes have made a message exchange with the singleton, we can exit this process.
68+
// This barrier is important in so that we don't exit the host of the singleton WHILE the others are still getting to talking to it.
6769
}
6870

6971
distributed actor TheSingleton: ClusterSingleton {

MultiNodeTests/DistributedActorsMultiNodeTests/MultiNode+MultiNodeConductorTests.swift

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -27,25 +27,12 @@ public final class MultiNodeConductorTests: MultiNodeTestSuite {
2727
///
2828
/// It also eliminates the possibility of "cheating" and a node peeking
2929
/// at shared state, since the nodes are properly isolated as if in a real cluster.
30-
///
31-
/// ## Distributed execution
32-
/// To execute the same test across different physical nodes pass a list ofv
33-
/// nodes to use when running the test, e.g.v
34-
///
35-
/// ```
36-
/// swift package multi-node test --deploy 192.168.0.101:22,192.168.0.102:22,192.168.0.103:22
37-
/// ```
38-
///
39-
/// Which will evenly spread the test nodes across the passed physical worker nodes.
40-
/// Actual network will be used, and it remains possible to kill off nodes and logs
41-
/// from all nodes are gathered automatically upon test failures.
4230
public enum Nodes: String, MultiNodeNodes {
4331
case first
4432
case second
4533
}
4634

4735
public static func configureMultiNodeTest(settings: inout MultiNodeTestSettings) {
48-
settings.initialJoinTimeout = .seconds(5)
4936
settings.dumpNodeLogs = .always
5037

5138
settings.logCapture.excludeGrep = [

Sources/DistributedActors/ClusterSystem.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1045,7 +1045,7 @@ extension ClusterSystem {
10451045

10461046
/// Called during actor deinit/destroy.
10471047
public func resignID(_ id: ActorID) {
1048-
self.log.warning("Resign actor id", metadata: ["actor/id": "\(id)"])
1048+
self.log.trace("Resign actor id", metadata: ["actor/id": "\(id)"])
10491049
self.namingLock.withLockVoid {
10501050
self._reservedNames.remove(id)
10511051
if let ref = self._managedRefs.removeValue(forKey: id) {

Sources/DistributedActors/DistributedActor+Internal.swift

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -39,11 +39,7 @@ struct AnyDistributedActor: Sendable, Hashable {
3939

4040
@usableFromInline
4141
func force<T: DistributedActor>(as _: T.Type) -> T {
42-
// if let cast = underlying as? T {
43-
// return cast
44-
// }
45-
46-
// FIXME: terrible hack, instead just store the id then?
42+
// FIXME: hack, instead just store the id then?
4743
if let resolved = try? T.resolve(id: underlying.id as! T.ID, using: underlying.actorSystem as! T.ActorSystem) {
4844
return resolved
4945
}

Sources/MultiNodeTestKit/MultiNodeTestConductor.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -217,11 +217,11 @@ extension MultiNodeTestConductor {
217217

218218
let error = MultiNodeCheckPointError(
219219
nodeName: nodeName,
220-
message: "Checkpoint \(checkpoint.name) failed, node [\(nodeName)] became [\(change.status)] and therefore unable to reach the checkpoint!"
220+
message: "Checkpoint [\(checkpoint.name)] failed, node [\(nodeName)] became [\(change.status)] and therefore unable to reach the checkpoint!"
221221
)
222222

223223
for (name, cc) in self.nodesAtCheckPoint {
224-
self.log.warning("Checkpoint \(checkpoint.name) failing. Node \(nodeName) became at least [.down]. Failing waiting node [\(name)]", metadata: [
224+
self.log.warning("Checkpoint [\(checkpoint.name)] failing. Node \(nodeName) became at least [.down]. Failing waiting node [\(name)]", metadata: [
225225
"multiNode/checkpoint/error": "\(error)",
226226
])
227227
cc.resume(throwing: error)

Sources/MultiNodeTestKitRunner/boot+MultiNodeTestKitRunner+Test.swift

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -124,8 +124,6 @@ extension MultiNodeTestKitRunnerBoot {
124124
throw MultiNodeTestNotFound(suite: suite, test: testName)
125125
}
126126

127-
print("NODESSSSS: \(multiNodeTest.nodeNames)")
128-
129127
let devNull = try FileHandle(forUpdating: URL(fileURLWithPath: "/dev/null"))
130128
defer {
131129
devNull.closeFile()
@@ -178,6 +176,7 @@ extension MultiNodeTestKitRunnerBoot {
178176
let testResult = try interpretNodeTestOutput(
179177
result,
180178
nodeName: nodeName,
179+
multiNodeTest: multiNodeTest,
181180
expectedFailureRegex: multiNodeTest.crashRegex,
182181
grepper: grepper,
183182
settings: settings,

Sources/MultiNodeTestKitRunner/boot+MultiNodeTestKitRunner.swift

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -125,13 +125,15 @@ struct MultiNodeTestKitRunnerBoot {
125125
func interpretNodeTestOutput(
126126
_ result: Result<ProgramOutput, Error>,
127127
nodeName: String,
128+
multiNodeTest: MultiNodeTest,
128129
expectedFailureRegex: String?,
129130
grepper: OutputGrepper,
130131
settings: MultiNodeTestSettings,
131132
runResult: RunResult
132133
) throws -> InterpretedRunResult {
134+
print()
133135
print(String(repeating: "-", count: 120))
134-
print("[multi-node] [\(nodeName)] Captured logs:")
136+
print("[multi-node] [\(nodeName)](\(multiNodeTest.fullTestName)) Captured logs:")
135137
defer {
136138
print(String(repeating: "=", count: 120))
137139
}
@@ -143,7 +145,7 @@ struct MultiNodeTestKitRunnerBoot {
143145
case .failure(let error as MultiNodeProgramError):
144146
var reason: String = "MultiNode test failed, output was dumped."
145147
for line in error.completeOutput {
146-
log("[\(nodeName)] \(line)")
148+
log("[\(nodeName)](\(multiNodeTest.testName)) \(line)")
147149

148150
if line.contains("Fatal error: ") {
149151
reason = line
@@ -153,7 +155,7 @@ struct MultiNodeTestKitRunnerBoot {
153155
case .success(let logs):
154156
if settings.dumpNodeLogs == .always {
155157
for line in logs {
156-
print("[multi-node] [\(nodeName)] \(line)")
158+
print("[multi-node] [\(nodeName)](\(multiNodeTest.testName)) \(line)")
157159
}
158160
}
159161
return .passedAsExpected
@@ -175,13 +177,13 @@ struct MultiNodeTestKitRunnerBoot {
175177
if outputJoined.range(of: expectedFailureRegex, options: .regularExpression) != nil {
176178
if settings.dumpNodeLogs == .always {
177179
for line in outputLines {
178-
log("[\(nodeName)] \(line)")
180+
log("[\(nodeName)](\(multiNodeTest.testName)) \(line)")
179181
}
180182
}
181183
return .crashedAsExpected
182184
} else {
183185
for line in outputLines {
184-
log("[\(nodeName)] \(line)")
186+
log("[\(nodeName)](\(multiNodeTest.testName)) \(line)")
185187
}
186188
return .crashRegexDidNotMatch(regex: expectedFailureRegex, output: outputJoined)
187189
}
@@ -203,11 +205,9 @@ struct MultiNodeTestKitRunnerBoot {
203205
func run() async throws {
204206
signal(SIGPIPE, SIG_IGN)
205207

206-
var failedTests = 0
207-
208+
var summary = MultiNodeTestSummary()
208209
switch CommandLine.arguments.dropFirst().first {
209210
case .some("test"):
210-
var summary = MultiNodeTestSummary()
211211
let filter = TestFilter(parse: CommandLine.arguments.dropFirst())
212212
defer {
213213
summary.dump()
@@ -241,7 +241,7 @@ struct MultiNodeTestKitRunnerBoot {
241241
exit(EXIT_FAILURE)
242242
}
243243

244-
exit(CInt(failedTests == 0 ? EXIT_SUCCESS : EXIT_FAILURE))
244+
exit(CInt(summary.failedTests == 0 ? EXIT_SUCCESS : EXIT_FAILURE))
245245
}
246246

247247
func makeAllNodesCommandString(nodeNames: OrderedSet<String>, deployNodes: [(String, Int)]) -> String {

0 commit comments

Comments
 (0)