You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@uima.apache.org by re...@apache.org on 2021/08/11 13:58:24 UTC

[uima-uimaj] 01/01: [UIMA-6374] Create CAS (de)serialization test suite

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

rec pushed a commit to branch origin/feature/UIMA-6374-Create-CAS-de--serialization-test-suite
in repository https://gitbox.apache.org/repos/asf/uima-uimaj.git

commit bdd2d69a77a8c7f60255fcd66805f2fd22337d0a
Author: Richard Eckart de Castilho <re...@apache.org>
AuthorDate: Wed Aug 11 15:58:02 2021 +0200

    [UIMA-6374] Create CAS (de)serialization test suite
    
    - Added additional test type "SER_DES"
    - Added option to configure random seed and to report random seed when randomized test fails
    - When comparing CASes with toComparableString, first convert both CASes to the string representation and then compare the string representation
---
 .../java/org/apache/uima/cas/serdes/TestType.java  |  8 +++++-
 .../datasuites/MultiFeatureRandomCasDataSuite.java |  2 +-
 .../datasuites/MultiTypeRandomCasDataSuite.java    | 12 ++++++---
 .../cas/serdes/generators/CasConfiguration.java    |  3 ++-
 .../generators/MultiTypeRandomCasGenerator.java    | 31 +++++++++++++++++-----
 .../cas/serdes/scenario/SerDesTestScenario.java    | 11 +++++---
 .../transitions/CasSourceTargetConfiguration.java  | 12 +++++++++
 7 files changed, 63 insertions(+), 16 deletions(-)

diff --git a/uimaj-core/src/test/java/org/apache/uima/cas/serdes/TestType.java b/uimaj-core/src/test/java/org/apache/uima/cas/serdes/TestType.java
index 7a00cf4..83f23b6 100644
--- a/uimaj-core/src/test/java/org/apache/uima/cas/serdes/TestType.java
+++ b/uimaj-core/src/test/java/org/apache/uima/cas/serdes/TestType.java
@@ -52,7 +52,13 @@ public enum TestType {
    * the derserialization mechanism for special cases that cannot be covered by {@link #ONE_WAY} or
    * {@link #ROUND_TRIP}.
    */
-  DES_REF(null, "des-ref", "des-ref");
+  DES_REF(null, "des-ref", "des-ref"),
+
+  /**
+   * Test serializes a CAS object from memory and then de-serializes it again. The target folder is
+   * used to store the intermediate representation for debugging purposes.
+   */
+  SER_DES(null, "ser-des", null);
 
   private String sourceFolderName;
   private String referenceFolderName;
diff --git a/uimaj-core/src/test/java/org/apache/uima/cas/serdes/datasuites/MultiFeatureRandomCasDataSuite.java b/uimaj-core/src/test/java/org/apache/uima/cas/serdes/datasuites/MultiFeatureRandomCasDataSuite.java
index 13b890d..8dc09fc 100644
--- a/uimaj-core/src/test/java/org/apache/uima/cas/serdes/datasuites/MultiFeatureRandomCasDataSuite.java
+++ b/uimaj-core/src/test/java/org/apache/uima/cas/serdes/datasuites/MultiFeatureRandomCasDataSuite.java
@@ -38,7 +38,7 @@ public class MultiFeatureRandomCasDataSuite {
       CasConfiguration cfg = new CasConfiguration(randomizer);
 
       confs.add(CasSourceTargetConfiguration.builder() //
-              .withTitle("randomCas-" + (n + 1)) //
+              .withTitle("MultiFeatureRandomCasDataSuite-" + (n + 1)) //
               .withSourceCasSupplier(cfg::generateRandomCas) //
               .withTargetCasSupplier(cfg::generateTargetCas) //
               .build());
diff --git a/uimaj-core/src/test/java/org/apache/uima/cas/serdes/datasuites/MultiTypeRandomCasDataSuite.java b/uimaj-core/src/test/java/org/apache/uima/cas/serdes/datasuites/MultiTypeRandomCasDataSuite.java
index 6900673..afcfff9 100644
--- a/uimaj-core/src/test/java/org/apache/uima/cas/serdes/datasuites/MultiTypeRandomCasDataSuite.java
+++ b/uimaj-core/src/test/java/org/apache/uima/cas/serdes/datasuites/MultiTypeRandomCasDataSuite.java
@@ -27,20 +27,26 @@ import org.apache.uima.cas.serdes.transitions.CasSourceTargetConfiguration;
 
 public class MultiTypeRandomCasDataSuite {
 
+  private static final int SIZE_FACTOR = 10;
+
   public static List<CasSourceTargetConfiguration> configurations(int aCount) {
     List<CasSourceTargetConfiguration> confs = new ArrayList<>();
 
     for (int n = 0; n < aCount; n++) {
       MultiTypeRandomCasGenerator randomizer = MultiTypeRandomCasGenerator.builder() //
-              .withTypeCount(aCount + 1) //
+              // NOTE: When you need to debug a certain configuration, comment out and set the
+              // random seed for the broken configuration. Do not commit with this line active!
+              // .withRandomSeed(-5987713889340419492l) //
+              .withTypeCount(n + 1) //
               .withMinimumAnnotationLength(0) //
-              .withSize((aCount + 1) * 10) //
+              .withSize((n + 1) * SIZE_FACTOR) //
               .build();
 
       CasConfiguration cfg = new CasConfiguration(randomizer);
 
       confs.add(CasSourceTargetConfiguration.builder() //
-              .withTitle("randomCas-" + (n + 1)) //
+              .withTitle("MultiTypeRandomCasDataSuite-" + (n + 1)) //
+              .withDebugInfo("Random seed: " + randomizer.getSeed()) //
               .withSourceCasSupplier(cfg::generateRandomCas) //
               .withTargetCasSupplier(cfg::generateTargetCas) //
               .build());
diff --git a/uimaj-core/src/test/java/org/apache/uima/cas/serdes/generators/CasConfiguration.java b/uimaj-core/src/test/java/org/apache/uima/cas/serdes/generators/CasConfiguration.java
index 3cecdc6..7ba48ef 100644
--- a/uimaj-core/src/test/java/org/apache/uima/cas/serdes/generators/CasConfiguration.java
+++ b/uimaj-core/src/test/java/org/apache/uima/cas/serdes/generators/CasConfiguration.java
@@ -21,6 +21,7 @@ package org.apache.uima.cas.serdes.generators;
 import org.apache.uima.cas.CAS;
 import org.apache.uima.resource.ResourceInitializationException;
 import org.apache.uima.resource.metadata.TypeSystemDescription;
+import org.apache.uima.util.CasCreationUtils;
 
 public class CasConfiguration {
   private final CasGenerator randomizer;
@@ -44,6 +45,6 @@ public class CasConfiguration {
   }
 
   public CAS generateTargetCas() throws ResourceInitializationException {
-    return randomizer.generateCas(generateTypeSystem());
+    return CasCreationUtils.createCas(generateTypeSystem(), null, null, null);
   }
 }
\ No newline at end of file
diff --git a/uimaj-core/src/test/java/org/apache/uima/cas/serdes/generators/MultiTypeRandomCasGenerator.java b/uimaj-core/src/test/java/org/apache/uima/cas/serdes/generators/MultiTypeRandomCasGenerator.java
index a6164e3..e743880 100644
--- a/uimaj-core/src/test/java/org/apache/uima/cas/serdes/generators/MultiTypeRandomCasGenerator.java
+++ b/uimaj-core/src/test/java/org/apache/uima/cas/serdes/generators/MultiTypeRandomCasGenerator.java
@@ -25,6 +25,7 @@ import java.util.ArrayList;
 import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.OptionalLong;
 import java.util.Random;
 
 import org.apache.uima.cas.CAS;
@@ -36,6 +37,7 @@ import org.apache.uima.resource.metadata.TypeSystemDescription;
 import org.apache.uima.util.CasCreationUtils;
 
 public class MultiTypeRandomCasGenerator implements CasGenerator {
+  private final Long seed;
   private final Random rnd;
   private final int size;
   private final int minimumWidth;
@@ -43,13 +45,18 @@ public class MultiTypeRandomCasGenerator implements CasGenerator {
   private final int typeCount;
 
   private MultiTypeRandomCasGenerator(Builder builder) {
-    this.rnd = builder.randomGenerator;
+    this.seed = builder.seed;
+    this.rnd = builder.randomizer != null ? builder.randomizer : new Random(seed);
     this.size = builder.size;
     this.minimumWidth = builder.minimumWidth;
     this.writeLog = builder.writeLog;
     this.typeCount = builder.typeCount;
   }
 
+  public OptionalLong getSeed() {
+    return seed != null ? OptionalLong.of(seed) : OptionalLong.empty();
+  }
+
   @Override
   public TypeSystemDescription generateTypeSystem() {
     TypeSystemDescription tsd = getResourceSpecifierFactory().createTypeSystemDescription();
@@ -130,7 +137,8 @@ public class MultiTypeRandomCasGenerator implements CasGenerator {
    * Builder to build {@link MultiTypeRandomCasGenerator}.
    */
   public static final class Builder {
-    private Random randomGenerator;
+    private Long seed;
+    private Random randomizer;
     private int size;
     private int minimumWidth;
     private boolean writeLog;
@@ -139,8 +147,11 @@ public class MultiTypeRandomCasGenerator implements CasGenerator {
     private Builder() {
     }
 
-    public Builder withRandomGenerator(Random rnd) {
-      this.randomGenerator = rnd;
+    public Builder withRandomSeed(long aSeed) {
+      if (randomizer != null) {
+        throw new IllegalStateException("Can either set a random seed or a randomizer");
+      }
+      this.seed = aSeed;
       return this;
     }
 
@@ -165,11 +176,19 @@ public class MultiTypeRandomCasGenerator implements CasGenerator {
     }
 
     public MultiTypeRandomCasGenerator build() {
-      if (randomGenerator == null) {
-        randomGenerator = new Random();
+      if (seed == null && randomizer == null) {
+        seed = new Random().nextLong();
       }
 
       return new MultiTypeRandomCasGenerator(this);
     }
+
+    public Builder withRandomGenerator(Random aRnd) {
+      if (seed != null) {
+        throw new IllegalStateException("Can either set a random seed or a randomizer");
+      }
+      randomizer = aRnd;
+      return this;
+    }
   }
 }
diff --git a/uimaj-core/src/test/java/org/apache/uima/cas/serdes/scenario/SerDesTestScenario.java b/uimaj-core/src/test/java/org/apache/uima/cas/serdes/scenario/SerDesTestScenario.java
index 93f6ebc..02bb063 100644
--- a/uimaj-core/src/test/java/org/apache/uima/cas/serdes/scenario/SerDesTestScenario.java
+++ b/uimaj-core/src/test/java/org/apache/uima/cas/serdes/scenario/SerDesTestScenario.java
@@ -18,7 +18,6 @@
  */
 package org.apache.uima.cas.serdes.scenario;
 
-import static java.util.Comparator.comparing;
 import static org.apache.uima.cas.serdes.CasToComparableText.toComparableString;
 import static org.assertj.core.api.Assertions.assertThat;
 
@@ -33,6 +32,7 @@ import org.assertj.core.internal.Failures;
 
 public class SerDesTestScenario implements Runnable {
   private final String title;
+  private final String debugInfo;
   private final FailableSupplier<CAS, ?> sourceCasSupplier;
   private final FailableSupplier<CAS, ?> targetCasSupplier;
   private final FailableBiConsumer<CAS, CAS, ?> cycle;
@@ -40,6 +40,7 @@ public class SerDesTestScenario implements Runnable {
   public SerDesTestScenario(CasSourceTargetConfiguration aSourceTargetConfig,
           CasSerDesCycleConfiguration aCycle) {
     title = aCycle.getTitle() + " - " + aSourceTargetConfig.getTitle();
+    debugInfo = aSourceTargetConfig.getDebugInfo();
     sourceCasSupplier = aSourceTargetConfig::createSourceCas;
     targetCasSupplier = aSourceTargetConfig::createTargetCas;
     cycle = aCycle::performCycle;
@@ -48,6 +49,7 @@ public class SerDesTestScenario implements Runnable {
   public SerDesTestScenario(String aTitle, FailableSupplier<CAS, ?> aSourceCasSupplier,
           FailableSupplier<CAS, ?> aTargetCasSupplier, FailableBiConsumer<CAS, CAS, ?> aCycle) {
     title = aTitle;
+    debugInfo = "no additional details";
     sourceCasSupplier = aSourceCasSupplier;
     targetCasSupplier = aTargetCasSupplier;
     cycle = aCycle;
@@ -83,11 +85,12 @@ public class SerDesTestScenario implements Runnable {
     serializationDeserializationCycle(sourceCas, targetCas);
 
     // Compare the de-serialized CAS against the original CAS
-    assertThat(targetCas) //
-            .usingComparator(comparing(cas -> toComparableString(cas))) //
-            .isEqualTo(sourceCas);
+    assertThat(toComparableString(targetCas)) //
+            .as("Comparable string representation must match (%s)", debugInfo)
+            .isEqualTo(toComparableString(sourceCas));
 
     assertThat(targetCas) //
+            .as("CasCompare comparison must match (%s)", debugInfo)
             .usingComparator((a, b) -> CasCompare.compareCASes((CASImpl) a, (CASImpl) b) ? 0 : 1) //
             .isEqualTo(sourceCas);
   }
diff --git a/uimaj-core/src/test/java/org/apache/uima/cas/serdes/transitions/CasSourceTargetConfiguration.java b/uimaj-core/src/test/java/org/apache/uima/cas/serdes/transitions/CasSourceTargetConfiguration.java
index db7edd6..b02f605 100644
--- a/uimaj-core/src/test/java/org/apache/uima/cas/serdes/transitions/CasSourceTargetConfiguration.java
+++ b/uimaj-core/src/test/java/org/apache/uima/cas/serdes/transitions/CasSourceTargetConfiguration.java
@@ -24,11 +24,13 @@ import org.assertj.core.internal.Failures;
 
 public class CasSourceTargetConfiguration {
   private final String title;
+  private final String debugInfo;
   private final FailableSupplier<CAS, ?> sourceCasSupplier;
   private final FailableSupplier<CAS, ?> targetCasSupplier;
 
   private CasSourceTargetConfiguration(Builder builder) {
     this.title = builder.title;
+    this.debugInfo = builder.debugInfo;
     this.sourceCasSupplier = builder.sourceCasSupplier;
     this.targetCasSupplier = builder.targetCasSupplier;
   }
@@ -57,6 +59,10 @@ public class CasSourceTargetConfiguration {
     return title;
   }
 
+  public String getDebugInfo() {
+    return debugInfo;
+  }
+
   /**
    * Creates builder to build {@link CasSourceTargetConfiguration}.
    * 
@@ -71,6 +77,7 @@ public class CasSourceTargetConfiguration {
    */
   public static final class Builder {
     private String title;
+    private String debugInfo;
     private FailableSupplier<CAS, ?> sourceCasSupplier;
     private FailableSupplier<CAS, ?> targetCasSupplier;
 
@@ -82,6 +89,11 @@ public class CasSourceTargetConfiguration {
       return this;
     }
 
+    public Builder withDebugInfo(String aDebugInfo) {
+      debugInfo = aDebugInfo;
+      return this;
+    }
+
     public Builder withSourceCasSupplier(FailableSupplier<CAS, ?> aSourceCasSupplier) {
       sourceCasSupplier = aSourceCasSupplier;
       return this;