Fix app image generation and checking with shared libraries.

We can now have multiple class loaders in an app image.

bug: 111174995
Test: dex2oat_test, test.py

Change-Id: Ie45c030b483efa78df2605fbcafb4e641b80c59a
diff --git a/dex2oat/dex2oat_test.cc b/dex2oat/dex2oat_test.cc
index 1fa21d5..97a5f24 100644
--- a/dex2oat/dex2oat_test.cc
+++ b/dex2oat/dex2oat_test.cc
@@ -1069,7 +1069,8 @@
   void RunTest(const char* class_loader_context,
                const char* expected_classpath_key,
                bool expected_success,
-               bool use_second_source = false) {
+               bool use_second_source = false,
+               bool generate_image = false) {
     std::string dex_location = GetUsedDexLocation();
     std::string odex_location = GetUsedOatLocation();
 
@@ -1080,6 +1081,9 @@
     if (class_loader_context != nullptr) {
       extra_args.push_back(std::string("--class-loader-context=") + class_loader_context);
     }
+    if (generate_image) {
+      extra_args.push_back(std::string("--app-image-file=") + GetUsedImageLocation());
+    }
     auto check_oat = [expected_classpath_key](const OatFile& oat_file) {
       ASSERT_TRUE(expected_classpath_key != nullptr);
       const char* classpath = oat_file.GetOatHeader().GetStoreValueByKey(OatHeader::kClassPathKey);
@@ -1104,6 +1108,10 @@
     return GetOdexDir() + "/Context.odex";
   }
 
+  std::string GetUsedImageLocation() {
+    return GetOdexDir() + "/Context.art";
+  }
+
   const char* kEmptyClassPathKey = "PCL[]";
 };
 
@@ -1213,6 +1221,55 @@
   RunTest(context.c_str(), expected_classpath_key.c_str(), true);
 }
 
+TEST_F(Dex2oatClassLoaderContextTest, ContextWithSharedLibraryAndImage) {
+  std::vector<std::unique_ptr<const DexFile>> dex_files1 = OpenTestDexFiles("Nested");
+  std::vector<std::unique_ptr<const DexFile>> dex_files2 = OpenTestDexFiles("MultiDex");
+
+  std::string context = "PCL[" + GetTestDexFileName("Nested") + "]" +
+      "{PCL[" + GetTestDexFileName("MultiDex") + "]}";
+  std::string expected_classpath_key = "PCL[" + CreateClassPathWithChecksums(dex_files1) + "]" +
+      "{PCL[" + CreateClassPathWithChecksums(dex_files2) + "]}";
+  RunTest(context.c_str(),
+          expected_classpath_key.c_str(),
+          /*expected_success=*/ true,
+          /*use_second_source=*/ false,
+          /*generate_image=*/ true);
+}
+
+TEST_F(Dex2oatClassLoaderContextTest, ContextWithSameSharedLibrariesAndImage) {
+  std::vector<std::unique_ptr<const DexFile>> dex_files1 = OpenTestDexFiles("Nested");
+  std::vector<std::unique_ptr<const DexFile>> dex_files2 = OpenTestDexFiles("MultiDex");
+
+  std::string context = "PCL[" + GetTestDexFileName("Nested") + "]" +
+      "{PCL[" + GetTestDexFileName("MultiDex") + "]" +
+      "#PCL[" + GetTestDexFileName("MultiDex") + "]}";
+  std::string expected_classpath_key = "PCL[" + CreateClassPathWithChecksums(dex_files1) + "]" +
+      "{PCL[" + CreateClassPathWithChecksums(dex_files2) + "]" +
+      "#PCL[" + CreateClassPathWithChecksums(dex_files2) + "]}";
+  RunTest(context.c_str(),
+          expected_classpath_key.c_str(),
+          /*expected_success=*/ true,
+          /*use_second_source=*/ false,
+          /*generate_image=*/ true);
+}
+
+TEST_F(Dex2oatClassLoaderContextTest, ContextWithSharedLibrariesDependenciesAndImage) {
+  std::vector<std::unique_ptr<const DexFile>> dex_files1 = OpenTestDexFiles("Nested");
+  std::vector<std::unique_ptr<const DexFile>> dex_files2 = OpenTestDexFiles("MultiDex");
+
+  std::string context = "PCL[" + GetTestDexFileName("Nested") + "]" +
+      "{PCL[" + GetTestDexFileName("MultiDex") + "]" +
+      "{PCL[" + GetTestDexFileName("Nested") + "]}}";
+  std::string expected_classpath_key = "PCL[" + CreateClassPathWithChecksums(dex_files1) + "]" +
+      "{PCL[" + CreateClassPathWithChecksums(dex_files2) + "]" +
+      "{PCL[" + CreateClassPathWithChecksums(dex_files1) + "]}}";
+  RunTest(context.c_str(),
+          expected_classpath_key.c_str(),
+          /*expected_success=*/ true,
+          /*use_second_source=*/ false,
+          /*generate_image=*/ true);
+}
+
 class Dex2oatDeterminism : public Dex2oatTest {};
 
 TEST_F(Dex2oatDeterminism, UnloadCompile) {