Skip to content

Commit

Permalink
[core/zip] Add test for compression buffer sizes
Browse files Browse the repository at this point in the history
This would have found any of the previous three commits.
  • Loading branch information
hahnjo committed Feb 8, 2024
1 parent 23261a6 commit 73d8c3d
Show file tree
Hide file tree
Showing 3 changed files with 79 additions and 0 deletions.
2 changes: 2 additions & 0 deletions core/zip/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,5 @@ target_include_directories(Core PUBLIC
)

ROOT_INSTALL_HEADERS()

ROOT_ADD_TEST_SUBDIRECTORY(test)
7 changes: 7 additions & 0 deletions core/zip/test/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Copyright (C) 1995-2024, Rene Brun and Fons Rademakers.
# All rights reserved.
#
# For the licensing terms see $ROOTSYS/LICENSE.
# For the list of contributors see $ROOTSYS/README/CREDITS.

ROOT_ADD_GTEST(ZipTest ZipTest.cxx LIBRARIES Core)
70 changes: 70 additions & 0 deletions core/zip/test/ZipTest.cxx
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
#include <Compression.h>
#include <RZip.h>

#include <gtest/gtest.h>

#include <memory>

static void testZipBufferSizes(ROOT::RCompressionSetting::EAlgorithm::EValues compressionAlgorithm)
{
static constexpr size_t BufferSize = 256;
static constexpr size_t MaxBytes = 128;
static_assert(MaxBytes <= BufferSize, "MaxBytes must be smaller than BufferSize");
static constexpr size_t StartOffset = (BufferSize - MaxBytes) / 2;
// For extra "safety", allocate the buffers on the heap to avoid corrupting the stack should anything go wrong.
std::unique_ptr<char[]> source(new char[BufferSize]);
std::unique_ptr<char[]> target(new char[BufferSize]);

// Fill the buffers with monotonically increasing numbers. This is easy to compress, but that's fine because we scan
// through all possible sizes.
for (size_t i = 0; i < BufferSize; i++) {
source[i] = static_cast<char>(i);
target[i] = static_cast<char>(i);
}

// Now test all possible combinations of target and source sizes. The outer loop is for the target sizes because that
// allows us to check that nothing got overwritten.
for (size_t targetSize = 1; targetSize <= MaxBytes; targetSize++) {
for (size_t sourceSize = 1; sourceSize <= MaxBytes; sourceSize++) {
for (int cxlevel = 1; cxlevel <= 9; cxlevel++) {
int srcsize = static_cast<int>(sourceSize);
int tgtsize = static_cast<int>(targetSize);
int irep = -1;
R__zipMultipleAlgorithm(cxlevel, &srcsize, source.get(), &tgtsize, target.get() + StartOffset, &irep,
compressionAlgorithm);

for (size_t i = 0; i < StartOffset; i++) {
EXPECT_EQ(target[i], static_cast<char>(i));
}
for (size_t i = StartOffset + targetSize + 1; i < BufferSize; i++) {
EXPECT_EQ(target[i], static_cast<char>(i));
}
}
}
}
}

TEST(RZip, ZipBufferSizesOld)
{
testZipBufferSizes(ROOT::RCompressionSetting::EAlgorithm::kOldCompressionAlgo);
}

TEST(RZip, ZipBufferSizesZLIB)
{
testZipBufferSizes(ROOT::RCompressionSetting::EAlgorithm::kZLIB);
}

TEST(RZip, ZipBufferSizesLZMA)
{
testZipBufferSizes(ROOT::RCompressionSetting::EAlgorithm::kLZMA);
}

TEST(RZip, ZipBufferSizesLZ4)
{
testZipBufferSizes(ROOT::RCompressionSetting::EAlgorithm::kLZ4);
}

TEST(RZip, ZipBufferSizesZSTD)
{
testZipBufferSizes(ROOT::RCompressionSetting::EAlgorithm::kZSTD);
}

0 comments on commit 73d8c3d

Please sign in to comment.