diff options
author | Ran Gu <guran@google.com> | 2024-02-14 01:13:09 +0000 |
---|---|---|
committer | Ran Gu <guran@google.com> | 2024-02-15 18:38:40 +0000 |
commit | 2a06a01679535a56d2854d6356ea786c6569c07d (patch) | |
tree | 075471b9be3d408ceb7e6a185dcfa867366c184b | |
parent | e5630dea4a6cc7a2132e4779e8c3f7b6bcabfbff (diff) | |
download | tradefederation-2a06a01679535a56d2854d6356ea786c6569c07d.tar.gz |
Added a new class DeviceFeatureFlag to parse device config flag strings.
Bug: b/299973599
Test: m tradefed-all &&
./tools/tradefederation/core/javatests/run_tradefed_tests.sh --class
com.android.tradefed.targetprep.FeatureFlagTargetPreparerTest
m tradefed-all &&
./tools/tradefederation/core/javatests/run_tradefed_tests.sh --class
com.android.tradefed.util.flag.DeviceFeatureFlagTest
Change-Id: If2e829dfe254ce36165bf8b37cc544814f701891
3 files changed, 142 insertions, 14 deletions
diff --git a/javatests/com/android/tradefed/util/flag/DeviceFeatureFlagTest.java b/javatests/com/android/tradefed/util/flag/DeviceFeatureFlagTest.java new file mode 100644 index 000000000..9b888dca9 --- /dev/null +++ b/javatests/com/android/tradefed/util/flag/DeviceFeatureFlagTest.java @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2010 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 com.android.tradefed.util.flag; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThrows; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Unit tests for {@link DeviceFeatureFlag}. */ +@RunWith(JUnit4.class) +public class DeviceFeatureFlagTest { + private static final String VALID_FLAG = "namespace/package.flag=value"; + private static final String INVALID_FLAG = "invalid flag"; + + @Test + public void testConstructor_validFlag_setsFlagAttributes() { + DeviceFeatureFlag deviceFeatureFlag = new DeviceFeatureFlag(VALID_FLAG); + assertEquals("namespace", deviceFeatureFlag.getNamespace()); + assertEquals("package.flag", deviceFeatureFlag.getFlagName()); + assertEquals("value", deviceFeatureFlag.getFlagValue()); + } + + @Test + public void testConstructor_invalidFlag_throwsException() { + assertThrows(IllegalArgumentException.class, () -> new DeviceFeatureFlag(INVALID_FLAG)); + } +} diff --git a/src/com/android/tradefed/util/flag/DeviceFeatureFlag.java b/src/com/android/tradefed/util/flag/DeviceFeatureFlag.java new file mode 100644 index 000000000..adf54b858 --- /dev/null +++ b/src/com/android/tradefed/util/flag/DeviceFeatureFlag.java @@ -0,0 +1,91 @@ +/* + * Copyright (C) 2010 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 com.android.tradefed.util.flag; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class DeviceFeatureFlag { + + // Expected flag format (same as output by "device_config list"): + // namespace/name=[value] + // Note value is optional. + private static final Pattern FLAG_PATTERN = + Pattern.compile("^(?<namespace>[^\\s/=]+)/(?<name>[^\\s/=]+)=(?<value>.*)$"); + + private final String namespace; + private final String flagName; + private final String flagValue; + + /** + * Constructor to create a new DeviceFeatureFlag object. + * + * @param flagString A device config flag string in the format of "namespace/flagName=flagValue" + * @throws IllegalArgumentException if the flagString parameter cannot be parsed + */ + public DeviceFeatureFlag(String flagString) { + Matcher match = FLAG_PATTERN.matcher(flagString); + if (!match.matches()) { + throw new IllegalArgumentException( + String.format("Failed to parse flag data: %s", flagString)); + } + namespace = match.group("namespace"); + flagName = match.group("name"); + flagValue = match.group("value"); + } + + /** + * Get the namespace of the DeviceFeatureFlag. E.g. "namespace" in flag string + * "namespace/flagName=flagValue". + * + * @return namespace string + */ + public String getNamespace() { + return namespace; + } + + /** + * Get the flag name of the DeviceFeatureFlag. E.g. "flagName" in flag string + * "namespace/flagName=flagValue". + * + * @return flag name string + */ + public String getFlagName() { + return flagName; + } + + /** + * Get the flag value of the DeviceFeatureFlag. E.g. "flagValue" in flag string + * "namespace/flagName=flagValue". + * + * @return flag value string + */ + public String getFlagValue() { + return flagValue; + } + + /** + * Convert the DeviceFeatureFlag object to a flag string in the format of + * "namespace/flagName=flagValue" + * + * @return formatted flag string + */ + @Override + public String toString() { + return String.format("%s/%s=%s", namespace, flagName, flagValue); + } +} diff --git a/test_framework/com/android/tradefed/targetprep/FeatureFlagTargetPreparer.java b/test_framework/com/android/tradefed/targetprep/FeatureFlagTargetPreparer.java index 71323517f..338200c56 100644 --- a/test_framework/com/android/tradefed/targetprep/FeatureFlagTargetPreparer.java +++ b/test_framework/com/android/tradefed/targetprep/FeatureFlagTargetPreparer.java @@ -17,6 +17,7 @@ package com.android.tradefed.targetprep; import com.android.tradefed.config.Option; import com.android.tradefed.config.OptionClass; +import com.android.tradefed.util.flag.DeviceFeatureFlag; import com.android.tradefed.device.DeviceNotAvailableException; import com.android.tradefed.device.ITestDevice; import com.android.tradefed.invoker.TestInformation; @@ -39,8 +40,6 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Objects; -import java.util.regex.Matcher; -import java.util.regex.Pattern; import java.util.stream.Collectors; /** @@ -68,12 +67,6 @@ import java.util.stream.Collectors; @OptionClass(alias = "feature-flags") public class FeatureFlagTargetPreparer extends BaseTargetPreparer { - // Expected flag format (same as output by "device_config list"): - // namespace/name=[value] - // Note value is optional. - private static final Pattern FLAG_PATTERN = - Pattern.compile("^(?<namespace>[^\\s/=]+)/(?<name>[^\\s/=]+)=(?<value>.*)$"); - @Option( name = "flag-file", description = "File containing flag values to apply. Can be repeated.") @@ -201,21 +194,21 @@ public class FeatureFlagTargetPreparer extends BaseTargetPreparer { throws TargetSetupError { Map<String, Map<String, String>> flags = new HashMap<>(); for (String line : lines) { - Matcher match = FLAG_PATTERN.matcher(line); - if (!match.matches()) { + try { + DeviceFeatureFlag deviceFeatureFlag = new DeviceFeatureFlag(line); + flags.computeIfAbsent(deviceFeatureFlag.getNamespace(), ns -> new HashMap<>()) + .put(deviceFeatureFlag.getFlagName(), deviceFeatureFlag.getFlagValue()); + } catch (IllegalArgumentException e) { if (throwIfInvalid) { throw new TargetSetupError( String.format("Failed to parse flag data: %s", line), + e, device.getDeviceDescriptor(), InfraErrorIdentifier.OPTION_CONFIGURATION_ERROR); } CLog.w("Skipping invalid flag data: %s", line); continue; } - String namespace = match.group("namespace"); - String name = match.group("name"); - String value = match.group("value"); - flags.computeIfAbsent(namespace, ns -> new HashMap<>()).put(name, value); } return flags; } |