See More

/* This file is part of VoltDB. * Copyright (C) 2008-2010 VoltDB Inc. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. */ #include #include #include #include "Exception.hpp" #include "ByteBuffer.hpp" #include #include #include #include #include #include "AuthenticationRequest.hpp" #include "AuthenticationResponse.hpp" #include "Parameter.hpp" #include "ParameterSet.hpp" #include "Procedure.hpp" #include "WireType.h" #include "Decimal.hpp" #include "InvocationResponse.hpp" #include "Table.h" #include "TableIterator.h" #include "Row.hpp" #include "sha1.h" namespace voltdb { class SerializationTest : public CppUnit::TestFixture { CPPUNIT_TEST_SUITE( SerializationTest ); CPPUNIT_TEST(testAuthenticationRequest); CPPUNIT_TEST(testAuthenticationResponse); CPPUNIT_TEST(testInvocationAllParams); CPPUNIT_TEST(testInvocationResponseSuccess); CPPUNIT_TEST(testInvocationResponseFailCV); CPPUNIT_TEST(testInvocationResponseSelect); CPPUNIT_TEST(testSerializedTable); CPPUNIT_TEST_SUITE_END(); public: SharedByteBuffer fileAsByteBuffer(std::string filename) { boost::filesystem::path p( "../test/" + filename); if (!boost::filesystem::exists(p)) { p = boost::filesystem::path( "test/" + filename); if (!boost::filesystem::exists(p)) { throw std::exception(); } } size_t size = boost::filesystem::file_size(p); char *buffer = new char[size]; SharedByteBuffer b(buffer, size); boost::filesystem::ifstream ifs(p); ifs.read(buffer, size); return b; } void testAuthenticationRequest() { SharedByteBuffer original = fileAsByteBuffer("authentication_request.msg"); SharedByteBuffer generated(new char[8192], 8192); unsigned char hashedPassword[20]; std::string password("world"); SHA1_CTX context; SHA1_Init(&context); SHA1_Update( &context, reinterpret_cast(password.data()), password.size()); SHA1_Final ( &context, hashedPassword); AuthenticationRequest request( "hello", "database", hashedPassword); request.serializeTo(&generated); CPPUNIT_ASSERT(original.remaining() == generated.remaining()); CPPUNIT_ASSERT(::memcmp(original.bytes(), generated.bytes(), original.remaining()) == 0); } void testAuthenticationResponse() { SharedByteBuffer original = fileAsByteBuffer("authentication_response.msg"); original.position(4);//skip length prefix AuthenticationResponse response(original); CPPUNIT_ASSERT(response.success()); CPPUNIT_ASSERT(response.hostId() == 0); CPPUNIT_ASSERT(response.clusterStartTime() == 1277314297206); CPPUNIT_ASSERT(response.leaderAddress() == 2130706433); CPPUNIT_ASSERT(response.buildString() == "?revision="); } void testInvocationAllParams() { SharedByteBuffer original = fileAsByteBuffer("invocation_request_all_params.msg"); std::vector params; params.push_back(Parameter(WIRE_TYPE_STRING, true)); params.push_back(Parameter(WIRE_TYPE_TINYINT, true)); params.push_back(Parameter(WIRE_TYPE_SMALLINT, true)); params.push_back(Parameter(WIRE_TYPE_INTEGER, true)); params.push_back(Parameter(WIRE_TYPE_BIGINT, true)); params.push_back(Parameter(WIRE_TYPE_FLOAT, true)); params.push_back(Parameter(WIRE_TYPE_TIMESTAMP, true)); params.push_back(Parameter(WIRE_TYPE_DECIMAL, true)); params.push_back(Parameter(WIRE_TYPE_DECIMAL, true)); params.push_back(Parameter(WIRE_TYPE_STRING)); params.push_back(Parameter(WIRE_TYPE_TINYINT)); params.push_back(Parameter(WIRE_TYPE_SMALLINT)); params.push_back(Parameter(WIRE_TYPE_INTEGER)); params.push_back(Parameter(WIRE_TYPE_BIGINT)); params.push_back(Parameter(WIRE_TYPE_FLOAT)); params.push_back(Parameter(WIRE_TYPE_TIMESTAMP)); params.push_back(Parameter(WIRE_TYPE_DECIMAL)); Procedure proc("foo", params); ParameterSet *ps = proc.params(); std::vector<:string> strings; strings.push_back("oh"); strings.push_back("noes"); ps->addString(strings); std::vector bytes; bytes.push_back( 22 ); bytes.push_back( 33 ); bytes.push_back( 44 ); ps->addInt8(bytes); std::vector shorts; shorts.push_back( 22 ); shorts.push_back( 33 ); shorts.push_back( 44 ); ps->addInt16(shorts); std::vector ints; ints.push_back( 22 ); ints.push_back( 33 ); ints.push_back( 44 ); ps->addInt32(ints); std::vector longs; longs.push_back( 22 ); longs.push_back( 33 ); longs.push_back( 44 ); ps->addInt64(longs); std::vector doubles; doubles.push_back( 3 ); doubles.push_back( 3.1 ); doubles.push_back( 3.14 ); doubles.push_back( 3.1459 ); ps->addDouble(doubles); std::vector timestamps; timestamps.push_back(33); timestamps.push_back(44); ps->addTimestamp(timestamps); std::vector decimals; decimals.push_back(Decimal(std::string("3"))); decimals.push_back(std::string("3.14")); decimals.push_back(std::string("3.1459")); ps->addDecimal(decimals); ps->addNull().addString("ohnoes!").addInt8(22).addInt16(22).addInt32(22).addInt64(22).addDouble(3.1459).addTimestamp(33).addDecimal(Decimal(std::string("3.1459"))); int32_t size = proc.getSerializedSize(); ScopedByteBuffer buffer(new char[size], size); proc.serializeTo(&buffer, INT64_MIN); CPPUNIT_ASSERT(original.remaining() == size); CPPUNIT_ASSERT(::memcmp(original.bytes(), buffer.bytes(), size) == 0); } void testInvocationResponseSuccess() { SharedByteBuffer original = fileAsByteBuffer("invocation_response_success.msg"); original.position(4); boost::shared_array copy(new char[original.remaining()]); original.get(copy.get(), original.remaining()); InvocationResponse response(copy, original.capacity() - 4); CPPUNIT_ASSERT(response.success()); CPPUNIT_ASSERT(response.clientData() == (-9223372036854775807 - 1)); CPPUNIT_ASSERT(response.appStatusCode() == -128); CPPUNIT_ASSERT(response.appStatusString() == ""); CPPUNIT_ASSERT(response.statusString() == ""); CPPUNIT_ASSERT(response.results().size() == 0); CPPUNIT_ASSERT(response.clusterRoundTripTime() == 9); } void testInvocationResponseFailCV() { SharedByteBuffer original = fileAsByteBuffer("invocation_response_fail_cv.msg"); original.position(4); boost::shared_array copy(new char[original.remaining()]); original.get(copy.get(), original.remaining()); InvocationResponse response(copy, original.capacity() - 4); CPPUNIT_ASSERT(response.failure()); CPPUNIT_ASSERT(response.statusCode() == STATUS_CODE_GRACEFUL_FAILURE); CPPUNIT_ASSERT(response.clientData() == -9223372036854775807); CPPUNIT_ASSERT(response.appStatusCode() == -128); CPPUNIT_ASSERT(response.appStatusString() == ""); CPPUNIT_ASSERT(response.statusString().find("VOLTDB ERROR: CONSTRAINT VIOLATION") != std::string::npos); CPPUNIT_ASSERT(response.results().size() == 0); CPPUNIT_ASSERT(response.clusterRoundTripTime() == 7); } void testInvocationResponseSelect() { SharedByteBuffer original = fileAsByteBuffer("invocation_response_select.msg"); original.position(4); boost::shared_array copy(new char[original.remaining()]); original.get(copy.get(), original.remaining()); InvocationResponse response(copy, original.capacity() - 4); CPPUNIT_ASSERT(response.success()); CPPUNIT_ASSERT(response.clientData() == -9223372036854775806); CPPUNIT_ASSERT(response.appStatusCode() == -128); CPPUNIT_ASSERT(response.appStatusString() == ""); CPPUNIT_ASSERT(response.statusString() == ""); CPPUNIT_ASSERT(response.results().size() == 1); CPPUNIT_ASSERT(response.clusterRoundTripTime() == 0); Table results = response.results()[0]; CPPUNIT_ASSERT(results.getStatusCode() == -128); CPPUNIT_ASSERT(results.rowCount() == 1); CPPUNIT_ASSERT(results.columnCount() == 2); std::vector<:column> columns = results.columns(); CPPUNIT_ASSERT(columns.size() == 2); CPPUNIT_ASSERT(columns[0].m_name == "HELLO"); CPPUNIT_ASSERT(columns[0].m_type == WIRE_TYPE_STRING); CPPUNIT_ASSERT(columns[1].m_name == "WORLD"); CPPUNIT_ASSERT(columns[1].m_type == WIRE_TYPE_STRING); TableIterator iterator = results.iterator(); int resultCount = 0; while (iterator.hasNext()) { Row r = iterator.next(); CPPUNIT_ASSERT(r.getString(0) == "Hello"); CPPUNIT_ASSERT(r.getString("HELLO") == "Hello"); CPPUNIT_ASSERT(r.getString(1) == "World"); CPPUNIT_ASSERT(r.getString("WORLD") == "World"); resultCount++; } CPPUNIT_ASSERT(resultCount == 1); } void testSerializedTable() { SharedByteBuffer original = fileAsByteBuffer("serialized_table.bin"); original.position(4); Table t(original.slice()); CPPUNIT_ASSERT(t.columnCount() == 7); CPPUNIT_ASSERT(t.rowCount() == 4); std::vector columns = t.columns(); CPPUNIT_ASSERT(columns.size() == 7); CPPUNIT_ASSERT(columns[0].m_name == "column1"); CPPUNIT_ASSERT(columns[1].m_name == "column2"); CPPUNIT_ASSERT(columns[2].m_name == "column3"); CPPUNIT_ASSERT(columns[3].m_name == "column4"); CPPUNIT_ASSERT(columns[4].m_name == "column5"); CPPUNIT_ASSERT(columns[5].m_name == "column6"); CPPUNIT_ASSERT(columns[6].m_name == "column7"); CPPUNIT_ASSERT(columns[0].m_type == WIRE_TYPE_TINYINT); CPPUNIT_ASSERT(columns[1].m_type == WIRE_TYPE_STRING); CPPUNIT_ASSERT(columns[2].m_type == WIRE_TYPE_SMALLINT); CPPUNIT_ASSERT(columns[3].m_type == WIRE_TYPE_INTEGER); CPPUNIT_ASSERT(columns[4].m_type == WIRE_TYPE_BIGINT); CPPUNIT_ASSERT(columns[5].m_type == WIRE_TYPE_TIMESTAMP); CPPUNIT_ASSERT(columns[6].m_type == WIRE_TYPE_DECIMAL); TableIterator ti = t.iterator(); CPPUNIT_ASSERT(ti.hasNext()); Row r = ti.next(); CPPUNIT_ASSERT(r.columnCount() == 7); CPPUNIT_ASSERT(r.isNull(0)); CPPUNIT_ASSERT(r.isNull("column1")); CPPUNIT_ASSERT(r.getInt8(0) == INT8_MIN); CPPUNIT_ASSERT(r.wasNull()); CPPUNIT_ASSERT(r.getInt8("column1") == INT8_MIN); CPPUNIT_ASSERT(r.wasNull()); CPPUNIT_ASSERT(r.isNull(1)); CPPUNIT_ASSERT(r.isNull("column2")); CPPUNIT_ASSERT(r.getString(1) == ""); CPPUNIT_ASSERT(r.wasNull()); CPPUNIT_ASSERT(r.getString("column2") == ""); CPPUNIT_ASSERT(r.wasNull()); CPPUNIT_ASSERT(r.isNull(2)); CPPUNIT_ASSERT(r.isNull("column3")); CPPUNIT_ASSERT(r.getInt16(2) == INT16_MIN); CPPUNIT_ASSERT(r.wasNull()); CPPUNIT_ASSERT(r.getInt16("column3") == INT16_MIN); CPPUNIT_ASSERT(r.wasNull()); CPPUNIT_ASSERT(r.isNull(3)); CPPUNIT_ASSERT(r.isNull("column4")); CPPUNIT_ASSERT(r.getInt32(3) == INT32_MIN); CPPUNIT_ASSERT(r.wasNull()); CPPUNIT_ASSERT(r.getInt32("column4") == INT32_MIN); CPPUNIT_ASSERT(r.wasNull()); CPPUNIT_ASSERT(r.isNull(4)); CPPUNIT_ASSERT(r.isNull("column5")); CPPUNIT_ASSERT(r.getInt64(4) == INT64_MIN); CPPUNIT_ASSERT(r.wasNull()); CPPUNIT_ASSERT(r.getInt64("column5") == INT64_MIN); CPPUNIT_ASSERT(r.wasNull()); CPPUNIT_ASSERT(r.isNull(5)); CPPUNIT_ASSERT(r.isNull("column6")); CPPUNIT_ASSERT(r.getTimestamp(5) == INT64_MIN); CPPUNIT_ASSERT(r.wasNull()); CPPUNIT_ASSERT(r.getTimestamp("column6") == INT64_MIN); CPPUNIT_ASSERT(r.wasNull()); CPPUNIT_ASSERT(r.isNull(6)); CPPUNIT_ASSERT(r.isNull("column7")); CPPUNIT_ASSERT(r.getDecimal(6).isNull()); CPPUNIT_ASSERT(r.wasNull()); CPPUNIT_ASSERT(r.getDecimal("column7").isNull()); CPPUNIT_ASSERT(r.wasNull()); CPPUNIT_ASSERT(ti.hasNext()); r = ti.next(); CPPUNIT_ASSERT(r.columnCount() == 7); CPPUNIT_ASSERT(!r.isNull(0)); CPPUNIT_ASSERT(!r.isNull("column1")); CPPUNIT_ASSERT(r.getInt8(0) == 0); CPPUNIT_ASSERT(!r.wasNull()); CPPUNIT_ASSERT(r.getInt8("column1") == 0); CPPUNIT_ASSERT(!r.wasNull()); CPPUNIT_ASSERT(!r.isNull(1)); CPPUNIT_ASSERT(!r.isNull("column2")); CPPUNIT_ASSERT(r.getString(1) == ""); CPPUNIT_ASSERT(!r.wasNull()); CPPUNIT_ASSERT(r.getString("column2") == ""); CPPUNIT_ASSERT(!r.wasNull()); CPPUNIT_ASSERT(!r.isNull(2)); CPPUNIT_ASSERT(!r.isNull("column3")); CPPUNIT_ASSERT(r.getInt16(2) == 2); CPPUNIT_ASSERT(!r.wasNull()); CPPUNIT_ASSERT(r.getInt16("column3") == 2); CPPUNIT_ASSERT(!r.wasNull()); CPPUNIT_ASSERT(!r.isNull(3)); CPPUNIT_ASSERT(!r.isNull("column4")); CPPUNIT_ASSERT(r.getInt32(3) == 4); CPPUNIT_ASSERT(!r.wasNull()); CPPUNIT_ASSERT(r.getInt32("column4") == 4); CPPUNIT_ASSERT(!r.wasNull()); CPPUNIT_ASSERT(!r.isNull(4)); CPPUNIT_ASSERT(!r.isNull("column5")); CPPUNIT_ASSERT(r.getInt64(4) == 5); CPPUNIT_ASSERT(!r.wasNull()); CPPUNIT_ASSERT(r.getInt64("column5") == 5); CPPUNIT_ASSERT(!r.wasNull()); CPPUNIT_ASSERT(!r.isNull(5)); CPPUNIT_ASSERT(!r.isNull("column6")); CPPUNIT_ASSERT(r.getTimestamp(5) == 44); CPPUNIT_ASSERT(!r.wasNull()); CPPUNIT_ASSERT(r.getTimestamp("column6") == 44); CPPUNIT_ASSERT(!r.wasNull()); CPPUNIT_ASSERT(!r.isNull(6)); CPPUNIT_ASSERT(!r.isNull("column7")); CPPUNIT_ASSERT(r.getDecimal(6).toString() == "3.145900000000"); CPPUNIT_ASSERT(!r.wasNull()); CPPUNIT_ASSERT(r.getDecimal("column7").toString() == "3.145900000000"); CPPUNIT_ASSERT(!r.wasNull()); CPPUNIT_ASSERT(ti.hasNext()); r = ti.next(); CPPUNIT_ASSERT(r.columnCount() == 7); CPPUNIT_ASSERT(!r.isNull(0)); CPPUNIT_ASSERT(!r.isNull("column1")); CPPUNIT_ASSERT(r.getInt8(0) == 0); CPPUNIT_ASSERT(!r.wasNull()); CPPUNIT_ASSERT(r.getInt8("column1") == 0); CPPUNIT_ASSERT(!r.wasNull()); CPPUNIT_ASSERT(r.isNull(1)); CPPUNIT_ASSERT(r.isNull("column2")); CPPUNIT_ASSERT(r.getString(1) == ""); CPPUNIT_ASSERT(r.wasNull()); CPPUNIT_ASSERT(r.getString("column2") == ""); CPPUNIT_ASSERT(r.wasNull()); CPPUNIT_ASSERT(!r.isNull(2)); CPPUNIT_ASSERT(!r.isNull("column3")); CPPUNIT_ASSERT(r.getInt16(2) == 2); CPPUNIT_ASSERT(!r.wasNull()); CPPUNIT_ASSERT(r.getInt16("column3") == 2); CPPUNIT_ASSERT(!r.wasNull()); CPPUNIT_ASSERT(!r.isNull(3)); CPPUNIT_ASSERT(!r.isNull("column4")); CPPUNIT_ASSERT(r.getInt32(3) == 4); CPPUNIT_ASSERT(!r.wasNull()); CPPUNIT_ASSERT(r.getInt32("column4") == 4); CPPUNIT_ASSERT(!r.wasNull()); CPPUNIT_ASSERT(!r.isNull(4)); CPPUNIT_ASSERT(!r.isNull("column5")); CPPUNIT_ASSERT(r.getInt64(4) == 5); CPPUNIT_ASSERT(!r.wasNull()); CPPUNIT_ASSERT(r.getInt64("column5") == 5); CPPUNIT_ASSERT(!r.wasNull()); CPPUNIT_ASSERT(r.isNull(5)); CPPUNIT_ASSERT(r.isNull("column6")); CPPUNIT_ASSERT(r.getTimestamp(5) == INT64_MIN); CPPUNIT_ASSERT(r.wasNull()); CPPUNIT_ASSERT(r.getTimestamp("column6") == INT64_MIN); CPPUNIT_ASSERT(r.wasNull()); CPPUNIT_ASSERT(r.isNull(6)); CPPUNIT_ASSERT(r.isNull("column7")); CPPUNIT_ASSERT(r.getDecimal(6).isNull()); CPPUNIT_ASSERT(r.wasNull()); CPPUNIT_ASSERT(r.getDecimal("column7").isNull()); CPPUNIT_ASSERT(r.wasNull()); CPPUNIT_ASSERT(ti.hasNext()); r = ti.next(); CPPUNIT_ASSERT(r.columnCount() == 7); CPPUNIT_ASSERT(r.isNull(0)); CPPUNIT_ASSERT(r.isNull("column1")); CPPUNIT_ASSERT(r.getInt8(0) == INT8_MIN); CPPUNIT_ASSERT(r.wasNull()); CPPUNIT_ASSERT(r.getInt8("column1") == INT8_MIN); CPPUNIT_ASSERT(r.wasNull()); CPPUNIT_ASSERT(!r.isNull(1)); CPPUNIT_ASSERT(!r.isNull("column2")); CPPUNIT_ASSERT(r.getString(1) == "woobie"); CPPUNIT_ASSERT(!r.wasNull()); CPPUNIT_ASSERT(r.getString("column2") == "woobie"); CPPUNIT_ASSERT(!r.wasNull()); CPPUNIT_ASSERT(r.isNull(2)); CPPUNIT_ASSERT(r.isNull("column3")); CPPUNIT_ASSERT(r.getInt16(2) == INT16_MIN); CPPUNIT_ASSERT(r.wasNull()); CPPUNIT_ASSERT(r.getInt16("column3") == INT16_MIN); CPPUNIT_ASSERT(r.wasNull()); CPPUNIT_ASSERT(r.isNull(3)); CPPUNIT_ASSERT(r.isNull("column4")); CPPUNIT_ASSERT(r.getInt32(3) == INT32_MIN); CPPUNIT_ASSERT(r.wasNull()); CPPUNIT_ASSERT(r.getInt32("column4") == INT32_MIN); CPPUNIT_ASSERT(r.wasNull()); CPPUNIT_ASSERT(r.isNull(4)); CPPUNIT_ASSERT(r.isNull("column5")); CPPUNIT_ASSERT(r.getInt64(4) == INT64_MIN); CPPUNIT_ASSERT(r.wasNull()); CPPUNIT_ASSERT(r.getInt64("column5") == INT64_MIN); CPPUNIT_ASSERT(r.wasNull()); CPPUNIT_ASSERT(!r.isNull(5)); CPPUNIT_ASSERT(!r.isNull("column6")); CPPUNIT_ASSERT(r.getTimestamp(5) == 44); CPPUNIT_ASSERT(!r.wasNull()); CPPUNIT_ASSERT(r.getTimestamp("column6") == 44); CPPUNIT_ASSERT(!r.wasNull()); CPPUNIT_ASSERT(!r.isNull(6)); CPPUNIT_ASSERT(!r.isNull("column7")); CPPUNIT_ASSERT(r.getDecimal(6).toString() == "3.145900000000"); CPPUNIT_ASSERT(!r.wasNull()); CPPUNIT_ASSERT(r.getDecimal("column7").toString() == "3.145900000000"); CPPUNIT_ASSERT(!r.wasNull()); } }; CPPUNIT_TEST_SUITE_REGISTRATION( SerializationTest ); }