diff options
Diffstat (limited to 'android/guava-tests/test/com/google/common/util/concurrent/AbstractFutureFallbackAtomicHelperTest.java')
-rw-r--r-- | android/guava-tests/test/com/google/common/util/concurrent/AbstractFutureFallbackAtomicHelperTest.java | 143 |
1 files changed, 0 insertions, 143 deletions
diff --git a/android/guava-tests/test/com/google/common/util/concurrent/AbstractFutureFallbackAtomicHelperTest.java b/android/guava-tests/test/com/google/common/util/concurrent/AbstractFutureFallbackAtomicHelperTest.java deleted file mode 100644 index d075f8016..000000000 --- a/android/guava-tests/test/com/google/common/util/concurrent/AbstractFutureFallbackAtomicHelperTest.java +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Copyright (C) 2015 The Guava Authors - * - * 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.google.common.util.concurrent; - -import com.google.common.collect.ImmutableSet; -import java.lang.reflect.Field; -import java.lang.reflect.Method; -import java.lang.reflect.Modifier; -import java.net.URLClassLoader; -import java.util.Set; -import java.util.concurrent.atomic.AtomicReferenceFieldUpdater; -import junit.framework.TestCase; -import junit.framework.TestSuite; - -/** - * Tests our AtomicHelper fallback strategies in AbstractFuture. - * - * <p>On different platforms AbstractFuture uses different strategies for its core synchronization - * primitives. The strategies are all implemented as subtypes of AtomicHelper and the strategy is - * selected in the static initializer of AbstractFuture. This is convenient and performant but - * introduces some testing difficulties. This test exercises the two fallback strategies in abstract - * future. - * - * <ul> - * <li>SafeAtomicHelper: uses AtomicReferenceFieldsUpdaters to implement synchronization - * <li>SynchronizedHelper: uses {@code synchronized} blocks for synchronization - * </ul> - * - * To force selection of our fallback strategies we load {@link AbstractFuture} (and all of {@code - * com.google.common.util.concurrent} in degenerate class loaders which make certain platform - * classes unavailable. Then we construct a test suite so we can run the normal AbstractFutureTest - * test methods in these degenerate classloaders. - */ - -public class AbstractFutureFallbackAtomicHelperTest extends TestCase { - - // stash these in static fields to avoid loading them over and over again (speeds up test - // execution significantly) - - /** - * This classloader disallows {@link sun.misc.Unsafe}, which will prevent us from selecting our - * preferred strategy {@code UnsafeAtomicHelper}. - */ - private static final ClassLoader NO_UNSAFE = - getClassLoader(ImmutableSet.of(sun.misc.Unsafe.class.getName())); - - /** - * This classloader disallows {@link sun.misc.Unsafe} and {@link AtomicReferenceFieldUpdater}, - * which will prevent us from selecting our {@code SafeAtomicHelper} strategy. - */ - private static final ClassLoader NO_ATOMIC_REFERENCE_FIELD_UPDATER = - getClassLoader( - ImmutableSet.of( - sun.misc.Unsafe.class.getName(), AtomicReferenceFieldUpdater.class.getName())); - - public static TestSuite suite() { - // we create a test suite containing a test for every AbstractFutureTest test method and we - // set it as the name of the test. Then in runTest we can reflectively load and invoke the - // corresponding method on AbstractFutureTest in the correct classloader. - TestSuite suite = new TestSuite(AbstractFutureFallbackAtomicHelperTest.class.getName()); - for (Method method : AbstractFutureTest.class.getDeclaredMethods()) { - if (Modifier.isPublic(method.getModifiers()) && method.getName().startsWith("test")) { - suite.addTest( - TestSuite.createTest(AbstractFutureFallbackAtomicHelperTest.class, method.getName())); - } - } - return suite; - } - - @Override - public void runTest() throws Exception { - // First ensure that our classloaders are initializing the correct helper versions - checkHelperVersion(getClass().getClassLoader(), "UnsafeAtomicHelper"); - checkHelperVersion(NO_UNSAFE, "SafeAtomicHelper"); - checkHelperVersion(NO_ATOMIC_REFERENCE_FIELD_UPDATER, "SynchronizedHelper"); - - // Run the corresponding AbstractFutureTest test method in a new classloader that disallows - // certain core jdk classes. - ClassLoader oldClassLoader = Thread.currentThread().getContextClassLoader(); - Thread.currentThread().setContextClassLoader(NO_UNSAFE); - try { - runTestMethod(NO_UNSAFE); - } finally { - Thread.currentThread().setContextClassLoader(oldClassLoader); - } - - Thread.currentThread().setContextClassLoader(NO_ATOMIC_REFERENCE_FIELD_UPDATER); - try { - runTestMethod(NO_ATOMIC_REFERENCE_FIELD_UPDATER); - // TODO(lukes): assert that the logs are full of errors - } finally { - Thread.currentThread().setContextClassLoader(oldClassLoader); - } - } - - private void runTestMethod(ClassLoader classLoader) throws Exception { - Class<?> test = classLoader.loadClass(AbstractFutureTest.class.getName()); - test.getMethod(getName()).invoke(test.newInstance()); - } - - private void checkHelperVersion(ClassLoader classLoader, String expectedHelperClassName) - throws Exception { - // Make sure we are actually running with the expected helper implementation - Class<?> abstractFutureClass = classLoader.loadClass(AbstractFuture.class.getName()); - Field helperField = abstractFutureClass.getDeclaredField("ATOMIC_HELPER"); - helperField.setAccessible(true); - assertEquals(expectedHelperClassName, helperField.get(null).getClass().getSimpleName()); - } - - private static ClassLoader getClassLoader(final Set<String> disallowedClassNames) { - final String concurrentPackage = SettableFuture.class.getPackage().getName(); - ClassLoader classLoader = AbstractFutureFallbackAtomicHelperTest.class.getClassLoader(); - // we delegate to the current classloader so both loaders agree on classes like TestCase - return new URLClassLoader(ClassPathUtil.getClassPathUrls(), classLoader) { - @Override - public Class<?> loadClass(String name) throws ClassNotFoundException { - if (disallowedClassNames.contains(name)) { - throw new ClassNotFoundException("I'm sorry Dave, I'm afraid I can't do that."); - } - if (name.startsWith(concurrentPackage)) { - Class<?> c = findLoadedClass(name); - if (c == null) { - return super.findClass(name); - } - return c; - } - return super.loadClass(name); - } - }; - } -} |