/*
 * 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 <fstream>
#include <regex>
#include <sstream>
#include <string>
#include <vector>

#include <sys/mman.h>
#include <sys/wait.h>
#include <unistd.h>

#include <android-base/logging.h>
#include <android-base/stringprintf.h>
#include <android-base/strings.h>

#include "common_runtime_test.h"

#include "base/array_ref.h"
#include "base/file_utils.h"
#include "base/macros.h"
#include "base/mem_map.h"
#include "base/string_view_cpp20.h"
#include "base/unix_file/fd_file.h"
#include "base/utils.h"
#include "dex/art_dex_file_loader.h"
#include "dex/dex_file-inl.h"
#include "dex/dex_file_loader.h"
#include "dex/method_reference.h"
#include "dex/type_reference.h"
#include "gc/space/image_space.h"
#include "runtime.h"
#include "scoped_thread_state_change-inl.h"
#include "thread-current-inl.h"

namespace art {

// A suitable address for loading the core images.
constexpr uint32_t kBaseAddress = ART_BASE_ADDRESS;

struct ImageSizes {
  size_t art_size = 0;
  size_t oat_size = 0;
  size_t vdex_size = 0;
};

std::ostream& operator<<(std::ostream& os, const ImageSizes& sizes) {
  os << "art=" << sizes.art_size << " oat=" << sizes.oat_size << " vdex=" << sizes.vdex_size;
  return os;
}

class Dex2oatImageTest : public CommonRuntimeTest {
 public:
  void TearDown() override {}

 protected:
  void SetUpRuntimeOptions(RuntimeOptions* options) override {
    // Disable implicit dex2oat invocations when loading image spaces.
    options->emplace_back("-Xnoimage-dex2oat", nullptr);
  }

  static void WriteLine(File* file, std::string line) {
    line += '\n';
    EXPECT_TRUE(file->WriteFully(&line[0], line.length()));
  }

  void AddRuntimeArg(std::vector<std::string>& args, const std::string& arg) {
    args.push_back("--runtime-arg");
    args.push_back(arg);
  }

  ImageSizes CompileImageAndGetSizes(ArrayRef<const std::string> dex_files,
                                     const std::vector<std::string>& extra_args) {
    ImageSizes ret;
    ScratchDir scratch;
    std::string filename_prefix = scratch.GetPath() + "boot";
    std::vector<std::string> local_extra_args = extra_args;
    local_extra_args.push_back(android::base::StringPrintf("--base=0x%08x", kBaseAddress));
    std::string error_msg;
    if (!CompileBootImage(local_extra_args, filename_prefix, dex_files, &error_msg)) {
      LOG(ERROR) << "Failed to compile image " << filename_prefix << error_msg;
    }
    std::string art_file = filename_prefix + ".art";
    std::string oat_file = filename_prefix + ".oat";
    std::string vdex_file = filename_prefix + ".vdex";
    int64_t art_size = OS::GetFileSizeBytes(art_file.c_str());
    int64_t oat_size = OS::GetFileSizeBytes(oat_file.c_str());
    int64_t vdex_size = OS::GetFileSizeBytes(vdex_file.c_str());
    CHECK_GT(art_size, 0u) << art_file;
    CHECK_GT(oat_size, 0u) << oat_file;
    CHECK_GT(vdex_size, 0u) << vdex_file;
    ret.art_size = art_size;
    ret.oat_size = oat_size;
    ret.vdex_size = vdex_size;
    return ret;
  }

  MemMap ReserveCoreImageAddressSpace(/*out*/std::string* error_msg) {
    constexpr size_t kReservationSize = 256 * MB;  // This should be enough for the compiled images.
    // Extend to both directions for maximum relocation difference.
    static_assert(ART_BASE_ADDRESS_MIN_DELTA < 0);
    static_assert(ART_BASE_ADDRESS_MAX_DELTA > 0);
    static_assert(IsAligned<kElfSegmentAlignment>(ART_BASE_ADDRESS_MIN_DELTA));
    static_assert(IsAligned<kElfSegmentAlignment>(ART_BASE_ADDRESS_MAX_DELTA));
    constexpr size_t kExtra = ART_BASE_ADDRESS_MAX_DELTA - ART_BASE_ADDRESS_MIN_DELTA;
    uint32_t min_relocated_address = kBaseAddress + ART_BASE_ADDRESS_MIN_DELTA;
    return MemMap::MapAnonymous("Reservation",
                                reinterpret_cast<uint8_t*>(min_relocated_address),
                                kReservationSize + kExtra,
                                PROT_NONE,
                                /*low_4gb=*/ true,
                                /*reuse=*/ false,
                                /*reservation=*/ nullptr,
                                error_msg);
  }

  void CopyDexFiles(const std::string& dir, /*inout*/std::vector<std::string>* dex_files) {
    CHECK(EndsWith(dir, "/"));
    for (std::string& dex_file : *dex_files) {
      size_t slash_pos = dex_file.rfind('/');
      CHECK(OS::FileExists(dex_file.c_str())) << dex_file;
      CHECK_NE(std::string::npos, slash_pos);
      std::string new_location = dir + dex_file.substr(slash_pos + 1u);
      std::ifstream src_stream(dex_file, std::ios::binary);
      std::ofstream dst_stream(new_location, std::ios::binary);
      dst_stream << src_stream.rdbuf();
      dex_file = new_location;
    }
  }

  bool CompareFiles(const std::string& filename1, const std::string& filename2) {
    std::unique_ptr<File> file1(OS::OpenFileForReading(filename1.c_str()));
    std::unique_ptr<File> file2(OS::OpenFileForReading(filename2.c_str()));
    // Did we open the files?
    if (file1 == nullptr || file2 == nullptr) {
      return false;
    }
    // Are they non-empty and the same length?
    if (file1->GetLength() <= 0 || file2->GetLength() != file1->GetLength()) {
      return false;
    }
    return file1->Compare(file2.get()) == 0;
  }

  void AddAndroidRootToImageCompilerOptions() {
    const char* android_root = getenv("ANDROID_ROOT");
    CHECK(android_root != nullptr);
    Runtime::Current()->image_compiler_options_.push_back(
        "--android-root=" + std::string(android_root));
  }

  void EnableImageDex2Oat() {
    Runtime::Current()->image_dex2oat_enabled_ = true;
  }

  void DisableImageDex2Oat() {
    Runtime::Current()->image_dex2oat_enabled_ = false;
  }
};

TEST_F(Dex2oatImageTest, TestModesAndFilters) {
  // This test crashes on the gtest-heap-poisoning configuration
  // (AddressSanitizer + CMS/RosAlloc + heap-poisoning); see b/111061592.
  // Temporarily disable this test on this configuration to keep
  // our automated build/testing green while we work on a fix.
  TEST_DISABLED_FOR_MEMORY_TOOL_WITH_HEAP_POISONING_WITHOUT_READ_BARRIERS();
  if (kIsTargetBuild) {
    // This test is too slow for target builds.
    return;
  }
  // Compile only a subset of the libcore dex files to make this test shorter.
  std::vector<std::string> libcore_dex_files = GetLibCoreDexFileNames();
  // The primary image must contain at least core-oj and core-libart to initialize the runtime.
  ASSERT_NE(std::string::npos, libcore_dex_files[0].find("core-oj"));
  ASSERT_NE(std::string::npos, libcore_dex_files[1].find("core-libart"));
  ArrayRef<const std::string> dex_files =
      ArrayRef<const std::string>(libcore_dex_files).SubArray(/*pos=*/ 0u, /*length=*/ 2u);

  ImageSizes base_sizes = CompileImageAndGetSizes(dex_files, {});
  ImageSizes everything_sizes;
  ImageSizes filter_sizes;
  std::cout << "Base compile sizes " << base_sizes << std::endl;
  // Compile all methods and classes
  std::vector<std::string> libcore_dexes = GetLibCoreDexFileNames();
  ArrayRef<const std::string> libcore_dexes_array(libcore_dexes);
  {
    ScratchFile profile_file;
    GenerateBootProfile(libcore_dexes_array,
                        profile_file.GetFile(),
                        /*method_frequency=*/ 1u,
                        /*type_frequency=*/ 1u);
    everything_sizes = CompileImageAndGetSizes(
        dex_files,
        {"--profile-file=" + profile_file.GetFilename(),
         "--compiler-filter=speed-profile"});
    profile_file.Close();
    std::cout << "All methods and classes sizes " << everything_sizes << std::endl;
    // Putting all classes as image classes should increase art size
    EXPECT_GE(everything_sizes.art_size, base_sizes.art_size);
    // Check that dex is the same size.
    EXPECT_EQ(everything_sizes.vdex_size, base_sizes.vdex_size);
  }
  static size_t kMethodFrequency = 3;
  static size_t kTypeFrequency = 4;
  // Test compiling fewer methods and classes.
  {
    ScratchFile profile_file;
    GenerateBootProfile(libcore_dexes_array,
                        profile_file.GetFile(),
                        kMethodFrequency,
                        kTypeFrequency);
    filter_sizes = CompileImageAndGetSizes(
        dex_files,
        {"--profile-file=" + profile_file.GetFilename(),
         "--compiler-filter=speed-profile"});
    profile_file.Close();
    std::cout << "Fewer methods and classes sizes " << filter_sizes << std::endl;
    EXPECT_LE(filter_sizes.art_size, everything_sizes.art_size);
    EXPECT_LE(filter_sizes.oat_size, everything_sizes.oat_size);
    EXPECT_LE(filter_sizes.vdex_size, everything_sizes.vdex_size);
  }
  // Test dirty image objects.
  {
    ScratchFile classes;
    VisitDexes(libcore_dexes_array,
               VoidFunctor(),
               [&](TypeReference ref) {
      WriteLine(classes.GetFile(), ref.dex_file->PrettyType(ref.TypeIndex()));
    }, /*method_frequency=*/ 1u, /*class_frequency=*/ 1u);
    ImageSizes image_classes_sizes = CompileImageAndGetSizes(
        dex_files,
        {"--dirty-image-objects=" + classes.GetFilename()});
    classes.Close();
    std::cout << "Dirty image object sizes " << image_classes_sizes << std::endl;
  }
}

TEST_F(Dex2oatImageTest, TestExtension) {
  std::string error_msg;
  MemMap reservation = ReserveCoreImageAddressSpace(&error_msg);
  ASSERT_TRUE(reservation.IsValid()) << error_msg;

  ScratchDir scratch;
  const std::string& scratch_dir = scratch.GetPath();
  std::string image_dir = scratch_dir + GetInstructionSetString(kRuntimeISA);
  int mkdir_result = mkdir(image_dir.c_str(), 0700);
  ASSERT_EQ(0, mkdir_result);
  std::string filename_prefix = image_dir + "/boot";

  // Copy the libcore dex files to a custom dir inside `scratch_dir` so that we do not
  // accidentally load pre-compiled core images from their original directory based on BCP paths.
  std::string jar_dir = scratch_dir + "jars";
  mkdir_result = mkdir(jar_dir.c_str(), 0700);
  ASSERT_EQ(0, mkdir_result);
  jar_dir += '/';
  std::vector<std::string> libcore_dex_files = GetLibCoreDexFileNames();
  CopyDexFiles(jar_dir, &libcore_dex_files);

  ArrayRef<const std::string> full_bcp(libcore_dex_files);
  size_t total_dex_files = full_bcp.size();
  ASSERT_GE(total_dex_files, 4u);  // 2 for "head", 1 for "tail", at least one for "mid", see below.

  // The primary image must contain at least core-oj and core-libart to initialize the runtime.
  ASSERT_NE(std::string::npos, full_bcp[0].find("core-oj"));
  ASSERT_NE(std::string::npos, full_bcp[1].find("core-libart"));
  ArrayRef<const std::string> head_dex_files = full_bcp.SubArray(/*pos=*/ 0u, /*length=*/ 2u);
  // Middle part is everything else except for conscrypt.
  ASSERT_NE(std::string::npos, full_bcp[full_bcp.size() - 1u].find("conscrypt"));
  ArrayRef<const std::string> mid_bcp =
      full_bcp.SubArray(/*pos=*/ 0u, /*length=*/ total_dex_files - 1u);
  ArrayRef<const std::string> mid_dex_files = mid_bcp.SubArray(/*pos=*/ 2u);
  // Tail is just the conscrypt.
  ArrayRef<const std::string> tail_dex_files =
      full_bcp.SubArray(/*pos=*/ total_dex_files - 1u, /*length=*/ 1u);

  // Prepare the "head", "mid" and "tail" names and locations.
  std::string base_name = "boot.art";
  std::string base_location = scratch_dir + base_name;
  std::vector<std::string> expanded_mid = gc::space::ImageSpace::ExpandMultiImageLocations(
      mid_dex_files.SubArray(/*pos=*/ 0u, /*length=*/ 1u),
      base_location,
      /*boot_image_extension=*/ true);
  CHECK_EQ(1u, expanded_mid.size());
  std::string mid_location = expanded_mid[0];
  size_t mid_slash_pos = mid_location.rfind('/');
  ASSERT_NE(std::string::npos, mid_slash_pos);
  std::string mid_name = mid_location.substr(mid_slash_pos + 1u);
  CHECK_EQ(1u, tail_dex_files.size());
  std::vector<std::string> expanded_tail = gc::space::ImageSpace::ExpandMultiImageLocations(
      tail_dex_files, base_location, /*boot_image_extension=*/ true);
  CHECK_EQ(1u, expanded_tail.size());
  std::string tail_location = expanded_tail[0];
  size_t tail_slash_pos = tail_location.rfind('/');
  ASSERT_NE(std::string::npos, tail_slash_pos);
  std::string tail_name = tail_location.substr(tail_slash_pos + 1u);

  // Create profiles.
  ScratchFile head_profile_file;
  GenerateBootProfile(head_dex_files,
                      head_profile_file.GetFile(),
                      /*method_frequency=*/ 1u,
                      /*type_frequency=*/ 1u);
  const std::string& head_profile_filename = head_profile_file.GetFilename();
  ScratchFile mid_profile_file;
  GenerateBootProfile(mid_dex_files,
                      mid_profile_file.GetFile(),
                      /*method_frequency=*/ 5u,
                      /*type_frequency=*/ 4u);
  const std::string& mid_profile_filename = mid_profile_file.GetFilename();
  ScratchFile tail_profile_file;
  GenerateBootProfile(tail_dex_files,
                      tail_profile_file.GetFile(),
                      /*method_frequency=*/ 5u,
                      /*type_frequency=*/ 4u);
  const std::string& tail_profile_filename = tail_profile_file.GetFilename();

  // Compile the "head", i.e. the primary boot image.
  std::vector<std::string> extra_args;
  extra_args.push_back("--profile-file=" + head_profile_filename);
  extra_args.push_back(android::base::StringPrintf("--base=0x%08x", kBaseAddress));
  bool head_ok = CompileBootImage(extra_args, filename_prefix, head_dex_files, &error_msg);
  ASSERT_TRUE(head_ok) << error_msg;

  // Compile the "mid", i.e. the first extension.
  std::string mid_bcp_string = android::base::Join(mid_bcp, ':');
  extra_args.clear();
  extra_args.push_back("--profile-file=" + mid_profile_filename);
  AddRuntimeArg(extra_args, "-Xbootclasspath:" + mid_bcp_string);
  AddRuntimeArg(extra_args, "-Xbootclasspath-locations:" + mid_bcp_string);
  extra_args.push_back("--boot-image=" + base_location);
  bool mid_ok = CompileBootImage(extra_args, filename_prefix, mid_dex_files, &error_msg);
  ASSERT_TRUE(mid_ok) << error_msg;

  // Try to compile the "tail" without specifying the "mid" extension. This shall fail.
  extra_args.clear();
  extra_args.push_back("--profile-file=" + tail_profile_filename);
  std::string full_bcp_string = android::base::Join(full_bcp, ':');
  AddRuntimeArg(extra_args, "-Xbootclasspath:" + full_bcp_string);
  AddRuntimeArg(extra_args, "-Xbootclasspath-locations:" + full_bcp_string);
  extra_args.push_back("--boot-image=" + base_location);
  bool tail_ok = CompileBootImage(extra_args, filename_prefix, tail_dex_files, &error_msg);
  ASSERT_FALSE(tail_ok) << error_msg;

  // Now compile the tail against both "head" and "mid".
  CHECK(StartsWith(extra_args.back(), "--boot-image="));
  extra_args.back() = "--boot-image=" + base_location + ':' + mid_location;
  tail_ok = CompileBootImage(extra_args, filename_prefix, tail_dex_files, &error_msg);
  ASSERT_TRUE(tail_ok) << error_msg;

  // Prepare directory for the single-image test that squashes the "mid" and "tail".
  std::string single_dir = scratch_dir + "single";
  mkdir_result = mkdir(single_dir.c_str(), 0700);
  ASSERT_EQ(0, mkdir_result);
  single_dir += '/';
  std::string single_image_dir = single_dir + GetInstructionSetString(kRuntimeISA);
  mkdir_result = mkdir(single_image_dir.c_str(), 0700);
  ASSERT_EQ(0, mkdir_result);
  std::string single_filename_prefix = single_image_dir + "/boot";

  // The dex files for the single-image are everything not in the "head".
  ArrayRef<const std::string> single_dex_files = full_bcp.SubArray(/*pos=*/ head_dex_files.size());

  // Create a smaller profile for the single-image test that squashes the "mid" and "tail".
  ScratchFile single_profile_file;
  GenerateBootProfile(single_dex_files,
                      single_profile_file.GetFile(),
                      /*method_frequency=*/ 5u,
                      /*type_frequency=*/ 4u);
  const std::string& single_profile_filename = single_profile_file.GetFilename();

  // Prepare the single image name and location.
  CHECK_GE(single_dex_files.size(), 2u);
  std::string single_base_location = single_dir + base_name;
  std::vector<std::string> expanded_single = gc::space::ImageSpace::ExpandMultiImageLocations(
      single_dex_files.SubArray(/*pos=*/ 0u, /*length=*/ 1u),
      single_base_location,
      /*boot_image_extension=*/ true);
  CHECK_EQ(1u, expanded_single.size());
  std::string single_location = expanded_single[0];
  size_t single_slash_pos = single_location.rfind('/');
  ASSERT_NE(std::string::npos, single_slash_pos);
  std::string single_name = single_location.substr(single_slash_pos + 1u);
  CHECK_EQ(single_name, mid_name);

  // Compile the single-image against the primary boot image.
  extra_args.clear();
  extra_args.push_back("--profile-file=" + single_profile_filename);
  AddRuntimeArg(extra_args, "-Xbootclasspath:" + full_bcp_string);
  AddRuntimeArg(extra_args, "-Xbootclasspath-locations:" + full_bcp_string);
  extra_args.push_back("--boot-image=" + base_location);
  extra_args.push_back("--single-image");
  extra_args.push_back("--avoid-storing-invocation");  // For comparison below.
  error_msg.clear();
  bool single_ok =
      CompileBootImage(extra_args, single_filename_prefix, single_dex_files, &error_msg);
  ASSERT_TRUE(single_ok) << error_msg;

  reservation = MemMap::Invalid();  // Free the reserved memory for loading images.

  // Try to load the boot image with different image locations.
  std::vector<std::string> boot_class_path = libcore_dex_files;
  std::vector<std::unique_ptr<gc::space::ImageSpace>> boot_image_spaces;
  bool relocate = false;
  MemMap extra_reservation;
  auto load = [&](const std::string& image_location) {
    boot_image_spaces.clear();
    extra_reservation = MemMap::Invalid();
    ScopedObjectAccess soa(Thread::Current());
    return gc::space::ImageSpace::LoadBootImage(
        /*boot_class_path=*/boot_class_path,
        /*boot_class_path_locations=*/libcore_dex_files,
        /*boot_class_path_files=*/{},
        /*boot_class_path_image_files=*/{},
        /*boot_class_path_vdex_files=*/{},
        /*boot_class_path_oat_files=*/{},
        android::base::Split(image_location, ":"),
        kRuntimeISA,
        relocate,
        /*executable=*/true,
        /*extra_reservation_size=*/0u,
        /*allow_in_memory_compilation=*/true,
        Runtime::GetApexVersions(ArrayRef<const std::string>(libcore_dex_files)),
        &boot_image_spaces,
        &extra_reservation);
  };
  auto silent_load = [&](const std::string& image_location) {
    ScopedLogSeverity quiet(LogSeverity::FATAL);
    return load(image_location);
  };

  for (bool r : { false, true }) {
    relocate = r;

    // Load primary image with full path.
    bool load_ok = load(base_location);
    ASSERT_TRUE(load_ok) << error_msg;
    ASSERT_FALSE(extra_reservation.IsValid());
    ASSERT_EQ(head_dex_files.size(), boot_image_spaces.size());

    // Fail to load primary image with just the name.
    load_ok = silent_load(base_name);
    ASSERT_FALSE(load_ok);

    // Fail to load primary image with a search path.
    load_ok = silent_load("*");
    ASSERT_FALSE(load_ok);
    load_ok = silent_load(scratch_dir + "*");
    ASSERT_FALSE(load_ok);

    // Load the primary and first extension with full path.
    load_ok = load(ART_FORMAT("{}:{}", base_location, mid_location));
    ASSERT_TRUE(load_ok) << error_msg;
    ASSERT_EQ(mid_bcp.size(), boot_image_spaces.size());

    // Load the primary with full path and fail to load first extension without full path.
    load_ok = load(ART_FORMAT("{}:{}", base_location, mid_name));
    ASSERT_TRUE(load_ok) << error_msg;  // Primary image loaded successfully.
    ASSERT_EQ(head_dex_files.size(), boot_image_spaces.size());  // But only the primary image.

    // Load all the libcore images with full paths.
    load_ok = load(ART_FORMAT("{}:{}:{}", base_location, mid_location, tail_location));
    ASSERT_TRUE(load_ok) << error_msg;
    ASSERT_EQ(full_bcp.size(), boot_image_spaces.size());

    // Load the primary and first extension with full paths, fail to load second extension by name.
    load_ok = load(ART_FORMAT("{}:{}:{}", base_location, mid_location, tail_name));
    ASSERT_TRUE(load_ok) << error_msg;
    ASSERT_EQ(mid_bcp.size(), boot_image_spaces.size());

    // Load the primary with full path and fail to load first extension without full path,
    // fail to load second extension because it depends on the first.
    load_ok = load(ART_FORMAT("{}:{}:{}", base_location, mid_name, tail_location));
    ASSERT_TRUE(load_ok) << error_msg;  // Primary image loaded successfully.
    ASSERT_EQ(head_dex_files.size(), boot_image_spaces.size());  // But only the primary image.

    // Load the primary with full path and extensions with a specified search path.
    load_ok = load(ART_FORMAT("{}:{}*", base_location, scratch_dir));
    ASSERT_TRUE(load_ok) << error_msg;
    ASSERT_EQ(full_bcp.size(), boot_image_spaces.size());

    // Load the primary with full path and fail to find extensions in BCP path.
    load_ok = load(base_location + ":*");
    ASSERT_TRUE(load_ok) << error_msg;
    ASSERT_EQ(head_dex_files.size(), boot_image_spaces.size());
  }

  // Now copy the libcore dex files to the `scratch_dir` and retry loading the boot image
  // with BCP in the scratch_dir so that the images can be found based on BCP paths.
  CopyDexFiles(scratch_dir, &boot_class_path);

  for (bool r : { false, true }) {
    relocate = r;

    // Loading the primary image with just the name now succeeds.
    bool load_ok = load(base_name);
    ASSERT_TRUE(load_ok) << error_msg;
    ASSERT_EQ(head_dex_files.size(), boot_image_spaces.size());

    // Loading the primary image with a search path still fails.
    load_ok = silent_load("*");
    ASSERT_FALSE(load_ok);
    load_ok = silent_load(scratch_dir + "*");
    ASSERT_FALSE(load_ok);

    // Load the primary and first extension without paths.
    load_ok = load(ART_FORMAT("{}:{}", base_name, mid_name));
    ASSERT_TRUE(load_ok) << error_msg;
    ASSERT_EQ(mid_bcp.size(), boot_image_spaces.size());

    // Load the primary without path and first extension with path.
    load_ok = load(ART_FORMAT("{}:{}", base_name, mid_location));
    ASSERT_TRUE(load_ok) << error_msg;
    ASSERT_EQ(mid_bcp.size(), boot_image_spaces.size());

    // Load the primary with full path and the first extension without full path.
    load_ok = load(ART_FORMAT("{}:{}", base_location, mid_name));
    ASSERT_TRUE(load_ok) << error_msg;  // Loaded successfully.
    ASSERT_EQ(mid_bcp.size(), boot_image_spaces.size());  // Including the extension.

    // Load all the libcore images without paths.
    load_ok = load(ART_FORMAT("{}:{}:{}", base_name, mid_name, tail_name));
    ASSERT_TRUE(load_ok) << error_msg;
    ASSERT_EQ(full_bcp.size(), boot_image_spaces.size());

    // Load the primary and first extension with full paths and second extension by name.
    load_ok = load(ART_FORMAT("{}:{}:{}", base_location, mid_location, tail_name));
    ASSERT_TRUE(load_ok) << error_msg;
    ASSERT_EQ(full_bcp.size(), boot_image_spaces.size());

    // Load the primary with full path, first extension without path,
    // and second extension with full path.
    load_ok = load(ART_FORMAT("{}:{}:{}", base_location, mid_name, tail_location));
    ASSERT_TRUE(load_ok) << error_msg;  // Loaded successfully.
    ASSERT_EQ(full_bcp.size(), boot_image_spaces.size());  // Including both extensions.

    // Load the primary with full path and find both extensions in BCP path.
    load_ok = load(base_location + ":*");
    ASSERT_TRUE(load_ok) << error_msg;
    ASSERT_EQ(full_bcp.size(), boot_image_spaces.size());

    // Fail to load any images with invalid image locations (named component after search paths).
    load_ok = silent_load(ART_FORMAT("{}:*:{}", base_location, tail_location));
    ASSERT_FALSE(load_ok);
    load_ok = silent_load(ART_FORMAT("{}:{}*:{}", base_location, scratch_dir, tail_location));
    ASSERT_FALSE(load_ok);

    // Load the primary and single-image extension with full path.
    load_ok = load(ART_FORMAT("{}:{}", base_location, single_location));
    ASSERT_TRUE(load_ok) << error_msg;
    ASSERT_EQ(head_dex_files.size() + 1u, boot_image_spaces.size());

    // Load the primary with full path and single-image extension with a specified search path.
    load_ok = load(ART_FORMAT("{}:{}*", base_location, single_dir));
    ASSERT_TRUE(load_ok) << error_msg;
    ASSERT_EQ(head_dex_files.size() + 1u, boot_image_spaces.size());
  }

  // Recompile the single-image extension using file descriptors and compare contents.
  std::vector<std::string> expanded_single_filename_prefix =
      gc::space::ImageSpace::ExpandMultiImageLocations(
          single_dex_files.SubArray(/*pos=*/ 0u, /*length=*/ 1u),
          single_filename_prefix,
          /*boot_image_extension=*/ true);
  CHECK_EQ(1u, expanded_single_filename_prefix.size());
  std::string single_ext_prefix = expanded_single_filename_prefix[0];
  std::string single_ext_prefix2 = single_ext_prefix + "2";
  error_msg.clear();
  single_ok = CompileBootImage(extra_args,
                               single_filename_prefix,
                               single_dex_files,
                               &error_msg,
                               /*use_fd_prefix=*/ single_ext_prefix2);
  ASSERT_TRUE(single_ok) << error_msg;
  EXPECT_TRUE(CompareFiles(single_ext_prefix + ".art", single_ext_prefix2 + ".art"));
  EXPECT_TRUE(CompareFiles(single_ext_prefix + ".vdex", single_ext_prefix2 + ".vdex"));
  EXPECT_TRUE(CompareFiles(single_ext_prefix + ".oat", single_ext_prefix2 + ".oat"));

  // Test parsing profile specification and creating the boot image extension on-the-fly.
  // We must set --android-root in the image compiler options.
  AddAndroidRootToImageCompilerOptions();
  for (bool r : { false, true }) {
    relocate = r;

    // Load primary boot image with a profile name.
    bool load_ok = silent_load(ART_FORMAT("{}!{}", base_location, single_profile_filename));
    ASSERT_TRUE(load_ok);

    // Try and fail to load with invalid spec, two profile name separators.
    load_ok =
        silent_load(ART_FORMAT("{}:{}!!arbitrary-profile-name", base_location, single_location));
    ASSERT_FALSE(load_ok);

    // Try and fail to load with invalid spec, missing profile name.
    load_ok = silent_load(ART_FORMAT("{}:{}!", base_location, single_location));
    ASSERT_FALSE(load_ok);

    // Try and fail to load with invalid spec, missing component name.
    load_ok = silent_load(ART_FORMAT("{}:!{}", base_location, single_profile_filename));
    ASSERT_FALSE(load_ok);

    // Load primary boot image, specifying invalid extension component and profile name.
    load_ok = load(
        ART_FORMAT("{}:/non-existent/{}!non-existent-profile-name", base_location, single_name));
    ASSERT_TRUE(load_ok) << error_msg;
    ASSERT_EQ(head_dex_files.size(), boot_image_spaces.size());

    // Load primary boot image and the single extension, specifying invalid profile name.
    // (Load extension from file.)
    load_ok = load(ART_FORMAT("{}:{}!non-existent-profile-name", base_location, single_location));
    ASSERT_TRUE(load_ok) << error_msg;
    ASSERT_EQ(head_dex_files.size() + 1u, boot_image_spaces.size());
    ASSERT_EQ(single_dex_files.size(),
              boot_image_spaces.back()->GetImageHeader().GetComponentCount());

    // Load primary boot image and fail to load the single extension, specifying
    // invalid extension component name but a valid profile file.
    // (Running dex2oat to compile extension is disabled.)
    ASSERT_FALSE(Runtime::Current()->IsImageDex2OatEnabled());
    load_ok = load(
        ART_FORMAT("{}:/non-existent/{}!{}", base_location, single_name, single_profile_filename));
    ASSERT_TRUE(load_ok) << error_msg;
    ASSERT_EQ(head_dex_files.size(), boot_image_spaces.size());

    EnableImageDex2Oat();

    // Load primary boot image and the single extension, specifying invalid extension
    // component name but a valid profile file. (Compile extension by running dex2oat.)
    load_ok = load(
        ART_FORMAT("{}:/non-existent/{}!{}", base_location, single_name, single_profile_filename));
    ASSERT_TRUE(load_ok) << error_msg;
    ASSERT_EQ(head_dex_files.size() + 1u, boot_image_spaces.size());
    ASSERT_EQ(single_dex_files.size(),
              boot_image_spaces.back()->GetImageHeader().GetComponentCount());

    // Load primary boot image and two extensions, specifying invalid extension component
    // names but valid profile files. (Compile extensions by running dex2oat.)
    load_ok = load(ART_FORMAT("{}:/non-existent/{}!{}:/non-existent/{}!{}",
                              base_location,
                              mid_name,
                              mid_profile_filename,
                              tail_name,
                              tail_profile_filename));
    ASSERT_TRUE(load_ok) << error_msg;
    ASSERT_EQ(head_dex_files.size() + 2u, boot_image_spaces.size());
    ASSERT_EQ(mid_dex_files.size(),
              boot_image_spaces[head_dex_files.size()]->GetImageHeader().GetComponentCount());
    ASSERT_EQ(tail_dex_files.size(),
              boot_image_spaces[head_dex_files.size() + 1u]->GetImageHeader().GetComponentCount());

    // Load primary boot image and fail to load extensions, specifying invalid component
    // names but valid profile file only for the second one. As we fail to load the first
    // extension, the second extension has a missing dependency and cannot be compiled.
    load_ok = load(ART_FORMAT("{}:/non-existent/{}:/non-existent/{}!{}",
                              base_location,
                              mid_name,
                              tail_name,
                              tail_profile_filename));
    ASSERT_TRUE(load_ok) << error_msg;
    ASSERT_EQ(head_dex_files.size(), boot_image_spaces.size());

    DisableImageDex2Oat();
  }
}

}  // namespace art
