/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "class_loader_context.h"

#include <gtest/gtest.h>

#include <filesystem>
#include <fstream>
#include <optional>
#include <vector>

#include "android-base/stringprintf.h"
#include "android-base/strings.h"
#include "art_field-inl.h"
#include "art_method-alloc-inl.h"
#include "base/dchecked_vector.h"
#include "base/stl_util.h"
#include "base/string_view_cpp20.h"
#include "class_linker.h"
#include "class_root-inl.h"
#include "common_runtime_test.h"
#include "dex/dex_file.h"
#include "handle_scope-inl.h"
#include "jni/jni_internal.h"
#include "mirror/class.h"
#include "mirror/class_loader-inl.h"
#include "mirror/object-inl.h"
#include "mirror/object_array-alloc-inl.h"
#include "oat/oat_file_assistant.h"
#include "runtime.h"
#include "scoped_thread_state_change-inl.h"
#include "thread.h"
#include "well_known_classes-inl.h"

namespace art HIDDEN {

class ClassLoaderContextTest : public CommonRuntimeTest {
 public:
  ClassLoaderContextTest() {
    use_boot_image_ = true;  // Make the Runtime creation cheaper.
  }

  void SetUp() override {
    CommonRuntimeTest::SetUp();
    scratch_dir_ = std::make_unique<ScratchDir>();
    scratch_path_ = scratch_dir_->GetPath();
    // Remove the trailing '/';
    scratch_path_.resize(scratch_path_.length() - 1);
  }

  void TearDown() override {
    scratch_dir_.reset();
    CommonRuntimeTest::TearDown();
  }

  void VerifyContextSize(ClassLoaderContext* context, size_t expected_size) {
    ASSERT_TRUE(context != nullptr);
    ASSERT_EQ(expected_size, context->GetParentChainSize());
  }

  void VerifyClassLoaderPCL(ClassLoaderContext* context,
                            size_t index,
                            const std::string& classpath) {
    VerifyClassLoaderInfo(
        context, index, ClassLoaderContext::kPathClassLoader, classpath);
  }

  void VerifyClassLoaderDLC(ClassLoaderContext* context,
                            size_t index,
                            const std::string& classpath) {
    VerifyClassLoaderInfo(
        context, index, ClassLoaderContext::kDelegateLastClassLoader, classpath);
  }

  void VerifyClassLoaderIMC(ClassLoaderContext* context,
                            size_t index,
                            const std::string& classpath) {
    VerifyClassLoaderInfo(
        context, index, ClassLoaderContext::kInMemoryDexClassLoader, classpath);
  }

  void VerifyClassLoaderSharedLibraryPCL(ClassLoaderContext* context,
                                         size_t loader_index,
                                         size_t shared_library_index,
                                         const std::string& classpath) {
    VerifyClassLoaderInfoSL(
        context, loader_index, shared_library_index, ClassLoaderContext::kPathClassLoader,
        classpath);
  }

  void VerifyClassLoaderSharedLibraryPCLAfter(ClassLoaderContext* context,
                                              size_t loader_index,
                                              size_t shared_library_index,
                                              const std::string& classpath) {
    VerifyClassLoaderInfoSLAfter(
        context, loader_index, shared_library_index, ClassLoaderContext::kPathClassLoader,
        classpath);
  }

  void VerifyClassLoaderSharedLibraryIMC(ClassLoaderContext* context,
                                         size_t loader_index,
                                         size_t shared_library_index,
                                         const std::string& classpath) {
    VerifyClassLoaderInfoSL(
        context, loader_index, shared_library_index, ClassLoaderContext::kInMemoryDexClassLoader,
        classpath);
  }

  void VerifySharedLibrariesSize(ClassLoaderContext* context,
                                 size_t loader_index,
                                 size_t expected_size) {
    ASSERT_TRUE(context != nullptr);
    ASSERT_GT(context->GetParentChainSize(), loader_index);
    const ClassLoaderContext::ClassLoaderInfo& info = *context->GetParent(loader_index);
    ASSERT_EQ(info.shared_libraries.size(), expected_size);
  }

  void VerifyClassLoaderSharedLibraryDLC(ClassLoaderContext* context,
                                         size_t loader_index,
                                         size_t shared_library_index,
                                         const std::string& classpath) {
    VerifyClassLoaderInfoSL(
        context, loader_index, shared_library_index, ClassLoaderContext::kDelegateLastClassLoader,
        classpath);
  }

  void VerifyClassLoaderPCLFromTestDex(ClassLoaderContext* context,
                                       size_t index,
                                       const std::string& test_name) {
    VerifyClassLoaderFromTestDex(
        context, index, ClassLoaderContext::kPathClassLoader, test_name);
  }

  void VerifyClassLoaderDLCFromTestDex(ClassLoaderContext* context,
                                       size_t index,
                                       const std::string& test_name) {
    VerifyClassLoaderFromTestDex(
        context, index, ClassLoaderContext::kDelegateLastClassLoader, test_name);
  }

  void VerifyClassLoaderIMCFromTestDex(ClassLoaderContext* context,
                                       size_t index,
                                       const std::string& test_name) {
    VerifyClassLoaderFromTestDex(
        context, index, ClassLoaderContext::kInMemoryDexClassLoader, test_name, "<unknown>");
  }

  enum class LocationCheck {
    kEquals,
    kEndsWith
  };
  enum class BaseLocationCheck {
    kEquals,
    kEndsWith
  };

  static bool IsAbsoluteLocation(const std::string& location) {
    return !location.empty() && location[0] == '/';
  }

  void VerifyOpenDexFiles(
      ClassLoaderContext* context,
      size_t index,
      std::vector<std::unique_ptr<const DexFile>>* all_dex_files,
      bool classpath_matches_dex_location = true,
      bool only_read_checksums = false) {
    ASSERT_TRUE(context != nullptr);
    if (only_read_checksums) {
      ASSERT_EQ(context->dex_files_state_,
                ClassLoaderContext::ContextDexFilesState::kDexFilesChecksumsRead);
    } else {
      ASSERT_EQ(context->dex_files_state_,
                ClassLoaderContext::ContextDexFilesState::kDexFilesOpened);
    }
    ClassLoaderContext::ClassLoaderInfo& info = *context->GetParent(index);

    std::vector<const DexFile*> primary_dex_files;
    std::vector<std::optional<uint32_t>> primary_checksums;
    for (size_t i = 0; i < all_dex_files->size();) {
      primary_dex_files.push_back((*all_dex_files)[i].get());
      primary_checksums.push_back(DexFileLoader::GetMultiDexChecksum(*all_dex_files, &i));
    }
    ASSERT_EQ(primary_dex_files.size(), info.classpath.size());
    ASSERT_EQ(primary_dex_files.size(), info.checksums.size());

    if (only_read_checksums) {
      ASSERT_EQ(0u, info.opened_dex_files.size());
      for (size_t k = 0; k < primary_dex_files.size(); k++) {
        const std::string& opened_location = info.classpath[k];
        uint32_t opened_checksum = info.checksums[k];

        const DexFile* expected_dex_file = primary_dex_files[k];
        std::string expected_location = expected_dex_file->GetLocation();

        if (!IsAbsoluteLocation(opened_location)) {
          // If the opened location is relative (it was open from a relative path without a
          // classpath_dir) it might not match the expected location which is absolute in tests).
          // So we compare the endings (the checksum will validate it's actually the same file).
          ASSERT_TRUE(EndsWith(expected_location, opened_location))
              << expected_location << " " << opened_location;
        } else {
          ASSERT_EQ(expected_location, opened_location);
        }
        ASSERT_EQ(primary_checksums[k], opened_checksum);
        if (classpath_matches_dex_location) {
          ASSERT_EQ(info.classpath[k], opened_location);
        }
      }
    } else {
      ASSERT_EQ(all_dex_files->size(), info.opened_dex_files.size());

      for (size_t k = 0; k < all_dex_files->size(); k++) {
        const std::string& opened_location = info.opened_dex_files[k]->GetLocation();
        uint32_t opened_checksum = info.opened_dex_files[k]->GetLocationChecksum();

        std::unique_ptr<const DexFile>& expected_dex_file = (*all_dex_files)[k];
        std::string expected_location = expected_dex_file->GetLocation();

        if (!IsAbsoluteLocation(opened_location)) {
          // If the opened location is relative (it was open from a relative path without a
          // classpath_dir) it might not match the expected location which is absolute in tests).
          // So we compare the endings (the checksum will validate it's actually the same file).
          ASSERT_TRUE(EndsWith(expected_location, opened_location))
              << expected_location << " " << opened_location;
        } else {
          ASSERT_EQ(expected_location, opened_location);
        }
        ASSERT_EQ(expected_dex_file->GetLocationChecksum(), opened_checksum);
        if (classpath_matches_dex_location) {
          ASSERT_EQ(info.classpath[k], opened_location);
        }
      }
    }
  }

  std::unique_ptr<ClassLoaderContext> CreateContextForClassLoader(jobject class_loader) {
    return ClassLoaderContext::CreateContextForClassLoader(class_loader, nullptr);
  }

  std::unique_ptr<ClassLoaderContext> ParseContextWithChecksums(const std::string& context_spec) {
    std::unique_ptr<ClassLoaderContext> context(new ClassLoaderContext());
    if (!context->Parse(context_spec, /*parse_checksums=*/ true)) {
      return nullptr;
    }
    return context;
  }

  void VerifyContextForClassLoader(ClassLoaderContext* context) {
    ASSERT_TRUE(context != nullptr);
    ASSERT_EQ(context->dex_files_state_, ClassLoaderContext::ContextDexFilesState::kDexFilesOpened);
    ASSERT_FALSE(context->owns_the_dex_files_);
  }

  void VerifyClassLoaderDexFiles(Thread* self,
                                 Handle<mirror::ClassLoader> class_loader,
                                 ObjPtr<mirror::Class> type,
                                 std::vector<const DexFile*>& expected_dex_files)
      REQUIRES_SHARED(Locks::mutator_lock_) {
    ASSERT_TRUE(class_loader->GetClass() == type);

    std::vector<const DexFile*> class_loader_dex_files = GetDexFiles(self, class_loader);
    ASSERT_EQ(expected_dex_files.size(), class_loader_dex_files.size());

    for (size_t i = 0; i < expected_dex_files.size(); i++) {
      ASSERT_EQ(expected_dex_files[i]->GetLocation(),
                class_loader_dex_files[i]->GetLocation());
      ASSERT_EQ(expected_dex_files[i]->GetLocationChecksum(),
                class_loader_dex_files[i]->GetLocationChecksum());
    }
  }

  void PretendContextOpenedDexFiles(ClassLoaderContext* context) {
    context->dex_files_state_ = ClassLoaderContext::ContextDexFilesState::kDexFilesOpened;
  }

  void PretendContextOpenedDexFilesForChecksums(ClassLoaderContext* context) {
    context->dex_files_state_ = ClassLoaderContext::ContextDexFilesState::kDexFilesChecksumsRead;
  }

  void TestOpenDexFiles(bool only_read_checksums) {
    std::string multidex_name = GetTestDexFileName("MultiDex");
    std::string myclass_dex_name = GetTestDexFileName("MyClass");
    std::string dex_name = GetTestDexFileName("Main");

    std::unique_ptr<ClassLoaderContext> context =
        ClassLoaderContext::Create(
            "PCL[" + multidex_name + ":" + myclass_dex_name + "];" +
            "DLC[" + dex_name + "]");

    ASSERT_TRUE(context->OpenDexFiles(
        /*classpath_dir=*/ "",
        /*context_fds=*/ std::vector<int>(),
        only_read_checksums));

    VerifyContextSize(context.get(), 2);

    std::vector<std::unique_ptr<const DexFile>> all_dex_files0 = OpenTestDexFiles("MultiDex");
    std::vector<std::unique_ptr<const DexFile>> myclass_dex_files = OpenTestDexFiles("MyClass");
    for (size_t i = 0; i < myclass_dex_files.size(); i++) {
      all_dex_files0.emplace_back(myclass_dex_files[i].release());
    }
    VerifyOpenDexFiles(context.get(),
                       /*index=*/ 0,
                       &all_dex_files0,
                       /*classpath_matches_dex_location=*/ false,
                       only_read_checksums);
    std::vector<std::unique_ptr<const DexFile>> all_dex_files1 = OpenTestDexFiles("Main");
    VerifyOpenDexFiles(context.get(),
                       /*index=*/ 1,
                       &all_dex_files1,
                       /*classpath_matches_dex_location=*/ false,
                       only_read_checksums);
  }

  void TestOpenValidDexFilesRelative(bool use_classpath_dir, bool only_read_checksums) {
    char cwd_buf[4096];
    if (getcwd(cwd_buf, arraysize(cwd_buf)) == nullptr) {
      PLOG(FATAL) << "Could not get working directory";
    }
    std::string multidex_name;
    std::string myclass_dex_name;
    std::string dex_name;
    if (!CreateRelativeString(GetTestDexFileName("MultiDex"), cwd_buf, &multidex_name) ||
        !CreateRelativeString(GetTestDexFileName("MyClass"), cwd_buf, &myclass_dex_name) ||
        !CreateRelativeString(GetTestDexFileName("Main"), cwd_buf, &dex_name)) {
      LOG(ERROR) << "Test OpenValidDexFilesRelative cannot be run because target dex files have no "
                << "relative path.";
      SUCCEED();
      return;
    }

    std::unique_ptr<ClassLoaderContext> context =
        ClassLoaderContext::Create(
            "PCL[" + multidex_name + ":" + myclass_dex_name + "];" +
            "DLC[" + dex_name + "]");

    ASSERT_TRUE(context->OpenDexFiles(
        /*classpath_dir=*/ use_classpath_dir ? cwd_buf : "",
        /*context_fds=*/ std::vector<int>(),
        only_read_checksums));
    VerifyContextSize(context.get(), 2);

    std::vector<std::unique_ptr<const DexFile>> all_dex_files0 = OpenTestDexFiles("MultiDex");
    std::vector<std::unique_ptr<const DexFile>> myclass_dex_files = OpenTestDexFiles("MyClass");
    for (size_t i = 0; i < myclass_dex_files.size(); i++) {
      all_dex_files0.emplace_back(myclass_dex_files[i].release());
    }
    VerifyOpenDexFiles(context.get(),
                       /*index=*/ 0,
                       &all_dex_files0,
                       /*classpath_matches_dex_location=*/ false,
                       only_read_checksums);

    std::vector<std::unique_ptr<const DexFile>> all_dex_files1 = OpenTestDexFiles("Main");
    VerifyOpenDexFiles(context.get(),
                       /*index=*/ 1,
                       &all_dex_files1,
                       /*classpath_matches_dex_location=*/ false,
                       only_read_checksums);
  }

  // Creates a relative path from cwd to 'in'. Returns false if it cannot be done.
  // TODO We should somehow support this in all situations. b/72042237.
  bool CreateRelativeString(const std::string& in, const char* cwd, std::string* out) {
    int cwd_len = strlen(cwd);
    if (!android::base::StartsWith(in, cwd) || (cwd_len < 1)) {
      return false;
    }
    bool contains_trailing_slash = (cwd[cwd_len - 1] == '/');
    int start_position = cwd_len + (contains_trailing_slash ? 0 : 1);
    *out = in.substr(start_position);
    return true;
  }

  std::unique_ptr<ScratchDir> scratch_dir_;
  std::string scratch_path_;

 private:
  void VerifyClassLoaderInfo(ClassLoaderContext* context,
                             size_t index,
                             ClassLoaderContext::ClassLoaderType type,
                             const std::string& classpath) {
    ASSERT_TRUE(context != nullptr);
    ASSERT_GT(context->GetParentChainSize(), index);
    ClassLoaderContext::ClassLoaderInfo& info = *context->GetParent(index);
    ASSERT_EQ(type, info.type);
    std::vector<std::string> expected_classpath;
    Split(classpath, ':', &expected_classpath);
    ASSERT_EQ(expected_classpath, info.classpath);
  }

  void VerifyClassLoaderInfoSL(ClassLoaderContext* context,
                               size_t loader_index,
                               size_t shared_library_index,
                               ClassLoaderContext::ClassLoaderType type,
                               const std::string& classpath) {
    ASSERT_TRUE(context != nullptr);
    ASSERT_GT(context->GetParentChainSize(), loader_index);
    const ClassLoaderContext::ClassLoaderInfo& info = *context->GetParent(loader_index);
    ASSERT_GT(info.shared_libraries.size(), shared_library_index);
    const ClassLoaderContext::ClassLoaderInfo& sl =
        *info.shared_libraries[shared_library_index].get();
    ASSERT_EQ(type, sl.type);
    std::vector<std::string> expected_classpath;
    Split(classpath, ':', &expected_classpath);
    ASSERT_EQ(expected_classpath, sl.classpath);
  }

  void VerifyClassLoaderInfoSLAfter(ClassLoaderContext* context,
                               size_t loader_index,
                               size_t shared_library_index,
                               ClassLoaderContext::ClassLoaderType type,
                               const std::string& classpath) {
    ASSERT_TRUE(context != nullptr);
    ASSERT_GT(context->GetParentChainSize(), loader_index);
    const ClassLoaderContext::ClassLoaderInfo& info = *context->GetParent(loader_index);
    ASSERT_GT(info.shared_libraries_after.size(), shared_library_index);

    const ClassLoaderContext::ClassLoaderInfo& sl =
        *info.shared_libraries_after[shared_library_index].get();
    ASSERT_EQ(type, sl.type);
    std::vector<std::string> expected_classpath;
    Split(classpath, ':', &expected_classpath);
    ASSERT_EQ(expected_classpath, sl.classpath);
  }

  void VerifyClassLoaderFromTestDex(ClassLoaderContext* context,
                                    size_t index,
                                    ClassLoaderContext::ClassLoaderType type,
                                    const std::string& test_name,
                                    const std::string& classpath = "") {
    std::vector<std::unique_ptr<const DexFile>> dex_files = OpenTestDexFiles(test_name.c_str());

    // If `classpath` is set, override the expected value of ClassLoaderInfo::classpath.
    // Otherwise assume it is equal to dex location (here test dex file name).
    VerifyClassLoaderInfo(context,
                          index,
                          type,
                          classpath.empty() ? GetTestDexFileName(test_name.c_str()) : classpath);
    VerifyOpenDexFiles(context,
                       index,
                       &dex_files,
                       /* classpath_matches_dex_location= */ classpath.empty());
  }
};

TEST_F(ClassLoaderContextTest, ParseValidEmptyContext) {
  std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create("");
  // An empty context should create a single empty PathClassLoader.
  VerifyContextSize(context.get(), 1);
  VerifyClassLoaderPCL(context.get(), 0, "");
}

TEST_F(ClassLoaderContextTest, ParseInvalidSharedLibraryContext) {
  // '&' used to be a special context.
  std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create("&");
  ASSERT_TRUE(context == nullptr);
}

TEST_F(ClassLoaderContextTest, ParseValidContextPCL) {
  std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create("PCL[a.dex]");
  VerifyContextSize(context.get(), 1);
  VerifyClassLoaderPCL(context.get(), 0, "a.dex");
}

TEST_F(ClassLoaderContextTest, ParseValidContextDLC) {
  std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create("DLC[a.dex]");
  VerifyContextSize(context.get(), 1);
  VerifyClassLoaderDLC(context.get(), 0, "a.dex");
}

TEST_F(ClassLoaderContextTest, ParseValidContextIMC) {
  std::unique_ptr<ClassLoaderContext> context = ParseContextWithChecksums("IMC[<unknown>*111]");
  ASSERT_FALSE(context == nullptr);
}

TEST_F(ClassLoaderContextTest, ParseInvalidContextIMCNoChecksum) {
  // IMC is treated as an unknown class loader unless a checksum is provided.
  // This is because the dex location is always bogus.
  std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create("IMC[<unknown>]");
  ASSERT_TRUE(context == nullptr);
}

TEST_F(ClassLoaderContextTest, ParseInvalidContextIMCWrongClasspathMagic) {
  // IMC does not support arbitrary dex location. A magic marker must be used
  // otherwise the spec should be rejected.
  std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create("IMC[a.dex*111]");
  ASSERT_TRUE(context == nullptr);
}

TEST_F(ClassLoaderContextTest, ParseValidContextChain) {
  std::unique_ptr<ClassLoaderContext> context =
      ClassLoaderContext::Create("PCL[a.dex:b.dex];DLC[c.dex:d.dex];PCL[e.dex]");
  VerifyContextSize(context.get(), 3);
  VerifyClassLoaderPCL(context.get(), 0, "a.dex:b.dex");
  VerifyClassLoaderDLC(context.get(), 1, "c.dex:d.dex");
  VerifyClassLoaderPCL(context.get(), 2, "e.dex");
}

TEST_F(ClassLoaderContextTest, ParseSharedLibraries) {
  std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create(
      "PCL[a.dex:b.dex]{PCL[s1.dex]#PCL[s2.dex:s3.dex]#~PCL[s5.dex]#~PCL[s6.dex:s7.dex]};"
      "DLC[c.dex:d.dex]{DLC[s4.dex]}");
  VerifyContextSize(context.get(), 2);
  VerifyClassLoaderSharedLibraryPCL(context.get(), 0, 0, "s1.dex");
  VerifyClassLoaderSharedLibraryPCL(context.get(), 0, 1, "s2.dex:s3.dex");
  VerifyClassLoaderSharedLibraryPCLAfter(context.get(), 0, 0, "s5.dex");
  VerifyClassLoaderSharedLibraryPCLAfter(context.get(), 0, 1, "s6.dex:s7.dex");
  VerifyClassLoaderDLC(context.get(), 1, "c.dex:d.dex");
  VerifyClassLoaderSharedLibraryDLC(context.get(), 1, 0, "s4.dex");
}

TEST_F(ClassLoaderContextTest, ParseEnclosingSharedLibraries) {
  std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create(
      "PCL[a.dex:b.dex]{PCL[s1.dex]{PCL[s2.dex:s3.dex];PCL[s4.dex]}}");
  VerifyContextSize(context.get(), 1);
  VerifyClassLoaderSharedLibraryPCL(context.get(), 0, 0, "s1.dex");
}

TEST_F(ClassLoaderContextTest, ParseComplexSharedLibraries1) {
  std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create(
      "PCL[]{PCL[s4.dex]{PCL[s5.dex]{PCL[s6.dex]}#PCL[s6.dex]}}");
  VerifyContextSize(context.get(), 1);
  VerifyClassLoaderSharedLibraryPCL(context.get(), 0, 0, "s4.dex");
}

TEST_F(ClassLoaderContextTest, ParseComplexSharedLibraries2) {
  std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create(
      "PCL[]{PCL[s1.dex]{PCL[s2.dex]}#PCL[s2.dex]#"
      "PCL[s3.dex]#PCL[s4.dex]{PCL[s5.dex]{PCL[s6.dex]}#PCL[s6.dex]}#PCL[s5.dex]{PCL[s6.dex]}}");
  VerifyContextSize(context.get(), 1);
  VerifyClassLoaderSharedLibraryPCL(context.get(), 0, 0, "s1.dex");
  VerifyClassLoaderSharedLibraryPCL(context.get(), 0, 1, "s2.dex");
  VerifyClassLoaderSharedLibraryPCL(context.get(), 0, 2, "s3.dex");
  VerifyClassLoaderSharedLibraryPCL(context.get(), 0, 3, "s4.dex");
  VerifyClassLoaderSharedLibraryPCL(context.get(), 0, 4, "s5.dex");
}

TEST_F(ClassLoaderContextTest, ParseValidEmptyContextDLC) {
  std::unique_ptr<ClassLoaderContext> context =
      ClassLoaderContext::Create("DLC[]");
  VerifyContextSize(context.get(), 1);
  VerifyClassLoaderDLC(context.get(), 0, "");
}

TEST_F(ClassLoaderContextTest, ParseValidEmptyContextSharedLibrary) {
  std::unique_ptr<ClassLoaderContext> context =
      ClassLoaderContext::Create("DLC[]{}");
  VerifyContextSize(context.get(), 1);
  VerifySharedLibrariesSize(context.get(), 0, 0);
}

TEST_F(ClassLoaderContextTest, ParseInvalidValidContexts) {
  ASSERT_TRUE(nullptr == ClassLoaderContext::Create("ABC[a.dex]"));
  ASSERT_TRUE(nullptr == ClassLoaderContext::Create("PCL"));
  ASSERT_TRUE(nullptr == ClassLoaderContext::Create("PCL[a.dex"));
  ASSERT_TRUE(nullptr == ClassLoaderContext::Create("PCLa.dex]"));
  ASSERT_TRUE(nullptr == ClassLoaderContext::Create("PCL{a.dex}"));
  ASSERT_TRUE(nullptr == ClassLoaderContext::Create("PCL[a.dex];DLC[b.dex"));
  ASSERT_TRUE(nullptr == ClassLoaderContext::Create("PCL[a.dex]{ABC};DLC[b.dex"));
  ASSERT_TRUE(nullptr == ClassLoaderContext::Create("PCL[a.dex]{};DLC[b.dex"));
  ASSERT_TRUE(nullptr == ClassLoaderContext::Create("DLC[s4.dex]}"));
  ASSERT_TRUE(nullptr == ClassLoaderContext::Create("DLC[s4.dex]{"));
  ASSERT_TRUE(nullptr == ClassLoaderContext::Create("DLC{DLC[s4.dex]}"));
  ASSERT_TRUE(nullptr == ClassLoaderContext::Create("PCL{##}"));
  ASSERT_TRUE(nullptr == ClassLoaderContext::Create("PCL{PCL[s4.dex]#}"));
  ASSERT_TRUE(nullptr == ClassLoaderContext::Create("PCL{PCL[s4.dex]##}"));
  ASSERT_TRUE(nullptr == ClassLoaderContext::Create("PCL{PCL[s4.dex]{PCL[s3.dex]}#}"));
}

TEST_F(ClassLoaderContextTest, OpenInvalidDexFiles) {
  std::unique_ptr<ClassLoaderContext> context =
      ClassLoaderContext::Create("PCL[does_not_exist.dex]");
  VerifyContextSize(context.get(), 1);
  ASSERT_FALSE(context->OpenDexFiles("."));
}

TEST_F(ClassLoaderContextTest, ReadChecksumsInvalidDexFiles) {
  std::unique_ptr<ClassLoaderContext> context =
      ClassLoaderContext::Create("PCL[does_not_exist.dex]");
  VerifyContextSize(context.get(), 1);
  ASSERT_FALSE(context->OpenDexFiles(
        /*classpath_dir=*/ ".",
        /*context_fds=*/ std::vector<int>(),
        /*only_read_checksums=*/ true));
}

TEST_F(ClassLoaderContextTest, OpenValidDexFiles) {
  TestOpenDexFiles(/*only_read_checksums=*/ false);
}

TEST_F(ClassLoaderContextTest, ReadDexFileChecksums) {
  TestOpenDexFiles(/*only_read_checksums=*/ true);
}

TEST_F(ClassLoaderContextTest, OpenValidDexFilesRelative) {
  TestOpenValidDexFilesRelative(/*use_classpath_dir=*/ false, /*only_read_checksums=*/ false);
}

TEST_F(ClassLoaderContextTest, ReadChecksumsValidDexFilesRelative) {
  TestOpenValidDexFilesRelative(/*use_classpath_dir=*/ false, /*only_read_checksums=*/ true);
}

TEST_F(ClassLoaderContextTest, OpenValidDexFilesClasspathDir) {
  TestOpenValidDexFilesRelative(/*use_classpath_dir=*/ true, /*only_read_checksums=*/ false);
}

TEST_F(ClassLoaderContextTest, ReadChecksumsValidDexFilesClasspathDir) {
  TestOpenValidDexFilesRelative(/*use_classpath_dir=*/ true, /*only_read_checksums=*/ true);
}

TEST_F(ClassLoaderContextTest, OpenInvalidDexFilesMix) {
  std::string dex_name = GetTestDexFileName("Main");
  std::unique_ptr<ClassLoaderContext> context =
      ClassLoaderContext::Create("PCL[does_not_exist.dex];DLC[" + dex_name + "]");
  ASSERT_FALSE(context->OpenDexFiles());
}

TEST_F(ClassLoaderContextTest, ReadChecksumsInvalidDexFilesMix) {
  std::string dex_name = GetTestDexFileName("Main");
  std::unique_ptr<ClassLoaderContext> context =
      ClassLoaderContext::Create("PCL[does_not_exist.dex];DLC[" + dex_name + "]");
  ASSERT_FALSE(context->OpenDexFiles(
      /*classpath_dir=*/ "",
      /*context_fds=*/ std::vector<int>(),
      /*only_read_checksums=*/ true));
}

TEST_F(ClassLoaderContextTest, OpenDexFilesForIMCFails) {
  std::unique_ptr<ClassLoaderContext> context;
  std::string dex_name = GetTestDexFileName("Main");

  context = ParseContextWithChecksums("IMC[<unknown>*111]");
  VerifyContextSize(context.get(), 1);
  ASSERT_FALSE(context->OpenDexFiles("."));
}

// Verify that we can fully open the dex files after only reading their checksums.
TEST_F(ClassLoaderContextTest, SubsequentOpenDexFilesOperations) {
  std::string dex_name = GetTestDexFileName("Main");
  std::unique_ptr<ClassLoaderContext> context =
      ClassLoaderContext::Create("PCL[" + dex_name + "]");

  std::vector<std::unique_ptr<const DexFile>> all_dex_files0 = OpenTestDexFiles("Main");

  ASSERT_TRUE(context->OpenDexFiles(
      /*classpath_dir=*/ "",
      /*context_fds=*/ std::vector<int>(),
      /*only_read_checksums=*/ true));

  VerifyOpenDexFiles(
      context.get(),
      /*index=*/ 0,
      &all_dex_files0,
      /*classpath_matches_dex_location=*/ false,
      /*only_read_checksums=*/ true);

  ASSERT_TRUE(context->OpenDexFiles(
      /*classpath_dir=*/ "",
      /*context_fds=*/ std::vector<int>(),
      /*only_read_checksums=*/ false));

  VerifyOpenDexFiles(
      context.get(),
      /*index=*/ 0,
      &all_dex_files0,
      /*classpath_matches_dex_location=*/ false,
      /*only_read_checksums=*/ false);
}

TEST_F(ClassLoaderContextTest, CreateClassLoader) {
  std::string dex_name = GetTestDexFileName("Main");
  std::unique_ptr<ClassLoaderContext> context =
      ClassLoaderContext::Create("PCL[" + dex_name + "]");
  ASSERT_TRUE(context->OpenDexFiles());

  std::vector<std::unique_ptr<const DexFile>> classpath_dex = OpenTestDexFiles("Main");
  std::vector<std::unique_ptr<const DexFile>> compilation_sources = OpenTestDexFiles("MultiDex");

  std::vector<const DexFile*> compilation_sources_raw =
      MakeNonOwningPointerVector(compilation_sources);
  jobject jclass_loader = context->CreateClassLoader(compilation_sources_raw);
  ASSERT_TRUE(jclass_loader != nullptr);

  ScopedObjectAccess soa(Thread::Current());

  StackHandleScope<1> hs(soa.Self());
  Handle<mirror::ClassLoader> class_loader = hs.NewHandle(
      soa.Decode<mirror::ClassLoader>(jclass_loader));

  ASSERT_TRUE(class_loader->GetClass() == WellKnownClasses::dalvik_system_PathClassLoader);
  ASSERT_TRUE(class_loader->GetParent()->GetClass() ==
      WellKnownClasses::java_lang_BootClassLoader);

  // For the first class loader the class path dex files must come first and then the
  // compilation sources.
  std::vector<const DexFile*> expected_classpath = MakeNonOwningPointerVector(classpath_dex);
  for (auto& dex : compilation_sources_raw) {
    expected_classpath.push_back(dex);
  }

  VerifyClassLoaderDexFiles(soa.Self(),
                            class_loader,
                            WellKnownClasses::dalvik_system_PathClassLoader.Get(),
                            expected_classpath);
}

TEST_F(ClassLoaderContextTest, CreateClassLoaderWithEmptyContext) {
  std::unique_ptr<ClassLoaderContext> context =
      ClassLoaderContext::Create("");
  ASSERT_TRUE(context->OpenDexFiles());

  std::vector<std::unique_ptr<const DexFile>> compilation_sources = OpenTestDexFiles("MultiDex");

  std::vector<const DexFile*> compilation_sources_raw =
      MakeNonOwningPointerVector(compilation_sources);
  jobject jclass_loader = context->CreateClassLoader(compilation_sources_raw);
  ASSERT_TRUE(jclass_loader != nullptr);

  ScopedObjectAccess soa(Thread::Current());

  StackHandleScope<1> hs(soa.Self());
  Handle<mirror::ClassLoader> class_loader = hs.NewHandle(
      soa.Decode<mirror::ClassLoader>(jclass_loader));

  // An empty context should create a single PathClassLoader with only the compilation sources.
  VerifyClassLoaderDexFiles(soa.Self(),
                            class_loader,
                            WellKnownClasses::dalvik_system_PathClassLoader.Get(),
                            compilation_sources_raw);
  ASSERT_TRUE(class_loader->GetParent()->GetClass() ==
      WellKnownClasses::java_lang_BootClassLoader);
}

TEST_F(ClassLoaderContextTest, CreateClassLoaderWithComplexChain) {
  // Setup the context.
  std::vector<std::unique_ptr<const DexFile>> classpath_dex_a = OpenTestDexFiles("ForClassLoaderA");
  std::vector<std::unique_ptr<const DexFile>> classpath_dex_b = OpenTestDexFiles("ForClassLoaderB");
  std::vector<std::unique_ptr<const DexFile>> classpath_dex_c = OpenTestDexFiles("ForClassLoaderC");
  std::vector<std::unique_ptr<const DexFile>> classpath_dex_d = OpenTestDexFiles("ForClassLoaderD");

  std::string context_spec =
      "PCL[" + CreateClassPath(classpath_dex_a) + ":" + CreateClassPath(classpath_dex_b) + "];" +
      "DLC[" + CreateClassPath(classpath_dex_c) + "];" +
      "PCL[" + CreateClassPath(classpath_dex_d) + "]";

  std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create(context_spec);
  ASSERT_TRUE(context->OpenDexFiles());

  // Setup the compilation sources.
  std::vector<std::unique_ptr<const DexFile>> compilation_sources = OpenTestDexFiles("MultiDex");
  std::vector<const DexFile*> compilation_sources_raw =
      MakeNonOwningPointerVector(compilation_sources);

  // Create the class loader.
  jobject jclass_loader = context->CreateClassLoader(compilation_sources_raw);
  ASSERT_TRUE(jclass_loader != nullptr);

  // Verify the class loader.
  ScopedObjectAccess soa(Thread::Current());

  StackHandleScope<3> hs(soa.Self());
  Handle<mirror::ClassLoader> class_loader_1 = hs.NewHandle(
      soa.Decode<mirror::ClassLoader>(jclass_loader));

  // Verify the first class loader

  // For the first class loader the class path dex files must come first and then the
  // compilation sources.
  std::vector<const DexFile*> class_loader_1_dex_files =
      MakeNonOwningPointerVector(classpath_dex_a);
  for (auto& dex : classpath_dex_b) {
    class_loader_1_dex_files.push_back(dex.get());
  }
  for (auto& dex : compilation_sources_raw) {
    class_loader_1_dex_files.push_back(dex);
  }
  VerifyClassLoaderDexFiles(soa.Self(),
                            class_loader_1,
                            WellKnownClasses::dalvik_system_PathClassLoader.Get(),
                            class_loader_1_dex_files);

  // Verify the second class loader
  Handle<mirror::ClassLoader> class_loader_2 = hs.NewHandle(class_loader_1->GetParent());
  std::vector<const DexFile*> class_loader_2_dex_files =
      MakeNonOwningPointerVector(classpath_dex_c);
  VerifyClassLoaderDexFiles(soa.Self(),
                            class_loader_2,
                            WellKnownClasses::dalvik_system_DelegateLastClassLoader.Get(),
                            class_loader_2_dex_files);

  // Verify the third class loader
  Handle<mirror::ClassLoader> class_loader_3 = hs.NewHandle(class_loader_2->GetParent());
  std::vector<const DexFile*> class_loader_3_dex_files =
      MakeNonOwningPointerVector(classpath_dex_d);
  VerifyClassLoaderDexFiles(soa.Self(),
                            class_loader_3,
                            WellKnownClasses::dalvik_system_PathClassLoader.Get(),
                            class_loader_3_dex_files);
  // The last class loader should have the BootClassLoader as a parent.
  ASSERT_TRUE(class_loader_3->GetParent()->GetClass() ==
      WellKnownClasses::java_lang_BootClassLoader);
}

TEST_F(ClassLoaderContextTest, CreateClassLoaderWithSharedLibraries) {
  // Setup the context.
  std::vector<std::unique_ptr<const DexFile>> classpath_dex_a = OpenTestDexFiles("ForClassLoaderA");
  std::vector<std::unique_ptr<const DexFile>> classpath_dex_b = OpenTestDexFiles("ForClassLoaderB");
  std::vector<std::unique_ptr<const DexFile>> classpath_dex_c = OpenTestDexFiles("ForClassLoaderC");
  std::vector<std::unique_ptr<const DexFile>> classpath_dex_d = OpenTestDexFiles("ForClassLoaderD");

  std::string context_spec =
      "PCL[" + CreateClassPath(classpath_dex_a) + ":" + CreateClassPath(classpath_dex_b) + "]{" +
      "DLC[" + CreateClassPath(classpath_dex_c) + "]#" +
      "PCL[" + CreateClassPath(classpath_dex_d) + "]}";

  std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create(context_spec);
  ASSERT_TRUE(context->OpenDexFiles());

  // Setup the compilation sources.
  std::vector<std::unique_ptr<const DexFile>> compilation_sources = OpenTestDexFiles("MultiDex");
  std::vector<const DexFile*> compilation_sources_raw =
      MakeNonOwningPointerVector(compilation_sources);

  // Create the class loader.
  jobject jclass_loader = context->CreateClassLoader(compilation_sources_raw);
  ASSERT_TRUE(jclass_loader != nullptr);

  // Verify the class loader.
  ScopedObjectAccess soa(Thread::Current());

  StackHandleScope<4> hs(soa.Self());
  Handle<mirror::ClassLoader> class_loader_1 = hs.NewHandle(
      soa.Decode<mirror::ClassLoader>(jclass_loader));

  // For the first class loader the class path dex files must come first and then the
  // compilation sources.
  std::vector<const DexFile*> class_loader_1_dex_files =
      MakeNonOwningPointerVector(classpath_dex_a);
  for (auto& dex : classpath_dex_b) {
    class_loader_1_dex_files.push_back(dex.get());
  }
  for (auto& dex : compilation_sources_raw) {
    class_loader_1_dex_files.push_back(dex);
  }
  VerifyClassLoaderDexFiles(soa.Self(),
                            class_loader_1,
                            WellKnownClasses::dalvik_system_PathClassLoader.Get(),
                            class_loader_1_dex_files);

  // Verify the shared libraries.
  ArtField* field = WellKnownClasses::dalvik_system_BaseDexClassLoader_sharedLibraryLoaders;
  ObjPtr<mirror::Object> raw_shared_libraries = field->GetObject(class_loader_1.Get());
  ASSERT_TRUE(raw_shared_libraries != nullptr);

  Handle<mirror::ObjectArray<mirror::ClassLoader>> shared_libraries(
      hs.NewHandle(raw_shared_libraries->AsObjectArray<mirror::ClassLoader>()));
  ASSERT_EQ(shared_libraries->GetLength(), 2);

  // Verify the first shared library.
  Handle<mirror::ClassLoader> class_loader_2 = hs.NewHandle(shared_libraries->Get(0));
  std::vector<const DexFile*> class_loader_2_dex_files =
      MakeNonOwningPointerVector(classpath_dex_c);
  VerifyClassLoaderDexFiles(soa.Self(),
                            class_loader_2,
                            WellKnownClasses::dalvik_system_DelegateLastClassLoader.Get(),
                            class_loader_2_dex_files);
  raw_shared_libraries = field->GetObject(class_loader_2.Get());
  ASSERT_TRUE(raw_shared_libraries == nullptr);

  // Verify the second shared library.
  Handle<mirror::ClassLoader> class_loader_3 = hs.NewHandle(shared_libraries->Get(1));
  std::vector<const DexFile*> class_loader_3_dex_files =
      MakeNonOwningPointerVector(classpath_dex_d);
  VerifyClassLoaderDexFiles(soa.Self(),
                            class_loader_3,
                            WellKnownClasses::dalvik_system_PathClassLoader.Get(),
                            class_loader_3_dex_files);
  raw_shared_libraries = field->GetObject(class_loader_3.Get());
  ASSERT_TRUE(raw_shared_libraries == nullptr);

  // All class loaders should have the BootClassLoader as a parent.
  ASSERT_TRUE(class_loader_1->GetParent()->GetClass() ==
      WellKnownClasses::java_lang_BootClassLoader);
  ASSERT_TRUE(class_loader_2->GetParent()->GetClass() ==
      WellKnownClasses::java_lang_BootClassLoader);
  ASSERT_TRUE(class_loader_3->GetParent()->GetClass() ==
      WellKnownClasses::java_lang_BootClassLoader);
}

TEST_F(ClassLoaderContextTest, CreateClassLoaderWithSharedLibrariesInParentToo) {
  // Setup the context.
  std::vector<std::unique_ptr<const DexFile>> classpath_dex_a = OpenTestDexFiles("ForClassLoaderA");
  std::vector<std::unique_ptr<const DexFile>> classpath_dex_b = OpenTestDexFiles("ForClassLoaderB");
  std::vector<std::unique_ptr<const DexFile>> classpath_dex_c = OpenTestDexFiles("ForClassLoaderC");
  std::vector<std::unique_ptr<const DexFile>> classpath_dex_d = OpenTestDexFiles("ForClassLoaderD");

  std::string context_spec =
      "PCL[" + CreateClassPath(classpath_dex_a) + "]{" +
      "PCL[" + CreateClassPath(classpath_dex_b) + "]};" +
      "PCL[" + CreateClassPath(classpath_dex_c) + "]{" +
      "PCL[" + CreateClassPath(classpath_dex_d) + "]}";

  std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create(context_spec);
  ASSERT_TRUE(context->OpenDexFiles());

  // Setup the compilation sources.
  std::vector<std::unique_ptr<const DexFile>> compilation_sources = OpenTestDexFiles("MultiDex");
  std::vector<const DexFile*> compilation_sources_raw =
      MakeNonOwningPointerVector(compilation_sources);

  // Create the class loader.
  jobject jclass_loader = context->CreateClassLoader(compilation_sources_raw);
  ASSERT_TRUE(jclass_loader != nullptr);

  // Verify the class loader.
  ScopedObjectAccess soa(Thread::Current());

  StackHandleScope<6> hs(soa.Self());
  Handle<mirror::ClassLoader> class_loader_1 = hs.NewHandle(
      soa.Decode<mirror::ClassLoader>(jclass_loader));

  // For the first class loader the class path dex files must come first and then the
  // compilation sources.
  std::vector<const DexFile*> class_loader_1_dex_files =
      MakeNonOwningPointerVector(classpath_dex_a);
  for (auto& dex : compilation_sources_raw) {
    class_loader_1_dex_files.push_back(dex);
  }
  VerifyClassLoaderDexFiles(soa.Self(),
                            class_loader_1,
                            WellKnownClasses::dalvik_system_PathClassLoader.Get(),
                            class_loader_1_dex_files);

  // Verify its shared library.
  ArtField* field = WellKnownClasses::dalvik_system_BaseDexClassLoader_sharedLibraryLoaders;
  ObjPtr<mirror::Object> raw_shared_libraries = field->GetObject(class_loader_1.Get());
  ASSERT_TRUE(raw_shared_libraries != nullptr);

  Handle<mirror::ObjectArray<mirror::ClassLoader>> shared_libraries(
      hs.NewHandle(raw_shared_libraries->AsObjectArray<mirror::ClassLoader>()));
  ASSERT_EQ(shared_libraries->GetLength(), 1);

  Handle<mirror::ClassLoader> class_loader_2 = hs.NewHandle(shared_libraries->Get(0));
  std::vector<const DexFile*> class_loader_2_dex_files =
      MakeNonOwningPointerVector(classpath_dex_b);
  VerifyClassLoaderDexFiles(soa.Self(),
                            class_loader_2,
                            WellKnownClasses::dalvik_system_PathClassLoader.Get(),
                            class_loader_2_dex_files);
  raw_shared_libraries = field->GetObject(class_loader_2.Get());
  ASSERT_TRUE(raw_shared_libraries == nullptr);

  // Verify the parent.
  Handle<mirror::ClassLoader> class_loader_3 = hs.NewHandle(class_loader_1->GetParent());
  std::vector<const DexFile*> class_loader_3_dex_files =
      MakeNonOwningPointerVector(classpath_dex_c);
  VerifyClassLoaderDexFiles(soa.Self(),
                            class_loader_3,
                            WellKnownClasses::dalvik_system_PathClassLoader.Get(),
                            class_loader_3_dex_files);

  // Verify its shared library.
  raw_shared_libraries = field->GetObject(class_loader_3.Get());
  ASSERT_TRUE(raw_shared_libraries != nullptr);

  Handle<mirror::ObjectArray<mirror::ClassLoader>> shared_libraries_2(
      hs.NewHandle(raw_shared_libraries->AsObjectArray<mirror::ClassLoader>()));
  ASSERT_EQ(shared_libraries->GetLength(), 1);

  Handle<mirror::ClassLoader> class_loader_4 = hs.NewHandle(shared_libraries_2->Get(0));
  std::vector<const DexFile*> class_loader_4_dex_files =
      MakeNonOwningPointerVector(classpath_dex_d);
  VerifyClassLoaderDexFiles(soa.Self(),
                            class_loader_4,
                            WellKnownClasses::dalvik_system_PathClassLoader.Get(),
                            class_loader_4_dex_files);
  raw_shared_libraries = field->GetObject(class_loader_4.Get());
  ASSERT_TRUE(raw_shared_libraries == nullptr);

  // Class loaders should have the BootClassLoader as a parent.
  ASSERT_TRUE(class_loader_2->GetParent()->GetClass() ==
      WellKnownClasses::java_lang_BootClassLoader);
  ASSERT_TRUE(class_loader_3->GetParent()->GetClass() ==
      WellKnownClasses::java_lang_BootClassLoader);
  ASSERT_TRUE(class_loader_4->GetParent()->GetClass() ==
      WellKnownClasses::java_lang_BootClassLoader);
}

TEST_F(ClassLoaderContextTest, CreateClassLoaderWithSharedLibrariesDependencies) {
  // Setup the context.
  std::vector<std::unique_ptr<const DexFile>> classpath_dex_a = OpenTestDexFiles("ForClassLoaderA");
  std::vector<std::unique_ptr<const DexFile>> classpath_dex_b = OpenTestDexFiles("ForClassLoaderB");
  std::vector<std::unique_ptr<const DexFile>> classpath_dex_c = OpenTestDexFiles("ForClassLoaderC");
  std::vector<std::unique_ptr<const DexFile>> classpath_dex_d = OpenTestDexFiles("ForClassLoaderD");

  std::string context_spec =
      "PCL[" + CreateClassPath(classpath_dex_a) + "]{" +
      "PCL[" + CreateClassPath(classpath_dex_b) + "]{" +
      "PCL[" + CreateClassPath(classpath_dex_c) + "]}};" +
      "PCL[" + CreateClassPath(classpath_dex_d) + "]";

  std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create(context_spec);
  ASSERT_TRUE(context->OpenDexFiles());

  // Setup the compilation sources.
  std::vector<std::unique_ptr<const DexFile>> compilation_sources = OpenTestDexFiles("MultiDex");
  std::vector<const DexFile*> compilation_sources_raw =
      MakeNonOwningPointerVector(compilation_sources);

  // Create the class loader.
  jobject jclass_loader = context->CreateClassLoader(compilation_sources_raw);
  ASSERT_TRUE(jclass_loader != nullptr);

  // Verify the class loader.
  ScopedObjectAccess soa(Thread::Current());

  StackHandleScope<6> hs(soa.Self());
  Handle<mirror::ClassLoader> class_loader_1 = hs.NewHandle(
      soa.Decode<mirror::ClassLoader>(jclass_loader));

  // For the first class loader the class path dex files must come first and then the
  // compilation sources.
  std::vector<const DexFile*> class_loader_1_dex_files =
      MakeNonOwningPointerVector(classpath_dex_a);
  for (auto& dex : compilation_sources_raw) {
    class_loader_1_dex_files.push_back(dex);
  }
  VerifyClassLoaderDexFiles(soa.Self(),
                            class_loader_1,
                            WellKnownClasses::dalvik_system_PathClassLoader.Get(),
                            class_loader_1_dex_files);

  // Verify its shared library.
  ArtField* field = WellKnownClasses::dalvik_system_BaseDexClassLoader_sharedLibraryLoaders;
  ObjPtr<mirror::Object> raw_shared_libraries = field->GetObject(class_loader_1.Get());
  ASSERT_TRUE(raw_shared_libraries != nullptr);

  Handle<mirror::ObjectArray<mirror::ClassLoader>> shared_libraries(
      hs.NewHandle(raw_shared_libraries->AsObjectArray<mirror::ClassLoader>()));
  ASSERT_EQ(shared_libraries->GetLength(), 1);

  Handle<mirror::ClassLoader> class_loader_2 = hs.NewHandle(shared_libraries->Get(0));
  std::vector<const DexFile*> class_loader_2_dex_files =
      MakeNonOwningPointerVector(classpath_dex_b);
  VerifyClassLoaderDexFiles(soa.Self(),
                            class_loader_2,
                            WellKnownClasses::dalvik_system_PathClassLoader.Get(),
                            class_loader_2_dex_files);

  // Verify the shared library dependency of the shared library.
  raw_shared_libraries = field->GetObject(class_loader_2.Get());
  ASSERT_TRUE(raw_shared_libraries != nullptr);

  Handle<mirror::ObjectArray<mirror::ClassLoader>> shared_libraries_2(
      hs.NewHandle(raw_shared_libraries->AsObjectArray<mirror::ClassLoader>()));
  ASSERT_EQ(shared_libraries_2->GetLength(), 1);

  Handle<mirror::ClassLoader> class_loader_3 = hs.NewHandle(shared_libraries_2->Get(0));
  std::vector<const DexFile*> class_loader_3_dex_files =
      MakeNonOwningPointerVector(classpath_dex_c);
  VerifyClassLoaderDexFiles(soa.Self(),
                            class_loader_3,
                            WellKnownClasses::dalvik_system_PathClassLoader.Get(),
                            class_loader_3_dex_files);
  raw_shared_libraries = field->GetObject(class_loader_3.Get());
  ASSERT_TRUE(raw_shared_libraries == nullptr);

  // Verify the parent.
  Handle<mirror::ClassLoader> class_loader_4 = hs.NewHandle(class_loader_1->GetParent());
  std::vector<const DexFile*> class_loader_4_dex_files =
      MakeNonOwningPointerVector(classpath_dex_d);
  VerifyClassLoaderDexFiles(soa.Self(),
                            class_loader_4,
                            WellKnownClasses::dalvik_system_PathClassLoader.Get(),
                            class_loader_4_dex_files);
  raw_shared_libraries = field->GetObject(class_loader_4.Get());
  ASSERT_TRUE(raw_shared_libraries == nullptr);

  // Class loaders should have the BootClassLoader as a parent.
  ASSERT_TRUE(class_loader_2->GetParent()->GetClass() ==
      WellKnownClasses::java_lang_BootClassLoader);
  ASSERT_TRUE(class_loader_3->GetParent()->GetClass() ==
      WellKnownClasses::java_lang_BootClassLoader);
  ASSERT_TRUE(class_loader_4->GetParent()->GetClass() ==
      WellKnownClasses::java_lang_BootClassLoader);
}

TEST_F(ClassLoaderContextTest, RemoveSourceLocations) {
  std::unique_ptr<ClassLoaderContext> context =
      ClassLoaderContext::Create("PCL[a.dex]");
  dchecked_vector<std::string> classpath_dex;
  classpath_dex.push_back("a.dex");
  dchecked_vector<std::string> compilation_sources;
  compilation_sources.push_back("src.dex");

  // Nothing should be removed.
  ASSERT_FALSE(context->RemoveLocationsFromClassPaths(compilation_sources));
  VerifyClassLoaderPCL(context.get(), 0, "a.dex");
  // Classes should be removed.
  ASSERT_TRUE(context->RemoveLocationsFromClassPaths(classpath_dex));
  VerifyClassLoaderPCL(context.get(), 0, "");
}

TEST_F(ClassLoaderContextTest, CreateClassLoaderWithSameSharedLibraries) {
  // Setup the context.
  std::vector<std::unique_ptr<const DexFile>> classpath_dex_a = OpenTestDexFiles("ForClassLoaderA");
  std::vector<std::unique_ptr<const DexFile>> classpath_dex_b = OpenTestDexFiles("ForClassLoaderB");
  std::vector<std::unique_ptr<const DexFile>> classpath_dex_c = OpenTestDexFiles("ForClassLoaderC");

  std::string context_spec =
      "PCL[" + CreateClassPath(classpath_dex_a) + "]{" +
      "PCL[" + CreateClassPath(classpath_dex_b) + "]};" +
      "PCL[" + CreateClassPath(classpath_dex_c) + "]{" +
      "PCL[" + CreateClassPath(classpath_dex_b) + "]}";

  std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create(context_spec);
  ASSERT_TRUE(context->OpenDexFiles());

  // Setup the compilation sources.
  std::vector<std::unique_ptr<const DexFile>> compilation_sources = OpenTestDexFiles("MultiDex");
  std::vector<const DexFile*> compilation_sources_raw =
      MakeNonOwningPointerVector(compilation_sources);

  // Create the class loader.
  jobject jclass_loader = context->CreateClassLoader(compilation_sources_raw);
  ASSERT_TRUE(jclass_loader != nullptr);

  // Verify the class loader.
  ScopedObjectAccess soa(Thread::Current());

  StackHandleScope<6> hs(soa.Self());
  Handle<mirror::ClassLoader> class_loader_1 = hs.NewHandle(
      soa.Decode<mirror::ClassLoader>(jclass_loader));

  // For the first class loader the class path dex files must come first and then the
  // compilation sources.
  std::vector<const DexFile*> class_loader_1_dex_files =
      MakeNonOwningPointerVector(classpath_dex_a);
  for (auto& dex : compilation_sources_raw) {
    class_loader_1_dex_files.push_back(dex);
  }
  VerifyClassLoaderDexFiles(soa.Self(),
                            class_loader_1,
                            WellKnownClasses::dalvik_system_PathClassLoader.Get(),
                            class_loader_1_dex_files);

  // Verify its shared library.
  ArtField* field = WellKnownClasses::dalvik_system_BaseDexClassLoader_sharedLibraryLoaders;
  ObjPtr<mirror::Object> raw_shared_libraries = field->GetObject(class_loader_1.Get());
  ASSERT_TRUE(raw_shared_libraries != nullptr);

  Handle<mirror::ObjectArray<mirror::ClassLoader>> shared_libraries(
      hs.NewHandle(raw_shared_libraries->AsObjectArray<mirror::ClassLoader>()));
  ASSERT_EQ(shared_libraries->GetLength(), 1);

  Handle<mirror::ClassLoader> class_loader_2 = hs.NewHandle(shared_libraries->Get(0));
  std::vector<const DexFile*> class_loader_2_dex_files =
      MakeNonOwningPointerVector(classpath_dex_b);
  VerifyClassLoaderDexFiles(soa.Self(),
                            class_loader_2,
                            WellKnownClasses::dalvik_system_PathClassLoader.Get(),
                            class_loader_2_dex_files);

  // Verify the parent.
  Handle<mirror::ClassLoader> class_loader_3 = hs.NewHandle(class_loader_1->GetParent());
  std::vector<const DexFile*> class_loader_3_dex_files =
      MakeNonOwningPointerVector(classpath_dex_c);
  VerifyClassLoaderDexFiles(soa.Self(),
                            class_loader_3,
                            WellKnownClasses::dalvik_system_PathClassLoader.Get(),
                            class_loader_3_dex_files);

  // Verify its shared library is the same as the child.
  raw_shared_libraries = field->GetObject(class_loader_3.Get());
  ASSERT_TRUE(raw_shared_libraries != nullptr);
  Handle<mirror::ObjectArray<mirror::ClassLoader>> shared_libraries_2(
      hs.NewHandle(raw_shared_libraries->AsObjectArray<mirror::ClassLoader>()));
  ASSERT_EQ(shared_libraries_2->GetLength(), 1);
  ASSERT_OBJ_PTR_EQ(shared_libraries_2->Get(0), class_loader_2.Get());

  // Class loaders should have the BootClassLoader as a parent.
  ASSERT_TRUE(class_loader_2->GetParent()->GetClass() ==
      WellKnownClasses::java_lang_BootClassLoader);
  ASSERT_TRUE(class_loader_3->GetParent()->GetClass() ==
      WellKnownClasses::java_lang_BootClassLoader);
}

TEST_F(ClassLoaderContextTest, EncodeInOatFile) {
  std::string dex1_name = GetTestDexFileName("Main");
  std::string dex2_name = GetTestDexFileName("MyClass");
  std::unique_ptr<ClassLoaderContext> context =
      ClassLoaderContext::Create("PCL[" + dex1_name + ":" + dex2_name + "]");
  ASSERT_TRUE(context->OpenDexFiles());

  std::vector<std::unique_ptr<const DexFile>> dex1 = OpenTestDexFiles("Main");
  std::vector<std::unique_ptr<const DexFile>> dex2 = OpenTestDexFiles("MyClass");
  std::string encoding = context->EncodeContextForOatFile("");
  std::string expected_encoding = "PCL[" + CreateClassPathWithChecksums(dex1) + ":" +
      CreateClassPathWithChecksums(dex2) + "]";
  ASSERT_EQ(expected_encoding, context->EncodeContextForOatFile(""));
}

// Same as above, but passes `only_read_checksums=true` to `OpenDexFiles`.
TEST_F(ClassLoaderContextTest, EncodeInOatFileOnlyReadChecksums) {
  std::string dex1_name = GetTestDexFileName("Main");
  std::string dex2_name = GetTestDexFileName("MyClass");
  std::unique_ptr<ClassLoaderContext> context =
      ClassLoaderContext::Create("PCL[" + dex1_name + ":" + dex2_name + "]");
  ASSERT_TRUE(context->OpenDexFiles(
      /*classpath_dir=*/"", /*context_fds=*/{}, /*only_read_checksums=*/true));

  std::vector<std::unique_ptr<const DexFile>> dex1 = OpenTestDexFiles("Main");
  std::vector<std::unique_ptr<const DexFile>> dex2 = OpenTestDexFiles("MyClass");
  std::string encoding = context->EncodeContextForOatFile("");
  std::string expected_encoding =
      "PCL[" + CreateClassPathWithChecksums(dex1) + ":" + CreateClassPathWithChecksums(dex2) + "]";
  ASSERT_EQ(expected_encoding, context->EncodeContextForOatFile(""));
}

TEST_F(ClassLoaderContextTest, EncodeInOatFileIMC) {
  jobject class_loader_a = LoadDexInPathClassLoader("Main", nullptr);
  jobject class_loader_b = LoadDexInInMemoryDexClassLoader("MyClass", class_loader_a);

  std::unique_ptr<ClassLoaderContext> context = CreateContextForClassLoader(class_loader_b);
  ASSERT_TRUE(context->OpenDexFiles());

  std::vector<std::unique_ptr<const DexFile>> dex1 = OpenTestDexFiles("Main");
  std::vector<std::unique_ptr<const DexFile>> dex2 = OpenTestDexFiles("MyClass");
  ASSERT_EQ(dex2.size(), 1u);

  uint32_t expected_checksum = DexFileLoader::GetMultiDexChecksum(dex2);

  std::string encoding = context->EncodeContextForOatFile("");
  std::string expected_encoding = "IMC[<unknown>*" + std::to_string(expected_checksum) + "];PCL[" +
                                  CreateClassPathWithChecksums(dex1) + "]";
  ASSERT_EQ(expected_encoding, context->EncodeContextForOatFile(""));
}

TEST_F(ClassLoaderContextTest, EncodeForDex2oat) {
  std::string dex1_name = GetTestDexFileName("Main");
  std::string dex2_name = GetTestDexFileName("MultiDex");
  std::unique_ptr<ClassLoaderContext> context =
      ClassLoaderContext::Create("PCL[" + dex1_name + ":" + dex2_name + "]");
  ASSERT_TRUE(context->OpenDexFiles());

  std::string encoding = context->EncodeContextForDex2oat("");
  std::string expected_encoding = "PCL[" + dex1_name + ":" + dex2_name + "]";
  ASSERT_EQ(expected_encoding, context->EncodeContextForDex2oat(""));
}

TEST_F(ClassLoaderContextTest, EncodeForDex2oatIMC) {
  jobject class_loader_a = LoadDexInPathClassLoader("Main", nullptr);
  jobject class_loader_b = LoadDexInInMemoryDexClassLoader("MyClass", class_loader_a);

  std::unique_ptr<ClassLoaderContext> context = CreateContextForClassLoader(class_loader_b);
  ASSERT_TRUE(context->OpenDexFiles());

  std::string encoding = context->EncodeContextForDex2oat("");
  std::string expected_encoding = "IMC[<unknown>];PCL[" + GetTestDexFileName("Main") + "]";
  ASSERT_EQ(expected_encoding, context->EncodeContextForDex2oat(""));
}

TEST_F(ClassLoaderContextTest, EncodeForDex2oatDuplicates) {
  std::string dex_name = GetTestDexFileName("Main");
  std::unique_ptr<ClassLoaderContext> context =
      ClassLoaderContext::Create("PCL[" + dex_name + ":" + dex_name + "]");
  ASSERT_TRUE(context->OpenDexFiles());

  std::string encoding = context->EncodeContextForDex2oat("");
  std::string expected_encoding = "PCL[" + dex_name + "]";
  ASSERT_EQ(expected_encoding, context->EncodeContextForDex2oat(""));
}

TEST_F(ClassLoaderContextTest, EncodeContextsSinglePath) {
  jobject class_loader = LoadDexInPathClassLoader("Main", nullptr);
  std::unique_ptr<ClassLoaderContext> context =
      CreateContextForClassLoader(class_loader);

  std::map<std::string, std::string> encodings = context->EncodeClassPathContexts("");
  ASSERT_EQ(1u, encodings.size());
  ASSERT_EQ("PCL[]", encodings.at(GetTestDexFileName("Main")));
}

TEST_F(ClassLoaderContextTest, EncodeContextsMultiDex) {
  jobject class_loader = LoadDexInPathClassLoader("MultiDex", nullptr);
  std::unique_ptr<ClassLoaderContext> context =
      CreateContextForClassLoader(class_loader);

  std::map<std::string, std::string> encodings = context->EncodeClassPathContexts("");
  ASSERT_EQ(1u, encodings.size());
  ASSERT_EQ("PCL[]", encodings.at(GetTestDexFileName("MultiDex")));
}

TEST_F(ClassLoaderContextTest, EncodeContextsRepeatedMultiDex) {
  jobject top_class_loader = LoadDexInPathClassLoader("MultiDex", nullptr);
  jobject middle_class_loader =
      LoadDexInPathClassLoader("Main", top_class_loader);
  jobject bottom_class_loader =
      LoadDexInPathClassLoader("MultiDex", middle_class_loader);
  std::unique_ptr<ClassLoaderContext> context =
      CreateContextForClassLoader(bottom_class_loader);

  std::map<std::string, std::string> encodings = context->EncodeClassPathContexts("");
  ASSERT_EQ(1u, encodings.size());

  std::string main_dex_name = GetTestDexFileName("Main");
  std::string multidex_dex_name = GetTestDexFileName("MultiDex");
  ASSERT_EQ(
      "PCL[];PCL[" + main_dex_name + "];PCL[" + multidex_dex_name + "]",
      encodings.at(multidex_dex_name));
}

TEST_F(ClassLoaderContextTest, EncodeContextsSinglePathWithShared) {
  jobject class_loader_a = LoadDexInPathClassLoader("MyClass", nullptr);

  ScopedObjectAccess soa(Thread::Current());
  StackHandleScope<1> hs(soa.Self());
  Handle<mirror::ObjectArray<mirror::ClassLoader>> libraries = hs.NewHandle(
    mirror::ObjectArray<mirror::ClassLoader>::Alloc(
        soa.Self(),
        GetClassRoot<mirror::ObjectArray<mirror::ClassLoader>>(),
        1));
  libraries->Set(0, soa.Decode<mirror::ClassLoader>(class_loader_a));

  jobject class_loader_b = LoadDexInPathClassLoader(
      "Main", nullptr, soa.AddLocalReference<jobject>(libraries.Get()));

  std::unique_ptr<ClassLoaderContext> context = CreateContextForClassLoader(class_loader_b);

  std::map<std::string, std::string> encodings = context->EncodeClassPathContexts("");
  ASSERT_EQ(1u, encodings.size());
  ASSERT_EQ(
      "PCL[]{PCL[" + GetTestDexFileName("MyClass") + "]}",
      encodings.at(GetTestDexFileName("Main")));
}

TEST_F(ClassLoaderContextTest, EncodeContextsMultiplePaths) {
  jobject class_loader = LoadDexInPathClassLoader(
      std::vector<std::string>{ "Main", "MultiDex"}, nullptr);

  std::unique_ptr<ClassLoaderContext> context =
      CreateContextForClassLoader(class_loader);

  std::map<std::string, std::string> encodings = context->EncodeClassPathContexts("");
  ASSERT_EQ(2u, encodings.size());
  ASSERT_EQ("PCL[]", encodings.at(GetTestDexFileName("Main")));
  ASSERT_EQ(
      "PCL[" + GetTestDexFileName("Main") + "]", encodings.at(GetTestDexFileName("MultiDex")));
}

TEST_F(ClassLoaderContextTest, EncodeContextsMultiplePathsWithShared) {
  jobject class_loader_a = LoadDexInPathClassLoader("MyClass", nullptr);

  ScopedObjectAccess soa(Thread::Current());
  StackHandleScope<1> hs(soa.Self());
  Handle<mirror::ObjectArray<mirror::ClassLoader>> libraries = hs.NewHandle(
    mirror::ObjectArray<mirror::ClassLoader>::Alloc(
        soa.Self(),
        GetClassRoot<mirror::ObjectArray<mirror::ClassLoader>>(),
        1));
  libraries->Set(0, soa.Decode<mirror::ClassLoader>(class_loader_a));

  jobject class_loader_b = LoadDexInPathClassLoader(
      std::vector<std::string> { "Main", "MultiDex" },
      nullptr, soa.AddLocalReference<jobject>(libraries.Get()));

  std::unique_ptr<ClassLoaderContext> context =
      CreateContextForClassLoader(class_loader_b);

  std::map<std::string, std::string> encodings = context->EncodeClassPathContexts("");
  ASSERT_EQ(2u, encodings.size());
  const std::string context_suffix =
      "{PCL[" + GetTestDexFileName("MyClass") + "]}";
  ASSERT_EQ("PCL[]" + context_suffix, encodings.at(GetTestDexFileName("Main")));
  ASSERT_EQ(
      "PCL[" + GetTestDexFileName("Main") + "]" + context_suffix,
      encodings.at(GetTestDexFileName("MultiDex")));
}

TEST_F(ClassLoaderContextTest, EncodeContextsIMC) {
  jobject class_loader_a = LoadDexInPathClassLoader("Main", nullptr);
  jobject class_loader_b =
      LoadDexInInMemoryDexClassLoader("MyClass", class_loader_a);

  std::unique_ptr<ClassLoaderContext> context =
      CreateContextForClassLoader(class_loader_b);

  std::map<std::string, std::string> encodings = context->EncodeClassPathContexts("");
  ASSERT_EQ(1u, encodings.size());
  ASSERT_EQ(
      "IMC[];PCL[" + GetTestDexFileName("Main") + "]",
      encodings.at("<unknown>"));
}

TEST_F(ClassLoaderContextTest, EncodeContextsForSingleDex) {
  jobject class_loader = LoadDexInPathClassLoader("Main", nullptr);
  std::map<std::string, std::string> encodings =
      ClassLoaderContext::EncodeClassPathContextsForClassLoader(class_loader);
  ASSERT_EQ(1u, encodings.size());
  ASSERT_EQ("PCL[]", encodings.at(GetTestDexFileName("Main")));
}

static jobject CreateForeignClassLoader() {
  ScopedObjectAccess soa(Thread::Current());

  // We cannot instantiate a ClassLoader directly, so instead we allocate an Object to represent
  // our foreign ClassLoader (this works because the runtime does proper instanceof checks before
  // operating on this object.
  ArtMethod* ctor =
      GetClassRoot<mirror::Object>()->FindClassMethod("<init>", "()V", kRuntimePointerSize);
  CHECK(ctor != nullptr);
  return soa.AddLocalReference<jobject>(ctor->NewObject<>(soa.Self()));
}

TEST_F(ClassLoaderContextTest, EncodeContextsForUnsupportedBase) {
  std::map<std::string, std::string> empty;
  ASSERT_EQ(
      empty, ClassLoaderContext::EncodeClassPathContextsForClassLoader(CreateForeignClassLoader()));
}

TEST_F(ClassLoaderContextTest, EncodeContextsForUnsupportedChain) {
  jobject class_loader = LoadDexInPathClassLoader("Main", CreateForeignClassLoader());
  std::map<std::string, std::string> encodings =
      ClassLoaderContext::EncodeClassPathContextsForClassLoader(class_loader);
  ASSERT_EQ(1u, encodings.size());
  ASSERT_EQ(
      ClassLoaderContext::kUnsupportedClassLoaderContextEncoding,
      encodings.at(GetTestDexFileName("Main")));
}

TEST_F(ClassLoaderContextTest, EncodeContextsForUnsupportedChainMultiPath) {
  jobject class_loader = LoadDexInPathClassLoader(std::vector<std::string> { "Main", "MyClass" },
                                                  CreateForeignClassLoader());
  std::map<std::string, std::string> encodings =
      ClassLoaderContext::EncodeClassPathContextsForClassLoader(class_loader);
  ASSERT_EQ(2u, encodings.size());
  ASSERT_EQ(
      ClassLoaderContext::kUnsupportedClassLoaderContextEncoding,
      encodings.at(GetTestDexFileName("Main")));
  ASSERT_EQ(
      ClassLoaderContext::kUnsupportedClassLoaderContextEncoding,
      encodings.at(GetTestDexFileName("MyClass")));
}

TEST_F(ClassLoaderContextTest, EncodeContextsForUnsupportedChainMultiDex) {
  jobject class_loader = LoadDexInPathClassLoader("MultiDex", CreateForeignClassLoader());
  std::map<std::string, std::string> encodings =
      ClassLoaderContext::EncodeClassPathContextsForClassLoader(class_loader);
  ASSERT_EQ(1u, encodings.size());
  ASSERT_EQ(
      ClassLoaderContext::kUnsupportedClassLoaderContextEncoding,
      encodings.at(GetTestDexFileName("MultiDex")));
}

TEST_F(ClassLoaderContextTest, IsValidEncoding) {
  ASSERT_TRUE(ClassLoaderContext::IsValidEncoding("PCL[]"));
  ASSERT_TRUE(ClassLoaderContext::IsValidEncoding("PCL[foo.dex]"));
  ASSERT_TRUE(ClassLoaderContext::IsValidEncoding("PCL[foo.dex];PCL[bar.dex]"));
  ASSERT_TRUE(ClassLoaderContext::IsValidEncoding("DLC[];PCL[bar.dex]"));
  ASSERT_TRUE(
      ClassLoaderContext::IsValidEncoding(
        ClassLoaderContext::kUnsupportedClassLoaderContextEncoding));
  ASSERT_FALSE(ClassLoaderContext::IsValidEncoding("not_valid"));
  ASSERT_FALSE(ClassLoaderContext::IsValidEncoding("[]"));
  ASSERT_FALSE(ClassLoaderContext::IsValidEncoding("FCL[]"));
  ASSERT_FALSE(ClassLoaderContext::IsValidEncoding("foo.dex:bar.dex"));
}

// TODO(calin) add a test which creates the context for a class loader together with dex_elements.
TEST_F(ClassLoaderContextTest, CreateContextForClassLoader) {
  // The chain is
  //    ClassLoaderA (PathClassLoader)
  //       ^
  //       |
  //    ClassLoaderB (DelegateLastClassLoader)
  //       ^
  //       |
  //    ClassLoaderC (PathClassLoader)
  //       ^
  //       |
  //    ClassLoaderD (DelegateLastClassLoader)

  jobject class_loader_a = LoadDexInPathClassLoader("ForClassLoaderA", nullptr);
  jobject class_loader_b = LoadDexInDelegateLastClassLoader("ForClassLoaderB", class_loader_a);
  jobject class_loader_c = LoadDexInPathClassLoader("ForClassLoaderC", class_loader_b);
  jobject class_loader_d = LoadDexInDelegateLastClassLoader("ForClassLoaderD", class_loader_c);

  std::unique_ptr<ClassLoaderContext> context = CreateContextForClassLoader(class_loader_d);

  VerifyContextForClassLoader(context.get());
  VerifyContextSize(context.get(), 4);

  VerifyClassLoaderDLCFromTestDex(context.get(), 0, "ForClassLoaderD");
  VerifyClassLoaderPCLFromTestDex(context.get(), 1, "ForClassLoaderC");
  VerifyClassLoaderDLCFromTestDex(context.get(), 2, "ForClassLoaderB");
  VerifyClassLoaderPCLFromTestDex(context.get(), 3, "ForClassLoaderA");
}

TEST_F(ClassLoaderContextTest, CreateContextForClassLoaderIMC) {
  // The chain is
  //    ClassLoaderA (PathClassLoader)
  //       ^
  //       |
  //    ClassLoaderB (InMemoryDexClassLoader)
  //       ^
  //       |
  //    ClassLoaderC (InMemoryDexClassLoader)
  //       ^
  //       |
  //    ClassLoaderD (DelegateLastClassLoader)

  jobject class_loader_a = LoadDexInPathClassLoader("ForClassLoaderA", nullptr);
  jobject class_loader_b = LoadDexInInMemoryDexClassLoader("ForClassLoaderB", class_loader_a);
  jobject class_loader_c = LoadDexInInMemoryDexClassLoader("ForClassLoaderC", class_loader_b);
  jobject class_loader_d = LoadDexInDelegateLastClassLoader("ForClassLoaderD", class_loader_c);

  std::unique_ptr<ClassLoaderContext> context = CreateContextForClassLoader(class_loader_d);

  VerifyContextForClassLoader(context.get());
  VerifyContextSize(context.get(), 4);

  VerifyClassLoaderDLCFromTestDex(context.get(), 0, "ForClassLoaderD");
  VerifyClassLoaderIMCFromTestDex(context.get(), 1, "ForClassLoaderC");
  VerifyClassLoaderIMCFromTestDex(context.get(), 2, "ForClassLoaderB");
  VerifyClassLoaderPCLFromTestDex(context.get(), 3, "ForClassLoaderA");
}

TEST_F(ClassLoaderContextTest, VerifyClassLoaderContextMatch) {
  std::string context_spec = "PCL[a.dex*123:b.dex*456];DLC[c.dex*890]";
  std::unique_ptr<ClassLoaderContext> context = ParseContextWithChecksums(context_spec);
  // Pretend that we successfully open the dex files to pass the DCHECKS.
  // (as it's much easier to test all the corner cases without relying on actual dex files).
  PretendContextOpenedDexFilesForChecksums(context.get());

  VerifyContextSize(context.get(), 2);
  VerifyClassLoaderPCL(context.get(), 0, "a.dex:b.dex");
  VerifyClassLoaderDLC(context.get(), 1, "c.dex");

  ASSERT_EQ(context->VerifyClassLoaderContextMatch(context_spec),
            ClassLoaderContext::VerificationResult::kVerifies);

  std::string wrong_class_loader_type = "PCL[a.dex*123:b.dex*456];PCL[c.dex*890]";
  ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_class_loader_type),
            ClassLoaderContext::VerificationResult::kMismatch);

  std::string wrong_class_loader_order = "DLC[c.dex*890];PCL[a.dex*123:b.dex*456]";
  ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_class_loader_order),
            ClassLoaderContext::VerificationResult::kMismatch);

  std::string wrong_classpath_order = "PCL[b.dex*456:a.dex*123];DLC[c.dex*890]";
  ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_classpath_order),
            ClassLoaderContext::VerificationResult::kMismatch);

  std::string wrong_checksum = "PCL[a.dex*999:b.dex*456];DLC[c.dex*890]";
  ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_checksum),
            ClassLoaderContext::VerificationResult::kMismatch);

  std::string wrong_extra_class_loader = "PCL[a.dex*123:b.dex*456];DLC[c.dex*890];PCL[d.dex*321]";
  ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_extra_class_loader),
            ClassLoaderContext::VerificationResult::kMismatch);

  std::string wrong_extra_classpath = "PCL[a.dex*123:b.dex*456];DLC[c.dex*890:d.dex*321]";
  ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_extra_classpath),
            ClassLoaderContext::VerificationResult::kMismatch);

  std::string wrong_spec = "PCL[a.dex*999:b.dex*456];DLC[";
  ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_spec),
            ClassLoaderContext::VerificationResult::kMismatch);
}

TEST_F(ClassLoaderContextTest, VerifyClassLoaderContextWithIMCMatch) {
  std::string context_spec = "PCL[a.dex*123:b.dex*456];DLC[c.dex*890];IMC[<unknown>*111]";
  std::unique_ptr<ClassLoaderContext> context = ParseContextWithChecksums(context_spec);
  // Pretend that we successfully open the dex files to pass the DCHECKS.
  // (as it's much easier to test all the corner cases without relying on actual dex files).
  PretendContextOpenedDexFiles(context.get());

  VerifyContextSize(context.get(), 3);
  VerifyClassLoaderPCL(context.get(), 0, "a.dex:b.dex");
  VerifyClassLoaderDLC(context.get(), 1, "c.dex");
  VerifyClassLoaderIMC(context.get(), 2, "<unknown>");

  ASSERT_EQ(context->VerifyClassLoaderContextMatch(context_spec),
            ClassLoaderContext::VerificationResult::kVerifies);
}

TEST_F(ClassLoaderContextTest, VerifyClassLoaderContextMatchWithSL) {
  std::string context_spec =
      "PCL[a.dex*123:b.dex*456]{PCL[d.dex*321];PCL[e.dex*654]#PCL[f.dex*098:g.dex*999]}"
      ";DLC[c.dex*890]";
  std::unique_ptr<ClassLoaderContext> context = ParseContextWithChecksums(context_spec);
  // Pretend that we successfully open the dex files to pass the DCHECKS.
  // (as it's much easier to test all the corner cases without relying on actual dex files).
  PretendContextOpenedDexFiles(context.get());

  VerifyContextSize(context.get(), 2);
  VerifyClassLoaderPCL(context.get(), 0, "a.dex:b.dex");
  VerifyClassLoaderDLC(context.get(), 1, "c.dex");
  VerifyClassLoaderSharedLibraryPCL(context.get(), 0, 0, "d.dex");
  VerifyClassLoaderSharedLibraryPCL(context.get(), 0, 1, "f.dex:g.dex");

  ASSERT_EQ(context->VerifyClassLoaderContextMatch(context_spec),
            ClassLoaderContext::VerificationResult::kVerifies);

  std::string wrong_class_loader_type =
      "PCL[a.dex*123:b.dex*456]{DLC[d.dex*321];PCL[e.dex*654]#PCL[f.dex*098:g.dex*999]}"
      ";DLC[c.dex*890]";
  ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_class_loader_type),
            ClassLoaderContext::VerificationResult::kMismatch);

  std::string wrong_class_loader_order =
      "PCL[a.dex*123:b.dex*456]{PCL[f.dex#098:g.dex#999}#PCL[d.dex*321];PCL[e.dex*654]}"
      ";DLC[c.dex*890]";
  ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_class_loader_order),
            ClassLoaderContext::VerificationResult::kMismatch);

  std::string wrong_classpath_order =
      "PCL[a.dex*123:b.dex*456]{PCL[d.dex*321];PCL[e.dex*654]#PCL[g.dex*999:f.dex*098]}"
      ";DLC[c.dex*890]";
  ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_classpath_order),
            ClassLoaderContext::VerificationResult::kMismatch);

  std::string wrong_checksum =
      "PCL[a.dex*123:b.dex*456]{PCL[d.dex*333];PCL[e.dex*654]#PCL[g.dex*999:f.dex*098]}"
      ";DLC[c.dex*890]";
  ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_checksum),
            ClassLoaderContext::VerificationResult::kMismatch);

  std::string wrong_extra_class_loader =
      "PCL[a.dex*123:b.dex*456]"
      "{PCL[d.dex*321];PCL[e.dex*654]#PCL[f.dex*098:g.dex*999];PCL[i.dex#444]}"
      ";DLC[c.dex*890]";
  ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_extra_class_loader),
            ClassLoaderContext::VerificationResult::kMismatch);

  std::string wrong_extra_classpath =
      "PCL[a.dex*123:b.dex*456]{PCL[d.dex*321:i.dex#444];PCL[e.dex*654]#PCL[f.dex*098:g.dex*999]}"
      ";DLC[c.dex*890]";
  ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_extra_classpath),
            ClassLoaderContext::VerificationResult::kMismatch);
}

TEST_F(ClassLoaderContextTest, VerifyClassLoaderContextMatchWithIMCSL) {
  std::string context_spec =
      "IMC[<unknown>*123:<unknown>*456]"
      "{IMC[<unknown>*321];IMC[<unknown>*654]#IMC[<unknown>*098:<unknown>*999]};"
      "DLC[c.dex*890]";
  std::unique_ptr<ClassLoaderContext> context = ParseContextWithChecksums(context_spec);
  // Pretend that we successfully open the dex files to pass the DCHECKS.
  // (as it's much easier to test all the corner cases without relying on actual dex files).
  PretendContextOpenedDexFiles(context.get());

  VerifyContextSize(context.get(), 2);
  VerifyClassLoaderIMC(context.get(), 0, "<unknown>:<unknown>");
  VerifyClassLoaderDLC(context.get(), 1, "c.dex");
  VerifyClassLoaderSharedLibraryIMC(context.get(), 0, 0, "<unknown>");
  VerifyClassLoaderSharedLibraryIMC(context.get(), 0, 1, "<unknown>:<unknown>");

  ASSERT_EQ(context->VerifyClassLoaderContextMatch(context_spec),
            ClassLoaderContext::VerificationResult::kVerifies);
}

TEST_F(ClassLoaderContextTest, VerifyClassLoaderContextMatchAfterResolvingSymlinks) {
  {
    std::ofstream ofs(scratch_path_ + "/foo.jar");
    ASSERT_TRUE(ofs);
  }
  std::filesystem::create_directory_symlink(scratch_path_, scratch_path_ + "/bar");

  std::string context_spec =
      android::base::StringPrintf("PCL[%s/foo.jar*123:%s/foo.jar!classes2.dex*456]",
                                  scratch_path_.c_str(),
                                  scratch_path_.c_str());
  std::unique_ptr<ClassLoaderContext> context = ParseContextWithChecksums(context_spec);
  PretendContextOpenedDexFilesForChecksums(context.get());

  std::string context_spec_with_symlinks =
      android::base::StringPrintf("PCL[%s/bar/foo.jar*123:%s/bar/foo.jar!classes2.dex*456]",
                                  scratch_path_.c_str(),
                                  scratch_path_.c_str());
  ASSERT_EQ(context->VerifyClassLoaderContextMatch(context_spec_with_symlinks),
            ClassLoaderContext::VerificationResult::kVerifies);
}

TEST_F(ClassLoaderContextTest, VerifyClassLoaderContextMatchAfterEncoding) {
  jobject class_loader_a = LoadDexInPathClassLoader("ForClassLoaderA", nullptr);
  jobject class_loader_b = LoadDexInDelegateLastClassLoader("ForClassLoaderB", class_loader_a);
  jobject class_loader_c = LoadDexInPathClassLoader("ForClassLoaderC", class_loader_b);
  jobject class_loader_d = LoadDexInDelegateLastClassLoader("ForClassLoaderD", class_loader_c);

  std::unique_ptr<ClassLoaderContext> context = CreateContextForClassLoader(class_loader_d);

  std::string context_with_no_base_dir = context->EncodeContextForOatFile("");
  ASSERT_EQ(context->VerifyClassLoaderContextMatch(context_with_no_base_dir),
            ClassLoaderContext::VerificationResult::kVerifies);

  std::string dex_location = GetTestDexFileName("ForClassLoaderA");
  size_t pos = dex_location.rfind('/');
  ASSERT_NE(std::string::npos, pos);
  std::string parent = dex_location.substr(0, pos);

  std::string context_with_base_dir = context->EncodeContextForOatFile(parent);
  ASSERT_NE(context_with_base_dir, context_with_no_base_dir);
  ASSERT_EQ(context->VerifyClassLoaderContextMatch(context_with_base_dir),
            ClassLoaderContext::VerificationResult::kVerifies);
}

TEST_F(ClassLoaderContextTest, VerifyClassLoaderContextMatchAfterEncodingIMC) {
  jobject class_loader_a = LoadDexInPathClassLoader("ForClassLoaderA", nullptr);
  jobject class_loader_b = LoadDexInInMemoryDexClassLoader("ForClassLoaderB", class_loader_a);
  jobject class_loader_c = LoadDexInInMemoryDexClassLoader("ForClassLoaderC", class_loader_b);
  jobject class_loader_d = LoadDexInDelegateLastClassLoader("ForClassLoaderD", class_loader_c);

  std::unique_ptr<ClassLoaderContext> context = CreateContextForClassLoader(class_loader_d);

  std::string context_with_no_base_dir = context->EncodeContextForOatFile("");
  ASSERT_EQ(context->VerifyClassLoaderContextMatch(context_with_no_base_dir),
            ClassLoaderContext::VerificationResult::kVerifies);

  std::string dex_location = GetTestDexFileName("ForClassLoaderA");
  size_t pos = dex_location.rfind('/');
  ASSERT_NE(std::string::npos, pos);
  std::string parent = dex_location.substr(0, pos);

  std::string context_with_base_dir = context->EncodeContextForOatFile(parent);
  ASSERT_NE(context_with_base_dir, context_with_no_base_dir);
  ASSERT_EQ(context->VerifyClassLoaderContextMatch(context_with_base_dir),
            ClassLoaderContext::VerificationResult::kVerifies);
}

TEST_F(ClassLoaderContextTest, VerifyClassLoaderContextMatchAfterEncodingMultidex) {
  jobject class_loader = LoadDexInPathClassLoader("MultiDex", nullptr);

  std::unique_ptr<ClassLoaderContext> context = CreateContextForClassLoader(class_loader);

  std::string context_with_no_base_dir = context->EncodeContextForOatFile("");
  ASSERT_EQ(context->VerifyClassLoaderContextMatch(context_with_no_base_dir),
            ClassLoaderContext::VerificationResult::kVerifies);

  std::string dex_location = GetTestDexFileName("MultiDex");
  size_t pos = dex_location.rfind('/');
  ASSERT_NE(std::string::npos, pos);
  std::string parent = dex_location.substr(0, pos);

  std::string context_with_base_dir = context->EncodeContextForOatFile(parent);
  ASSERT_NE(context_with_base_dir, context_with_no_base_dir);
  ASSERT_EQ(context->VerifyClassLoaderContextMatch(context_with_base_dir),
            ClassLoaderContext::VerificationResult::kVerifies);
}

TEST_F(ClassLoaderContextTest, CreateContextForClassLoaderWithSharedLibraries) {
  jobject class_loader_a = LoadDexInPathClassLoader("ForClassLoaderA", nullptr);

  ScopedObjectAccess soa(Thread::Current());
  StackHandleScope<1> hs(soa.Self());
  Handle<mirror::ObjectArray<mirror::ClassLoader>> libraries = hs.NewHandle(
    mirror::ObjectArray<mirror::ClassLoader>::Alloc(
        soa.Self(),
        GetClassRoot<mirror::ObjectArray<mirror::ClassLoader>>(),
        1));
  libraries->Set(0, soa.Decode<mirror::ClassLoader>(class_loader_a));

  jobject class_loader_b = LoadDexInPathClassLoader(
      "ForClassLoaderB", nullptr, soa.AddLocalReference<jobject>(libraries.Get()));

  std::unique_ptr<ClassLoaderContext> context = CreateContextForClassLoader(class_loader_b);
  ASSERT_TRUE(context != nullptr);
  std::vector<std::unique_ptr<const DexFile>> dex_files = OpenTestDexFiles("ForClassLoaderB");
  VerifyClassLoaderPCL(context.get(), 0, dex_files[0]->GetLocation());
  dex_files = OpenTestDexFiles("ForClassLoaderA");
  VerifyClassLoaderSharedLibraryPCL(context.get(), 0, 0, dex_files[0]->GetLocation());

  ASSERT_EQ(context->VerifyClassLoaderContextMatch(context->EncodeContextForOatFile("")),
            ClassLoaderContext::VerificationResult::kVerifies);
}

TEST_F(ClassLoaderContextTest, CheckForDuplicateDexFilesNotFoundSingleCL) {
  jobject class_loader = LoadDexInPathClassLoader("Main", nullptr);

  std::unique_ptr<ClassLoaderContext> context = CreateContextForClassLoader(class_loader);

  std::set<const DexFile*> result = context->CheckForDuplicateDexFiles(
      std::vector<const DexFile*>());
  ASSERT_EQ(0u, result.size());

  std::vector<std::unique_ptr<const DexFile>> dex1 = OpenTestDexFiles("ForClassLoaderA");
  std::vector<const DexFile*> dex1_raw = MakeNonOwningPointerVector(dex1);
  result = context->CheckForDuplicateDexFiles(dex1_raw);
  ASSERT_EQ(0u, result.size());
}

TEST_F(ClassLoaderContextTest, CheckForDuplicateDexFilesFound) {
  jobject class_loader = LoadDexInPathClassLoader(std::vector<std::string> { "Main", "Main" }, nullptr);

  std::unique_ptr<ClassLoaderContext> context = CreateContextForClassLoader(class_loader);

  std::vector<std::unique_ptr<const DexFile>> dex1 = OpenTestDexFiles("Main");
  std::vector<const DexFile*> dex1_raw = MakeNonOwningPointerVector(dex1);
  std::set<const DexFile*> result = context->CheckForDuplicateDexFiles(dex1_raw);
  ASSERT_EQ(1u, result.size()) << context->EncodeContextForOatFile("");
  ASSERT_EQ(dex1_raw[0], *(result.begin()));
}


TEST_F(ClassLoaderContextTest, CheckForDuplicateCrossCLNotFound) {
  jobject class_loader_a = LoadDexInPathClassLoader("ForClassLoaderA", nullptr);
  jobject class_loader_b = LoadDexInInMemoryDexClassLoader("ForClassLoaderB", class_loader_a);

  std::unique_ptr<ClassLoaderContext> context = CreateContextForClassLoader(class_loader_b);

  std::vector<std::unique_ptr<const DexFile>> dex1 = OpenTestDexFiles("ForClassLoaderA");
  std::vector<const DexFile*> dex1_raw = MakeNonOwningPointerVector(dex1);
  std::set<const DexFile*> result = context->CheckForDuplicateDexFiles(dex1_raw);
  ASSERT_EQ(0u, result.size());
}

}  // namespace art
