Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rajan/serialization tests #4

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion ext_libs/vcpkg
Submodule vcpkg updated 4619 files
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

#include "vw/serialization/base.h"
#include "vw/serialization/type_reflection.h"
#include <type_traits>

namespace typesys
{
Expand All @@ -11,6 +12,14 @@ struct PropBase
using field_kind_t = std::integral_constant<field_kind, kind>;
using storage_type = T;

// (C++ 14 has enable_if_t, but this works with C++ 11)
// If T is default-constructible, provide a default constructor for PropBase<T>
template <typename U = T, typename std::enable_if<std::is_default_constructible<U>::value>::type* = nullptr>
PropBase() : val(T()) {}

PropBase(const T& val) : val(val) {} // copy constructor that takes a T
PropBase(T&& val) : val(std::move(val)) {} // move constructor that takes a T

protected:
T val;
};
Expand All @@ -26,10 +35,28 @@ struct Prop : public PropBase<T, field_kind::scalar>
return _eftype;
}

Prop() = default;
// (C++ 14 has enable_if_t, but this works with C++ 11)
// If T is default-constructible, provide a default constructor for PropBase<T>
template <typename U = T, typename std::enable_if<std::is_default_constructible<U>::value>::type* = nullptr>
Prop() : PropBase<T, field_kind::scalar>{} {}

Prop(const T& val) : PropBase<T, field_kind::scalar>{val} {}
Prop(T&& val) : PropBase<T, field_kind::scalar>{std::move(val)} {}

// copy assignment operator
Prop& operator=(const T& other)
{
this->val = other;
return *this;
}

// move assignment operator
Prop& operator=(T&& other)
{
this->val = std::move(other);
return *this;
}

inline erased_lvalue_ref reflect() { return erased_lvalue_ref{eftype().evalue, ref{val}}; }

using PropBase<T, typesys::field_kind::scalar>::val;
Expand Down Expand Up @@ -125,4 +152,4 @@ struct is_instance : public std::false_type {};
template <typename...Ts, template <typename, typename...> typename U>
struct is_instance<U<Ts...>, U> : public std::true_type {};

} // namespace typesys
} // namespace typesys
9 changes: 4 additions & 5 deletions vowpalwabbit/serialization/src/autofb.cc
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@

#include "flatbuffers/flatbuffers.h"
#include "flatbuffers/idl.h"
#include "flatbuffers/bfbs_generator.h"
#include "flatbuffers/util.h"

#include <sstream>
Expand Down Expand Up @@ -71,8 +70,8 @@ namespace autofb
{
return nullptr;
}

return it->get_base_type();
const typesys::type_descriptor* ret_val = it->has_base_type() ? it->get_base_type() : &*it;
return ret_val;
}

fbs_data schema_builder::build_idl()
Expand Down Expand Up @@ -301,7 +300,7 @@ void read_flatbuffer_vector_field(
}
else
{
//read_flatbuffer_vector_table()
//read_flatbuffer_vector_table();
}
}

Expand Down Expand Up @@ -646,4 +645,4 @@ typesys::activation serializer::read_flatbuffer(
return result;
}
}
#pragma endregion
#pragma endregion
117 changes: 114 additions & 3 deletions vowpalwabbit/serialization/tests/autofb_schema_test.cc
Original file line number Diff line number Diff line change
@@ -1,13 +1,122 @@
#include "vw/serialization/autofb_schema.h"
#include "vw/serialization/autofb_serializer.h"
#include "vw/serialization/type_registry.h"
#include "vw/serialization/type_builder.h"
#include "vw/serialization/type_constructors.h"

#include <gmock/gmock.h>
#include <gtest/gtest.h>

using namespace typesys;
using namespace autofb;

// function that takes a string and returns a string and
// replaces newlines and tabs with spaces
std::string normalize(const std::string& str)
{
// replace newlines and tabs with spaces
std::string ret = str;
std::replace(ret.begin(), ret.end(), '\n', ' ');
std::replace(ret.begin(), ret.end(), '\t', ' ');

// remove multiple spaces
ret.erase(std::unique(
ret.begin(),
ret.end(),
[](char a, char b) { return a == ' ' && b == ' '; }),
ret.end());
return ret;
}

class NoDefaultConstructor
{
public:
NoDefaultConstructor(int a) : a(a) {}
int a;
};

class DefaultConstructor
{
public:
DefaultConstructor() = default;
DefaultConstructor(int a) : a(a) {}
int a;
};

// TODO: test all basic types Prop<>, Vec<>
// TODO: struct, struct of struct
// Note: need a default constructor for now

TEST(Serialization, PropClasses)
{
Prop<int> a;
a=1;
EXPECT_EQ(a.val, 1);
EXPECT_EQ(a, 1);

Prop<int> b(1);
EXPECT_EQ(b.val, 1);
EXPECT_EQ(b, 1);

Prop<int> c = 1;
EXPECT_EQ(c.val, 1);
EXPECT_EQ(c, 1);

Prop<DefaultConstructor> d;

// The following is a compile error, as expected
//Prop<NoDefaultConstructor> d;

Prop<NoDefaultConstructor> e(1);
EXPECT_EQ(e.val.a, 1);
}

template <typename T>
struct test_single
{
Prop<T> a;
};

TEST(Serialization, IndividualTypes)
{
std::string schema_str = R"(
namespace test;
table test_single {
a:int32;
}
)";

type_registry registry;
type_descriptor td = type_builder_ex<test_single<int>>::register_type(
registry, "test_single"
)
.with_property<Prop<int>, &test_single<int>::a>("a")
.descriptor();
schema_builder builder("test", registry);
fbs_data fbs = builder.build_idl();
EXPECT_EQ(normalize(fbs.text_data), normalize(schema_str));

// Serialize and deserialize test

// Begin serialize
schema schema_var = builder.build();
serializer serializer(schema_var);
flatbuffers::FlatBufferBuilder fbb;
test_single<int> t{1};
auto erased = type<test_single<int>>::erase();
ref a_ref(t);
erased_lvalue_ref elv { erased, a_ref };
offset_of_any offset = serializer.write_flatbuffer(fbb, elv);
fbb.Finish(flatbuffers::Offset<void>(offset));
// End serialize

// Begin deserialize
uint8_t* buf = fbb.GetBufferPointer();
size_t size = fbb.GetSize();

// End deserialize
}

struct test_type
{
Prop<int> a;
Expand All @@ -17,7 +126,7 @@ struct test_type

TEST(SerializationSchema, SmokeTest)
{
std::string schema = R"(namespace test;
std::string schema_str = R"(namespace test;

table test_type {
a:int32;
Expand All @@ -39,9 +148,11 @@ table test_type {
.with_property<Prop<std::string>, &test_type::c>("c")
.descriptor();


schema_builder builder("test", registry);
fbs_data fbs = builder.build_idl();

EXPECT_EQ(fbs.text_data, schema);
EXPECT_EQ(fbs.text_data, schema_str);

}

}
Loading