summaryrefslogtreecommitdiffstats
path: root/sdch/open-vcdiff/src/vcdecoder5_test.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sdch/open-vcdiff/src/vcdecoder5_test.cc')
-rw-r--r--sdch/open-vcdiff/src/vcdecoder5_test.cc113
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