From 0b8d87100a97735d5797dc2a78870f6df8f1acee Mon Sep 17 00:00:00 2001 From: pbt-santos <60274019+pbt-santos@users.noreply.github.com> Date: Mon, 17 Jul 2023 13:42:16 -0400 Subject: [PATCH] Run tests for showcases (#721) * Run tests for showcases Adds workflow to test changes to showcases twice daily, on PRs or commit on master. Showcase tests consist of a roundtrip compilation test with latest legend versions to enforce compilation and formatting. Does not yet allow for comments. The paths in the poms and the test file are different due to the location that workflows vs tests checkout the code. Showcase code moved to not clog up directory structure. * Fix workflow formatting --- .github/workflows/showcase-test.yml | 39 ++++++++ .gitignore | 4 + scripts/buildShowcasesData.js | 2 +- showcases/README.md | 14 +++ .../Stores/Model Store/Mapping/code.pure | 0 .../Stores/Model Store/Mapping/info.md | 0 .../Relational Database/Mapping/code.pure | 0 .../Relational Database/Mapping/info.md | 0 showcases/pom.xml | 85 ++++++++++++++++++ .../org/example/ShowcaseCompilerTest.java | 89 +++++++++++++++++++ 10 files changed, 232 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/showcase-test.yml create mode 100644 showcases/README.md rename showcases/{ => data}/Stores/Model Store/Mapping/code.pure (100%) rename showcases/{ => data}/Stores/Model Store/Mapping/info.md (100%) rename showcases/{ => data}/Stores/Relational Database/Mapping/code.pure (100%) rename showcases/{ => data}/Stores/Relational Database/Mapping/info.md (100%) create mode 100644 showcases/pom.xml create mode 100644 showcases/src/test/java/org/example/ShowcaseCompilerTest.java diff --git a/.github/workflows/showcase-test.yml b/.github/workflows/showcase-test.yml new file mode 100644 index 000000000..eb631ff4a --- /dev/null +++ b/.github/workflows/showcase-test.yml @@ -0,0 +1,39 @@ +name: showcase-tests +run-name: Showcase Tests +on: + schedule: + - cron: '0 0,12 * * *' # run twice daily + push: + branches: + - master + paths: + - 'showcases/' + pull_request: + branches: + - '**' + paths: + - 'showcases/' + +jobs: + test: + name: Showcase Compile Test + runs-on: ubuntu-latest + + steps: + - name: Checkout repo + uses: actions/checkout@v3 + + - name: Setup Java JDK 11 + uses: actions/setup-java@v3 + with: + java-version: '11' + distribution: 'oracle' + cache: 'maven' + + - name: Run Showcase test with latest Legend versions + run: | + mvn versions:use-latest-versions -f legend/showcases/pom.xml + mvn -B -Dmaven.surefire.thread.count=$THREAD_COUNT -showcase.locations=$SHOWCASE_LOCATIONS test + env: + THREAD_COUNT: 3 + SHOWCASE_LOCATIONS: legend/showcases/data diff --git a/.gitignore b/.gitignore index f0c9ae8b5..5051fae26 100644 --- a/.gitignore +++ b/.gitignore @@ -7,6 +7,7 @@ Thumbs.db # IDE /.idea/ +*.iml # Dependencies **/node_modules @@ -34,3 +35,6 @@ docs/roadmap.md # Ignore checked out models docs/models + +# Ignore Java generated files +showcases/target/ diff --git a/scripts/buildShowcasesData.js b/scripts/buildShowcasesData.js index f8182b2c7..619382d52 100644 --- a/scripts/buildShowcasesData.js +++ b/scripts/buildShowcasesData.js @@ -14,7 +14,7 @@ const startTime = Date.now(); console.log(`Building showcase registry data...`); extractShowcaseRegistryData( - resolve(__dirname, "../showcases"), + resolve(__dirname, "../showcases/data"), resolve(outputDir, "data.json") ); diff --git a/showcases/README.md b/showcases/README.md new file mode 100644 index 000000000..e2a2d840a --- /dev/null +++ b/showcases/README.md @@ -0,0 +1,14 @@ +# Contribution Guide + +Disclaimer: This guide is a work in progress. + + +## Showcases + +Definition: the smallest snippet of code that highlights a feature. + + +## Navigation + +Add any new showcase under the data directory. The src directory will contain +code that helps test and maintain the showcase code. diff --git a/showcases/Stores/Model Store/Mapping/code.pure b/showcases/data/Stores/Model Store/Mapping/code.pure similarity index 100% rename from showcases/Stores/Model Store/Mapping/code.pure rename to showcases/data/Stores/Model Store/Mapping/code.pure diff --git a/showcases/Stores/Model Store/Mapping/info.md b/showcases/data/Stores/Model Store/Mapping/info.md similarity index 100% rename from showcases/Stores/Model Store/Mapping/info.md rename to showcases/data/Stores/Model Store/Mapping/info.md diff --git a/showcases/Stores/Relational Database/Mapping/code.pure b/showcases/data/Stores/Relational Database/Mapping/code.pure similarity index 100% rename from showcases/Stores/Relational Database/Mapping/code.pure rename to showcases/data/Stores/Relational Database/Mapping/code.pure diff --git a/showcases/Stores/Relational Database/Mapping/info.md b/showcases/data/Stores/Relational Database/Mapping/info.md similarity index 100% rename from showcases/Stores/Relational Database/Mapping/info.md rename to showcases/data/Stores/Relational Database/Mapping/info.md diff --git a/showcases/pom.xml b/showcases/pom.xml new file mode 100644 index 000000000..bdc5e3031 --- /dev/null +++ b/showcases/pom.xml @@ -0,0 +1,85 @@ + + + + 4.0.0 + + org.finos + legend-showcases + 1.0-SNAPSHOT + + Legend Showcases + + + UTF-8 + 1.8 + 1.8 + 3 + data + + + + + + org.finos.legend.engine + legend-engine-extensions-collection-execution + 4.18.2 + test + + + org.finos.legend.engine + legend-engine-extensions-collection-generation + 4.18.2 + test + + + + junit + junit + 4.13.2 + test + + + + + + + + + org.codehaus.mojo + versions-maven-plugin + 2.7 + + + maven-surefire-plugin + 2.22.1 + + + + + + org.codehaus.mojo + versions-maven-plugin + + + org.finos.legend.engine:legend-engine-extensions-collection-execution + org.finos.legend.engine:legend-engine-extensions-collection-generation + + true + + + + + org.apache.maven.plugins + maven-surefire-plugin + + all + ${maven.surefire.thread.count} + + + + + + + + diff --git a/showcases/src/test/java/org/example/ShowcaseCompilerTest.java b/showcases/src/test/java/org/example/ShowcaseCompilerTest.java new file mode 100644 index 000000000..d2317e9b0 --- /dev/null +++ b/showcases/src/test/java/org/example/ShowcaseCompilerTest.java @@ -0,0 +1,89 @@ +package org.example; + +import org.eclipse.collections.api.factory.Sets; +import org.finos.legend.engine.language.pure.grammar.from.PureGrammarParser; +import org.finos.legend.engine.language.pure.grammar.to.PureGrammarComposer; +import org.finos.legend.engine.language.pure.grammar.to.PureGrammarComposerContext; +import org.finos.legend.engine.protocol.pure.v1.model.context.PureModelContextData; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.junit.runners.Parameterized.Parameter; +import org.junit.runners.Parameterized.Parameters; + +import java.io.IOException; +import java.nio.file.FileSystems; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.PathMatcher; +import java.nio.file.Paths; +import java.util.Set; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import static org.junit.Assert.assertEquals; + +/** + * Unit tests for each showcase that will run in parallel reading from file + */ +@RunWith(Parameterized.class) +public class ShowcaseCompilerTest +{ + private static final PathMatcher PURE_FILE_MATCHER = FileSystems.getDefault().getPathMatcher("glob:*.pure"); + @Parameter + public Path showcasePath; + + @Parameters(name = "{0}") + public static Iterable showcaseFilePathsToTest() + { + final String[] SHOWCASE_LOCATIONS = System.getProperty("showcase.locations", "data").split(","); + + Set showcasePaths = Sets.mutable.empty(); + + for (String location : SHOWCASE_LOCATIONS) + { + Path path = Paths.get(location); + if (Files.isDirectory(path)) + { + showcasePaths.addAll(getShowcaseFilePaths(path)); + } + else if (PURE_FILE_MATCHER.matches(path.getFileName())) + { + showcasePaths.add(path); + } + } + + return showcasePaths; + } + + private static Set getShowcaseFilePaths(Path showcaseDirectory) + { + try (Stream pathStream = Files.walk(showcaseDirectory)) + { + return pathStream + .filter(p -> !Files.isDirectory(p)) + .filter(p -> PURE_FILE_MATCHER.matches(p.getFileName())) + .collect(Collectors.toSet()); + } + catch (IOException e) + { + throw new IllegalStateException(String.format("Invalid directory name %s.", showcaseDirectory), e); + } + } + + /** + * Tests that a file can be processed by the new Legend version + */ + @Test + public void processShowcaseFile() throws IOException + { + String pureGrammar = String.join("\n", Files.readAllLines(showcasePath)); + + // TODO: Ideally want compilation and all testables to be run while maintaining comments in the code + PureModelContextData pureModelContextData = PureGrammarParser.newInstance().parseModel(pureGrammar, "", 0, 0, true); + PureGrammarComposer grammarComposer = PureGrammarComposer.newInstance(PureGrammarComposerContext.Builder.newInstance().build()); + + // Grammar composer adds a trailing newline + assertEquals(pureGrammar + "\n", grammarComposer.renderPureModelContextData(pureModelContextData)); + } +}