/*
 * 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) {
  TEST_DISABLED_FOR_RISCV64();
  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
