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

rec pushed a commit to branch 
bugfix/231-CAS-not-reset-if-validation-fails-in-managed-CASes
in repository https://gitbox.apache.org/repos/asf/uima-uimafit.git

commit 94dc9a19b93878870cd843ceb730579ea9967b96
Author: Richard Eckart de Castilho <r...@apache.org>
AuthorDate: Wed Jul 5 12:17:33 2023 +0200

    Issue #231: CAS not reset if validation fails in managed CASes
    
    - Fix issue that CAS is not reset if validation fails
    - Added unit tests
---
 .../apache/uima/fit/testing/junit/ManagedCas.java  | 22 +++++++-
 .../apache/uima/fit/testing/junit/ManagedJCas.java | 22 +++++++-
 .../uima/fit/testing/junit/ManagedCasTest.java     | 66 ++++++++++++++++++++++
 .../uima/fit/testing/junit/ManagedJCasTest.java    | 66 ++++++++++++++++++++++
 4 files changed, 170 insertions(+), 6 deletions(-)

diff --git 
a/uimafit-junit/src/main/java/org/apache/uima/fit/testing/junit/ManagedCas.java 
b/uimafit-junit/src/main/java/org/apache/uima/fit/testing/junit/ManagedCas.java
index 98b6aac..a1edd91 100644
--- 
a/uimafit-junit/src/main/java/org/apache/uima/fit/testing/junit/ManagedCas.java
+++ 
b/uimafit-junit/src/main/java/org/apache/uima/fit/testing/junit/ManagedCas.java
@@ -26,6 +26,7 @@ import static 
org.apache.uima.fit.factory.CasFactory.createCas;
 import static org.apache.uima.fit.validation.ValidationResult.Severity.ERROR;
 import static org.junit.jupiter.api.Assertions.fail;
 
+import java.lang.invoke.MethodHandles;
 import java.util.Set;
 import java.util.WeakHashMap;
 
@@ -41,6 +42,8 @@ import org.junit.jupiter.api.extension.AfterAllCallback;
 import org.junit.jupiter.api.extension.AfterTestExecutionCallback;
 import org.junit.jupiter.api.extension.ExtensionContext;
 import org.junit.jupiter.api.extension.TestWatcher;
+import org.junit.platform.commons.logging.Logger;
+import org.junit.platform.commons.logging.LoggerFactory;
 
 /**
  * Provides a {@link CAS} object which is automatically reset before the test. 
The idea of this
@@ -53,6 +56,8 @@ import org.junit.jupiter.api.extension.TestWatcher;
 public final class ManagedCas implements TestWatcher, 
AfterTestExecutionCallback, AfterAllCallback {
   private final ThreadLocal<CAS> casHolder;
 
+  private static final Logger LOG = 
LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
+
   private final Set<CAS> managedCases = synchronizedSet(newSetFromMap(new 
WeakHashMap<>()));
 
   private Validator defaultValidator = new Validator.Builder().build();
@@ -117,9 +122,20 @@ public final class ManagedCas implements TestWatcher, 
AfterTestExecutionCallback
   public void afterTestExecution(ExtensionContext context) throws Exception {
     try {
       managedCases.forEach(this::assertValid);
-      managedCases.forEach(CAS::reset);
     } finally {
-      this.validator = null;
+      reset();
+    }
+  }
+
+  private void reset() {
+    this.validator = null;
+
+    for (CAS cas : managedCases) {
+      try {
+        cas.reset();
+      } catch (Exception e) {
+        LOG.error(e, () -> "Unable to reset managed CAS");
+      }
     }
   }
 
@@ -165,7 +181,7 @@ public final class ManagedCas implements TestWatcher, 
AfterTestExecutionCallback
     return this;
   }
 
-  private Validator getValidator() {
+  Validator getValidator() {
     if (validator != null) {
       return validator;
     }
diff --git 
a/uimafit-junit/src/main/java/org/apache/uima/fit/testing/junit/ManagedJCas.java
 
b/uimafit-junit/src/main/java/org/apache/uima/fit/testing/junit/ManagedJCas.java
index 8ff2a55..99a1c9c 100644
--- 
a/uimafit-junit/src/main/java/org/apache/uima/fit/testing/junit/ManagedJCas.java
+++ 
b/uimafit-junit/src/main/java/org/apache/uima/fit/testing/junit/ManagedJCas.java
@@ -26,6 +26,7 @@ import static 
org.apache.uima.fit.factory.JCasFactory.createJCas;
 import static org.apache.uima.fit.validation.ValidationResult.Severity.ERROR;
 import static org.junit.jupiter.api.Assertions.fail;
 
+import java.lang.invoke.MethodHandles;
 import java.util.Set;
 import java.util.WeakHashMap;
 
@@ -41,6 +42,8 @@ import org.junit.jupiter.api.extension.AfterAllCallback;
 import org.junit.jupiter.api.extension.AfterTestExecutionCallback;
 import org.junit.jupiter.api.extension.ExtensionContext;
 import org.junit.jupiter.api.extension.TestWatcher;
+import org.junit.platform.commons.logging.Logger;
+import org.junit.platform.commons.logging.LoggerFactory;
 
 /**
  * Provides a {@link JCas} object which is automatically reset before the 
test. The idea of this
@@ -54,6 +57,8 @@ public final class ManagedJCas
         implements TestWatcher, AfterTestExecutionCallback, AfterAllCallback {
   private final ThreadLocal<JCas> casHolder;
 
+  private static final Logger LOG = 
LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
+
   private final Set<JCas> managedCases = synchronizedSet(newSetFromMap(new 
WeakHashMap<>()));
 
   private Validator defaultValidator = new Validator.Builder().build();
@@ -118,9 +123,20 @@ public final class ManagedJCas
   public void afterTestExecution(ExtensionContext context) throws Exception {
     try {
       managedCases.forEach(this::assertValid);
-      managedCases.forEach(JCas::reset);
     } finally {
-      this.validator = null;
+      reset();
+    }
+  }
+
+  private void reset() {
+    this.validator = null;
+
+    for (JCas cas : managedCases) {
+      try {
+        cas.reset();
+      } catch (Exception e) {
+        LOG.error(e, () -> "Unable to reset managed CAS");
+      }
     }
   }
 
@@ -166,7 +182,7 @@ public final class ManagedJCas
     return this;
   }
 
-  private Validator getValidator() {
+  Validator getValidator() {
     if (validator != null) {
       return validator;
     }
diff --git 
a/uimafit-junit/src/test/java/org/apache/uima/fit/testing/junit/ManagedCasTest.java
 
b/uimafit-junit/src/test/java/org/apache/uima/fit/testing/junit/ManagedCasTest.java
new file mode 100644
index 0000000..56ca059
--- /dev/null
+++ 
b/uimafit-junit/src/test/java/org/apache/uima/fit/testing/junit/ManagedCasTest.java
@@ -0,0 +1,66 @@
+/*
+ * 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.uima.fit.testing.junit;
+
+import static java.util.Arrays.asList;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
+
+import org.apache.uima.cas.CAS;
+import org.apache.uima.fit.validation.ValidationResult;
+import org.apache.uima.fit.validation.Validator;
+import org.junit.jupiter.api.Test;
+import org.opentest4j.AssertionFailedError;
+
+class ManagedCasTest {
+
+  private ManagedCas sut = new ManagedCas();
+
+  @Test
+  void thatValidatorIsResetBeforeNextTest() throws Exception {
+    Validator defaultValidator = sut.getValidator();
+    Validator transientValidator = new Validator.Builder().build();
+    sut.withValidator(transientValidator);
+    assertThat(sut.getValidator()).isSameAs(transientValidator);
+    sut.afterTestExecution(null);
+    assertThat(sut.getValidator()).isSameAs(defaultValidator);
+  }
+
+  @Test
+  void thatCasIsResetBeforeNextTest() throws Exception {
+    CAS cas = sut.get();
+    cas.setDocumentText("test");
+    sut.afterTestExecution(null);
+    assertThat(cas.getDocumentText()).isNull();
+  }
+
+  @Test
+  void thatCasIsResetBeforeNextTestIfValidationFails() throws Exception {
+    sut.withValidator(new Validator.Builder()
+            .withCheck(cas -> asList(ValidationResult.error(this, 
"fail"))).build());
+    CAS cas = sut.get();
+    cas.setDocumentText("test");
+    assertThatExceptionOfType(AssertionFailedError.class) //
+            .as("Validation should fail") //
+            .isThrownBy(() -> sut.afterTestExecution(null));
+    assertThat(cas.getDocumentText()) //
+            .as("Despite failed validation, CAS should have been reset") //
+            .isNull();
+  }
+}
diff --git 
a/uimafit-junit/src/test/java/org/apache/uima/fit/testing/junit/ManagedJCasTest.java
 
b/uimafit-junit/src/test/java/org/apache/uima/fit/testing/junit/ManagedJCasTest.java
new file mode 100644
index 0000000..e07cdd1
--- /dev/null
+++ 
b/uimafit-junit/src/test/java/org/apache/uima/fit/testing/junit/ManagedJCasTest.java
@@ -0,0 +1,66 @@
+/*
+ * 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.uima.fit.testing.junit;
+
+import static java.util.Arrays.asList;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
+
+import org.apache.uima.fit.validation.ValidationResult;
+import org.apache.uima.fit.validation.Validator;
+import org.apache.uima.jcas.JCas;
+import org.junit.jupiter.api.Test;
+import org.opentest4j.AssertionFailedError;
+
+class ManagedJCasTest {
+
+  private ManagedJCas sut = new ManagedJCas();
+
+  @Test
+  void thatValidatorIsResetBeforeNextTest() throws Exception {
+    Validator defaultValidator = sut.getValidator();
+    Validator transientValidator = new Validator.Builder().build();
+    sut.withValidator(transientValidator);
+    assertThat(sut.getValidator()).isSameAs(transientValidator);
+    sut.afterTestExecution(null);
+    assertThat(sut.getValidator()).isSameAs(defaultValidator);
+  }
+
+  @Test
+  void thatCasIsResetBeforeNextTest() throws Exception {
+    JCas cas = sut.get();
+    cas.setDocumentText("test");
+    sut.afterTestExecution(null);
+    assertThat(cas.getDocumentText()).isNull();
+  }
+
+  @Test
+  void thatCasIsResetBeforeNextTestIfValidationFails() throws Exception {
+    sut.withValidator(new Validator.Builder()
+            .withCheck(cas -> asList(ValidationResult.error(this, 
"fail"))).build());
+    JCas cas = sut.get();
+    cas.setDocumentText("test");
+    assertThatExceptionOfType(AssertionFailedError.class) //
+            .as("Validation should fail") //
+            .isThrownBy(() -> sut.afterTestExecution(null));
+    assertThat(cas.getDocumentText()) //
+            .as("Despite failed validation, JCAS should have been reset") //
+            .isNull();
+  }
+}

Reply via email to