Home | History | Annotate | Download | only in courgette
      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