This is an automated email from the ASF dual-hosted git repository. klund pushed a commit to branch support/1.14 in repository https://gitbox.apache.org/repos/asf/geode.git
commit 14582d05ed0032f5315313e3d29c1773b7bf0f53 Author: Kirk Lund <kl...@apache.org> AuthorDate: Tue Sep 21 09:39:48 2021 -0700 GEODE-9486: Improve AnalyzeSerializables integration tests (#6878) Allow geode modules to have an AnalyzeSerializables integration test without implementing SanctionedSerializablesService. Improve debugging information for AnalyzeSerializables integration tests: - Provide new failure message when no SanctionedSerializablesService exists. - Create ANALYZE_SERIALIZABLES.md to provide detailed instructions for failures involving AnalyzeSerializables integration tests. - Reference ANALYZE_SERIALIZABLES.md in failure messages. Remove geode-serialization and geode-common jars from geode-pulse .war file: - Change getModuleClass() to return Optional. - Delete PulseSanctionedSerializablesService and its resources. - Change geode-pulse dependency on geode-serialization to be for integrationTest only. (cherry picked from commit 7bd1d73dcd02712a10e5c3f2ac5ac0522923bf9e) --- .../AnalyzeRedisSerializablesIntegrationTest.java | 6 +- ...lyzeConnectorsSerializablesIntegrationTest.java | 6 +- .../AnalyzeCoreSerializablesIntegrationTest.java | 6 +- .../AnalyzeCQSerializablesIntegrationTest.java | 6 +- .../AnalyzeDUnitSerializablesIntegrationTest.java | 4 +- .../AnalyzeGfshSerializablesIntegrationTest.java | 6 +- .../AnalyzeJUnitSerializablesIntegrationTest.java | 5 +- .../AnalyzeDataSerializablesJUnitTestBase.java | 55 +++++----- .../AnalyzeSerializablesJUnitTestBase.java | 71 ++++++++++--- .../AnalyzeLuceneSerializablesIntegrationTest.java | 6 +- ...lyzeManagementSerializablesIntegrationTest.java | 6 +- ...lyzeMembershipSerializablesIntegrationTest.java | 5 +- ...alyzeMemcachedSerializablesIntegrationTest.java | 6 +- geode-pulse/build.gradle | 4 +- .../AnalyzePulseSerializablesIntegrationTest.java | 7 +- ...ctionedSerializablesServiceIntegrationTest.java | 39 ------- .../PulseSanctionedSerializablesService.java | 27 ----- ...al.serialization.SanctionedSerializablesService | 15 --- .../sanctioned-geode-pulse-serializables.txt | 0 geode-serialization/ANALYZE_SERIALIZABLES.md | 116 +++++++++++++++++++++ ...eSerializationSerializablesIntegrationTest.java | 6 +- .../AnalyzeWANSerializablesIntegrationTest.java | 6 +- .../AnalyzeWebApiSerializablesIntegrationTest.java | 6 +- .../sanctioned-geode-web-api-serializables.txt | 0 24 files changed, 254 insertions(+), 160 deletions(-) diff --git a/geode-apis-compatible-with-redis/src/integrationTest/java/org/apache/geode/codeAnalysis/AnalyzeRedisSerializablesIntegrationTest.java b/geode-apis-compatible-with-redis/src/integrationTest/java/org/apache/geode/codeAnalysis/AnalyzeRedisSerializablesIntegrationTest.java index e08d444..7c89c5b 100755 --- a/geode-apis-compatible-with-redis/src/integrationTest/java/org/apache/geode/codeAnalysis/AnalyzeRedisSerializablesIntegrationTest.java +++ b/geode-apis-compatible-with-redis/src/integrationTest/java/org/apache/geode/codeAnalysis/AnalyzeRedisSerializablesIntegrationTest.java @@ -14,6 +14,8 @@ */ package org.apache.geode.codeAnalysis; +import java.util.Optional; + import org.junit.experimental.categories.Category; import org.apache.geode.redis.internal.RedisSanctionedSerializablesService; @@ -28,7 +30,7 @@ public class AnalyzeRedisSerializablesIntegrationTest extends AnalyzeSerializabl } @Override - protected Class<?> getModuleClass() { - return RedisSanctionedSerializablesService.class; + protected Optional<Class<?>> getModuleClass() { + return Optional.of(RedisSanctionedSerializablesService.class); } } diff --git a/geode-connectors/src/integrationTest/java/org/apache/geode/codeAnalysis/AnalyzeConnectorsSerializablesIntegrationTest.java b/geode-connectors/src/integrationTest/java/org/apache/geode/codeAnalysis/AnalyzeConnectorsSerializablesIntegrationTest.java index b53ac7d..a5fa5a1 100644 --- a/geode-connectors/src/integrationTest/java/org/apache/geode/codeAnalysis/AnalyzeConnectorsSerializablesIntegrationTest.java +++ b/geode-connectors/src/integrationTest/java/org/apache/geode/codeAnalysis/AnalyzeConnectorsSerializablesIntegrationTest.java @@ -14,6 +14,8 @@ */ package org.apache.geode.codeAnalysis; +import java.util.Optional; + import org.junit.experimental.categories.Category; import org.apache.geode.connectors.jdbc.internal.ConnectorsSanctionedSerializablesService; @@ -29,7 +31,7 @@ public class AnalyzeConnectorsSerializablesIntegrationTest } @Override - protected Class<?> getModuleClass() { - return ConnectorsSanctionedSerializablesService.class; + protected Optional<Class<?>> getModuleClass() { + return Optional.of(ConnectorsSanctionedSerializablesService.class); } } diff --git a/geode-core/src/integrationTest/java/org/apache/geode/codeAnalysis/AnalyzeCoreSerializablesIntegrationTest.java b/geode-core/src/integrationTest/java/org/apache/geode/codeAnalysis/AnalyzeCoreSerializablesIntegrationTest.java index 54128fe..6832442 100755 --- a/geode-core/src/integrationTest/java/org/apache/geode/codeAnalysis/AnalyzeCoreSerializablesIntegrationTest.java +++ b/geode-core/src/integrationTest/java/org/apache/geode/codeAnalysis/AnalyzeCoreSerializablesIntegrationTest.java @@ -14,6 +14,8 @@ */ package org.apache.geode.codeAnalysis; +import java.util.Optional; + import org.junit.experimental.categories.Category; import org.apache.geode.internal.CoreSanctionedSerializablesService; @@ -28,7 +30,7 @@ public class AnalyzeCoreSerializablesIntegrationTest extends AnalyzeSerializable } @Override - protected Class<?> getModuleClass() { - return CoreSanctionedSerializablesService.class; + protected Optional<Class<?>> getModuleClass() { + return Optional.of(CoreSanctionedSerializablesService.class); } } diff --git a/geode-cq/src/integrationTest/java/org/apache/geode/codeAnalysis/AnalyzeCQSerializablesIntegrationTest.java b/geode-cq/src/integrationTest/java/org/apache/geode/codeAnalysis/AnalyzeCQSerializablesIntegrationTest.java index 43cc2df..96c036a 100755 --- a/geode-cq/src/integrationTest/java/org/apache/geode/codeAnalysis/AnalyzeCQSerializablesIntegrationTest.java +++ b/geode-cq/src/integrationTest/java/org/apache/geode/codeAnalysis/AnalyzeCQSerializablesIntegrationTest.java @@ -14,6 +14,8 @@ */ package org.apache.geode.codeAnalysis; +import java.util.Optional; + import org.junit.experimental.categories.Category; import org.apache.geode.cache.query.cq.internal.CQSanctionedSerializablesService; @@ -29,7 +31,7 @@ public class AnalyzeCQSerializablesIntegrationTest extends AnalyzeSerializablesJ } @Override - protected Class<?> getModuleClass() { - return CQSanctionedSerializablesService.class; + protected Optional<Class<?>> getModuleClass() { + return Optional.of(CQSanctionedSerializablesService.class); } } diff --git a/geode-dunit/src/integrationTest/java/org/apache/geode/codeAnalysis/AnalyzeDUnitSerializablesIntegrationTest.java b/geode-dunit/src/integrationTest/java/org/apache/geode/codeAnalysis/AnalyzeDUnitSerializablesIntegrationTest.java index 4186351..f188c06 100644 --- a/geode-dunit/src/integrationTest/java/org/apache/geode/codeAnalysis/AnalyzeDUnitSerializablesIntegrationTest.java +++ b/geode-dunit/src/integrationTest/java/org/apache/geode/codeAnalysis/AnalyzeDUnitSerializablesIntegrationTest.java @@ -43,8 +43,8 @@ public class AnalyzeDUnitSerializablesIntegrationTest extends AnalyzeSerializabl } @Override - protected Class<?> getModuleClass() { - return DUnitSanctionedSerializablesService.class; + protected Optional<Class<?>> getModuleClass() { + return Optional.of(DUnitSanctionedSerializablesService.class); } @Override diff --git a/geode-gfsh/src/integrationTest/java/org/apache/geode/codeAnalysis/AnalyzeGfshSerializablesIntegrationTest.java b/geode-gfsh/src/integrationTest/java/org/apache/geode/codeAnalysis/AnalyzeGfshSerializablesIntegrationTest.java index 1f68a7d..fb4e398 100755 --- a/geode-gfsh/src/integrationTest/java/org/apache/geode/codeAnalysis/AnalyzeGfshSerializablesIntegrationTest.java +++ b/geode-gfsh/src/integrationTest/java/org/apache/geode/codeAnalysis/AnalyzeGfshSerializablesIntegrationTest.java @@ -14,6 +14,8 @@ */ package org.apache.geode.codeAnalysis; +import java.util.Optional; + import org.junit.experimental.categories.Category; import org.apache.geode.management.internal.GfshSanctionedSerializablesService; @@ -28,7 +30,7 @@ public class AnalyzeGfshSerializablesIntegrationTest extends AnalyzeSerializable } @Override - protected Class<?> getModuleClass() { - return GfshSanctionedSerializablesService.class; + protected Optional<Class<?>> getModuleClass() { + return Optional.of(GfshSanctionedSerializablesService.class); } } diff --git a/geode-junit/src/integrationTest/java/org/apache/geode/codeAnalysis/AnalyzeJUnitSerializablesIntegrationTest.java b/geode-junit/src/integrationTest/java/org/apache/geode/codeAnalysis/AnalyzeJUnitSerializablesIntegrationTest.java index fa1b8c6..6e4aeab 100644 --- a/geode-junit/src/integrationTest/java/org/apache/geode/codeAnalysis/AnalyzeJUnitSerializablesIntegrationTest.java +++ b/geode-junit/src/integrationTest/java/org/apache/geode/codeAnalysis/AnalyzeJUnitSerializablesIntegrationTest.java @@ -17,6 +17,7 @@ package org.apache.geode.codeAnalysis; import static java.util.Arrays.asList; import java.util.HashSet; +import java.util.Optional; import java.util.Set; import org.junit.experimental.categories.Category; @@ -38,8 +39,8 @@ public class AnalyzeJUnitSerializablesIntegrationTest extends AnalyzeSerializabl } @Override - protected Class<?> getModuleClass() { - return JUnitSanctionedSerializablesService.class; + protected Optional<Class<?>> getModuleClass() { + return Optional.of(JUnitSanctionedSerializablesService.class); } @Override diff --git a/geode-junit/src/main/java/org/apache/geode/codeAnalysis/AnalyzeDataSerializablesJUnitTestBase.java b/geode-junit/src/main/java/org/apache/geode/codeAnalysis/AnalyzeDataSerializablesJUnitTestBase.java index 1a0dca2..173c58c 100644 --- a/geode-junit/src/main/java/org/apache/geode/codeAnalysis/AnalyzeDataSerializablesJUnitTestBase.java +++ b/geode-junit/src/main/java/org/apache/geode/codeAnalysis/AnalyzeDataSerializablesJUnitTestBase.java @@ -26,7 +26,6 @@ import java.io.IOException; import java.io.InputStream; import java.io.InvalidClassException; import java.io.Serializable; -import java.net.URI; import java.net.URL; import java.nio.file.Path; import java.nio.file.Paths; @@ -35,6 +34,7 @@ import java.util.Collections; import java.util.LinkedList; import java.util.List; import java.util.Map; +import java.util.Optional; import org.junit.AfterClass; import org.junit.Rule; @@ -62,17 +62,26 @@ public abstract class AnalyzeDataSerializablesJUnitTestBase { private static final Path MODULE_ROOT = Paths.get("..", "..", "..").toAbsolutePath().normalize(); private static final Path SOURCE_ROOT = MODULE_ROOT.resolve(Paths.get("src")); - private static final Path TEST_RESOURCES_SOURCE_ROOT = + static final Path INTEGRATION_TEST_RESOURCES_SOURCE_ROOT = SOURCE_ROOT.resolve(Paths.get("integrationTest", "resources")); - private static final Path BUILD_RESOURCES_ROOT = - MODULE_ROOT.resolve(Paths.get("build", "resources")); - - private static final String NEW_LINE = System.getProperty("line.separator"); - - static final String FAIL_MESSAGE = NEW_LINE + NEW_LINE - + "If the class is not persisted or sent over the wire add it to the file " + NEW_LINE + "%s" - + NEW_LINE + "Otherwise if this doesn't break backward compatibility, copy the file " - + NEW_LINE + "%s to " + NEW_LINE + "%s."; + static final Path MAIN_RESOURCES_SOURCE_ROOT = + SOURCE_ROOT.resolve(Paths.get("main", "resources")); + + static final String FAIL_MESSAGE = "%n" + + "If the class is not persisted or sent over the wire, add it to the file%n" + + " %s%n" + // excluded file in integrationTest resources + "Otherwise, if this doesn't break backward compatibility, copy the file%n" + + " %s%n" + // actual file in build + " to %n" + + " %s%n" + // sanctioned file in main resources + "If this potentially breaks backward compatibility, follow the instructions in%n" + + " geode-serialization/ANALYZE_SERIALIZABLES.md%n"; // readme in geode-serialization + + static final String FAIL_MESSAGE_NO_SERVICE = "%n" + + "If the class is not persisted or sent over the wire, add it to the file%n" + + " %s%n" + // excluded file in integrationTest resources + "Otherwise, follow the instructions in%n" + + " geode-serialization/ANALYZE_SERIALIZABLES.md%n"; // readme in geode-serialization static final String EXCLUDED_CLASSES_TXT = "excludedClasses.txt"; private static final String ACTUAL_DATA_SERIALIZABLES_DAT = "actualDataSerializables.dat"; @@ -109,7 +118,7 @@ public abstract class AnalyzeDataSerializablesJUnitTestBase { * you have put your sanctioned-modulename-serializables.txt file in the production resources * tree. */ - protected abstract Class<?> getModuleClass(); + protected abstract Optional<Class<?>> getModuleClass(); /** * Implement this to deserialize an object that was serialized with serializeObject() @@ -234,7 +243,7 @@ public abstract class AnalyzeDataSerializablesJUnitTestBase { } } - String toBuildPathString(File file) { + private String toBuildPathString(File file) { if (file == null) { return null; } @@ -242,23 +251,7 @@ public abstract class AnalyzeDataSerializablesJUnitTestBase { } private String toTestResourcesSourcePathString(Path relativeFilePath) { - return TEST_RESOURCES_SOURCE_ROOT.resolve(relativeFilePath).normalize().toString(); - } - - /** - * <pre> - * FROM: - * /Users/user/dev/geode/geode-junit/build/resources/main/org/apache/geode/test/junit/internal/sanctioned-geode-junit-serializables.txt - * - * TO: - * /Users/user/dev/geode/geode-junit/src/main/resources/org/apache/geode/test/junit/internal/sanctioned-geode-junit-serializables.txt - * </pre> - */ - String mainResourceToSourcePath(URI buildResourceURI) { - Path mainBuildResources = BUILD_RESOURCES_ROOT.resolve(Paths.get("main")); - Path mainSourceResources = SOURCE_ROOT.resolve(Paths.get("main", "resources")); - Path relativeFilePath = mainBuildResources.relativize(Paths.get(buildResourceURI)); - return mainSourceResources.resolve(relativeFilePath).toString(); + return INTEGRATION_TEST_RESOURCES_SOURCE_ROOT.resolve(relativeFilePath).normalize().toString(); } List<String> loadExcludedClasses(File excludedClassesFile) throws IOException { @@ -388,7 +381,7 @@ public abstract class AnalyzeDataSerializablesJUnitTestBase { return getResource(associatedClass, resourceName).openStream(); } - static URL getResource(final Class<?> classInSamePackage, final String resourceName) { + private static URL getResource(final Class<?> classInSamePackage, final String resourceName) { return classInSamePackage.getResource(resourceName); } } diff --git a/geode-junit/src/main/java/org/apache/geode/codeAnalysis/AnalyzeSerializablesJUnitTestBase.java b/geode-junit/src/main/java/org/apache/geode/codeAnalysis/AnalyzeSerializablesJUnitTestBase.java index 08e09f9..d26a4cb 100644 --- a/geode-junit/src/main/java/org/apache/geode/codeAnalysis/AnalyzeSerializablesJUnitTestBase.java +++ b/geode-junit/src/main/java/org/apache/geode/codeAnalysis/AnalyzeSerializablesJUnitTestBase.java @@ -14,7 +14,6 @@ */ package org.apache.geode.codeAnalysis; -import static java.util.Collections.emptyList; import static org.apache.geode.distributed.ConfigurationProperties.SERIALIZABLE_OBJECT_FILTER; import static org.apache.geode.distributed.ConfigurationProperties.VALIDATE_SERIALIZABLE_OBJECTS; import static org.assertj.core.api.Assertions.fail; @@ -29,8 +28,10 @@ import java.io.IOException; import java.io.InputStream; import java.io.InvalidClassException; import java.io.Serializable; +import java.io.UncheckedIOException; import java.lang.reflect.Constructor; import java.lang.reflect.Modifier; +import java.nio.file.Path; import java.rmi.RemoteException; import java.util.ArrayList; import java.util.Collections; @@ -71,7 +72,7 @@ public abstract class AnalyzeSerializablesJUnitTestBase private final String expectedSerializablesFileName = "sanctioned-" + getModuleName() + "-serializables.txt"; - protected List<ClassAndVariableDetails> expectedSerializables; + protected final List<ClassAndVariableDetails> expectedSerializables = new ArrayList<>(); @Before public void setUp() throws Exception { @@ -97,13 +98,47 @@ public abstract class AnalyzeSerializablesJUnitTestBase System.out.println( "++++++++++++++++++++++++++++++testSerializables found discrepancies++++++++++++++++++++++++++++++++++++"); System.out.println(diff); - fail(diff + FAIL_MESSAGE, toBuildPathString(getResourceAsFile(EXCLUDED_CLASSES_TXT)), - actualSerializablesFile.getAbsolutePath(), - mainResourceToSourcePath( - getResource(getModuleClass(), expectedSerializablesFileName).toURI())); + + String codeAnalysisPackageDir = getPackageDirForClass(getClass()); + Path excludedClassesSourceFile = INTEGRATION_TEST_RESOURCES_SOURCE_ROOT + .resolve(codeAnalysisPackageDir) + .resolve(EXCLUDED_CLASSES_TXT); + + String failureMessage = getModuleClass() + .map(clazz -> failWithServiceMessage( + actualSerializablesFile, diff, excludedClassesSourceFile, clazz)) + .orElse(failWithoutServiceMessage( + diff, excludedClassesSourceFile)); + + fail(failureMessage); } } + private String failWithServiceMessage(File actualSerializablesFile, + String diff, + Path excludedClassesSourceFile, + Class<?> serviceClass) { + Path sanctionedSerializablesSourceFile = + getSanctionedSerializablesSourceFileForServiceClass(serviceClass); + return String.format(diff + FAIL_MESSAGE, + excludedClassesSourceFile, + actualSerializablesFile.getAbsolutePath(), + sanctionedSerializablesSourceFile); + } + + private String failWithoutServiceMessage(String diff, + Path excludedClassesSourceFile) { + return String.format(diff + FAIL_MESSAGE_NO_SERVICE, + excludedClassesSourceFile); + } + + private Path getSanctionedSerializablesSourceFileForServiceClass(Class<?> serviceClass) { + String moduleServicePackageDir = getPackageDirForClass(serviceClass); + return MAIN_RESOURCES_SOURCE_ROOT + .resolve(moduleServicePackageDir) + .resolve(expectedSerializablesFileName); + } + @Test public void testSanctionedClassesExistAndDoDeserialize() throws Exception { loadExpectedSerializables(); @@ -238,15 +273,17 @@ public abstract class AnalyzeSerializablesJUnitTestBase } public void loadExpectedSerializables() throws Exception { - if (expectedSerializablesFileName == null) { - expectedSerializables = emptyList(); - } else { - try (InputStream expectedSerializablesStream = - getResourceAsStream(getModuleClass(), expectedSerializablesFileName)) { - // the expectedSerializablesStream will be automatically closed when we exit this block - expectedSerializables = - CompiledClassUtils.loadClassesAndVariables(expectedSerializablesStream); - } + getModuleClass().ifPresent(this::loadSanctionedSerializables); + } + + private void loadSanctionedSerializables(Class<?> clazz) { + try (InputStream expectedSerializablesStream = + getResourceAsStream(clazz, expectedSerializablesFileName)) { + // the expectedSerializablesStream will be automatically closed when we exit this block + expectedSerializables.addAll( + CompiledClassUtils.loadClassesAndVariables(expectedSerializablesStream)); + } catch (IOException e) { + throw new UncheckedIOException(e); } } @@ -343,4 +380,8 @@ public abstract class AnalyzeSerializablesJUnitTestBase } return false; } + + private static String getPackageDirForClass(Class<?> theClass) { + return theClass.getPackage().getName().replace(".", File.separator); + } } diff --git a/geode-lucene/src/integrationTest/java/org/apache/geode/codeAnalysis/AnalyzeLuceneSerializablesIntegrationTest.java b/geode-lucene/src/integrationTest/java/org/apache/geode/codeAnalysis/AnalyzeLuceneSerializablesIntegrationTest.java index 1e0af7c..d170cd0 100644 --- a/geode-lucene/src/integrationTest/java/org/apache/geode/codeAnalysis/AnalyzeLuceneSerializablesIntegrationTest.java +++ b/geode-lucene/src/integrationTest/java/org/apache/geode/codeAnalysis/AnalyzeLuceneSerializablesIntegrationTest.java @@ -14,6 +14,8 @@ */ package org.apache.geode.codeAnalysis; +import java.util.Optional; + import org.junit.experimental.categories.Category; import org.apache.geode.cache.lucene.internal.LuceneSanctionedSerializablesService; @@ -29,7 +31,7 @@ public class AnalyzeLuceneSerializablesIntegrationTest extends AnalyzeSerializab } @Override - protected Class<?> getModuleClass() { - return LuceneSanctionedSerializablesService.class; + protected Optional<Class<?>> getModuleClass() { + return Optional.of(LuceneSanctionedSerializablesService.class); } } diff --git a/geode-management/src/integrationTest/java/org/apache/geode/codeAnalysis/AnalyzeManagementSerializablesIntegrationTest.java b/geode-management/src/integrationTest/java/org/apache/geode/codeAnalysis/AnalyzeManagementSerializablesIntegrationTest.java index 9cb2f81..aab75d2 100644 --- a/geode-management/src/integrationTest/java/org/apache/geode/codeAnalysis/AnalyzeManagementSerializablesIntegrationTest.java +++ b/geode-management/src/integrationTest/java/org/apache/geode/codeAnalysis/AnalyzeManagementSerializablesIntegrationTest.java @@ -14,6 +14,8 @@ */ package org.apache.geode.codeAnalysis; +import java.util.Optional; + import org.junit.experimental.categories.Category; import org.apache.geode.management.internal.ManagementSanctionedSerializablesService; @@ -29,7 +31,7 @@ public class AnalyzeManagementSerializablesIntegrationTest } @Override - protected Class<?> getModuleClass() { - return ManagementSanctionedSerializablesService.class; + protected Optional<Class<?>> getModuleClass() { + return Optional.of(ManagementSanctionedSerializablesService.class); } } diff --git a/geode-membership/src/integrationTest/java/org/apache/geode/codeAnalysis/AnalyzeMembershipSerializablesIntegrationTest.java b/geode-membership/src/integrationTest/java/org/apache/geode/codeAnalysis/AnalyzeMembershipSerializablesIntegrationTest.java index 0fb6f85..e473148 100644 --- a/geode-membership/src/integrationTest/java/org/apache/geode/codeAnalysis/AnalyzeMembershipSerializablesIntegrationTest.java +++ b/geode-membership/src/integrationTest/java/org/apache/geode/codeAnalysis/AnalyzeMembershipSerializablesIntegrationTest.java @@ -17,6 +17,7 @@ package org.apache.geode.codeAnalysis; import java.io.ByteArrayInputStream; import java.io.DataInputStream; import java.io.IOException; +import java.util.Optional; import org.junit.experimental.categories.Category; @@ -45,8 +46,8 @@ public class AnalyzeMembershipSerializablesIntegrationTest } @Override - protected Class<?> getModuleClass() { - return Services.class; + protected Optional<Class<?>> getModuleClass() { + return Optional.of(Services.class); } @Override diff --git a/geode-memcached/src/integrationTest/java/org/apache/geode/codeAnalysis/AnalyzeMemcachedSerializablesIntegrationTest.java b/geode-memcached/src/integrationTest/java/org/apache/geode/codeAnalysis/AnalyzeMemcachedSerializablesIntegrationTest.java index f2ac741..8959d85 100644 --- a/geode-memcached/src/integrationTest/java/org/apache/geode/codeAnalysis/AnalyzeMemcachedSerializablesIntegrationTest.java +++ b/geode-memcached/src/integrationTest/java/org/apache/geode/codeAnalysis/AnalyzeMemcachedSerializablesIntegrationTest.java @@ -14,6 +14,8 @@ */ package org.apache.geode.codeAnalysis; +import java.util.Optional; + import org.junit.experimental.categories.Category; import org.apache.geode.internal.memcached.MemcachedSanctionedSerializablesService; @@ -29,7 +31,7 @@ public class AnalyzeMemcachedSerializablesIntegrationTest } @Override - protected Class<?> getModuleClass() { - return MemcachedSanctionedSerializablesService.class; + protected Optional<Class<?>> getModuleClass() { + return Optional.of(MemcachedSanctionedSerializablesService.class); } } diff --git a/geode-pulse/build.gradle b/geode-pulse/build.gradle index 761c854..46b60ae 100644 --- a/geode-pulse/build.gradle +++ b/geode-pulse/build.gradle @@ -30,8 +30,6 @@ dependencies { compileOnly(platform(project(':boms:geode-all-bom'))) providedCompile(platform(project(':boms:geode-all-bom'))) - implementation(project(':geode-serialization')) - implementation('org.springframework.security:spring-security-core') implementation('javax.servlet:javax.servlet-api') implementation('mx4j:mx4j') { @@ -122,6 +120,8 @@ dependencies { integrationTestImplementation(project(':geode-pulse')) integrationTestImplementation(project(':geode-pulse:geode-pulse-test')) + integrationTestImplementation(project(':geode-serialization')) + integrationTestImplementation('org.powermock:powermock-core') integrationTestImplementation('org.powermock:powermock-module-junit4') integrationTestImplementation('org.powermock:powermock-api-mockito2') diff --git a/geode-pulse/src/integrationTest/java/org/apache/geode/codeAnalysis/AnalyzePulseSerializablesIntegrationTest.java b/geode-pulse/src/integrationTest/java/org/apache/geode/codeAnalysis/AnalyzePulseSerializablesIntegrationTest.java index 13fed94..fbf8d52 100644 --- a/geode-pulse/src/integrationTest/java/org/apache/geode/codeAnalysis/AnalyzePulseSerializablesIntegrationTest.java +++ b/geode-pulse/src/integrationTest/java/org/apache/geode/codeAnalysis/AnalyzePulseSerializablesIntegrationTest.java @@ -14,10 +14,11 @@ */ package org.apache.geode.codeAnalysis; +import java.util.Optional; + import org.junit.experimental.categories.Category; import org.apache.geode.test.junit.categories.SerializationTest; -import org.apache.geode.tools.pulse.internal.PulseSanctionedSerializablesService; @Category(SerializationTest.class) public class AnalyzePulseSerializablesIntegrationTest extends AnalyzeSerializablesJUnitTestBase { @@ -28,7 +29,7 @@ public class AnalyzePulseSerializablesIntegrationTest extends AnalyzeSerializabl } @Override - protected Class<?> getModuleClass() { - return PulseSanctionedSerializablesService.class; + protected Optional<Class<?>> getModuleClass() { + return Optional.empty(); } } diff --git a/geode-pulse/src/integrationTest/java/org/apache/geode/tools/pulse/internal/PulseSanctionedSerializablesServiceIntegrationTest.java b/geode-pulse/src/integrationTest/java/org/apache/geode/tools/pulse/internal/PulseSanctionedSerializablesServiceIntegrationTest.java deleted file mode 100644 index 3019f09..0000000 --- a/geode-pulse/src/integrationTest/java/org/apache/geode/tools/pulse/internal/PulseSanctionedSerializablesServiceIntegrationTest.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more contributor license - * agreements. See the NOTICE file distributed with this work for additional information regarding - * copyright ownership. The ASF licenses this file to You 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 org.apache.geode.tools.pulse.internal; - -import org.junit.experimental.categories.Category; - -import org.apache.geode.codeAnalysis.SanctionedSerializablesServiceIntegrationTestBase; -import org.apache.geode.internal.serialization.SanctionedSerializablesService; -import org.apache.geode.test.junit.categories.SanctionedSerializablesTest; -import org.apache.geode.test.junit.categories.SerializationTest; - -@Category({SerializationTest.class, SanctionedSerializablesTest.class}) -public class PulseSanctionedSerializablesServiceIntegrationTest - extends SanctionedSerializablesServiceIntegrationTestBase { - - private final SanctionedSerializablesService service = new PulseSanctionedSerializablesService(); - - @Override - protected SanctionedSerializablesService getService() { - return service; - } - - @Override - protected ServiceResourceExpectation getServiceResourceExpectation() { - return ServiceResourceExpectation.EMPTY; - } -} diff --git a/geode-pulse/src/main/java/org/apache/geode/tools/pulse/internal/PulseSanctionedSerializablesService.java b/geode-pulse/src/main/java/org/apache/geode/tools/pulse/internal/PulseSanctionedSerializablesService.java deleted file mode 100644 index 29981bf..0000000 --- a/geode-pulse/src/main/java/org/apache/geode/tools/pulse/internal/PulseSanctionedSerializablesService.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more contributor license - * agreements. See the NOTICE file distributed with this work for additional information regarding - * copyright ownership. The ASF licenses this file to You 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 org.apache.geode.tools.pulse.internal; - -import java.net.URL; - -import org.apache.geode.internal.serialization.SanctionedSerializablesService; - -public class PulseSanctionedSerializablesService implements SanctionedSerializablesService { - - @Override - public URL getSanctionedSerializablesURL() { - return getClass().getResource("sanctioned-geode-pulse-serializables.txt"); - } -} diff --git a/geode-pulse/src/main/resources/META-INF/services/org.apache.geode.internal.serialization.SanctionedSerializablesService b/geode-pulse/src/main/resources/META-INF/services/org.apache.geode.internal.serialization.SanctionedSerializablesService deleted file mode 100644 index 52d2158..0000000 --- a/geode-pulse/src/main/resources/META-INF/services/org.apache.geode.internal.serialization.SanctionedSerializablesService +++ /dev/null @@ -1,15 +0,0 @@ -# -# Licensed to the Apache Software Foundation (ASF) under one or more contributor license -# agreements. See the NOTICE file distributed with this work for additional information regarding -# copyright ownership. The ASF licenses this file to You 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. -# -org.apache.geode.tools.pulse.internal.PulseSanctionedSerializablesService diff --git a/geode-pulse/src/main/resources/org/apache/geode/tools/pulse/internal/sanctioned-geode-pulse-serializables.txt b/geode-pulse/src/main/resources/org/apache/geode/tools/pulse/internal/sanctioned-geode-pulse-serializables.txt deleted file mode 100644 index e69de29..0000000 diff --git a/geode-serialization/ANALYZE_SERIALIZABLES.md b/geode-serialization/ANALYZE_SERIALIZABLES.md new file mode 100644 index 0000000..c9597d3 --- /dev/null +++ b/geode-serialization/ANALYZE_SERIALIZABLES.md @@ -0,0 +1,116 @@ +# Analyze Serializables + +## Adding AnalyzeSerializables test to a new geode module + +If you've created a new geode module, then add an integration test to detect any additions or changes to serializable classes in the module. + +Change the module's `build.gradle` to add a dependency on geode-serialization: +``` +integrationTestImplementation(project(':geode-serialization')) +``` + +Create `AnalyzeModuleSerializablesIntegrationTest` that extends `AnalyzeSerializablesJUnitTestBase`. It needs to be in package `org.apache.geode.codeAnalysis`. + +## Implementing SanctionedSerializablesService + +If you've changed or added any serializable classes to a geode module, the previously added integration test should fail. You'll need to implement `SanctionedSerializablesService` for the geode module. + +Change the module's `build.gradle` to add a dependency on geode-serialization: +``` +implementation(project(':geode-serialization')) +``` + +Create a new `ModuleSanctionedSerializablesService` that implements `SanctionedSerializablesService`: +``` +geode-module/src/main/java/org/apache/geode/module/internal/ModuleSanctionedSerializablesService.java +``` + +Add a service file for `SanctionedSerializablesService`: +``` +geode-module/src/main/resources/META-INF/services/org.apache.geode.internal.serialization.SanctionedSerializablesService +``` + +Add a line to the service file specifying the fully qualified name of the service implementation: +``` +org.apache.geode.module.internal.ModuleSanctionedSerializablesService +``` + +Update `AnalyzeModuleSerializablesIntegrationTest` to return the new `SanctionedSerializablesService` implementation from `getModuleClass`: +```java +@Override +protected Optional<Class<?>> getModuleClass() { + return Optional.of(ModuleSanctionedSerializablesService.class); +} +``` + +## Fixing failures in AnalyzeModuleSerializablesIntegrationTest + +`AnalyzeModuleSerializablesIntegrationTest` analyzes serializable classes in a module. It fails if either: +- a new serializable class is added to the main src +- an existing serializable class in main src is modified + +The content of the failure message depends on whether the module implements `SanctionedSerializablesService`. + +If it implements `SanctionedSerializablesService`, the failure message looks like: +``` +New or moved classes---------------------------------------- +org/apache/geode/CancelException,true,3215578659523282642 + +If the class is not persisted or sent over the wire, add it to the file + /path/to/geode/geode-core/src/integrationTest/resources/org/apache/geode/codeAnalysis/excludedClasses.txt +Otherwise, if this doesn't break backward compatibility, copy the file + /path/to/geode/geode-core/build/integrationTest/test-worker-000009/actualSerializables.dat + to + /path/to/geode/geode-core/src/main/resources/org/apache/geode/internal/sanctioned-geode-core-serializables.txt +If this potentially breaks backward compatibility, follow the instructions in + geode-serialization/ANALYZE_SERIALIZABLES.md +``` + +If the module does not implement `SanctionedSerializablesService`, the failure message looks like: +``` +New or moved classes---------------------------------------- +org/apache/geode/tools/pulse/internal/security/GemFireAuthentication,true,550: new class + +If the class is not persisted or sent over the wire, add it to the file + /path/to/geode/geode-pulse/src/integrationTest/resources/org/apache/geode/codeAnalysis/excludedClasses.txt +Otherwise, follow the instructions in + geode-serialization/ANALYZE_SERIALIZABLES.md +``` + +### If the module does not implement SanctionedSerializablesService + +Fixing will require determining if the class will actually go on the wire or not. + +If the class is neither persisted nor sent over the wire, add it to `excludedClasses.txt` in integrationTest resources: +``` +org/apache/geode/tools/pulse/internal/security/GemFireAuthentication +``` + +If `excludedClasses.txt` does not yet exist, create an empty file in integrationTest resources. It needs to be in package `org.apache.geode.codeAnalysis`: +``` +geode-module/src/integrationTest/resources/org/apache/geode/codeAnalysis/excludedClasses.txt +``` + +If the class will go on the wire, then follow the instructions for implementing `SanctionedSerializablesService`. Rerun the test and follow the instructions in the following section. + +### If the module implements SanctionedSerializablesService + +If the change does not break backward compatibility, copy the file `actualSerializables.dat` to `sanctioned-geode-module-serializables.txt` using the paths indicated in the failure message. + +If the class is neither persisted nor sent over the wire, add a line to `excludedClasses.txt` identifying the class to exclude. + +If `excludedClasses.txt` does not yet exist, create an empty file in integrationTest resources. It needs to be in package `org.apache.geode.codeAnalysis`: +``` +geode-module/src/integrationTest/resources/org/apache/geode/codeAnalysis/excludedClasses.txt +``` + +The failure message identifies the class. For example, if the message contains a line such as: +``` +New or moved classes---------------------------------------- +org/apache/geode/CancelException,true,3215578659523282642 +``` + +Then add this line to `excludedClasses.txt` if you need to exclude that class: +``` +org/apache/geode/CancelException +``` diff --git a/geode-serialization/src/integrationTest/java/org/apache/geode/codeAnalysis/AnalyzeSerializationSerializablesIntegrationTest.java b/geode-serialization/src/integrationTest/java/org/apache/geode/codeAnalysis/AnalyzeSerializationSerializablesIntegrationTest.java index dcfc7a2..4aa74ff 100644 --- a/geode-serialization/src/integrationTest/java/org/apache/geode/codeAnalysis/AnalyzeSerializationSerializablesIntegrationTest.java +++ b/geode-serialization/src/integrationTest/java/org/apache/geode/codeAnalysis/AnalyzeSerializationSerializablesIntegrationTest.java @@ -14,6 +14,8 @@ */ package org.apache.geode.codeAnalysis; +import java.util.Optional; + import org.junit.experimental.categories.Category; import org.apache.geode.internal.serialization.SerializationSanctionedSerializablesService; @@ -29,7 +31,7 @@ public class AnalyzeSerializationSerializablesIntegrationTest } @Override - protected Class<?> getModuleClass() { - return SerializationSanctionedSerializablesService.class; + protected Optional<Class<?>> getModuleClass() { + return Optional.of(SerializationSanctionedSerializablesService.class); } } diff --git a/geode-wan/src/integrationTest/java/org/apache/geode/codeAnalysis/AnalyzeWANSerializablesIntegrationTest.java b/geode-wan/src/integrationTest/java/org/apache/geode/codeAnalysis/AnalyzeWANSerializablesIntegrationTest.java index 8fe1a80..1438f2f 100644 --- a/geode-wan/src/integrationTest/java/org/apache/geode/codeAnalysis/AnalyzeWANSerializablesIntegrationTest.java +++ b/geode-wan/src/integrationTest/java/org/apache/geode/codeAnalysis/AnalyzeWANSerializablesIntegrationTest.java @@ -14,6 +14,8 @@ */ package org.apache.geode.codeAnalysis; +import java.util.Optional; + import org.junit.experimental.categories.Category; import org.apache.geode.internal.cache.wan.WANSanctionedSerializablesService; @@ -29,7 +31,7 @@ public class AnalyzeWANSerializablesIntegrationTest extends AnalyzeSerializables } @Override - protected Class<?> getModuleClass() { - return WANSanctionedSerializablesService.class; + protected Optional<Class<?>> getModuleClass() { + return Optional.of(WANSanctionedSerializablesService.class); } } diff --git a/geode-web-api/src/integrationTest/java/org/apache/geode/codeAnalysis/AnalyzeWebApiSerializablesIntegrationTest.java b/geode-web-api/src/integrationTest/java/org/apache/geode/codeAnalysis/AnalyzeWebApiSerializablesIntegrationTest.java index 828dba6..9ed629a 100644 --- a/geode-web-api/src/integrationTest/java/org/apache/geode/codeAnalysis/AnalyzeWebApiSerializablesIntegrationTest.java +++ b/geode-web-api/src/integrationTest/java/org/apache/geode/codeAnalysis/AnalyzeWebApiSerializablesIntegrationTest.java @@ -14,6 +14,8 @@ */ package org.apache.geode.codeAnalysis; +import java.util.Optional; + import org.junit.experimental.categories.Category; import org.apache.geode.rest.internal.WebApiSanctionedSerializablesService; @@ -29,7 +31,7 @@ public class AnalyzeWebApiSerializablesIntegrationTest extends AnalyzeSerializab } @Override - protected Class<?> getModuleClass() { - return WebApiSanctionedSerializablesService.class; + protected Optional<Class<?>> getModuleClass() { + return Optional.of(WebApiSanctionedSerializablesService.class); } } diff --git a/geode-web-api/src/main/resources/org/apache/geode/internal/sanctioned-geode-web-api-serializables.txt b/geode-web-api/src/main/resources/org/apache/geode/internal/sanctioned-geode-web-api-serializables.txt deleted file mode 100644 index e69de29..0000000