blob: ff967ddf939d63d51c11f2a6c810a01658299d72 [file] [log] [blame]
// Copyright 2020 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <gtest/gtest.h>
#include <measure_tape/hlcpp/measure_tape_for_toplevelunion.h>
#include <measuretape/cpp/fidl.h>
namespace measure_tape {
namespace measuretape {
const char kHelloWorldEn[] = "hello, world!";
const char kHelloWorldFr[] = "bonjour, le monde!";
const char kHelloWorldDe[] = "hallo, welt!";
const char kHelloWorldEs[] = "Hola, Mundo!";
const char kHelloWorldRu[] = "Привет мир!";
const char kHelloWorldZh[] = "你好,世界!";
static_assert(sizeof(kHelloWorldEn) == 13 + 1);
static_assert(sizeof(kHelloWorldFr) == 18 + 1);
static_assert(sizeof(kHelloWorldDe) == 12 + 1);
static_assert(sizeof(kHelloWorldEs) == 12 + 1);
static_assert(sizeof(kHelloWorldRu) == 20 + 1);
static_assert(sizeof(kHelloWorldZh) == 16 + 1);
TEST(MeasureTape, Primitive) {
::measuretape::TopLevelUnion value;
value.set_primitive(5);
auto size = Measure(value);
EXPECT_EQ(size.num_bytes, 24 + 8);
EXPECT_EQ(size.num_handles, 0);
}
TEST(MeasureTape, Handle) {
::measuretape::TopLevelUnion value;
zx::handle h;
value.set_handle(std::move(h));
auto size = Measure(value);
EXPECT_EQ(size.num_bytes, 24 + 8);
EXPECT_EQ(size.num_handles, 1);
}
TEST(MeasureTape, StructWithString) {
::measuretape::TopLevelUnion value;
::measuretape::StructWithString struct_with_string;
struct_with_string.string = kHelloWorldEn; // 13 chars
value.set_struct_with_string(std::move(struct_with_string));
auto size = Measure(value);
EXPECT_EQ(size.num_bytes, 24 + 16 + 16);
EXPECT_EQ(size.num_handles, 0);
}
TEST(MeasureTape, StructWithOptString_NoString) {
::measuretape::TopLevelUnion value;
::measuretape::StructWithOptString struct_with_opt_string;
value.set_struct_with_opt_string(std::move(struct_with_opt_string));
auto size = Measure(value);
EXPECT_EQ(size.num_bytes, 24 + 16);
EXPECT_EQ(size.num_handles, 0);
}
TEST(MeasureTape, StructWithOptString_HasString) {
::measuretape::TopLevelUnion value;
::measuretape::StructWithOptString struct_with_opt_string;
struct_with_opt_string.opt_string = kHelloWorldFr; // 18 chars
value.set_struct_with_opt_string(std::move(struct_with_opt_string));
auto size = Measure(value);
EXPECT_EQ(size.num_bytes, 24 + 16 + 24);
EXPECT_EQ(size.num_handles, 0);
}
TEST(MeasureTape, Table_Empty) {
::measuretape::TopLevelUnion value;
::measuretape::Table table;
value.set_table(std::move(table));
auto size = Measure(value);
EXPECT_EQ(size.num_bytes, 24 + 16);
EXPECT_EQ(size.num_handles, 0);
}
TEST(MeasureTape, Table_OnlyMaxOrdinalIsSet) {
::measuretape::TopLevelUnion value;
::measuretape::Table table;
table.set_primitive(42);
value.set_table(std::move(table));
auto size = Measure(value);
EXPECT_EQ(size.num_bytes, 24 + 16 + (5 * 16) + 8);
EXPECT_EQ(size.num_handles, 0);
}
TEST(MeasureTape, Table_StringIsSet) {
::measuretape::TopLevelUnion value;
::measuretape::Table table;
table.set_string(kHelloWorldDe); // 12 chars
value.set_table(std::move(table));
auto size = Measure(value);
EXPECT_EQ(size.num_bytes, 24 + 16 + (3 * 16) + 16 + 16);
EXPECT_EQ(size.num_handles, 0);
}
TEST(MeasureTape, ArrayOfTwelveBytes) {
::measuretape::TopLevelUnion value;
std::array<uint8_t, 12> array_of_twelve_bytes = {};
value.set_array_of_twelve_bytes(std::move(array_of_twelve_bytes));
auto size = Measure(value);
EXPECT_EQ(size.num_bytes, 24 + 16);
EXPECT_EQ(size.num_handles, 0);
}
TEST(MeasureTape, ArrayOfThreeStrings) {
::measuretape::TopLevelUnion value;
std::array<std::string, 3> array_of_three_strings = {
kHelloWorldEs, // 12 bytes
kHelloWorldRu, // 20 bytes
kHelloWorldZh, // 16 bytes
};
value.set_array_of_three_strings(std::move(array_of_three_strings));
auto size = Measure(value);
EXPECT_EQ(size.num_bytes, 24 + (3 * 16) + 16 + 24 + 16);
EXPECT_EQ(size.num_handles, 0);
}
TEST(MeasureTape, ArrayOfThreeHandles) {
::measuretape::TopLevelUnion value;
std::array<zx::handle, 3> array_of_three_handles = {};
value.set_array_of_three_handles(std::move(array_of_three_handles));
auto size = Measure(value);
EXPECT_EQ(size.num_bytes, 24 + 16);
EXPECT_EQ(size.num_handles, 3);
}
TEST(MeasureTape, ArrayOfTwoTables_BothEmpty) {
::measuretape::TopLevelUnion value;
std::array<::measuretape::Table, 2> array_of_two_tables = {};
value.set_array_of_two_tables(std::move(array_of_two_tables));
auto size = Measure(value);
EXPECT_EQ(size.num_bytes, 24 + (2 * 16));
EXPECT_EQ(size.num_handles, 0);
}
TEST(MeasureTape, ArrayOfTwoTables_Mixed) {
::measuretape::TopLevelUnion value;
::measuretape::Table t1;
t1.set_primitive(27);
::measuretape::Table t2;
zx::handle handle;
t2.set_handle(std::move(handle));
std::array<::measuretape::Table, 2> array_of_two_tables = {
std::move(t1),
std::move(t2),
};
value.set_array_of_two_tables(std::move(array_of_two_tables));
auto size = Measure(value);
EXPECT_EQ(size.num_bytes, 24 + (2 * 16) + (5 * 16) + 8 + (4 * 16) + 8);
EXPECT_EQ(size.num_handles, 1);
}
TEST(MeasureTape, ArrayOfTwoUnions) {
::measuretape::TopLevelUnion value;
::measuretape::Union u1;
u1.set_primitive(654321);
::measuretape::Union u2;
u2.set_primitive(123456);
std::array<::measuretape::Union, 2> array_of_two_unions = {
std::move(u1),
std::move(u2),
};
value.set_array_of_two_unions(std::move(array_of_two_unions));
auto size = Measure(value);
EXPECT_EQ(size.num_bytes, 24 + (2 * 24) + 8 + 8);
EXPECT_EQ(size.num_handles, 0);
}
TEST(MeasureTape, StructWithTwoArrays) {
::measuretape::TopLevelUnion value;
::measuretape::StructWithTwoArrays struct_with_two_arrays;
value.set_struct_with_two_arrays(std::move(struct_with_two_arrays));
auto size = Measure(value);
EXPECT_EQ(size.num_bytes, 24 + 64);
EXPECT_EQ(size.num_handles, 0);
}
TEST(MeasureTape, ArrayOfThreeStructsWithOneHandle) {
::measuretape::TopLevelUnion value;
std::array<::measuretape::StructWithOneHandle, 3> array_of_three_structs_with_one_handle = {};
value.set_array_of_three_structs_with_one_handle(
std::move(array_of_three_structs_with_one_handle));
auto size = Measure(value);
EXPECT_EQ(size.num_bytes, 24 + (3 * 12 + 4));
EXPECT_EQ(size.num_handles, 3);
}
TEST(MeasureTape, ArrayOfThreeStructsWithTwoHandles) {
::measuretape::TopLevelUnion value;
std::array<::measuretape::StructWithTwoHandles, 3> array_of_three_structs_with_two_handles = {};
value.set_array_of_three_structs_with_two_handles(
std::move(array_of_three_structs_with_two_handles));
auto size = Measure(value);
EXPECT_EQ(size.num_bytes, 24 + (3 * 12 + 4));
EXPECT_EQ(size.num_handles, 6);
}
TEST(MeasureTape, VectorOfBytes_ThreeBytes) {
::measuretape::TopLevelUnion value;
std::vector<uint8_t> vector_of_bytes = {1, 2, 3};
value.set_vector_of_bytes(std::move(vector_of_bytes));
auto size = Measure(value);
EXPECT_EQ(size.num_bytes, 24 + 16 + 8);
EXPECT_EQ(size.num_handles, 0);
}
TEST(MeasureTape, VectorOfBytes_NineBytes) {
::measuretape::TopLevelUnion value;
std::vector<uint8_t> vector_of_bytes = {1, 2, 3, 4, 5, 6, 7, 8, 9};
value.set_vector_of_bytes(std::move(vector_of_bytes));
auto size = Measure(value);
EXPECT_EQ(size.num_bytes, 24 + 16 + 16);
EXPECT_EQ(size.num_handles, 0);
}
TEST(MeasureTape, VectorOfStrings) {
::measuretape::TopLevelUnion value;
std::vector<std::string> vector_of_strings = {
kHelloWorldEs, // 12 bytes
kHelloWorldRu, // 20 bytes
kHelloWorldZh, // 16 bytes
};
value.set_vector_of_strings(std::move(vector_of_strings));
auto size = Measure(value);
EXPECT_EQ(size.num_bytes, 24 + 16 + (3 * 16) + 16 + 24 + 16);
EXPECT_EQ(size.num_handles, 0);
}
TEST(MeasureTape, VectorOfHandles_Empty) {
::measuretape::TopLevelUnion value;
std::vector<zx::handle> vector_of_handles;
value.set_vector_of_handles(std::move(vector_of_handles));
auto size = Measure(value);
EXPECT_EQ(size.num_bytes, 24 + 16);
EXPECT_EQ(size.num_handles, 0);
}
TEST(MeasureTape, VectorOfHandles_ThreeHandles) {
// three handles, i.e. 16 bytes payload with alignment
::measuretape::TopLevelUnion value;
std::vector<zx::handle> vector_of_handles;
zx::handle handle1;
vector_of_handles.push_back(std::move(handle1));
zx::handle handle2;
vector_of_handles.push_back(std::move(handle2));
zx::handle handle3;
vector_of_handles.push_back(std::move(handle3));
value.set_vector_of_handles(std::move(vector_of_handles));
auto size = Measure(value);
EXPECT_EQ(size.num_bytes, 24 + 16 + 16);
EXPECT_EQ(size.num_handles, 3);
}
TEST(MeasureTape, VectorOfTables_TwoEmptyTables) {
::measuretape::TopLevelUnion value;
std::vector<::measuretape::Table> vector_of_tables;
::measuretape::Table t1;
vector_of_tables.push_back(std::move(t1));
::measuretape::Table t2;
vector_of_tables.push_back(std::move(t2));
value.set_vector_of_tables(std::move(vector_of_tables));
auto size = Measure(value);
EXPECT_EQ(size.num_bytes, 24 + 16 + (2 * 16));
EXPECT_EQ(size.num_handles, 0);
}
TEST(MeasureTape, VectorOfTables_Mixed) {
::measuretape::TopLevelUnion value;
std::vector<::measuretape::Table> vector_of_tables;
::measuretape::Table t1;
t1.set_primitive(27);
vector_of_tables.push_back(std::move(t1));
::measuretape::Table t2;
zx::handle handle;
t2.set_handle(std::move(handle));
vector_of_tables.push_back(std::move(t2));
value.set_vector_of_tables(std::move(vector_of_tables));
auto size = Measure(value);
EXPECT_EQ(size.num_bytes, 24 + 16 + (2 * 16) + (5 * 16) + 8 + (4 * 16) + 8);
EXPECT_EQ(size.num_handles, 1);
}
TEST(MeasureTape, VectorOfUnions) {
::measuretape::TopLevelUnion value;
std::vector<::measuretape::Union> vector_of_unions;
::measuretape::Union u1;
u1.set_primitive(654321);
vector_of_unions.push_back(std::move(u1));
::measuretape::Union u2;
u2.set_primitive(123456);
vector_of_unions.push_back(std::move(u2));
value.set_vector_of_unions(std::move(vector_of_unions));
auto size = Measure(value);
EXPECT_EQ(size.num_bytes, 24 + 16 + (2 * 24) + 8 + 8);
EXPECT_EQ(size.num_handles, 0);
}
TEST(MeasureTape, StructWithTwoVectors_BothNull) {
::measuretape::TopLevelUnion value;
::measuretape::StructWithTwoVectors struct_with_two_vectors;
EXPECT_FALSE(struct_with_two_vectors.vector_of_bytes.has_value());
EXPECT_FALSE(struct_with_two_vectors.vector_of_strings.has_value());
value.set_struct_with_two_vectors(std::move(struct_with_two_vectors));
auto size = Measure(value);
EXPECT_EQ(size.num_bytes, 24 + 32);
EXPECT_EQ(size.num_handles, 0);
}
TEST(MeasureTape, StructWithTwoVectors_ThreeBytesInFirstTwoStringsInSecond) {
::measuretape::TopLevelUnion value;
::measuretape::StructWithTwoVectors struct_with_two_vectors;
std::vector<uint8_t> vector_of_bytes = {1, 2, 3};
fidl::VectorPtr<uint8_t> ptr_vector_of_bytes(std::move(vector_of_bytes));
struct_with_two_vectors.vector_of_bytes = std::move(ptr_vector_of_bytes);
std::vector<std::string> vector_of_strings = {
kHelloWorldRu, // 20 bytes
kHelloWorldDe, // 12 bytes
};
fidl::VectorPtr<std::string> ptr_vector_of_strings(std::move(vector_of_strings));
struct_with_two_vectors.vector_of_strings = std::move(ptr_vector_of_strings);
value.set_struct_with_two_vectors(std::move(struct_with_two_vectors));
auto size = Measure(value);
EXPECT_EQ(size.num_bytes, 24 + 32 + 8 + (2 * 16) + 24 + 16);
EXPECT_EQ(size.num_handles, 0);
}
TEST(MeasureTape, VectorOfStructsWithOneHandle) {
::measuretape::TopLevelUnion value;
std::vector<::measuretape::StructWithOneHandle> vector_of_structs_with_one_handle;
::measuretape::StructWithOneHandle struct_with_handle1;
vector_of_structs_with_one_handle.push_back(std::move(struct_with_handle1));
::measuretape::StructWithOneHandle struct_with_handle2;
vector_of_structs_with_one_handle.push_back(std::move(struct_with_handle2));
::measuretape::StructWithOneHandle struct_with_handle3;
vector_of_structs_with_one_handle.push_back(std::move(struct_with_handle3));
value.set_vector_of_structs_with_one_handle(std::move(vector_of_structs_with_one_handle));
auto size = Measure(value);
EXPECT_EQ(size.num_bytes, 24 + 16 + (3 * 12 + 4));
EXPECT_EQ(size.num_handles, 3);
}
TEST(MeasureTape, VectorOfStructsWithTwoHandles) {
::measuretape::TopLevelUnion value;
std::vector<::measuretape::StructWithTwoHandles> vector_of_structs_with_two_handles;
::measuretape::StructWithTwoHandles struct_with_two_handles1;
vector_of_structs_with_two_handles.push_back(std::move(struct_with_two_handles1));
::measuretape::StructWithTwoHandles struct_with_two_handles2;
vector_of_structs_with_two_handles.push_back(std::move(struct_with_two_handles1));
::measuretape::StructWithTwoHandles struct_with_two_handles3;
vector_of_structs_with_two_handles.push_back(std::move(struct_with_two_handles1));
value.set_vector_of_structs_with_two_handles(std::move(vector_of_structs_with_two_handles));
auto size = Measure(value);
EXPECT_EQ(size.num_bytes, 24 + 16 + (3 * 12 + 4));
EXPECT_EQ(size.num_handles, 6);
}
} // namespace measuretape
} // namespace measure_tape