summaryrefslogtreecommitdiffstats
path: root/document/src/tests/serialization/vespadocumentserializer_test.cpp
diff options
context:
space:
mode:
authorTor Brede Vekterli <vekterli@yahoo-inc.com>2017-02-01 15:57:47 +0100
committerTor Brede Vekterli <vekterli@yahoo-inc.com>2017-02-02 15:18:37 +0100
commit76d66d3cc617155c7cb54bb0f921b3484ba31d9d (patch)
tree215f8751451ec866d780b0965699a0fda5564555 /document/src/tests/serialization/vespadocumentserializer_test.cpp
parent140da1c8d693ee646fdd6bad4619a6e7b94b19ee (diff)
Add (de-)serialization of reference field values
Diffstat (limited to 'document/src/tests/serialization/vespadocumentserializer_test.cpp')
-rw-r--r--document/src/tests/serialization/vespadocumentserializer_test.cpp104
1 files changed, 90 insertions, 14 deletions
diff --git a/document/src/tests/serialization/vespadocumentserializer_test.cpp b/document/src/tests/serialization/vespadocumentserializer_test.cpp
index 9ef9f80aaee..4d30fce7ef1 100644
--- a/document/src/tests/serialization/vespadocumentserializer_test.cpp
+++ b/document/src/tests/serialization/vespadocumentserializer_test.cpp
@@ -24,6 +24,7 @@
#include <vespa/document/fieldvalue/structfieldvalue.h>
#include <vespa/document/fieldvalue/weightedsetfieldvalue.h>
#include <vespa/document/fieldvalue/tensorfieldvalue.h>
+#include <vespa/document/fieldvalue/referencefieldvalue.h>
#include <vespa/document/predicate/predicate.h>
#include <vespa/document/predicate/predicate_slime_builder.h>
#include <vespa/document/repo/configbuilder.h>
@@ -70,6 +71,10 @@ const int a_id = 12345;
const string a_name = "annotation";
const int predicate_doc_type_id = 321;
const string predicate_field_name = "my_predicate";
+const int doc_with_ref_type_id = 54321;
+const string doc_with_ref_name = "doc_with_ref";
+const string ref_field_name = "ref_field";
+const int ref_type_id = 789;
DocumenttypesConfig getDocTypesConfig() {
DocumenttypesConfigBuilderHelper builder;
@@ -92,25 +97,41 @@ DocumenttypesConfig getDocTypesConfig() {
Struct("my_type.header"),
Struct("my_type.body")
.addField(predicate_field_name, DataType::T_PREDICATE));
+ builder.document(doc_with_ref_type_id, doc_with_ref_name,
+ Struct(doc_with_ref_name + ".header"),
+ Struct(doc_with_ref_name + ".body")
+ .addField(ref_field_name, ref_type_id))
+ .referenceType(ref_type_id, doc_type_id);
return builder.config();
}
const DocumentTypeRepo doc_repo(getDocTypesConfig());
const FixedTypeRepo repo(doc_repo, *doc_repo.getDocumentType(doc_type_id));
-template <typename T> T newFieldValue(const T&) { return T(); }
-template <> ArrayFieldValue newFieldValue(const ArrayFieldValue &value)
-{ return ArrayFieldValue(*value.getDataType()); }
-template <> MapFieldValue newFieldValue(const MapFieldValue &value)
-{ return MapFieldValue(*value.getDataType()); }
+template <typename T> T newFieldValue(const T&) {
+ return T();
+}
+template <> ArrayFieldValue newFieldValue(const ArrayFieldValue &value) {
+ return ArrayFieldValue(*value.getDataType());
+}
+template <> MapFieldValue newFieldValue(const MapFieldValue &value) {
+ return MapFieldValue(*value.getDataType());
+}
template <> WeightedSetFieldValue newFieldValue(
- const WeightedSetFieldValue &value)
-{ return WeightedSetFieldValue(*value.getDataType()); }
-template <> StructFieldValue newFieldValue(const StructFieldValue &value)
-{ return StructFieldValue(*value.getDataType()); }
+ const WeightedSetFieldValue &value) {
+ return WeightedSetFieldValue(*value.getDataType());
+}
+template <> StructFieldValue newFieldValue(const StructFieldValue &value) {
+ return StructFieldValue(*value.getDataType());
+}
template <> AnnotationReferenceFieldValue newFieldValue(
- const AnnotationReferenceFieldValue &value)
-{ return AnnotationReferenceFieldValue(*value.getDataType()); }
+ const AnnotationReferenceFieldValue &value) {
+ return AnnotationReferenceFieldValue(*value.getDataType());
+}
+template <> ReferenceFieldValue newFieldValue(const ReferenceFieldValue& value) {
+ return ReferenceFieldValue(dynamic_cast<const ReferenceDataType&>(
+ *value.getDataType()));
+}
template<typename T>
void testDeserializeAndClone(const T& value, const nbostream &stream, bool checkEqual=true) {
@@ -134,7 +155,8 @@ void testDeserializeAndClone(const T& value, const nbostream &stream, bool check
// Leaves the stream's read position at the start of the serialized object.
template<typename T>
-void serializeAndDeserialize(const T& value, nbostream &stream, bool checkEqual=true) {
+void serializeAndDeserialize(const T& value, nbostream &stream,
+ const FixedTypeRepo& fixed_repo, bool checkEqual = true) {
size_t start_size = stream.size();
VespaDocumentSerializer serializer(stream);
serializer.write(value);
@@ -143,7 +165,7 @@ void serializeAndDeserialize(const T& value, nbostream &stream, bool checkEqual=
testDeserializeAndClone(value, stream, checkEqual);
T read_value = newFieldValue(value);
- VespaDocumentDeserializer deserializer(repo, stream, 8);
+ VespaDocumentDeserializer deserializer(fixed_repo, stream, 8);
deserializer.read(read_value);
EXPECT_EQUAL(0u, stream.size());
@@ -153,6 +175,11 @@ void serializeAndDeserialize(const T& value, nbostream &stream, bool checkEqual=
stream.adjustReadPos(-serialized_size);
}
+template<typename T>
+void serializeAndDeserialize(const T& value, nbostream &stream, bool checkEqual=true) {
+ serializeAndDeserialize(value, stream, repo, checkEqual);
+}
+
template <typename T> struct ValueType { typedef typename T::Number Type; };
template <> struct ValueType<IntFieldValue> { typedef uint32_t Type; };
template <> struct ValueType<LongFieldValue> { typedef uint64_t Type; };
@@ -230,7 +257,7 @@ TEST("requireThatStringFieldValueCanBeSerialized") {
TEST_DO(checkStringFieldValueWithAnnotation());
}
-TEST("require that strings can be redesrialized") {
+TEST("require that strings can be re-deserialized") {
StringFieldValue value("foo");
nbostream streamNotAnnotated;
VespaDocumentSerializer serializer(streamNotAnnotated);
@@ -850,6 +877,55 @@ TEST("Require that tensor deserialization matches Java") {
{ "dimX", "dimY" }));
}
+struct RefFixture {
+ FixedTypeRepo fixed_repo{doc_repo, *doc_repo.getDocumentType(doc_with_ref_type_id)};
+
+ const ReferenceDataType& ref_type() const {
+ auto* raw_type = fixed_repo.getDataType(ref_type_id);
+ assert(raw_type != nullptr);
+ return dynamic_cast<const ReferenceDataType&>(*raw_type);
+ }
+
+ void roundtripSerialize(const ReferenceFieldValue& src, ReferenceFieldValue& dest) {
+ nbostream stream;
+ VespaDocumentSerializer serializer(stream);
+ serializer.write(src);
+
+ VespaDocumentDeserializer deserializer(fixed_repo, stream, 8);
+ deserializer.read(dest);
+ }
+};
+
+TEST_F("Empty ReferenceFieldValue can be roundtrip serialized", RefFixture) {
+ ReferenceFieldValue empty_ref(f.ref_type());
+ nbostream stream;
+ serializeAndDeserialize(empty_ref, stream, f.fixed_repo);
+}
+
+TEST_F("ReferenceFieldValue with ID can be roundtrip serialized", RefFixture) {
+ ReferenceFieldValue ref_with_id(
+ f.ref_type(), DocumentId("id:ns:" + doc_name + "::foo"));
+ nbostream stream;
+ serializeAndDeserialize(ref_with_id, stream, f.fixed_repo);
+}
+
+TEST_F("Empty ReferenceFieldValue has changed-flag cleared after deserialization", RefFixture) {
+ ReferenceFieldValue src(f.ref_type());
+ ReferenceFieldValue dest(f.ref_type());
+ f.roundtripSerialize(src, dest);
+
+ EXPECT_FALSE(dest.hasChanged());
+}
+
+TEST_F("ReferenceFieldValue with ID has changed-flag cleared after deserialization", RefFixture) {
+ ReferenceFieldValue src(
+ f.ref_type(), DocumentId("id:ns:" + doc_name + "::foo"));
+ ReferenceFieldValue dest(f.ref_type());
+ f.roundtripSerialize(src, dest);
+
+ EXPECT_FALSE(dest.hasChanged());
+}
+
} // namespace
TEST_MAIN() { TEST_RUN_ALL(); }