summaryrefslogtreecommitdiffstats
path: root/streamingvisitors/src/tests/docsum/docsum.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'streamingvisitors/src/tests/docsum/docsum.cpp')
-rw-r--r--streamingvisitors/src/tests/docsum/docsum.cpp293
1 files changed, 293 insertions, 0 deletions
diff --git a/streamingvisitors/src/tests/docsum/docsum.cpp b/streamingvisitors/src/tests/docsum/docsum.cpp
new file mode 100644
index 00000000000..475489d2f5a
--- /dev/null
+++ b/streamingvisitors/src/tests/docsum/docsum.cpp
@@ -0,0 +1,293 @@
+// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+#include <vespa/vespalib/testkit/testapp.h>
+#include <vespa/document/fieldvalue/fieldvalues.h>
+#include <vespa/document/datatype/structdatatype.h>
+#include <vespa/document/datatype/weightedsetdatatype.h>
+#include <vespa/document/datatype/mapdatatype.h>
+#include <vespa/vsm/common/docsum.h>
+#include <vespa/vsm/vsm/flattendocsumwriter.h>
+#include <vespa/vsm/vsm/slimefieldwriter.h>
+
+using namespace document;
+
+namespace vsm {
+
+template <typename T>
+class Vector : public std::vector<T>
+{
+public:
+ Vector<T> & add(T v) { this->push_back(v); return *this; }
+};
+
+typedef Vector<std::string> StringList;
+typedef Vector<std::pair<std::string, int32_t> > WeightedStringList;
+
+
+class TestDocument : public vsm::Document
+{
+private:
+ std::vector<FieldValueContainer> _fields;
+
+public:
+ TestDocument(const search::DocumentIdT & docId, size_t numFields) : vsm::Document(docId, numFields), _fields(numFields) {}
+ virtual bool setField(FieldIdT fId, document::FieldValue::UP fv) override {
+ if (fId < _fields.size()) {
+ _fields[fId].reset(fv.release());
+ return true;
+ }
+ return false;
+ }
+ virtual const document::FieldValue * getField(FieldIdT fId) const override {
+ if (fId < _fields.size()) {
+ return _fields[fId].get();
+ }
+ return NULL;
+ }
+};
+
+
+class DocsumTest : public vespalib::TestApp
+{
+private:
+ ArrayFieldValue createFieldValue(const StringList & fv);
+ WeightedSetFieldValue createFieldValue(const WeightedStringList & fv);
+
+ void assertFlattenDocsumWriter(const FieldValue & fv, const std::string & exp) {
+ FlattenDocsumWriter fdw;
+ assertFlattenDocsumWriter(fdw, fv, exp);
+ }
+ void assertFlattenDocsumWriter(FlattenDocsumWriter & fdw, const FieldValue & fv, const std::string & exp);
+ void assertSlimeFieldWriter(const FieldValue & fv, const std::string & exp) {
+ SlimeFieldWriter sfw;
+ TEST_DO(assertSlimeFieldWriter(sfw, fv, exp));
+ }
+ void assertSlimeFieldWriter(SlimeFieldWriter & sfw, const FieldValue & fv, const std::string & exp);
+
+ void testFlattenDocsumWriter();
+ void testSlimeFieldWriter();
+ void requireThatSlimeFieldWriterHandlesMap();
+ void testDocSumCache();
+
+public:
+ int Main() override;
+};
+
+ArrayFieldValue
+DocsumTest::createFieldValue(const StringList & fv)
+{
+
+ static ArrayDataType type(*DataType::STRING);
+ ArrayFieldValue afv(type);
+ for (size_t i = 0; i < fv.size(); ++i) {
+ afv.add(StringFieldValue(fv[i]));
+ }
+ return afv;
+}
+
+WeightedSetFieldValue
+DocsumTest::createFieldValue(const WeightedStringList & fv)
+{
+ static WeightedSetDataType type(*DataType::STRING, false, false);
+ WeightedSetFieldValue wsfv(type);
+ for (size_t i = 0; i < fv.size(); ++i) {
+ wsfv.add(StringFieldValue(fv[i].first), fv[i].second);
+ }
+ return wsfv;
+}
+
+void
+DocsumTest::assertFlattenDocsumWriter(FlattenDocsumWriter & fdw, const FieldValue & fv, const std::string & exp)
+{
+ FieldPath empty;
+ fv.iterateNested(empty.getFullRange(), fdw);
+ std::string actual(fdw.getResult().getBuffer(), fdw.getResult().getPos());
+ EXPECT_EQUAL(actual, exp);
+}
+
+void
+DocsumTest::assertSlimeFieldWriter(SlimeFieldWriter & sfw, const FieldValue & fv, const std::string & exp)
+{
+ sfw.convert(fv);
+
+ vespalib::Slime gotSlime;
+ vespalib::Memory serialized(sfw.out());
+ size_t decodeRes = vespalib::slime::BinaryFormat::decode(serialized, gotSlime);
+ ASSERT_EQUAL(decodeRes, serialized.size);
+
+ vespalib::Slime expSlime;
+ size_t used = vespalib::slime::JsonFormat::decode(exp, expSlime);
+ EXPECT_TRUE(used > 0);
+ EXPECT_EQUAL(expSlime, gotSlime);
+}
+
+void
+DocsumTest::testFlattenDocsumWriter()
+{
+ { // basic tests
+ TEST_DO(assertFlattenDocsumWriter(StringFieldValue("foo bar"), "foo bar"));
+ TEST_DO(assertFlattenDocsumWriter(RawFieldValue("foo bar"), "foo bar"));
+ TEST_DO(assertFlattenDocsumWriter(BoolFieldValue(true), "true"));
+ TEST_DO(assertFlattenDocsumWriter(BoolFieldValue(false), "false"));
+ TEST_DO(assertFlattenDocsumWriter(LongFieldValue(123456789), "123456789"));
+ TEST_DO(assertFlattenDocsumWriter(createFieldValue(StringList().add("foo bar").add("baz").add(" qux ")),
+ "foo bar baz qux "));
+ }
+ { // test mulitple invokations
+ FlattenDocsumWriter fdw("#");
+ TEST_DO(assertFlattenDocsumWriter(fdw, StringFieldValue("foo"), "foo"));
+ TEST_DO(assertFlattenDocsumWriter(fdw, StringFieldValue("bar"), "foo#bar"));
+ fdw.clear();
+ TEST_DO(assertFlattenDocsumWriter(fdw, StringFieldValue("baz"), "baz"));
+ TEST_DO(assertFlattenDocsumWriter(fdw, StringFieldValue("qux"), "baz qux"));
+ }
+ { // test resizing
+ FlattenDocsumWriter fdw("#");
+ EXPECT_EQUAL(fdw.getResult().getPos(), 0u);
+ EXPECT_EQUAL(fdw.getResult().getLength(), 32u);
+ TEST_DO(assertFlattenDocsumWriter(fdw, StringFieldValue("aaaabbbbccccddddeeeeffffgggghhhh"),
+ "aaaabbbbccccddddeeeeffffgggghhhh"));
+ EXPECT_EQUAL(fdw.getResult().getPos(), 32u);
+ EXPECT_EQUAL(fdw.getResult().getLength(), 32u);
+ TEST_DO(assertFlattenDocsumWriter(fdw, StringFieldValue("aaaa"), "aaaabbbbccccddddeeeeffffgggghhhh#aaaa"));
+ EXPECT_EQUAL(fdw.getResult().getPos(), 37u);
+ EXPECT_TRUE(fdw.getResult().getLength() >= 37u);
+ fdw.clear();
+ EXPECT_EQUAL(fdw.getResult().getPos(), 0u);
+ EXPECT_TRUE(fdw.getResult().getLength() >= 37u);
+ }
+}
+
+void
+DocsumTest::testSlimeFieldWriter()
+{
+ { // basic types
+ assertSlimeFieldWriter(LongFieldValue(123456789), "123456789");
+ assertSlimeFieldWriter(BoolFieldValue(true), "true");
+ assertSlimeFieldWriter(BoolFieldValue(false), "false");
+ assertSlimeFieldWriter(DoubleFieldValue(12.34), "12.34");
+ assertSlimeFieldWriter(StringFieldValue("foo bar"), "\"foo bar\"");
+ }
+ { // collection field values
+ assertSlimeFieldWriter(createFieldValue(StringList().add("foo").add("bar").add("baz")),
+ "[\"foo\",\"bar\",\"baz\"]");
+ assertSlimeFieldWriter(createFieldValue(WeightedStringList().add(std::make_pair("bar", 20)).
+ add(std::make_pair("baz", 30)).
+ add(std::make_pair("foo", 10))),
+ "[{item:\"bar\",weight:20},{item:\"baz\",weight:30},{item:\"foo\",weight:10}]");
+ }
+ { // struct field value
+ StructDataType subType("substruct");
+ Field fd("d", 0, *DataType::STRING);
+ Field fe("e", 1, *DataType::STRING);
+ subType.addField(fd);
+ subType.addField(fe);
+ StructFieldValue subValue(subType);
+ subValue.setValue(fd, StringFieldValue("baz"));
+ subValue.setValue(fe, StringFieldValue("qux"));
+
+ StructDataType type("struct");
+ Field fa("a", 0, *DataType::STRING);
+ Field fb("b", 1, *DataType::STRING);
+ Field fc("c", 2, subType);
+ type.addField(fa);
+ type.addField(fb);
+ type.addField(fc);
+ StructFieldValue value(type);
+ value.setValue(fa, StringFieldValue("foo"));
+ value.setValue(fb, StringFieldValue("bar"));
+ value.setValue(fc, subValue);
+
+
+ { // select a subset and then all
+ SlimeFieldWriter sfw;
+ DocsumFieldSpec::FieldIdentifierVector fields;
+ {
+ FieldPath path;
+ type.buildFieldPath(path, "a");
+ fields.push_back(DocsumFieldSpec::FieldIdentifier(0, std::move(path)));
+ }
+ {
+ FieldPath path;
+ type.buildFieldPath(path, "c.e");
+ fields.push_back(DocsumFieldSpec::FieldIdentifier(0, std::move(path)));
+ }
+ sfw.setInputFields(fields);
+ TEST_DO(assertSlimeFieldWriter(sfw, value, "{\"a\":\"foo\",\"c\":{\"e\":\"qux\"}}"));
+ sfw.clear();
+ TEST_DO(assertSlimeFieldWriter(sfw, value, "{\"a\":\"foo\",\"b\":\"bar\",\"c\":{\"d\":\"baz\",\"e\":\"qux\"}}"));
+ }
+
+ { // multiple invocations
+ SlimeFieldWriter sfw;
+ TEST_DO(assertSlimeFieldWriter(sfw, StringFieldValue("foo"), "\"foo\""));
+ sfw.clear();
+ TEST_DO(assertSlimeFieldWriter(sfw, StringFieldValue("bar"), "\"bar\""));
+ sfw.clear();
+ TEST_DO(assertSlimeFieldWriter(sfw, StringFieldValue("baz"), "\"baz\""));
+ }
+
+ }
+}
+
+void
+DocsumTest::requireThatSlimeFieldWriterHandlesMap()
+{
+ { // map<string, string>
+ MapDataType mapType(*DataType::STRING, *DataType::STRING);
+ MapFieldValue mapfv(mapType);
+ EXPECT_TRUE(mapfv.put(StringFieldValue("k1"), StringFieldValue("v1")));
+ EXPECT_TRUE(mapfv.put(StringFieldValue("k2"), StringFieldValue("v2")));
+ assertSlimeFieldWriter(mapfv, "[{\"key\":\"k1\",\"value\":\"v1\"},{\"key\":\"k2\",\"value\":\"v2\"}]");
+ }
+ { // map<string, struct>
+ StructDataType structType("struct");
+ Field fa("a", 0, *DataType::STRING);
+ Field fb("b", 1, *DataType::STRING);
+ structType.addField(fa);
+ structType.addField(fb);
+ StructFieldValue structValue(structType);
+ structValue.setValue(fa, StringFieldValue("foo"));
+ structValue.setValue(fb, StringFieldValue("bar"));
+ MapDataType mapType(*DataType::STRING, structType);
+ MapFieldValue mapfv(mapType);
+ EXPECT_TRUE(mapfv.put(StringFieldValue("k1"), structValue));
+ { // select a subset and then all
+ SlimeFieldWriter sfw;
+ DocsumFieldSpec::FieldIdentifierVector fields;
+ {
+ FieldPath path;
+ mapType.buildFieldPath(path, "value.b");
+ fields.push_back(DocsumFieldSpec::FieldIdentifier(0, std::move(path)));
+ }
+ sfw.setInputFields(fields);
+ TEST_DO(assertSlimeFieldWriter(sfw, mapfv, "[{\"key\":\"k1\",\"value\":{\"b\":\"bar\"}}]"));
+ {
+ FieldPath path;
+ mapType.buildFieldPath(path, "{k1}.a");
+ fields[0] = DocsumFieldSpec::FieldIdentifier(0, std::move(path));
+ }
+ sfw.clear();
+ sfw.setInputFields(fields);
+ TEST_DO(assertSlimeFieldWriter(sfw, mapfv, "[{\"key\":\"k1\",\"value\":{\"a\":\"foo\"}}]"));
+ sfw.clear(); // all fields implicit
+ TEST_DO(assertSlimeFieldWriter(sfw, mapfv, "[{\"key\":\"k1\",\"value\":{\"a\":\"foo\",\"b\":\"bar\"}}]"));
+ }
+ }
+}
+
+int
+DocsumTest::Main()
+{
+ TEST_INIT("docsum_test");
+
+ TEST_DO(testFlattenDocsumWriter());
+ TEST_DO(testSlimeFieldWriter());
+ TEST_DO(requireThatSlimeFieldWriterHandlesMap());
+
+ TEST_DONE();
+}
+
+}
+
+TEST_APPHOOK(vsm::DocsumTest);
+