From 9fbca83ac0ba0017d22cd84b696cff3baa1cde23 Mon Sep 17 00:00:00 2001 From: frsyuki Date: Sun, 25 Apr 2010 18:08:14 +0900 Subject: [PATCH] cpp: add test/{zone,pack_unpack,streaming,object,convert,buffer}.cc --- cpp/Makefile.am | 2 + cpp/configure.in | 2 +- cpp/msgpack/unpack.hpp | 2 +- cpp/test/Makefile.am | 26 ++++++++ cpp/test/buffer.cc | 50 +++++++++++++++ cpp/test/convert.cc | 74 ++++++++++++++++++++++ cpp/test/object.cc | 134 ++++++++++++++++++++++++++++++++++++++++ cpp/test/pack_unpack.cc | 101 ++++++++++++++++++++++++++++++ cpp/test/streaming.cc | 109 ++++++++++++++++++++++++++++++++ cpp/test/zone.cc | 78 +++++++++++++++++++++++ 10 files changed, 576 insertions(+), 2 deletions(-) create mode 100644 cpp/test/Makefile.am create mode 100644 cpp/test/buffer.cc create mode 100644 cpp/test/convert.cc create mode 100644 cpp/test/object.cc create mode 100644 cpp/test/pack_unpack.cc create mode 100644 cpp/test/streaming.cc create mode 100644 cpp/test/zone.cc diff --git a/cpp/Makefile.am b/cpp/Makefile.am index fa8d6cf9..3cbb4002 100644 --- a/cpp/Makefile.am +++ b/cpp/Makefile.am @@ -61,6 +61,8 @@ EXTRA_DIST = \ msgpack_vc8.sln \ msgpack_vc8.postbuild.bat +SUBDIRS = test + check_PROGRAMS = \ msgpackc_test \ msgpack_test diff --git a/cpp/configure.in b/cpp/configure.in index 8c59ddad..596b28d4 100644 --- a/cpp/configure.in +++ b/cpp/configure.in @@ -39,5 +39,5 @@ add CFLAGS="--march=i686" and CXXFLAGS="-march=i686" options to ./configure as f ]) fi -AC_OUTPUT([Makefile]) +AC_OUTPUT([Makefile test/Makefile]) diff --git a/cpp/msgpack/unpack.hpp b/cpp/msgpack/unpack.hpp index 324111a5..d39b5df8 100644 --- a/cpp/msgpack/unpack.hpp +++ b/cpp/msgpack/unpack.hpp @@ -81,7 +81,7 @@ public: // while( /* readable */ ) { // // // 1. - // pac.reserve(1024); + // pac.reserve_buffer(1024); // // // 2. // ssize_t bytes = diff --git a/cpp/test/Makefile.am b/cpp/test/Makefile.am new file mode 100644 index 00000000..a80f3194 --- /dev/null +++ b/cpp/test/Makefile.am @@ -0,0 +1,26 @@ + +AM_LDFLAGS = ../libmsgpack.la -lgtest_main + +check_PROGRAMS = \ + zone \ + pack_unpack \ + streaming \ + object \ + convert \ + buffer + +TESTS = $(check_PROGRAMS) + +zone_SOURCES = zone.cc + +pack_unpack_SOURCES = pack_unpack.cc + +streaming_SOURCES = streaming.cc + +object_SOURCES = object.cc + +convert_SOURCES = convert.cc + +buffer_SOURCES = buffer.cc +buffer_LDADD = -lz + diff --git a/cpp/test/buffer.cc b/cpp/test/buffer.cc new file mode 100644 index 00000000..a2e90378 --- /dev/null +++ b/cpp/test/buffer.cc @@ -0,0 +1,50 @@ +#include +#include +#include +#include + +TEST(buffer, sbuffer) +{ + msgpack::sbuffer sbuf; + sbuf.write("a", 1); + sbuf.write("a", 1); + sbuf.write("a", 1); + + EXPECT_EQ(3, sbuf.size()); + EXPECT_TRUE( memcmp(sbuf.data(), "aaa", 3) == 0 ); +} + + +TEST(buffer, vrefbuffer) +{ + msgpack::vrefbuffer vbuf; + vbuf.write("a", 1); + vbuf.write("a", 1); + vbuf.write("a", 1); + + const struct iovec* vec = vbuf.vector(); + size_t veclen = vbuf.vector_size(); + + msgpack::sbuffer sbuf; + for(size_t i=0; i < veclen; ++i) { + sbuf.write((const char*)vec[i].iov_base, vec[i].iov_len); + } + + EXPECT_EQ(3, sbuf.size()); + EXPECT_TRUE( memcmp(sbuf.data(), "aaa", 3) == 0 ); +} + + +TEST(buffer, zbuffer) +{ + msgpack::zbuffer zbuf; + zbuf.write("a", 1); + zbuf.write("a", 1); + zbuf.write("a", 1); + + zbuf.flush(); + + char* data = zbuf.data(); + size_t size = zbuf.size(); +} + diff --git a/cpp/test/convert.cc b/cpp/test/convert.cc new file mode 100644 index 00000000..f2a85237 --- /dev/null +++ b/cpp/test/convert.cc @@ -0,0 +1,74 @@ +#include +#include + +class compatibility { +public: + compatibility() : str1("default"), str2("default") { } + + std::string str1; + std::string str2; + + MSGPACK_DEFINE(str1, str2); +}; + +TEST(convert, compatibility_less) +{ + std::vector src(1); + src[0] = "kumofs"; + + msgpack::zone z; + msgpack::object obj(src, &z); + + compatibility c; + EXPECT_NO_THROW( obj.convert(&c) ); + + EXPECT_EQ("kumofs", c.str1); + EXPECT_EQ("default", c.str2); +} + +TEST(convert, compatibility_more) +{ + std::vector src(3); + src[0] = "kumofs"; + src[1] = "mpio"; + src[2] = "cloudy"; + + msgpack::zone z; + msgpack::object obj(src, &z); + + compatibility to; + EXPECT_NO_THROW( obj.convert(&to) ); + + EXPECT_EQ("kumofs", to.str1); + EXPECT_EQ("mpio", to.str2); +} + + +class enum_member { +public: + enum_member() : flag(A) { } + + enum flags_t { + A = 0, + B = 1, + }; + + flags_t flag; + + MSGPACK_DEFINE((int&)flag); +}; + +TEST(convert, enum_member) +{ + enum_member src; + src.flag = enum_member::B; + + msgpack::zone z; + msgpack::object obj(src, &z); + + enum_member to; + EXPECT_NO_THROW( obj.convert(&to) ); + + EXPECT_EQ(enum_member::B, to.flag); +} + diff --git a/cpp/test/object.cc b/cpp/test/object.cc new file mode 100644 index 00000000..5390c4ae --- /dev/null +++ b/cpp/test/object.cc @@ -0,0 +1,134 @@ +#include +#include + +struct myclass { + myclass() : num(0), str("default") { } + + myclass(int num, const std::string& str) : + num(0), str("default") { } + + ~myclass() { } + + int num; + std::string str; + + MSGPACK_DEFINE(num, str); + + bool operator==(const myclass& o) const + { + return num == o.num && str == o.str; + } +}; + +std::ostream& operator<<(std::ostream& o, const myclass& m) +{ + return o << "myclass("<()); +} + + +TEST(object, print) +{ + msgpack::object obj; + std::cout << obj << std::endl; +} + + +TEST(object, is_nil) +{ + msgpack::object obj; + EXPECT_TRUE(obj.is_nil()); +} + + +TEST(object, type_error) +{ + msgpack::object obj(1); + EXPECT_THROW(obj.as(), msgpack::type_error); + EXPECT_THROW(obj.as >(), msgpack::type_error); + EXPECT_EQ(1, obj.as()); + EXPECT_EQ(1, obj.as()); + EXPECT_EQ(1u, obj.as()); + EXPECT_EQ(1u, obj.as()); +} + + +TEST(object, equal_primitive) +{ + msgpack::object obj_nil; + EXPECT_EQ(obj_nil, msgpack::object()); + + msgpack::object obj_int(1); + EXPECT_EQ(obj_int, msgpack::object(1)); + EXPECT_EQ(obj_int, 1); + + msgpack::object obj_double(1.2); + EXPECT_EQ(obj_double, msgpack::object(1.2)); + EXPECT_EQ(obj_double, 1.2); + + msgpack::object obj_bool(true); + EXPECT_EQ(obj_bool, msgpack::object(true)); + EXPECT_EQ(obj_bool, true); +} + + +TEST(object, construct_primitive) +{ + msgpack::object obj_nil; + EXPECT_EQ(msgpack::type::NIL, obj_nil.type); + + msgpack::object obj_uint(1); + EXPECT_EQ(msgpack::type::POSITIVE_INTEGER, obj_uint.type); + EXPECT_EQ(1u, obj_uint.via.u64); + + msgpack::object obj_int(-1); + EXPECT_EQ(msgpack::type::NEGATIVE_INTEGER, obj_int.type); + EXPECT_EQ(-1, obj_int.via.i64); + + msgpack::object obj_double(1.2); + EXPECT_EQ(msgpack::type::DOUBLE, obj_double.type); + EXPECT_EQ(1.2, obj_double.via.dec); + + msgpack::object obj_bool(true); + EXPECT_EQ(msgpack::type::BOOLEAN, obj_bool.type); + EXPECT_EQ(true, obj_bool.via.boolean); +} + diff --git a/cpp/test/pack_unpack.cc b/cpp/test/pack_unpack.cc new file mode 100644 index 00000000..ecf52c5a --- /dev/null +++ b/cpp/test/pack_unpack.cc @@ -0,0 +1,101 @@ +#include +#include +#include + +TEST(pack, num) +{ + msgpack::sbuffer sbuf; + msgpack::pack(sbuf, 1); +} + + +TEST(pack, vector) +{ + msgpack::sbuffer sbuf; + std::vector vec; + vec.push_back(1); + vec.push_back(2); + vec.push_back(3); + msgpack::pack(sbuf, vec); +} + + +TEST(pack, to_ostream) +{ + std::ostringstream stream; + msgpack::pack(stream, 1); +} + + +struct myclass { + myclass() : num(0), str("default") { } + + myclass(int num, const std::string& str) : + num(0), str("default") { } + + ~myclass() { } + + int num; + std::string str; + + MSGPACK_DEFINE(num, str); +}; + + +TEST(pack, myclass) +{ + msgpack::sbuffer sbuf; + myclass m(1, "msgpack"); + msgpack::pack(sbuf, m); +} + + +TEST(unpack, myclass) +{ + msgpack::sbuffer sbuf; + myclass m1(1, "phraser"); + msgpack::pack(sbuf, m1); + + msgpack::zone z; + msgpack::object obj; + + msgpack::unpack_return ret = + msgpack::unpack(sbuf.data(), sbuf.size(), NULL, &z, &obj); + + EXPECT_EQ(ret, msgpack::UNPACK_SUCCESS); + + myclass m2 = obj.as(); + EXPECT_EQ(m1.num, m2.num); + EXPECT_EQ(m1.str, m2.str); +} + + +TEST(unpack, sequence) +{ + msgpack::sbuffer sbuf; + msgpack::pack(sbuf, 1); + msgpack::pack(sbuf, 2); + msgpack::pack(sbuf, 3); + + size_t offset = 0; + + msgpack::zone z; + msgpack::object obj; + msgpack::unpack_return ret; + + ret = msgpack::unpack(sbuf.data(), sbuf.size(), &offset, &z, &obj); + EXPECT_TRUE(ret >= 0); + EXPECT_EQ(ret, msgpack::UNPACK_EXTRA_BYTES); + EXPECT_EQ(1, obj.as()); + + ret = msgpack::unpack(sbuf.data(), sbuf.size(), &offset, &z, &obj); + EXPECT_TRUE(ret >= 0); + EXPECT_EQ(ret, msgpack::UNPACK_EXTRA_BYTES); + EXPECT_EQ(2, obj.as()); + + ret = msgpack::unpack(sbuf.data(), sbuf.size(), &offset, &z, &obj); + EXPECT_TRUE(ret >= 0); + EXPECT_EQ(ret, msgpack::UNPACK_SUCCESS); + EXPECT_EQ(3, obj.as()); +} + diff --git a/cpp/test/streaming.cc b/cpp/test/streaming.cc new file mode 100644 index 00000000..2d03976a --- /dev/null +++ b/cpp/test/streaming.cc @@ -0,0 +1,109 @@ +#include +#include +#include + +TEST(streaming, basic) +{ + std::ostringstream stream; + msgpack::packer pk(&stream); + + pk.pack(1); + pk.pack(2); + pk.pack(3); + + std::istringstream input(stream.str()); + + msgpack::unpacker pac; + + int count = 0; + while(count < 3) { + pac.reserve_buffer(32*1024); + + size_t len = input.readsome(pac.buffer(), pac.buffer_capacity()); + pac.buffer_consumed(len); + + while(pac.execute()) { + std::auto_ptr z(pac.release_zone()); + msgpack::object obj = pac.data(); + pac.reset(); + + switch(count++) { + case 0: + EXPECT_EQ(1, obj.as()); + break; + case 1: + EXPECT_EQ(2, obj.as()); + break; + case 2: + EXPECT_EQ(3, obj.as()); + return; + } + + } + } +} + + +class event_handler { +public: + event_handler(std::istream& input) : input(input) { } + ~event_handler() { } + + void on_read() + { + while(true) { + pac.reserve_buffer(32*1024); + + size_t len = input.readsome(pac.buffer(), pac.buffer_capacity()); + + if(len == 0) { + return; + } + + pac.buffer_consumed(len); + + while(pac.execute()) { + std::auto_ptr z(pac.release_zone()); + msgpack::object obj = pac.data(); + pac.reset(); + on_message(obj, z); + } + + if(pac.message_size() > 10*1024*1024) { + throw std::runtime_error("message is too large"); + } + } + } + + void on_message(msgpack::object obj, std::auto_ptr z) + { + EXPECT_EQ(expect, obj.as()); + } + + int expect; + +private: + std::istream& input; + msgpack::unpacker pac; +}; + +TEST(streaming, event) +{ + std::stringstream stream; + msgpack::packer pk(&stream); + + event_handler handler(stream); + + pk.pack(1); + handler.expect = 1; + handler.on_read(); + + pk.pack(2); + handler.expect = 2; + handler.on_read(); + + pk.pack(3); + handler.expect = 3; + handler.on_read(); +} + diff --git a/cpp/test/zone.cc b/cpp/test/zone.cc new file mode 100644 index 00000000..5274e9f0 --- /dev/null +++ b/cpp/test/zone.cc @@ -0,0 +1,78 @@ +#include +#include + +TEST(zone, malloc) +{ + msgpack::zone z; + char* buf1 = (char*)z.malloc(4); + memcpy(buf1, "test", 4); + char* buf2 = (char*)z.malloc(4); + memcpy(buf2, "test", 4); +} + + +class myclass { +public: + myclass() : num(0), str("default") { } + + myclass(int num, const std::string& str) : + num(num), str(str) { } + + ~myclass() { } + + int num; + std::string str; + +private: + myclass(const myclass&); +}; + + +TEST(zone, allocate) +{ + msgpack::zone z; + myclass* m = z.allocate(); + EXPECT_EQ(m->num, 0); + EXPECT_EQ(m->str, "default"); +} + + +TEST(zone, allocate_constructor) +{ + msgpack::zone z; + myclass* m = z.allocate(7, "msgpack"); + EXPECT_EQ(m->num, 7); + EXPECT_EQ(m->str, "msgpack"); +} + + +static void custom_finalizer_func(void* user) +{ + myclass* m = (myclass*)user; + delete m; +} + +TEST(zone, push_finalizer) +{ + msgpack::zone z; + myclass* m = new myclass(); + z.push_finalizer(custom_finalizer_func, (void*)m); +} + + +TEST(zone, push_finalizer_auto_ptr) +{ + msgpack::zone z; + std::auto_ptr am(new myclass()); + z.push_finalizer(am); +} + + +TEST(zone, malloc_no_align) +{ + msgpack::zone z; + char* buf1 = (char*)z.malloc_no_align(4); + char* buf2 = (char*)z.malloc_no_align(4); + EXPECT_EQ(buf1+4, buf2); +} +