From 3dae13d1a216528aff2e2509ff51d54140435069 Mon Sep 17 00:00:00 2001 From: Maxim Pimenov Date: Wed, 16 Dec 2015 21:18:17 +0300 Subject: [PATCH] [search] Search quality tests. --- omim.pro | 4 + search/search_engine.cpp | 2 + search/search_engine.hpp | 2 +- .../search_query_v2_test.cpp | 1 + search/search_quality_tests/queries.txt | 30 ++++ .../search_quality_tests.cpp | 156 ++++++++++++++++++ .../search_quality_tests.pro | 29 ++++ 7 files changed, 223 insertions(+), 1 deletion(-) create mode 100644 search/search_quality_tests/queries.txt create mode 100644 search/search_quality_tests/search_quality_tests.cpp create mode 100644 search/search_quality_tests/search_quality_tests.pro diff --git a/omim.pro b/omim.pro index 2292e35681..b8446fdc45 100644 --- a/omim.pro +++ b/omim.pro @@ -151,6 +151,10 @@ SUBDIRS = 3party base coding geometry indexer search routing search_integration_tests.depends = $$MapDepLibs search_tests_support generator SUBDIRS *= search_integration_tests + search_quality_tests.subdir = search/search_quality_tests + search_quality_tests.depends = $$MapDepLibs generator search_tests_support + SUBDIRS *= search_quality_tests + generator_tests.subdir = generator/generator_tests generator_tests.depends = $$MapDepLibs routing generator SUBDIRS *= generator_tests diff --git a/search/search_engine.cpp b/search/search_engine.cpp index 803bfd3c84..2518d6b42a 100644 --- a/search/search_engine.cpp +++ b/search/search_engine.cpp @@ -14,6 +14,7 @@ #include "geometry/distance_on_sphere.hpp" #include "geometry/mercator.hpp" +#include "base/logging.hpp" #include "base/scope_guard.hpp" #include "base/stl_add.hpp" @@ -267,6 +268,7 @@ void Engine::DoSearch(SearchParams const & params, m2::RectD const & viewport, } catch (Query::CancelException const &) { + LOG(LDEBUG, ("Search has been cancelled.")); } if (!viewportSearch && !m_query->IsCancelled()) diff --git a/search/search_engine.hpp b/search/search_engine.hpp index 45468eb00e..502de88f14 100644 --- a/search/search_engine.hpp +++ b/search/search_engine.hpp @@ -76,7 +76,7 @@ private: class Engine { public: - // Doesn't take ownership of index. Takes ownership of pCategories + // Doesn't take ownership of index. Takes ownership of categoriesR. Engine(Index & index, Reader * categoriesR, storage::CountryInfoGetter const & infoGetter, string const & locale, unique_ptr && factory); ~Engine(); diff --git a/search/search_integration_tests/search_query_v2_test.cpp b/search/search_integration_tests/search_query_v2_test.cpp index f4e0e0a5ca..db99f13c97 100644 --- a/search/search_integration_tests/search_query_v2_test.cpp +++ b/search/search_integration_tests/search_query_v2_test.cpp @@ -10,6 +10,7 @@ #include "search/v2/search_query_v2.hpp" #include "indexer/classificator_loader.hpp" +#include "indexer/index.hpp" #include "indexer/mwm_set.hpp" #include "storage/country_decl.hpp" diff --git a/search/search_quality_tests/queries.txt b/search/search_quality_tests/queries.txt new file mode 100644 index 0000000000..68aeea4f11 --- /dev/null +++ b/search/search_quality_tests/queries.txt @@ -0,0 +1,30 @@ +Москва +London +кафе москва +улица ленина +улица Ленина дом 1 +ленина 1 +лесная 12 +ул. лесная д. 13 +улица Лесная д14 +лесная 15/1 +Ленинградский проспект 39 +Ленинградский проспект 39с79 +Ленинградский проспект 39-79 +Ленинградский проспект 39 стр. 79 +Senieji Trakai +Trakų str +IKEA Москва +Красноармейская улица +улица набережная +квартира 44 +Tehama street +tehama 4th street +Улица 8 Марта +4-я улица 8 Марта +орехово-зуево лапина улица 78 +поварово i +поварово 1 +чехова улица завод +чехов улица лермонтова +чехов улица чехова diff --git a/search/search_quality_tests/search_quality_tests.cpp b/search/search_quality_tests/search_quality_tests.cpp new file mode 100644 index 0000000000..979532bc67 --- /dev/null +++ b/search/search_quality_tests/search_quality_tests.cpp @@ -0,0 +1,156 @@ +#include "search/params.hpp" + +#include "indexer/classificator_loader.hpp" +#include "indexer/index.hpp" +#include "indexer/mwm_set.hpp" + +#include "storage/country_info_getter.hpp" + +#include "geometry/point2d.hpp" + +#include "search/search_tests_support/test_search_engine.hpp" +#include "search/search_tests_support/test_search_request.hpp" + +#include "platform/country_file.hpp" +#include "platform/local_country_file.hpp" +#include "platform/local_country_file_utils.hpp" +#include "platform/platform.hpp" + +#include "base/logging.hpp" +#include "base/scope_guard.hpp" + +#include "std/cstdio.hpp" +#include "std/numeric.hpp" +#include "std/string.hpp" +#include "std/vector.hpp" + +#include "3party/gflags/src/gflags/gflags.h" + +using namespace search::tests_support; + +#pragma mark Define options +DEFINE_string(data_path, "", "Path to data directory (resources dir)"); +DEFINE_string(locale, "en", "Locale of all the search queries"); +DEFINE_string(mwm_list_path, "", "Path to a file containing the names of available mwms, one per line"); +DEFINE_string(mwm_path, "", "Path to mwm files (writable dir)"); +DEFINE_string(queries_path, "", "Path to the file with queries"); +DEFINE_int32(top, 1, "Number of top results to show for every query"); + +size_t const kNumTopResults = 5; +string const kDefaultQueriesPathSuffix = "/../search/search_quality_tests/queries.txt"; + +class SearchQueryV2Factory : public search::SearchQueryFactory +{ + // search::SearchQueryFactory overrides: + unique_ptr BuildSearchQuery(Index & index, CategoriesHolder const & categories, + vector const & suggests, + storage::CountryInfoGetter const & infoGetter) override + { + return make_unique(index, categories, suggests, infoGetter); + } +}; + +unique_ptr CreateCountryInfoGetter() +{ + Platform & platform = GetPlatform(); + return make_unique(platform.GetReader(PACKED_POLYGONS_FILE), + platform.GetReader(COUNTRIES_FILE)); +} + +void ReadStringsFromFile(string const & path, vector & result) +{ + FILE * f = fopen(path.data(), "r"); + CHECK(f != nullptr, ("Error when reading strings from", path, ":", string(strerror(errno)))); + MY_SCOPE_GUARD(cleanup, [&] + { + fclose(f); + }); + + int const kBufSize = 1 << 20; + char buf[kBufSize]; + while (fgets(buf, sizeof(buf), f)) + { + string s(buf); + strings::Trim(s); + if (!s.empty()) + result.push_back(s); + } +} + +void PrintTopResults(string const & query, vector const & results, size_t n) +{ + printf("%s", query.data()); + for (size_t i = 0; i < n; i++) + { + if (n > 1) + printf("\n"); + printf("\t"); + if (i < results.size()) + // todo(@m) Print more information: coordinates, viewport, etc. + printf("%s", results[i].GetString()); + else + printf(""); + } + printf("\n"); +} + +int main(int argc, char * argv[]) +{ + Platform & platform = GetPlatform(); + + google::SetUsageMessage("Search quality tests."); + google::ParseCommandLineFlags(&argc, &argv, true); + + if (!FLAGS_data_path.empty()) + platform.SetResourceDir(FLAGS_data_path); + + if (!FLAGS_mwm_path.empty()) + platform.SetWritableDirForTests(FLAGS_mwm_path); + + LOG(LINFO, ("writable dir =", platform.WritableDir())); + LOG(LINFO, ("resources dir =", platform.ResourcesDir())); + + classificator::Load(); + auto infoGetter = CreateCountryInfoGetter(); + + TestSearchEngine engine(FLAGS_locale, move(infoGetter), make_unique()); + + vector mwms; + if (!FLAGS_mwm_list_path.empty()) + { + vector availableMwms; + ReadStringsFromFile(FLAGS_mwm_list_path, availableMwms); + for (auto const & countryName : availableMwms) + mwms.emplace_back(platform.WritableDir(), platform::CountryFile(countryName), 0); + } + else + { + platform::FindAllLocalMapsAndCleanup(numeric_limits::max() /* the latest version */, + mwms); + for (auto & map : mwms) + map.SyncWithDisk(); + } + for (auto const & mwm : mwms) + { + LOG(LINFO, ("Registering map:", mwm.GetCountryName())); + engine.RegisterMap(mwm); + } + + vector queries; + string queriesPath = FLAGS_queries_path; + if (queriesPath.empty()) + queriesPath = platform.WritableDir() + kDefaultQueriesPathSuffix; + ReadStringsFromFile(queriesPath, queries); + + for (string const & query : queries) + { + // todo(@m) Viewport and position should belong to the query info. + m2::RectD viewport(m2::PointD(0.0, 0.0), m2::PointD(1.0, 1.0)); + TestSearchRequest request(engine, query, FLAGS_locale, search::SearchParams::ALL, viewport); + request.Wait(); + + PrintTopResults(query, request.Results(), FLAGS_top); + } + + return 0; +} diff --git a/search/search_quality_tests/search_quality_tests.pro b/search/search_quality_tests/search_quality_tests.pro new file mode 100644 index 0000000000..e4c4f6d199 --- /dev/null +++ b/search/search_quality_tests/search_quality_tests.pro @@ -0,0 +1,29 @@ +# Search quality tests. + +TARGET = search_quality_tests +CONFIG += console warn_on +CONFIG -= app_bundle +TEMPLATE = app + +ROOT_DIR = ../.. +# todo(@m) revise +DEPENDENCIES = map drape_frontend routing search search_tests_support storage indexer drape platform geometry coding base \ + freetype expat fribidi tomcrypt gflags jansson protobuf osrm stats_client minizip succinct \ + opening_hours + +include($$ROOT_DIR/common.pri) + +INCLUDEPATH *= $$ROOT_DIR/3party/gflags/src + + +# needed for Platform::WorkingDir() and unicode combining +QT *= core network opengl + +macx-* { + LIBS *= "-framework IOKit" "-framework SystemConfiguration" +} + +SOURCES += \ + search_quality_tests.cpp \ + +HEADERS += \