diff --git a/root/crawler.cpp b/root/crawler.cpp index a2060648adc4..df8416551553 100644 --- a/root/crawler.cpp +++ b/root/crawler.cpp @@ -145,7 +145,7 @@ void InMemoryView::crawler( logf(DBG, "in crawler calling process_path on {}\n", full_path); int newFlags = 0; - if (recursive || !(file && file->exists)) { + if (recursive || !file || !file->exists) { newFlags |= W_PENDING_RECURSIVE; } diff --git a/tests/PendingCollectionTest.cpp b/tests/PendingCollectionTest.cpp index 831c3fefe1fa..2e595461411d 100644 --- a/tests/PendingCollectionTest.cpp +++ b/tests/PendingCollectionTest.cpp @@ -137,6 +137,15 @@ class NaivePendingCollection { const w_string& path, std::chrono::system_clock::time_point now, int flags) { + for (std::shared_ptr p = head_; p; p = p->next) { + if (w_string_startswith(path, p->path) && + watchman::is_path_prefix(path, p->path)) { + if (p->flags & W_PENDING_RECURSIVE) { + return; + } + } + } + for (std::shared_ptr p = head_; p; p = p->next) { if (p->path == path) { // consolidateItem @@ -185,7 +194,7 @@ class NaivePendingCollection { std::shared_ptr head_; }; -using PCTypes = ::testing::Types; +using PCTypes = ::testing::Types; } // namespace @@ -236,9 +245,36 @@ TYPED_TEST(PendingCollectionFixture, same_item_consolidates) { } TYPED_TEST(PendingCollectionFixture, prune_obsoleted_children) { - int flags = 0; - this->coll.add(w_string{"foo/bar"}, this->now, flags); + this->coll.add(w_string{"foo/bar"}, this->now, 0); + this->coll.add(w_string{"foo"}, this->now, W_PENDING_RECURSIVE); + + auto item = this->coll.stealItems(); + ASSERT_NE(nullptr, item); + EXPECT_EQ(nullptr, item->next); + EXPECT_EQ(w_string{"foo"}, item->path); + EXPECT_EQ(W_PENDING_RECURSIVE, item->flags); +} + +TYPED_TEST( + PendingCollectionFixture, + recursive_parents_prevent_children_from_being_added) { + this->coll.add(w_string{"foo"}, this->now, W_PENDING_RECURSIVE); + this->coll.add(w_string{"foo/bar"}, this->now, 0); + + auto item = this->coll.stealItems(); + ASSERT_NE(nullptr, item); + EXPECT_EQ(nullptr, item->next); + EXPECT_EQ(w_string{"foo"}, item->path); + EXPECT_EQ(W_PENDING_RECURSIVE, item->flags); +} + +TYPED_TEST( + PendingCollectionFixture, + mixed_addition_is_cleared_by_recursive_parents) { + this->coll.add(w_string{"foo/bar"}, this->now, 0); + this->coll.add(w_string{"foo/bar/baz"}, this->now, 0); this->coll.add(w_string{"foo"}, this->now, W_PENDING_RECURSIVE); + this->coll.add(w_string{"foo/bar/baz/qux"}, this->now, 0); auto item = this->coll.stealItems(); ASSERT_NE(nullptr, item);