vcdecoder5_test.cc revision c7f5f8508d98d5952d42ed7648c2a8f30a4da156
1fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar// Copyright 2008 Google Inc.
2fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar// Author: Lincoln Smith
3fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar//
4fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar// Licensed under the Apache License, Version 2.0 (the "License");
5fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar// you may not use this file except in compliance with the License.
6fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar// You may obtain a copy of the License at
7fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar//
8fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar//      http://www.apache.org/licenses/LICENSE-2.0
9fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar//
10fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar// Unless required by applicable law or agreed to in writing, software
11fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar// distributed under the License is distributed on an "AS IS" BASIS,
12fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar// See the License for the specific language governing permissions and
14fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar// limitations under the License.
15500d3297d2a21edeac4d46cbcbe21bc2352c2a28Chris Lattner
164726d03ab3abce41911c31d1354a18f1258cae4dTed Kremenek#include <config.h>
1719510856727e0e14a3696b2a72c35163bff2a71fJohn McCall#include "google/vcdecoder.h"
18fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar#include <string>
19fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar#include "codetable.h"
20b918d0f5d8f147e1e26c34e6cf42a79af2d2ec41Argyrios Kyrtzidis#include "testing.h"
21b918d0f5d8f147e1e26c34e6cf42a79af2d2ec41Argyrios Kyrtzidis#include "vcdecoder_test.h"
22b918d0f5d8f147e1e26c34e6cf42a79af2d2ec41Argyrios Kyrtzidis
23b918d0f5d8f147e1e26c34e6cf42a79af2d2ec41Argyrios Kyrtzidisnamespace open_vcdiff {
24b918d0f5d8f147e1e26c34e6cf42a79af2d2ec41Argyrios Kyrtzidisnamespace {
25b918d0f5d8f147e1e26c34e6cf42a79af2d2ec41Argyrios Kyrtzidis
26b918d0f5d8f147e1e26c34e6cf42a79af2d2ec41Argyrios Kyrtzidis
27b918d0f5d8f147e1e26c34e6cf42a79af2d2ec41Argyrios Kyrtzidis// Decode an encoding that uses a RUN instruction to allocate 64MB.
28b918d0f5d8f147e1e26c34e6cf42a79af2d2ec41Argyrios Kyrtzidisclass VCDiffLargeTargetTest : public VCDiffDecoderTest {
29b918d0f5d8f147e1e26c34e6cf42a79af2d2ec41Argyrios Kyrtzidis protected:
30b918d0f5d8f147e1e26c34e6cf42a79af2d2ec41Argyrios Kyrtzidis  VCDiffLargeTargetTest();
31aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman  virtual ~VCDiffLargeTargetTest() {}
32aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman
33aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman  static const char kLargeRunWindow[];
34aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman};
3580c60f72848896f867f6b7e664e7060d9e78f019Douglas Gregor
3680c60f72848896f867f6b7e664e7060d9e78f019Douglas Gregorconst char VCDiffLargeTargetTest::kLargeRunWindow[] = {
3780c60f72848896f867f6b7e664e7060d9e78f019Douglas Gregor    0x00,  // Win_Indicator: no source segment
38aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman    0x0E,  // Length of the delta encoding
39aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman    0xA0,  // Size of the target window (0x4000000)
40aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman    0x80,  // Size of the target window cont'd
41aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman    0x80,  // Size of the target window cont'd
42aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman    0x00,  // Size of the target window cont'd
43aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman    0x00,  // Delta_indicator (no compression)
44aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman    0x00,  // length of data for ADDs and RUNs
45aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman    0x06,  // length of instructions section
46aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman    0x00,  // length of addresses for COPYs
47aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman    // Interleaved segment
48aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman    0x00,  // VCD_RUN size 0
49aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman    0xA0,  // Size of RUN (0x4000000)
50aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman    0x80,  // Size of RUN cont'd
51aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman    0x80,  // Size of RUN cont'd
52aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman    0x00,  // Size of RUN cont'd
53aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman    0xBE,  // Data for RUN
54aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman};
55aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman
56aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli FriedmanVCDiffLargeTargetTest::VCDiffLargeTargetTest() {
57aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman  UseInterleavedFileHeader();
58aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman}
59aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman
60aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman// Ensure that, with allow_vcd_target set to false, we can decode any number of
61aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman// 64MB windows without running out of memory.
62aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli FriedmanTEST_F(VCDiffLargeTargetTest, Decode) {
63aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman  // 50 x 64MB = 3.2GB, which should be too large if memory usage accumulates
64aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman  // during each iteration.
65aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman  const int kIterations = 50;
66aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman  decoder_.SetAllowVcdTarget(false);
67aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman  decoder_.SetMaximumTargetFileSize(0x4000000UL * 50);
68aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman  decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
69aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman  EXPECT_TRUE(decoder_.DecodeChunk(delta_file_header_.data(),
70aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman                                   delta_file_header_.size(),
71aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman                                   &output_));
72aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman  EXPECT_EQ("", output_);
73aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman  for (int i = 0; i < kIterations; i++) {
74aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman    EXPECT_TRUE(decoder_.DecodeChunk(kLargeRunWindow, sizeof(kLargeRunWindow),
75aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman                                     &output_));
76aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman    EXPECT_EQ(0x4000000U, output_.size());
7784021556baceb76eedf7d44be8ba71d9b8cfaccePeter Collingbourne    EXPECT_EQ(static_cast<char>(0xBE), output_[0]);
78aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman    EXPECT_EQ(static_cast<char>(0xBE),
79aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman              output_[output_.size() / 2]);  // middle element
80aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman    EXPECT_EQ(static_cast<char>(0xBE),
81aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman              output_[output_.size() - 1]);  // last element
82aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman    output_.clear();
83aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman  }
84aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman  EXPECT_TRUE(decoder_.FinishDecoding());
85aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman}
86fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar
87fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar// If we don't increase the maximum target file size first, the same test should
88fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar// produce an error.
89fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel DunbarTEST_F(VCDiffLargeTargetTest, DecodeReachesMaxFileSize) {
9080c60f72848896f867f6b7e664e7060d9e78f019Douglas Gregor  decoder_.SetAllowVcdTarget(false);
9180c60f72848896f867f6b7e664e7060d9e78f019Douglas Gregor  decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
9280c60f72848896f867f6b7e664e7060d9e78f019Douglas Gregor  EXPECT_TRUE(decoder_.DecodeChunk(delta_file_header_.data(),
93fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar                                   delta_file_header_.size(),
94fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar                                   &output_));
95fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar  EXPECT_EQ("", output_);
96fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar  // The default maximum target file size is 64MB, which just matches the target
97fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar  // data produced by a single iteration.
984726d03ab3abce41911c31d1354a18f1258cae4dTed Kremenek  EXPECT_TRUE(decoder_.DecodeChunk(kLargeRunWindow, sizeof(kLargeRunWindow),
99fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar                                   &output_));
100fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar  EXPECT_EQ(0x4000000U, output_.size());
101fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar  EXPECT_EQ(static_cast<char>(0xBE), output_[0]);
102f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall  EXPECT_EQ(static_cast<char>(0xBE),
103fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar            output_[output_.size() / 2]);  // middle element
10460d7b3a319d84d688752be3870615ac0f111fb16John McCall  EXPECT_EQ(static_cast<char>(0xBE),
105fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar            output_[output_.size() - 1]);  // last element
1061eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  output_.clear();
107fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar  // Trying to decode a second window should exceed the target file size limit.
108fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar  EXPECT_FALSE(decoder_.DecodeChunk(kLargeRunWindow, sizeof(kLargeRunWindow),
1090e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl                                    &output_));
110fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar}
111fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar
112fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar}  // unnamed namespace
113fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar}  // namespace open_vcdiff
114fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar