diff options
Diffstat (limited to 'sdch/open-vcdiff/src/vcdecoder5_test.cc')
-rw-r--r-- | sdch/open-vcdiff/src/vcdecoder5_test.cc | 113 |
1 files changed, 113 insertions, 0 deletions
diff --git a/sdch/open-vcdiff/src/vcdecoder5_test.cc b/sdch/open-vcdiff/src/vcdecoder5_test.cc new file mode 100644 index 0000000..641a0d7 --- /dev/null +++ b/sdch/open-vcdiff/src/vcdecoder5_test.cc @@ -0,0 +1,113 @@ +// Copyright 2008 Google Inc. +// Author: Lincoln Smith +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include <config.h> +#include "google/vcdecoder.h" +#include <string> +#include "codetable.h" +#include "testing.h" +#include "vcdecoder_test.h" + +namespace open_vcdiff { +namespace { + + +// Decode an encoding that uses a RUN instruction to allocate 64MB. +class VCDiffLargeTargetTest : public VCDiffDecoderTest { + protected: + VCDiffLargeTargetTest(); + virtual ~VCDiffLargeTargetTest() {} + + static const char kLargeRunWindow[]; +}; + +const char VCDiffLargeTargetTest::kLargeRunWindow[] = { + 0x00, // Win_Indicator: no source segment + 0x0E, // Length of the delta encoding + 0xA0, // Size of the target window (0x4000000) + 0x80, // Size of the target window cont'd + 0x80, // Size of the target window cont'd + 0x00, // Size of the target window cont'd + 0x00, // Delta_indicator (no compression) + 0x00, // length of data for ADDs and RUNs + 0x06, // length of instructions section + 0x00, // length of addresses for COPYs + // Interleaved segment + 0x00, // VCD_RUN size 0 + 0xA0, // Size of RUN (0x4000000) + 0x80, // Size of RUN cont'd + 0x80, // Size of RUN cont'd + 0x00, // Size of RUN cont'd + 0xBE, // Data for RUN +}; + +VCDiffLargeTargetTest::VCDiffLargeTargetTest() { + UseInterleavedFileHeader(); +} + +// Ensure that, with allow_vcd_target set to false, we can decode any number of +// 64MB windows without running out of memory. +TEST_F(VCDiffLargeTargetTest, Decode) { + // 50 x 64MB = 3.2GB, which should be too large if memory usage accumulates + // during each iteration. + const int kIterations = 50; + decoder_.SetAllowVcdTarget(false); + decoder_.SetMaximumTargetFileSize(0x4000000UL * 50); + decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); + EXPECT_TRUE(decoder_.DecodeChunk(delta_file_header_.data(), + delta_file_header_.size(), + &output_)); + EXPECT_EQ("", output_); + for (int i = 0; i < kIterations; i++) { + EXPECT_TRUE(decoder_.DecodeChunk(kLargeRunWindow, sizeof(kLargeRunWindow), + &output_)); + EXPECT_EQ(0x4000000U, output_.size()); + EXPECT_EQ(static_cast<char>(0xBE), output_[0]); + EXPECT_EQ(static_cast<char>(0xBE), + output_[output_.size() / 2]); // middle element + EXPECT_EQ(static_cast<char>(0xBE), + output_[output_.size() - 1]); // last element + output_.clear(); + } + EXPECT_TRUE(decoder_.FinishDecoding()); +} + +// If we don't increase the maximum target file size first, the same test should +// produce an error. +TEST_F(VCDiffLargeTargetTest, DecodeReachesMaxFileSize) { + decoder_.SetAllowVcdTarget(false); + decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); + EXPECT_TRUE(decoder_.DecodeChunk(delta_file_header_.data(), + delta_file_header_.size(), + &output_)); + EXPECT_EQ("", output_); + // The default maximum target file size is 64MB, which just matches the target + // data produced by a single iteration. + EXPECT_TRUE(decoder_.DecodeChunk(kLargeRunWindow, sizeof(kLargeRunWindow), + &output_)); + EXPECT_EQ(0x4000000U, output_.size()); + EXPECT_EQ(static_cast<char>(0xBE), output_[0]); + EXPECT_EQ(static_cast<char>(0xBE), + output_[output_.size() / 2]); // middle element + EXPECT_EQ(static_cast<char>(0xBE), + output_[output_.size() - 1]); // last element + output_.clear(); + // Trying to decode a second window should exceed the target file size limit. + EXPECT_FALSE(decoder_.DecodeChunk(kLargeRunWindow, sizeof(kLargeRunWindow), + &output_)); +} + +} // unnamed namespace +} // namespace open_vcdiff |