You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by ib...@apache.org on 2021/10/01 11:00:13 UTC

[ignite-3] branch main updated: IGNITE-15661 Fix SystemPropertiesExtension state usage (#368)

This is an automated email from the ASF dual-hosted git repository.

ibessonov pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/ignite-3.git


The following commit(s) were added to refs/heads/main by this push:
     new 809e5d8  IGNITE-15661 Fix SystemPropertiesExtension state usage (#368)
809e5d8 is described below

commit 809e5d896ed4954e375d8413510317b7738a70ee
Author: Alexander Polovtcev <al...@gmail.com>
AuthorDate: Fri Oct 1 14:00:09 2021 +0300

    IGNITE-15661 Fix SystemPropertiesExtension state usage (#368)
---
 .../testframework/SystemPropertiesExtension.java   | 157 ++++++++-------------
 .../testframework/WorkDirectoryExtension.java      |  20 ++-
 2 files changed, 75 insertions(+), 102 deletions(-)

diff --git a/modules/core/src/test/java/org/apache/ignite/internal/testframework/SystemPropertiesExtension.java b/modules/core/src/test/java/org/apache/ignite/internal/testframework/SystemPropertiesExtension.java
index 5e4db6e..939e3fb 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/testframework/SystemPropertiesExtension.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/testframework/SystemPropertiesExtension.java
@@ -17,10 +17,11 @@
 
 package org.apache.ignite.internal.testframework;
 
-import java.lang.reflect.Method;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collections;
 import java.util.List;
+import org.jetbrains.annotations.Nullable;
 import org.junit.jupiter.api.extension.AfterAllCallback;
 import org.junit.jupiter.api.extension.AfterEachCallback;
 import org.junit.jupiter.api.extension.BeforeAllCallback;
@@ -28,6 +29,8 @@ import org.junit.jupiter.api.extension.BeforeEachCallback;
 import org.junit.jupiter.api.extension.ExtendWith;
 import org.junit.jupiter.api.extension.ExtensionContext;
 
+import static org.junit.jupiter.api.extension.ExtensionContext.Namespace;
+
 /**
  * JUnit rule that manages usage of {@link WithSystemProperty} annotations.<br>
  * Should be used in {@link ExtendWith}.
@@ -37,143 +40,105 @@ import org.junit.jupiter.api.extension.ExtensionContext;
  */
 public class SystemPropertiesExtension implements
     BeforeAllCallback, AfterAllCallback, BeforeEachCallback, AfterEachCallback {
-    /** Method properties. */
-    @SuppressWarnings("InstanceVariableMayNotBeInitialized")
-    private List<Prop<String, String>> testMethodSysProps;
-
-    /** Class properties. */
-    @SuppressWarnings("InstanceVariableMayNotBeInitialized")
-    private List<Prop<String, String>> testClassSysProps;
+    /** JUnit namespace for the extension. */
+    private static final Namespace NAMESPACE = Namespace.create(SystemPropertiesExtension.class);
 
     /** {@inheritDoc} */
     @Override public void beforeAll(ExtensionContext ctx) {
-        testClassSysProps = extractSystemPropertiesBeforeClass(ctx.getRequiredTestClass());
-    }
-
-    /** {@inheritDoc} */
-    @Override public void afterAll(ExtensionContext context) {
-        clearSystemProperties(testClassSysProps);
+        List<WithSystemProperty> newProps = new ArrayList<>();
 
-        testClassSysProps = null;
-    }
-
-    /** {@inheritDoc} */
-    @Override public void beforeEach(ExtensionContext ctx) {
-        testMethodSysProps = extractSystemPropertiesBeforeTestMethod(ctx.getRequiredTestMethod());
-    }
+        for (Class<?> cls = ctx.getRequiredTestClass(); cls != null; cls = cls.getSuperclass()) {
+            WithSystemProperty[] props = cls.getAnnotationsByType(WithSystemProperty.class);
 
-    /** {@inheritDoc} */
-    @Override public void afterEach(ExtensionContext context) {
-        clearSystemProperties(testMethodSysProps);
+            if (props.length > 0)
+                newProps.addAll(Arrays.asList(props));
+        }
 
-        testMethodSysProps = null;
-    }
+        if (newProps.isEmpty())
+            return;
 
-    /**
-     * Set system properties before class.
-     *
-     * @param testCls Current test class.
-     * @return List of updated properties in reversed order.
-     */
-    private static List<Prop<String, String>> extractSystemPropertiesBeforeClass(Class<?> testCls) {
-        List<WithSystemProperty[]> allProps = new ArrayList<>();
+        // Reverse the collected properties to set properties from the superclass first. This may be important
+        // if the same property gets overridden in a subclass.
+        Collections.reverse(newProps);
 
-        for (Class<?> cls = testCls; cls != null; cls = cls.getSuperclass()) {
-            WithSystemProperty[] props = cls.getAnnotationsByType(WithSystemProperty.class);
+        List<Property> oldProps = replaceProperties(newProps);
 
-            if (props.length > 0)
-                allProps.add(props);
-        }
+        ctx.getStore(NAMESPACE).put(ctx.getUniqueId(), oldProps);
+    }
 
-        Collections.reverse(allProps);
+    /** {@inheritDoc} */
+    @Override public void afterAll(ExtensionContext ctx) {
+        resetProperties(ctx);
+    }
 
-        // List of system properties to set when all tests in class are finished.
-        List<Prop<String, String>> clsSysProps = new ArrayList<>();
+    /** {@inheritDoc} */
+    @Override public void beforeEach(ExtensionContext ctx) {
+        WithSystemProperty[] newProps = ctx.getRequiredTestMethod().getAnnotationsByType(WithSystemProperty.class);
 
-        for (WithSystemProperty[] props : allProps) {
-            for (WithSystemProperty prop : props) {
-                String oldVal = System.setProperty(prop.key(), prop.value());
+        if (newProps.length == 0)
+            return;
 
-                clsSysProps.add(new Prop<>(prop.key(), oldVal));
-            }
-        }
+        List<Property> oldProps = replaceProperties(Arrays.asList(newProps));
 
-        Collections.reverse(clsSysProps);
+        ctx.getStore(NAMESPACE).put(ctx.getUniqueId(), oldProps);
+    }
 
-        return clsSysProps;
+    /** {@inheritDoc} */
+    @Override public void afterEach(ExtensionContext ctx) {
+        resetProperties(ctx);
     }
 
     /**
-     * Set system properties before test method.
+     * Replaces the system properties with the given properties.
      *
-     * @param testMtd Current test method.
-     * @return List of updated properties in reversed order.
+     * @return List of the previous property values.
      */
-    private static List<Prop<String, String>> extractSystemPropertiesBeforeTestMethod(Method testMtd) {
-        WithSystemProperty[] allProps = testMtd.getAnnotationsByType(WithSystemProperty.class);
-
+    private static List<Property> replaceProperties(List<WithSystemProperty> newProps) {
         // List of system properties to set when test is finished.
-        List<Prop<String, String>> testSysProps = new ArrayList<>();
+        var oldProps = new ArrayList<Property>(newProps.size());
 
-        for (WithSystemProperty prop : allProps) {
+        for (WithSystemProperty prop : newProps) {
             String oldVal = System.setProperty(prop.key(), prop.value());
 
-            testSysProps.add(new Prop<>(prop.key(), oldVal));
+            oldProps.add(new Property(prop.key(), oldVal));
         }
 
-        Collections.reverse(testSysProps);
-
-        return testSysProps;
+        return oldProps;
     }
 
     /**
-     * Return old values of updated properties.
-     *
-     * @param sysProps List of properties to clear.
+     * Resets the system properties to the pre-test state.
      */
-    private static void clearSystemProperties(List<Prop<String, String>> sysProps) {
-        if (sysProps == null)
+    private static void resetProperties(ExtensionContext ctx) {
+        List<Property> oldProps = ctx.getStore(NAMESPACE).remove(ctx.getUniqueId(), List.class);
+
+        if (oldProps == null)
             return; // Nothing to do.
 
-        for (Prop<String, String> prop : sysProps) {
-            if (prop.value() == null)
-                System.clearProperty(prop.key());
+        // Bring back the old properties in the reverse order
+        Collections.reverse(oldProps);
+
+        for (Property prop : oldProps) {
+            if (prop.val == null)
+                System.clearProperty(prop.key);
             else
-                System.setProperty(prop.key(), prop.value());
+                System.setProperty(prop.key, prop.val);
         }
     }
 
-    /**
-     * Property.
-     */
-    public static class Prop<K, V> {
+    /** Property. */
+    private static class Property {
         /** Property key. */
-        private final K key;
+        final String key;
 
         /** Property value. */
-        private final V val;
+        @Nullable
+        final String val;
 
-        /**
-         * @param key Property key.
-         * @param val Property value.
-         */
-        Prop(K key, V val) {
+        /** */
+        Property(String key, @Nullable String val) {
             this.key = key;
             this.val = val;
         }
-
-        /**
-         * @return Property key.
-         */
-        K key() {
-            return key;
-        }
-
-        /**
-         * @return Property value.
-         */
-        V value() {
-            return val;
-        }
     }
 }
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/testframework/WorkDirectoryExtension.java b/modules/core/src/test/java/org/apache/ignite/internal/testframework/WorkDirectoryExtension.java
index 0423dd0..67acd9f 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/testframework/WorkDirectoryExtension.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/testframework/WorkDirectoryExtension.java
@@ -95,6 +95,9 @@ public class WorkDirectoryExtension
 
     /** {@inheritDoc} */
     @Override public void afterAll(ExtensionContext context) throws Exception {
+        removeWorkDir(context);
+
+        // remove the base folder, if empty
         try (Stream<Path> list = Files.list(BASE_PATH)) {
             if (list.findAny().isEmpty())
                 IgniteUtils.deleteIfExists(BASE_PATH);
@@ -117,12 +120,7 @@ public class WorkDirectoryExtension
 
     /** {@inheritDoc} */
     @Override public void afterEach(ExtensionContext context) throws Exception {
-        if (shouldRemoveDir()) {
-            Path workDir = context.getStore(NAMESPACE).get(context.getUniqueId(), Path.class);
-
-            if (workDir != null)
-                IgniteUtils.deleteIfExists(workDir);
-        }
+        removeWorkDir(context);
     }
 
     /** {@inheritDoc} */
@@ -176,6 +174,16 @@ public class WorkDirectoryExtension
     }
 
     /**
+     * Removes a previously created work directory.
+     */
+    private static void removeWorkDir(ExtensionContext context) {
+        Path workDir = context.getStore(NAMESPACE).remove(context.getUniqueId(), Path.class);
+
+        if (workDir != null && shouldRemoveDir())
+            IgniteUtils.deleteIfExists(workDir);
+    }
+
+    /**
      * Looks for the annotated field inside the given test class.
      *
      * @return Annotated field or {@code null} if no fields have been found