Skip to content

Commit 456e8eb

Browse files
authored
C++ migration: port watch stream-related part of FSTRemoteStore (#2331)
1 parent 3905bd2 commit 456e8eb

22 files changed

+767
-539
lines changed

Firestore/Example/Tests/Integration/FSTDatastoreTests.mm

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -219,7 +219,7 @@ - (void)testStreamingWrite {
219219
FSTRemoteStoreEventCapture *capture = [[FSTRemoteStoreEventCapture alloc] initWithTestCase:self];
220220
[capture expectWriteEventWithDescription:@"write mutations"];
221221

222-
_remoteStore.syncEngine = capture;
222+
[_remoteStore setSyncEngine:capture];
223223

224224
FSTSetMutation *mutation = [self setMutation];
225225
FSTMutationBatch *batch = [[FSTMutationBatch alloc] initWithBatchID:23

Firestore/Example/Tests/Local/FSTLocalStoreTests.mm

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
#import <FirebaseFirestore/FIRTimestamp.h>
2020
#import <XCTest/XCTest.h>
2121

22+
#include <vector>
23+
2224
#import "Firestore/Source/Core/FSTQuery.h"
2325
#import "Firestore/Source/Local/FSTLocalWriteResult.h"
2426
#import "Firestore/Source/Local/FSTPersistence.h"
@@ -51,6 +53,7 @@
5153
using firebase::firestore::model::SnapshotVersion;
5254
using firebase::firestore::model::TargetId;
5355
using firebase::firestore::remote::RemoteEvent;
56+
using firebase::firestore::remote::TestTargetMetadataProvider;
5457
using firebase::firestore::remote::WatchChangeAggregator;
5558
using firebase::firestore::remote::WatchTargetChange;
5659
using firebase::firestore::remote::WatchTargetChangeState;
@@ -906,9 +909,9 @@ - (void)testPersistsResumeTokens {
906909
NSData *resumeToken = FSTTestResumeTokenFromSnapshotVersion(1000);
907910

908911
WatchTargetChange watchChange{WatchTargetChangeState::Current, {targetID}, resumeToken};
909-
WatchChangeAggregator aggregator{[FSTTestTargetMetadataProvider
910-
providerWithSingleResultForKey:testutil::Key("foo/bar")
911-
targets:{targetID}]};
912+
auto metadataProvider = TestTargetMetadataProvider::CreateSingleResultProvider(
913+
testutil::Key("foo/bar"), std::vector<TargetId>{targetID});
914+
WatchChangeAggregator aggregator{&metadataProvider};
912915
aggregator.HandleTargetChange(watchChange);
913916
RemoteEvent remoteEvent = aggregator.CreateRemoteEvent(testutil::Version(1000));
914917
[self applyRemoteEvent:remoteEvent];

Firestore/Example/Tests/Remote/FSTRemoteEventTests.mm

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
using firebase::firestore::remote::ExistenceFilterWatchChange;
4747
using firebase::firestore::remote::RemoteEvent;
4848
using firebase::firestore::remote::TargetChange;
49+
using firebase::firestore::remote::TestTargetMetadataProvider;
4950
using firebase::firestore::remote::WatchChange;
5051
using firebase::firestore::remote::WatchChangeAggregator;
5152
using firebase::firestore::remote::WatchTargetChange;
@@ -92,13 +93,12 @@ @interface FSTRemoteEventTests : XCTestCase
9293

9394
@implementation FSTRemoteEventTests {
9495
NSData *_resumeToken1;
95-
FSTTestTargetMetadataProvider *_targetMetadataProvider;
96+
TestTargetMetadataProvider _targetMetadataProvider;
9697
std::unordered_map<TargetId, int> _noOutstandingResponses;
9798
}
9899

99100
- (void)setUp {
100101
_resumeToken1 = [@"resume1" dataUsingEncoding:NSUTF8StringEncoding];
101-
_targetMetadataProvider = [FSTTestTargetMetadataProvider new];
102102
}
103103

104104
/**
@@ -145,7 +145,7 @@ - (void)setUp {
145145
* considered active, or `_noOutstandingResponses` if all targets are already active.
146146
* @param existingKeys The set of documents that are considered synced with the test targets as
147147
* part of a previous listen. To modify this set during test execution, invoke
148-
* `[_targetMetadataProvider setSyncedKeys:forQueryData:]`.
148+
* `_targetMetadataProvider.SetSyncedKeys()`.
149149
* @param watchChanges The watch changes to apply before returning the aggregator. Supported
150150
* changes are `DocumentWatchChange` and `WatchTargetChange`.
151151
*/
@@ -154,15 +154,15 @@ - (void)setUp {
154154
outstandingResponses:(const std::unordered_map<TargetId, int> &)outstandingResponses
155155
existingKeys:(DocumentKeySet)existingKeys
156156
changes:(const std::vector<std::unique_ptr<WatchChange>> &)watchChanges {
157-
WatchChangeAggregator aggregator{_targetMetadataProvider};
157+
WatchChangeAggregator aggregator{&_targetMetadataProvider};
158158

159159
std::vector<TargetId> targetIDs;
160160
for (const auto &kv : targetMap) {
161161
TargetId targetID = kv.first;
162162
FSTQueryData *queryData = kv.second;
163163

164164
targetIDs.push_back(targetID);
165-
[_targetMetadataProvider setSyncedKeys:existingKeys forQueryData:queryData];
165+
_targetMetadataProvider.SetSyncedKeys(existingKeys, queryData);
166166
};
167167

168168
for (const auto &kv : outstandingResponses) {
@@ -223,7 +223,7 @@ - (void)setUp {
223223

224224
- (void)testWillAccumulateDocumentAddedAndRemovedEvents {
225225
// The target map that contains an entry for every target in this test. If a target ID is
226-
// omitted, the target is considered inactive and FSTTestTargetMetadataProvider will fail on
226+
// omitted, the target is considered inactive and `TestTargetMetadataProvider` will fail on
227227
// access.
228228
std::unordered_map<TargetId, FSTQueryData *> targetMap{
229229
[self queryDataForTargets:{1, 2, 3, 4, 5, 6}]};
@@ -614,8 +614,7 @@ - (void)testDocumentUpdate {
614614
XCTAssertEqualObjects(event.document_updates().at(doc1.key), doc1);
615615
XCTAssertEqualObjects(event.document_updates().at(doc2.key), doc2);
616616

617-
[_targetMetadataProvider setSyncedKeys:DocumentKeySet{doc1.key, doc2.key}
618-
forQueryData:targetMap[1]];
617+
_targetMetadataProvider.SetSyncedKeys(DocumentKeySet{doc1.key, doc2.key}, targetMap[1]);
619618

620619
FSTDeletedDocument *deletedDoc1 = [FSTDeletedDocument documentWithKey:doc1.key
621620
version:testutil::Version(3)

Firestore/Example/Tests/SpecTests/FSTMockDatastore.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ class MockDatastore : public Datastore {
3939
util::AsyncQueue* worker_queue,
4040
auth::CredentialsProvider* credentials);
4141

42-
std::shared_ptr<WatchStream> CreateWatchStream(id<FSTWatchStreamDelegate> delegate) override;
42+
std::shared_ptr<WatchStream> CreateWatchStream(WatchStreamCallback* callback) override;
4343
std::shared_ptr<WriteStream> CreateWriteStream(id<FSTWriteStreamDelegate> delegate) override;
4444

4545
/**

Firestore/Example/Tests/SpecTests/FSTMockDatastore.mm

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -70,11 +70,11 @@
7070
CredentialsProvider* credentials_provider,
7171
FSTSerializerBeta* serializer,
7272
GrpcConnection* grpc_connection,
73-
id<FSTWatchStreamDelegate> delegate,
73+
WatchStreamCallback* callback,
7474
MockDatastore* datastore)
75-
: WatchStream{worker_queue, credentials_provider, serializer, grpc_connection, delegate},
75+
: WatchStream{worker_queue, credentials_provider, serializer, grpc_connection, callback},
7676
datastore_{datastore},
77-
delegate_{delegate} {
77+
callback_{callback} {
7878
}
7979

8080
const std::unordered_map<TargetId, FSTQueryData*>& ActiveTargets() const {
@@ -84,7 +84,7 @@
8484
void Start() override {
8585
HARD_ASSERT(!open_, "Trying to start already started watch stream");
8686
open_ = true;
87-
[delegate_ watchStreamDidOpen];
87+
callback_->OnWatchStreamOpen();
8888
}
8989

9090
void Stop() override {
@@ -118,7 +118,7 @@ void UnwatchTargetId(model::TargetId target_id) override {
118118

119119
void FailStream(const Status& error) {
120120
open_ = false;
121-
[delegate_ watchStreamWasInterruptedWithError:error];
121+
callback_->OnWatchStreamClose(error);
122122
}
123123

124124
void WriteWatchChange(const WatchChange& change, SnapshotVersion snap) {
@@ -145,14 +145,14 @@ void WriteWatchChange(const WatchChange& change, SnapshotVersion snap) {
145145
}
146146
}
147147

148-
[delegate_ watchStreamDidChange:change snapshotVersion:snap];
148+
callback_->OnWatchStreamChange(change, snap);
149149
}
150150

151151
private:
152152
bool open_ = false;
153153
std::unordered_map<TargetId, FSTQueryData*> active_targets_;
154154
MockDatastore* datastore_ = nullptr;
155-
id<FSTWatchStreamDelegate> delegate_ = nullptr;
155+
WatchStreamCallback* callback_ = nullptr;
156156
};
157157

158158
class MockWriteStream : public WriteStream {
@@ -248,11 +248,11 @@ int sent_mutations_count() const {
248248
credentials_{credentials} {
249249
}
250250

251-
std::shared_ptr<WatchStream> MockDatastore::CreateWatchStream(id<FSTWatchStreamDelegate> delegate) {
251+
std::shared_ptr<WatchStream> MockDatastore::CreateWatchStream(WatchStreamCallback* callback) {
252252
watch_stream_ = std::make_shared<MockWatchStream>(
253253
worker_queue_, credentials_,
254254
[[FSTSerializerBeta alloc] initWithDatabaseID:&database_info_->database_id()],
255-
grpc_connection(), delegate, this);
255+
grpc_connection(), callback, this);
256256

257257
return watch_stream_;
258258
}

Firestore/Example/Tests/SpecTests/FSTSyncEngineTestDriver.mm

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@ - (instancetype)initWithPersistence:(id<FSTPersistence>)persistence
165165
_syncEngine = [[FSTSyncEngine alloc] initWithLocalStore:_localStore
166166
remoteStore:_remoteStore
167167
initialUser:initialUser];
168-
_remoteStore.syncEngine = _syncEngine;
168+
[_remoteStore setSyncEngine:_syncEngine];
169169
_eventManager = [FSTEventManager eventManagerWithSyncEngine:_syncEngine];
170170

171171
// Set up internal event tracking for the spec tests.

Firestore/Example/Tests/Util/FSTHelpers.h

Lines changed: 48 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#import <Foundation/Foundation.h>
1818

1919
#include <string>
20+
#include <unordered_map>
2021
#include <vector>
2122

2223
#import "Firestore/Source/Model/FSTDocument.h"
@@ -141,51 +142,57 @@ inline NSString *FSTRemoveExceptionPrefix(NSString *exception) {
141142
} while (0)
142143

143144
/**
144-
* An implementation of FSTTargetMetadataProvider that provides controlled access to the
145-
* `FSTTargetMetadataProvider` callbacks. Any target accessed via these callbacks must be
145+
* An implementation of `TargetMetadataProvider` that provides controlled access to the
146+
* `TargetMetadataProvider` callbacks. Any target accessed via these callbacks must be
146147
* registered beforehand via the factory methods or via `setSyncedKeys:forQueryData:`.
147148
*/
148-
@interface FSTTestTargetMetadataProvider : NSObject <FSTTargetMetadataProvider>
149-
150-
/**
151-
* Creates an FSTTestTargetMetadataProvider that behaves as if there's an established listen for
152-
* each of the given targets, where each target has previously seen query results containing just
153-
* the given documentKey.
154-
*
155-
* Internally this means that the `remoteKeysForTarget` callback for these targets will return just
156-
* the documentKey and that the provided targets will be returned as active from the
157-
* `queryDataForTarget` target.
158-
*/
159-
+ (instancetype)
160-
providerWithSingleResultForKey:(firebase::firestore::model::DocumentKey)documentKey
161-
targets:
162-
(const std::vector<firebase::firestore::model::TargetId> &)targets;
163-
164-
+ (instancetype)
165-
providerWithSingleResultForKey:(firebase::firestore::model::DocumentKey)documentKey
166-
listenTargets:
167-
(const std::vector<firebase::firestore::model::TargetId> &)listenTargets
168-
limboTargets:
169-
(const std::vector<firebase::firestore::model::TargetId> &)limboTargets;
170-
171-
/**
172-
* Creates an FSTTestTargetMetadataProvider that behaves as if there's an established listen for
173-
* each of the given targets, where each target has not seen any previous document.
174-
*
175-
* Internally this means that the `remoteKeysForTarget` callback for these targets will return an
176-
* empty set of document keys and that the provided targets will be returned as active from the
177-
* `queryDataForTarget` target.
178-
*/
179-
+ (instancetype)
180-
providerWithEmptyResultForKey:(firebase::firestore::model::DocumentKey)documentKey
181-
targets:
182-
(const std::vector<firebase::firestore::model::TargetId> &)targets;
149+
namespace firebase {
150+
namespace firestore {
151+
namespace remote {
183152

184-
/** Sets or replaces the local state for the provided query data. */
185-
- (void)setSyncedKeys:(firebase::firestore::model::DocumentKeySet)keys
186-
forQueryData:(FSTQueryData *)queryData;
153+
class TestTargetMetadataProvider : public TargetMetadataProvider {
154+
public:
155+
/**
156+
* Creates a `TestTargetMetadataProvider` that behaves as if there's an established listen for
157+
* each of the given targets, where each target has previously seen query results containing just
158+
* the given `document_key`.
159+
*
160+
* Internally this means that the `GetRemoteKeysForTarget` callback for these targets will return
161+
* just the `document_key` and that the provided targets will be returned as active from the
162+
* `GetQueryDataForTarget` target.
163+
*/
164+
static TestTargetMetadataProvider CreateSingleResultProvider(
165+
model::DocumentKey document_key, const std::vector<model::TargetId> &targets);
166+
static TestTargetMetadataProvider CreateSingleResultProvider(
167+
model::DocumentKey document_key,
168+
const std::vector<model::TargetId> &targets,
169+
const std::vector<model::TargetId> &limbo_targets);
170+
171+
/**
172+
* Creates an `TestTargetMetadataProvider` that behaves as if there's an established listen for
173+
* each of the given targets, where each target has not seen any previous document.
174+
*
175+
* Internally this means that the `GetRemoteKeysForTarget` callback for these targets will return
176+
* an empty set of document keys and that the provided targets will be returned as active from the
177+
* `GetQueryDataForTarget` target.
178+
*/
179+
static TestTargetMetadataProvider CreateEmptyResultProvider(
180+
const model::DocumentKey &document_key, const std::vector<model::TargetId> &targets);
181+
182+
/** Sets or replaces the local state for the provided query data. */
183+
void SetSyncedKeys(model::DocumentKeySet keys, FSTQueryData *query_data);
184+
185+
model::DocumentKeySet GetRemoteKeysForTarget(model::TargetId target_id) const override;
186+
FSTQueryData *GetQueryDataForTarget(model::TargetId target_id) const override;
187+
188+
private:
189+
std::unordered_map<model::TargetId, model::DocumentKeySet> synced_keys_;
190+
std::unordered_map<model::TargetId, FSTQueryData *> query_data_;
191+
};
187192

188-
@end
193+
} // namespace remote
194+
} // namespace firestore
195+
} // namespace firebase
189196

190197
/** Creates a new FIRTimestamp from components. Note that year, month, and day are all one-based. */
191198
FIRTimestamp *FSTTestTimestamp(int year, int month, int day, int hour, int minute, int second);

0 commit comments

Comments
 (0)