Skip to content

Commit ac75cce

Browse files
author
Alex Ames
authored
Merge pull request #392 from firebase/bugfix/database-sync-point-test-fixes
Fixed a number of minor issues with database.
2 parents 7ebd34a + d5e9b14 commit ac75cce

File tree

11 files changed

+46
-58
lines changed

11 files changed

+46
-58
lines changed

database/src/desktop/core/indexed_variant.cc

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -145,19 +145,18 @@ void IndexedVariant::EnsureIndexed() {
145145
PruneNulls(&variant_);
146146

147147
for (const auto& entry : variant_.map()) {
148+
if (entry.first.is_string() && entry.first.string_value()[0] == '.') {
149+
// Do not index pseudo-keys.
150+
continue;
151+
}
148152
index_.insert(entry);
149153
}
150154
}
151155

152156
IndexedVariant IndexedVariant::UpdateChild(const std::string& key,
153157
const Variant& child) const {
154-
// Remove element.
155-
Variant result = variant_.is_map() ? variant_ : Variant::EmptyMap();
156-
if (child.is_null()) {
157-
result.map().erase(key);
158-
} else {
159-
result.map()[key] = child;
160-
}
158+
Variant result = variant_;
159+
VariantUpdateChild(&result, key, child);
161160
return IndexedVariant(result, query_params_);
162161
}
163162

database/src/desktop/view/child_change_accumulator.cc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,8 @@ void TrackChildChange(const Change& change,
6060
} else if (type == kEventTypeChildRemoved &&
6161
old_type == kEventTypeChildChanged) {
6262
// Change from kTypeChildChanged to kTypeChildRemoved => kTypeChildRemoved
63-
iter->second = ChildRemovedChange(child_key, old_change.indexed_variant);
63+
iter->second =
64+
ChildRemovedChange(child_key, old_change.old_indexed_variant);
6465
} else if (type == kEventTypeChildChanged &&
6566
old_type == kEventTypeChildAdded) {
6667
// Change from kTypeChildAdded to kTypeChildChanged => kTypeChildAdded

database/src/desktop/view/indexed_filter.cc

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,10 @@ IndexedVariant IndexedFilter::UpdateFullVariant(
8686
const Variant* new_value = GetVariantValue(&new_snap.variant());
8787
if (old_value->is_map()) {
8888
for (auto& key_value_pair : old_value->map()) {
89+
if (key_value_pair.first.string_value()[0] == '.') {
90+
// Do not create events for pseudo-keys.
91+
continue;
92+
}
8993
const Variant& key = key_value_pair.first;
9094
const Variant& value = key_value_pair.second;
9195
if (!GetInternalVariant(new_value, key)) {
@@ -97,6 +101,10 @@ IndexedVariant IndexedFilter::UpdateFullVariant(
97101
if (new_value->is_map()) {
98102
// Check which elements were changed or added.
99103
for (auto& key_value_pair : new_value->map()) {
104+
if (key_value_pair.first.string_value()[0] == '.') {
105+
// Do not create events for pseudo-keys.
106+
continue;
107+
}
100108
std::string key = key_value_pair.first.string_value();
101109
const Variant& value = key_value_pair.second;
102110
const Variant* old_child = GetInternalVariant(old_value, key);

database/src/desktop/view/limited_filter.cc

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,9 @@ IndexedVariant LimitedFilter::UpdatePriority(
121121
return old_snap;
122122
}
123123

124-
const VariantFilter* LimitedFilter::GetIndexedFilter() const { return this; }
124+
const VariantFilter* LimitedFilter::GetIndexedFilter() const {
125+
return ranged_filter_->GetIndexedFilter();
126+
}
125127

126128
bool LimitedFilter::FiltersVariants() const { return true; }
127129

database/src/desktop/view/ranged_filter.cc

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,9 @@ IndexedVariant RangedFilter::UpdatePriority(const IndexedVariant& old_snap,
7676
return old_snap;
7777
}
7878

79-
const VariantFilter* RangedFilter::GetIndexedFilter() const { return this; }
79+
const VariantFilter* RangedFilter::GetIndexedFilter() const {
80+
return indexed_filter_.get();
81+
}
8082

8183
bool RangedFilter::FiltersVariants() const { return true; }
8284

database/src/desktop/view/view.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ std::vector<Event> View::ApplyOperation(
152152
const Variant* opt_complete_server_cache,
153153
std::vector<Change>* out_changes) {
154154
if (operation.type == Operation::kTypeMerge &&
155-
!operation.source.query_params.has_value()) {
155+
operation.source.query_params.has_value()) {
156156
FIREBASE_DEV_ASSERT_MESSAGE(
157157
view_cache_.GetCompleteServerSnap() != nullptr,
158158
"We should always have a full cache before handling merges");

database/src/desktop/view/view_processor.cc

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -384,9 +384,8 @@ ViewCache ViewProcessor::ApplyServerOverwrite(
384384
ChildChangeAccumulator* accumulator) {
385385
CacheNode old_server_snap = old_view_cache.server_snap();
386386
IndexedVariant new_server_cache;
387-
IndexedFilter default_filter((QueryParams()));
388-
VariantFilter* server_filter =
389-
filter_server_node ? filter_.get() : &default_filter;
387+
const VariantFilter* server_filter =
388+
filter_server_node ? filter_.get() : filter_->GetIndexedFilter();
390389

391390
if (change_path.empty()) {
392391
// If the path is empty, we can just apply the overwrite directly.
@@ -420,8 +419,8 @@ ViewCache ViewProcessor::ApplyServerOverwrite(
420419
VariantUpdateChild(&new_child_node, child_change_path, changed_snap);
421420
if (IsPriorityKey(child_key.str())) {
422421
// If this is a priority node, update the priority on the indexed node.
423-
new_server_cache =
424-
server_filter->UpdatePriority(new_server_cache, new_child_node);
422+
new_server_cache = server_filter->UpdatePriority(
423+
old_server_snap.indexed_variant(), new_child_node);
425424
} else {
426425
// If this is a regular update, the update through the filter to make sure
427426
// we get only the values that are not filtered by the query spec.

database/tests/desktop/core/sync_point_spec_test.cc

Lines changed: 10 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,6 @@ class TestEventRegistration : public EventRegistration {
160160
}
161161

162162
bool MatchesListener(const void* listener_ptr) const override {
163-
EXPECT_TRUE(false) << "Can't raise test events!";
164163
return static_cast<const void*>(this) == listener_ptr;
165164
}
166165
};
@@ -257,7 +256,8 @@ void SyncTreeTest::RunTest(const test_data::TestCase* test_spec,
257256
EventRegistration* event_registration = nullptr;
258257
int callback_id = spec->callbackId();
259258
if (callback_id != 0 && registrations.count(callback_id) != 0) {
260-
event_registration = registrations[callback_id];
259+
event_registration = new TestEventRegistration(
260+
registrations[callback_id]->query_spec());
261261
} else {
262262
event_registration = new TestEventRegistration(query->query_spec());
263263
if (callback_id != 0) {
@@ -296,8 +296,9 @@ void SyncTreeTest::RunTest(const test_data::TestCase* test_spec,
296296
break;
297297
}
298298
case test_data::StepType_serverMerge: {
299-
std::map<Path, Variant> merges =
300-
VariantToPathMap(FlexbufferToVariant(spec->data_flexbuffer_root()));
299+
std::map<Path, Variant> merges = VariantToPathMap(
300+
spec->data() ? FlexbufferToVariant(spec->data_flexbuffer_root())
301+
: Variant::Null());
301302
std::vector<Event> actual;
302303
if (spec->tag()) {
303304
actual =
@@ -309,7 +310,9 @@ void SyncTreeTest::RunTest(const test_data::TestCase* test_spec,
309310
break;
310311
}
311312
case test_data::StepType_set: {
312-
Variant to_set = FlexbufferToVariant(spec->data_flexbuffer_root());
313+
Variant to_set = spec->data()
314+
? FlexbufferToVariant(spec->data_flexbuffer_root())
315+
: Variant::Null();
313316
OverwriteVisibility visible =
314317
spec->visible() ? kOverwriteVisible : kOverwriteInvisible;
315318
// For now, assume anything visible should be persisted.
@@ -321,7 +324,8 @@ void SyncTreeTest::RunTest(const test_data::TestCase* test_spec,
321324
}
322325
case test_data::StepType_update: {
323326
CompoundWrite merges = CompoundWrite::FromVariantMerge(
324-
FlexbufferToVariant(spec->data_flexbuffer_root()));
327+
spec->data() ? FlexbufferToVariant(spec->data_flexbuffer_root())
328+
: Variant::Null());
325329
std::vector<Event> actual = sync_tree_->ApplyUserMerge(
326330
path, merges, merges, current_write_id++, kPersist);
327331
EXPECT_THAT(actual, UnorderedPointwise(EventEq(), expected));
@@ -420,12 +424,10 @@ TEST_F(SyncTreeTest, AQueryCanGetACompleteCacheThenAMerge) {
420424
}
421425

422426
TEST_F(SyncTreeTest, ServerMergeOnListenerWithCompleteChildren) {
423-
GTEST_SKIP(); // Fails assert.
424427
RunOne("Server merge on listener with complete children");
425428
}
426429

427430
TEST_F(SyncTreeTest, DeepMergeOnListenerWithCompleteChildren) {
428-
GTEST_SKIP(); // Fails assert.
429431
RunOne("Deep merge on listener with complete children");
430432
}
431433

@@ -490,7 +492,6 @@ TEST_F(SyncTreeTest, RevertDeepSetWithNoServerData) {
490492
}
491493

492494
TEST_F(SyncTreeTest, RevertSetCoveredByNonvisibleTransaction) {
493-
GTEST_SKIP(); // Fails expectations.
494495
RunOne("Revert set covered by non-visible transaction");
495496
}
496497

@@ -511,17 +512,14 @@ TEST_F(SyncTreeTest, CanSetAlongsideARemoteMerge) {
511512
}
512513

513514
TEST_F(SyncTreeTest, SetPriorityOnALocationWithNoCache) {
514-
// GTEST_SKIP();
515515
RunOne("setPriority on a location with no cache");
516516
}
517517

518518
TEST_F(SyncTreeTest, DeepUpdateDeletesChildFromLimitWindowAndPullsInNewChild) {
519-
GTEST_SKIP(); // Fails assert.
520519
RunOne("deep update deletes child from limit window and pulls in new child");
521520
}
522521

523522
TEST_F(SyncTreeTest, DeepSetDeletesChildFromLimitWindowAndPullsInNewChild) {
524-
GTEST_SKIP(); // Fails assert.
525523
RunOne("deep set deletes child from limit window and pulls in new child");
526524
}
527525

@@ -534,7 +532,6 @@ TEST_F(SyncTreeTest, RevertSetInQueryWindow) {
534532
}
535533

536534
TEST_F(SyncTreeTest, HandlesAServerValueMovingAChildOutOfAQueryWindow) {
537-
GTEST_SKIP(); // Fails assert.
538535
RunOne("Handles a server value moving a child out of a query window");
539536
}
540537

@@ -551,12 +548,10 @@ TEST_F(SyncTreeTest, LimitIsRefilledFromServerDataAfterMerge) {
551548
}
552549

553550
TEST_F(SyncTreeTest, HandleRepeatedListenWithMergeAsFirstUpdate) {
554-
GTEST_SKIP(); // Fails assert.
555551
RunOne("Handle repeated listen with merge as first update");
556552
}
557553

558554
TEST_F(SyncTreeTest, LimitIsRefilledFromServerDataAfterSet) {
559-
GTEST_SKIP(); // Fails assert.
560555
RunOne("Limit is refilled from server data after set");
561556
}
562557

@@ -615,7 +610,6 @@ TEST_F(SyncTreeTest, WriteLeafNodeOverwriteAtParentNode) {
615610
}
616611

617612
TEST_F(SyncTreeTest, ConfirmCompleteChildrenFromTheServer) {
618-
GTEST_SKIP(); // Fails expectations.
619613
RunOne("Confirm complete children from the server");
620614
}
621615

@@ -634,7 +628,6 @@ TEST_F(SyncTreeTest, BasicKeyIndexSanityCheck) {
634628
}
635629

636630
TEST_F(SyncTreeTest, CollectCorrectSubviewsToListenOn) {
637-
GTEST_SKIP(); // Fails assert.
638631
RunOne("Collect correct subviews to listen on");
639632
}
640633

@@ -663,7 +656,6 @@ TEST_F(SyncTreeTest, ServerDataIsNotPurgedForNonServerIndexedQueries) {
663656
}
664657

665658
TEST_F(SyncTreeTest, LimitWithCustomOrderByIsRefilledWithCorrectItem) {
666-
GTEST_SKIP(); // Fails assert.
667659
RunOne("Limit with custom orderBy is refilled with correct item");
668660
}
669661

@@ -680,7 +672,6 @@ TEST_F(SyncTreeTest, LimitedQueryDoesntPullInOutOfRangeChild) {
680672
}
681673

682674
TEST_F(SyncTreeTest, MergerForLocationWithDefaultAndLimitedListener) {
683-
GTEST_SKIP(); // Fails assert.
684675
RunOne("Merge for location with default and limited listener");
685676
}
686677

@@ -716,7 +707,6 @@ TEST_F(SyncTreeTest, UserWriteWithDeepOverwrite) {
716707
TEST_F(SyncTreeTest, DeepServerMerge) { RunOne("Deep server merge"); }
717708

718709
TEST_F(SyncTreeTest, ServerUpdatesPriority) {
719-
GTEST_SKIP(); // Fails expectations.
720710
RunOne("Server updates priority");
721711
}
722712

@@ -729,27 +719,22 @@ TEST_F(SyncTreeTest, UserChildOverwriteForNonexistentServerNode) {
729719
}
730720

731721
TEST_F(SyncTreeTest, RevertUserOverwriteOfChildOnLeafNode) {
732-
GTEST_SKIP(); // Fails expectations.
733722
RunOne("Revert user overwrite of child on leaf node");
734723
}
735724

736725
TEST_F(SyncTreeTest, ServerOverwriteWithDeepUserDelete) {
737-
GTEST_SKIP(); // Fails assert.
738726
RunOne("Server overwrite with deep user delete");
739727
}
740728

741729
TEST_F(SyncTreeTest, UserOverwritesLeafNodeWithPriority) {
742-
GTEST_SKIP(); // Fails expectations.
743730
RunOne("User overwrites leaf node with priority");
744731
}
745732

746733
TEST_F(SyncTreeTest, UserOverwritesInheritPriorityValuesFromLeafNodes) {
747-
GTEST_SKIP(); // Fails assert.
748734
RunOne("User overwrites inherit priority values from leaf nodes");
749735
}
750736

751737
TEST_F(SyncTreeTest, UserUpdateOnUserSetLeafNodeWithPriorityAfterServerUpdate) {
752-
GTEST_SKIP(); // Fails expectations.
753738
RunOne("User update on user set leaf node with priority after server update");
754739
}
755740

@@ -762,32 +747,26 @@ TEST_F(SyncTreeTest, UserSetsRootPriority) {
762747
}
763748

764749
TEST_F(SyncTreeTest, UserUpdatesPriorityOnEmptyRoot) {
765-
GTEST_SKIP(); // Fails assert.
766750
RunOne("User updates priority on empty root");
767751
}
768752

769753
TEST_F(SyncTreeTest, RevertSetAtRootWithPriority) {
770-
GTEST_SKIP(); // Fails assert.
771754
RunOne("Revert set at root with priority");
772755
}
773756

774757
TEST_F(SyncTreeTest, ServerUpdatesPriorityAfterUserSetsPriority) {
775-
GTEST_SKIP(); // Fails expectations.
776758
RunOne("Server updates priority after user sets priority");
777759
}
778760

779761
TEST_F(SyncTreeTest, EmptySetDoesntPreventServerUpdates) {
780-
GTEST_SKIP(); // Fails assert.
781762
RunOne("Empty set doesn't prevent server updates");
782763
}
783764

784765
TEST_F(SyncTreeTest, UserUpdatesPriorityTwiceFirstIsReverted) {
785-
GTEST_SKIP(); // Fails expectations.
786766
RunOne("User updates priority twice, first is reverted");
787767
}
788768

789769
TEST_F(SyncTreeTest, ServerAcksRootPrioritySetAfterUserDeletesRootNode) {
790-
GTEST_SKIP(); // Fails assert.
791770
RunOne("Server acks root priority set after user deletes root node");
792771
}
793772

@@ -796,7 +775,6 @@ TEST_F(SyncTreeTest, ADeleteInAMergeDoesntPushOutNodes) {
796775
}
797776

798777
TEST_F(SyncTreeTest, ATaggedQueryFiresEventsEventually) {
799-
GTEST_SKIP(); // Fails assert.
800778
RunOne("A tagged query fires events eventually");
801779
}
802780

@@ -817,13 +795,11 @@ TEST_F(SyncTreeTest, ClearParentShadowingServerValuesMergeWithServerChildren) {
817795
}
818796

819797
TEST_F(SyncTreeTest, PrioritiesDontMakeMeSick) {
820-
GTEST_SKIP(); // Fails assert.
821798
RunOne("Priorities don't make me sick");
822799
}
823800

824801
TEST_F(SyncTreeTest,
825802
MergeThatMovesChildFromWindowToBoundaryDoesNotCauseChildToBeReadded) {
826-
GTEST_SKIP(); // Fails expectations.
827803
RunOne(
828804
"Merge that moves child from window to boundary does not cause child "
829805
"to be readded");
@@ -865,7 +841,6 @@ TEST_F(SyncTreeTest, UnrelatedAckedUpdateIsNotCachedInTaggedListen) {
865841
}
866842

867843
TEST_F(SyncTreeTest, DeepUpdateRaisesImmediateEventsOnlyIfHasCompleteData) {
868-
GTEST_SKIP(); // Fails expectations.
869844
RunOne("Deep update raises immediate events only if has complete data");
870845
}
871846

database/tests/desktop/view/child_change_accumulator_test.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -121,15 +121,15 @@ TEST(ChildChangeAccumulator, TrackChildChangeAddedThenRemoved) {
121121
// in sequence.
122122
TEST(ChildChangeAccumulator, TrackChildChangeChangedThenRemoved) {
123123
ChildChangeAccumulator accumulator;
124-
TrackChildChange(ChildChangedChange("ChildChangeThenRemove", "old", "order"),
124+
TrackChildChange(ChildChangedChange("ChildChangeThenRemove", "old", "older"),
125125
&accumulator);
126126
// Note: the removed value "new" does not need to match the value "old"
127127
// changed previously.
128128
TrackChildChange(ChildRemovedChange("ChildChangeThenRemove", "new"),
129129
&accumulator);
130130

131131
// Expected result should be a ChildRemoved change from "old" value
132-
Change expected = ChildRemovedChange("ChildChangeThenRemove", "old");
132+
Change expected = ChildRemovedChange("ChildChangeThenRemove", "older");
133133

134134
auto it = accumulator.find("ChildChangeThenRemove");
135135
ASSERT_NE(it, accumulator.end());

database/tests/desktop/view/indexed_filter_test.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,7 @@ TEST(IndexedFilter, UpdateChild_RemovedValue) {
175175
CompleteChildSource* source = nullptr;
176176
ChildChangeAccumulator change_accumulator;
177177

178-
IndexedVariant expected_result(Variant::EmptyMap());
178+
IndexedVariant expected_result(Variant::Null());
179179
ChildChangeAccumulator expected_changes{
180180
std::make_pair(
181181
"aaa",

0 commit comments

Comments
 (0)