/*
 * 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 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, info.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]};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");
  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
