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();
- }
- }
-}