Home | History | Annotate | Download | only in base
      1 /*
      2  * Copyright (C) 2018 The Android Open Source Project
      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 
     17 #ifndef ART_LIBARTBASE_BASE_COMMON_ART_TEST_H_
     18 #define ART_LIBARTBASE_BASE_COMMON_ART_TEST_H_
     19 
     20 #include <gtest/gtest.h>
     21 
     22 #include <functional>
     23 #include <string>
     24 
     25 #include <sys/wait.h>
     26 
     27 #include <android-base/logging.h>
     28 
     29 #include "base/globals.h"
     30 #include "base/mutex.h"
     31 #include "base/os.h"
     32 #include "base/unix_file/fd_file.h"
     33 #include "dex/art_dex_file_loader.h"
     34 #include "dex/compact_dex_level.h"
     35 #include "obj_ptr-inl.h"
     36 
     37 namespace art {
     38 
     39 using LogSeverity = android::base::LogSeverity;
     40 using ScopedLogSeverity = android::base::ScopedLogSeverity;
     41 
     42 template<class MirrorType>
     43 static inline ObjPtr<MirrorType> MakeObjPtr(MirrorType* ptr) {
     44   return ptr;
     45 }
     46 
     47 template<class MirrorType>
     48 static inline ObjPtr<MirrorType> MakeObjPtr(ObjPtr<MirrorType> ptr) {
     49   return ptr;
     50 }
     51 
     52 // OBJ pointer helpers to avoid needing .Decode everywhere.
     53 #define EXPECT_OBJ_PTR_EQ(a, b) EXPECT_EQ(MakeObjPtr(a).Ptr(), MakeObjPtr(b).Ptr())
     54 #define ASSERT_OBJ_PTR_EQ(a, b) ASSERT_EQ(MakeObjPtr(a).Ptr(), MakeObjPtr(b).Ptr())
     55 #define EXPECT_OBJ_PTR_NE(a, b) EXPECT_NE(MakeObjPtr(a).Ptr(), MakeObjPtr(b).Ptr())
     56 #define ASSERT_OBJ_PTR_NE(a, b) ASSERT_NE(MakeObjPtr(a).Ptr(), MakeObjPtr(b).Ptr())
     57 
     58 class DexFile;
     59 
     60 class ScratchFile {
     61  public:
     62   ScratchFile();
     63 
     64   explicit ScratchFile(const std::string& filename);
     65 
     66   ScratchFile(const ScratchFile& other, const char* suffix);
     67 
     68   ScratchFile(ScratchFile&& other) noexcept;
     69 
     70   ScratchFile& operator=(ScratchFile&& other) noexcept;
     71 
     72   explicit ScratchFile(File* file);
     73 
     74   ~ScratchFile();
     75 
     76   const std::string& GetFilename() const {
     77     return filename_;
     78   }
     79 
     80   File* GetFile() const {
     81     return file_.get();
     82   }
     83 
     84   int GetFd() const;
     85 
     86   void Close();
     87   void Unlink();
     88 
     89  private:
     90   std::string filename_;
     91   std::unique_ptr<File> file_;
     92 };
     93 
     94 class CommonArtTestImpl {
     95  public:
     96   CommonArtTestImpl() = default;
     97   virtual ~CommonArtTestImpl() = default;
     98 
     99   // Set up ANDROID_BUILD_TOP, ANDROID_HOST_OUT, ANDROID_ROOT, ANDROID_RUNTIME_ROOT,
    100   // and ANDROID_TZDATA_ROOT environment variables using sensible defaults if not already set.
    101   static void SetUpAndroidRootEnvVars();
    102 
    103   // Set up the ANDROID_DATA environment variable, creating the directory if required.
    104   // Note: setting up ANDROID_DATA may create a temporary directory. If this is used in a
    105   // non-derived class, be sure to also call the corresponding tear-down below.
    106   static void SetUpAndroidDataDir(std::string& android_data);
    107 
    108   static void TearDownAndroidDataDir(const std::string& android_data, bool fail_on_error);
    109 
    110   // Get the names of the libcore modules.
    111   virtual std::vector<std::string> GetLibCoreModuleNames() const;
    112 
    113   // Gets the paths of the libcore dex files for given modules.
    114   std::vector<std::string> GetLibCoreDexFileNames(const std::vector<std::string>& modules) const;
    115 
    116   // Gets the paths of the libcore dex files.
    117   std::vector<std::string> GetLibCoreDexFileNames() const;
    118 
    119   // Gets the locations of the libcore dex files for given modules.
    120   std::vector<std::string> GetLibCoreDexLocations(const std::vector<std::string>& modules) const;
    121 
    122   // Gets the locations of the libcore dex files.
    123   std::vector<std::string> GetLibCoreDexLocations() const;
    124 
    125   static std::string GetClassPathOption(const char* option,
    126                                         const std::vector<std::string>& class_path);
    127 
    128   // Returns bin directory which contains host's prebuild tools.
    129   static std::string GetAndroidHostToolsDir();
    130 
    131   // Retuerns the filename for a test dex (i.e. XandY or ManyMethods).
    132   std::string GetTestDexFileName(const char* name) const;
    133 
    134   template <typename Mutator>
    135   bool MutateDexFile(File* output_dex, const std::string& input_jar, const Mutator& mutator) {
    136     std::vector<std::unique_ptr<const DexFile>> dex_files;
    137     std::string error_msg;
    138     const ArtDexFileLoader dex_file_loader;
    139     CHECK(dex_file_loader.Open(input_jar.c_str(),
    140                                input_jar.c_str(),
    141                                /*verify*/ true,
    142                                /*verify_checksum*/ true,
    143                                &error_msg,
    144                                &dex_files)) << error_msg;
    145     EXPECT_EQ(dex_files.size(), 1u) << "Only one input dex is supported";
    146     const std::unique_ptr<const DexFile>& dex = dex_files[0];
    147     CHECK(dex->EnableWrite()) << "Failed to enable write";
    148     DexFile* dex_file = const_cast<DexFile*>(dex.get());
    149     mutator(dex_file);
    150     const_cast<DexFile::Header&>(dex_file->GetHeader()).checksum_ = dex_file->CalculateChecksum();
    151     if (!output_dex->WriteFully(dex->Begin(), dex->Size())) {
    152       return false;
    153     }
    154     if (output_dex->Flush() != 0) {
    155       PLOG(FATAL) << "Could not flush the output file.";
    156     }
    157     return true;
    158   }
    159 
    160   struct ForkAndExecResult {
    161     enum Stage {
    162       kLink,
    163       kFork,
    164       kWaitpid,
    165       kFinished,
    166     };
    167     Stage stage;
    168     int status_code;
    169 
    170     bool StandardSuccess() {
    171       return stage == kFinished && WIFEXITED(status_code) && WEXITSTATUS(status_code) == 0;
    172     }
    173   };
    174   using OutputHandlerFn = std::function<void(char*, size_t)>;
    175   using PostForkFn = std::function<bool()>;
    176   static ForkAndExecResult ForkAndExec(const std::vector<std::string>& argv,
    177                                        const PostForkFn& post_fork,
    178                                        const OutputHandlerFn& handler);
    179   static ForkAndExecResult ForkAndExec(const std::vector<std::string>& argv,
    180                                        const PostForkFn& post_fork,
    181                                        std::string* output);
    182 
    183  protected:
    184   static bool IsHost() {
    185     return !kIsTargetBuild;
    186   }
    187 
    188   // Helper - find directory with the following format:
    189   // ${ANDROID_BUILD_TOP}/${subdir1}/${subdir2}-${version}/${subdir3}/bin/
    190   static std::string GetAndroidToolsDir(const std::string& subdir1,
    191                                         const std::string& subdir2,
    192                                         const std::string& subdir3);
    193 
    194   // File location to core.art, e.g. $ANDROID_HOST_OUT/system/framework/core.art
    195   static std::string GetCoreArtLocation();
    196 
    197   // File location to core.oat, e.g. $ANDROID_HOST_OUT/system/framework/core.oat
    198   static std::string GetCoreOatLocation();
    199 
    200   std::unique_ptr<const DexFile> LoadExpectSingleDexFile(const char* location);
    201 
    202   void ClearDirectory(const char* dirpath, bool recursive = true);
    203 
    204   std::string GetTestAndroidRoot();
    205 
    206   // Open a file (allows reading of framework jars).
    207   std::vector<std::unique_ptr<const DexFile>> OpenDexFiles(const char* filename);
    208 
    209   // Open a single dex file (aborts if there are more than one).
    210   std::unique_ptr<const DexFile> OpenDexFile(const char* filename);
    211 
    212   // Open a test file (art-gtest-*.jar).
    213   std::vector<std::unique_ptr<const DexFile>> OpenTestDexFiles(const char* name);
    214 
    215   std::unique_ptr<const DexFile> OpenTestDexFile(const char* name);
    216 
    217 
    218   std::string android_data_;
    219   std::string dalvik_cache_;
    220 
    221   virtual void SetUp();
    222 
    223   virtual void TearDown();
    224 
    225   // Creates the class path string for the given dex files (the list of dex file locations
    226   // separated by ':').
    227   std::string CreateClassPath(const std::vector<std::unique_ptr<const DexFile>>& dex_files);
    228   // Same as CreateClassPath but add the dex file checksum after each location. The separator
    229   // is '*'.
    230   std::string CreateClassPathWithChecksums(
    231       const std::vector<std::unique_ptr<const DexFile>>& dex_files);
    232 
    233   static std::string GetCoreFileLocation(const char* suffix);
    234 
    235   std::vector<std::unique_ptr<const DexFile>> loaded_dex_files_;
    236 };
    237 
    238 template <typename TestType>
    239 class CommonArtTestBase : public TestType, public CommonArtTestImpl {
    240  public:
    241   CommonArtTestBase() {}
    242   virtual ~CommonArtTestBase() {}
    243 
    244  protected:
    245   void SetUp() override {
    246     CommonArtTestImpl::SetUp();
    247   }
    248 
    249   void TearDown() override {
    250     CommonArtTestImpl::TearDown();
    251   }
    252 };
    253 
    254 using CommonArtTest = CommonArtTestBase<testing::Test>;
    255 
    256 template <typename Param>
    257 using CommonArtTestWithParam = CommonArtTestBase<testing::TestWithParam<Param>>;
    258 
    259 #define TEST_DISABLED_FOR_TARGET() \
    260   if (kIsTargetBuild) { \
    261     printf("WARNING: TEST DISABLED FOR TARGET\n"); \
    262     return; \
    263   }
    264 
    265 #define TEST_DISABLED_FOR_NON_STATIC_HOST_BUILDS() \
    266   if (!kHostStaticBuildEnabled) { \
    267     printf("WARNING: TEST DISABLED FOR NON-STATIC HOST BUILDS\n"); \
    268     return; \
    269   }
    270 
    271 #define TEST_DISABLED_FOR_MEMORY_TOOL() \
    272   if (kRunningOnMemoryTool) { \
    273     printf("WARNING: TEST DISABLED FOR MEMORY TOOL\n"); \
    274     return; \
    275   }
    276 
    277 #define TEST_DISABLED_FOR_HEAP_POISONING() \
    278   if (kPoisonHeapReferences) { \
    279     printf("WARNING: TEST DISABLED FOR HEAP POISONING\n"); \
    280     return; \
    281   }
    282 }  // namespace art
    283 
    284 #define TEST_DISABLED_FOR_MEMORY_TOOL_WITH_HEAP_POISONING() \
    285   if (kRunningOnMemoryTool && kPoisonHeapReferences) { \
    286     printf("WARNING: TEST DISABLED FOR MEMORY TOOL WITH HEAP POISONING\n"); \
    287     return; \
    288   }
    289 
    290 #endif  // ART_LIBARTBASE_BASE_COMMON_ART_TEST_H_
    291