Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit de521a1b authored by Zhi Dou's avatar Zhi Dou Committed by Gerrit Code Review
Browse files

Merge changes from topic "fakefeatureflagsimpl" into main

* changes:
  Add setFlag and resetAll in FeatureFlags test mode
  Generate FakeFeatureFlagsImpl in test mode
parents aea0819f a7200115
Loading
Loading
Loading
Loading
+20 −1
Original line number Diff line number Diff line
@@ -101,7 +101,7 @@ java_aconfig_library {
android_test {
    name: "aconfig.test.java",
    srcs: [
        "tests/**/*.java",
        "tests/AconfigTest.java",
    ],
    manifest: "tests/AndroidManifest.xml",
    certificate: "platform",
@@ -113,6 +113,25 @@ android_test {
    test_suites: ["device-tests"],
}

java_aconfig_library {
    name: "aconfig_host_test_java_library",
    aconfig_declarations: "aconfig.test.flags",
    host_supported: true,
    test: true,
}

java_test_host {
    name: "AconfigJavaHostTest",
    srcs: [
        "tests/AconfigHostTest.java",
    ],
    static_libs: [
        "aconfig_host_test_java_library",
        "junit",
    ],
    test_suites: ["general-tests"],
}

// integration tests: C++

cc_aconfig_library {
+87 −12
Original line number Diff line number Diff line
@@ -47,9 +47,13 @@ where
        "FeatureFlags.java",
        include_str!("../templates/FeatureFlags.java.template"),
    )?;
    template.add_template(
        "FakeFeatureFlagsImpl.java",
        include_str!("../templates/FakeFeatureFlagsImpl.java.template"),
    )?;

    let path: PathBuf = package.split('.').collect();
    ["Flags.java", "FeatureFlagsImpl.java", "FeatureFlags.java"]
    ["Flags.java", "FeatureFlags.java", "FeatureFlagsImpl.java", "FakeFeatureFlagsImpl.java"]
        .iter()
        .map(|file| {
            Ok(OutputFile {
@@ -112,14 +116,14 @@ mod tests {
    use super::*;
    use std::collections::HashMap;

    const EXPECTED_FEATUREFLAGS_CONTENT: &str = r#"
    const EXPECTED_FEATUREFLAGS_COMMON_CONTENT: &str = r#"
    package com.android.aconfig.test;
    public interface FeatureFlags {
        boolean disabledRo();
        boolean disabledRw();
        boolean enabledRo();
        boolean enabledRw();
    }"#;
    "#;

    const EXPECTED_FLAG_COMMON_CONTENT: &str = r#"
    package com.android.aconfig.test;
@@ -143,6 +147,29 @@ mod tests {
        }
    "#;

    const EXPECTED_METHOD_NOT_IMPL_COMMON_CONTENT: &str = r#"
        @Override
        public boolean disabledRo() {
            throw new UnsupportedOperationException(
                "Method is not implemented.");
        }
        @Override
        public boolean disabledRw() {
            throw new UnsupportedOperationException(
                "Method is not implemented.");
        }
        @Override
        public boolean enabledRo() {
            throw new UnsupportedOperationException(
                "Method is not implemented.");
        }
        @Override
        public boolean enabledRw() {
            throw new UnsupportedOperationException(
                "Method is not implemented.");
        }
    "#;

    #[test]
    fn test_generate_java_code_production() {
        let parsed_flags = crate::test::parse_test_flags();
@@ -152,11 +179,22 @@ mod tests {
            CodegenMode::Production,
        )
        .unwrap();
        let expect_featureflags_content = EXPECTED_FEATUREFLAGS_COMMON_CONTENT.to_string()
            + r#"
        }"#;
        let expect_flags_content = EXPECTED_FLAG_COMMON_CONTENT.to_string()
            + r#"
            private static FeatureFlags FEATURE_FLAGS = new FeatureFlagsImpl();
        }"#;
        let expected_featureflagsimpl_content = r#"
        let expect_fakefeatureflagsimpl_content = r#"
        package com.android.aconfig.test;
        public class FakeFeatureFlagsImpl implements FeatureFlags {"#
            .to_owned()
            + EXPECTED_METHOD_NOT_IMPL_COMMON_CONTENT
            + r#"
        }
        "#;
        let expect_featureflagsimpl_content = r#"
        package com.android.aconfig.test;
        import android.provider.DeviceConfig;
        public final class FeatureFlagsImpl implements FeatureFlags {
@@ -188,8 +226,12 @@ mod tests {
        "#;
        let mut file_set = HashMap::from([
            ("com/android/aconfig/test/Flags.java", expect_flags_content.as_str()),
            ("com/android/aconfig/test/FeatureFlagsImpl.java", expected_featureflagsimpl_content),
            ("com/android/aconfig/test/FeatureFlags.java", EXPECTED_FEATUREFLAGS_CONTENT),
            ("com/android/aconfig/test/FeatureFlagsImpl.java", expect_featureflagsimpl_content),
            ("com/android/aconfig/test/FeatureFlags.java", expect_featureflags_content.as_str()),
            (
                "com/android/aconfig/test/FakeFeatureFlagsImpl.java",
                expect_fakefeatureflagsimpl_content.as_str(),
            ),
        ]);

        for file in generated_files {
@@ -219,24 +261,47 @@ mod tests {
            CodegenMode::Test,
        )
        .unwrap();
        let expect_featureflags_content = EXPECTED_FEATUREFLAGS_COMMON_CONTENT.to_string()
            + r#"
            public void setFlag(String flagName, boolean value);
            public void resetAll();
        }"#;
        let expect_flags_content = EXPECTED_FLAG_COMMON_CONTENT.to_string()
            + r#"
            public static void setFeatureFlagsImpl(FeatureFlags featureFlags) {
            public static void setFeatureFlags(FeatureFlags featureFlags) {
                Flags.FEATURE_FLAGS = featureFlags;
            }
            public static void unsetFeatureFlagsImpl() {
            public static void unsetFeatureFlags() {
                Flags.FEATURE_FLAGS = null;
            }
            private static FeatureFlags FEATURE_FLAGS;
        }
        "#;
        let expected_featureflagsimpl_content = r#"
        let expect_featureflagsimpl_content = r#"
        package com.android.aconfig.test;
        public final class FeatureFlagsImpl implements FeatureFlags {"#
            .to_owned()
            + EXPECTED_METHOD_NOT_IMPL_COMMON_CONTENT
            + r#"
            @Override
            public void setFlag(String flagName, boolean value) {
                throw new UnsupportedOperationException(
                    "Method is not implemented.");
            }
            @Override
            public void resetAll() {
                throw new UnsupportedOperationException(
                    "Method is not implemented.");
            }
        }
        "#;
        let expect_fakefeatureflagsimpl_content = r#"
        package com.android.aconfig.test;
        import static java.util.stream.Collectors.toMap;
        import java.util.HashMap;
        import java.util.Map;
        import java.util.stream.Stream;
        public final class FeatureFlagsImpl implements FeatureFlags {
        public class FakeFeatureFlagsImpl implements FeatureFlags {
            @Override
            public boolean disabledRo() {
                return getFlag(Flags.FLAG_DISABLED_RO);
@@ -253,12 +318,14 @@ mod tests {
            public boolean enabledRw() {
                return getFlag(Flags.FLAG_ENABLED_RW);
            }
            @Override
            public void setFlag(String flagName, boolean value) {
                if (!this.mFlagMap.containsKey(flagName)) {
                    throw new IllegalArgumentException("no such flag" + flagName);
                }
                this.mFlagMap.put(flagName, value);
            }
            @Override
            public void resetAll() {
                for (Map.Entry entry : mFlagMap.entrySet()) {
                    entry.setValue(null);
@@ -284,10 +351,18 @@ mod tests {
                );
        }
        "#;

        let mut file_set = HashMap::from([
            ("com/android/aconfig/test/Flags.java", expect_flags_content.as_str()),
            ("com/android/aconfig/test/FeatureFlagsImpl.java", expected_featureflagsimpl_content),
            ("com/android/aconfig/test/FeatureFlags.java", EXPECTED_FEATUREFLAGS_CONTENT),
            ("com/android/aconfig/test/FeatureFlags.java", expect_featureflags_content.as_str()),
            (
                "com/android/aconfig/test/FeatureFlagsImpl.java",
                expect_featureflagsimpl_content.as_str(),
            ),
            (
                "com/android/aconfig/test/FakeFeatureFlagsImpl.java",
                expect_fakefeatureflagsimpl_content,
            ),
        ]);

        for file in generated_files {
+61 −0
Original line number Diff line number Diff line
package {package_name};
{{ if is_test_mode }}
import static java.util.stream.Collectors.toMap;

import java.util.HashMap;
import java.util.Map;
import java.util.stream.Stream;

public class FakeFeatureFlagsImpl implements FeatureFlags \{
{{ for item in class_elements}}
    @Override
    public boolean {item.method_name}() \{
        return getFlag(Flags.FLAG_{item.flag_name_constant_suffix});
    }
{{ endfor}}
    @Override
    public void setFlag(String flagName, boolean value) \{
        if (!this.mFlagMap.containsKey(flagName)) \{
            throw new IllegalArgumentException("no such flag" + flagName);
        }
        this.mFlagMap.put(flagName, value);
    }

    @Override
    public void resetAll() \{
        for (Map.Entry entry : mFlagMap.entrySet()) \{
            entry.setValue(null);
        }
    }

    private boolean getFlag(String flagName) \{
        Boolean value = this.mFlagMap.get(flagName);
        if (value == null) \{
            throw new IllegalArgumentException(flagName + " is not set");
        }
        return value;
    }

    private HashMap<String, Boolean> mFlagMap = Stream.of(
            {{-for item in class_elements}}
            Flags.FLAG_{item.flag_name_constant_suffix}{{ if not @last }},{{ endif }}
            {{ -endfor }}
        )
        .collect(
            HashMap::new,
            (map, elem) -> map.put(elem, null),
            HashMap::putAll
        );
}
{{ else }}
{#- Generate only stub if in prod mode #}
public class FakeFeatureFlagsImpl implements FeatureFlags \{
{{ for item in class_elements}}
    @Override
    public boolean {item.method_name}() \{
        throw new UnsupportedOperationException(
            "Method is not implemented.");
    }
{{ endfor}}
}
{{ endif }}
+6 −0
Original line number Diff line number Diff line
@@ -4,4 +4,10 @@ public interface FeatureFlags \{
{{ for item in class_elements}}
    boolean {item.method_name}();
{{ endfor }}

{{ -if is_test_mode }}
    public void setFlag(String flagName, boolean value);

    public void resetAll();
{{ -endif }}
}
+22 −43
Original line number Diff line number Diff line
package {package_name};
{{ -if is_test_mode }}
import static java.util.stream.Collectors.toMap;

import java.util.HashMap;
import java.util.Map;
import java.util.stream.Stream;
{{ else}}
{{ if not is_test_mode }}
{{ if is_read_write- }}
import android.provider.DeviceConfig;
{{ -endif- }}
{{ endif }}
public final class FeatureFlagsImpl implements FeatureFlags \{
{{ for item in class_elements}}
    @Override
    public boolean {item.method_name}() \{
        {{ -if not is_test_mode- }}
        {{ if item.is_read_write }}
    {{ -if item.is_read_write }}
        return DeviceConfig.getBoolean(
            "{item.device_config_namespace}",
            "{item.device_config_flag}",
            {item.default_value}
        );
        {{ -else }}
    {{ else }}
        return {item.default_value};
        {{ -endif- }}
    {{ endif- }}
    }
{{ endfor- }}
}
{{ else }}
        return getFlag(Flags.FLAG_{item.flag_name_constant_suffix});
        {{ -endif }}
{#- Generate only stub if in test mode #}
public final class FeatureFlagsImpl implements FeatureFlags \{
{{ for item in class_elements}}
    @Override
    public boolean {item.method_name}() \{
        throw new UnsupportedOperationException(
            "Method is not implemented.");
    }
{{ endfor- }}
{{ if is_test_mode }}
    @Override
    public void setFlag(String flagName, boolean value) \{
        if (!this.mFlagMap.containsKey(flagName)) \{
            throw new IllegalArgumentException("no such flag" + flagName);
        }
        this.mFlagMap.put(flagName, value);
        throw new UnsupportedOperationException(
            "Method is not implemented.");
    }

    @Override
    public void resetAll() \{
        for (Map.Entry entry : mFlagMap.entrySet()) \{
            entry.setValue(null);
        }
    }

    private boolean getFlag(String flagName) \{
        Boolean value = this.mFlagMap.get(flagName);
        if (value == null) \{
            throw new IllegalArgumentException(flagName + " is not set");
        throw new UnsupportedOperationException(
            "Method is not implemented.");
    }
        return value;
    }

    private HashMap<String, Boolean> mFlagMap = Stream.of(
            {{-for item in class_elements}}
            Flags.FLAG_{item.flag_name_constant_suffix}{{ if not @last }},{{ endif }}
            {{ -endfor }}
        )
        .collect(
            HashMap::new,
            (map, elem) -> map.put(elem, null),
            HashMap::putAll
        );
{{ -endif }}
}
{{ endif }}
Loading