Commit 4cda4c15 authored by Steven Murray's avatar Steven Murray
Browse files

Removed tapeserver/castor/io

parent 14080f94
......@@ -18,7 +18,6 @@
#
cmake_minimum_required (VERSION 2.6)
add_subdirectory (io)
add_subdirectory (legacymsg)
add_subdirectory (messages)
add_subdirectory (tape)
......
cmake_minimum_required (VERSION 2.6)
include_directories(${PROJECT_SOURCE_DIR}/tapeserver)
include_directories(${PROJECT_SOURCE_DIR}/tapeserver/h)
add_library (ctaio
io.cpp
IpAndPort.cpp)
add_library (ctaiounittests SHARED
IoTest.cpp)
target_link_libraries (ctaiounittests
ctaio)
install(TARGETS ctaiounittests DESTINATION usr/${CMAKE_INSTALL_LIBDIR})
/******************************************************************************
*
* 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 Castor Dev team, castor-dev@cern.ch
*****************************************************************************/
#pragma once
#include <stdint.h>
#include <stdlib.h>
namespace castor {
namespace io {
const size_t HOSTNAMEBUFLEN = 256;
const int LISTENBACKLOG = 2;
const size_t SERVICENAMEBUFLEN = 256;
} // namespace io
} // namespace castor
/******************************************************************************
*
* 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 Castor Dev team, castor-dev@cern.ch
*****************************************************************************/
#include "castor/io/io.hpp"
#include "common/exception/Errnum.hpp"
#include "common/SmartFd.hpp"
#include <fcntl.h>
#include <gtest/gtest.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <unistd.h>
namespace unitTests {
class castor_io_IoTest: public ::testing::Test {
protected:
const char *const m_listenSockPath;
castor_io_IoTest(): m_listenSockPath("/tmp/listenSockForCastorIoTest") {
// Do nothing
}
void setUp() {
unlink(m_listenSockPath);
}
void tearDown() {
unlink(m_listenSockPath);
}
int createLocalListenSocket(const char *const listenSockPath)
{
// Delete the file to be used for the socket if the file already exists
unlink(listenSockPath);
// Create the socket
cta::SmartFd smartListenSock(socket(PF_LOCAL, SOCK_STREAM, 0));
if(-1 == smartListenSock.get()) {
char strErrBuf[256];
if(0 != strerror_r(errno, strErrBuf, sizeof(strErrBuf))) {
memset(strErrBuf, '\0', sizeof(strErrBuf));
strncpy(strErrBuf, "Unknown", sizeof(strErrBuf) - 1);
}
std::string errorMessage("Call to socket() failed: ");
errorMessage += strErrBuf;
cta::exception::Exception ex;
ex.getMessage() << errorMessage;
throw ex;
}
// Bind the socket
{
struct sockaddr_un listenAddr;
memset(&listenAddr, '\0', sizeof(listenAddr));
listenAddr.sun_family = PF_LOCAL;
strncpy(listenAddr.sun_path, listenSockPath,
sizeof(listenAddr.sun_path) - 1);
cta::exception::Errnum::throwOnNonZero(
bind(smartListenSock.get(), (const struct sockaddr *)&listenAddr,
sizeof(listenAddr)), "Call to bind() failed: ");
}
// Make the socket listen
{
const int backlog = 128;
if(0 != listen(smartListenSock.get(), backlog)) {
char strErrBuf[256];
if(0 != strerror_r(errno, strErrBuf, sizeof(strErrBuf))) {
memset(strErrBuf, '\0', sizeof(strErrBuf));
strncpy(strErrBuf, "Unknown", sizeof(strErrBuf) - 1);
}
std::string errorMessage("Call to listen() failed: ");
errorMessage += strErrBuf;
cta::exception::Exception ex;
ex.getMessage() << errorMessage;
throw ex;
}
}
return smartListenSock.release();
}
}; // class castor_io_IoTest
TEST_F(castor_io_IoTest, connectWithTimeout) {
cta::SmartFd smartListenSock;
ASSERT_NO_THROW(smartListenSock.reset(
createLocalListenSocket(m_listenSockPath)));
cta::SmartFd smartClientConnectionSock;
{
const int sockDomain = PF_LOCAL;
const int sockType = SOCK_STREAM;
const int sockProtocol = 0;
struct sockaddr_un address;
const socklen_t address_len = sizeof(address);
const int timeout = 10; // 10 seconds
memset(&address, '\0', sizeof(address));
address.sun_family = PF_LOCAL;
strncpy(address.sun_path, m_listenSockPath, sizeof(address.sun_path) - 1);
ASSERT_NO_THROW(
smartClientConnectionSock.reset(castor::io::connectWithTimeout(
sockDomain,
sockType,
sockProtocol,
(const struct sockaddr *)&address,
address_len,
timeout)));
}
cta::SmartFd smartServerConnectionSock;
{
const time_t acceptTimeout = 10; // Timeout is in seconds
ASSERT_NO_THROW(smartServerConnectionSock.reset(
castor::io::acceptConnection(smartListenSock.get(), acceptTimeout)));
}
// Send message from client to server and check it was sent
char clientToServerMessageBuf[] =
"Test message from client to server: HELLO";
const size_t clientToServerMessageBufLen = sizeof(clientToServerMessageBuf);
{
const int timeout = 1; // Time out is in seconds
ASSERT_NO_THROW(castor::io::writeBytes(smartClientConnectionSock.get(),
timeout, clientToServerMessageBufLen, clientToServerMessageBuf));
}
{
const int timeout = 1; // Time out is in seconds
char serverInputBuf[clientToServerMessageBufLen];
memset(serverInputBuf, '\0', sizeof(serverInputBuf));
ASSERT_NO_THROW(castor::io::readBytes(smartServerConnectionSock.get(),
timeout, clientToServerMessageBufLen, serverInputBuf));
ASSERT_EQ(std::string(clientToServerMessageBuf),
std::string(serverInputBuf));
}
// Send message from server to client and check it was sent
char serverToClientMessageBuf[] =
"Test message from server to client: BONJOUR";
const size_t serverToClientMessageBufLen = sizeof(serverToClientMessageBuf);
{
const int timeout = 1; // Time out is in seconds
ASSERT_NO_THROW(castor::io::writeBytes(smartServerConnectionSock.get(),
timeout, serverToClientMessageBufLen, serverToClientMessageBuf));
}
{
const int timeout = 1; // Time out is in seconds
char clientInputBuf[serverToClientMessageBufLen];
memset(clientInputBuf, '\0', sizeof(clientInputBuf));
ASSERT_NO_THROW(castor::io::readBytes(smartClientConnectionSock.get(),
timeout, serverToClientMessageBufLen, clientInputBuf));
ASSERT_EQ( std::string(serverToClientMessageBuf),
std::string(clientInputBuf));
}
}
TEST_F(castor_io_IoTest, marshalUint8) {
const uint8_t v = 0x87;
char buf[1];
char *ptr = buf;
memset(buf, '\0', sizeof(buf));
ASSERT_NO_THROW(castor::io::marshalUint8(v, ptr));
ASSERT_EQ(buf+1, ptr);
ASSERT_EQ(0x87 & 0xFF, buf[0] & 0xFF);
}
static void check16BitsWereMarshalledBigEndian(const char *const buf) {
ASSERT_EQ(0x87 & 0xFF, buf[0] & 0xFF);
ASSERT_EQ(0x65 & 0xFF, buf[1] & 0xFF);
}
TEST_F(castor_io_IoTest, marshalInt16) {
const uint16_t v = 0x8765;
char buf[2];
char *ptr = buf;
memset(buf, '\0', sizeof(buf));
ASSERT_NO_THROW(castor::io::marshalInt16(v, ptr));
ASSERT_EQ(buf+2, ptr);
check16BitsWereMarshalledBigEndian(buf);
}
TEST_F(castor_io_IoTest, marshalUint16) {
const uint16_t v = 0x8765;
char buf[2];
char *ptr = buf;
memset(buf, '\0', sizeof(buf));
ASSERT_NO_THROW(castor::io::marshalUint16(v, ptr));
ASSERT_EQ(buf+2, ptr);
check16BitsWereMarshalledBigEndian(buf);
}
static void check32BitsWereMarshalledBigEndian(const char *const buf) {
ASSERT_EQ(0x87 & 0xFF, buf[0] & 0xFF);
ASSERT_EQ(0x65 & 0xFF, buf[1] & 0xFF);
ASSERT_EQ(0x43 & 0xFF, buf[2] & 0xFF);
ASSERT_EQ(0x21 & 0xFF, buf[3] & 0xFF);
}
TEST_F(castor_io_IoTest, marshalInt32) {
const int32_t v = 0x87654321;
char buf[4];
char *ptr = buf;
memset(buf, '\0', sizeof(buf));
ASSERT_NO_THROW(castor::io::marshalInt32(v, ptr));
ASSERT_EQ(buf+4, ptr);
check32BitsWereMarshalledBigEndian(buf);
}
TEST_F(castor_io_IoTest, marshalUint32) {
const uint32_t v = 0x87654321;
char buf[4];
char *ptr = buf;
memset(buf, '\0', sizeof(buf));
ASSERT_NO_THROW(castor::io::marshalUint32(v, ptr));
ASSERT_EQ(buf+4, ptr);
check32BitsWereMarshalledBigEndian(buf);
}
static void check64BitsWereMarshalledBigEndian(const char *const buf) {
ASSERT_EQ(0x88 & 0xFF, buf[0] & 0xFF);
ASSERT_EQ(0x77 & 0xFF, buf[1] & 0xFF);
ASSERT_EQ(0x66 & 0xFF, buf[2] & 0xFF);
ASSERT_EQ(0x55 & 0xFF, buf[3] & 0xFF);
ASSERT_EQ(0x44 & 0xFF, buf[4] & 0xFF);
ASSERT_EQ(0x33 & 0xFF, buf[5] & 0xFF);
ASSERT_EQ(0x22 & 0xFF, buf[6] & 0xFF);
ASSERT_EQ(0x11 & 0xFF, buf[7] & 0xFF);
}
TEST_F(castor_io_IoTest, marshalUint64) {
const uint64_t v = 0x8877665544332211LL;
char buf[8];
char *ptr = buf;
memset(buf, '\0', sizeof(buf));
ASSERT_NO_THROW(castor::io::marshalUint64(v, ptr));
ASSERT_EQ(buf+8, ptr);
check64BitsWereMarshalledBigEndian(buf);
}
static void checkStringWasMarshalled(const char *const buf) {
ASSERT_EQ('V', buf[0]);
ASSERT_EQ('a', buf[1]);
ASSERT_EQ('l', buf[2]);
ASSERT_EQ('u', buf[3]);
ASSERT_EQ('e', buf[4]);
ASSERT_EQ('\0', buf[5]);
ASSERT_EQ('E', buf[6]);
ASSERT_EQ('E', buf[7]);
}
TEST_F(castor_io_IoTest, marshalString) {
const char *const v = "Value";
char buf[8];
char *ptr = buf;
memset(buf, 'E', sizeof(buf));
ASSERT_NO_THROW(castor::io::marshalString(v, ptr));
ASSERT_EQ(buf+6, ptr);
checkStringWasMarshalled(buf);
}
TEST_F(castor_io_IoTest, unmarshalUint8) {
char buf[] = {'\x87'};
size_t bufLen = sizeof(buf);
const char *ptr = buf;
uint8_t v = 0;
ASSERT_NO_THROW(castor::io::unmarshalUint8(ptr, bufLen, v));
ASSERT_EQ(buf+1, ptr);
ASSERT_EQ((size_t)0, bufLen);
ASSERT_EQ(0x87, v);
}
TEST_F(castor_io_IoTest, unmarshalInt16) {
char buf[] = {'\x87', '\x65'};
size_t bufLen = sizeof(buf);
const char *ptr = buf;
int16_t v = 0;
ASSERT_NO_THROW(castor::io::unmarshalInt16(ptr, bufLen, v));
ASSERT_EQ(buf+2, ptr);
ASSERT_EQ((size_t)0, bufLen);
ASSERT_EQ((int16_t)0x8765, v);
}
TEST_F(castor_io_IoTest, unmarshalUint16) {
char buf[] = {'\x87', '\x65'};
size_t bufLen = sizeof(buf);
const char *ptr = buf;
uint16_t v = 0;
ASSERT_NO_THROW(castor::io::unmarshalUint16(ptr, bufLen, v));
ASSERT_EQ(buf+2, ptr);
ASSERT_EQ((size_t)0, bufLen);
ASSERT_EQ((uint16_t)0x8765, v);
}
TEST_F(castor_io_IoTest, unmarshalUint32) {
char buf[] = {'\x87', '\x65', '\x43', '\x21'};
size_t bufLen = sizeof(buf);
const char *ptr = buf;
uint32_t v = 0;
ASSERT_NO_THROW(castor::io::unmarshalUint32(ptr, bufLen, v));
ASSERT_EQ(buf+4, ptr);
ASSERT_EQ((size_t)0, bufLen);
ASSERT_EQ((uint32_t)0x87654321, v);
}
TEST_F(castor_io_IoTest, unmarshalInt32) {
char buf[] = {'\x87', '\x65', '\x43', '\x21'};
size_t bufLen = sizeof(buf);
const char *ptr = buf;
int32_t v = 0;
ASSERT_NO_THROW(castor::io::unmarshalInt32(ptr, bufLen, v));
ASSERT_EQ(buf+4, ptr);
ASSERT_EQ((size_t)0, bufLen);
ASSERT_EQ((int32_t)0x87654321, v);
}
TEST_F(castor_io_IoTest, unmarshalUint64) {
char buf[] = {'\x88', '\x77', '\x66', '\x55', '\x44', '\x33', '\x22', '\x11'};
size_t bufLen = sizeof(buf);
const char *ptr = buf;
uint64_t v = 0;
ASSERT_NO_THROW(castor::io::unmarshalUint64(ptr, bufLen, v));
ASSERT_EQ(buf+8, ptr);
ASSERT_EQ((size_t)0, bufLen);
ASSERT_EQ((uint64_t)0x8877665544332211LL, v);
}
TEST_F(castor_io_IoTest, unmarshalString) {
char src[] = {'V', 'a', 'l', 'u', 'e', '\0', 'E', 'E'};
size_t srcLen = sizeof(src);
const char *srcPtr = src;
char dst[6];
const size_t dstLen = sizeof(dst);
ASSERT_NO_THROW(castor::io::unmarshalString(srcPtr, srcLen, dst, dstLen));
ASSERT_EQ(src+6, srcPtr);
ASSERT_EQ((size_t)2, srcLen);
ASSERT_EQ(std::string("Value"), std::string(dst));
}
} // namespace unitTests
/******************************************************************************
*
* 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 Castor Dev team, castor-dev@cern.ch
*****************************************************************************/
#include "castor/io/IpAndPort.hpp"
//-----------------------------------------------------------------------------
// constructor
//-----------------------------------------------------------------------------
castor::io::IpAndPort::IpAndPort(
const unsigned long ip,
const unsigned short port) throw():
m_ip(ip),
m_port(port) {
// Do nothing
}
//-----------------------------------------------------------------------------
// setIp
//-----------------------------------------------------------------------------
void castor::io::IpAndPort::setIp(const unsigned long ip) throw() {
m_ip = ip;
}
//-----------------------------------------------------------------------------
// setPort
//-----------------------------------------------------------------------------
void castor::io::IpAndPort::setPort(const unsigned short port) throw() {
m_port = port;
}
//-----------------------------------------------------------------------------
// getIp
//-----------------------------------------------------------------------------
unsigned long castor::io::IpAndPort::getIp() const throw() {
return m_ip;
}
//-----------------------------------------------------------------------------
// getPort
//-----------------------------------------------------------------------------
unsigned short castor::io::IpAndPort::getPort() const throw() {
return m_port;
}
/******************************************************************************
*
* 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 Castor Dev team, castor-dev@cern.ch
*****************************************************************************/
#pragma once
#include <stdint.h>
#include <stdlib.h>
namespace castor {
namespace io {
/**
* Class used to store the IP number and the port number of a TCP/IP address.
*/
class IpAndPort {
public:
/**
* Constructor.
*
* @param ip The IP number of the TCP/IP address.
* @param port The port number of the TCP/IP address.
*/
IpAndPort(const unsigned long ip, const unsigned short port) throw();
/**
* Sets the IP number of the TCP/IP address.
*/
void setIp(const unsigned long ip) throw();
/**
* Sets the port number of the TCP/IP address.
*/
void setPort(const unsigned short port) throw();
/**
* Gets the IP number of the TCP/IP address.
*/
unsigned long getIp() const throw();
/**
* Gets the port number of the TCP/IP address.
*/
unsigned short getPort() const throw();
private:
/**
* The IP number of the TCP/IP address.
*/
unsigned long m_ip;
/**
* The port number of the TCP/IP address.
*/
unsigned short m_port;
}; // class IpAndPort
} // namespace io
} // namespace castor
This diff is collapsed.
This diff is collapsed.
......@@ -21,7 +21,6 @@
* @author Castor Dev team, castor-dev@cern.ch
*****************************************************************************/