aboutsummaryrefslogtreecommitdiffstats
path: root/streamingvisitors/src/tests/searchvisitor/searchvisitor_test.cpp
diff options
context:
space:
mode:
authorGeir Storli <geirst@yahooinc.com>2023-04-27 14:01:00 +0000
committerGeir Storli <geirst@yahooinc.com>2023-04-27 14:11:03 +0000
commit232b1d3460c1a15aa64e1aae3f516dbfda290701 (patch)
treefce0623f10d0656bf90010b0d80fd8561b339019 /streamingvisitors/src/tests/searchvisitor/searchvisitor_test.cpp
parentf5dd3cb5d31875cf596adc01f2207f690afe553f (diff)
Test basic query execution in search visitor.
Diffstat (limited to 'streamingvisitors/src/tests/searchvisitor/searchvisitor_test.cpp')
-rw-r--r--streamingvisitors/src/tests/searchvisitor/searchvisitor_test.cpp224
1 files changed, 177 insertions, 47 deletions
diff --git a/streamingvisitors/src/tests/searchvisitor/searchvisitor_test.cpp b/streamingvisitors/src/tests/searchvisitor/searchvisitor_test.cpp
index 5521994e60e..b93a2c25f82 100644
--- a/streamingvisitors/src/tests/searchvisitor/searchvisitor_test.cpp
+++ b/streamingvisitors/src/tests/searchvisitor/searchvisitor_test.cpp
@@ -1,6 +1,8 @@
// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
#include <vespa/document/base/testdocrepo.h>
+#include <vespa/document/datatype/documenttype.h>
+#include <vespa/document/fieldvalue/document.h>
#include <vespa/document/repo/documenttyperepo.h>
#include <vespa/persistence/spi/docentry.h>
#include <vespa/searchlib/query/tree/querybuilder.h>
@@ -22,27 +24,149 @@ using namespace storage;
namespace streaming {
-class SearchVisitorTest : public testing::Test
-{
+vespalib::string get_doc_id(int id) {
+ return "id:test:test::" + std::to_string(id);
+}
+
+/**
+ * This class reflects the document type defined in cfg/test.sd.
+ */
+struct MyDocument {
+ int id;
+ MyDocument(int id_in) : id(id_in) {}
+ std::unique_ptr<Document> to_document(const DocumentTypeRepo& repo, const DataType& doc_type) const {
+ auto result = std::make_unique<Document>(repo, doc_type, DocumentId(get_doc_id(id)));
+ result->setValue("id", std::make_unique<IntFieldValue>(id));
+ return result;
+ }
+};
+
+using DocumentVector = std::vector<MyDocument>;
+
+struct MyHit {
+ vespalib::string doc_id;
+ double rank;
+ MyHit(int id, double rank_in) noexcept : doc_id(get_doc_id(id)), rank(rank_in) {}
+ MyHit(int id) noexcept : doc_id(get_doc_id(id)), rank(0.0) {}
+ MyHit(const vespalib::string& doc_id_in, double rank_in) noexcept : doc_id(doc_id_in), rank(rank_in) {}
+ bool operator==(const MyHit& rhs) const {
+ return (doc_id == rhs.doc_id) &&
+ (rank == rhs.rank);
+ }
+};
+
+using HitVector = std::vector<MyHit>;
+
+std::ostream& operator<<(std::ostream& oss, const MyHit& hit) {
+ oss << "{doc_id=" << hit.doc_id << ",rank=" << hit.rank << "}";
+ return oss;
+}
+
+class RequestBuilder {
+private:
+ vdslib::Parameters _params;
+ QueryBuilder<SimpleQueryNodeTypes> _builder;
+ int32_t _term_id;
+
+public:
+ RequestBuilder() : _params(), _builder(), _term_id(1)
+ {
+ search_cluster("mycl");
+ rank_profile("myrank");
+ summary_class("mysum");
+ summary_count(10);
+ }
+ RequestBuilder& set_param(const vespalib::string& key, const vespalib::string& value) {
+ _params.set(key, value);
+ return *this;
+ }
+ RequestBuilder& search_cluster(const vespalib::string& value) { return set_param("searchcluster", value); }
+ RequestBuilder& rank_profile(const vespalib::string& value) { return set_param("rankprofile", value); }
+ RequestBuilder& summary_class(const vespalib::string& value) { return set_param("summaryclass", value); }
+ RequestBuilder& summary_count(uint32_t value) { return set_param("summarycount", std::to_string(value)); }
+ RequestBuilder& string_term(const vespalib::string& term, const vespalib::string& field) {
+ _builder.addStringTerm(term, field, _term_id++, Weight(100));
+ return *this;
+ }
+ RequestBuilder& number_term(const vespalib::string& term, const vespalib::string& field) {
+ _builder.addNumberTerm(term, field, _term_id++, Weight(100));
+ return *this;
+ }
+ vdslib::Parameters build() {
+ auto node = _builder.build();
+ vespalib::string query_stack_dump = StackDumpCreator::create(*node);
+ _params.set("query", query_stack_dump);
+ return _params;
+ }
+};
+
+struct VisitorSession {
+ std::unique_ptr<SearchVisitor> search_visitor;
+ Visitor& visitor;
+ Visitor::HitCounter hit_counter;
+ VisitorSession(SearchVisitor* sv)
+ : search_visitor(sv),
+ visitor(*search_visitor),
+ hit_counter()
+ {
+ }
+ void handle_documents(Visitor::DocEntryList& docs) {
+ document::BucketId bucket_id;
+ visitor.handleDocuments(bucket_id, docs, hit_counter);
+ }
+ std::unique_ptr<documentapi::QueryResultMessage> generate_query_result() {
+ return search_visitor->generate_query_result(hit_counter);
+ }
+};
+
+class SearchVisitorTest : public testing::Test {
public:
framework::defaultimplementation::FakeClock _clock;
StorageComponentRegisterImpl _componentRegister;
std::unique_ptr<StorageComponent> _component;
SearchEnvironment _env;
- void testCreateSearchVisitor(const vespalib::string & dir, const vdslib::Parameters & parameters);
+ SearchVisitorFactory _factory;
+ std::shared_ptr<DocumentTypeRepo> _repo;
+ const document::DocumentType* _doc_type;
SearchVisitorTest();
~SearchVisitorTest() override;
+
+ std::unique_ptr<VisitorSession> make_visitor_session(const vdslib::Parameters& params) {
+ VisitorFactory& factory(_factory);
+ auto *visitor = factory.makeVisitor(*_component, _env, params);
+ auto *search_visitor = dynamic_cast<SearchVisitor *>(visitor);
+ assert(search_visitor != nullptr);
+ return std::make_unique<VisitorSession>(search_visitor);
+ }
+ Visitor::DocEntryList make_documents(const std::vector<MyDocument>& docs) const {
+ Visitor::DocEntryList result;
+ for (const auto& doc : docs) {
+ result.push_back(spi::DocEntry::create(spi::Timestamp(),
+ doc.to_document(*_repo, *_doc_type)));
+ }
+ return result;
+ }
+ std::unique_ptr<documentapi::QueryResultMessage> execute_query(const vdslib::Parameters& params,
+ const DocumentVector& docs) {
+ auto session = make_visitor_session(params);
+ auto entries = make_documents(docs);
+ session->handle_documents(entries);
+ return session->generate_query_result();
+ }
};
SearchVisitorTest::SearchVisitorTest() :
_componentRegister(),
- _env(::config::ConfigUri("dir:cfg"))
+ _env(::config::ConfigUri("dir:cfg")),
+ _factory(::config::ConfigUri("dir:cfg")),
+ _repo(std::make_shared<DocumentTypeRepo>(readDocumenttypesConfig("cfg/documenttypes.cfg"))),
+ _doc_type(_repo->getDocumentType("test"))
{
- _componentRegister.setNodeInfo("mycluster", lib::NodeType::STORAGE, 1);
+ assert(_doc_type != nullptr);
+ _componentRegister.setNodeInfo("mycl", lib::NodeType::STORAGE, 1);
_componentRegister.setClock(_clock);
- auto repo = std::make_shared<DocumentTypeRepo>(readDocumenttypesConfig("cfg/documenttypes.cfg"));
- _componentRegister.setDocumentTypeRepo(repo);
+ _componentRegister.setDocumentTypeRepo(_repo);
_component = std::make_unique<StorageComponent>(_componentRegister, "storage");
}
@@ -51,61 +175,67 @@ SearchVisitorTest::~SearchVisitorTest()
_env.clear_thread_local_env_map();
}
-Visitor::DocEntryList
-createDocuments(const vespalib::string & dir)
+TEST_F(SearchVisitorTest, search_environment_is_configured)
+{
+ EXPECT_TRUE(_env.getVSMAdapter("mycl") != nullptr);
+ EXPECT_TRUE(_env.getRankManager("mycl") != nullptr);
+}
+
+HitVector
+to_hit_vector(vdslib::SearchResult& res)
+{
+ HitVector result;
+ const char* doc_id;
+ double rank;
+ for (size_t i = 0; i < res.getHitCount(); ++i) {
+ res.getHit(i, doc_id, rank);
+ result.emplace_back(vespalib::string(doc_id), rank);
+ }
+ return result;
+}
+
+HitVector
+to_hit_vector(vdslib::DocumentSummary& sum)
{
- (void) dir;
- Visitor::DocEntryList documents;
- spi::Timestamp ts;
- auto e = spi::DocEntry::create(ts, std::make_unique<Document>());
- documents.push_back(std::move(e));
- return documents;
+ HitVector result;
+ const char* doc_id;
+ const void* buf;
+ size_t sz;
+ for (size_t i = 0; i < sum.getSummaryCount(); ++i) {
+ sum.getSummary(i, doc_id, buf, sz);
+ result.emplace_back(vespalib::string(doc_id), 0.0);
+ }
+ return result;
}
void
-SearchVisitorTest::testCreateSearchVisitor(const vespalib::string & dir, const vdslib::Parameters & params)
+expect_hits(const HitVector& exp_hits, documentapi::QueryResultMessage& res)
{
- ::config::ConfigUri uri(dir);
- SearchVisitorFactory sFactory(uri);
- VisitorFactory & factory(sFactory);
- std::unique_ptr<Visitor> sv(static_cast<SearchVisitor *>(factory.makeVisitor(*_component, _env, params)));
- document::BucketId bucketId;
- Visitor::DocEntryList documents(createDocuments(dir));
- Visitor::HitCounter hitCounter;
- sv->handleDocuments(bucketId, documents, hitCounter);
+ EXPECT_EQ(exp_hits.size(), res.getSearchResult().getHitCount());
+ EXPECT_EQ(exp_hits, to_hit_vector(res.getSearchResult()));
}
-TEST_F(SearchVisitorTest, test_search_environment)
+void
+expect_summary(const HitVector& exp_summary, documentapi::QueryResultMessage& res)
{
- EXPECT_TRUE(_env.getVSMAdapter("simple") != nullptr);
- EXPECT_TRUE(_env.getRankManager("simple") != nullptr);
+ EXPECT_EQ(exp_summary.size(), res.getDocumentSummary().getSummaryCount());
+ EXPECT_EQ(exp_summary, to_hit_vector(res.getDocumentSummary()));
}
-TEST_F(SearchVisitorTest, test_search_visitor)
+TEST_F(SearchVisitorTest, basic_query_execution_in_search_visitor)
{
- vdslib::Parameters params;
- params.set("searchcluster", "aaa");
- params.set("queryflags", "0x40000");
- params.set("summarycount", "3");
- params.set("summaryclass", "petra");
- params.set("rankprofile", "default");
-
- QueryBuilder<SimpleQueryNodeTypes> builder;
- builder.addStringTerm("maptest", "sddocname", 0, Weight(0));
- Node::UP node = builder.build();
- vespalib::string stackDump = StackDumpCreator::create(*node);
-
- params.set("query", stackDump);
- testCreateSearchVisitor("dir:cfg", params);
+ auto res = execute_query(RequestBuilder().
+ number_term("[5;10]", "id").build(),
+ {{3},{7},{4},{5},{9}});
+ expect_hits({{9,19.0}, {7,17.0}, {5,15.0}}, *res);
+ expect_summary({{5}, {7}, {9}}, *res);
}
-TEST_F(SearchVisitorTest, test_only_require_weak_read_consistency)
+TEST_F(SearchVisitorTest, visitor_only_require_weak_read_consistency)
{
- SearchVisitorFactory factory(::config::ConfigUri("dir:cfg"));
- VisitorFactory& factoryBase(factory);
vdslib::Parameters params;
- std::unique_ptr<Visitor> sv(factoryBase.makeVisitor(*_component, _env, params));
- EXPECT_TRUE(sv->getRequiredReadConsistency() == spi::ReadConsistency::WEAK);
+ auto session = make_visitor_session(params);
+ EXPECT_TRUE(session->visitor.getRequiredReadConsistency() == spi::ReadConsistency::WEAK);
}
}