diff --git a/src/java/com/google/devtools/mobileharness/infra/ats/console/result/report/BUILD b/src/java/com/google/devtools/mobileharness/infra/ats/console/result/report/BUILD index 5e891409a..9f56182f9 100644 --- a/src/java/com/google/devtools/mobileharness/infra/ats/console/result/report/BUILD +++ b/src/java/com/google/devtools/mobileharness/infra/ats/console/result/report/BUILD @@ -201,6 +201,7 @@ java_library( ":certification_suite_info", "//src/java/com/google/devtools/mobileharness/platform/android/xts/suite:suite_common", "//src/java/com/google/devtools/mobileharness/platform/android/xts/suite:test_suite_info", + "//src/java/com/google/devtools/mobileharness/platform/android/xts/suite:test_suite_info_provider", ], ) diff --git a/src/java/com/google/devtools/mobileharness/infra/ats/console/result/report/CertificationSuiteInfoFactory.java b/src/java/com/google/devtools/mobileharness/infra/ats/console/result/report/CertificationSuiteInfoFactory.java index a5fff3bd7..c00f70b6e 100644 --- a/src/java/com/google/devtools/mobileharness/infra/ats/console/result/report/CertificationSuiteInfoFactory.java +++ b/src/java/com/google/devtools/mobileharness/infra/ats/console/result/report/CertificationSuiteInfoFactory.java @@ -18,6 +18,7 @@ import com.google.devtools.mobileharness.platform.android.xts.suite.SuiteCommon; import com.google.devtools.mobileharness.platform.android.xts.suite.TestSuiteInfo; +import com.google.devtools.mobileharness.platform.android.xts.suite.TestSuiteInfoProvider; import java.util.HashMap; import java.util.Map; import java.util.Optional; @@ -85,7 +86,7 @@ public CertificationSuiteInfo createSuiteInfo(Map suiteInfo) { */ public Map generateSuiteInfoMap( String xtsRootDir, String xtsType, String suitePlan) { - TestSuiteInfo testSuiteInfo = TestSuiteInfo.getInstance(xtsRootDir, xtsType); + TestSuiteInfo testSuiteInfo = TestSuiteInfoProvider.getTestSuiteInfo(xtsRootDir, xtsType); Map suiteInfoMap = new HashMap<>(); suiteInfoMap.put(SuiteCommon.SUITE_NAME, testSuiteInfo.getName()); diff --git a/src/java/com/google/devtools/mobileharness/infra/ats/console/util/version/BUILD b/src/java/com/google/devtools/mobileharness/infra/ats/console/util/version/BUILD index f01828674..98a5d9ea1 100644 --- a/src/java/com/google/devtools/mobileharness/infra/ats/console/util/version/BUILD +++ b/src/java/com/google/devtools/mobileharness/infra/ats/console/util/version/BUILD @@ -28,6 +28,7 @@ java_library( "//src/java/com/google/devtools/mobileharness/infra/ats/console:console_info", "//src/java/com/google/devtools/mobileharness/infra/ats/console/util/command:command_helper", "//src/java/com/google/devtools/mobileharness/platform/android/xts/suite:test_suite_info", + "//src/java/com/google/devtools/mobileharness/platform/android/xts/suite:test_suite_info_provider", "//src/java/com/google/devtools/mobileharness/shared/version", "//src/java/com/google/devtools/mobileharness/shared/version:version_util", "@maven//:javax_inject_jsr330_api", diff --git a/src/java/com/google/devtools/mobileharness/infra/ats/console/util/version/VersionMessageUtil.java b/src/java/com/google/devtools/mobileharness/infra/ats/console/util/version/VersionMessageUtil.java index 0cca4542e..349749bb5 100644 --- a/src/java/com/google/devtools/mobileharness/infra/ats/console/util/version/VersionMessageUtil.java +++ b/src/java/com/google/devtools/mobileharness/infra/ats/console/util/version/VersionMessageUtil.java @@ -19,6 +19,7 @@ import com.google.devtools.mobileharness.infra.ats.console.ConsoleInfo; import com.google.devtools.mobileharness.infra.ats.console.util.command.CommandHelper; import com.google.devtools.mobileharness.platform.android.xts.suite.TestSuiteInfo; +import com.google.devtools.mobileharness.platform.android.xts.suite.TestSuiteInfoProvider; import com.google.devtools.mobileharness.shared.version.Version; import com.google.devtools.mobileharness.shared.version.VersionUtil; import java.nio.file.Path; @@ -51,7 +52,8 @@ public class VersionMessageUtil { public String getVersionMessage() { Path xtsRootDir = consoleInfo.getXtsRootDirectoryNonEmpty(); String xtsType = commandHelper.getXtsType(); - TestSuiteInfo testSuiteInfo = TestSuiteInfo.getInstance(xtsRootDir.toString(), xtsType); + TestSuiteInfo testSuiteInfo = + TestSuiteInfoProvider.getTestSuiteInfo(xtsRootDir.toString(), xtsType); String buildNumber = versionParser.fetchVersion(testSuiteInfo).orElseGet(testSuiteInfo::getBuildNumber); String labVersion = Version.LAB_VERSION.toString(); diff --git a/src/java/com/google/devtools/mobileharness/platform/android/xts/suite/BUILD b/src/java/com/google/devtools/mobileharness/platform/android/xts/suite/BUILD index 1815fc18d..e39c1b5ba 100644 --- a/src/java/com/google/devtools/mobileharness/platform/android/xts/suite/BUILD +++ b/src/java/com/google/devtools/mobileharness/platform/android/xts/suite/BUILD @@ -29,7 +29,7 @@ java_library( deps = [ ":abi", ":suite_module_loader", - ":test_suite_info", + ":test_suite_info_provider", "//src/devtools/mobileharness/platform/android/xts/proto:configuration_java_proto", "//src/java/com/google/devtools/mobileharness/api/model/error", "//src/java/com/google/devtools/mobileharness/api/model/error:exception_factory", @@ -84,6 +84,7 @@ java_library( visibility = [ "//src/java/com/google/devtools/mobileharness/infra/ats/console/result/report:__subpackages__", "//src/java/com/google/devtools/mobileharness/infra/ats/console/util/version:__pkg__", + "//src/javatests/com/google/devtools/mobileharness/platform/android/xts/suite:__pkg__", ], deps = [ "//src/java/com/google/devtools/mobileharness/infra/ats/common/plan:jar_file_util", @@ -184,3 +185,20 @@ java_library( "@maven//:javax_inject_jsr330_api", ], ) + +java_library( + name = "test_suite_info_provider", + srcs = ["TestSuiteInfoProvider.java"], + visibility = [ + "//src/java/com/google/devtools/mobileharness/infra/ats/console/result/report:__subpackages__", + "//src/java/com/google/devtools/mobileharness/infra/ats/console/util/version:__pkg__", + "//src/javatests/com/google/devtools/mobileharness/platform/android/xts/suite:__pkg__", + ], + deps = [ + ":test_suite_info", + "//src/java/com/google/devtools/mobileharness/infra/ats/common/plan:jar_file_util", + "//src/java/com/google/devtools/mobileharness/shared/util/auto:auto_value", + "//src/java/com/google/devtools/mobileharness/shared/util/logging:google_logger", + "@maven//:com_google_guava_guava", + ], +) diff --git a/src/java/com/google/devtools/mobileharness/platform/android/xts/suite/TestSuiteHelper.java b/src/java/com/google/devtools/mobileharness/platform/android/xts/suite/TestSuiteHelper.java index 162932610..1655100c2 100644 --- a/src/java/com/google/devtools/mobileharness/platform/android/xts/suite/TestSuiteHelper.java +++ b/src/java/com/google/devtools/mobileharness/platform/android/xts/suite/TestSuiteHelper.java @@ -201,7 +201,8 @@ private File getTestsDir() throws MobileHarnessException { /** Gets the possible abis from the TestSuiteInfo. */ public Set getAbisForBuildTargetArchFromSuite() { Set abis = new LinkedHashSet<>(); - for (String arch : TestSuiteInfo.getInstance(xtsRootDir, xtsType).getTargetArchs()) { + for (String arch : + TestSuiteInfoProvider.getTestSuiteInfo(xtsRootDir, xtsType).getTargetArchs()) { abis.addAll(AbiUtil.getAbisForArch(arch)); } return abis; diff --git a/src/java/com/google/devtools/mobileharness/platform/android/xts/suite/TestSuiteInfo.java b/src/java/com/google/devtools/mobileharness/platform/android/xts/suite/TestSuiteInfo.java index 0d7fa6c02..c5dc54e27 100644 --- a/src/java/com/google/devtools/mobileharness/platform/android/xts/suite/TestSuiteInfo.java +++ b/src/java/com/google/devtools/mobileharness/platform/android/xts/suite/TestSuiteInfo.java @@ -47,15 +47,12 @@ public class TestSuiteInfo { private static final String FULLNAME = "fullname"; private static final String VERSION = "version"; - @SuppressWarnings("NonFinalStaticField") - private static volatile TestSuiteInfo instance; - private Properties testSuiteInfoProps; private final JarFileUtil jarFileUtil; private final String xtsRootDir; private final String xtsTypeStr; - private TestSuiteInfo(String xtsRootDir, String xtsType, JarFileUtil jarFileUtil) { + TestSuiteInfo(String xtsRootDir, String xtsType, JarFileUtil jarFileUtil) { this.jarFileUtil = jarFileUtil; this.xtsRootDir = xtsRootDir; this.xtsTypeStr = xtsType; @@ -96,24 +93,6 @@ private Properties loadSuiteInfoFromInputStream(InputStream testSuiteInfoPropsIn return props; } - /** - * Retrieves the singleton instance, which also triggers loading of the related test suite info - * from embedded resource files - */ - public static TestSuiteInfo getInstance(String xtsRootDir, String xtsType) { - if (instance == null) { - synchronized (TestSuiteInfo.class) { - if (instance == null) { - logger.atFine().log( - "Creating %s instance with params [xts root dir: %s, xts type: %s]", - TestSuiteInfo.class.getSimpleName(), xtsRootDir, xtsType); - instance = new TestSuiteInfo(xtsRootDir, xtsType, new JarFileUtil()); - } - } - } - return instance; - } - /** Gets the build number of the test suite. */ public String getBuildNumber() { return testSuiteInfoProps.getProperty(BUILD_NUMBER); diff --git a/src/java/com/google/devtools/mobileharness/platform/android/xts/suite/TestSuiteInfoProvider.java b/src/java/com/google/devtools/mobileharness/platform/android/xts/suite/TestSuiteInfoProvider.java new file mode 100644 index 000000000..82cc475e5 --- /dev/null +++ b/src/java/com/google/devtools/mobileharness/platform/android/xts/suite/TestSuiteInfoProvider.java @@ -0,0 +1,79 @@ +/* + * Copyright 2022 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 + * + * https://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.google.devtools.mobileharness.platform.android.xts.suite; + +import com.google.auto.value.AutoValue; +import com.google.common.cache.CacheBuilder; +import com.google.common.cache.CacheLoader; +import com.google.common.cache.LoadingCache; +import com.google.common.flogger.FluentLogger; +import com.google.devtools.mobileharness.infra.ats.common.plan.JarFileUtil; +import java.util.concurrent.ExecutionException; + +/** A provider for {@link TestSuiteInfo}. */ +public final class TestSuiteInfoProvider { + + private static final FluentLogger logger = FluentLogger.forEnclosingClass(); + + @AutoValue + abstract static class CacheKey { + abstract String xtsRootDir(); + + abstract String xtsType(); + + static CacheKey create(String xtsRootDir, String xtsType) { + return new AutoValue_TestSuiteInfoProvider_CacheKey(xtsRootDir, xtsType); + } + } + + private static final LoadingCache cache = + CacheBuilder.newBuilder() + .maximumSize(1000) + .build( + new CacheLoader() { + @Override + public TestSuiteInfo load(CacheKey key) { + logger.atFine().log( + "Creating %s instance with params [xts root dir: %s, xts type: %s]", + TestSuiteInfo.class.getSimpleName(), key.xtsRootDir(), key.xtsType()); + return new TestSuiteInfo(key.xtsRootDir(), key.xtsType(), new JarFileUtil()); + } + }); + + /** + * Gets the {@link TestSuiteInfo} for the given xTS root directory and xTS type. Cache is used to + * avoid creating the same test suite info multiple times. + * + * @param xtsRootDir the xTS root directory + * @param xtsType the xTS type + * @return the {@link TestSuiteInfo} for the given xTS root directory and xTS type + * @throws IllegalStateException if there is an error loading the test suite info + */ + public static TestSuiteInfo getTestSuiteInfo(String xtsRootDir, String xtsType) { + try { + return cache.get(CacheKey.create(xtsRootDir, xtsType)); + } catch (ExecutionException e) { + throw new IllegalStateException( + String.format( + "Error loading test suite info for xts root dir \"%s\" and xts type \"%s\"", + xtsRootDir, xtsType), + e); + } + } + + private TestSuiteInfoProvider() {} +}