summaryrefslogtreecommitdiff
path: root/ravenwood/junit-src
diff options
context:
space:
mode:
author John Wu <topjohnwu@google.com> 2024-11-23 00:29:29 +0000
committer John Wu <topjohnwu@google.com> 2024-11-23 00:29:29 +0000
commit2f3a9c61f771790f0d59fc6b9991d63cfddbf2c7 (patch)
treeb63ec2e2a56a26de31ef03e3d3f1425093e43ea6 /ravenwood/junit-src
parent558cd71f0f6ec8f1af5d49fd9c208411f7b77615 (diff)
[Ravenwood] Update system property handling
- Split out "core" system properties (the default properties we set during the global initialization) and "test" system properties (the properties defined and set through RavenwoodRule) - Reset only the "test" system properties before each test execution - Update the implementation to support nested RavenwoodRule in the future Flag: EXEMPT host test change only Bug: 377765941 Test: $ANDROID_BUILD_TOP/frameworks/base/ravenwood/scripts/run-ravenwood-tests.sh Change-Id: Ia9a2ee217aa89e0f2565d14fb26e3842947e9dc7
Diffstat (limited to 'ravenwood/junit-src')
-rw-r--r--ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodRule.java10
-rw-r--r--ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodSystemProperties.java248
-rw-r--r--ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodTestProperties.java59
3 files changed, 64 insertions, 253 deletions
diff --git a/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodRule.java b/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodRule.java
index 6262ad160c0f..e49d3d934e9f 100644
--- a/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodRule.java
+++ b/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodRule.java
@@ -92,7 +92,7 @@ public final class RavenwoodRule implements TestRule {
}
}
- final RavenwoodSystemProperties mSystemProperties = new RavenwoodSystemProperties();
+ final RavenwoodTestProperties mProperties = new RavenwoodTestProperties();
public static class Builder {
@@ -144,8 +144,8 @@ public final class RavenwoodRule implements TestRule {
* Has no effect on non-Ravenwood environments.
*/
public Builder setSystemPropertyImmutable(@NonNull String key, @Nullable Object value) {
- mRule.mSystemProperties.setValue(key, value);
- mRule.mSystemProperties.setAccessReadOnly(key);
+ mRule.mProperties.setValue(key, value);
+ mRule.mProperties.setAccessReadOnly(key);
return this;
}
@@ -160,8 +160,8 @@ public final class RavenwoodRule implements TestRule {
* Has no effect on non-Ravenwood environments.
*/
public Builder setSystemPropertyMutable(@NonNull String key, @Nullable Object value) {
- mRule.mSystemProperties.setValue(key, value);
- mRule.mSystemProperties.setAccessReadWrite(key);
+ mRule.mProperties.setValue(key, value);
+ mRule.mProperties.setAccessReadWrite(key);
return this;
}
diff --git a/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodSystemProperties.java b/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodSystemProperties.java
deleted file mode 100644
index 9bd376a76f77..000000000000
--- a/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodSystemProperties.java
+++ /dev/null
@@ -1,248 +0,0 @@
-/*
- * Copyright (C) 2024 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.
- */
-
-package android.platform.test.ravenwood;
-
-import static com.android.ravenwood.common.RavenwoodCommonUtils.RAVENWOOD_VERBOSE_LOGGING;
-import static com.android.ravenwood.common.RavenwoodCommonUtils.getRavenwoodRuntimePath;
-
-import android.util.Log;
-
-import java.io.IOException;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.LinkedHashMap;
-import java.util.Map;
-import java.util.Set;
-
-public class RavenwoodSystemProperties {
- private static final String TAG = "RavenwoodSystemProperties";
-
- /** We pull in propeties from this file. */
- private static final String RAVENWOOD_BUILD_PROP = "ravenwood-data/ravenwood-build.prop";
-
- /** This is the actual build.prop we use to build the device (contents depends on lunch). */
- private static final String DEVICE_BUILD_PROP = "ravenwood-data/build.prop";
-
- /** The default values. */
- private static final Map<String, String> sDefaultValues = new HashMap<>();
-
- private static final String[] PARTITIONS = {
- "bootimage",
- "odm",
- "product",
- "system",
- "system_ext",
- "vendor",
- "vendor_dlkm",
- };
-
- static Map<String, String> readProperties(String propFile) {
- // Use an ordered map just for cleaner dump log.
- final Map<String, String> ret = new LinkedHashMap<>();
- try {
- Files.readAllLines(Path.of(propFile)).stream()
- .map(String::trim)
- .filter(s -> !s.startsWith("#"))
- .map(s -> s.split("\\s*=\\s*", 2))
- .filter(a -> a.length == 2 && a[1].length() > 0)
- .forEach(a -> ret.put(a[0], a[1]));
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
- return ret;
- }
-
- /**
- * Load default sysprops from {@link #RAVENWOOD_BUILD_PROP}. We also pull in
- * certain properties from the acutual device's build.prop {@link #DEVICE_BUILD_PROP} too.
- *
- * More info about property file loading: system/core/init/property_service.cpp
- * In the following logic, the only partition we would need to consider is "system",
- * since we only read from system-build.prop
- */
- static void initialize() {
- var path = getRavenwoodRuntimePath();
- var ravenwoodProps = readProperties(path + RAVENWOOD_BUILD_PROP);
- var deviceProps = readProperties(path + DEVICE_BUILD_PROP);
-
- Log.i(TAG, "Default system properties:");
- ravenwoodProps.forEach((key, origValue) -> {
- final String value;
-
- // If a value starts with "$$$", then this is a reference to the device-side value.
- if (origValue.startsWith("$$$")) {
- var deviceKey = origValue.substring(3);
- var deviceValue = deviceProps.get(deviceKey);
- if (deviceValue == null) {
- throw new RuntimeException("Failed to initialize system properties. Key '"
- + deviceKey + "' doesn't exist in the device side build.prop");
- }
- value = deviceValue;
- } else {
- value = origValue;
- }
- Log.i(TAG, key + "=" + value);
- sDefaultValues.put(key, value);
- });
-
- // Copy ro.product.* and ro.build.* to all partitions, just in case
- // We don't want to log these because these are just a lot of duplicate values
- for (var entry : Set.copyOf(sDefaultValues.entrySet())) {
- var key = entry.getKey();
- if (key.startsWith("ro.product.") || key.startsWith("ro.build.")) {
- var name = key.substring(3);
- for (String partition : PARTITIONS) {
- var newKey = "ro." + partition + "." + name;
- if (!sDefaultValues.containsKey(newKey)) {
- sDefaultValues.put(newKey, entry.getValue());
- }
- }
- }
- }
- if (RAVENWOOD_VERBOSE_LOGGING) {
- // Dump all properties for local debugging.
- Log.v(TAG, "All system properties:");
- for (var key : sDefaultValues.keySet().stream().sorted().toList()) {
- Log.v(TAG, "" + key + "=" + sDefaultValues.get(key));
- }
- }
- }
-
- private volatile boolean mIsImmutable;
-
- private final Map<String, String> mValues = new HashMap<>();
-
- /** Set of additional keys that should be considered readable */
- private final Set<String> mKeyReadable = new HashSet<>();
-
- /** Set of additional keys that should be considered writable */
- private final Set<String> mKeyWritable = new HashSet<>();
-
- public RavenwoodSystemProperties() {
- mValues.putAll(sDefaultValues);
- }
-
- /** Copy constructor */
- public RavenwoodSystemProperties(RavenwoodSystemProperties source, boolean immutable) {
- mKeyReadable.addAll(source.mKeyReadable);
- mKeyWritable.addAll(source.mKeyWritable);
- mValues.putAll(source.mValues);
- mIsImmutable = immutable;
- }
-
- public Map<String, String> getValues() {
- return new HashMap<>(mValues);
- }
-
- public boolean isKeyReadable(String key) {
- final String root = getKeyRoot(key);
-
- if (root.startsWith("debug.")) return true;
-
- // This set is carefully curated to help identify situations where a test may
- // accidentally depend on a default value of an obscure property whose owner hasn't
- // decided how Ravenwood should behave.
- if (root.startsWith("boot.")) return true;
- if (root.startsWith("build.")) return true;
- if (root.startsWith("product.")) return true;
- if (root.startsWith("soc.")) return true;
- if (root.startsWith("system.")) return true;
-
- // For PropertyInvalidatedCache
- if (root.startsWith("cache_key.")) return true;
-
- switch (key) {
- case "gsm.version.baseband":
- case "no.such.thing":
- case "qemu.sf.lcd_density":
- case "ro.bootloader":
- case "ro.debuggable":
- case "ro.hardware":
- case "ro.hw_timeout_multiplier":
- case "ro.odm.build.media_performance_class":
- case "ro.sf.lcd_density":
- case "ro.treble.enabled":
- case "ro.vndk.version":
- case "ro.icu.data.path":
- return true;
- }
-
- return mKeyReadable.contains(key);
- }
-
- public boolean isKeyWritable(String key) {
- final String root = getKeyRoot(key);
-
- if (root.startsWith("debug.")) return true;
-
- // For PropertyInvalidatedCache
- if (root.startsWith("cache_key.")) return true;
-
- return mKeyWritable.contains(key);
- }
-
- private void ensureNotImmutable() {
- if (mIsImmutable) {
- throw new RuntimeException("Unable to update immutable instance");
- }
- }
-
- public void setValue(String key, Object value) {
- ensureNotImmutable();
-
- final String valueString = (value == null) ? null : String.valueOf(value);
- if ((valueString == null) || valueString.isEmpty()) {
- mValues.remove(key);
- } else {
- mValues.put(key, valueString);
- }
- }
-
- public void setAccessNone(String key) {
- ensureNotImmutable();
- mKeyReadable.remove(key);
- mKeyWritable.remove(key);
- }
-
- public void setAccessReadOnly(String key) {
- ensureNotImmutable();
- mKeyReadable.add(key);
- mKeyWritable.remove(key);
- }
-
- public void setAccessReadWrite(String key) {
- ensureNotImmutable();
- mKeyReadable.add(key);
- mKeyWritable.add(key);
- }
-
- /**
- * Return the "root" of the given property key, stripping away any modifier prefix such as
- * {@code ro.} or {@code persist.}.
- */
- private static String getKeyRoot(String key) {
- if (key.startsWith("ro.")) {
- return key.substring(3);
- } else if (key.startsWith("persist.")) {
- return key.substring(8);
- } else {
- return key;
- }
- }
-}
diff --git a/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodTestProperties.java b/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodTestProperties.java
new file mode 100644
index 000000000000..66a26b511213
--- /dev/null
+++ b/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodTestProperties.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2024 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.
+ */
+
+package android.platform.test.ravenwood;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * A class to store system properties defined by tests.
+ */
+public class RavenwoodTestProperties {
+ final Map<String, String> mValues = new HashMap<>();
+
+ /** Set of additional keys that should be considered readable */
+ final Set<String> mKeyReadable = new HashSet<>();
+
+ /** Set of additional keys that should be considered writable */
+ final Set<String> mKeyWritable = new HashSet<>();
+
+ public void setValue(String key, Object value) {
+ final String valueString = (value == null) ? null : String.valueOf(value);
+ if ((valueString == null) || valueString.isEmpty()) {
+ mValues.remove(key);
+ } else {
+ mValues.put(key, valueString);
+ }
+ }
+
+ public void setAccessNone(String key) {
+ mKeyReadable.remove(key);
+ mKeyWritable.remove(key);
+ }
+
+ public void setAccessReadOnly(String key) {
+ mKeyReadable.add(key);
+ mKeyWritable.remove(key);
+ }
+
+ public void setAccessReadWrite(String key) {
+ mKeyReadable.add(key);
+ mKeyWritable.add(key);
+ }
+}