From 9810d6bf8bade7cb056f18db7cef0f49cef9da38 Mon Sep 17 00:00:00 2001
From: Brandon Clayton <bclayton@usgs.gov>
Date: Fri, 1 Sep 2023 10:33:01 -0600
Subject: [PATCH] generate actual

---
 .gitignore                                    |  1 +
 .gitlab-ci.yml                                | 35 +------
 gradle/nshm.gradle                            | 91 +++++++++++++++++++
 .../nshmp/model/GenerateActual.java           | 22 +++++
 .../earthquake/nshmp/model/NshmTestUtils.java | 36 ++++----
 .../earthquake/nshmp/model/NshmTests.java     | 23 +++--
 6 files changed, 149 insertions(+), 59 deletions(-)
 create mode 100644 src/test/java/gov/usgs/earthquake/nshmp/model/GenerateActual.java

diff --git a/.gitignore b/.gitignore
index d4c5e0c3..e5021b74 100644
--- a/.gitignore
+++ b/.gitignore
@@ -22,6 +22,7 @@ nshms/
 .factorypath
 .apt_generated*
 *version.json
+src/test/resources/e2e/actual
 
 # Node
 node_modules
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 3fb882d2..7e6bcb78 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -266,13 +266,6 @@ Unit Tests:
   after_script:
     - cat ${JACOCO_HTML_DIR}/index.html
 
-.alaska-sites: &alaska-sites
-  - TEST_SITE: ANCHORAGE_AK
-  - TEST_SITE: FAIRBANKS_AK
-  - TEST_SITE: JUNEAU_AK
-  - TEST_SITE: KODIAK_AK
-  - TEST_SITE: VALDEZ_AK
-
 Alaska 2007 NSHM Test:
   extends:
     - .nshm-test
@@ -283,42 +276,24 @@ Alaska 2007 NSHM Test:
 Alaska 2023 NSHM Test:
   extends:
     - .nshm-test
-  parallel:
-    matrix:
-      *alaska-sites
   script:
-    - ./gradlew testAlaska2023 -DTEST_SITE=${TEST_SITE} --info
+    - ./gradlew testAlaska2023 --info
   stage: alaska-test
 
-.conus-sites: &conus-sites
-  - TEST_SITE: LOS_ANGELES_CA
-  - TEST_SITE: SAN_FRANCISCO_CA
-  - TEST_SITE: SEATTLE_WA
-  - TEST_SITE: SALT_LAKE_CITY_UT
-  - TEST_SITE: RENO_NV
-  - TEST_SITE: NEW_MADRID_MO
-  - TEST_SITE: BOSTON_MA
-  - TEST_SITE: NEW_YORK_NY
-  - TEST_SITE: CHICAGO_IL
-
 CONUS 2018 NSHM Test:
   extends:
     - .nshm-test
-  parallel:
-    matrix:
-      *conus-sites
   script:
-    - ./gradlew testConus2018 -DTEST_SITE=${TEST_SITE} --info
+    - ./gradlew generateConus2018 --info
+    - ./gradlew testConus2018 --info
   stage: conus-test
 
 CONUS 2023 NSHM Test:
   extends:
     - .nshm-test
-  parallel:
-    matrix:
-      *conus-sites
   script:
-    - ./gradlew testConus2023 -DTEST_SITE=${TEST_SITE} --info
+    - ./gradlew generateConus2023 --info
+    - ./gradlew testConus2023 --info
   stage: conus-test
 
 Hawaii 2021 NSHM Test:
diff --git a/gradle/nshm.gradle b/gradle/nshm.gradle
index 86cce87f..086ebc77 100644
--- a/gradle/nshm.gradle
+++ b/gradle/nshm.gradle
@@ -78,6 +78,97 @@ task nshms() {
   }
 }
 
+// Generate Alaska 2007 for CI
+task generateAlaska2007(type: JavaExec) {
+  description = "Generate alaska-2007 acutal for CI/CD"
+  classpath = sourceSets.test.runtimeClasspath
+
+  doFirst {
+    downloadNshm(findNshm("nshm-alaska", 2007))
+  }
+
+  jvmArgs(
+      "-Xms2g",
+      "-Xmx${xmx}",
+      "-DNSHM=nshm-alaska-2007"
+      )
+
+  main = "gov.usgs.earthquake.nshmp.model.GenerateActual"
+}
+
+// Generate Alaska 2023 for CI
+task generateAlaska2023(type: JavaExec) {
+  description = "Generate alaska-2023 acutal for CI/CD"
+  classpath = sourceSets.test.runtimeClasspath
+
+  doFirst {
+    downloadNshm(findNshm("nshm-alaska", 2023))
+  }
+
+  jvmArgs(
+      "-Xms2g",
+      "-Xmx${xmx}",
+      "-DNSHM=nshm-alaska-2023"
+      )
+
+  main = "gov.usgs.earthquake.nshmp.model.GenerateActual"
+}
+
+
+// Generate CONUS 2018 for CI
+task generateConus2018(type: JavaExec) {
+  description = "Generate conus-2018 acutal for CI/CD"
+  classpath = sourceSets.test.runtimeClasspath
+
+  doFirst {
+    downloadNshm(findNshm("nshm-conus", 2018))
+  }
+
+  jvmArgs(
+      "-Xms2g",
+      "-Xmx${xmx}",
+      "-DNSHM=nshm-conus-2018"
+      )
+
+  main = "gov.usgs.earthquake.nshmp.model.GenerateActual"
+}
+
+// Generate CONUS 2023 for CI
+task generateConus2023(type: JavaExec) {
+  description = "Generate conus-2023 acutal for CI/CD"
+  classpath = sourceSets.test.runtimeClasspath
+
+  doFirst {
+    downloadNshm(findNshm("nshm-conus", 2023))
+  }
+
+  jvmArgs(
+      "-Xms2g",
+      "-Xmx${xmx}",
+      "-DNSHM=nshm-conus-2023"
+      )
+
+  main = "gov.usgs.earthquake.nshmp.model.GenerateActual"
+}
+
+// Generate Hawaii 2021 for CI
+task generateHawaii2021(type: JavaExec) {
+  description = "Generate hawaii-2021 acutal for CI/CD"
+  classpath = sourceSets.test.runtimeClasspath
+
+  doFirst {
+    downloadNshm(findNshm("nshm-hawaii", 2021))
+  }
+
+  jvmArgs(
+      "-Xms2g",
+      "-Xmx${xmx}",
+      "-DNSHM=nshm-hawaii-2021"
+      )
+
+  main = "gov.usgs.earthquake.nshmp.model.GenerateActual"
+}
+
 // Test Alaska 2007 NSHM
 task testAlaska2007(type: Test) {
   description = "Test Alaska 2007 NSHM"
diff --git a/src/test/java/gov/usgs/earthquake/nshmp/model/GenerateActual.java b/src/test/java/gov/usgs/earthquake/nshmp/model/GenerateActual.java
new file mode 100644
index 00000000..489304c5
--- /dev/null
+++ b/src/test/java/gov/usgs/earthquake/nshmp/model/GenerateActual.java
@@ -0,0 +1,22 @@
+package gov.usgs.earthquake.nshmp.model;
+
+import java.io.IOException;
+import java.util.Optional;
+
+import gov.usgs.earthquake.nshmp.model.NshmTestUtils.Nshm;
+import gov.usgs.earthquake.nshmp.model.NshmTestUtils.NshmModel;
+
+/**
+ * Generate actual results to compare to expected results.
+ *
+ * Used in CI environment for faster unit tests.
+ */
+class GenerateActual {
+
+  public static void main(String[] args) throws IOException {
+    Nshm nshm = NshmTests.NSHMS.get(System.getProperty("NSHM"));
+    NshmModel nshmModel = NshmTestUtils.loadModel(nshm);
+    NshmTestUtils.writeExpecteds(nshmModel, Optional.of(NshmTests.DATA_PATH));
+    nshmModel.exec.shutdown();
+  }
+}
diff --git a/src/test/java/gov/usgs/earthquake/nshmp/model/NshmTestUtils.java b/src/test/java/gov/usgs/earthquake/nshmp/model/NshmTestUtils.java
index 8edc4534..cb390cc0 100644
--- a/src/test/java/gov/usgs/earthquake/nshmp/model/NshmTestUtils.java
+++ b/src/test/java/gov/usgs/earthquake/nshmp/model/NshmTestUtils.java
@@ -35,7 +35,6 @@ import gov.usgs.earthquake.nshmp.calc.Site;
 import gov.usgs.earthquake.nshmp.data.XySequence;
 import gov.usgs.earthquake.nshmp.geo.Location;
 import gov.usgs.earthquake.nshmp.gmm.Imt;
-import gov.usgs.earthquake.nshmp.site.NshmpSite;
 
 import io.swagger.v3.core.util.Yaml;
 
@@ -84,17 +83,12 @@ class NshmTestUtils {
    *
    * @param nshm The NSHM to test
    */
-  static void testNshm(Nshm nshm, Optional<NshmpSite> site) {
+  static void testNshm(Nshm nshm, Optional<Path> dataPath) {
     NshmModel nshmModel = loadModel(nshm);
 
-    if (site.isPresent()) {
-      LOGGER.info("Location: " + site.get().toString());
-      compareCurves(nshmModel, site.get());
-    } else {
-      for (NamedLocation location : nshm.locations()) {
-        LOGGER.info("Location: " + location.toString());
-        compareCurves(nshmModel, location);
-      }
+    for (NamedLocation location : nshm.locations()) {
+      LOGGER.info("Location: " + location.toString());
+      compareCurves(nshmModel, location, dataPath);
     }
 
     nshmModel.exec.shutdown();
@@ -105,11 +99,11 @@ class NshmTestUtils {
    *
    * @param nshmModel The NSHM model
    */
-  static void writeExpecteds(NshmModel nshmModel) throws IOException {
+  static void writeExpecteds(NshmModel nshmModel, Optional<Path> dataPath) throws IOException {
     for (NamedLocation location : nshmModel.nshm.locations()) {
       Map<String, XySequence> xyMap = generateActual(nshmModel, location);
       String json = GSON.toJson(xyMap);
-      writeExpected(nshmModel.nshm, location, json);
+      writeExpected(nshmModel.nshm, location, json, dataPath);
     }
   }
 
@@ -140,9 +134,11 @@ class NshmTestUtils {
         Double.valueOf(expected).equals(Double.valueOf(actual));
   }
 
-  private static void compareCurves(NshmModel nshmModel, NamedLocation location) {
-    Map<String, XySequence> actual = generateActual(nshmModel, location);
-    Map<String, XySequence> expected = readExpected(nshmModel, location);
+  private static void compareCurves(NshmModel nshmModel, NamedLocation location,
+      Optional<Path> dataPath) {
+    Map<String, XySequence> actual = dataPath.isPresent()
+        ? readExpected(nshmModel, location, dataPath) : generateActual(nshmModel, location);
+    Map<String, XySequence> expected = readExpected(nshmModel, location, Optional.empty());
 
     for (String key : actual.keySet()) {
       assertCurveEquals(expected.get(key), actual.get(key), TOLERANCE);
@@ -175,8 +171,9 @@ class NshmTestUtils {
     return xyMap;
   }
 
-  private static Map<String, XySequence> readExpected(NshmModel nshmModel, NamedLocation loc) {
-    Path resultPath = DATA_PATH
+  private static Map<String, XySequence> readExpected(NshmModel nshmModel, NamedLocation loc,
+      Optional<Path> dataPath) {
+    Path resultPath = dataPath.orElse(DATA_PATH)
         .resolve(nshmModel.nshm.modelName())
         .resolve(nshmModel.nshm.resultFilename(loc));
 
@@ -199,8 +196,9 @@ class NshmTestUtils {
   private static void writeExpected(
       Nshm nshm,
       NamedLocation loc,
-      String json) throws IOException {
-    Path modelDir = DATA_PATH.resolve(nshm.modelName());
+      String json,
+      Optional<Path> dataPath) throws IOException {
+    Path modelDir = dataPath.orElse(DATA_PATH).resolve(nshm.modelName());
     if (!Files.exists(modelDir)) {
       Files.createDirectories(modelDir);
     }
diff --git a/src/test/java/gov/usgs/earthquake/nshmp/model/NshmTests.java b/src/test/java/gov/usgs/earthquake/nshmp/model/NshmTests.java
index e174fc11..68417b07 100644
--- a/src/test/java/gov/usgs/earthquake/nshmp/model/NshmTests.java
+++ b/src/test/java/gov/usgs/earthquake/nshmp/model/NshmTests.java
@@ -1,6 +1,8 @@
 package gov.usgs.earthquake.nshmp.model;
 
 import java.io.IOException;
+import java.nio.file.Path;
+import java.nio.file.Paths;
 import java.util.ArrayList;
 import java.util.EnumSet;
 import java.util.HashMap;
@@ -22,6 +24,8 @@ import gov.usgs.earthquake.nshmp.site.NshmpSite;
  * Test NSHMs.
  */
 class NshmTests {
+  static Path DATA_PATH = Paths.get("src/test/resources/e2e/actual");
+
   /* Alaska test sites */
   private static final List<NamedLocation> ALASKA_LOCATIONS = List.of(
       NshmpSite.ANCHORAGE_AK,
@@ -51,7 +55,7 @@ class NshmTests {
   private static final Set<Imt> IMTS = EnumSet.of(Imt.PGA, Imt.SA0P2, Imt.SA1P0, Imt.SA5P0);
   private static final Set<Imt> AK_2007_IMTS = EnumSet.of(Imt.PGA, Imt.SA0P2, Imt.SA1P0);
 
-  private static final Map<String, Nshm> NSHMS;
+  static final Map<String, Nshm> NSHMS;
 
   static {
     Map<String, Nshm> nshms = new HashMap<>();
@@ -98,7 +102,7 @@ class NshmTests {
     NshmModel nshmModel =
         NshmTestUtils.loadModel(NSHMS.get("nshm-alaska-2023"));
 
-    NshmTestUtils.writeExpecteds(nshmModel);
+    NshmTestUtils.writeExpecteds(nshmModel, Optional.empty());
     nshmModel.exec.shutdown();
 
     // run all models
@@ -116,7 +120,7 @@ class NshmTests {
    */
   @Test
   final void testAlaska2007() throws IOException {
-    NshmTestUtils.testNshm(NSHMS.get("nshm-alaska-2007"), Optional.ofNullable(getSite()));
+    NshmTestUtils.testNshm(NSHMS.get("nshm-alaska-2007"), getDataPath());
   }
 
   /**
@@ -126,7 +130,7 @@ class NshmTests {
    */
   @Test
   final void testAlaska2023() throws IOException {
-    NshmTestUtils.testNshm(NSHMS.get("nshm-alaska-2023"), Optional.ofNullable(getSite()));
+    NshmTestUtils.testNshm(NSHMS.get("nshm-alaska-2023"), getDataPath());
   }
 
   /**
@@ -136,7 +140,7 @@ class NshmTests {
    */
   @Test
   final void testConus2018() throws IOException {
-    NshmTestUtils.testNshm(NSHMS.get("nshm-conus-2018"), Optional.ofNullable(getSite()));
+    NshmTestUtils.testNshm(NSHMS.get("nshm-conus-2018"), getDataPath());
   }
 
   /**
@@ -146,7 +150,7 @@ class NshmTests {
    */
   @Test
   final void testConus2023() throws IOException {
-    NshmTestUtils.testNshm(NSHMS.get("nshm-conus-2023"), Optional.ofNullable(getSite()));
+    NshmTestUtils.testNshm(NSHMS.get("nshm-conus-2023"), getDataPath());
   }
 
   /**
@@ -156,11 +160,10 @@ class NshmTests {
    */
   @Test
   final void testHawaii2021() throws IOException {
-    NshmTestUtils.testNshm(NSHMS.get("nshm-hawaii-2021"), Optional.ofNullable(getSite()));
+    NshmTestUtils.testNshm(NSHMS.get("nshm-hawaii-2021"), getDataPath());
   }
 
-  private NshmpSite getSite() {
-    var testSite = System.getProperty("TEST_SITE");
-    return testSite == null ? null : NshmpSite.valueOf(testSite);
+  private static Optional<Path> getDataPath() {
+    return System.getenv("GITLAB_CI") != null ? Optional.of(DATA_PATH) : Optional.empty();
   }
 }
-- 
GitLab