/*
 * 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 "android-base/strings.h"
#include "art_field-inl.h"
#include "base/dchecked_vector.h"
#include "base/stl_util.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_file_assistant.h"
#include "runtime.h"
#include "scoped_thread_state_change-inl.h"
#include "thread.h"
#include "well_known_classes.h"

namespace art {

class ClassLoaderContextTest : public CommonRuntimeTest {
 public:
  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);
    ASSERT_EQ(all_dex_files->size(), info.classpath.size());
    ASSERT_EQ(all_dex_files->size(), info.checksums.size());
    if (only_read_checksums) {
      ASSERT_EQ(0u, info.opened_dex_files.size());
    } else {
      ASSERT_EQ(all_dex_files->size(), info.opened_dex_files.size());
    }

    for (size_t k = 0, cur_open_dex_index = 0;
         k < all_dex_files->size();
         k++, cur_open_dex_index++) {
      const std::string& opened_location = only_read_checksums
          ? info.classpath[cur_open_dex_index]
          : info.opened_dex_files[cur_open_dex_index]->GetLocation();
      uint32_t opened_checksum = only_read_checksums
          ? info.checksums[cur_open_dex_index]
          : info.opened_dex_files[cur_open_dex_index]->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_EQ(0, expected_location.compare(
            expected_location.length() - opened_location.length(),
            opened_location.length(),
            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(ScopedObjectAccess& soa,
                                 Handle<mirror::ClassLoader> class_loader,
                                 jclass type,
                                 std::vector<const DexFile*>& expected_dex_files)
      REQUIRES_SHARED(Locks::mutator_lock_) {
    ASSERT_TRUE(class_loader->GetClass() == soa.Decode<mirror::Class>(type));

    std::vector<const DexFile*> class_loader_dex_files = GetDexFiles(soa, 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;
  }

 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() ==
      soa.Decode<mirror::Class>(WellKnownClasses::dalvik_system_PathClassLoader));
  ASSERT_TRUE(class_loader->GetParent()->GetClass() ==
      soa.Decode<mirror::Class>(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,
                            class_loader,
                            WellKnownClasses::dalvik_system_PathClassLoader,
                            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,
                            class_loader,
                            WellKnownClasses::dalvik_system_PathClassLoader,
                            compilation_sources_raw);
  ASSERT_TRUE(class_loader->GetParent()->GetClass() ==
      soa.Decode<mirror::Class>(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,
                            class_loader_1,
                            WellKnownClasses::dalvik_system_PathClassLoader,
                            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,
                            class_loader_2,
                            WellKnownClasses::dalvik_system_DelegateLastClassLoader,
                            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,
                            class_loader_3,
                            WellKnownClasses::dalvik_system_PathClassLoader,
                            class_loader_3_dex_files);
  // The last class loader should have the BootClassLoader as a parent.
  ASSERT_TRUE(class_loader_3->GetParent()->GetClass() ==
      soa.Decode<mirror::Class>(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,
                            class_loader_1,
                            WellKnownClasses::dalvik_system_PathClassLoader,
                            class_loader_1_dex_files);

  // Verify the shared libraries.
  ArtField* field =
      jni::DecodeArtField(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,
                            class_loader_2,
                            WellKnownClasses::dalvik_system_DelegateLastClassLoader,
                            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,
                            class_loader_3,
                            WellKnownClasses::dalvik_system_PathClassLoader,
                            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() ==
      soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader));
  ASSERT_TRUE(class_loader_2->GetParent()->GetClass() ==
      soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader));
  ASSERT_TRUE(class_loader_3->GetParent()->GetClass() ==
      soa.Decode<mirror::Class>(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,
                            class_loader_1,
                            WellKnownClasses::dalvik_system_PathClassLoader,
                            class_loader_1_dex_files);

  // Verify its shared library.
  ArtField* field =
      jni::DecodeArtField(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,
                            class_loader_2,
                            WellKnownClasses::dalvik_system_PathClassLoader,
                            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,
                            class_loader_3,
                            WellKnownClasses::dalvik_system_PathClassLoader,
                            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,
                            class_loader_4,
                            WellKnownClasses::dalvik_system_PathClassLoader,
                            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() ==
      soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader));
  ASSERT_TRUE(class_loader_3->GetParent()->GetClass() ==
      soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader));
  ASSERT_TRUE(class_loader_4->GetParent()->GetClass() ==
      soa.Decode<mirror::Class>(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,
                            class_loader_1,
                            WellKnownClasses::dalvik_system_PathClassLoader,
                            class_loader_1_dex_files);

  // Verify its shared library.
  ArtField* field =
      jni::DecodeArtField(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,
                            class_loader_2,
                            WellKnownClasses::dalvik_system_PathClassLoader,
                            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,
                            class_loader_3,
                            WellKnownClasses::dalvik_system_PathClassLoader,
                            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,
                            class_loader_4,
                            WellKnownClasses::dalvik_system_PathClassLoader,
                            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() ==
      soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader));
  ASSERT_TRUE(class_loader_3->GetParent()->GetClass() ==
      soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader));
  ASSERT_TRUE(class_loader_4->GetParent()->GetClass() ==
      soa.Decode<mirror::Class>(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,
                            class_loader_1,
                            WellKnownClasses::dalvik_system_PathClassLoader,
                            class_loader_1_dex_files);

  // Verify its shared library.
  ArtField* field =
      jni::DecodeArtField(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,
                            class_loader_2,
                            WellKnownClasses::dalvik_system_PathClassLoader,
                            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,
                            class_loader_3,
                            WellKnownClasses::dalvik_system_PathClassLoader,
                            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() ==
      soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader));
  ASSERT_TRUE(class_loader_3->GetParent()->GetClass() ==
      soa.Decode<mirror::Class>(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(""));
}

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);

  std::string encoding = context->EncodeContextForOatFile("");
  std::string expected_encoding = "IMC[<unknown>*" + std::to_string(dex2[0]->GetLocationChecksum())
      + "];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, 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());
  JNIEnv* env = soa.Env();

  // 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.
  jmethodID ctor = env->GetMethodID(WellKnownClasses::java_lang_Object, "<init>", "()V");
  return env->NewObject(WellKnownClasses::java_lang_Object, ctor);
}

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, 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
