• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2008 Google Inc.
2 // Author: Lincoln Smith
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 //      http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
16 // Unit tests for the class VCDiffCodeTableWriter, found in encodetable.h.
17 
18 #include <config.h>
19 #include "encodetable.h"
20 #include <string.h>  // strlen
21 #include <algorithm>
22 #include <string>
23 #include <vector>
24 #include "addrcache.h"  // VCDiffAddressCache::kDefaultNearCacheSize
25 #include "checksum.h"
26 #include "codetable.h"
27 #include "google/output_string.h"
28 #include "testing.h"
29 #include "vcdiff_defs.h"
30 
31 namespace open_vcdiff {
32 namespace {
33 
34 class CodeTableWriterTest : public testing::Test {
35  protected:
36   typedef std::string string;
37 
CodeTableWriterTest()38   CodeTableWriterTest()
39       : standard_writer(false),
40         interleaved_writer(true),
41         exercise_writer(true,
42                         VCDiffAddressCache::kDefaultNearCacheSize,
43                         VCDiffAddressCache::kDefaultSameCacheSize,
44                         *g_exercise_code_table_, kLastExerciseMode),
45         output_string(&out),
46         out_index(0) { }
47 
~CodeTableWriterTest()48   virtual ~CodeTableWriterTest() { }
49 
AddExerciseOpcode(unsigned char inst1,unsigned char mode1,unsigned char size1,unsigned char inst2,unsigned char mode2,unsigned char size2,int opcode)50   static void AddExerciseOpcode(unsigned char inst1,
51                                 unsigned char mode1,
52                                 unsigned char size1,
53                                 unsigned char inst2,
54                                 unsigned char mode2,
55                                 unsigned char size2,
56                                 int opcode) {
57     g_exercise_code_table_->inst1[opcode] = inst1;
58     g_exercise_code_table_->mode1[opcode] = mode1;
59     g_exercise_code_table_->size1[opcode] = (inst1 == VCD_NOOP) ? 0 : size1;
60     g_exercise_code_table_->inst2[opcode] = inst2;
61     g_exercise_code_table_->mode2[opcode] = mode2;
62     g_exercise_code_table_->size2[opcode] = (inst2 == VCD_NOOP) ? 0 : size2;
63   }
64 
SetUpTestCase()65   static void SetUpTestCase() {
66     g_exercise_code_table_ = new VCDiffCodeTableData;
67     int opcode = 0;
68     for (unsigned char inst_mode1 = 0;
69          inst_mode1 <= VCD_LAST_INSTRUCTION_TYPE + kLastExerciseMode;
70          ++inst_mode1) {
71       unsigned char inst1 = inst_mode1;
72       unsigned char mode1 = 0;
73       if (inst_mode1 > VCD_COPY) {
74         inst1 = VCD_COPY;
75         mode1 = inst_mode1 - VCD_COPY;
76       }
77       for (unsigned char inst_mode2 = 0;
78            inst_mode2 <= VCD_LAST_INSTRUCTION_TYPE + kLastExerciseMode;
79            ++inst_mode2) {
80         unsigned char inst2 = inst_mode2;
81         unsigned char mode2 = 0;
82         if (inst_mode2 > VCD_COPY) {
83           inst2 = VCD_COPY;
84           mode2 = inst_mode2 - VCD_COPY;
85         }
86         AddExerciseOpcode(inst1, mode1, 0, inst2, mode2, 0, opcode++);
87         AddExerciseOpcode(inst1, mode1, 0, inst2, mode2, 255, opcode++);
88         AddExerciseOpcode(inst1, mode1, 255, inst2, mode2, 0, opcode++);
89         AddExerciseOpcode(inst1, mode1, 255, inst2, mode2, 255, opcode++);
90       }
91     }
92     // This is a CHECK rather than an EXPECT because it validates only
93     // the logic of the test, not of the code being tested.
94     CHECK_EQ(VCDiffCodeTableData::kCodeTableSize, opcode);
95 
96     EXPECT_TRUE(g_exercise_code_table_->Validate(kLastExerciseMode));
97   }
98 
TearDownTestCase()99   static void TearDownTestCase() {
100     delete g_exercise_code_table_;
101   }
102 
ExpectByte(unsigned char b)103   void ExpectByte(unsigned char b) {
104     EXPECT_EQ(b, static_cast<unsigned char>(out[out_index]));
105     ++out_index;
106   }
107 
ExpectString(const char * s)108   void ExpectString(const char* s) {
109     const size_t size = strlen(s);  // don't include terminating NULL char
110     EXPECT_EQ(string(s, size),
111               string(out.data() + out_index, size));
112     out_index += size;
113   }
114 
ExpectNoMoreBytes()115   void ExpectNoMoreBytes() {
116     EXPECT_EQ(out_index, out.size());
117   }
118 
AnyMatch(int match_count)119   static bool AnyMatch(int match_count) { return match_count != 0; }
120 
ExpectNoMatchesForWriter(const VCDiffCodeTableWriter & writer)121   static void ExpectNoMatchesForWriter(const VCDiffCodeTableWriter& writer) {
122     const std::vector<int>& match_counts = writer.match_counts();
123     EXPECT_TRUE(find_if(match_counts.begin(), match_counts.end(), AnyMatch)
124                     == match_counts.end());
125   }
126 
ExpectNoMatches() const127   void ExpectNoMatches() const {
128     ExpectNoMatchesForWriter(standard_writer);
129     ExpectNoMatchesForWriter(interleaved_writer);
130     ExpectNoMatchesForWriter(exercise_writer);
131   }
132 
133   // This value is designed so that the total number of inst values and modes
134   // will equal 8 (VCD_NOOP, VCD_ADD, VCD_RUN, VCD_COPY modes 0 - 4).
135   // Eight combinations of inst and mode, times two possible size values,
136   // squared (because there are two instructions per opcode), makes
137   // exactly 256 possible instruction combinations, which fits kCodeTableSize
138   // (the number of opcodes in the table.)
139   static const int kLastExerciseMode = 4;
140 
141   // A code table that exercises as many combinations as possible:
142   // 2 instructions, each is a NOOP, ADD, RUN, or one of 5 copy modes
143   // (== 8 total combinations of inst and mode), and each has
144   // size == 0 or 255 (2 possibilities.)
145   static VCDiffCodeTableData* g_exercise_code_table_;
146 
147   // The code table writer for standard encoding, default code table.
148   VCDiffCodeTableWriter standard_writer;
149 
150   // The code table writer for interleaved encoding, default code table.
151   VCDiffCodeTableWriter interleaved_writer;
152 
153   // The code table writer corresponding to g_exercise_code_table_
154   // (interleaved encoding).
155   VCDiffCodeTableWriter exercise_writer;
156 
157   // Destination for VCDiffCodeTableWriter::Output()
158   string out;
159   OutputString<string> output_string;
160   size_t out_index;
161 };
162 
163 VCDiffCodeTableData* CodeTableWriterTest::g_exercise_code_table_;
164 
165 #ifdef GTEST_HAS_DEATH_TEST
166 typedef CodeTableWriterTest CodeTableWriterDeathTest;
167 #endif  // GTEST_HAS_DEATH_TEST
168 
169 #ifdef GTEST_HAS_DEATH_TEST
TEST_F(CodeTableWriterDeathTest,WriterAddWithoutInit)170 TEST_F(CodeTableWriterDeathTest, WriterAddWithoutInit) {
171 #ifndef NDEBUG
172   // This condition is only checked in the debug build.
173   EXPECT_DEBUG_DEATH(standard_writer.Add("Hello", 5),
174                      "Init");
175 #endif  // !NDEBUG
176 }
177 
TEST_F(CodeTableWriterDeathTest,WriterRunWithoutInit)178 TEST_F(CodeTableWriterDeathTest, WriterRunWithoutInit) {
179 #ifndef NDEBUG
180   // This condition is only checked in the debug build.
181   EXPECT_DEBUG_DEATH(standard_writer.Run(3, 'a'),
182                      "Init");
183 #endif  // !NDEBUG
184 }
185 
TEST_F(CodeTableWriterDeathTest,WriterCopyWithoutInit)186 TEST_F(CodeTableWriterDeathTest, WriterCopyWithoutInit) {
187 #ifndef NDEBUG
188   // This condition is only checked in the debug build.
189   EXPECT_DEBUG_DEATH(standard_writer.Copy(6, 5),
190                      "Init");
191 #endif  // !NDEBUG
192 }
193 #endif  // GTEST_HAS_DEATH_TEST
194 
195 // Output() without Init() is harmless, but will produce no output.
TEST_F(CodeTableWriterTest,WriterOutputWithoutInit)196 TEST_F(CodeTableWriterTest, WriterOutputWithoutInit) {
197   standard_writer.Output(&output_string);
198   EXPECT_TRUE(out.empty());
199 }
200 
TEST_F(CodeTableWriterTest,WriterEncodeNothing)201 TEST_F(CodeTableWriterTest, WriterEncodeNothing) {
202   EXPECT_TRUE(standard_writer.Init(0));
203   standard_writer.Output(&output_string);
204   // The writer should know not to append a delta file window
205   // if nothing was encoded.
206   EXPECT_TRUE(out.empty());
207 
208   out.clear();
209   EXPECT_TRUE(interleaved_writer.Init(0x10));
210   interleaved_writer.Output(&output_string);
211   EXPECT_TRUE(out.empty());
212 
213   out.clear();
214   EXPECT_TRUE(exercise_writer.Init(0x20));
215   exercise_writer.Output(&output_string);
216   EXPECT_TRUE(out.empty());
217 
218   ExpectNoMatches();
219 }
220 
TEST_F(CodeTableWriterTest,StandardWriterEncodeAdd)221 TEST_F(CodeTableWriterTest, StandardWriterEncodeAdd) {
222   EXPECT_TRUE(standard_writer.Init(0x11));
223   standard_writer.Add("foo", 3);
224   standard_writer.Output(&output_string);
225   ExpectByte(VCD_SOURCE);  // Win_Indicator: VCD_SOURCE (dictionary)
226   ExpectByte(0x11);  // Source segment size: dictionary length
227   ExpectByte(0x00);  // Source segment position: start of dictionary
228   ExpectByte(0x09);  // Length of the delta encoding
229   ExpectByte(0x03);  // Size of the target window
230   ExpectByte(0x00);  // Delta_indicator (no compression)
231   ExpectByte(0x03);  // length of data for ADDs and RUNs
232   ExpectByte(0x01);  // length of instructions section
233   ExpectByte(0x00);  // length of addresses for COPYs
234   ExpectString("foo");
235   ExpectByte(0x04);  // ADD(3) opcode
236   ExpectNoMoreBytes();
237   ExpectNoMatches();
238 }
239 
TEST_F(CodeTableWriterTest,ExerciseWriterEncodeAdd)240 TEST_F(CodeTableWriterTest, ExerciseWriterEncodeAdd) {
241   EXPECT_TRUE(exercise_writer.Init(0x11));
242   exercise_writer.Add("foo", 3);
243   exercise_writer.Output(&output_string);
244   ExpectByte(VCD_SOURCE);  // Win_Indicator: VCD_SOURCE (dictionary)
245   ExpectByte(0x11);  // Source segment size: dictionary length
246   ExpectByte(0x00);  // Source segment position: start of dictionary
247   ExpectByte(0x0A);  // Length of the delta encoding
248   ExpectByte(0x03);  // Size of the target window
249   ExpectByte(0x00);  // Delta_indicator (no compression)
250   ExpectByte(0x00);  // length of data for ADDs and RUNs
251   ExpectByte(0x05);  // length of instructions section
252   ExpectByte(0x00);  // length of addresses for COPYs
253   ExpectByte(0x04);  // Opcode: NOOP + ADD(0)
254   ExpectByte(0x03);  // Size of ADD (3)
255   ExpectString("foo");
256   ExpectNoMatches();
257 }
258 
TEST_F(CodeTableWriterTest,StandardWriterEncodeRun)259 TEST_F(CodeTableWriterTest, StandardWriterEncodeRun) {
260   EXPECT_TRUE(standard_writer.Init(0x11));
261   standard_writer.Run(3, 'a');
262   standard_writer.Output(&output_string);
263   ExpectByte(VCD_SOURCE);  // Win_Indicator: VCD_SOURCE (dictionary)
264   ExpectByte(0x11);  // Source segment size: dictionary length
265   ExpectByte(0x00);  // Source segment position: start of dictionary
266   ExpectByte(0x08);  // Length of the delta encoding
267   ExpectByte(0x03);  // Size of the target window
268   ExpectByte(0x00);  // Delta_indicator (no compression)
269   ExpectByte(0x01);  // length of data for ADDs and RUNs
270   ExpectByte(0x02);  // length of instructions section
271   ExpectByte(0x00);  // length of addresses for COPYs
272   ExpectByte('a');
273   ExpectByte(0x00);  // RUN(0) opcode
274   ExpectByte(0x03);  // Size of RUN (3)
275   ExpectNoMoreBytes();
276   ExpectNoMatches();
277 }
278 
TEST_F(CodeTableWriterTest,ExerciseWriterEncodeRun)279 TEST_F(CodeTableWriterTest, ExerciseWriterEncodeRun) {
280   EXPECT_TRUE(exercise_writer.Init(0x11));
281   exercise_writer.Run(3, 'a');
282   exercise_writer.Output(&output_string);
283   ExpectByte(VCD_SOURCE);  // Win_Indicator: VCD_SOURCE (dictionary)
284   ExpectByte(0x11);  // Source segment size: dictionary length
285   ExpectByte(0x00);  // Source segment position: start of dictionary
286   ExpectByte(0x08);  // Length of the delta encoding
287   ExpectByte(0x03);  // Size of the target window
288   ExpectByte(0x00);  // Delta_indicator (no compression)
289   ExpectByte(0x00);  // length of data for ADDs and RUNs
290   ExpectByte(0x03);  // length of instructions section
291   ExpectByte(0x00);  // length of addresses for COPYs
292   ExpectByte(0x08);  // Opcode: NOOP + RUN(0)
293   ExpectByte(0x03);  // Size of RUN (3)
294   ExpectByte('a');
295   ExpectNoMoreBytes();
296   ExpectNoMatches();
297 }
298 
TEST_F(CodeTableWriterTest,StandardWriterEncodeCopy)299 TEST_F(CodeTableWriterTest, StandardWriterEncodeCopy) {
300   EXPECT_TRUE(standard_writer.Init(0x11));
301   standard_writer.Copy(2, 8);
302   standard_writer.Copy(2, 8);
303   standard_writer.Output(&output_string);
304   ExpectByte(VCD_SOURCE);  // Win_Indicator: VCD_SOURCE (dictionary)
305   ExpectByte(0x11);  // Source segment size: dictionary length
306   ExpectByte(0x00);  // Source segment position: start of dictionary
307   ExpectByte(0x09);  // Length of the delta encoding
308   ExpectByte(0x10);  // Size of the target window
309   ExpectByte(0x00);  // Delta_indicator (no compression)
310   ExpectByte(0x00);  // length of data for ADDs and RUNs
311   ExpectByte(0x02);  // length of instructions section
312   ExpectByte(0x02);  // length of addresses for COPYs
313   ExpectByte(0x18);  // COPY mode SELF, size 8
314   ExpectByte(0x78);  // COPY mode SAME(0), size 8
315   ExpectByte(0x02);  // COPY address (2)
316   ExpectByte(0x02);  // COPY address (2)
317   ExpectNoMoreBytes();
318   EXPECT_LE(9U, standard_writer.match_counts().size());
319   EXPECT_EQ(0, standard_writer.match_counts()[0]);
320   EXPECT_EQ(0, standard_writer.match_counts()[1]);
321   EXPECT_EQ(0, standard_writer.match_counts()[2]);
322   EXPECT_EQ(0, standard_writer.match_counts()[3]);
323   EXPECT_EQ(0, standard_writer.match_counts()[4]);
324   EXPECT_EQ(0, standard_writer.match_counts()[5]);
325   EXPECT_EQ(0, standard_writer.match_counts()[6]);
326   EXPECT_EQ(0, standard_writer.match_counts()[7]);
327   EXPECT_EQ(2, standard_writer.match_counts()[8]);
328 }
329 
330 // The exercise code table can't be used to test how the code table
331 // writer encodes COPY instructions because the code table writer
332 // always uses the default cache sizes, which exceed the maximum mode
333 // used in the exercise table.
TEST_F(CodeTableWriterTest,InterleavedWriterEncodeCopy)334 TEST_F(CodeTableWriterTest, InterleavedWriterEncodeCopy) {
335   EXPECT_TRUE(interleaved_writer.Init(0x11));
336   interleaved_writer.Copy(2, 8);
337   interleaved_writer.Copy(2, 8);
338   interleaved_writer.Output(&output_string);
339   ExpectByte(VCD_SOURCE);  // Win_Indicator: VCD_SOURCE (dictionary)
340   ExpectByte(0x11);  // Source segment size: dictionary length
341   ExpectByte(0x00);  // Source segment position: start of dictionary
342   ExpectByte(0x09);  // Length of the delta encoding
343   ExpectByte(0x10);  // Size of the target window
344   ExpectByte(0x00);  // Delta_indicator (no compression)
345   ExpectByte(0x00);  // length of data for ADDs and RUNs
346   ExpectByte(0x04);  // length of instructions section
347   ExpectByte(0x00);  // length of addresses for COPYs
348   ExpectByte(0x18);  // COPY mode SELF, size 8
349   ExpectByte(0x02);  // COPY address (2)
350   ExpectByte(0x78);  // COPY mode SAME(0), size 8
351   ExpectByte(0x02);  // COPY address (2)
352   ExpectNoMoreBytes();
353   EXPECT_LE(9U, interleaved_writer.match_counts().size());
354   EXPECT_EQ(0, interleaved_writer.match_counts()[0]);
355   EXPECT_EQ(0, interleaved_writer.match_counts()[1]);
356   EXPECT_EQ(0, interleaved_writer.match_counts()[2]);
357   EXPECT_EQ(0, interleaved_writer.match_counts()[3]);
358   EXPECT_EQ(0, interleaved_writer.match_counts()[4]);
359   EXPECT_EQ(0, interleaved_writer.match_counts()[5]);
360   EXPECT_EQ(0, interleaved_writer.match_counts()[6]);
361   EXPECT_EQ(0, interleaved_writer.match_counts()[7]);
362   EXPECT_EQ(2, interleaved_writer.match_counts()[8]);
363 }
364 
TEST_F(CodeTableWriterTest,StandardWriterEncodeCombo)365 TEST_F(CodeTableWriterTest, StandardWriterEncodeCombo) {
366   EXPECT_TRUE(standard_writer.Init(0x11));
367   standard_writer.Add("rayo", 4);
368   standard_writer.Copy(2, 5);
369   standard_writer.Copy(0, 4);
370   standard_writer.Add("X", 1);
371   standard_writer.Output(&output_string);
372   ExpectByte(VCD_SOURCE);  // Win_Indicator: VCD_SOURCE (dictionary)
373   ExpectByte(0x11);  // Source segment size: dictionary length
374   ExpectByte(0x00);  // Source segment position: start of dictionary
375   ExpectByte(0x0E);  // Length of the delta encoding
376   ExpectByte(0x0E);  // Size of the target window
377   ExpectByte(0x00);  // Delta_indicator (no compression)
378   ExpectByte(0x05);  // length of data for ADDs and RUNs
379   ExpectByte(0x02);  // length of instructions section
380   ExpectByte(0x02);  // length of addresses for COPYs
381   ExpectString("rayoX");
382   ExpectByte(0xAD);  // Combo: Add size 4 + COPY mode SELF, size 5
383   ExpectByte(0xFD);  // Combo: COPY mode SAME(0), size 4 + Add size 1
384   ExpectByte(0x02);  // COPY address (2)
385   ExpectByte(0x00);  // COPY address (0)
386   ExpectNoMoreBytes();
387   EXPECT_LE(6U, standard_writer.match_counts().size());
388   EXPECT_EQ(0, standard_writer.match_counts()[0]);
389   EXPECT_EQ(0, standard_writer.match_counts()[1]);
390   EXPECT_EQ(0, standard_writer.match_counts()[2]);
391   EXPECT_EQ(0, standard_writer.match_counts()[3]);
392   EXPECT_EQ(1, standard_writer.match_counts()[4]);
393   EXPECT_EQ(1, standard_writer.match_counts()[5]);
394 }
395 
TEST_F(CodeTableWriterTest,InterleavedWriterEncodeCombo)396 TEST_F(CodeTableWriterTest, InterleavedWriterEncodeCombo) {
397   EXPECT_TRUE(interleaved_writer.Init(0x11));
398   interleaved_writer.Add("rayo", 4);
399   interleaved_writer.Copy(2, 5);
400   interleaved_writer.Copy(0, 4);
401   interleaved_writer.Add("X", 1);
402   interleaved_writer.Output(&output_string);
403   ExpectByte(VCD_SOURCE);  // Win_Indicator: VCD_SOURCE (dictionary)
404   ExpectByte(0x11);  // Source segment size: dictionary length
405   ExpectByte(0x00);  // Source segment position: start of dictionary
406   ExpectByte(0x0E);  // Length of the delta encoding
407   ExpectByte(0x0E);  // Size of the target window
408   ExpectByte(0x00);  // Delta_indicator (no compression)
409   ExpectByte(0x00);  // length of data for ADDs and RUNs
410   ExpectByte(0x09);  // length of instructions section
411   ExpectByte(0x00);  // length of addresses for COPYs
412   ExpectByte(0xAD);  // Combo: Add size 4 + COPY mode SELF, size 5
413   ExpectString("rayo");
414   ExpectByte(0x02);  // COPY address (2)
415   ExpectByte(0xFD);  // Combo: COPY mode SAME(0), size 4 + Add size 1
416   ExpectByte(0x00);  // COPY address (0)
417   ExpectByte('X');
418   ExpectNoMoreBytes();
419   EXPECT_LE(6U, interleaved_writer.match_counts().size());
420   EXPECT_EQ(0, interleaved_writer.match_counts()[0]);
421   EXPECT_EQ(0, interleaved_writer.match_counts()[1]);
422   EXPECT_EQ(0, interleaved_writer.match_counts()[2]);
423   EXPECT_EQ(0, interleaved_writer.match_counts()[3]);
424   EXPECT_EQ(1, interleaved_writer.match_counts()[4]);
425   EXPECT_EQ(1, interleaved_writer.match_counts()[5]);
426 }
427 
TEST_F(CodeTableWriterTest,InterleavedWriterEncodeComboWithChecksum)428 TEST_F(CodeTableWriterTest, InterleavedWriterEncodeComboWithChecksum) {
429   EXPECT_TRUE(interleaved_writer.Init(0x11));
430   const VCDChecksum checksum = 0xFFFFFFFF;  // would be negative if signed
431   interleaved_writer.AddChecksum(checksum);
432   interleaved_writer.Add("rayo", 4);
433   interleaved_writer.Copy(2, 5);
434   interleaved_writer.Copy(0, 4);
435   interleaved_writer.Add("X", 1);
436   interleaved_writer.Output(&output_string);
437   ExpectByte(VCD_SOURCE | VCD_CHECKSUM);  // Win_Indicator
438   ExpectByte(0x11);  // Source segment size: dictionary length
439   ExpectByte(0x00);  // Source segment position: start of dictionary
440   ExpectByte(0x13);  // Length of the delta encoding
441   ExpectByte(0x0E);  // Size of the target window
442   ExpectByte(0x00);  // Delta_indicator (no compression)
443   ExpectByte(0x00);  // length of data for ADDs and RUNs
444   ExpectByte(0x09);  // length of instructions section
445   ExpectByte(0x00);  // length of addresses for COPYs
446   ExpectByte(0x8F);  // checksum byte 1
447   ExpectByte(0xFF);  // checksum byte 2
448   ExpectByte(0xFF);  // checksum byte 3
449   ExpectByte(0xFF);  // checksum byte 4
450   ExpectByte(0x7F);  // checksum byte 5
451   ExpectByte(0xAD);  // Combo: Add size 4 + COPY mode SELF, size 5
452   ExpectString("rayo");
453   ExpectByte(0x02);  // COPY address (2)
454   ExpectByte(0xFD);  // Combo: COPY mode SAME(0), size 4 + Add size 1
455   ExpectByte(0x00);  // COPY address (0)
456   ExpectByte('X');
457   ExpectNoMoreBytes();
458 }
459 
TEST_F(CodeTableWriterTest,ReallyBigDictionary)460 TEST_F(CodeTableWriterTest, ReallyBigDictionary) {
461   EXPECT_TRUE(interleaved_writer.Init(0x3FFFFFFF));
462   interleaved_writer.Copy(2, 8);
463   interleaved_writer.Copy(0x3FFFFFFE, 8);
464   interleaved_writer.Output(&output_string);
465   ExpectByte(VCD_SOURCE);  // Win_Indicator: VCD_SOURCE (dictionary)
466   ExpectByte(0x83);  // Source segment size: dictionary length (1)
467   ExpectByte(0xFF);  // Source segment size: dictionary length (2)
468   ExpectByte(0xFF);  // Source segment size: dictionary length (3)
469   ExpectByte(0xFF);  // Source segment size: dictionary length (4)
470   ExpectByte(0x7F);  // Source segment size: dictionary length (5)
471   ExpectByte(0x00);  // Source segment position: start of dictionary
472   ExpectByte(0x09);  // Length of the delta encoding
473   ExpectByte(0x10);  // Size of the target window
474   ExpectByte(0x00);  // Delta_indicator (no compression)
475   ExpectByte(0x00);  // length of data for ADDs and RUNs
476   ExpectByte(0x04);  // length of instructions section
477   ExpectByte(0x00);  // length of addresses for COPYs
478   ExpectByte(0x18);  // COPY mode SELF, size 8
479   ExpectByte(0x02);  // COPY address (2)
480   ExpectByte(0x28);  // COPY mode HERE, size 8
481   ExpectByte(0x09);  // COPY address (9)
482   ExpectNoMoreBytes();
483   EXPECT_LE(9U, interleaved_writer.match_counts().size());
484   EXPECT_EQ(0, interleaved_writer.match_counts()[0]);
485   EXPECT_EQ(0, interleaved_writer.match_counts()[1]);
486   EXPECT_EQ(0, interleaved_writer.match_counts()[2]);
487   EXPECT_EQ(0, interleaved_writer.match_counts()[3]);
488   EXPECT_EQ(0, interleaved_writer.match_counts()[4]);
489   EXPECT_EQ(0, interleaved_writer.match_counts()[5]);
490   EXPECT_EQ(0, interleaved_writer.match_counts()[6]);
491   EXPECT_EQ(0, interleaved_writer.match_counts()[7]);
492   EXPECT_EQ(2, interleaved_writer.match_counts()[8]);
493 }
494 
495 #ifdef GTEST_HAS_DEATH_TEST
TEST_F(CodeTableWriterDeathTest,DictionaryTooBig)496 TEST_F(CodeTableWriterDeathTest, DictionaryTooBig) {
497   EXPECT_TRUE(interleaved_writer.Init(0x7FFFFFFF));
498   interleaved_writer.Copy(2, 8);
499   EXPECT_DEBUG_DEATH(interleaved_writer.Copy(0x7FFFFFFE, 8),
500                      "address.*<.*here_address");
501 }
502 #endif  // GTEST_HAS_DEATH_TEST
503 
504 }  // unnamed namespace
505 }  // namespace open_vcdiff
506