diff options
author | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2023-10-13 03:30:58 +0000 |
---|---|---|
committer | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2023-10-13 03:30:58 +0000 |
commit | 95c4168fbc77ef775fc646d87f84a4b9970eac4a (patch) | |
tree | 04d77fef556447b08cd12a39d16b4c547a85dc0c | |
parent | 01dc038625d348fc4aebf48239fcbc8d1780114b (diff) | |
parent | 8874ecbe733278c1e30c143ec14ac2a74111c1e0 (diff) | |
download | linkerconfig-95c4168fbc77ef775fc646d87f84a4b9970eac4a.tar.gz |
Snap for 10942032 from 8874ecbe733278c1e30c143ec14ac2a74111c1e0 to 24Q1-release
Change-Id: I4b5f3f92e524ed2fd6572faff91f7095605c86d8
9 files changed, 731 insertions, 0 deletions
diff --git a/devicetest/Android.bp b/devicetest/Android.bp new file mode 100644 index 0000000..233b5cb --- /dev/null +++ b/devicetest/Android.bp @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2020 Google LLC. + * + * 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. + */ + +package { + default_applicable_licenses: [ + "Android-Apache-2.0", + ], +} + +java_test_host { + name: "GtsLinkerConfigTestCases", + libs: [ + "tradefed", + ], + static_libs: [ + "hamcrest-library", + "compatibility-host-util", + ], + srcs: ["src/**/*.java"], + // Tag this module as a gts test artifact + test_suites: [ + "gts", + "general-tests", + "mts-mainline-infra", + ], +} diff --git a/devicetest/AndroidTest.xml b/devicetest/AndroidTest.xml new file mode 100644 index 0000000..44f325d --- /dev/null +++ b/devicetest/AndroidTest.xml @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2020 Google LLC. + + 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. +--> +<configuration description="Config for GTS Linkerconfig test cases"> + <option name="test-suite-tag" value="gts" /> + <option name="config-descriptor:metadata" key="component" value="gms" /> + <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" /> + <option name="config-descriptor:metadata" key="parameter" value="not_multi_abi" /> + <option name="config-descriptor:metadata" key="parameter" value="secondary_user" /> + <option name="config-descriptor:metadata" key="parameter" value="no_foldable_states" /> + <test class="com.android.tradefed.testtype.HostTest" > + <option name="jar" value="GtsLinkerConfigTestCases.jar" /> + </test> + + <object type="module_controller" class="com.android.tradefed.testtype.suite.module.Sdk30ModuleController"/> +</configuration> diff --git a/devicetest/src/android/linkerconfig/gts/LinkerConfigTest.java b/devicetest/src/android/linkerconfig/gts/LinkerConfigTest.java new file mode 100644 index 0000000..e24ae18 --- /dev/null +++ b/devicetest/src/android/linkerconfig/gts/LinkerConfigTest.java @@ -0,0 +1,235 @@ +/* + * Copyright (C) 2020 Google LLC. + * + * 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. + */ + +package android.linkerconfig.gts; + +import static org.hamcrest.Matchers.contains; +import static org.hamcrest.Matchers.empty; +import static org.hamcrest.Matchers.not; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import android.linkerconfig.gts.utils.LibraryListLoader; +import android.linkerconfig.gts.utils.LinkerConfigParser; +import android.linkerconfig.gts.utils.elements.Configuration; +import android.linkerconfig.gts.utils.elements.Namespace; +import android.linkerconfig.gts.utils.elements.Section; + +import com.android.compatibility.common.util.ApiLevelUtil; +import com.android.compatibility.common.util.GmsTest; +import com.android.tradefed.device.DeviceNotAvailableException; +import com.android.tradefed.device.INativeDevice; +import com.android.tradefed.device.ITestDevice; +import com.android.tradefed.testtype.DeviceJUnit4ClassRunner; +import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; + +@RunWith(DeviceJUnit4ClassRunner.class) +public class LinkerConfigTest extends BaseHostJUnit4Test { + + private static final String LINKER_CONFIG_LOCATION = "/linkerconfig/ld.config.txt"; + private static final String VENDOR_VNDK_LITE = "ro.vndk.lite"; + private static final String VENDOR_VNDK_VERSION = "ro.vndk.version"; + private static final int TARGET_MIN_VER = 30; // linkerconfig is available from R + + private static boolean isValidVersion(ITestDevice device) { + try { + return ApiLevelUtil.isAtLeast(device, TARGET_MIN_VER); + } catch (DeviceNotAvailableException e) { + fail("There is no available device : " + e.getMessage()); + } + + return false; + } + + private static Configuration loadConfig(INativeDevice targetDevice, String path) { + File target = null; + + try { + target = targetDevice.pullFile(path); + } catch (DeviceNotAvailableException e) { + fail("There is no available device : " + e.getMessage()); + } + + assertTrue("Failed to get linker configuration from expected location", + target.exists()); + + List<String> lines = new ArrayList<>(); + try (BufferedReader reader = new BufferedReader(new FileReader(target))) { + String line; + while ((line = reader.readLine()) != null) { + line = line.trim(); + if (!line.isEmpty()) { + lines.add(line); + } + } + } catch (Exception e) { + fail("Failed to read file " + path + " with error : " + e.getMessage()); + } + + return LinkerConfigParser.parseConfiguration(lines); + } + + private static void verifyVendorSection(Section section, Set<String> systemAvailableLibraries) { + List<Namespace> systemNamespaces = section.namespaces.values().stream() + .filter(ns -> ns.searchPaths.stream() + .anyMatch(searchPath -> searchPath.startsWith("/system") + && !searchPath.startsWith("/system/vendor"))) + .distinct() + .collect(Collectors.toList()); + + assertFalse("System namespace should not be visible", + systemNamespaces.parallelStream().anyMatch(ns -> ns.isVisible)); + + section.namespaces.values().forEach((ns) -> { + boolean isVendorNamespace = false; + for (String libPath : ns.searchPaths) { + if (libPath.startsWith(("/vendor")) || libPath.startsWith("/odm")) { + isVendorNamespace = true; + break; + } + } + + if (!isVendorNamespace) { + return; + } + + assertThat( + "Vendor libs and System libs should not exist in same namespace : " + ns.name, + systemNamespaces, not(contains(ns))); + + ns.links.values().forEach((link) -> { + if (systemNamespaces.contains(link.to)) { + assertFalse( + "It is not allowed to link all shared libs from non-system namespace " + + link.from + + "to system namespace " + link.to, + link.allowAll); + + link.libraries.forEach(library -> { + assertTrue("Library " + library + " is not allowed to use", + systemAvailableLibraries.contains(library)); + }); + } + }); + }); + } + + + private static Set<String> loadSystemAvailableLibraries(INativeDevice targetDevice, + String vendorVndkVersion) { + Set<String> libraries = new HashSet<>(); + + // Add Sanitizer libraries + libraries.addAll(LibraryListLoader.getLibrariesFromFile(targetDevice, + "/system/etc/sanitizer.libraries.txt", true)); + + // Add LLNDK libraries + libraries.addAll(LibraryListLoader.getLibrariesFromFile(targetDevice, + "/apex/com.android.vndk.v" + vendorVndkVersion + "/etc/llndk.libraries." + + vendorVndkVersion + ".txt", true)); + + // Add Stub libraries + libraries.addAll(LibraryListLoader.STUB_LIBRARIES); + + // Allowed on userdebug/eng for debugging. + libraries.add("libfdtrack.so"); + + // Add VNDK core variant libraries + libraries.addAll(LibraryListLoader.getLibrariesFromFile(targetDevice, + "/system/etc/vndkcorevariant.libraries.txt", false)); + + return libraries; + } + + @GmsTest(requirement = "GMS-3.5-014") + @Test + public void shouldHaveLinkerConfigAtExpectedLocation() { + ITestDevice targetDevice = getDevice(); + + if (!isValidVersion(targetDevice)) { + return; + } + + try { + File linkerConfigFile = targetDevice.pullFile(LINKER_CONFIG_LOCATION); + assertTrue("Failed to get linker configuration from expected location", + linkerConfigFile.exists()); + } catch (DeviceNotAvailableException e) { + fail("Target device is not available : " + e.getMessage()); + } + } + + @GmsTest(requirement = "GMS-3.5-014") + @Test + public void shouldNotAccessSystemFromVendorExceptVndk() { + ITestDevice targetDevice = getDevice(); + boolean vndkLiteEnabled = false; + + try { + vndkLiteEnabled = Boolean.parseBoolean(targetDevice.getProperty(VENDOR_VNDK_LITE)); + } catch (DeviceNotAvailableException e) { + fail("Target device is not available : " + e.getMessage()); + } + + if (!isValidVersion(targetDevice) || vndkLiteEnabled) { + return; + } + + String vendorVndkVersion = ""; + try { + vendorVndkVersion = targetDevice.getProperty(VENDOR_VNDK_VERSION); + } catch (DeviceNotAvailableException e) { + fail("Target device is not available : " + e.getMessage()); + } + + if (vendorVndkVersion == null || vendorVndkVersion.isEmpty()) { + return; + } + + Configuration conf = loadConfig(targetDevice, LINKER_CONFIG_LOCATION); + + List<Section> vendorSections = conf.dirToSections.entrySet().stream() + .filter(item -> item.getKey().startsWith("/vendor") || item.getKey().startsWith( + ("/odm"))) + .map(Map.Entry::getValue) + .distinct() + .collect(Collectors.toList()); + + assertThat("No section for vendor", vendorSections, not(empty())); + + Set<String> availableLibraries = loadSystemAvailableLibraries(targetDevice, + vendorVndkVersion); + + for (Section section : vendorSections) { + verifyVendorSection(section, availableLibraries); + } + } +} diff --git a/devicetest/src/android/linkerconfig/gts/utils/LibraryListLoader.java b/devicetest/src/android/linkerconfig/gts/utils/LibraryListLoader.java new file mode 100644 index 0000000..c12a7c3 --- /dev/null +++ b/devicetest/src/android/linkerconfig/gts/utils/LibraryListLoader.java @@ -0,0 +1,95 @@ +/* + * Copyright (C) 2020 Google LLC. + * + * 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. + */ + +package android.linkerconfig.gts.utils; + +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import com.android.tradefed.device.DeviceNotAvailableException; +import com.android.tradefed.device.INativeDevice; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class LibraryListLoader { + public static List<String> getLibrariesFromFile(INativeDevice targetDevice, + String path, boolean expectFileExists) { + List<String> libraries = new ArrayList<>(); + + File target = null; + + try { + target = targetDevice.pullFile(path); + } catch (DeviceNotAvailableException e) { + fail("There is no available device : " + e.getMessage()); + } + + assertTrue("Failed to get library list file from " + path, + target.exists() || !expectFileExists); + + if (target.exists()) { + try (BufferedReader reader = new BufferedReader(new FileReader(target))) { + String library; + while ((library = reader.readLine()) != null) { + library = library.trim(); + if (!library.isEmpty()) { + libraries.add(library); + } + } + } catch (Exception e) { + fail("Failed to read file " + path + " with error : " + e.getMessage()); + } + } + + return libraries; + } + + public static final List<String> STUB_LIBRARIES = Arrays.asList("libEGL.so", + "libGLESv1_CM.so", + "libGLESv2.so", + "libGLESv3.so", + "libRS.so", + "libaaudio.so", + "libadbd_auth.so", + "libadbd_fs.so", + "libandroid.so", + "libandroid_net.so", + "libbinder_ndk.so", + "libc.so", + "libcgrouprc.so", + "libclang_rt.asan-arm-android.so", + "libclang_rt.asan-i686-android.so", + "libclang_rt.asan-x86_64-android.so", + "libdl.so", + "libdl_android.so", + "libft2.so", + "libincident.so", + "liblog.so", + "libm.so", + "libmediametrics.so", + "libmediandk.so", + "libnativewindow.so", + "libneuralnetworks_packageinfo.so", + "libsync.so", + "libvndksupport.so", + "libvulkan.so", + "libselinux.so"); +} diff --git a/devicetest/src/android/linkerconfig/gts/utils/LinkerConfigParser.java b/devicetest/src/android/linkerconfig/gts/utils/LinkerConfigParser.java new file mode 100644 index 0000000..a1db499 --- /dev/null +++ b/devicetest/src/android/linkerconfig/gts/utils/LinkerConfigParser.java @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2020 Google LLC. + * + * 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. + */ + +package android.linkerconfig.gts.utils; + +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import android.linkerconfig.gts.utils.elements.Configuration; +import android.linkerconfig.gts.utils.elements.Section; + +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class LinkerConfigParser { + static final String REGEX_SECTION_NAME = "\\[\\s*(\\w+)\\s*\\]"; + static Pattern sSectionNamePattern = Pattern.compile(REGEX_SECTION_NAME); + + public static Configuration parseConfiguration(List<String> contents) { + Configuration configuration = new Configuration(); + Section currentSection = null; + + for (String content : contents) { + if (content.isEmpty()) { + continue; + } + + Matcher sectionNameMatcher = sSectionNamePattern.matcher(content); + if (sectionNameMatcher.matches()) { + String sectionName = sectionNameMatcher.group(1); + assertTrue("Section should have been defined from dir to section map", + configuration.sections.containsKey(sectionName)); + currentSection = configuration.getSectionFromName(sectionName); + continue; + } + + if (currentSection == null && configuration.parseConfiguration(content)) { + continue; + } + + assertNotNull("This line cannot be parsed without section : " + content, + currentSection); + + currentSection.parseConfiguration(content); + } + + return configuration; + } +} diff --git a/devicetest/src/android/linkerconfig/gts/utils/elements/Configuration.java b/devicetest/src/android/linkerconfig/gts/utils/elements/Configuration.java new file mode 100644 index 0000000..9ee3278 --- /dev/null +++ b/devicetest/src/android/linkerconfig/gts/utils/elements/Configuration.java @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2020 Google LLC. + * + * 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. + */ + +package android.linkerconfig.gts.utils.elements; + + +import java.util.HashMap; +import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class Configuration { + private static final String REGEX_DIR_TO_SECTION = "dir\\.(\\w+)\\s*=\\s([\\w.\\-/]+)"; + private Pattern mDirToSectionPattern = Pattern.compile(REGEX_DIR_TO_SECTION); + + public Map<String, Section> sections = new HashMap<>(); + public Map<String, Section> dirToSections = new HashMap<>(); + + public Section getSectionFromName(String name) { + if (sections.containsKey(name)) { + return sections.get(name); + } + + Section s = new Section(); + s.name = name; + sections.put(name, s); + + return s; + } + + public boolean parseConfiguration(String dirDefinition) { + Matcher dirToSectionMatcher = mDirToSectionPattern.matcher(dirDefinition); + + if (!dirToSectionMatcher.matches()) { + return false; + } + + String sectionName = dirToSectionMatcher.group(1); + String dirPath = dirToSectionMatcher.group(2); + Section section = getSectionFromName(sectionName); + dirToSections.put(dirPath, section); + + return true; + } +} diff --git a/devicetest/src/android/linkerconfig/gts/utils/elements/Link.java b/devicetest/src/android/linkerconfig/gts/utils/elements/Link.java new file mode 100644 index 0000000..045b47b --- /dev/null +++ b/devicetest/src/android/linkerconfig/gts/utils/elements/Link.java @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2020 Google LLC. + * + * 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. + */ + +package android.linkerconfig.gts.utils.elements; + + +import java.util.ArrayList; +import java.util.List; + +public class Link { + public Namespace from, to; + public List<String> libraries = new ArrayList<>(); + public boolean allowAll; +} diff --git a/devicetest/src/android/linkerconfig/gts/utils/elements/Namespace.java b/devicetest/src/android/linkerconfig/gts/utils/elements/Namespace.java new file mode 100644 index 0000000..25649e1 --- /dev/null +++ b/devicetest/src/android/linkerconfig/gts/utils/elements/Namespace.java @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2020 Google LLC. + * + * 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. + */ + +package android.linkerconfig.gts.utils.elements; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class Namespace { + public String name; + public boolean isVisible; + public boolean isIsolated; + + public List<String> searchPaths = new ArrayList<>(); + public List<String> permittedPaths = new ArrayList<>(); + public Map<String, Link> links = new HashMap<>(); +} diff --git a/devicetest/src/android/linkerconfig/gts/utils/elements/Section.java b/devicetest/src/android/linkerconfig/gts/utils/elements/Section.java new file mode 100644 index 0000000..a63b1aa --- /dev/null +++ b/devicetest/src/android/linkerconfig/gts/utils/elements/Section.java @@ -0,0 +1,154 @@ +/* + * Copyright (C) 2020 Google LLC. + * + * 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. + */ + +package android.linkerconfig.gts.utils.elements; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.util.HashMap; +import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class Section { + public Section() { + Namespace defaultNamespace = new Namespace(); + defaultNamespace.name = "default"; + + namespaces.put("default", defaultNamespace); + } + + static final String REGEX_ADDITIONAL_NAMESPACES = + "additional\\.namespaces\\s*=\\s*((?:[\\w]+)(?:,[\\w]+)*)"; + static final String REGEX_NAMESPACE = + "namespace\\.(\\w+)\\.([^\\s=]+)\\s*(?:=|\\+=)\\s*([^\\s]+)"; + + static Pattern sAdditionalNamespacesPattern = Pattern.compile(REGEX_ADDITIONAL_NAMESPACES); + static Pattern sNamespacePattern = Pattern.compile(REGEX_NAMESPACE); + + public String name; + public Map<String, Namespace> namespaces = new HashMap<>(); + + + public Namespace getNamespaceFromName(String namespace) { + assertTrue("Failed to find namespace " + namespace + " from section " + name, + namespaces.containsKey(namespace)); + + return namespaces.get(namespace); + } + + public void parseConfiguration(String line) { + Matcher additionalNamespacesMatcher = sAdditionalNamespacesPattern.matcher(line); + if (additionalNamespacesMatcher.matches()) { + assertEquals("Additional namespaces are already defined.", 1, namespaces.size()); + String additionalNamespaces = additionalNamespacesMatcher.group(1); + for (String additionalNamespace : additionalNamespaces.split(",")) { + Namespace ns = new Namespace(); + ns.name = additionalNamespace; + namespaces.put(additionalNamespace, ns); + } + + return; + } + + Matcher namespaceMatcher = sNamespacePattern.matcher(line); + assertTrue("Cannot parse : " + line, namespaceMatcher.matches()); + + String targetNamespace = namespaceMatcher.group(1); + String[] commands = namespaceMatcher.group(2).split("\\."); + String value = namespaceMatcher.group(3); + + assertTrue("Cannot find namespace " + targetNamespace, + namespaces.containsKey(targetNamespace)); + + Namespace ns = getNamespaceFromName(targetNamespace); + + assertTrue("Invalid command : " + namespaceMatcher.group(2) + " from " + line, + commands.length > 0); + switch (commands[0]) { + case "isolated": + assertEquals("Invalid command : " + line, 1, commands.length); + ns.isIsolated = Boolean.parseBoolean(value); + return; + case "visible": + assertEquals("Invalid command : " + line, 1, commands.length); + ns.isVisible = Boolean.parseBoolean(value); + return; + case "search": + assertEquals("Invalid command : " + line, 2, commands.length); + assertEquals("Invalid command : " + line, "paths", commands[1]); + if (!value.isEmpty()) { + ns.searchPaths.add(value); + } + return; + case "permitted": + assertEquals("Invalid command : " + line, 2, commands.length); + assertEquals("Invalid command : " + line, "paths", commands[1]); + if (!value.isEmpty()) { + ns.permittedPaths.add(value); + } + return; + case "asan": + case "hwasan": + // Do not parse configuration for hwasan or asan in this test + assertEquals("Invalid command : " + line, 3, commands.length); + assertTrue("Invalid command : " + line, + commands[1].equals("search") || commands[1].equals("permitted")); + assertEquals("Invalid command : " + line, "paths", commands[2]); + return; + case "links": + assertEquals("Invalid command : " + line, 1, commands.length); + for (String linkTarget : value.split(",")) { + assertTrue("Invalid target namespace : " + linkTarget + " from " + line, + namespaces.containsKey(linkTarget)); + Link link = new Link(); + link.from = ns; + link.to = getNamespaceFromName(linkTarget); + ns.links.put(linkTarget, link); + } + return; + case "link": + assertEquals("Invalid command : " + line, 3, commands.length); + String linkTarget = commands[1]; + assertTrue("Link not defined : " + linkTarget + " from " + line, + ns.links.containsKey(linkTarget)); + Link link = ns.links.get(linkTarget); + + if (commands[2].equals("allow_all_shared_libs")) { + link.allowAll = Boolean.parseBoolean(value); + } else if (commands[2].equals("shared_libs")) { + String[] libs = value.split(":"); + for (String lib : libs) { + link.libraries.add(lib); + } + } else { + fail("Invalid link command : " + line); + } + return; + case "whitelisted": + case "allowed_libs": + assertEquals("Invalid command : " + line, 1, commands.length); + // Do not parse allowed library list in this test + return; + } + + + fail("Unable to parse command : " + line); + return; + } +} |