diff options
Diffstat (limited to 'runtime/module_exclusion_test.cc')
-rw-r--r-- | runtime/module_exclusion_test.cc | 130 |
1 files changed, 130 insertions, 0 deletions
diff --git a/runtime/module_exclusion_test.cc b/runtime/module_exclusion_test.cc new file mode 100644 index 0000000000..14942edea6 --- /dev/null +++ b/runtime/module_exclusion_test.cc @@ -0,0 +1,130 @@ +/* + * Copyright (C) 2019 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 "common_compiler_test.h" + +#include "class_linker-inl.h" +#include "handle.h" +#include "handle_scope-inl.h" +#include "mirror/class_loader.h" +#include "mirror/dex_cache.h" +#include "mirror/object-inl.h" +#include "runtime.h" +#include "scoped_thread_state_change-inl.h" +#include "thread-current-inl.h" +#include "well_known_classes.h" + +namespace art { + +class ModuleExclusionTest : public CommonCompilerTest { + public: + explicit ModuleExclusionTest(const std::string& module) + : CommonCompilerTest(), + module_(module) {} + + std::vector<std::string> GetLibCoreModuleNames() const override { + std::vector<std::string> modules = CommonCompilerTest::GetLibCoreModuleNames(); + // Exclude `module_` from boot class path. + auto it = std::find(modules.begin(), modules.end(), module_); + if (it != modules.end()) { + modules.erase(it); + } + return modules; + } + + void DoTest() { + Thread* self = Thread::Current(); + ScopedObjectAccess soa(self); + StackHandleScope<2u> hs(self); + Runtime* runtime = Runtime::Current(); + ASSERT_TRUE(runtime->IsAotCompiler()); + ClassLinker* class_linker = runtime->GetClassLinker(); + CHECK(loaded_dex_files_.empty()); + Handle<mirror::ClassLoader> class_loader = hs.NewHandle(LoadModule(soa, class_linker)); + MutableHandle<mirror::DexCache> dex_cache = hs.NewHandle<mirror::DexCache>(nullptr); + CHECK(!loaded_dex_files_.empty()); + + // Verify that classes defined in the loaded dex files cannot be resolved. + for (const std::unique_ptr<const DexFile>& dex_file : loaded_dex_files_) { + dex_cache.Assign(class_linker->RegisterDexFile(*dex_file, class_loader.Get())); + for (size_t i = 0u, size = dex_file->NumClassDefs(); i != size; ++i) { + const dex::ClassDef& class_def = dex_file->GetClassDef(i); + ObjPtr<mirror::Class> resolved_type = + class_linker->ResolveType(class_def.class_idx_, dex_cache, class_loader); + ASSERT_TRUE(resolved_type == nullptr) << resolved_type->PrettyDescriptor(); + ASSERT_TRUE(self->IsExceptionPending()); + self->ClearException(); + } + } + } + + private: + std::string GetModuleFileName() const { + std::vector<std::string> filename = GetLibCoreDexFileNames({ module_ }); + CHECK_EQ(filename.size(), 1u); + return filename[0]; + } + + // Load the module as an app, i.e. in a class loader other than the boot class loader. + ObjPtr<mirror::ClassLoader> LoadModule(ScopedObjectAccess& soa, ClassLinker* class_linker) + REQUIRES_SHARED(Locks::mutator_lock_) { + std::string filename = GetModuleFileName(); + std::vector<std::unique_ptr<const DexFile>> dex_files = OpenDexFiles(filename.c_str()); + + std::vector<const DexFile*> class_path; + CHECK_NE(0U, dex_files.size()); + for (auto& dex_file : dex_files) { + class_path.push_back(dex_file.get()); + loaded_dex_files_.push_back(std::move(dex_file)); + } + + StackHandleScope<1u> hs(soa.Self()); + Handle<mirror::Class> loader_class(hs.NewHandle( + soa.Decode<mirror::Class>(WellKnownClasses::dalvik_system_PathClassLoader))); + ScopedNullHandle<mirror::ClassLoader> parent_loader; + ScopedNullHandle<mirror::ObjectArray<mirror::ClassLoader>> shared_libraries; + + ObjPtr<mirror::ClassLoader> result = class_linker->CreateWellKnownClassLoader( + soa.Self(), + class_path, + loader_class, + parent_loader, + shared_libraries); + + // Verify that the result has the correct class. + CHECK_EQ(loader_class.Get(), result->GetClass()); + // Verify that the parent is not null. The boot class loader will be set up as a + // proper BootClassLoader object. + ObjPtr<mirror::ClassLoader> actual_parent(result->GetParent()); + CHECK(actual_parent != nullptr); + CHECK(class_linker->IsBootClassLoader(soa, actual_parent)); + + return result; + } + + const std::string module_; +}; + +class ConscryptExclusionTest : public ModuleExclusionTest { + public: + ConscryptExclusionTest() : ModuleExclusionTest("conscrypt") {} +}; + +TEST_F(ConscryptExclusionTest, Test) { + DoTest(); +} + +} // namespace art |