10a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath// Copyright 2008 Google Inc.
20a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath// Author: Lincoln Smith
30a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath//
40a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath// Licensed under the Apache License, Version 2.0 (the "License");
50a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath// you may not use this file except in compliance with the License.
60a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath// You may obtain a copy of the License at
70a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath//
80a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath//      http://www.apache.org/licenses/LICENSE-2.0
90a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath//
100a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath// Unless required by applicable law or agreed to in writing, software
110a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath// distributed under the License is distributed on an "AS IS" BASIS,
120a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
130a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath// See the License for the specific language governing permissions and
140a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath// limitations under the License.
150a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath//
160a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath// Unit tests for struct VCDiffCodeTableData, found in codetable.h.
170a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath
180a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath#include <config.h>
190a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath#include "codetable.h"
200a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath#include "addrcache.h"
210a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath#include "testing.h"
220a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath
230a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamathnamespace open_vcdiff {
240a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamathnamespace {
250a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath
260a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamathclass CodeTableTest : public testing::Test {
270a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath protected:
280a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath  CodeTableTest()
290a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath  : code_table_data_(VCDiffCodeTableData::kDefaultCodeTableData) { }
300a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath
310a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath  virtual ~CodeTableTest() { }
320a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath
330a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath  virtual void SetUp() {
340a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath    // Default code table must pass
350a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath    EXPECT_TRUE(ValidateCodeTable());
360a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath  }
370a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath
380a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath  static void AddExerciseOpcode(unsigned char inst1,
390a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath                                unsigned char mode1,
400a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath                                unsigned char size1,
410a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath                                unsigned char inst2,
420a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath                                unsigned char mode2,
430a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath                                unsigned char size2,
440a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath                                int opcode) {
450a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath    g_exercise_code_table_->inst1[opcode] = inst1;
460a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath    g_exercise_code_table_->mode1[opcode] = mode1;
470a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath    g_exercise_code_table_->size1[opcode] = (inst1 == VCD_NOOP) ? 0 : size1;
480a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath    g_exercise_code_table_->inst2[opcode] = inst2;
490a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath    g_exercise_code_table_->mode2[opcode] = mode2;
500a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath    g_exercise_code_table_->size2[opcode] = (inst2 == VCD_NOOP) ? 0 : size2;
510a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath  }
520a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath
530a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath  static void SetUpTestCase() {
540a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath    g_exercise_code_table_ = new VCDiffCodeTableData;
550a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath    int opcode = 0;
560a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath    for (unsigned char inst_mode1 = 0;
570a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath         inst_mode1 <= VCD_LAST_INSTRUCTION_TYPE + kLastExerciseMode;
580a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath         ++inst_mode1) {
590a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath      unsigned char inst1 = inst_mode1;
600a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath      unsigned char mode1 = 0;
610a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath      if (inst_mode1 > VCD_COPY) {
620a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath        inst1 = VCD_COPY;
630a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath        mode1 = inst_mode1 - VCD_COPY;
640a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath      }
650a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath      for (unsigned char inst_mode2 = 0;
660a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath           inst_mode2 <= VCD_LAST_INSTRUCTION_TYPE + kLastExerciseMode;
670a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath           ++inst_mode2) {
680a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath        unsigned char inst2 = inst_mode2;
690a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath        unsigned char mode2 = 0;
700a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath        if (inst_mode2 > VCD_COPY) {
710a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath          inst2 = VCD_COPY;
720a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath          mode2 = inst_mode2 - VCD_COPY;
730a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath        }
740a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath        AddExerciseOpcode(inst1, mode1, 0, inst2, mode2, 0, opcode++);
750a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath        AddExerciseOpcode(inst1, mode1, 0, inst2, mode2, 255, opcode++);
760a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath        AddExerciseOpcode(inst1, mode1, 255, inst2, mode2, 0, opcode++);
770a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath        AddExerciseOpcode(inst1, mode1, 255, inst2, mode2, 255, opcode++);
780a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath      }
790a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath    }
800a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath    // This is a CHECK rather than an EXPECT because it validates only
810a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath    // the logic of the test, not of the code being tested.
820a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath    CHECK_EQ(VCDiffCodeTableData::kCodeTableSize, opcode);
830a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath
840a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath    EXPECT_TRUE(VCDiffCodeTableData::kDefaultCodeTableData.Validate());
850a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath    EXPECT_TRUE(g_exercise_code_table_->Validate(kLastExerciseMode));
860a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath  }
870a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath
880a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath  static void TearDownTestCase() {
890a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath    delete g_exercise_code_table_;
900a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath  }
910a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath
920a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath  void VerifyInstruction(unsigned char opcode,
930a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath                         unsigned char inst,
940a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath                         unsigned char size,
950a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath                         unsigned char mode) {
960a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath    EXPECT_EQ(inst, code_table_data_.inst1[opcode]);
970a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath    EXPECT_EQ(size, code_table_data_.size1[opcode]);
980a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath    EXPECT_EQ(mode, code_table_data_.mode1[opcode]);
990a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath    EXPECT_EQ(VCD_NOOP, code_table_data_.inst2[opcode]);
1000a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath    EXPECT_EQ(0, code_table_data_.size2[opcode]);
1010a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath    EXPECT_EQ(0, code_table_data_.mode2[opcode]);
1020a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath  }
1030a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath
1040a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath  bool ValidateCodeTable() {
1050a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath    return code_table_data_.Validate();
1060a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath  }
1070a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath
1080a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath  // This value is designed so that the total number of inst values and modes
1090a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath  // will equal 8 (VCD_NOOP, VCD_ADD, VCD_RUN, VCD_COPY modes 0 - 4).
1100a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath  // Eight combinations of inst and mode, times two possible size values,
1110a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath  // squared (because there are two instructions per opcode), makes
1120a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath  // exactly 256 possible instruction combinations, which fits kCodeTableSize
1130a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath  // (the number of opcodes in the table.)
1140a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath  static const int kLastExerciseMode = 4;
1150a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath
1160a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath  // A code table that exercises as many combinations as possible:
1170a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath  // 2 instructions, each is a NOOP, ADD, RUN, or one of 5 copy modes
1180a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath  // (== 8 total combinations of inst and mode), and each has
1190a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath  // size == 0 or 255 (2 possibilities.)
1200a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath  static VCDiffCodeTableData* g_exercise_code_table_;
1210a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath
1220a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath  // The code table used by the current test.
1230a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath  VCDiffCodeTableData code_table_data_;
1240a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath};
1250a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath
1260a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan KamathVCDiffCodeTableData* CodeTableTest::g_exercise_code_table_ = NULL;
1270a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath
1280a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath// These tests make sure that ValidateCodeTable() catches particular
1290a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath// error conditions in a custom code table.
1300a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath
1310a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath// All possible combinations of inst and mode should have an opcode with size 0.
1320a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan KamathTEST_F(CodeTableTest, MissingCopyMode) {
1330a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath  VerifyInstruction(/* opcode */ 131, VCD_COPY, /* size */ 0, /* mode */ 7);
1340a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath  code_table_data_.size1[131] = 0xFF;
1350a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath  // Now there is no opcode expressing COPY with mode 7 and size 0.
1360a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath  EXPECT_FALSE(ValidateCodeTable());
1370a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath}
1380a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath
1390a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan KamathTEST_F(CodeTableTest, MissingAdd) {
1400a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath  VerifyInstruction(/* opcode */ 1, VCD_ADD, /* size */ 0, /* mode */ 0);
1410a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath  code_table_data_.size1[1] = 0xFF;  // Add size 0 => size 255
1420a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath  // Now there is no opcode expressing ADD with size 0.
1430a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath  EXPECT_FALSE(ValidateCodeTable());
1440a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath}
1450a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath
1460a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan KamathTEST_F(CodeTableTest, MissingRun) {
1470a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath  VerifyInstruction(/* opcode */ 0, VCD_RUN, /* size */ 0, /* mode */ 0);
1480a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath  code_table_data_.size1[0] = 0xFF;  // Run size 0 => size 255
1490a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath  // Now there is no opcode expressing RUN with size 0.
1500a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath  EXPECT_FALSE(ValidateCodeTable());
1510a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath}
1520a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath
1530a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan KamathTEST_F(CodeTableTest, BadOpcode) {
1540a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath  VerifyInstruction(/* opcode */ 0, VCD_RUN, /* size */ 0, /* mode */ 0);
1550a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath  code_table_data_.inst1[0] = VCD_LAST_INSTRUCTION_TYPE + 1;
1560a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath  EXPECT_FALSE(ValidateCodeTable());
1570a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath  code_table_data_.inst1[0] = 0xFF;
1580a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath  EXPECT_FALSE(ValidateCodeTable());
1590a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath}
1600a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath
1610a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan KamathTEST_F(CodeTableTest, BadMode) {
1620a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath  VerifyInstruction(/* opcode */ 131, VCD_COPY, /* size */ 0, /* mode */ 7);
1630a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath  code_table_data_.mode1[131] = VCDiffAddressCache::DefaultLastMode() + 1;
1640a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath  EXPECT_FALSE(ValidateCodeTable());
1650a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath  code_table_data_.mode1[131] = 0xFF;
1660a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath  EXPECT_FALSE(ValidateCodeTable());
1670a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath}
1680a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath
1690a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan KamathTEST_F(CodeTableTest, AddWithNonzeroMode) {
1700a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath  VerifyInstruction(/* opcode */ 1, VCD_ADD, /* size */ 0, /* mode */ 0);
1710a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath  code_table_data_.mode1[1] = 1;
1720a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath  EXPECT_FALSE(ValidateCodeTable());
1730a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath}
1740a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath
1750a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan KamathTEST_F(CodeTableTest, RunWithNonzeroMode) {
1760a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath  VerifyInstruction(/* opcode */ 0, VCD_RUN, /* size */ 0, /* mode */ 0);
1770a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath  code_table_data_.mode1[0] = 1;
1780a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath  EXPECT_FALSE(ValidateCodeTable());
1790a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath}
1800a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath
1810a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan KamathTEST_F(CodeTableTest, NoOpWithNonzeroMode) {
1820a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath  VerifyInstruction(/* opcode */ 20, VCD_COPY, /* size */ 4, /* mode */ 0);
1830a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath  code_table_data_.inst1[20] = VCD_NOOP;
1840a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath  code_table_data_.mode1[20] = 0;
1850a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath  code_table_data_.size1[20] = 0;
1860a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath  EXPECT_TRUE(ValidateCodeTable());
1870a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath  code_table_data_.mode1[20] = 1;
1880a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath  EXPECT_FALSE(ValidateCodeTable());
1890a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath}
1900a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath
1910a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan KamathTEST_F(CodeTableTest, NoOpWithNonzeroSize) {
1920a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath  VerifyInstruction(/* opcode */ 20, VCD_COPY, /* size */ 4, /* mode */ 0);
1930a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath  code_table_data_.inst1[20] = VCD_NOOP;
1940a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath  code_table_data_.mode1[20] = 0;
1950a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath  code_table_data_.size1[20] = 0;
1960a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath  EXPECT_TRUE(ValidateCodeTable());
1970a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath  code_table_data_.size1[20] = 1;
1980a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath  EXPECT_FALSE(ValidateCodeTable());
1990a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath}
2000a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath
2010a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan KamathTEST_F(CodeTableTest, BadSecondOpcode) {
2020a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath  VerifyInstruction(/* opcode */ 20, VCD_COPY, /* size */ 4, /* mode */ 0);
2030a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath  code_table_data_.inst2[20] = VCD_LAST_INSTRUCTION_TYPE + 1;
2040a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath  EXPECT_FALSE(ValidateCodeTable());
2050a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath  code_table_data_.inst2[20] = 0xFF;
2060a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath  EXPECT_FALSE(ValidateCodeTable());
2070a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath}
2080a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath
2090a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan KamathTEST_F(CodeTableTest, BadSecondMode) {
2100a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath  VerifyInstruction(/* opcode */ 20, VCD_COPY, /* size */ 4, /* mode */ 0);
2110a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath  code_table_data_.inst2[20] = VCD_COPY;
2120a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath  EXPECT_TRUE(ValidateCodeTable());
2130a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath  code_table_data_.mode2[20] = VCDiffAddressCache::DefaultLastMode() + 1;
2140a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath  EXPECT_FALSE(ValidateCodeTable());
2150a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath  code_table_data_.mode2[20] = 0xFF;
2160a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath  EXPECT_FALSE(ValidateCodeTable());
2170a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath}
2180a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath
2190a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan KamathTEST_F(CodeTableTest, AddSecondWithNonzeroMode) {
2200a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath  VerifyInstruction(/* opcode */ 20, VCD_COPY, /* size */ 4, /* mode */ 0);
2210a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath  code_table_data_.inst2[20] = VCD_ADD;
2220a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath  EXPECT_TRUE(ValidateCodeTable());
2230a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath  code_table_data_.mode2[20] = 1;
2240a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath  EXPECT_FALSE(ValidateCodeTable());
2250a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath}
2260a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath
2270a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan KamathTEST_F(CodeTableTest, RunSecondWithNonzeroMode) {
2280a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath  VerifyInstruction(/* opcode */ 20, VCD_COPY, /* size */ 4, /* mode */ 0);
2290a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath  code_table_data_.inst2[20] = VCD_RUN;
2300a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath  EXPECT_TRUE(ValidateCodeTable());
2310a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath  code_table_data_.mode2[20] = 1;
2320a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath  EXPECT_FALSE(ValidateCodeTable());
2330a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath}
2340a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath
2350a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan KamathTEST_F(CodeTableTest, SecondNoOpWithNonzeroMode) {
2360a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath  VerifyInstruction(/* opcode */ 20, VCD_COPY, /* size */ 4, /* mode */ 0);
2370a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath  EXPECT_EQ(VCD_NOOP, code_table_data_.inst2[20]);
2380a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath  code_table_data_.mode2[20] = 1;
2390a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath  EXPECT_FALSE(ValidateCodeTable());
2400a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath}
2410a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath
2420a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan KamathTEST_F(CodeTableTest, SecondNoOpWithNonzeroSize) {
2430a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath  VerifyInstruction(/* opcode */ 20, VCD_COPY, /* size */ 4, /* mode */ 0);
2440a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath  EXPECT_EQ(VCD_NOOP, code_table_data_.inst2[20]);
2450a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath  code_table_data_.size2[20] = 1;
2460a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath  EXPECT_FALSE(ValidateCodeTable());
2470a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath}
2480a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath
2490a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan KamathTEST_F(CodeTableTest, ValidateExerciseCodeTable) {
2500a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath  EXPECT_TRUE(g_exercise_code_table_->Validate(kLastExerciseMode));
2510a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath}
2520a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath
2530a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath}  // unnamed namespace
2540a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath}  // namespace open_vcdiff
255