Commit b8b82fb5 authored by Eric Cano's avatar Eric Cano
Browse files

Replaced byte arrays with simple std::strings

Added url style conversion of checksums
Added support for checksums in mockNs
Fixed support for checksums in the scheduler
Re-instated several ASSERT_NO_THROW which were commented out during debugging.
parent 2a8b51b6
......@@ -15,7 +15,6 @@ set (COMMON_LIB_SRC_FILES
archiveNS/Tape.cpp
archiveNS/TapeFileLocation.cpp
CreationLog.cpp
checksum/ByteArray.cpp
checksum/Checksum.cpp
exception/Backtrace.cpp
exception/DiskException.hpp
......@@ -49,10 +48,10 @@ target_link_libraries (ctacommon
pthread
${SQLITE3_LIBRARY_RELEASE}
uuid
z)
z
Utils)
set (COMMON_UNIT_TESTS_LIB_SRC_FILES
checksum/ByteArrayTest.cpp
checksum/ChecksumTest.cpp
remoteFS/RemotePathTest.cpp
UserIdentityTest.cpp
......
/*
* The CERN Tape Archive (CTA) project
* Copyright (C) 2015 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 3 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, see <http://www.gnu.org/licenses/>.
*/
#include "common/checksum/ByteArray.hpp"
#include <ostream>
#include <strings.h>
//------------------------------------------------------------------------------
// constructor
//------------------------------------------------------------------------------
cta::ByteArray::ByteArray(): m_size(0), m_bytes(NULL) {
}
//------------------------------------------------------------------------------
// constructor
//------------------------------------------------------------------------------
cta::ByteArray::ByteArray(const uint32_t arraySize, const uint8_t *const bytes) {
m_size = arraySize;
m_bytes = new uint8_t[m_size];
for(uint32_t i = 0; i < m_size; i++) {
m_bytes[i] = bytes[i];
}
}
//------------------------------------------------------------------------------
// constructor
//------------------------------------------------------------------------------
cta::ByteArray::ByteArray(const std::string &bytes) {
m_size = bytes.size();
m_bytes = new uint8_t[m_size];
for(uint32_t i = 0; i < m_size; i++) {
m_bytes[i] = bytes.at(i);
}
}
//------------------------------------------------------------------------------
// copy constructor
//------------------------------------------------------------------------------
cta::ByteArray::ByteArray(const uint32_t value) {
m_size = sizeof value;
m_bytes = new uint8_t[sizeof value];
bzero(m_bytes, sizeof m_bytes);
m_bytes[0] = value & 0xFF;
m_bytes[1] = value >> 8 & 0xFF;
m_bytes[2] = value >> 16 & 0xFF;
m_bytes[3] = value >> 24 & 0xFF;
}
//------------------------------------------------------------------------------
// copy constructor
//------------------------------------------------------------------------------
cta::ByteArray::ByteArray(const ByteArray &other) {
m_size = other.m_size;
m_bytes = new uint8_t[m_size];
for(uint32_t i = 0; i < m_size; i++) {
m_bytes[i] = other.m_bytes[i];
}
}
//------------------------------------------------------------------------------
// destructor
//------------------------------------------------------------------------------
cta::ByteArray::~ByteArray() throw() {
delete[] m_bytes;
}
//------------------------------------------------------------------------------
// assignment
//------------------------------------------------------------------------------
cta::ByteArray &cta::ByteArray::operator=(const ByteArray &rhs) {
if(this != &rhs) {
delete[] m_bytes;
m_size = rhs.m_size;
m_bytes = new uint8_t[m_size];
for(uint32_t i = 0; i < m_size; i++) {
m_bytes[i] = rhs.m_bytes[i];
}
}
return *this;
}
//------------------------------------------------------------------------------
// operator==
//------------------------------------------------------------------------------
bool cta::ByteArray::operator==(const ByteArray &rhs) const {
if(this == &rhs) {
return true;
}
if(m_size != rhs.m_size) {
return false;
}
for(uint32_t i = 0; i < m_size; i++) {
if(m_bytes[i] != rhs.m_bytes[i]) {
return false;
}
}
return true;
}
//------------------------------------------------------------------------------
// operator!=
//------------------------------------------------------------------------------
bool cta::ByteArray::operator!=(const ByteArray &rhs) const {
return !operator==(rhs);
}
//------------------------------------------------------------------------------
// getSize
//------------------------------------------------------------------------------
uint32_t cta::ByteArray::getSize() const throw() {
return m_size;
}
//------------------------------------------------------------------------------
// getBytes
//------------------------------------------------------------------------------
const uint8_t *cta::ByteArray::getBytes() const throw() {
return m_bytes;
}
//------------------------------------------------------------------------------
// operator<<
//------------------------------------------------------------------------------
std::ostream &operator<<(std::ostream &os, const cta::ByteArray &obj) {
os << "{";
const auto size = obj.getSize();
const auto bytes = obj.getBytes();
for(uint32_t i = 0; i < size; i++) {
os << bytes[i];
}
os << "}";
return os;
}
/*
* The CERN Tape Archive (CTA) project
* Copyright (C) 2015 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 3 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, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <stdint.h>
#include <string>
namespace cta {
/**
* An array of bytes toegther with its size.
*/
class ByteArray {
public:
/**
* Constructor.
*/
ByteArray();
/**
* Constructor.
*
* Copies the specified array of bytes into this object.
*
* @oaram arraySize The size of the array in bytes.
* @param bytes A raw array of bytes.
*/
ByteArray(const uint32_t arraySize, const uint8_t *const bytes);
/**
* Constructor.
*
* Copies the specified array of bytes into this object.
*
* @param bytes A raw array of bytes.
*/
template<uint32_t arraySize> ByteArray(const uint8_t (&bytes)[arraySize]) {
m_size = arraySize;
m_bytes = new uint8_t[arraySize];
for(uint32_t i = 0; i < arraySize; i++) {
m_bytes[i] = bytes[i];
}
}
/**
* Constructor.
*
* Copies the specified array of bytes into this object.
*
* @param bytes An std::string used to store an array of bytes.
*/
ByteArray(const std::string &bytes);
/**
* Constructor.
*
* Copies the specified uint32_t into this object in little endian byte order.
*
* @param value The value.
*/
explicit ByteArray(const uint32_t value);
/**
* Copy constructor.
*/
ByteArray(const ByteArray &other);
/**
* Destructor.
*
* Deallocates the memory occupied by the array of bytes.
*/
~ByteArray() throw();
/**
* Assignment operator.
*/
ByteArray &operator=(const ByteArray &rhs);
/**
* Returns true if the specified right-hand side is equal to this object.
*
* @param rhs The object on the right-hand side of the == operator.
* @return True if the specified right-hand side is equal to this object.
*/
bool operator==(const ByteArray &rhs) const;
/**
* Returns true if the specified right-hand side is not euqal to this object.
*
* @param rhs The object on the right-hand side of the != operator.
* @return True if the specified right-hand side is not equal to this object.
*/
bool operator!=(const ByteArray &rhs) const;
/**
* Returns the size of the array in bytes.
*
* @return The size of the array in bytes.
*/
uint32_t getSize() const throw();
/**
* Returns the contents of the array of bytes.
*
* This metho shall return NULL if the array of bytes is empty.
*
* @return The contents of the array of bytes or NULL if the array is empty.
*/
const uint8_t *getBytes() const throw();
private:
/**
* The size of the array in bytes.
*/
uint32_t m_size;
/**
* The array of bytes allocated on the heap.
*/
uint8_t *m_bytes;
}; // class ByteArray
} // namespace cta
/**
* Output stream operator for the cta::ByteArray class.
*/
std::ostream &operator<<(std::ostream &os, const cta::ByteArray &obj);
/*
* The CERN Tape Archive (CTA) project
* Copyright (C) 2015 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 3 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, see <http://www.gnu.org/licenses/>.
*/
#include "common/checksum/ByteArray.hpp"
#include <gtest/gtest.h>
namespace unitTests {
class cta_ByteArrayTest : public ::testing::Test {
protected:
virtual void SetUp() {
}
virtual void TearDown() {
}
};
TEST_F(cta_ByteArrayTest, default_constructor) {
using namespace cta;
const ByteArray byteArray;
ASSERT_EQ((uint32_t)0, byteArray.getSize());
ASSERT_EQ(NULL, byteArray.getBytes());
}
TEST_F(cta_ByteArrayTest, two_param_constructor) {
using namespace cta;
const uint32_t arraySize = 4;
const uint8_t bytes[4] = {10, 20, 30, 40};
const ByteArray byteArray(arraySize, bytes);
ASSERT_EQ(arraySize, byteArray.getSize());
ASSERT_EQ((uint8_t)10, byteArray.getBytes()[0]);
ASSERT_EQ((uint8_t)20, byteArray.getBytes()[1]);
ASSERT_EQ((uint8_t)30, byteArray.getBytes()[2]);
ASSERT_EQ((uint8_t)40, byteArray.getBytes()[3]);
}
TEST_F(cta_ByteArrayTest, template_constructor) {
using namespace cta;
const uint8_t bytes[4] = {10, 20, 30, 40};
const ByteArray byteArray(bytes);
ASSERT_EQ((uint32_t)4, byteArray.getSize());
ASSERT_EQ((uint8_t)10, byteArray.getBytes()[0]);
ASSERT_EQ((uint8_t)20, byteArray.getBytes()[1]);
ASSERT_EQ((uint8_t)30, byteArray.getBytes()[2]);
ASSERT_EQ((uint8_t)40, byteArray.getBytes()[3]);
}
TEST_F(cta_ByteArrayTest, string_constructor) {
using namespace cta;
const std::string bytes("Hello");
const ByteArray byteArray(bytes);
ASSERT_EQ((uint32_t)5, byteArray.getSize());
ASSERT_EQ((uint8_t)'H', byteArray.getBytes()[0]);
ASSERT_EQ((uint8_t)'e', byteArray.getBytes()[1]);
ASSERT_EQ((uint8_t)'l', byteArray.getBytes()[2]);
ASSERT_EQ((uint8_t)'l', byteArray.getBytes()[3]);
ASSERT_EQ((uint8_t)'o', byteArray.getBytes()[4]);
}
TEST_F(cta_ByteArrayTest, uint32_t_constructor) {
using namespace cta;
const uint32_t value = 0x10203040;
const ByteArray byteArray(value);
// uint32_t should be stored in little endian byte order
ASSERT_EQ((uint32_t)4, byteArray.getSize());
ASSERT_EQ((uint8_t)0x40, byteArray.getBytes()[0]);
ASSERT_EQ((uint8_t)0x30, byteArray.getBytes()[1]);
ASSERT_EQ((uint8_t)0x20, byteArray.getBytes()[2]);
ASSERT_EQ((uint8_t)0x10, byteArray.getBytes()[3]);
}
TEST_F(cta_ByteArrayTest, copy_constructor) {
using namespace cta;
const uint32_t arraySize = 4;
const uint8_t bytes[4] = {10,20,30,40};
const ByteArray byteArray1(arraySize, bytes);
ASSERT_EQ(arraySize, byteArray1.getSize());
ASSERT_EQ((uint8_t)10, byteArray1.getBytes()[0]);
ASSERT_EQ((uint8_t)20, byteArray1.getBytes()[1]);
ASSERT_EQ((uint8_t)30, byteArray1.getBytes()[2]);
ASSERT_EQ((uint8_t)40, byteArray1.getBytes()[3]);
const ByteArray byteArray2(byteArray1);
ASSERT_EQ(arraySize, byteArray2.getSize());
ASSERT_EQ((uint8_t)10, byteArray2.getBytes()[0]);
ASSERT_EQ((uint8_t)20, byteArray2.getBytes()[1]);
ASSERT_EQ((uint8_t)30, byteArray2.getBytes()[2]);
ASSERT_EQ((uint8_t)40, byteArray2.getBytes()[3]);
ASSERT_NE(byteArray1.getBytes(), byteArray2.getBytes());
}
TEST_F(cta_ByteArrayTest, assignment_operator) {
using namespace cta;
const uint32_t arraySize1 = 4;
const uint8_t bytes1[4] = {10,20,30,40};
const ByteArray byteArray1(arraySize1, bytes1);
ASSERT_EQ(arraySize1, byteArray1.getSize());
ASSERT_EQ((uint8_t)10, byteArray1.getBytes()[0]);
ASSERT_EQ((uint8_t)20, byteArray1.getBytes()[1]);
ASSERT_EQ((uint8_t)30, byteArray1.getBytes()[2]);
ASSERT_EQ((uint8_t)40, byteArray1.getBytes()[3]);
const uint32_t arraySize2 = 10;
const uint8_t bytes2[10] = {10, 9, 8, 7 ,6 , 5, 4, 3, 2, 1};
ByteArray byteArray2(arraySize2, bytes2);
ASSERT_EQ(arraySize2, byteArray2.getSize());
ASSERT_EQ((uint8_t)10, byteArray2.getBytes()[0]);
ASSERT_EQ( (uint8_t)9, byteArray2.getBytes()[1]);
ASSERT_EQ( (uint8_t)8, byteArray2.getBytes()[2]);
ASSERT_EQ( (uint8_t)7, byteArray2.getBytes()[3]);
ASSERT_EQ( (uint8_t)6, byteArray2.getBytes()[4]);
ASSERT_EQ( (uint8_t)5, byteArray2.getBytes()[5]);
ASSERT_EQ( (uint8_t)4, byteArray2.getBytes()[6]);
ASSERT_EQ( (uint8_t)3, byteArray2.getBytes()[7]);
ASSERT_EQ( (uint8_t)2, byteArray2.getBytes()[8]);
ASSERT_EQ( (uint8_t)1, byteArray2.getBytes()[9]);
byteArray2 = byteArray1;
ASSERT_EQ(arraySize1, byteArray2.getSize());
ASSERT_EQ((uint8_t)10, byteArray2.getBytes()[0]);
ASSERT_EQ((uint8_t)20, byteArray2.getBytes()[1]);
ASSERT_EQ((uint8_t)30, byteArray2.getBytes()[2]);
ASSERT_EQ((uint8_t)40, byteArray2.getBytes()[3]);
ASSERT_NE(byteArray1.getBytes(), byteArray2.getBytes());
}
TEST_F(cta_ByteArrayTest, equality_operator_eq) {
using namespace cta;
const uint32_t arraySize1 = 4;
const uint8_t bytes1[4] = {10, 20, 30, 40};
const ByteArray byteArray1(arraySize1, bytes1);
ASSERT_EQ(arraySize1, byteArray1.getSize());
ASSERT_EQ((uint8_t)10, byteArray1.getBytes()[0]);
ASSERT_EQ((uint8_t)20, byteArray1.getBytes()[1]);
ASSERT_EQ((uint8_t)30, byteArray1.getBytes()[2]);
ASSERT_EQ((uint8_t)40, byteArray1.getBytes()[3]);
const uint32_t arraySize2 = 4;
const uint8_t bytes2[4] = {10, 20, 30, 40};
ByteArray byteArray2(arraySize2, bytes2);
ASSERT_EQ(arraySize2, byteArray2.getSize());
ASSERT_EQ((uint8_t)10, byteArray2.getBytes()[0]);
ASSERT_EQ((uint8_t)20, byteArray2.getBytes()[1]);
ASSERT_EQ((uint8_t)30, byteArray2.getBytes()[2]);
ASSERT_EQ((uint8_t)40, byteArray2.getBytes()[3]);
ASSERT_EQ(byteArray1, byteArray2);
}
TEST_F(cta_ByteArrayTest, equality_operator_ne) {
using namespace cta;
const uint32_t arraySize1 = 4;
const uint8_t bytes1[4] = {10,20,30,40};
const ByteArray byteArray1(arraySize1, bytes1);
ASSERT_EQ(arraySize1, byteArray1.getSize());
ASSERT_EQ((uint8_t)10, byteArray1.getBytes()[0]);
ASSERT_EQ((uint8_t)20, byteArray1.getBytes()[1]);
ASSERT_EQ((uint8_t)30, byteArray1.getBytes()[2]);
ASSERT_EQ((uint8_t)40, byteArray1.getBytes()[3]);
const uint32_t arraySize2 = 10;
const uint8_t bytes2[10] = {10, 9, 8, 7 ,6 , 5, 4, 3, 2, 1};
ByteArray byteArray2(arraySize2, bytes2);
ASSERT_EQ(arraySize2, byteArray2.getSize());
ASSERT_EQ((uint8_t)10, byteArray2.getBytes()[0]);
ASSERT_EQ( (uint8_t)9, byteArray2.getBytes()[1]);
ASSERT_EQ( (uint8_t)8, byteArray2.getBytes()[2]);
ASSERT_EQ( (uint8_t)7, byteArray2.getBytes()[3]);
ASSERT_EQ( (uint8_t)6, byteArray2.getBytes()[4]);
ASSERT_EQ( (uint8_t)5, byteArray2.getBytes()[5]);
ASSERT_EQ( (uint8_t)4, byteArray2.getBytes()[6]);
ASSERT_EQ( (uint8_t)3, byteArray2.getBytes()[7]);
ASSERT_EQ( (uint8_t)2, byteArray2.getBytes()[8]);
ASSERT_EQ( (uint8_t)1, byteArray2.getBytes()[9]);
ASSERT_NE(byteArray1, byteArray2);
}
} // namespace unitTests
......@@ -17,7 +17,7 @@
*/
#include "common/checksum/Checksum.hpp"
#include "tapeserver/castor/tape/tapeserver/utils/Regex.hpp"
#include <sstream>
//------------------------------------------------------------------------------
......@@ -35,17 +35,25 @@ const char *cta::Checksum::checksumTypeToStr(const ChecksumType enumValue)
//------------------------------------------------------------------------------
// constructor
//------------------------------------------------------------------------------
cta::Checksum::Checksum(): m_type(CHECKSUMTYPE_NONE) {
}
//------------------------------------------------------------------------------
// constructor
//------------------------------------------------------------------------------
cta::Checksum::Checksum(const ChecksumType &type, const ByteArray &byteArray):
m_type(type),
m_byteArray(byteArray) {
cta::Checksum::Checksum(): m_type(CHECKSUMTYPE_NONE) { }
cta::Checksum::Checksum(const std::string& url) {
if (url.empty()) {
return;
}
castor::tape::utils::Regex re("^adler32:0[Xx]([[:xdigit:]]+)$");
auto result = re.exec(url);
if (result.size()) {
m_type = CHECKSUMTYPE_ADLER32;
std::stringstream valStr(result.at(1));
uint32_t val;
valStr >> std::hex >> val;
setNumeric(val);
}
}
//------------------------------------------------------------------------------
// operator==
//------------------------------------------------------------------------------
......@@ -63,7 +71,7 @@ cta::Checksum::ChecksumType cta::Checksum::getType() const throw() {
//------------------------------------------------------------------------------
// getByteArray
//------------------------------------------------------------------------------
const cta::ByteArray &cta::Checksum::getByteArray() const throw() {
const std::string &cta::Checksum::getByteArray() const throw() {
return m_byteArray;
}
......@@ -71,13 +79,13 @@ const cta::ByteArray &cta::Checksum::getByteArray() const throw() {