You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@logging.apache.org by ma...@apache.org on 2022/01/17 01:44:59 UTC

[logging-log4j2] 01/02: Update Cassandra test to JUnit 5

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

mattsicker pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/logging-log4j2.git

commit 99f7336101a172f884730da598a9e2701a2b4ed5
Author: Matt Sicker <ma...@apache.org>
AuthorDate: Sun Jan 16 19:44:14 2022 -0600

    Update Cassandra test to JUnit 5
    
    Also adds an error check for unsupported platforms.
    
    Signed-off-by: Matt Sicker <ma...@apache.org>
---
 .../log4j/cassandra/CassandraAppenderIT.java       |  40 +++---
 .../log4j/cassandra/CassandraExtension.java        | 158 +++++++++++++++++++++
 .../logging/log4j/cassandra/CassandraFixture.java  |  42 ++++++
 .../logging/log4j/cassandra/CassandraRule.java     | 141 ------------------
 4 files changed, 217 insertions(+), 164 deletions(-)

diff --git a/log4j-cassandra/src/test/java/org/apache/logging/log4j/cassandra/CassandraAppenderIT.java b/log4j-cassandra/src/test/java/org/apache/logging/log4j/cassandra/CassandraAppenderIT.java
index da9892c..6adae43 100644
--- a/log4j-cassandra/src/test/java/org/apache/logging/log4j/cassandra/CassandraAppenderIT.java
+++ b/log4j-cassandra/src/test/java/org/apache/logging/log4j/cassandra/CassandraAppenderIT.java
@@ -16,30 +16,28 @@
  */
 package org.apache.logging.log4j.cassandra;
 
-import java.util.Date;
-import java.util.List;
-import java.util.Map;
-import java.util.UUID;
-import java.util.concurrent.TimeUnit;
-
+import com.datastax.driver.core.Cluster;
 import com.datastax.driver.core.Row;
 import com.datastax.driver.core.Session;
 import org.apache.logging.log4j.Logger;
 import org.apache.logging.log4j.MarkerManager;
 import org.apache.logging.log4j.ThreadContext;
-import org.apache.logging.log4j.core.test.categories.Appenders;
-import org.apache.logging.log4j.core.test.junit.LoggerContextRule;
-import org.junit.ClassRule;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
-import org.junit.rules.RuleChain;
+import org.apache.logging.log4j.core.LoggerContext;
+import org.apache.logging.log4j.core.test.junit.LoggerContextSource;
+import org.junit.jupiter.api.Test;
+
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+import java.util.concurrent.TimeUnit;
 
-import static org.junit.Assert.*;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
 
 /**
  * Integration test for CassandraAppender.
  */
-@Category(Appenders.Cassandra.class)
 public class CassandraAppenderIT {
 
     private static final String DDL = "CREATE TABLE logs (" +
@@ -54,15 +52,11 @@ public class CassandraAppenderIT {
         "ndc list<text>" +
         ")";
 
-    private static final LoggerContextRule CTX = new LoggerContextRule("CassandraAppenderTest.xml");
-    private static final CassandraRule CASSANDRA = new CassandraRule("test", DDL);
-
-    @ClassRule
-    public static RuleChain rules = RuleChain.outerRule(CASSANDRA).around(CTX);
-
     @Test
-    public void appendManyEvents() throws Exception {
-        final Logger logger = CTX.getLogger();
+    @CassandraFixture(keyspace = "test", setup = DDL)
+    @LoggerContextSource("CassandraAppenderTest.xml")
+    public void appendManyEvents(final LoggerContext context, final Cluster cluster) throws Exception {
+        final Logger logger = context.getLogger(getClass());
         ThreadContext.put("test", "mdc");
         ThreadContext.push("ndc");
         for (int i = 0; i < 20; i++) {
@@ -73,7 +67,7 @@ public class CassandraAppenderIT {
         TimeUnit.SECONDS.sleep(3);
 
         int i = 0;
-        try (final Session session = CASSANDRA.connect()) {
+        try (final Session session = cluster.connect()) {
             for (final Row row : session.execute("SELECT * FROM logs")) {
                 assertNotNull(row.get("id", UUID.class));
                 assertNotNull(row.get("timeid", UUID.class));
diff --git a/log4j-cassandra/src/test/java/org/apache/logging/log4j/cassandra/CassandraExtension.java b/log4j-cassandra/src/test/java/org/apache/logging/log4j/cassandra/CassandraExtension.java
new file mode 100644
index 0000000..06736d0
--- /dev/null
+++ b/log4j-cassandra/src/test/java/org/apache/logging/log4j/cassandra/CassandraExtension.java
@@ -0,0 +1,158 @@
+/*
+ * 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.logging.log4j.cassandra;
+
+import com.datastax.driver.core.Cluster;
+import com.datastax.driver.core.Session;
+import org.apache.cassandra.service.CassandraDaemon;
+import org.apache.logging.log4j.core.util.Cancellable;
+import org.apache.logging.log4j.core.util.Closer;
+import org.apache.logging.log4j.core.util.Log4jThreadFactory;
+import org.apache.logging.log4j.core.util.Throwables;
+import org.apache.logging.log4j.util.PropertiesUtil;
+import org.junit.jupiter.api.extension.AfterEachCallback;
+import org.junit.jupiter.api.extension.BeforeEachCallback;
+import org.junit.jupiter.api.extension.ExtensionContext;
+import org.junit.jupiter.api.extension.ParameterContext;
+import org.junit.jupiter.api.extension.ParameterResolutionException;
+import org.junit.jupiter.api.extension.support.TypeBasedParameterResolver;
+import org.opentest4j.TestAbortedException;
+
+import java.net.InetAddress;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.security.Permission;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.atomic.AtomicReference;
+
+public class CassandraExtension extends TypeBasedParameterResolver<Cluster> implements BeforeEachCallback, AfterEachCallback {
+    private static final ThreadFactory THREAD_FACTORY = Log4jThreadFactory.createThreadFactory("CassandraFixture");
+
+    @Override
+    public void beforeEach(final ExtensionContext context) throws Exception {
+        final var cassandraFixture = context.getRequiredTestMethod().getAnnotation(CassandraFixture.class);
+        if (cassandraFixture != null) {
+            final var latch = new CountDownLatch(1);
+            final var errorRef = new AtomicReference<Throwable>();
+            final var embeddedCassandra = new EmbeddedCassandra(latch, errorRef);
+            final Path root = Files.createTempDirectory("cassandra");
+            Files.createDirectories(root.resolve("data"));
+            final Path config = root.resolve("cassandra.yml");
+            Files.copy(getClass().getResourceAsStream("/cassandra.yaml"), config);
+            System.setProperty("cassandra.config", "file:" + config.toString());
+            System.setProperty("cassandra.storagedir", root.toString());
+            System.setProperty("cassandra-foreground", "true"); // prevents Cassandra from closing stdout/stderr
+            THREAD_FACTORY.newThread(embeddedCassandra).start();
+            latch.await();
+            final Throwable error = errorRef.get();
+            if (error instanceof NoClassDefFoundError) {
+                throw new TestAbortedException("Unsupported platform", error);
+            }
+            final var cluster = Cluster.builder().addContactPoints(InetAddress.getLoopbackAddress()).build();
+            final var store = context.getStore(
+                    ExtensionContext.Namespace.create(CassandraFixture.class, context.getRequiredTestInstance()));
+            store.put(Cluster.class, cluster);
+            store.put(EmbeddedCassandra.class, embeddedCassandra);
+            try (final Session session = cluster.connect()) {
+                session.execute("CREATE KEYSPACE " + cassandraFixture.keyspace() + " WITH REPLICATION = " +
+                        "{ 'class': 'SimpleStrategy', 'replication_factor': 2 };");
+                for (final String ddl : cassandraFixture.setup()) {
+                    session.execute(ddl);
+                }
+            }
+        }
+
+    }
+
+    @Override
+    public void afterEach(final ExtensionContext context) throws Exception {
+        final var store =
+                context.getStore(ExtensionContext.Namespace.create(CassandraFixture.class, context.getRequiredTestInstance()));
+        final var cluster = store.get(Cluster.class, Cluster.class);
+        final var embeddedCassandra = store.get(EmbeddedCassandra.class, EmbeddedCassandra.class);
+        if (embeddedCassandra != null) {
+            Closer.closeSilently(cluster);
+            embeddedCassandra.cancel();
+        }
+    }
+
+    @Override
+    public Cluster resolveParameter(
+            final ParameterContext parameterContext, final ExtensionContext extensionContext)
+            throws ParameterResolutionException {
+        final var store = extensionContext.getStore(
+                ExtensionContext.Namespace.create(CassandraFixture.class, extensionContext.getRequiredTestInstance()));
+        return store.get(Cluster.class, Cluster.class);
+    }
+
+    private static class EmbeddedCassandra implements Cancellable {
+
+        private final CassandraDaemon daemon = new CassandraDaemon();
+        private final CountDownLatch latch;
+        private final AtomicReference<Throwable> errorRef;
+
+        private EmbeddedCassandra(
+                final CountDownLatch latch, final AtomicReference<Throwable> errorRef) {
+            this.latch = latch;
+            this.errorRef = errorRef;
+        }
+
+        @Override
+        public void cancel() {
+            // LOG4J2-1850 Cassandra on Windows calls System.exit in the daemon stop method
+            if (PropertiesUtil.getProperties().isOsWindows()) {
+                cancelOnWindows();
+            } else {
+                daemon.stop();
+            }
+        }
+
+        private void cancelOnWindows() {
+            final SecurityManager currentSecurityManager = System.getSecurityManager();
+            try {
+                final SecurityManager securityManager = new SecurityManager() {
+                    @Override
+                    public void checkPermission(final Permission permission) {
+                        final String permissionName = permission.getName();
+                        if (permissionName != null && permissionName.startsWith("exitVM")) {
+                            throw new SecurityException("test");
+                        }
+                    }
+                };
+                System.setSecurityManager(securityManager);
+                daemon.stop();
+            } catch (final SecurityException ex) {
+                // ignore
+            } finally {
+                System.setSecurityManager(currentSecurityManager);
+            }
+        }
+
+        @Override
+        public void run() {
+            try {
+                daemon.init(null);
+                daemon.start();
+            } catch (final Exception e) {
+                errorRef.set(Throwables.getRootCause(e));
+            }
+            latch.countDown();
+        }
+    }
+}
diff --git a/log4j-cassandra/src/test/java/org/apache/logging/log4j/cassandra/CassandraFixture.java b/log4j-cassandra/src/test/java/org/apache/logging/log4j/cassandra/CassandraFixture.java
new file mode 100644
index 0000000..1c9e893
--- /dev/null
+++ b/log4j-cassandra/src/test/java/org/apache/logging/log4j/cassandra/CassandraFixture.java
@@ -0,0 +1,42 @@
+/*
+ * 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.logging.log4j.cassandra;
+
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.api.extension.ExtendWith;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Target(ElementType.METHOD)
+@Retention(RetentionPolicy.RUNTIME)
+@ExtendWith(CassandraExtension.class)
+@Tag("cassandra")
+public @interface CassandraFixture {
+    /**
+     * Name of keyspace to create.
+     */
+    String keyspace();
+
+    /**
+     * List of setup statements to execute in keyspace.
+     */
+    String[] setup();
+}
diff --git a/log4j-cassandra/src/test/java/org/apache/logging/log4j/cassandra/CassandraRule.java b/log4j-cassandra/src/test/java/org/apache/logging/log4j/cassandra/CassandraRule.java
deleted file mode 100644
index 2939d07..0000000
--- a/log4j-cassandra/src/test/java/org/apache/logging/log4j/cassandra/CassandraRule.java
+++ /dev/null
@@ -1,141 +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.logging.log4j.cassandra;
-
-import java.io.IOException;
-import java.net.InetAddress;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.security.Permission;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.ThreadFactory;
-
-import com.datastax.driver.core.Cluster;
-import com.datastax.driver.core.Session;
-import org.apache.cassandra.service.CassandraDaemon;
-import org.apache.logging.log4j.LoggingException;
-import org.apache.logging.log4j.core.util.Cancellable;
-import org.apache.logging.log4j.core.util.Closer;
-import org.apache.logging.log4j.core.util.Log4jThreadFactory;
-import org.apache.logging.log4j.util.PropertiesUtil;
-import org.junit.rules.ExternalResource;
-
-/**
- * JUnit rule to set up and tear down a Cassandra database instance.
- */
-public class CassandraRule extends ExternalResource {
-
-    private static final ThreadFactory THREAD_FACTORY = Log4jThreadFactory.createThreadFactory("Cassandra");
-
-    private final CountDownLatch latch = new CountDownLatch(1);
-    private final Cancellable embeddedCassandra = new EmbeddedCassandra(latch);
-    private final String keyspace;
-    private final String tableDdl;
-    private Cluster cluster;
-
-    public CassandraRule(final String keyspace, final String tableDdl) {
-        this.keyspace = keyspace;
-        this.tableDdl = tableDdl;
-    }
-
-    public Cluster getCluster() {
-        return cluster;
-    }
-
-    public Session connect() {
-        return cluster.connect(keyspace);
-    }
-
-    @Override
-    protected void before() throws Throwable {
-        final Path root = Files.createTempDirectory("cassandra");
-        Files.createDirectories(root.resolve("data"));
-        final Path config = root.resolve("cassandra.yml");
-        Files.copy(getClass().getResourceAsStream("/cassandra.yaml"), config);
-        System.setProperty("cassandra.config", "file:" + config.toString());
-        System.setProperty("cassandra.storagedir", root.toString());
-        System.setProperty("cassandra-foreground", "true"); // prevents Cassandra from closing stdout/stderr
-        THREAD_FACTORY.newThread(embeddedCassandra).start();
-        latch.await();
-        cluster = Cluster.builder().addContactPoints(InetAddress.getLoopbackAddress()).build();
-        try (final Session session = cluster.connect()) {
-            session.execute("CREATE KEYSPACE " + keyspace + " WITH REPLICATION = " +
-                "{ 'class': 'SimpleStrategy', 'replication_factor': 2 };");
-        }
-        try (final Session session = connect()) {
-            session.execute(tableDdl);
-        }
-    }
-
-    @Override
-    protected void after() {
-        Closer.closeSilently(cluster);
-        embeddedCassandra.cancel();
-    }
-
-    private static class EmbeddedCassandra implements Cancellable {
-
-        private final CassandraDaemon daemon = new CassandraDaemon();
-        private final CountDownLatch latch;
-
-        private EmbeddedCassandra(final CountDownLatch latch) {
-            this.latch = latch;
-        }
-
-        @Override
-        public void cancel() {
-            // LOG4J2-1850 Cassandra on Windows calls System.exit in the daemon stop method
-            if (PropertiesUtil.getProperties().isOsWindows()) {
-                cancelOnWindows();
-            } else {
-                daemon.stop();
-            }
-        }
-
-        private void cancelOnWindows() {
-            final SecurityManager currentSecurityManager = System.getSecurityManager();
-            try {
-                final SecurityManager securityManager = new SecurityManager() {
-                    @Override
-                    public void checkPermission(final Permission permission) {
-                        final String permissionName = permission.getName();
-                        if (permissionName != null && permissionName.startsWith("exitVM")) {
-                            throw new SecurityException("test");
-                        }
-                    }
-                };
-                System.setSecurityManager(securityManager);
-                daemon.stop();
-            } catch (final SecurityException ex) {
-                // ignore
-            } finally {
-                System.setSecurityManager(currentSecurityManager);
-            }
-        }
-
-        @Override
-        public void run() {
-            try {
-                daemon.init(null);
-            } catch (final IOException e) {
-                throw new LoggingException("Cannot initialize embedded Cassandra instance", e);
-            }
-            daemon.start();
-            latch.countDown();
-        }
-    }
-}