1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include <string> 6 7 #include "base/strings/string_util.h" 8 9 #include "courgette/assembly_program.h" 10 #include "courgette/courgette.h" 11 #include "courgette/streams.h" 12 13 #include "testing/gtest/include/gtest/gtest.h" 14 15 class AdjustmentMethodTest : public testing::Test { 16 public: 17 void Test1() const; 18 19 private: 20 void SetUp() { 21 } 22 23 void TearDown() { 24 } 25 26 // Returns one of two similar a simple programs. They differ only in the 27 // label assignment, so that it is possible to make them look identical. 28 courgette::AssemblyProgram* MakeProgram(int kind) const { 29 courgette::AssemblyProgram* prog = 30 new courgette::AssemblyProgram(courgette::EXE_WIN_32_X86); 31 prog->set_image_base(0x00400000); 32 33 courgette::Label* labelA = prog->FindOrMakeAbs32Label(0x00410000); 34 courgette::Label* labelB = prog->FindOrMakeAbs32Label(0x00410004); 35 36 EXPECT_TRUE(prog->EmitAbs32(labelA)); 37 EXPECT_TRUE(prog->EmitAbs32(labelA)); 38 EXPECT_TRUE(prog->EmitAbs32(labelB)); 39 EXPECT_TRUE(prog->EmitAbs32(labelA)); 40 EXPECT_TRUE(prog->EmitAbs32(labelA)); 41 EXPECT_TRUE(prog->EmitAbs32(labelB)); 42 43 if (kind == 0) { 44 labelA->index_ = 0; 45 labelB->index_ = 1; 46 } else { 47 labelA->index_ = 1; 48 labelB->index_ = 0; 49 } 50 prog->AssignRemainingIndexes(); 51 52 return prog; 53 } 54 55 courgette::AssemblyProgram* MakeProgramA() const { return MakeProgram(0); } 56 courgette::AssemblyProgram* MakeProgramB() const { return MakeProgram(1); } 57 58 // Returns a string that is the serialized version of |program|. 59 // Deletes |program|. 60 std::string Serialize(courgette::AssemblyProgram *program) const { 61 courgette::EncodedProgram* encoded = NULL; 62 63 const courgette::Status encode_status = Encode(program, &encoded); 64 EXPECT_EQ(courgette::C_OK, encode_status); 65 66 DeleteAssemblyProgram(program); 67 68 courgette::SinkStreamSet sinks; 69 const courgette::Status write_status = WriteEncodedProgram(encoded, &sinks); 70 EXPECT_EQ(courgette::C_OK, write_status); 71 72 DeleteEncodedProgram(encoded); 73 74 courgette::SinkStream sink; 75 bool can_collect = sinks.CopyTo(&sink); 76 EXPECT_TRUE(can_collect); 77 78 return std::string(reinterpret_cast<const char *>(sink.Buffer()), 79 sink.Length()); 80 } 81 }; 82 83 84 void AdjustmentMethodTest::Test1() const { 85 courgette::AssemblyProgram* prog1 = MakeProgramA(); 86 courgette::AssemblyProgram* prog2 = MakeProgramB(); 87 std::string s1 = Serialize(prog1); 88 std::string s2 = Serialize(prog2); 89 90 // Don't use EXPECT_EQ because strings are unprintable. 91 EXPECT_FALSE(s1 == s2); // Unadjusted A and B differ. 92 93 courgette::AssemblyProgram* prog5 = MakeProgramA(); 94 courgette::AssemblyProgram* prog6 = MakeProgramB(); 95 courgette::Status can_adjust = Adjust(*prog5, prog6); 96 EXPECT_EQ(courgette::C_OK, can_adjust); 97 std::string s5 = Serialize(prog5); 98 std::string s6 = Serialize(prog6); 99 100 EXPECT_TRUE(s1 == s5); // Adjustment did not change A (prog5) 101 EXPECT_TRUE(s5 == s6); // Adjustment did change B into A 102 } 103 104 105 TEST_F(AdjustmentMethodTest, All) { 106 Test1(); 107 } 108