Annotation for package in FrameworkRobolectricTestRunner

Makes it easier to maintain the tests.

Test: m -j RunFrameworksServicesRoboTests
Change-Id: I798b7c980b4e3426baa6a205d4ca16f82b42109d
This commit is contained in:
Bernardo Rufino
2018-01-30 17:43:47 +00:00
parent 88ca395b5b
commit 03b767733c
8 changed files with 79 additions and 48 deletions

View File

@@ -26,6 +26,7 @@ import android.provider.Settings;
import com.android.server.testing.FrameworkRobolectricTestRunner;
import com.android.server.testing.SystemLoaderClasses;
import com.android.server.testing.SystemLoaderPackages;
import org.junit.Before;
import org.junit.Test;
@@ -36,7 +37,7 @@ import org.robolectric.annotation.Config;
@RunWith(FrameworkRobolectricTestRunner.class)
@Config(manifest = Config.NONE, sdk = 26)
@SystemLoaderClasses({BackupManagerConstants.class})
@SystemLoaderPackages({"com.android.server.backup"})
@Presubmit
public class BackupManagerConstantsTest {
private static final String PACKAGE_NAME = "some.package.name";

View File

@@ -48,7 +48,8 @@ import com.android.server.backup.testing.TransportData;
import com.android.server.backup.testing.TransportTestUtils.TransportMock;
import com.android.server.backup.transport.TransportNotRegisteredException;
import com.android.server.testing.FrameworkRobolectricTestRunner;
import com.android.server.testing.SystemLoaderClasses;
import com.android.server.testing.SystemLoaderPackages;
import java.io.File;
import java.util.HashMap;
import java.util.List;
@@ -74,11 +75,7 @@ import org.robolectric.shadows.ShadowSystemClock;
sdk = 26,
shadows = {ShadowAppBackupUtils.class, ShadowBackupPolicyEnforcer.class}
)
@SystemLoaderClasses({
BackupManagerService.class,
TransportManager.class,
PackageManagerBackupAgent.class
})
@SystemLoaderPackages({"com.android.server.backup"})
@Presubmit
public class BackupManagerServiceTest {
private static final String TAG = "BMSTest";

View File

@@ -69,6 +69,7 @@ import com.android.server.backup.testing.TransportTestUtils.TransportMock;
import com.android.server.backup.transport.TransportClient;
import com.android.server.testing.FrameworkRobolectricTestRunner;
import com.android.server.testing.SystemLoaderClasses;
import com.android.server.testing.SystemLoaderPackages;
import com.android.server.testing.shadows.FrameworkShadowPackageManager;
import com.android.server.testing.shadows.ShadowBackupDataInput;
import com.android.server.testing.shadows.ShadowBackupDataOutput;
@@ -102,12 +103,10 @@ import java.util.stream.Stream;
ShadowQueuedWork.class
}
)
@SystemLoaderPackages({"com.android.server.backup"})
@SystemLoaderClasses({
BackupManagerService.class,
PerformBackupTask.class,
BackupDataOutput.class,
FullBackupDataOutput.class,
TransportManager.class,
BackupAgent.class,
IBackupTransport.class,
IBackupAgent.class,

View File

@@ -51,7 +51,7 @@ import com.android.server.backup.transport.TransportClient;
import com.android.server.backup.transport.TransportClientManager;
import com.android.server.backup.transport.TransportNotRegisteredException;
import com.android.server.testing.FrameworkRobolectricTestRunner;
import com.android.server.testing.SystemLoaderClasses;
import com.android.server.testing.SystemLoaderPackages;
import com.android.server.testing.shadows.FrameworkShadowContextImpl;
import com.android.server.testing.shadows.FrameworkShadowPackageManager;
import java.util.ArrayList;
@@ -75,7 +75,7 @@ import org.robolectric.shadows.ShadowPackageManager;
sdk = 26,
shadows = {FrameworkShadowPackageManager.class, FrameworkShadowContextImpl.class}
)
@SystemLoaderClasses({TransportManager.class})
@SystemLoaderPackages({"com.android.server.backup"})
@Presubmit
public class TransportManagerTest {
private static final String PACKAGE_A = "some.package.a";

View File

@@ -49,7 +49,7 @@ import com.android.server.backup.testing.TransportData;
import com.android.server.backup.testing.TransportTestUtils.TransportMock;
import com.android.server.backup.transport.TransportClient;
import com.android.server.testing.FrameworkRobolectricTestRunner;
import com.android.server.testing.SystemLoaderClasses;
import com.android.server.testing.SystemLoaderPackages;
import org.junit.Before;
import org.junit.Test;
@@ -67,11 +67,7 @@ import java.util.stream.Stream;
@RunWith(FrameworkRobolectricTestRunner.class)
@Config(manifest = Config.NONE, sdk = 26)
@SystemLoaderClasses({
BackupManagerService.class,
PerformInitializeTaskTest.class,
TransportManager.class
})
@SystemLoaderPackages({"com.android.server.backup"})
@Presubmit
public class PerformInitializeTaskTest {
@Mock private BackupManagerService mBackupManagerService;

View File

@@ -46,6 +46,7 @@ import com.android.server.EventLogTags;
import com.android.server.backup.TransportManager;
import com.android.server.testing.FrameworkRobolectricTestRunner;
import com.android.server.testing.SystemLoaderClasses;
import com.android.server.testing.SystemLoaderPackages;
import com.android.server.testing.shadows.ShadowCloseGuard;
import com.android.server.testing.shadows.ShadowEventLog;
import com.android.server.testing.shadows.ShadowSlog;
@@ -66,7 +67,7 @@ import org.robolectric.shadows.ShadowLooper;
sdk = 26,
shadows = {ShadowEventLog.class, ShadowCloseGuard.class, ShadowSlog.class}
)
@SystemLoaderClasses({TransportManager.class, TransportClient.class})
@SystemLoaderPackages({"com.android.server.backup"})
@Presubmit
public class TransportClientTest {
private static final String PACKAGE_NAME = "some.package.name";

View File

@@ -16,8 +16,7 @@
package com.android.server.testing;
import com.android.server.backup.PerformBackupTaskTest;
import com.android.server.backup.internal.PerformBackupTask;
import static java.util.Arrays.asList;
import com.google.common.collect.ImmutableSet;
@@ -33,10 +32,11 @@ import org.robolectric.util.Util;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Set;
import java.util.stream.Stream;
import javax.annotation.Nonnull;
@@ -51,9 +51,9 @@ import javax.annotation.Nonnull;
* against the actual classes that are in the tree, not a past version of them. Ideally we would
* have a locally built jar referenced by Robolectric, but until that happens one can use this
* class.
* This class reads the {@link SystemLoaderClasses} annotation on test classes and for each class
* in that annotation value it will bypass the android jar and load it from the system class loader.
* Allowing the test to test the actual class in the tree.
* This class reads the {@link SystemLoaderClasses} or {@link SystemLoaderPackages} annotations on
* test classes, for classes that match the annotations it will bypass the android jar and load it
* from the system class loader. Allowing the test to test the actual class in the tree.
*
* Implementation note: One could think about overriding
* {@link RobolectricTestRunner#createClassLoaderConfig(FrameworkMethod)} method and putting the
@@ -72,11 +72,21 @@ public class FrameworkRobolectricTestRunner extends RobolectricTestRunner {
public FrameworkRobolectricTestRunner(Class<?> testClass) throws InitializationError {
super(testClass);
SystemLoaderClasses annotation = testClass.getAnnotation(SystemLoaderClasses.class);
Class<?>[] systemLoaderClasses =
(annotation != null) ? annotation.value() : new Class<?>[0];
Set<String> systemLoaderClassNames = classesToClassNames(systemLoaderClasses);
mSandboxFactory = new FrameworkSandboxFactory(systemLoaderClassNames);
Set<String> classPrefixes = getSystemLoaderClassPrefixes(testClass);
mSandboxFactory = new FrameworkSandboxFactory(classPrefixes);
}
private Set<String> getSystemLoaderClassPrefixes(Class<?> testClass) {
Set<String> classPrefixes = new HashSet<>();
SystemLoaderClasses byClass = testClass.getAnnotation(SystemLoaderClasses.class);
if (byClass != null) {
Stream.of(byClass.value()).map(Class::getName).forEach(classPrefixes::add);
}
SystemLoaderPackages byPackage = testClass.getAnnotation(SystemLoaderPackages.class);
if (byPackage != null) {
classPrefixes.addAll(asList(byPackage.value()));
}
return classPrefixes;
}
@Nonnull
@@ -92,15 +102,15 @@ public class FrameworkRobolectricTestRunner extends RobolectricTestRunner {
}
private static class FrameworkClassLoader extends SandboxClassLoader {
private final Set<String> mSystemLoaderClasses;
private final Set<String> mSystemLoaderClassPrefixes;
private FrameworkClassLoader(
Set<String> systemLoaderClasses,
Set<String> systemLoaderClassPrefixes,
ClassLoader systemClassLoader,
InstrumentationConfiguration instrumentationConfig,
URL... urls) {
super(systemClassLoader, instrumentationConfig, urls);
mSystemLoaderClasses = systemLoaderClasses;
mSystemLoaderClassPrefixes = systemLoaderClassPrefixes;
}
@Override
@@ -146,8 +156,8 @@ public class FrameworkRobolectricTestRunner extends RobolectricTestRunner {
* loader, so we test if the classes in the annotation are prefixes of the class to load.
*/
private boolean shouldLoadFromSystemLoader(String className) {
for (String classNamePrefix : mSystemLoaderClasses) {
if (className.startsWith(classNamePrefix)) {
for (String classPrefix : mSystemLoaderClassPrefixes) {
if (className.startsWith(classPrefix)) {
return true;
}
}
@@ -156,10 +166,10 @@ public class FrameworkRobolectricTestRunner extends RobolectricTestRunner {
}
private static class FrameworkSandboxFactory extends SandboxFactory {
private final Set<String> mSystemLoaderClasses;
private final Set<String> mSystemLoaderClassPrefixes;
private FrameworkSandboxFactory(Set<String> systemLoaderClasses) {
mSystemLoaderClasses = systemLoaderClasses;
private FrameworkSandboxFactory(Set<String> systemLoaderClassPrefixes) {
mSystemLoaderClassPrefixes = systemLoaderClassPrefixes;
}
@Nonnull
@@ -167,18 +177,10 @@ public class FrameworkRobolectricTestRunner extends RobolectricTestRunner {
public ClassLoader createClassLoader(
InstrumentationConfiguration instrumentationConfig, URL... urls) {
return new FrameworkClassLoader(
mSystemLoaderClasses,
mSystemLoaderClassPrefixes,
ClassLoader.getSystemClassLoader(),
instrumentationConfig,
urls);
}
}
private static Set<String> classesToClassNames(Class<?>[] classes) {
ImmutableSet.Builder<String> builder = ImmutableSet.builder();
for (Class<?> classObject : classes) {
builder.add(classObject.getName());
}
return builder.build();
}
}

View File

@@ -0,0 +1,35 @@
/*
* Copyright (C) 2018 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.server.testing;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Annotation to be used in test classes that run with {@link FrameworkRobolectricTestRunner}.
* This will make the classes under the specified packages be loaded from the system class loader,
* NOT from the Robolectric android jar.
*
* @see FrameworkRobolectricTestRunner
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface SystemLoaderPackages {
String[] value() default {};
}