Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(4)

Unified Diff: mojo/public/cpp/bindings/tests/union_unittest.cc

Issue 923033003: Implement unions as members of structs. (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « mojo/public/cpp/bindings/tests/struct_unittest.cc ('k') | mojo/public/interfaces/bindings/tests/BUILD.gn » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: mojo/public/cpp/bindings/tests/union_unittest.cc
diff --git a/mojo/public/cpp/bindings/tests/union_unittest.cc b/mojo/public/cpp/bindings/tests/union_unittest.cc
index aba7faa6fbeaf07ebe18f86cfe548c9bf9a98efe..ef9bac17f7319cba284ca8d3f5af89d862405bbd 100644
--- a/mojo/public/cpp/bindings/tests/union_unittest.cc
+++ b/mojo/public/cpp/bindings/tests/union_unittest.cc
@@ -2,10 +2,14 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include "mojo/public/cpp/bindings/array.h"
+#include "mojo/public/cpp/bindings/lib/array_internal.h"
+#include "mojo/public/cpp/bindings/lib/array_serialization.h"
#include "mojo/public/cpp/bindings/lib/bounds_checker.h"
#include "mojo/public/cpp/bindings/lib/fixed_buffer.h"
#include "mojo/public/cpp/bindings/string.h"
#include "mojo/public/cpp/environment/environment.h"
+#include "mojo/public/interfaces/bindings/tests/test_structs.mojom.h"
#include "mojo/public/interfaces/bindings/tests/test_unions.mojom.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -104,12 +108,12 @@ TEST(UnionTest, SerializationPod) {
PodUnionPtr pod1(PodUnion::New());
pod1->set_f_int8(10);
- size_t size = GetSerializedSize_(pod1);
+ size_t size = GetSerializedSize_(pod1, false);
EXPECT_EQ(16U, size);
mojo::internal::FixedBuffer buf(size);
- internal::PodUnion_Data* data;
- Serialize_(pod1.Pass(), &buf, &data);
+ internal::PodUnion_Data* data = nullptr;
+ SerializeUnion_(pod1.Pass(), &buf, &data, false);
PodUnionPtr pod2;
Deserialize_(data, &pod2);
@@ -119,27 +123,68 @@ TEST(UnionTest, SerializationPod) {
EXPECT_EQ(pod2->which(), PodUnion::Tag::F_INT8);
}
-TEST(UnionTest, ValidationJustWorksPod) {
+TEST(UnionTest, PodValidation) {
PodUnionPtr pod(PodUnion::New());
pod->set_f_int8(10);
- size_t size = GetSerializedSize_(pod);
+ size_t size = GetSerializedSize_(pod, false);
EXPECT_EQ(16U, size);
mojo::internal::FixedBuffer buf(size);
- internal::PodUnion_Data* data;
- Serialize_(pod.Pass(), &buf, &data);
+ internal::PodUnion_Data* data = nullptr;
+ SerializeUnion_(pod.Pass(), &buf, &data, false);
void* raw_buf = buf.Leak();
mojo::internal::BoundsChecker bounds_checker(data,
static_cast<uint32_t>(size), 0);
- EXPECT_TRUE(internal::PodUnion_Data::Validate(raw_buf, &bounds_checker));
+ EXPECT_TRUE(
+ internal::PodUnion_Data::Validate(raw_buf, &bounds_checker, false));
free(raw_buf);
}
+TEST(UnionTest, SerializeNotNull) {
+ PodUnionPtr pod(PodUnion::New());
+ pod->set_f_int8(0);
+ size_t size = GetSerializedSize_(pod, false);
+ mojo::internal::FixedBuffer buf(size);
+ internal::PodUnion_Data* data = nullptr;
+ SerializeUnion_(pod.Pass(), &buf, &data, false);
+ EXPECT_FALSE(data->is_null());
+}
+
+TEST(UnionTest, SerializeIsNullInlined) {
+ PodUnionPtr pod;
+ size_t size = GetSerializedSize_(pod, false);
+ EXPECT_EQ(16U, size);
+ mojo::internal::FixedBuffer buf(size);
+ internal::PodUnion_Data* data = internal::PodUnion_Data::New(&buf);
+
+ // Check that dirty output buffers are handled correctly by serialization.
+ data->size = 16U;
+ data->tag = PodUnion::Tag::F_UINT16;
+ data->data.f_f_int16 = 20;
+
+ SerializeUnion_(pod.Pass(), &buf, &data, true);
+ EXPECT_TRUE(data->is_null());
+
+ PodUnionPtr pod2;
+ Deserialize_(data, &pod2);
+ EXPECT_TRUE(pod2.is_null());
+}
+
+TEST(UnionTest, SerializeIsNullNotInlined) {
+ PodUnionPtr pod;
+ size_t size = GetSerializedSize_(pod, false);
+ EXPECT_EQ(16U, size);
+ mojo::internal::FixedBuffer buf(size);
+ internal::PodUnion_Data* data = nullptr;
+ SerializeUnion_(pod.Pass(), &buf, &data, false);
+ EXPECT_EQ(nullptr, data);
+}
+
TEST(UnionTest, NullValidation) {
void* buf = nullptr;
mojo::internal::BoundsChecker bounds_checker(buf, 0, 0);
- EXPECT_TRUE(internal::PodUnion_Data::Validate(buf, &bounds_checker));
+ EXPECT_TRUE(internal::PodUnion_Data::Validate(buf, &bounds_checker, false));
}
TEST(UnionTest, OutOfAlignmentValidation) {
@@ -154,7 +199,7 @@ TEST(UnionTest, OutOfAlignmentValidation) {
reinterpret_cast<internal::PodUnion_Data*>(buf);
mojo::internal::BoundsChecker bounds_checker(data,
static_cast<uint32_t>(size), 0);
- EXPECT_FALSE(internal::PodUnion_Data::Validate(buf, &bounds_checker));
+ EXPECT_FALSE(internal::PodUnion_Data::Validate(buf, &bounds_checker, false));
free(raw_buf);
}
@@ -166,7 +211,8 @@ TEST(UnionTest, OOBValidation) {
mojo::internal::BoundsChecker bounds_checker(data,
static_cast<uint32_t>(size), 0);
void* raw_buf = buf.Leak();
- EXPECT_FALSE(internal::PodUnion_Data::Validate(raw_buf, &bounds_checker));
+ EXPECT_FALSE(
+ internal::PodUnion_Data::Validate(raw_buf, &bounds_checker, false));
free(raw_buf);
}
@@ -179,7 +225,8 @@ TEST(UnionTest, UnknownTagValidation) {
mojo::internal::BoundsChecker bounds_checker(data,
static_cast<uint32_t>(size), 0);
void* raw_buf = buf.Leak();
- EXPECT_FALSE(internal::PodUnion_Data::Validate(raw_buf, &bounds_checker));
+ EXPECT_FALSE(
+ internal::PodUnion_Data::Validate(raw_buf, &bounds_checker, false));
free(raw_buf);
}
@@ -222,10 +269,10 @@ TEST(UnionTest, StringSerialization) {
String hello("hello world");
pod1->set_f_string(hello);
- size_t size = GetSerializedSize_(pod1);
+ size_t size = GetSerializedSize_(pod1, false);
mojo::internal::FixedBuffer buf(size);
- internal::ObjectUnion_Data* data;
- Serialize_(pod1.Pass(), &buf, &data);
+ internal::ObjectUnion_Data* data = nullptr;
+ SerializeUnion_(pod1.Pass(), &buf, &data, false);
ObjectUnionPtr pod2;
Deserialize_(data, &pod2);
@@ -234,7 +281,7 @@ TEST(UnionTest, StringSerialization) {
EXPECT_EQ(pod2->which(), ObjectUnion::Tag::F_STRING);
}
-TEST(UnionTest, StringValidationNull) {
+TEST(UnionTest, NullStringValidation) {
Environment environment;
size_t size = sizeof(internal::ObjectUnion_Data);
mojo::internal::FixedBuffer buf(size);
@@ -244,11 +291,12 @@ TEST(UnionTest, StringValidationNull) {
mojo::internal::BoundsChecker bounds_checker(data,
static_cast<uint32_t>(size), 0);
void* raw_buf = buf.Leak();
- EXPECT_FALSE(internal::ObjectUnion_Data::Validate(raw_buf, &bounds_checker));
+ EXPECT_FALSE(
+ internal::ObjectUnion_Data::Validate(raw_buf, &bounds_checker, false));
free(raw_buf);
}
-TEST(UnionTest, StringValidationPointerOverflow) {
+TEST(UnionTest, StringPointerOverflowValidation) {
Environment environment;
size_t size = sizeof(internal::ObjectUnion_Data);
mojo::internal::FixedBuffer buf(size);
@@ -258,11 +306,12 @@ TEST(UnionTest, StringValidationPointerOverflow) {
mojo::internal::BoundsChecker bounds_checker(data,
static_cast<uint32_t>(size), 0);
void* raw_buf = buf.Leak();
- EXPECT_FALSE(internal::ObjectUnion_Data::Validate(raw_buf, &bounds_checker));
+ EXPECT_FALSE(
+ internal::ObjectUnion_Data::Validate(raw_buf, &bounds_checker, false));
free(raw_buf);
}
-TEST(UnionTest, StringValidationValidateString) {
+TEST(UnionTest, StringValidateOOB) {
Environment environment;
size_t size = 32;
mojo::internal::FixedBuffer buf(size);
@@ -277,8 +326,203 @@ TEST(UnionTest, StringValidationValidateString) {
array_header->num_elements = 20;
mojo::internal::BoundsChecker bounds_checker(data, 32, 0);
void* raw_buf = buf.Leak();
- EXPECT_FALSE(internal::ObjectUnion_Data::Validate(raw_buf, &bounds_checker));
+ EXPECT_FALSE(
+ internal::ObjectUnion_Data::Validate(raw_buf, &bounds_checker, false));
+ free(raw_buf);
+}
+
+// TODO(azani): Move back in array_unittest.cc when possible.
+// Array tests
+TEST(UnionTest, PodUnionInArray) {
+ SmallStructPtr small_struct(SmallStruct::New());
+ small_struct->pod_union_array = Array<PodUnionPtr>(2);
+ small_struct->pod_union_array[0] = PodUnion::New();
+ small_struct->pod_union_array[1] = PodUnion::New();
+
+ small_struct->pod_union_array[0]->set_f_int8(10);
+ small_struct->pod_union_array[1]->set_f_int16(12);
+
+ EXPECT_EQ(10, small_struct->pod_union_array[0]->get_f_int8());
+ EXPECT_EQ(12, small_struct->pod_union_array[1]->get_f_int16());
+}
+
+TEST(UnionTest, PodUnionInArraySerialization) {
+ Environment environment;
+ Array<PodUnionPtr> array(2);
+ array[0] = PodUnion::New();
+ array[1] = PodUnion::New();
+
+ array[0]->set_f_int8(10);
+ array[1]->set_f_int16(12);
+ EXPECT_EQ(2U, array.size());
+
+ size_t size = GetSerializedSize_(array);
+ EXPECT_EQ(40U, size);
+
+ mojo::internal::FixedBuffer buf(size);
+ mojo::internal::Array_Data<internal::PodUnion_Data>* data;
+ SerializeArray_<mojo::internal::ArrayValidateParams<
+ 0, false, mojo::internal::NoValidateParams>>(array.Pass(), &buf, &data);
+
+ Array<PodUnionPtr> array2;
+ Deserialize_(data, &array2);
+
+ EXPECT_EQ(2U, array2.size());
+
+ EXPECT_EQ(10, array2[0]->get_f_int8());
+ EXPECT_EQ(12, array2[1]->get_f_int16());
+}
+
+TEST(UnionTest, PodUnionInArraySerializationWithNull) {
+ Environment environment;
+ Array<PodUnionPtr> array(2);
+ array[0] = PodUnion::New();
+
+ array[0]->set_f_int8(10);
+ EXPECT_EQ(2U, array.size());
+
+ size_t size = GetSerializedSize_(array);
+ EXPECT_EQ(40U, size);
+
+ mojo::internal::FixedBuffer buf(size);
+ mojo::internal::Array_Data<internal::PodUnion_Data>* data;
+ SerializeArray_<mojo::internal::ArrayValidateParams<
+ 0, true, mojo::internal::NoValidateParams>>(array.Pass(), &buf, &data);
+
+ Array<PodUnionPtr> array2;
+ Deserialize_(data, &array2);
+
+ EXPECT_EQ(2U, array2.size());
+
+ EXPECT_EQ(10, array2[0]->get_f_int8());
+ EXPECT_TRUE(array2[1].is_null());
+}
+
+// TODO(azani): Move back in struct_unittest.cc when possible.
+// Struct tests
+TEST(UnionTest, Clone_Union) {
+ Environment environment;
+ SmallStructPtr small_struct(SmallStruct::New());
+ small_struct->pod_union = PodUnion::New();
+ small_struct->pod_union->set_f_int8(10);
+
+ SmallStructPtr clone = small_struct.Clone();
+ EXPECT_EQ(10, clone->pod_union->get_f_int8());
+}
+
+// Serialization test of a struct with a union of plain old data.
+TEST(UnionTest, Serialization_UnionOfPods) {
+ Environment environment;
+ SmallStructPtr small_struct(SmallStruct::New());
+ small_struct->pod_union = PodUnion::New();
+ small_struct->pod_union->set_f_int32(10);
+
+ size_t size = GetSerializedSize_(small_struct);
+
+ mojo::internal::FixedBuffer buf(size);
+ internal::SmallStruct_Data* data = nullptr;
+ Serialize_(small_struct.Pass(), &buf, &data);
+
+ SmallStructPtr deserialized;
+ Deserialize_(data, &deserialized);
+
+ EXPECT_EQ(10, deserialized->pod_union->get_f_int32());
+}
+
+// Serialization test of a struct with a union of structs.
+TEST(UnionTest, Serialization_UnionOfObjects) {
+ Environment environment;
+ SmallObjStructPtr obj_struct(SmallObjStruct::New());
+ obj_struct->obj_union = ObjectUnion::New();
+ String hello("hello world");
+ obj_struct->obj_union->set_f_string(hello);
+
+ size_t size = GetSerializedSize_(obj_struct);
+
+ mojo::internal::FixedBuffer buf(size);
+ internal::SmallObjStruct_Data* data = nullptr;
+ Serialize_(obj_struct.Pass(), &buf, &data);
+
+ SmallObjStructPtr deserialized;
+ Deserialize_(data, &deserialized);
+
+ EXPECT_EQ(hello, deserialized->obj_union->get_f_string());
+}
+
+// Validation test of a struct with a union.
+TEST(UnionTest, Validation_UnionsInStruct) {
+ Environment environment;
+ SmallStructPtr small_struct(SmallStruct::New());
+ small_struct->pod_union = PodUnion::New();
+ small_struct->pod_union->set_f_int32(10);
+
+ size_t size = GetSerializedSize_(small_struct);
+
+ mojo::internal::FixedBuffer buf(size);
+ internal::SmallStruct_Data* data = nullptr;
+ Serialize_(small_struct.Pass(), &buf, &data);
+
+ void* raw_buf = buf.Leak();
+ mojo::internal::BoundsChecker bounds_checker(data, size, 0);
+ EXPECT_TRUE(internal::SmallStruct_Data::Validate(raw_buf, &bounds_checker));
+ free(raw_buf);
+}
+
+// Validation test of a struct union fails due to unknown union tag.
+TEST(UnionTest, Validation_PodUnionInStruct_Failure) {
+ Environment environment;
+ SmallStructPtr small_struct(SmallStruct::New());
+ small_struct->pod_union = PodUnion::New();
+ small_struct->pod_union->set_f_int32(10);
+
+ size_t size = GetSerializedSize_(small_struct);
+
+ mojo::internal::FixedBuffer buf(size);
+ internal::SmallStruct_Data* data = nullptr;
+ Serialize_(small_struct.Pass(), &buf, &data);
+ data->pod_union.tag = static_cast<internal::PodUnion_Data::PodUnion_Tag>(100);
+
+ void* raw_buf = buf.Leak();
+ mojo::internal::BoundsChecker bounds_checker(data, size, 0);
+ EXPECT_FALSE(internal::SmallStruct_Data::Validate(raw_buf, &bounds_checker));
free(raw_buf);
}
+
+// Validation fails due to non-nullable null union in struct.
+TEST(UnionTest, Validation_NullUnion_Failure) {
+ Environment environment;
+ SmallStructNonNullableUnionPtr small_struct(
+ SmallStructNonNullableUnion::New());
+
+ size_t size = GetSerializedSize_(small_struct);
+
+ mojo::internal::FixedBuffer buf(size);
+ internal::SmallStructNonNullableUnion_Data* data =
+ internal::SmallStructNonNullableUnion_Data::New(&buf);
+
+ void* raw_buf = buf.Leak();
+ mojo::internal::BoundsChecker bounds_checker(data, size, 0);
+ EXPECT_FALSE(internal::SmallStructNonNullableUnion_Data::Validate(
+ raw_buf, &bounds_checker));
+ free(raw_buf);
+}
+
+// Validation passes with nullable null union.
+TEST(UnionTest, Validation_NullableUnion) {
+ Environment environment;
+ SmallStructPtr small_struct(SmallStruct::New());
+
+ size_t size = GetSerializedSize_(small_struct);
+
+ mojo::internal::FixedBuffer buf(size);
+ internal::SmallStruct_Data* data = nullptr;
+ Serialize_(small_struct.Pass(), &buf, &data);
+
+ void* raw_buf = buf.Leak();
+ mojo::internal::BoundsChecker bounds_checker(data, size, 0);
+ EXPECT_TRUE(internal::SmallStruct_Data::Validate(raw_buf, &bounds_checker));
+ free(raw_buf);
+}
+
} // namespace test
} // namespace mojo
« no previous file with comments | « mojo/public/cpp/bindings/tests/struct_unittest.cc ('k') | mojo/public/interfaces/bindings/tests/BUILD.gn » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698