From b6417c0dee85cef1e695b6e9ff877482f7f10914 Mon Sep 17 00:00:00 2001
From: Michael Davis <michael.davis@cern.ch>
Date: Thu, 4 Jul 2019 11:30:20 +0200
Subject: [PATCH] [catalogue] Fixes checksum_adler32 for unit tests

- Removes assumption that if we have a valid checksumBlob it must
  contain an ADLER32 checksum. (Some of the unit tests have MD5
  checksums only).
---
 catalogue/RdbmsCatalogue.cpp         | 9 ++++++++-
 common/checksum/ChecksumBlob.hpp     | 9 ++++++++-
 common/checksum/ChecksumBlobTest.cpp | 8 ++++++++
 3 files changed, 24 insertions(+), 2 deletions(-)

diff --git a/catalogue/RdbmsCatalogue.cpp b/catalogue/RdbmsCatalogue.cpp
index 3a42339590..8334552f18 100644
--- a/catalogue/RdbmsCatalogue.cpp
+++ b/catalogue/RdbmsCatalogue.cpp
@@ -4329,7 +4329,14 @@ void RdbmsCatalogue::insertArchiveFile(rdbms::Conn &conn, const ArchiveFileRow &
     stmt.bindUint64(":DISK_FILE_GID", row.diskFileGid);
     stmt.bindUint64(":SIZE_IN_BYTES", row.size);
     stmt.bindBlob  (":CHECKSUM_BLOB", row.checksumBlob.serialize());
-    stmt.bindBlob  (":CHECKSUM_ADLER32", "0x" + checksum::ChecksumBlob::ByteArrayToHex(row.checksumBlob.at(checksum::ADLER32)));
+    // Keep transition ADLER32 checksum up-to-date if it exists
+    std::string adler32str;
+    try {
+      adler32str = checksum::ChecksumBlob::ByteArrayToHex(row.checksumBlob.at(checksum::ADLER32));
+    } catch(exception::ChecksumTypeMismatch &ex) {
+      adler32str = "0";
+    }
+    stmt.bindBlob  (":CHECKSUM_ADLER32", "0x" + adler32str);
     stmt.bindString(":STORAGE_CLASS_NAME", row.storageClassName);
     stmt.bindUint64(":CREATION_TIME", now);
     stmt.bindUint64(":RECONCILIATION_TIME", now);
diff --git a/common/checksum/ChecksumBlob.hpp b/common/checksum/ChecksumBlob.hpp
index 2dd33ba834..25b1251724 100644
--- a/common/checksum/ChecksumBlob.hpp
+++ b/common/checksum/ChecksumBlob.hpp
@@ -135,7 +135,14 @@ public:
    * Return the checksum for the specified key
    */
   std::string at(ChecksumType type) const {
-    return m_cs.at(type);
+    try {
+      return m_cs.at(type);
+    } catch(std::out_of_range) {
+      std::stringstream ss;
+      ss << ChecksumTypeName.at(type) << " checksum not found. Checksum blob contents: "
+         << *this;
+      throw exception::ChecksumTypeMismatch(ss.str());
+    }
   }
 
   /*!
diff --git a/common/checksum/ChecksumBlobTest.cpp b/common/checksum/ChecksumBlobTest.cpp
index a46018d244..1a9bd3768b 100644
--- a/common/checksum/ChecksumBlobTest.cpp
+++ b/common/checksum/ChecksumBlobTest.cpp
@@ -38,6 +38,14 @@ TEST_F(cta_ChecksumBlobTest, checksum_types) {
   ASSERT_EQ(checksumBlob.empty(), true);
   ASSERT_EQ(checksumBlob.size(), 0);
 
+  // Checksum type not in blob
+  ASSERT_THROW(checksumBlob.at(NONE),    ChecksumTypeMismatch);
+  ASSERT_THROW(checksumBlob.at(ADLER32), ChecksumTypeMismatch);
+  ASSERT_THROW(checksumBlob.at(CRC32),   ChecksumTypeMismatch);
+  ASSERT_THROW(checksumBlob.at(CRC32C),  ChecksumTypeMismatch);
+  ASSERT_THROW(checksumBlob.at(MD5),     ChecksumTypeMismatch);
+  ASSERT_THROW(checksumBlob.at(SHA1),    ChecksumTypeMismatch);
+
   // valid insertions
   checksumBlob.insert(NONE, "");                      // 0 bits
   ASSERT_EQ(checksumBlob.size(), 1);
-- 
GitLab