aboutsummaryrefslogtreecommitdiff
path: root/android/guava-tests/test/com/google/common/util/concurrent/AbstractFutureFallbackAtomicHelperTest.java
diff options
context:
space:
mode:
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.java143
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);
- }
- };
- }
-}