xref: /aosp_15_r20/external/angle/src/libANGLE/Decompress_unittest.cpp (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
1*8975f5c5SAndroid Build Coastguard Worker //
2*8975f5c5SAndroid Build Coastguard Worker // Copyright 2024 The ANGLE Project Authors. All rights reserved.
3*8975f5c5SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
4*8975f5c5SAndroid Build Coastguard Worker // found in the LICENSE file.
5*8975f5c5SAndroid Build Coastguard Worker //
6*8975f5c5SAndroid Build Coastguard Worker // Decompress_unittest.cpp: Unit tests for the |(Compress/Decompress)*Blob| functions.
7*8975f5c5SAndroid Build Coastguard Worker 
8*8975f5c5SAndroid Build Coastguard Worker #include <gtest/gtest.h>
9*8975f5c5SAndroid Build Coastguard Worker 
10*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/angletypes.h"
11*8975f5c5SAndroid Build Coastguard Worker 
12*8975f5c5SAndroid Build Coastguard Worker namespace angle
13*8975f5c5SAndroid Build Coastguard Worker {
14*8975f5c5SAndroid Build Coastguard Worker namespace
15*8975f5c5SAndroid Build Coastguard Worker {
16*8975f5c5SAndroid Build Coastguard Worker class DecompressTest : public ::testing::Test
17*8975f5c5SAndroid Build Coastguard Worker {
18*8975f5c5SAndroid Build Coastguard Worker   protected:
SetUp()19*8975f5c5SAndroid Build Coastguard Worker     void SetUp() override
20*8975f5c5SAndroid Build Coastguard Worker     {
21*8975f5c5SAndroid Build Coastguard Worker         constexpr size_t kTestDataSize = 100'000;
22*8975f5c5SAndroid Build Coastguard Worker 
23*8975f5c5SAndroid Build Coastguard Worker         mTestData.resize(kTestDataSize);
24*8975f5c5SAndroid Build Coastguard Worker         for (size_t i = 0; i < kTestDataSize; ++i)
25*8975f5c5SAndroid Build Coastguard Worker         {
26*8975f5c5SAndroid Build Coastguard Worker             mTestData[i] = static_cast<uint8_t>(i);
27*8975f5c5SAndroid Build Coastguard Worker         }
28*8975f5c5SAndroid Build Coastguard Worker 
29*8975f5c5SAndroid Build Coastguard Worker         ASSERT_TRUE(CompressBlob(mTestData.size(), mTestData.data(), &mCompressedData));
30*8975f5c5SAndroid Build Coastguard Worker     }
31*8975f5c5SAndroid Build Coastguard Worker 
setCompressedDataLastDWord(uint32_t value)32*8975f5c5SAndroid Build Coastguard Worker     void setCompressedDataLastDWord(uint32_t value)
33*8975f5c5SAndroid Build Coastguard Worker     {
34*8975f5c5SAndroid Build Coastguard Worker         ASSERT(IsLittleEndian());
35*8975f5c5SAndroid Build Coastguard Worker         ASSERT(mCompressedData.size() > sizeof(value));
36*8975f5c5SAndroid Build Coastguard Worker         memcpy(mCompressedData.data() + mCompressedData.size() - sizeof(value), &value,
37*8975f5c5SAndroid Build Coastguard Worker                sizeof(value));
38*8975f5c5SAndroid Build Coastguard Worker     }
39*8975f5c5SAndroid Build Coastguard Worker 
decompress(size_t compressedSize,size_t maxUncompressedDataSize)40*8975f5c5SAndroid Build Coastguard Worker     bool decompress(size_t compressedSize, size_t maxUncompressedDataSize)
41*8975f5c5SAndroid Build Coastguard Worker     {
42*8975f5c5SAndroid Build Coastguard Worker         return DecompressBlob(mCompressedData.data(), compressedSize, maxUncompressedDataSize,
43*8975f5c5SAndroid Build Coastguard Worker                               &mUncompressedData);
44*8975f5c5SAndroid Build Coastguard Worker     }
45*8975f5c5SAndroid Build Coastguard Worker 
checkUncompressedData()46*8975f5c5SAndroid Build Coastguard Worker     bool checkUncompressedData()
47*8975f5c5SAndroid Build Coastguard Worker     {
48*8975f5c5SAndroid Build Coastguard Worker         return (mTestData.size() == mUncompressedData.size()) &&
49*8975f5c5SAndroid Build Coastguard Worker                (memcmp(mTestData.data(), mUncompressedData.data(), mTestData.size()) == 0);
50*8975f5c5SAndroid Build Coastguard Worker     }
51*8975f5c5SAndroid Build Coastguard Worker 
52*8975f5c5SAndroid Build Coastguard Worker     std::vector<uint8_t> mTestData;
53*8975f5c5SAndroid Build Coastguard Worker     MemoryBuffer mCompressedData;
54*8975f5c5SAndroid Build Coastguard Worker     MemoryBuffer mUncompressedData;
55*8975f5c5SAndroid Build Coastguard Worker };
56*8975f5c5SAndroid Build Coastguard Worker 
57*8975f5c5SAndroid Build Coastguard Worker // Tests that decompressing full data has no errors.
TEST_F(DecompressTest,FullData)58*8975f5c5SAndroid Build Coastguard Worker TEST_F(DecompressTest, FullData)
59*8975f5c5SAndroid Build Coastguard Worker {
60*8975f5c5SAndroid Build Coastguard Worker     EXPECT_TRUE(decompress(mCompressedData.size(), mTestData.size()));
61*8975f5c5SAndroid Build Coastguard Worker     EXPECT_TRUE(checkUncompressedData());
62*8975f5c5SAndroid Build Coastguard Worker }
63*8975f5c5SAndroid Build Coastguard Worker 
64*8975f5c5SAndroid Build Coastguard Worker // Tests expected failure if |maxUncompressedDataSize| is less than actual uncompressed size.
TEST_F(DecompressTest,InsufficientMaxUncompressedDataSize)65*8975f5c5SAndroid Build Coastguard Worker TEST_F(DecompressTest, InsufficientMaxUncompressedDataSize)
66*8975f5c5SAndroid Build Coastguard Worker {
67*8975f5c5SAndroid Build Coastguard Worker     EXPECT_FALSE(decompress(mCompressedData.size(), mTestData.size() - 1));
68*8975f5c5SAndroid Build Coastguard Worker }
69*8975f5c5SAndroid Build Coastguard Worker 
70*8975f5c5SAndroid Build Coastguard Worker // Tests expected failure if try to decompress partial compressed data.
TEST_F(DecompressTest,UnexpectedPartialData)71*8975f5c5SAndroid Build Coastguard Worker TEST_F(DecompressTest, UnexpectedPartialData)
72*8975f5c5SAndroid Build Coastguard Worker {
73*8975f5c5SAndroid Build Coastguard Worker     // Use this to avoid |maxUncompressedDataSize| affecting the test.
74*8975f5c5SAndroid Build Coastguard Worker     constexpr size_t kMaxUncompressedDataSize = std::numeric_limits<size_t>::max();
75*8975f5c5SAndroid Build Coastguard Worker 
76*8975f5c5SAndroid Build Coastguard Worker     EXPECT_FALSE(decompress(mCompressedData.size() - 1, kMaxUncompressedDataSize));
77*8975f5c5SAndroid Build Coastguard Worker }
78*8975f5c5SAndroid Build Coastguard Worker 
79*8975f5c5SAndroid Build Coastguard Worker // Tests expected failure if try to decompress corrupted data.
TEST_F(DecompressTest,CorruptedData)80*8975f5c5SAndroid Build Coastguard Worker TEST_F(DecompressTest, CorruptedData)
81*8975f5c5SAndroid Build Coastguard Worker {
82*8975f5c5SAndroid Build Coastguard Worker     // Corrupt the compressed data.
83*8975f5c5SAndroid Build Coastguard Worker     const size_t corruptIndex = mCompressedData.size() / 2;
84*8975f5c5SAndroid Build Coastguard Worker     mCompressedData[corruptIndex] ^= 255;
85*8975f5c5SAndroid Build Coastguard Worker 
86*8975f5c5SAndroid Build Coastguard Worker     EXPECT_FALSE(decompress(mCompressedData.size(), mTestData.size()));
87*8975f5c5SAndroid Build Coastguard Worker }
88*8975f5c5SAndroid Build Coastguard Worker 
89*8975f5c5SAndroid Build Coastguard Worker // Tests expected failures if try to decompress data with the corrupted last dword.
TEST_F(DecompressTest,CorruptedLastDWord)90*8975f5c5SAndroid Build Coastguard Worker TEST_F(DecompressTest, CorruptedLastDWord)
91*8975f5c5SAndroid Build Coastguard Worker {
92*8975f5c5SAndroid Build Coastguard Worker     // Last dword stores decompressed data size and not the actual compressed data. This dword must
93*8975f5c5SAndroid Build Coastguard Worker     // match the decompressed size. Decompress should fail if it is not the case.
94*8975f5c5SAndroid Build Coastguard Worker 
95*8975f5c5SAndroid Build Coastguard Worker     // Use this to avoid |maxUncompressedDataSize| affecting the test.
96*8975f5c5SAndroid Build Coastguard Worker     constexpr size_t kMaxUncompressedDataSize = std::numeric_limits<size_t>::max();
97*8975f5c5SAndroid Build Coastguard Worker 
98*8975f5c5SAndroid Build Coastguard Worker     // Try to decompress with decreased size in the last dword.
99*8975f5c5SAndroid Build Coastguard Worker     setCompressedDataLastDWord(static_cast<uint32_t>(mTestData.size() - 1));
100*8975f5c5SAndroid Build Coastguard Worker     EXPECT_FALSE(decompress(mCompressedData.size(), kMaxUncompressedDataSize));
101*8975f5c5SAndroid Build Coastguard Worker 
102*8975f5c5SAndroid Build Coastguard Worker     // Try to decompress with increased size in the last dword.
103*8975f5c5SAndroid Build Coastguard Worker     setCompressedDataLastDWord(static_cast<uint32_t>(mTestData.size() + 1));
104*8975f5c5SAndroid Build Coastguard Worker     EXPECT_FALSE(decompress(mCompressedData.size(), kMaxUncompressedDataSize));
105*8975f5c5SAndroid Build Coastguard Worker 
106*8975f5c5SAndroid Build Coastguard Worker     // Try to decompress with the last dword set to 0.
107*8975f5c5SAndroid Build Coastguard Worker     setCompressedDataLastDWord(0);
108*8975f5c5SAndroid Build Coastguard Worker     EXPECT_FALSE(decompress(mCompressedData.size(), kMaxUncompressedDataSize));
109*8975f5c5SAndroid Build Coastguard Worker 
110*8975f5c5SAndroid Build Coastguard Worker     // Decompress with the last dword set to the correct size should succeed.
111*8975f5c5SAndroid Build Coastguard Worker     setCompressedDataLastDWord(static_cast<uint32_t>(mTestData.size()));
112*8975f5c5SAndroid Build Coastguard Worker     EXPECT_TRUE(decompress(mCompressedData.size(), kMaxUncompressedDataSize));
113*8975f5c5SAndroid Build Coastguard Worker     EXPECT_TRUE(checkUncompressedData());
114*8975f5c5SAndroid Build Coastguard Worker }
115*8975f5c5SAndroid Build Coastguard Worker 
116*8975f5c5SAndroid Build Coastguard Worker }  // anonymous namespace
117*8975f5c5SAndroid Build Coastguard Worker }  // namespace angle
118