Skip to content

Commit 3eb642c

Browse files
authored
SWIFT-1553: Always report wallTime in the change stream event output (#762)
1 parent ad33e26 commit 3eb642c

File tree

6 files changed

+1691
-43
lines changed

6 files changed

+1691
-43
lines changed

Sources/MongoSwift/ChangeStreamEvent.swift

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
import Foundation
2+
import SwiftBSON
3+
14
/// An `UpdateDescription` containing fields that will be present in the change stream document for
25
/// operations of type `update`.
36
public struct UpdateDescription: Codable {
@@ -115,6 +118,10 @@ public struct ChangeStreamEvent<T: Codable>: Codable {
115118
/// type`update`.
116119
public let updateDescription: UpdateDescription?
117120

121+
/// The wall time from the `mongod` that the change event originated from.
122+
/// Only present for server versions 6.0 and above.
123+
public let wallTime: Date?
124+
118125
/**
119126
* Always present for operations of type `insert` and `replace`. Also present for operations of type `update` if
120127
* the user has specified `.updateLookup` for the `fullDocument` option in the `ChangeStreamOptions` used to create
@@ -129,7 +136,7 @@ public struct ChangeStreamEvent<T: Codable>: Codable {
129136
public let fullDocument: T?
130137

131138
private enum CodingKeys: String, CodingKey {
132-
case operationType, _id, ns, to, documentKey, updateDescription, fullDocument
139+
case operationType, _id, ns, to, documentKey, updateDescription, wallTime, fullDocument
133140
}
134141

135142
// Custom decode method to work around the fact that `invalidate` events do not have an `ns` field in the raw
@@ -156,6 +163,7 @@ public struct ChangeStreamEvent<T: Codable>: Codable {
156163
}
157164

158165
self.documentKey = try container.decodeIfPresent(BSONDocument.self, forKey: .documentKey)
166+
self.wallTime = try container.decodeIfPresent(Date.self, forKey: .wallTime)
159167
self.updateDescription = try container.decodeIfPresent(UpdateDescription.self, forKey: .updateDescription)
160168
self.fullDocument = try container.decodeIfPresent(T.self, forKey: .fullDocument)
161169
}

Tests/MongoSwiftSyncTests/UnifiedTestRunner/ExpectedEventsForClient.swift

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,13 @@ struct ExpectedEventsForClient: Decodable {
1818
/// (excluding ignored events).
1919
let events: [ExpectedEvent]
2020

21+
/// Specifies how the `events` array is matched against observed events. If false, observed events after all
22+
/// specified events have matched MUST cause a test failure; if true, observed events after all specified events
23+
/// have been matched MUST NOT cause a test failure. Defaults to false.
24+
let ignoreExtraEvents: Bool
25+
2126
enum CodingKeys: String, CodingKey {
22-
case client, eventType, events
27+
case client, eventType, events, ignoreExtraEvents
2328
}
2429

2530
init(from decoder: Decoder) throws {
@@ -34,6 +39,7 @@ struct ExpectedEventsForClient: Decodable {
3439
// TODO: SWIFT-1321 actually parse these out.
3540
self.events = []
3641
}
42+
self.ignoreExtraEvents = try container.decodeIfPresent(Bool.self, forKey: .ignoreExtraEvents) ?? false
3743
}
3844
}
3945

@@ -77,8 +83,12 @@ enum ExpectedEvent: Decodable {
7783
/// Name of the database the command is run against.
7884
let databaseName: String?
7985

80-
/// Specifies whether the serviceId field of the event is set.
86+
/// Specifies whether the `serviceId` field of the event is set.
8187
let hasServiceId: Bool?
88+
89+
/// Specifies whether the `serviceConnectionId` field of an event is set.
90+
// TODO: SWIFT-1262: update unified test runner to use this value.
91+
let hasServerConnectionId: Bool?
8292
}
8393

8494
/// Represents expectations for a CommandSucceededEvent.
@@ -91,6 +101,10 @@ enum ExpectedEvent: Decodable {
91101

92102
/// Specifies whether the serviceId field of the event is set.
93103
let hasServiceId: Bool?
104+
105+
/// Specifies whether the `serviceConnectionId` field of an event is set.
106+
// TODO: SWIFT-1262: update unified test runner to use this value.
107+
let hasServerConnectionId: Bool?
94108
}
95109

96110
/// Represents expectations for a CommandStartedEvent.
@@ -100,5 +114,9 @@ enum ExpectedEvent: Decodable {
100114

101115
/// Specifies whether the serviceId field of the event is set.
102116
let hasServiceId: Bool?
117+
118+
/// Specifies whether the `serviceConnectionId` field of an event is set.
119+
// TODO: SWIFT-1262: update unified test runner to use this value.
120+
let hasServerConnectionId: Bool?
103121
}
104122
}

Tests/MongoSwiftSyncTests/UnifiedTestRunner/Matching.swift

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -309,12 +309,18 @@ enum SpecialOperator {
309309
}
310310

311311
/// Determines if the events in `actual` match the events in `expected`.
312-
func matchesEvents(expected: [ExpectedEvent], actual: [CommandEvent], context: Context) throws {
313-
guard actual.count == expected.count else {
312+
func matchesEvents(
313+
expected: [ExpectedEvent],
314+
actual: [CommandEvent],
315+
context: Context,
316+
ignoreExtraEvents: Bool
317+
) throws {
318+
// Ensure correct amount of events present (or more than enough if ignorable)
319+
guard (actual.count == expected.count) || (ignoreExtraEvents && actual.count >= expected.count) else {
314320
throw NonMatchingError(expected: expected, actual: actual, context: context)
315321
}
316322

317-
for i in 0..<actual.count {
323+
for i in 0..<expected.count {
318324
try context.withPushedElt(String(i)) {
319325
let expectedEvent = expected[i]
320326
let actualEvent = actual[i]

Tests/MongoSwiftSyncTests/UnifiedTestRunner/UnifiedTestRunner.swift

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ struct UnifiedTestRunner {
3838
let serverParameters: BSONDocument
3939

4040
static let minSchemaVersion = SchemaVersion(rawValue: "1.0.0")!
41-
static let maxSchemaVersion = SchemaVersion(rawValue: "1.5.0")!
41+
static let maxSchemaVersion = SchemaVersion(rawValue: "1.7.0")!
4242

4343
init() throws {
4444
switch MongoSwiftTestCase.topologyType {
@@ -219,7 +219,8 @@ struct UnifiedTestRunner {
219219
try matchesEvents(
220220
expected: expectedEventList.events,
221221
actual: actualEvents,
222-
context: context
222+
context: context,
223+
ignoreExtraEvents: expectedEventList.ignoreExtraEvents
223224
)
224225
}
225226
}

0 commit comments

Comments
 (0)