ddnet/src/test/compression.cpp

85 lines
2.9 KiB
C++

#include <gtest/gtest.h>
#include <engine/shared/compression.h>
static const int DATA[] = {0, 1, -1, 32, 64, 256, -512, 12345, -123456, 1234567, 12345678, 123456789, 2147483647, (-2147483647 - 1)};
static const int NUM = std::size(DATA);
static const int SIZES[NUM] = {1, 1, 1, 1, 2, 2, 2, 3, 3, 4, 4, 4, 5, 5};
TEST(CVariableInt, RoundtripPackUnpack)
{
for(int i = 0; i < NUM; i++)
{
unsigned char aPacked[CVariableInt::MAX_BYTES_PACKED];
int Result;
EXPECT_EQ(CVariableInt::Pack(aPacked, DATA[i], sizeof(aPacked)) - aPacked, (ptrdiff_t)SIZES[i]);
EXPECT_EQ(CVariableInt::Unpack(aPacked, &Result, sizeof(aPacked)) - aPacked, (ptrdiff_t)SIZES[i]);
EXPECT_EQ(Result, DATA[i]);
}
}
TEST(CVariableInt, UnpackInvalid)
{
unsigned char aPacked[CVariableInt::MAX_BYTES_PACKED];
for(auto &Byte : aPacked)
Byte = 0xFF;
int Result;
EXPECT_EQ(CVariableInt::Unpack(aPacked, &Result, sizeof(aPacked)) - aPacked, (ptrdiff_t)CVariableInt::MAX_BYTES_PACKED);
EXPECT_EQ(Result, (-2147483647 - 1));
aPacked[0] &= ~0x40; // unset sign bit
EXPECT_EQ(CVariableInt::Unpack(aPacked, &Result, sizeof(aPacked)) - aPacked, (ptrdiff_t)CVariableInt::MAX_BYTES_PACKED);
EXPECT_EQ(Result, 2147483647);
}
TEST(CVariableInt, PackBufferTooSmall)
{
unsigned char aPacked[CVariableInt::MAX_BYTES_PACKED / 2]; // too small
EXPECT_EQ(CVariableInt::Pack(aPacked, 2147483647, sizeof(aPacked)), (const unsigned char *)0x0);
}
TEST(CVariableInt, UnpackBufferTooSmall)
{
unsigned char aPacked[CVariableInt::MAX_BYTES_PACKED / 2];
for(auto &Byte : aPacked)
Byte = 0xFF; // extended bits are set, but buffer ends too early
int UnusedResult;
EXPECT_EQ(CVariableInt::Unpack(aPacked, &UnusedResult, sizeof(aPacked)), (const unsigned char *)0x0);
}
TEST(CVariableInt, RoundtripCompressDecompress)
{
unsigned char aCompressed[NUM * CVariableInt::MAX_BYTES_PACKED];
int aDecompressed[NUM];
long ExpectedCompressedSize = 0;
for(auto Size : SIZES)
ExpectedCompressedSize += Size;
long CompressedSize = CVariableInt::Compress(DATA, sizeof(DATA), aCompressed, sizeof(aCompressed));
ASSERT_EQ(CompressedSize, ExpectedCompressedSize);
long DecompressedSize = CVariableInt::Decompress(aCompressed, ExpectedCompressedSize, aDecompressed, sizeof(aDecompressed));
ASSERT_EQ(DecompressedSize, sizeof(DATA));
for(int i = 0; i < NUM; i++)
{
EXPECT_EQ(aDecompressed[i], DATA[i]);
}
}
TEST(CVariableInt, CompressBufferTooSmall)
{
unsigned char aCompressed[NUM]; // too small
long CompressedSize = CVariableInt::Compress(DATA, sizeof(DATA), aCompressed, sizeof(aCompressed));
ASSERT_EQ(CompressedSize, -1);
}
TEST(CVariableInt, DecompressBufferTooSmall)
{
unsigned char aCompressed[] = {0x00, 0x01, 0x40, 0x20, 0x80, 0x01, 0x80, 0x04, 0xFF, 0x07, 0xB9, 0xC0, 0x01};
int aUncompressed[4]; // too small
long CompressedSize = CVariableInt::Decompress(aCompressed, sizeof(aCompressed), aUncompressed, sizeof(aUncompressed));
ASSERT_EQ(CompressedSize, -1);
}