aboutsummaryrefslogtreecommitdiffstats
path: root/searchlib/src/tests
diff options
context:
space:
mode:
authorHåvard Pettersen <havardpe@oath.com>2017-08-22 13:31:02 +0000
committerHåvard Pettersen <havardpe@oath.com>2017-08-23 13:17:53 +0000
commita4e3de1bc975ba00ce38c9e4909bff5bef51156f (patch)
treeba42543fe83973a82b491675509c1728eb6dc360 /searchlib/src/tests
parentc9714fd5f0da37b73c075b81da8fe55c007afcc8 (diff)
max reduce prod join replacer with test
Diffstat (limited to 'searchlib/src/tests')
-rw-r--r--searchlib/src/tests/features/max_reduce_prod_join_replacer/CMakeLists.txt8
-rw-r--r--searchlib/src/tests/features/max_reduce_prod_join_replacer/max_reduce_prod_join_replacer_test.cpp103
2 files changed, 111 insertions, 0 deletions
diff --git a/searchlib/src/tests/features/max_reduce_prod_join_replacer/CMakeLists.txt b/searchlib/src/tests/features/max_reduce_prod_join_replacer/CMakeLists.txt
new file mode 100644
index 00000000000..5a1ac74aed0
--- /dev/null
+++ b/searchlib/src/tests/features/max_reduce_prod_join_replacer/CMakeLists.txt
@@ -0,0 +1,8 @@
+# Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+vespa_add_executable(searchlib_max_reduce_prod_join_replacer_test_app TEST
+ SOURCES
+ max_reduce_prod_join_replacer_test.cpp
+ DEPENDS
+ searchlib
+)
+vespa_add_test(NAME searchlib_max_reduce_prod_join_replacer_test_app COMMAND searchlib_max_reduce_prod_join_replacer_test_app)
diff --git a/searchlib/src/tests/features/max_reduce_prod_join_replacer/max_reduce_prod_join_replacer_test.cpp b/searchlib/src/tests/features/max_reduce_prod_join_replacer/max_reduce_prod_join_replacer_test.cpp
new file mode 100644
index 00000000000..1c6c224cc79
--- /dev/null
+++ b/searchlib/src/tests/features/max_reduce_prod_join_replacer/max_reduce_prod_join_replacer_test.cpp
@@ -0,0 +1,103 @@
+// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+
+#include <vespa/vespalib/testkit/test_kit.h>
+
+#include <vespa/eval/eval/function.h>
+#include <vespa/searchlib/features/max_reduce_prod_join_replacer.h>
+#include <vespa/searchlib/features/rankingexpression/feature_name_extractor.h>
+#include <vespa/searchlib/fef/test/indexenvironment.h>
+#include <vespa/searchlib/fef/blueprint.h>
+
+using search::features::MaxReduceProdJoinReplacer;
+using search::features::rankingexpression::ExpressionReplacer;
+using search::features::rankingexpression::FeatureNameExtractor;
+using search::fef::Blueprint;
+using search::fef::FeatureExecutor;
+using search::fef::FeatureType;
+using search::fef::IDumpFeatureVisitor;
+using search::fef::IIndexEnvironment;
+using search::fef::IQueryEnvironment;
+using search::fef::test::IndexEnvironment;
+using vespalib::Stash;
+using vespalib::eval::Function;
+
+struct MyBlueprint : Blueprint {
+ bool &was_used;
+ MyBlueprint(bool &was_used_out) : Blueprint("my_bp"), was_used(was_used_out) {}
+ void visitDumpFeatures(const IIndexEnvironment &, IDumpFeatureVisitor &) const override {}
+ Blueprint::UP createInstance() const override { return std::make_unique<MyBlueprint>(was_used); }
+ bool setup(const IIndexEnvironment &, const std::vector<vespalib::string> &params) override {
+ EXPECT_EQUAL(getName(), "my_bp(foo,bar)");
+ ASSERT_TRUE(params.size() == 2);
+ EXPECT_EQUAL(params[0], "foo");
+ EXPECT_EQUAL(params[1], "bar");
+ describeOutput("out", "my output", FeatureType::number());
+ was_used = true;
+ return true;
+ }
+ FeatureExecutor &createExecutor(const IQueryEnvironment &, vespalib::Stash &) const override {
+ abort();
+ }
+};
+
+bool replaced(const vespalib::string &expr) {
+ bool was_used = false;
+ ExpressionReplacer::UP replacer = MaxReduceProdJoinReplacer::create(std::make_unique<MyBlueprint>(was_used));
+ Function rank_function = Function::parse(expr, FeatureNameExtractor());
+ if (!EXPECT_TRUE(!rank_function.has_error())) {
+ fprintf(stderr, "parse error: %s\n", rank_function.dump().c_str());
+ }
+ auto result = replacer->maybe_replace(rank_function, IndexEnvironment());
+ EXPECT_EQUAL(bool(result), was_used);
+ return was_used;
+}
+
+TEST("require that matching expression with appropriate inputs is replaced") {
+ EXPECT_TRUE(replaced("reduce(tensorFromLabels(attribute(foo),dim)*tensorFromWeightedSet(query(bar),dim),max)"));
+}
+
+TEST("require that matching expression with unrelated inputs is not replaced") {
+ EXPECT_TRUE(!replaced("reduce(foo*bar,max)"));
+}
+
+TEST("require that input feature parameter lists have flexible matching") {
+ EXPECT_TRUE(replaced("reduce(tensorFromLabels( attribute ( foo ) , dim )*tensorFromWeightedSet( query ( bar ) , dim ),max)"));
+}
+
+TEST("require that reduce dimension can be specified explicitly") {
+ EXPECT_TRUE(replaced("reduce(tensorFromLabels(attribute(foo),dim)*tensorFromWeightedSet(query(bar),dim),max,dim)"));
+}
+
+TEST("require that expression using tensor join with lambda can also be replaced") {
+ EXPECT_TRUE(replaced("reduce(join(tensorFromLabels(attribute(foo),dim),tensorFromWeightedSet(query(bar),dim),f(x,y)(x*y)),max)"));
+}
+
+TEST("require that parameter ordering does not matter") {
+ EXPECT_TRUE(replaced("reduce(tensorFromWeightedSet(query(bar),dim)*tensorFromLabels(attribute(foo),dim),max)"));
+ EXPECT_TRUE(replaced("reduce(join(tensorFromWeightedSet(query(bar),dim),tensorFromLabels(attribute(foo),dim),f(x,y)(x*y)),max)"));
+ EXPECT_TRUE(replaced("reduce(join(tensorFromLabels(attribute(foo),dim),tensorFromWeightedSet(query(bar),dim),f(x,y)(y*x)),max)"));
+}
+
+TEST("require that source specifiers must match") {
+ EXPECT_TRUE(!replaced("reduce(tensorFromLabels(query(foo),dim)*tensorFromWeightedSet(attribute(bar),dim),max)"));
+}
+
+TEST("require that reduce operation must match") {
+ EXPECT_TRUE(!replaced("reduce(tensorFromLabels(attribute(foo),dim)*tensorFromWeightedSet(query(bar),dim),min)"));
+}
+
+TEST("require that join operation must match") {
+ EXPECT_TRUE(!replaced("reduce(tensorFromLabels(attribute(foo),dim)+tensorFromWeightedSet(query(bar),dim),max)"));
+ EXPECT_TRUE(!replaced("reduce(join(tensorFromLabels(attribute(foo),dim),tensorFromWeightedSet(query(bar),dim),f(x,y)(x+y)),max)"));
+ EXPECT_TRUE(!replaced("reduce(join(tensorFromLabels(attribute(foo),dim),tensorFromWeightedSet(query(bar),dim),f(x,y)(x*x)),max)"));
+ EXPECT_TRUE(!replaced("reduce(join(tensorFromLabels(attribute(foo),dim),tensorFromWeightedSet(query(bar),dim),f(x,y)(y*y)),max)"));
+ EXPECT_TRUE(!replaced("reduce(join(tensorFromLabels(attribute(foo),dim),tensorFromWeightedSet(query(bar),dim),f(x,y)(x*y*1)),max)"));
+}
+
+TEST("require that reduce dimension must match") {
+ EXPECT_TRUE(!replaced("reduce(tensorFromLabels(attribute(foo),x)*tensorFromWeightedSet(query(bar),x),max,y)"));
+ EXPECT_TRUE(!replaced("reduce(tensorFromLabels(attribute(foo),x)*tensorFromWeightedSet(query(bar),y),max)"));
+ EXPECT_TRUE(!replaced("reduce(tensorFromLabels(attribute(foo),x)*tensorFromWeightedSet(query(bar),x),max,x,y)"));
+}
+
+TEST_MAIN() { TEST_RUN_ALL(); }