Index: third_party/protobuf/java/core/src/test/java/com/google/protobuf/ExtensionRegistryFactoryTest.java |
diff --git a/third_party/protobuf/java/core/src/test/java/com/google/protobuf/ExtensionRegistryFactoryTest.java b/third_party/protobuf/java/core/src/test/java/com/google/protobuf/ExtensionRegistryFactoryTest.java |
new file mode 100644 |
index 0000000000000000000000000000000000000000..6157e58966bca23edfa1065072997804ed13e32a |
--- /dev/null |
+++ b/third_party/protobuf/java/core/src/test/java/com/google/protobuf/ExtensionRegistryFactoryTest.java |
@@ -0,0 +1,276 @@ |
+// Protocol Buffers - Google's data interchange format |
+// Copyright 2008 Google Inc. All rights reserved. |
+// https://developers.google.com/protocol-buffers/ |
+// |
+// Redistribution and use in source and binary forms, with or without |
+// modification, are permitted provided that the following conditions are |
+// met: |
+// |
+// * Redistributions of source code must retain the above copyright |
+// notice, this list of conditions and the following disclaimer. |
+// * Redistributions in binary form must reproduce the above |
+// copyright notice, this list of conditions and the following disclaimer |
+// in the documentation and/or other materials provided with the |
+// distribution. |
+// * Neither the name of Google Inc. nor the names of its |
+// contributors may be used to endorse or promote products derived from |
+// this software without specific prior written permission. |
+// |
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
+ |
+package com.google.protobuf; |
+ |
+import protobuf_unittest.NonNestedExtension; |
+import protobuf_unittest.NonNestedExtensionLite; |
+import java.lang.reflect.Method; |
+import java.net.URLClassLoader; |
+import java.util.Arrays; |
+import java.util.Collections; |
+import java.util.HashSet; |
+import java.util.Set; |
+import junit.framework.Test; |
+import junit.framework.TestCase; |
+import junit.framework.TestSuite; |
+ |
+/** |
+ * Tests for {@link ExtensionRegistryFactory} and the {@link ExtensionRegistry} instances it |
+ * creates. |
+ * |
+ * <p>This test simulates the runtime behaviour of the ExtensionRegistryFactory by delegating test |
+ * definitions to two inner classes {@link InnerTest} and {@link InnerLiteTest}, the latter of |
+ * which is executed using a custom ClassLoader, simulating the ProtoLite environment. |
+ * |
+ * <p>The test mechanism employed here is based on the pattern in |
+ * {@code com.google.common.util.concurrent.AbstractFutureFallbackAtomicHelperTest} |
+ */ |
+public class ExtensionRegistryFactoryTest extends TestCase { |
+ |
+ // A classloader which blacklists some non-Lite classes. |
+ private static final ClassLoader LITE_CLASS_LOADER = getLiteOnlyClassLoader(); |
+ |
+ /** |
+ * Defines the set of test methods which will be run. |
+ */ |
+ static interface RegistryTests { |
+ void testCreate(); |
+ void testEmpty(); |
+ void testIsFullRegistry(); |
+ void testAdd(); |
+ void testAdd_immutable(); |
+ } |
+ |
+ /** |
+ * Test implementations for the non-Lite usage of ExtensionRegistryFactory. |
+ */ |
+ public static class InnerTest implements RegistryTests { |
+ |
+ @Override |
+ public void testCreate() { |
+ ExtensionRegistryLite registry = ExtensionRegistryFactory.create(); |
+ |
+ assertEquals(registry.getClass(), ExtensionRegistry.class); |
+ } |
+ |
+ @Override |
+ public void testEmpty() { |
+ ExtensionRegistryLite emptyRegistry = ExtensionRegistryFactory.createEmpty(); |
+ |
+ assertEquals(emptyRegistry.getClass(), ExtensionRegistry.class); |
+ assertEquals(emptyRegistry, ExtensionRegistry.EMPTY_REGISTRY); |
+ } |
+ |
+ @Override |
+ public void testIsFullRegistry() { |
+ ExtensionRegistryLite registry = ExtensionRegistryFactory.create(); |
+ assertTrue(ExtensionRegistryFactory.isFullRegistry(registry)); |
+ } |
+ |
+ @Override |
+ public void testAdd() { |
+ ExtensionRegistryLite registry1 = ExtensionRegistryLite.newInstance(); |
+ NonNestedExtensionLite.registerAllExtensions(registry1); |
+ registry1.add(NonNestedExtensionLite.nonNestedExtensionLite); |
+ |
+ ExtensionRegistryLite registry2 = ExtensionRegistryLite.newInstance(); |
+ NonNestedExtension.registerAllExtensions((ExtensionRegistry) registry2); |
+ registry2.add(NonNestedExtension.nonNestedExtension); |
+ |
+ ExtensionRegistry fullRegistry1 = (ExtensionRegistry) registry1; |
+ ExtensionRegistry fullRegistry2 = (ExtensionRegistry) registry2; |
+ |
+ assertTrue("Test is using a non-lite extension", |
+ GeneratedMessageLite.GeneratedExtension.class.isAssignableFrom( |
+ NonNestedExtensionLite.nonNestedExtensionLite.getClass())); |
+ assertNull("Extension is not registered in masqueraded full registry", |
+ fullRegistry1.findImmutableExtensionByName("protobuf_unittest.nonNestedExtension")); |
+ GeneratedMessageLite.GeneratedExtension<NonNestedExtensionLite.MessageLiteToBeExtended, ?> |
+ extension = registry1.findLiteExtensionByNumber( |
+ NonNestedExtensionLite.MessageLiteToBeExtended.getDefaultInstance(), 1); |
+ assertNotNull("Extension registered in lite registry", extension); |
+ |
+ assertTrue("Test is using a non-lite extension", |
+ GeneratedMessage.GeneratedExtension.class.isAssignableFrom( |
+ NonNestedExtension.nonNestedExtension.getClass())); |
+ assertNotNull("Extension is registered in masqueraded full registry", |
+ fullRegistry2.findImmutableExtensionByName("protobuf_unittest.nonNestedExtension")); |
+ } |
+ |
+ @Override |
+ public void testAdd_immutable() { |
+ ExtensionRegistryLite registry1 = ExtensionRegistryLite.newInstance().getUnmodifiable(); |
+ try { |
+ NonNestedExtensionLite.registerAllExtensions(registry1); |
+ fail(); |
+ } catch (UnsupportedOperationException expected) {} |
+ try { |
+ registry1.add(NonNestedExtensionLite.nonNestedExtensionLite); |
+ fail(); |
+ } catch (UnsupportedOperationException expected) {} |
+ |
+ ExtensionRegistryLite registry2 = ExtensionRegistryLite.newInstance().getUnmodifiable(); |
+ try { |
+ NonNestedExtension.registerAllExtensions((ExtensionRegistry) registry2); |
+ fail(); |
+ } catch (IllegalArgumentException expected) {} |
+ try { |
+ registry2.add(NonNestedExtension.nonNestedExtension); |
+ fail(); |
+ } catch (IllegalArgumentException expected) {} |
+ } |
+ } |
+ |
+ /** |
+ * Test implementations for the Lite usage of ExtensionRegistryFactory. |
+ */ |
+ public static final class InnerLiteTest implements RegistryTests { |
+ |
+ @Override |
+ public void testCreate() { |
+ ExtensionRegistryLite registry = ExtensionRegistryFactory.create(); |
+ |
+ assertEquals(registry.getClass(), ExtensionRegistryLite.class); |
+ } |
+ |
+ @Override |
+ public void testEmpty() { |
+ ExtensionRegistryLite emptyRegistry = ExtensionRegistryFactory.createEmpty(); |
+ |
+ assertEquals(emptyRegistry.getClass(), ExtensionRegistryLite.class); |
+ assertEquals(emptyRegistry, ExtensionRegistryLite.EMPTY_REGISTRY_LITE); |
+ } |
+ |
+ @Override |
+ public void testIsFullRegistry() { |
+ ExtensionRegistryLite registry = ExtensionRegistryFactory.create(); |
+ assertFalse(ExtensionRegistryFactory.isFullRegistry(registry)); |
+ } |
+ |
+ @Override |
+ public void testAdd() { |
+ ExtensionRegistryLite registry = ExtensionRegistryLite.newInstance(); |
+ NonNestedExtensionLite.registerAllExtensions(registry); |
+ GeneratedMessageLite.GeneratedExtension<NonNestedExtensionLite.MessageLiteToBeExtended, ?> |
+ extension = registry.findLiteExtensionByNumber( |
+ NonNestedExtensionLite.MessageLiteToBeExtended.getDefaultInstance(), 1); |
+ assertNotNull("Extension is registered in Lite registry", extension); |
+ } |
+ |
+ @Override |
+ public void testAdd_immutable() { |
+ ExtensionRegistryLite registry = ExtensionRegistryLite.newInstance().getUnmodifiable(); |
+ try { |
+ NonNestedExtensionLite.registerAllExtensions(registry); |
+ fail(); |
+ } catch (UnsupportedOperationException expected) {} |
+ } |
+ } |
+ |
+ /** |
+ * Defines a suite of tests which the JUnit3 runner retrieves by reflection. |
+ */ |
+ public static Test suite() { |
+ TestSuite suite = new TestSuite(); |
+ for (Method method : RegistryTests.class.getMethods()) { |
+ suite.addTest(TestSuite.createTest(ExtensionRegistryFactoryTest.class, method.getName())); |
+ } |
+ return suite; |
+ } |
+ |
+ /** |
+ * Sequentially runs first the Lite and then the non-Lite test variant via classloader |
+ * manipulation. |
+ */ |
+ @Override |
+ public void runTest() throws Exception { |
+ ClassLoader storedClassLoader = Thread.currentThread().getContextClassLoader(); |
+ Thread.currentThread().setContextClassLoader(LITE_CLASS_LOADER); |
+ try { |
+ runTestMethod(LITE_CLASS_LOADER, InnerLiteTest.class); |
+ } finally { |
+ Thread.currentThread().setContextClassLoader(storedClassLoader); |
+ } |
+ try { |
+ runTestMethod(storedClassLoader, InnerTest.class); |
+ } finally { |
+ Thread.currentThread().setContextClassLoader(storedClassLoader); |
+ } |
+ } |
+ |
+ private void runTestMethod(ClassLoader classLoader, Class<? extends RegistryTests> testClass) |
+ throws Exception { |
+ classLoader.loadClass(ExtensionRegistryFactory.class.getName()); |
+ Class<?> test = classLoader.loadClass(testClass.getName()); |
+ String testName = getName(); |
+ test.getMethod(testName).invoke(test.newInstance()); |
+ } |
+ |
+ /** |
+ * Constructs a custom ClassLoader blacklisting the classes which are inspected in the SUT |
+ * to determine the Lite/non-Lite runtime. |
+ */ |
+ private static ClassLoader getLiteOnlyClassLoader() { |
+ ClassLoader testClassLoader = ExtensionRegistryFactoryTest.class.getClassLoader(); |
+ final Set<String> classNamesNotInLite = |
+ Collections.unmodifiableSet( |
+ new HashSet<String>( |
+ Arrays.asList( |
+ ExtensionRegistryFactory.FULL_REGISTRY_CLASS_NAME, |
+ ExtensionRegistry.EXTENSION_CLASS_NAME))); |
+ |
+ // Construct a URLClassLoader delegating to the system ClassLoader, and looking up classes |
+ // in jar files based on the URLs already configured for this test's UrlClassLoader. |
+ // Certain classes throw a ClassNotFoundException by design. |
+ return new URLClassLoader(((URLClassLoader) testClassLoader).getURLs(), |
+ ClassLoader.getSystemClassLoader()) { |
+ @Override |
+ public Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException { |
+ if (classNamesNotInLite.contains(name)) { |
+ throw new ClassNotFoundException("Class deliberately blacklisted by test."); |
+ } |
+ Class<?> loadedClass = null; |
+ try { |
+ loadedClass = findLoadedClass(name); |
+ if (loadedClass == null) { |
+ loadedClass = findClass(name); |
+ if (resolve) { |
+ resolveClass(loadedClass); |
+ } |
+ } |
+ } catch (ClassNotFoundException e) { |
+ loadedClass = super.loadClass(name, resolve); |
+ } |
+ return loadedClass; |
+ } |
+ }; |
+ } |
+} |