Commit 2b586f9b authored by Daniele Kruse's avatar Daniele Kruse
Browse files

Added test for the TapeMessageBody message marshalling and unmarshalling

parent e3d3616a
......@@ -30,10 +30,127 @@
#include "castor/tape/utils/utils.hpp"
#include "h/rtcp_constants.h"
#include "h/vdqm_constants.h"
#include "h/Ctape.h"
#include "h/serrno.h"
#include <errno.h>
#include <string.h>
//-----------------------------------------------------------------------------
// marshal
//-----------------------------------------------------------------------------
size_t castor::tape::legacymsg::marshal(char *const dst, const size_t dstLen, const TapeStatRequestMsgBody &src) throw(castor::exception::Exception) {
if(dst == NULL) {
castor::exception::Exception ex(EINVAL);
ex.getMessage() << "Failed to marshal TapeStatRequestMsgBody"
": Pointer to destination buffer is NULL";
throw ex;
}
// Calculate the length of the message body
const uint32_t len =
sizeof(int32_t) + // uid
sizeof(int32_t);// gid
// Calculate the total length of the message (header + body)
// Message header = magic + reqType + len = 3 * sizeof(uint32_t)
const size_t totalLen = 3 * sizeof(uint32_t) + len;
// Check that the message buffer is big enough
if(totalLen > dstLen) {
castor::exception::Exception ex(EMSGSIZE);
ex.getMessage() << "Failed to marshal TapeStatRequestMsgBody"
": Buffer too small: required=" << totalLen << " actual=" << dstLen;
throw ex;
}
// Marshall message header
char *p = dst;
io::marshalUint32(TPMAGIC , p); // Magic number
io::marshalUint32(TPSTAT, p); // Request type
char *msg_len_field_pointer = p;
io::marshalUint32(0, p); // Temporary length
// Marshall message body
io::marshalUint32(src.uid, p);
io::marshalUint32(src.gid, p);
// Calculate the number of bytes actually marshalled
const size_t nbBytesMarshalled = p - dst;
io::marshalUint32(nbBytesMarshalled, msg_len_field_pointer); // Actual length
// Check that the number of bytes marshalled was what was expected
if(totalLen != nbBytesMarshalled) {
castor::exception::Internal ex;
ex.getMessage() << "Failed to marshal TapeStatRequestMsgBody"
": Mismatch between expected total length and actual"
": expected=" << totalLen << "actual=" << nbBytesMarshalled;
throw ex;
}
return totalLen;
}
//-----------------------------------------------------------------------------
// marshal
//-----------------------------------------------------------------------------
size_t castor::tape::legacymsg::marshal(char *const dst, const size_t dstLen, const TapeConfigRequestMsgBody &src) throw(castor::exception::Exception) {
if(dst == NULL) {
castor::exception::Exception ex(EINVAL);
ex.getMessage() << "Failed to marshal TapeConfigRequestMsgBody"
": Pointer to destination buffer is NULL";
throw ex;
}
// Calculate the length of the message body
const uint32_t len =
sizeof(int32_t) + // uid
sizeof(int32_t) + // gid
strlen(src.drive) + 1 + // drive
sizeof(int16_t); // status
// Calculate the total length of the message (header + body)
// Message header = magic + reqType + len = 3 * sizeof(uint32_t)
const size_t totalLen = 3 * sizeof(uint32_t) + len;
// Check that the message buffer is big enough
if(totalLen > dstLen) {
castor::exception::Exception ex(EMSGSIZE);
ex.getMessage() << "Failed to marshal TapeConfigRequestMsgBody"
": Buffer too small: required=" << totalLen << " actual=" << dstLen;
throw ex;
}
// Marshall message header
char *p = dst;
io::marshalUint32(TPMAGIC , p); // Magic number
io::marshalUint32(TPCONF, p); // Request type
char *msg_len_field_pointer = p;
io::marshalUint32(0, p); // Temporary length
// Marshall message body
io::marshalUint32(src.uid, p);
io::marshalUint32(src.gid, p);
io::marshalString(src.drive, p);
io::marshalUint16(src.status, p);
// Calculate the number of bytes actually marshalled
const size_t nbBytesMarshalled = p - dst;
io::marshalUint32(nbBytesMarshalled, msg_len_field_pointer); // Actual length
// Check that the number of bytes marshalled was what was expected
if(totalLen != nbBytesMarshalled) {
castor::exception::Internal ex;
ex.getMessage() << "Failed to marshal TapeConfigRequestMsgBody"
": Mismatch between expected total length and actual"
": expected=" << totalLen << "actual=" << nbBytesMarshalled;
throw ex;
}
return totalLen;
}
//-----------------------------------------------------------------------------
// unmarshal
......
......@@ -37,6 +37,28 @@
namespace castor {
namespace tape {
namespace legacymsg {
/**
* Marshals the specified source message body structure and its implicit
* header into the specified destination buffer.
*
* @param dst The destination message buffer.
* @param dstLen The length of the destination buffer.
* @param src The source structure.
* @return The total length of the message (header + body).
*/
size_t marshal(char *const dst, const size_t dstLen, const TapeConfigRequestMsgBody &src) throw(castor::exception::Exception);
/**
* Marshals the specified source message body structure and its implicit
* header into the specified destination buffer.
*
* @param dst The destination message buffer.
* @param dstLen The length of the destination buffer.
* @param src The source structure.
* @return The total length of the message (header + body).
*/
size_t marshal(char *const dst, const size_t dstLen, const TapeStatRequestMsgBody &src) throw(castor::exception::Exception);
/**
* Unmarshals a message body with the specified destination structure type
......
/******************************************************************************
* castor/server/TapeMarshalTest.cpp
*
* This file is part of the Castor project.
* See http://castor.web.cern.ch/castor
*
* Copyright (C) 2003 CERN
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
*
*
* @author dkruse@cern.ch
*****************************************************************************/
#include "castor/tape/legacymsg/CommonMarshal.hpp"
#include "castor/tape/legacymsg/TapeMarshal.hpp"
#include "castor/utils/utils.hpp"
#include "h/vdqm_constants.h"
#include "h/Ctape.h"
#include "h/serrno.h"
#include <gtest/gtest.h>
namespace unitTests {
class castor_server_TapeMarshalTest : public ::testing::Test {
protected:
virtual void SetUp() {
}
virtual void TearDown() {
}
};
TEST_F(castor_server_TapeMarshalTest, marshalTapeConfigRequestMsgBody) {
using namespace castor::tape::legacymsg;
char buf[80]; // Expect message (header + body) to occupy exactly 80 bytes
TapeConfigRequestMsgBody srcMsgBody;
// Marshal entire message (header + body)
{
srcMsgBody.uid = 1;
srcMsgBody.gid = 2;
castor::utils::copyString(srcMsgBody.drive, "HELLO");
srcMsgBody.status = 4;
size_t bufLen = sizeof(buf);
size_t totalLen = 0; // Total length of message (header + body)
ASSERT_NO_THROW(totalLen = marshal(buf, bufLen, srcMsgBody));
ASSERT_EQ((uint32_t)28, totalLen);
}
// Unmarshall message header
{
MessageHeader dstHeader;
const char *bufPtr = buf;
size_t bufLen = 12; // Length of the message header
ASSERT_NO_THROW(unmarshal(bufPtr, bufLen, dstHeader));
ASSERT_EQ(buf + 12, bufPtr);
ASSERT_EQ((size_t)0, bufLen);
ASSERT_EQ((uint32_t)TPMAGIC, dstHeader.magic);
ASSERT_EQ((uint32_t)TPCONF, dstHeader.reqType);
ASSERT_EQ((uint32_t)28, dstHeader.lenOrStatus);
}
// Unmarshall message body
{
TapeConfigRequestMsgBody dstMsgBody;
const char *bufPtr = buf + 12; // Point at beginning of message body
size_t bufLen = 16; // Length of the message body
ASSERT_NO_THROW(unmarshal(bufPtr, bufLen, dstMsgBody));
ASSERT_EQ(buf + 28, bufPtr);
ASSERT_EQ((size_t)0, bufLen);
ASSERT_EQ((int32_t)1, dstMsgBody.uid);
ASSERT_EQ((int32_t)2, dstMsgBody.gid);
ASSERT_EQ(std::string("HELLO"), dstMsgBody.drive);
ASSERT_EQ((int32_t)4, dstMsgBody.status);
}
}
TEST_F(castor_server_TapeMarshalTest, marshalTapeStatRequestMsgBody) {
using namespace castor::tape::legacymsg;
char buf[80]; // Expect message (header + body) to occupy exactly 80 bytes
TapeStatRequestMsgBody srcMsgBody;
// Marshal entire message (header + body)
{
srcMsgBody.uid = 1;
srcMsgBody.gid = 2;
size_t bufLen = sizeof(buf);
size_t totalLen = 0; // Total length of message (header + body)
ASSERT_NO_THROW(totalLen = marshal(buf, bufLen, srcMsgBody));
ASSERT_EQ((uint32_t)20, totalLen);
}
// Unmarshall message header
{
MessageHeader dstHeader;
const char *bufPtr = buf;
size_t bufLen = 12; // Length of the message header
ASSERT_NO_THROW(unmarshal(bufPtr, bufLen, dstHeader));
ASSERT_EQ(buf + 12, bufPtr);
ASSERT_EQ((size_t)0, bufLen);
ASSERT_EQ((uint32_t)TPMAGIC, dstHeader.magic);
ASSERT_EQ((uint32_t)TPSTAT, dstHeader.reqType);
ASSERT_EQ((uint32_t)20, dstHeader.lenOrStatus);
}
// Unmarshall message body
{
TapeStatRequestMsgBody dstMsgBody;
const char *bufPtr = buf + 12; // Point at beginning of message body
size_t bufLen = 8; // Length of the message body
ASSERT_NO_THROW(unmarshal(bufPtr, bufLen, dstMsgBody));
ASSERT_EQ(buf + 20, bufPtr);
ASSERT_EQ((size_t)0, bufLen);
ASSERT_EQ((int32_t)1, dstMsgBody.uid);
ASSERT_EQ((int32_t)2, dstMsgBody.gid);
}
}
} // namespace unitTests
......@@ -93,6 +93,7 @@ add_executable(castorUnitTests
../castor/tape/tapeserver/daemon/ClientProxyTest.cpp
../castor/tape/legacymsg/RmcMarshalTest.cpp
../castor/tape/legacymsg/VdqmMarshalTest.cpp
../castor/tape/legacymsg/TapeMarshalTest.cpp
../castor/tape/tapeserver/daemon/AdminAcceptHandler.cpp
../castor/tape/tapeserver/daemon/DebugMountSessionForVdqmProtocol.cpp
../castor/tape/tapeserver/daemon/DriveCatalogue.cpp
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment