diff --git a/.github/workflows/run-pdfa-tests-workflow.yml b/.github/workflows/run-pdfa-tests-workflow.yml index 5775f30..2614dc2 100644 --- a/.github/workflows/run-pdfa-tests-workflow.yml +++ b/.github/workflows/run-pdfa-tests-workflow.yml @@ -7,19 +7,20 @@ jobs: run_tests: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 with: submodules: true - - name: Set up JDK 1.11 - uses: actions/setup-java@v1 + - name: Set up JDK 11 + uses: actions/setup-java@v4 with: - java-version: 1.11 + java-version: 11 + distribution: 'temurin' - name: Set up run: mvn -B -DskipTests=true clean package --file pom.xml - name: Run pdf/a and pdf/ua regression tests run: java -Djdk.xml.xpathTotalOpLimit=0 -Djdk.xml.xpathExprOpLimit=0 -Djdk.xml.xpathExprGrpLimit=0 -cp "/home/runner/work/veraPDF-integration-tests/veraPDF-integration-tests/veraPDF-pdf-regression-tests/target"/'*' org.verapdf.pdf.regression.tests.PDFRegressionTestUtils - - name: Notify slack tests succeded + - name: Notify slack tests succeeded if: success() env: SLACK_BOT_TOKEN: ${{ secrets.SLACK_NOTIFICATIONS_BOT_TOKEN }} diff --git a/.github/workflows/run-tests-workflow.yml b/.github/workflows/run-tests-workflow.yml index 3442877..27c5562 100644 --- a/.github/workflows/run-tests-workflow.yml +++ b/.github/workflows/run-tests-workflow.yml @@ -7,19 +7,20 @@ jobs: run_tests: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 with: submodules: true - - name: Set up JDK 1.11 - uses: actions/setup-java@v1 + - name: Set up JDK 11 + uses: actions/setup-java@v4 with: - java-version: 1.11 + java-version: 11 + distribution: 'temurin' - name: Set up run: mvn -B -DskipTests=true clean package --file pom.xml - name: Run wcag regression tests run: java -Djdk.xml.xpathTotalOpLimit=0 -Djdk.xml.xpathExprOpLimit=0 -Djdk.xml.xpathExprGrpLimit=0 -cp "/home/runner/work/veraPDF-integration-tests/veraPDF-integration-tests/veraPDF-wcag-regression-tests/target"/'*' org.verapdf.wcag.regression.tests.WCAGRegressionTestUtils - - name: Notify slack tests succeded + - name: Notify slack tests succeeded if: success() env: SLACK_BOT_TOKEN: ${{ secrets.SLACK_NOTIFICATIONS_BOT_TOKEN }} diff --git a/.github/workflows/test-pr.yml b/.github/workflows/test-pr.yml index 3b30365..e8abce4 100644 --- a/.github/workflows/test-pr.yml +++ b/.github/workflows/test-pr.yml @@ -7,16 +7,19 @@ on: jobs: build: name: Checkout and Build - runs-on: ubuntu-20.04 + runs-on: ubuntu-latest + + continue-on-error: true strategy: + fail-fast: false matrix: - java-version: [8, 11, 16, 17] + java-version: [8, 11, 16, 17, 21] steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - name: JDK setup - uses: actions/setup-java@v2 + uses: actions/setup-java@v4 with: java-version: ${{ matrix.java-version }} distribution: 'temurin' diff --git a/.github/workflows/update-arlington-workflow.yml b/.github/workflows/update-arlington-workflow.yml new file mode 100644 index 0000000..d60400d --- /dev/null +++ b/.github/workflows/update-arlington-workflow.yml @@ -0,0 +1,93 @@ +name: Update arlington branch + +on: + push: + branches: + - integration + +jobs: + checkout-and-build: + runs-on: ubuntu-latest + + continue-on-error: true + + strategy: + fail-fast: false + matrix: + java-version: [11, 16, 17, 21] + + steps: + - name: Checkout code + uses: actions/checkout@v4 + with: + fetch-depth: 0 + ref: integration + - name: JDK setup + uses: actions/setup-java@v4 + with: + java-version: ${{ matrix.java-version }} + distribution: 'temurin' + cache: maven + - name: Fetch arlington branch and checkout + run: | + git fetch origin arlington:arlington + git checkout -b test-branch arlington + - name: Configure user nameF + run: | + git config user.name "Git User" + git config user.email "user@test.com" + - name: Add commit to the test branch + run: git cherry-pick -m 1 ${{ github.sha }} + - name: Build project with Maven + if: success() + run: mvn --batch-mode --update-snapshots verify + + merge: + runs-on: ubuntu-latest + needs: checkout-and-build + steps: + - name: Checkout code + uses: actions/checkout@v4 + with: + fetch-depth: 0 + ref: integration + - name: Generate new branch name + id: new-branch-name + run: echo "branch_name=new-branch-$(date +%s)" >> "$GITHUB_OUTPUT" + - name: Fetch arlington branch and checkout + run: | + git fetch origin arlington:arlington + git checkout -b ${{ steps.new-branch-name.outputs.branch_name }} arlington + - name: Configure user name + run: | + git config user.name "Git User" + git config user.email "user@temp.com" + - name: Add commit to new branch + run: git cherry-pick -m 1 ${{ github.sha }} + - name: Merge branch into arlington + if: success() + run: | + git push origin ${{ steps.new-branch-name.outputs.branch_name }} + git checkout arlington + git merge ${{ steps.new-branch-name.outputs.branch_name }} + git push origin arlington + - name: Delete new branch + run: git push origin --delete ${{ steps.new-branch-name.outputs.branch_name }} + + send-notification: + runs-on: ubuntu-latest + needs: [checkout-and-build, merge] + if: | + always() && + (contains(needs.*.result, 'failure') || + contains(needs.*.result, 'skipped') || + contains(needs.*.result, 'cancelled')) + steps: + - name: Send notification if build or merge failed + env: + SLACK_BOT_TOKEN: ${{ secrets.SLACK_NOTIFICATIONS_BOT_TOKEN }} + uses: voxmedia/github-action-slack-notify-build@v1 + with: + channel_id: C03E3JJGLQL + status: FAILED + color: danger diff --git a/.github/workflows/update-jakarta-workflow.yml b/.github/workflows/update-jakarta-workflow.yml new file mode 100644 index 0000000..8e05273 --- /dev/null +++ b/.github/workflows/update-jakarta-workflow.yml @@ -0,0 +1,93 @@ +name: Update jakarta branch + +on: + push: + branches: + - integration + +jobs: + checkout-and-build: + runs-on: ubuntu-latest + + continue-on-error: true + + strategy: + fail-fast: false + matrix: + java-version: [11, 16, 17, 21] + + steps: + - name: Checkout code + uses: actions/checkout@v4 + with: + fetch-depth: 0 + ref: integration + - name: JDK setup + uses: actions/setup-java@v4 + with: + java-version: ${{ matrix.java-version }} + distribution: 'temurin' + cache: maven + - name: Fetch jakarta branch and checkout + run: | + git fetch origin jakarta:jakarta + git checkout -b test-branch jakarta + - name: Configure user name + run: | + git config user.name "Git User" + git config user.email "user@test.com" + - name: Add commit to the test branch + run: git cherry-pick -m 1 ${{ github.sha }} + - name: Build project with Maven + if: success() + run: mvn --batch-mode --update-snapshots verify + + merge: + runs-on: ubuntu-latest + needs: checkout-and-build + steps: + - name: Checkout code + uses: actions/checkout@v4 + with: + fetch-depth: 0 + ref: integration + - name: Generate new branch name + id: new-branch-name + run: echo "branch_name=new-branch-$(date +%s)" >> "$GITHUB_OUTPUT" + - name: Fetch jakarta branch and checkout + run: | + git fetch origin jakarta:jakarta + git checkout -b ${{ steps.new-branch-name.outputs.branch_name }} jakarta + - name: Configure user name + run: | + git config user.name "Git User" + git config user.email "user@temp.com" + - name: Add commit to new branch + run: git cherry-pick -m 1 ${{ github.sha }} + - name: Merge branch into jakarta + if: success() + run: | + git push origin ${{ steps.new-branch-name.outputs.branch_name }} + git checkout jakarta + git merge ${{ steps.new-branch-name.outputs.branch_name }} + git push origin jakarta + - name: Delete new branch + run: git push origin --delete ${{ steps.new-branch-name.outputs.branch_name }} + + send-notification: + runs-on: ubuntu-latest + needs: [checkout-and-build, merge] + if: | + always() && + (contains(needs.*.result, 'failure') || + contains(needs.*.result, 'skipped') || + contains(needs.*.result, 'cancelled')) + steps: + - name: Send notification if build or merge failed + env: + SLACK_BOT_TOKEN: ${{ secrets.SLACK_NOTIFICATIONS_BOT_TOKEN }} + uses: voxmedia/github-action-slack-notify-build@v1 + with: + channel_id: C03E3JJGLQL + status: FAILED + color: danger diff --git a/.gitignore b/.gitignore index 19940c7..2b18cdc 100644 --- a/.gitignore +++ b/.gitignore @@ -24,3 +24,6 @@ hs_err_pid* **/pom.xml.versionsBackup /target/ /bin/ + +# VS Code +.vscode diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 3d59eff..0000000 --- a/.travis.yml +++ /dev/null @@ -1,18 +0,0 @@ -language: java -sudo: required -dist: trusty - -jdk: - - openjdk8 - - oraclejdk8 - - openjdk11 - -branches: - except: - - /^v|d\d+\.\d+\.\d+$/ - -install: - - mvn clean install -Dmaven.wagon.http.ssl.insecure=true -Dmaven.wagon.http.ssl.allowall=true -Dhttps.protocols=TLSv1,TLSv1.1,TLSv1.2 -Dmaven.wagon.http.pool=false - -script: - - cat target/test-results/index.html diff --git a/README.md b/README.md index a925c24..d5bb44b 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ veraPDF-integration-tests ========================= -[![Build Status](https://jenkins.openpreservation.org/job/veraPDF/job/1.24/job/integration-tests/badge/icon)](https://jenkins.openpreservation.org/job/veraPDF/job/1.24/job/integration-tests/ "OPF Jenkins") +[![Build Status](https://jenkins.openpreservation.org/job/veraPDF/job/1.26/job/integration-tests/badge/icon)](https://jenkins.openpreservation.org/job/veraPDF/job/1.26/job/integration-tests/ "OPF Jenkins") [![CodeCov Coverage](https://img.shields.io/codecov/c/github/veraPDF/veraPDF-integration-tests.svg)](https://codecov.io/gh/veraPDF/veraPDF-integration-tests/ "CodeCov coverage") [![Codacy Badge](https://app.codacy.com/project/badge/Grade/8d54ee7467f14bf5844b91081981f6ee)](https://app.codacy.com/gh/veraPDF/veraPDF-integration-tests/dashboard?utm_source=gh&utm_medium=referral&utm_content=&utm_campaign=Badge_grade "Codacy coverage") @@ -27,7 +27,7 @@ Quick Start In order to build the library you'll need: - * Java 8 - 17, which can be downloaded [from Oracle](https://www.oracle.com/technetwork/java/javase/downloads/index.html), or for Linux users [OpenJDK](https://openjdk.java.net/install/index.html). + * Java 8 - 21, which can be downloaded [from Oracle](https://www.oracle.com/technetwork/java/javase/downloads/index.html), or for Linux users [OpenJDK](https://openjdk.java.net/install/index.html). * [Maven v3+](https://maven.apache.org/) Life will be easier if you also use [Git](https://git-scm.com/) to obtain and manage the source. diff --git a/pom.xml b/pom.xml index 82807ce..37f80e9 100644 --- a/pom.xml +++ b/pom.xml @@ -27,11 +27,11 @@ verapdf-parent org.verapdf - 1.24.1 + 1.26.2 verapdf-integration-tests - 1.24.0 + 1.26.0 pom veraPDF Quality Assurance @@ -72,10 +72,10 @@ 0.8.1 - [1.24.0,1.25.0) - [1.24.0,1.25.0) - [1.24.0,1.25.0) - 1.67 + [1.26.0,1.27.0) + [1.26.0,1.27.0) + [1.26.0,1.27.0) + 1.70 @@ -141,6 +141,20 @@ 2.3.0.1 + + + org.hamcrest + hamcrest + 2.2 + test + + + + org.yaml + snakeyaml + 2.0 + + diff --git a/veraPDF-integration/pom.xml b/veraPDF-integration/pom.xml index ba35893..fdce2ff 100644 --- a/veraPDF-integration/pom.xml +++ b/veraPDF-integration/pom.xml @@ -28,7 +28,7 @@ verapdf-integration-tests org.verapdf - 1.24.0 + 1.26.0 veraPDF-integration diff --git a/veraPDF-integration/src/main/java/org/verapdf/pdfa/qa/AbstractTestCorpus.java b/veraPDF-integration/src/main/java/org/verapdf/pdfa/qa/AbstractTestCorpus.java index 6e18412..cc040bc 100644 --- a/veraPDF-integration/src/main/java/org/verapdf/pdfa/qa/AbstractTestCorpus.java +++ b/veraPDF-integration/src/main/java/org/verapdf/pdfa/qa/AbstractTestCorpus.java @@ -41,223 +41,227 @@ */ @XmlRootElement(namespace = "http://www.verapdf.org/corpus", name = "corpus") public abstract class AbstractTestCorpus implements TestCorpus { - private static final String veraUrl = "https://github.com/veraPDF/veraPDF-corpus/archive/staging.zip"; - private static final String isartorUrl = "https://corpora.openpreservation.org/veraPDF/isartor-pdfa-2008-08-13.zip"; - private static final String bfoUrl = "https://github.com/bfosupport/pdfa-testsuite/archive/master.zip"; - - @XmlElement(name = "details") - private final CorpusDetails details; - @XmlElementWrapper - @XmlElement(name = "item") - private final Map itemMap; - protected final Corpus type; - - protected AbstractTestCorpus(final CorpusDetails details, final Corpus type, final Map itemMap) { - this.details = details; - this.type = type; - this.itemMap = new HashMap<>(itemMap); - } - - @Override - public Corpus getType() { - return this.type; - } - - /** - * { @inheritDoc } - */ - @Override - public CorpusDetails getDetails() { - return this.details; - } - - /** - * { @inheritDoc } - */ - @Override - public int getItemCount() { - return this.itemMap.size(); - } - - /** - * { @inheritDoc } - */ - @Override - public Set getItemNames() { - return Collections.unmodifiableSet(this.itemMap.keySet()); - } - - /** - * { @inheritDoc } - */ - @Override - public Set getItemNamesForFlavour(PDFAFlavour flavour) { - // TODO Look at implementing filtering by flavour - return Collections.unmodifiableSet(this.itemMap.keySet()); - } - - /** - * { @inheritDoc } - */ - @Override - public InputStream getItemStream(String itemName) throws IOException { - if (!this.itemMap.containsKey(itemName)) - throw new IOException("No element found for name=" + itemName); - return getStreamFromReference(this.itemMap.get(itemName)); - } - - abstract protected InputStream getStreamFromReference(final L reference) throws IOException; - - /** - * { @inheritDoc } - */ - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((this.details == null) ? 0 : this.details.hashCode()); - result = prime * result + ((this.getItemNames() == null) ? 0 : this.getItemNames().hashCode()); - return result; - } - - /** - * { @inheritDoc } - */ - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (!(obj instanceof TestCorpus)) - return false; - TestCorpus other = (TestCorpus) obj; - if (this.details == null) { - if (other.getDetails() != null) - return false; - } else if (!this.details.equals(other.getDetails())) - return false; - if (this.getItemNames() == null) { - if (other.getItemNames() != null) - return false; - } else if (!this.getItemNames().equals(other.getItemNames())) - return false; - return true; - } - - public static enum Corpus { - VERA("veraPDF", - EnumSet.of(PDFAFlavour.PDFA_1_A, PDFAFlavour.PDFA_1_B, PDFAFlavour.PDFA_2_A, PDFAFlavour.PDFA_2_B, PDFAFlavour.PDFA_2_U, - PDFAFlavour.PDFA_3_B, PDFAFlavour.PDFA_4, PDFAFlavour.PDFA_4_F, PDFAFlavour.PDFA_4_E, - PDFAFlavour.PDFUA_1), - URI.create(veraUrl), "veraCorp-"), - ISARTOR("Isartor", EnumSet.of(PDFAFlavour.PDFA_1_B), URI.create(isartorUrl), "isartCorp-"), - BFO("BFO", EnumSet.of(PDFAFlavour.PDFA_2_B), URI.create(bfoUrl), "bfoCorp-"), - TWG("TWG", EnumSet.of(PDFAFlavour.NO_FLAVOUR), VERA.getZipFile().toURI(), "twgCorp-"); - private static final String desc = "Synthetic test files for PDF/A validation."; - - private final String id; - private final EnumSet flavours; - private final File zipFile; - - private Corpus(final String id, final EnumSet flavours, final URI downloadUri, - final String prefix) { - this.id = id; - this.flavours = EnumSet.copyOf(flavours); - try { - this.zipFile = createTempFileFromCorpus(downloadUri.toURL(), prefix); - } catch (IOException excep) { - throw new IllegalStateException(excep); - } - } - - private Corpus(final String id, final EnumSet flavours, final String name) { - this.id = id; - this.flavours = EnumSet.copyOf(flavours); - this.zipFile = new File(name); - } - - - public String getId() { - return this.id; - } - - @SuppressWarnings("static-method") - public String getDescription() { - return desc; - } - - public File getZipFile() { - return this.zipFile; - } - - public EnumSet getFlavours() { - return this.flavours; - } - } - - public static File createTempFileFromCorpus(final URL downloadLoc, final String prefix) throws IOException { - File tempFile = File.createTempFile(prefix, ".zip"); - System.out.println("Downloading: " + downloadLoc + ", to temp:" + tempFile); - int totalBytes = 0; - try (OutputStream output = new FileOutputStream(tempFile); - InputStream corpusInput = handleRedirects(downloadLoc);) { - byte[] buffer = new byte[8 * 1024]; - int bytesRead; - while ((bytesRead = corpusInput.read(buffer)) != -1) { - output.write(buffer, 0, bytesRead); - totalBytes += bytesRead; - } - } - System.out.println("Downloaded: " + totalBytes + " bytes"); - tempFile.deleteOnExit(); - return tempFile; - } - - static InputStream handleRedirects(URL url) throws IOException { - if (!url.getProtocol().startsWith("http")) { - return url.openStream(); - } - System.err.println("Prot:" + url.getProtocol()); - URL resourceUrl; - URL base; - URL next; - Map visited; - HttpURLConnection conn; - String location; - String urlString = url.toExternalForm(); - int times; - - visited = new HashMap<>(); - - while (true) { - times = visited.compute(urlString, (key, count) -> count == null ? 1 : count + 1); - - if (times > 3) - throw new IOException("Stuck in redirect loop"); - - resourceUrl = new URL(urlString); - conn = (HttpURLConnection) resourceUrl.openConnection(); - - conn.setConnectTimeout(15000); - conn.setReadTimeout(15000); - conn.setInstanceFollowRedirects(false); // Make the logic below easier to detect redirections - conn.setRequestProperty("User-Agent", "Mozilla/5.0..."); - - switch (conn.getResponseCode()) { - case HttpURLConnection.HTTP_MOVED_PERM: - case HttpURLConnection.HTTP_MOVED_TEMP: - location = conn.getHeaderField("Location"); - location = URLDecoder.decode(location, "UTF-8"); - base = new URL(urlString); - next = new URL(base, location); // Deal with relative URLs - urlString = next.toExternalForm(); - continue; - } - - break; - } - - return conn.getInputStream(); - } + private static final String VERA_URL = "https://github.com/veraPDF/veraPDF-corpus/archive/rel/1.26.zip"; + private static final String ISARTOR_URL = "https://corpora.openpreservation.org/veraPDF/isartor-pdfa-2008-08-13.zip"; + private static final String BFO_URL = "https://github.com/bfosupport/pdfa-testsuite/archive/master.zip"; + + @XmlElement(name = "details") + private final CorpusDetails details; + @XmlElementWrapper + @XmlElement(name = "item") + private final Map itemMap; + protected final Corpus type; + + protected AbstractTestCorpus(final CorpusDetails details, final Corpus type, final Map itemMap) { + this.details = details; + this.type = type; + this.itemMap = new HashMap<>(itemMap); + } + + @Override + public Corpus getType() { + return this.type; + } + + /** + * { @inheritDoc } + */ + @Override + public CorpusDetails getDetails() { + return this.details; + } + + /** + * { @inheritDoc } + */ + @Override + public int getItemCount() { + return this.itemMap.size(); + } + + /** + * { @inheritDoc } + */ + @Override + public Set getItemNames() { + return Collections.unmodifiableSet(this.itemMap.keySet()); + } + + /** + * { @inheritDoc } + */ + @Override + public Set getItemNamesForFlavour(PDFAFlavour flavour) { + // TODO Look at implementing filtering by flavour + return Collections.unmodifiableSet(this.itemMap.keySet()); + } + + /** + * { @inheritDoc } + */ + @Override + public InputStream getItemStream(String itemName) throws IOException { + if (!this.itemMap.containsKey(itemName)) + throw new IOException("No element found for name=" + itemName); + return getStreamFromReference(this.itemMap.get(itemName)); + } + + abstract protected InputStream getStreamFromReference(final L reference) throws IOException; + + /** + * { @inheritDoc } + */ + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((this.details == null) ? 0 : this.details.hashCode()); + result = prime * result + ((this.getItemNames() == null) ? 0 : this.getItemNames().hashCode()); + return result; + } + + /** + * { @inheritDoc } + */ + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (!(obj instanceof TestCorpus)) + return false; + TestCorpus other = (TestCorpus) obj; + if (this.details == null) { + if (other.getDetails() != null) + return false; + } else if (!this.details.equals(other.getDetails())) + return false; + if (this.getItemNames() == null) { + if (other.getItemNames() != null) + return false; + } else if (!this.getItemNames().equals(other.getItemNames())) + return false; + return true; + } + + public enum Corpus { + VERA("veraPDF", + EnumSet.of(PDFAFlavour.PDFA_1_A, PDFAFlavour.PDFA_1_B, PDFAFlavour.PDFA_2_A, PDFAFlavour.PDFA_2_B, + PDFAFlavour.PDFA_2_U, + PDFAFlavour.PDFA_3_B, PDFAFlavour.PDFA_4, PDFAFlavour.PDFA_4_F, PDFAFlavour.PDFA_4_E, + PDFAFlavour.PDFUA_1, PDFAFlavour.PDFUA_2), + URI.create(VERA_URL), "veraCorp-"), + ISARTOR("Isartor", EnumSet.of(PDFAFlavour.PDFA_1_B), URI.create(ISARTOR_URL), "isartCorp-"), + BFO("BFO", EnumSet.of(PDFAFlavour.PDFA_2_B), URI.create(BFO_URL), "bfoCorp-"), + TWG("TWG", EnumSet.of(PDFAFlavour.NO_FLAVOUR), VERA.getZipFile().toURI(), "twgCorp-"); + + private static final String desc = "Synthetic test files for PDF/A validation."; + private static final Map ID_LOOKUP = new HashMap<>(); + static { + for (Corpus corpus : Corpus.values()) { + ID_LOOKUP.put(corpus.id, corpus); + } + } + + private final String id; + private final EnumSet flavours; + private final File zipFile; + + private Corpus(final String id, final EnumSet flavours, final URI downloadUri, + final String prefix) { + this.id = id; + this.flavours = EnumSet.copyOf(flavours); + try { + this.zipFile = createTempFileFromCorpus(downloadUri.toURL(), prefix); + } catch (IOException excep) { + throw new IllegalStateException(excep); + } + } + + public String getId() { + return this.id; + } + + @SuppressWarnings("static-method") + public String getDescription() { + return desc; + } + + public File getZipFile() { + return this.zipFile; + } + + public Set getFlavours() { + return this.flavours; + } + + public static Corpus fromId(final String id) { + return ID_LOOKUP.get(id); + } + } + + public static File createTempFileFromCorpus(final URL downloadLoc, final String prefix) throws IOException { + File tempFile = File.createTempFile(prefix, ".zip"); + System.out.println("Downloading: " + downloadLoc + ", to temp:" + tempFile); + int totalBytes = 0; + try (OutputStream output = new FileOutputStream(tempFile); + InputStream corpusInput = handleRedirects(downloadLoc);) { + byte[] buffer = new byte[8 * 1024]; + int bytesRead; + while ((bytesRead = corpusInput.read(buffer)) != -1) { + output.write(buffer, 0, bytesRead); + totalBytes += bytesRead; + } + } + System.out.println("Downloaded: " + totalBytes + " bytes"); + tempFile.deleteOnExit(); + return tempFile; + } + + static InputStream handleRedirects(URL url) throws IOException { + if (!url.getProtocol().startsWith("http")) { + return url.openStream(); + } + URL resourceUrl; + URL base; + URL next; + Map visited; + HttpURLConnection conn; + String location; + String urlString = url.toExternalForm(); + int times; + + visited = new HashMap<>(); + + while (true) { + times = visited.compute(urlString, (key, count) -> count == null ? 1 : count + 1); + + if (times > 3) + throw new IOException("Stuck in redirect loop"); + + resourceUrl = new URL(urlString); + conn = (HttpURLConnection) resourceUrl.openConnection(); + + conn.setConnectTimeout(15000); + conn.setReadTimeout(15000); + conn.setInstanceFollowRedirects(false); // Make the logic below easier to detect redirections + conn.setRequestProperty("User-Agent", "Mozilla/5.0..."); + + switch (conn.getResponseCode()) { + case HttpURLConnection.HTTP_MOVED_PERM: + case HttpURLConnection.HTTP_MOVED_TEMP: + location = conn.getHeaderField("Location"); + location = URLDecoder.decode(location, "UTF-8"); + base = new URL(urlString); + next = new URL(base, location); // Deal with relative URLs + urlString = next.toExternalForm(); + continue; + } + + break; + } + + return conn.getInputStream(); + } } diff --git a/veraPDF-integration/src/main/java/org/verapdf/pdfa/qa/CorpusItemId.java b/veraPDF-integration/src/main/java/org/verapdf/pdfa/qa/CorpusItemId.java index c248a97..4dd5496 100644 --- a/veraPDF-integration/src/main/java/org/verapdf/pdfa/qa/CorpusItemId.java +++ b/veraPDF-integration/src/main/java/org/verapdf/pdfa/qa/CorpusItemId.java @@ -83,7 +83,7 @@ public String getId() { return this.id; } - public final static TestType fromId(final String id) { + public static final TestType fromId(final String id) { for (TestType type : TestType.values()) { if (id.equalsIgnoreCase(type.id)) { return type; diff --git a/veraPDF-integration/src/main/java/org/verapdf/pdfa/qa/CorpusManager.java b/veraPDF-integration/src/main/java/org/verapdf/pdfa/qa/CorpusManager.java index efdb655..b49a2df 100644 --- a/veraPDF-integration/src/main/java/org/verapdf/pdfa/qa/CorpusManager.java +++ b/veraPDF-integration/src/main/java/org/verapdf/pdfa/qa/CorpusManager.java @@ -23,54 +23,53 @@ */ package org.verapdf.pdfa.qa; -import org.verapdf.pdfa.flavours.PDFAFlavour; -import org.verapdf.pdfa.qa.AbstractTestCorpus.Corpus; - import java.io.IOException; import java.util.Collections; import java.util.EnumMap; import java.util.HashSet; import java.util.Set; +import org.verapdf.pdfa.flavours.PDFAFlavour; +import org.verapdf.pdfa.qa.AbstractTestCorpus.Corpus; + /** * @author Carl Wilson */ public final class CorpusManager { - // Reference to corpus zip temp file - private static final EnumMap> corporaByFlavour = new EnumMap<>(PDFAFlavour.class); + // Reference to corpus zip temp file + private static final EnumMap> corporaByFlavour = new EnumMap<>(PDFAFlavour.class); - private CorpusManager() { - assert (false); - } + private CorpusManager() { + assert (false); + } - public static void initialise() throws IOException { - if (!corporaByFlavour.isEmpty()) - return; - for (Corpus corpus : Corpus.values()) { - for (PDFAFlavour flavour : corpus.getFlavours()) { - TestCorpus toAdd = ZipBackedTestCorpus.fromZipSource(corpus.getId(), corpus, corpus.getDescription(), flavour); - if (!corporaByFlavour.containsKey(flavour)) { - corporaByFlavour.put(flavour, new HashSet()); - } - corporaByFlavour.get(flavour).add(toAdd); - } - } - } + public static void initialise() throws IOException { + if (!corporaByFlavour.isEmpty()) + return; + for (Corpus corpus : Corpus.values()) { + for (PDFAFlavour flavour : corpus.getFlavours()) { + TestCorpus toAdd = ZipBackedTestCorpus.fromZipSource(corpus.getId(), corpus, corpus.getDescription(), + flavour); + corporaByFlavour.computeIfAbsent(flavour, k -> new HashSet<>()); + corporaByFlavour.get(flavour).add(toAdd); + } + } + } - public static Set testableFlavours() { - return Collections.unmodifiableSet(corporaByFlavour.keySet()); - } + public static Set testableFlavours() { + return Collections.unmodifiableSet(corporaByFlavour.keySet()); + } - public static Set corporaForFlavour(final PDFAFlavour key) { - return Collections.unmodifiableSet(corporaByFlavour.get(key)); - } + public static Set corporaForFlavour(final PDFAFlavour key) { + return Collections.unmodifiableSet(corporaByFlavour.get(key)); + } - public static TestCorpus corpusByFlavourAndType(final PDFAFlavour key, final Corpus type) { - for (TestCorpus corpus : corporaByFlavour.get(key)) { - if (corpus.getType() == type) { - return corpus; - } - } - return null; - } + public static TestCorpus corpusByFlavourAndType(final PDFAFlavour key, final Corpus type) { + for (TestCorpus corpus : corporaByFlavour.get(key)) { + if (corpus.getType() == type) { + return corpus; + } + } + return null; + } } diff --git a/veraPDF-integration/src/main/java/org/verapdf/pdfa/qa/GitHubBackedProfileDirectory.java b/veraPDF-integration/src/main/java/org/verapdf/pdfa/qa/GitHubBackedProfileDirectory.java index 54af420..15b9694 100644 --- a/veraPDF-integration/src/main/java/org/verapdf/pdfa/qa/GitHubBackedProfileDirectory.java +++ b/veraPDF-integration/src/main/java/org/verapdf/pdfa/qa/GitHubBackedProfileDirectory.java @@ -115,10 +115,10 @@ private static Set fromGitHubBranch(final String branchName) String PDFUApathPrefix = GITHUB_ROOT + branchName + PDFUA_PROFILE_PATH_PART + PDFUA_PROFILE_PREFIX; Set profileSet = new HashSet<>(); for (PDFAFlavour flavour : PDFAFlavour.values()) { - if (flavour == PDFAFlavour.NO_FLAVOUR || flavour == PDFAFlavour.WCAG2_1) { + if (flavour == PDFAFlavour.NO_FLAVOUR || flavour.getPart().getFamily() == PDFAFlavour.SpecificationFamily.WCAG) { continue; } - String profileURLString = (flavour != PDFAFlavour.PDFUA_1 ? PDFApathPrefix : PDFUApathPrefix) + String profileURLString = (flavour.getPart().getFamily() != PDFAFlavour.SpecificationFamily.PDF_UA ? PDFApathPrefix : PDFUApathPrefix) + flavour.getPart().getPartNumber() + flavour.getLevel().getCode().toUpperCase() + XML_SUFFIX; try { URL profileURL = new URL(profileURLString); diff --git a/veraPDF-integration/src/main/java/org/verapdf/pdfa/qa/ProfilesMerger.java b/veraPDF-integration/src/main/java/org/verapdf/pdfa/qa/ProfilesMerger.java index 4e9bf8a..6546dcc 100644 --- a/veraPDF-integration/src/main/java/org/verapdf/pdfa/qa/ProfilesMerger.java +++ b/veraPDF-integration/src/main/java/org/verapdf/pdfa/qa/ProfilesMerger.java @@ -63,7 +63,7 @@ public static void mergeAtomicProfiles(OutputStream out, final String description, final String creator) throws IOException, JAXBException { SortedSet rules = new TreeSet<>(new RuleComparator()); - Set variables = new HashSet<>(); + SortedSet variables = new TreeSet<>(Comparator.comparing(Variable::getName)); PDFAFlavour flavour = null; for (File dir : root) { @@ -84,7 +84,8 @@ private static Set updateSpecification(final Collection rules, final Set res = new HashSet<>(rules.size()); for (Rule r : rules) { RuleId id = Profiles.ruleIdFromValues(flavour.getPart(), r.getRuleId().getClause(), r.getRuleId().getTestNumber()); - res.add(Profiles.ruleFromValues(id, r.getObject(), r.getDeferred(), r.getDescription(), r.getTest(), r.getError(), r.getReferences())); + res.add(Profiles.ruleFromValues(id, r.getObject(), r.getDeferred(), r.getTags(), r.getDescription(), r.getTest(), + r.getError(), r.getReferences())); } return res; } diff --git a/veraPDF-integration/src/main/java/org/verapdf/pdfa/qa/RegressionTestingHelper.java b/veraPDF-integration/src/main/java/org/verapdf/pdfa/qa/RegressionTestingHelper.java index be360c7..f79c06c 100644 --- a/veraPDF-integration/src/main/java/org/verapdf/pdfa/qa/RegressionTestingHelper.java +++ b/veraPDF-integration/src/main/java/org/verapdf/pdfa/qa/RegressionTestingHelper.java @@ -1,37 +1,58 @@ package org.verapdf.pdfa.qa; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.URL; +import java.util.ArrayList; +import java.util.Collections; +import java.util.EnumSet; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.zip.ZipEntry; +import java.util.zip.ZipFile; + +import javax.xml.bind.JAXBException; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.xpath.XPath; +import javax.xml.xpath.XPathConstants; +import javax.xml.xpath.XPathExpressionException; +import javax.xml.xpath.XPathFactory; + +import org.verapdf.ReleaseDetails; import org.verapdf.core.VeraPDFException; +import org.verapdf.gf.foundry.VeraGreenfieldFoundryProvider; import org.verapdf.metadata.fixer.FixerFactory; import org.verapdf.metadata.fixer.MetadataFixerConfig; -import org.verapdf.gf.foundry.VeraGreenfieldFoundryProvider; +import org.verapdf.pdfa.Foundries; import org.verapdf.pdfa.flavours.PDFAFlavour; +import org.verapdf.pdfa.validation.profiles.Profiles; import org.verapdf.pdfa.validation.profiles.ValidationProfile; +import org.verapdf.pdfa.validation.validators.ValidatorConfig; import org.verapdf.pdfa.validation.validators.ValidatorConfigBuilder; import org.verapdf.policy.PolicyChecker; -import org.verapdf.processor.*; +import org.verapdf.processor.BatchProcessor; +import org.verapdf.processor.FormatOption; +import org.verapdf.processor.ProcessorConfig; +import org.verapdf.processor.ProcessorFactory; +import org.verapdf.processor.TaskType; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.xml.sax.SAXException; -import javax.xml.bind.JAXBException; -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.parsers.ParserConfigurationException; -import javax.xml.xpath.XPath; -import javax.xml.xpath.XPathConstants; -import javax.xml.xpath.XPathExpressionException; -import javax.xml.xpath.XPathFactory; -import java.io.*; -import java.net.URL; -import java.util.*; -import java.util.logging.Level; -import java.util.zip.ZipEntry; -import java.util.zip.ZipFile; - public class RegressionTestingHelper { - private static final String testFilesZipUrl = "https://github.com/veraPDF/veraPDF-regression-tests/archive/refs/heads/rel/1.24.zip"; + private static final String testFilesZipUrl = "https://github.com/veraPDF/veraPDF-regression-tests/archive/refs/heads/rel/1.26.zip"; private final ZipFile zipSource; private final Map pdfMap; @@ -39,6 +60,7 @@ public class RegressionTestingHelper { public RegressionTestingHelper(boolean isWcag) throws IOException { VeraGreenfieldFoundryProvider.initialise(); + printDependencies(); File zipFile; try { zipFile = AbstractTestCorpus.createTempFileFromCorpus(new URL(testFilesZipUrl), "regression"); @@ -55,17 +77,15 @@ public Set getPdfFileNames() { return pdfMap.keySet(); } - public void getFailedPolicyComplianceFiles(Map> failedFiles, PDFAFlavour flavour, ValidationProfile customProfile, Set fileNames) throws JAXBException, IOException { - MetadataFixerConfig fixConf = FixerFactory.configFromValues("test", true); - ProcessorConfig processorConfig = customProfile == null ? - ProcessorFactory.fromValues(new ValidatorConfigBuilder().flavour(flavour) - .defaultFlavour(PDFAFlavour.NO_FLAVOUR).recordPasses(true).maxFails(0) - .isLogsEnabled(true).showErrorMessages(false).build(), - null, null, fixConf, EnumSet.of(TaskType.VALIDATE), (String) null) : - ProcessorFactory.fromValues(new ValidatorConfigBuilder() - .defaultFlavour(PDFAFlavour.NO_FLAVOUR).recordPasses(true).maxFails(0) - .isLogsEnabled(true).showErrorMessages(false).build(), - null, null, fixConf, EnumSet.of(TaskType.VALIDATE), customProfile, null); + public void getFailedPolicyComplianceFiles(Map> failedFiles, PDFAFlavour flavour, + ValidationProfile customProfile, Set fileNames) throws JAXBException, IOException { + MetadataFixerConfig fixConf = FixerFactory.configFromValues("test"); + ValidatorConfig validatorConfig = new ValidatorConfigBuilder().flavour(flavour) + .defaultFlavour(PDFAFlavour.NO_FLAVOUR).recordPasses(true).maxFails(0) + .isLogsEnabled(true).showErrorMessages(false).build(); + ProcessorConfig processorConfig = ProcessorFactory.fromValues(validatorConfig, null, + null, fixConf, EnumSet.of(TaskType.VALIDATE), + customProfile == null ? Profiles.defaultProfile() : customProfile, null); BatchProcessor processor = ProcessorFactory.fileBatchProcessor(processorConfig); File tempSchFile = File.createTempFile("veraPDF", ".sch"); @@ -91,7 +111,7 @@ public void getFailedPolicyComplianceFiles(Map> applyPolicy(tempSchFile, tempMrrFile, tempResultFile); int failedPolicyJobsCount = countFailedPolicyJobs(tempResultFile); if (failedPolicyJobsCount > 0) { - failedFiles.put(pdfName, getFailedChecks(tempResultFile)); + failedFiles.put(pdfName, getFailedChecks(tempResultFile, tempMrrFile)); } } catch (Exception e) { failedFiles.put(pdfName, Collections.singletonList(new FailedPolicyCheck(e.getMessage()))); @@ -126,7 +146,7 @@ private void itemsMapFromZipSource(File zipFile, boolean isWcag) throws IOExcept while (entries.hasMoreElements()) { ZipEntry entry = entries.nextElement(); String entryName = entry.getName(); - if ((isWcag == entryName.contains("WCAG-21")) && !entry.isDirectory()) { + if ((isWcag == entryName.contains("WCAG_2_2")) && !entry.isDirectory()) { if (entryName.endsWith(".pdf")) { this.pdfMap.put(entryName, entry); } else if (entryName.endsWith(".sch")) { @@ -159,42 +179,37 @@ public static void copyInputStreamToFile(InputStream inputStream, File file) thr } } - public static int countFailedPolicyJobs(File xmlReport) throws IOException, SAXException, ParserConfigurationException, XPathExpressionException { + public static int countFailedPolicyJobs(File xmlReport) + throws IOException, SAXException, ParserConfigurationException, XPathExpressionException { DocumentBuilder documentBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder(); Document document = documentBuilder.parse(xmlReport); - XPath path = XPathFactory.newInstance().newXPath(); - return ((Number) path.evaluate("count(//policyReport[@failedChecks > 0])", document, XPathConstants.NUMBER)).intValue(); + return document.getElementsByTagName("svrl:failed-assert").getLength(); } - public static List getFailedChecks(File xmlReport) throws IOException, SAXException, ParserConfigurationException, XPathExpressionException { + public static List getFailedChecks(File xmlReport, File tempMrrFile) + throws IOException, SAXException, ParserConfigurationException, XPathExpressionException { DocumentBuilder documentBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder(); Document document = documentBuilder.parse(xmlReport); + Document mrrDocument = documentBuilder.parse(tempMrrFile); XPath path = XPathFactory.newInstance().newXPath(); List failedChecks = new LinkedList<>(); - NodeList list = ((NodeList)path.evaluate("//policyReport/failedChecks/check", document, XPathConstants.NODESET)); + NodeList list = document.getElementsByTagName("svrl:failed-assert"); for (int i = 0; i < list.getLength(); i++) { - Element check = (Element)list.item(i); + Element check = (Element) list.item(i); String test = check.getAttribute("test"); - String messageValue = getProperty(check, "message").getTextContent(); - Element node = (Element)path.evaluate(check.getAttribute("location"), document, XPathConstants.NODE); + String messageValue = getProperty(check, "svrl:text").getTextContent(); + Element node = (Element) path.evaluate(check.getAttribute("location"), mrrDocument, XPathConstants.NODE); failedChecks.add(new FailedPolicyCheck(node, messageValue, test)); } return failedChecks; } - public static void applyPolicy(File policyFile, File tempMrrFile, File tempResultFile) throws IOException, VeraPDFException { - File tempPolicyResult = File.createTempFile("policyResult", "veraPDF"); + public static void applyPolicy(File policyFile, File tempMrrFile, File tempResultFile) + throws IOException, VeraPDFException { try (InputStream mrrIs = new FileInputStream(tempMrrFile); - OutputStream policyResultOs = new FileOutputStream(tempPolicyResult)) { + OutputStream policyResultOs = new FileOutputStream(tempResultFile)) { PolicyChecker.applyPolicy(policyFile, mrrIs, policyResultOs); } - try (OutputStream mrrReport = new FileOutputStream(tempResultFile)) { - PolicyChecker.insertPolicyReport(tempPolicyResult, tempMrrFile, mrrReport); - } - - if (!tempPolicyResult.delete()) { - tempPolicyResult.deleteOnExit(); - } } private static Node getProperty(Node parent, String propertyName) { @@ -204,10 +219,20 @@ private static Node getProperty(Node parent, String propertyName) { NodeList childNodes = parent.getChildNodes(); for (int i = 0; i < childNodes.getLength(); i++) { Node item = childNodes.item(i); - if (propertyName.equals(item.getNodeName())){ + if (propertyName.equals(item.getNodeName())) { return item; } } return null; } + + public static void printDependencies() { + System.out.println("Dependencies"); + Foundries.defaultInstance().getDetails(); + for (ReleaseDetails details : ReleaseDetails.getDetails()) { + System.out.println(details.getId() + " " + details.getVersion() + " " + details.getBuildDate()); + } + System.out.println(); + } + } diff --git a/veraPDF-integration/src/main/java/org/verapdf/pdfa/qa/ResultSet.java b/veraPDF-integration/src/main/java/org/verapdf/pdfa/qa/ResultSet.java index e7e3141..090a696 100644 --- a/veraPDF-integration/src/main/java/org/verapdf/pdfa/qa/ResultSet.java +++ b/veraPDF-integration/src/main/java/org/verapdf/pdfa/qa/ResultSet.java @@ -23,234 +23,240 @@ */ package org.verapdf.pdfa.qa; +import java.util.Comparator; +import java.util.Set; + +import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; + import org.verapdf.component.AuditDuration; import org.verapdf.pdfa.qa.CorpusItemId.TestType; import org.verapdf.pdfa.qa.CorpusItemIdImpl.CorpusItemIdComparator; import org.verapdf.pdfa.results.ValidationResult; import org.verapdf.pdfa.validation.profiles.ValidationProfile; -import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; -import java.util.Comparator; -import java.util.Set; - /** * @author Carl Wilson */ @XmlJavaTypeAdapter(ResultSetImpl.Adapter.class) public interface ResultSet { - /** - * @return the {@link ResultSetDetails} for the instance - */ - public ResultSetDetails getDetails(); - - /** - * @return the {@link CorpusDetails} for the instance - */ - public CorpusDetails getCorpusDetails(); - - /** - * @return the {@link ValidationProfile} used to generate the result set - */ - public ValidationProfile getValidationProfile(); - - /** - * @return the {@link ResultSetSummary} for the result set - */ - public ResultSetSummary getSummary(); - - /** - * @return the {@code Set} of {@link Result}s - */ - public Set getResults(); - - /** - * @return - */ - public Set getExceptions(); - - /** - * @author Carl Wilson - */ - public static final class Result { - private final CorpusItemId corpusItemId; - private final ValidationResult result; - private final AuditDuration duration; - private final long memoryUsed; - - Result(final CorpusItemId corpusItemId, final ValidationResult result, final AuditDuration duration, - long memoryUsed) { - this.corpusItemId = corpusItemId; - this.result = result; - this.duration = duration; - this.memoryUsed = memoryUsed; - } - - /** - * @return the corpusItem - */ - public CorpusItemId getCorpusItemId() { - return this.corpusItemId; - } - - /** - * @return the result - */ - public ValidationResult getResult() { - return this.result; - } - - public boolean isExpectedResult() { - return this.corpusItemId.getExpectedResult() == this.result.isCompliant(); - } - - public String getTestType() { - if ((this.corpusItemId.getTestType() == TestType.PASS) - || (this.corpusItemId.getTestType() == TestType.FAIL)) { - return this.isExpectedResult() ? "pass" : "fail"; - } - return this.corpusItemId.getTestType().getId(); - } - - public String getCorpusItemName() { - return this.corpusItemId.getName(); - } - - public String getDuration() { - return this.duration.getDuration(); - } - - public long getMemoryUsed() { - return this.memoryUsed; - } - - /** - * { @inheritDoc } - */ - @Override - public int hashCode() { - final int prime = 31; - int hashResult = 1; - hashResult = prime * hashResult + ((this.corpusItemId == null) ? 0 : this.corpusItemId.hashCode()); - hashResult = prime * hashResult + ((this.result == null) ? 0 : this.result.hashCode()); - return hashResult; - } - - /** - * { @inheritDoc } - */ - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - Result other = (Result) obj; - if (this.corpusItemId == null) { - if (other.corpusItemId != null) - return false; - } else if (!this.corpusItemId.equals(other.corpusItemId)) - return false; - if (this.result == null) { - if (other.result != null) - return false; - } else if (!this.result.equals(other.result)) - return false; - return true; - } - - /** - * { @inheritDoc } - */ - @Override - public String toString() { - return "Result [corpusItemid=" + this.corpusItemId + ", result=" + this.result + "]"; - } - - } - - /** - * @author Carl Wilson - */ - public static class Incomplete { - private final CorpusItemId corpusItemId; - private final Throwable cause; - - /** - * @param corpusItem - * @param cause - */ - public Incomplete(final CorpusItemId corpusItemId, final Throwable cause) { - this.corpusItemId = corpusItemId; - this.cause = cause; - } - - /** - * @return the corpusItem - */ - public CorpusItemId getCorpusItemId() { - return this.corpusItemId; - } - - /** - * @return the cause - */ - public Throwable getCause() { - return this.cause; - } - - /** - * { @inheritDoc } - */ - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((this.cause == null) ? 0 : this.cause.hashCode()); - result = prime * result + ((this.corpusItemId == null) ? 0 : this.corpusItemId.hashCode()); - return result; - } - - /** - * { @inheritDoc } - */ - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - Incomplete other = (Incomplete) obj; - if (this.cause == null) { - if (other.cause != null) - return false; - } else if (!this.cause.equals(other.cause)) - return false; - if (this.corpusItemId == null) { - if (other.corpusItemId != null) - return false; - } else if (!this.corpusItemId.equals(other.corpusItemId)) - return false; - return true; - } - - /** - * { @inheritDoc } - */ - @Override - public String toString() { - return "Incomplete [corpusItemId=" + this.corpusItemId + ", cause=" + this.cause + "]"; - } - } - - public static class ResultComparator implements Comparator { - @Override - public int compare(Result firstResult, Result secondResult) { - return new CorpusItemIdComparator().compare(firstResult.getCorpusItemId(), secondResult.getCorpusItemId()); - } - } + /** + * @return the {@link ResultSetDetails} for the instance + */ + public ResultSetDetails getDetails(); + + /** + * @return the {@link CorpusDetails} for the instance + */ + public CorpusDetails getCorpusDetails(); + + /** + * @return the Corpus ID for the result set + */ + public String getCorpusId(); + + /** + * @return the {@link ValidationProfile} used to generate the result set + */ + public ValidationProfile getValidationProfile(); + + /** + * @return the {@link ResultSetSummary} for the result set + */ + public ResultSetSummary getSummary(); + + /** + * @return the {@code Set} of {@link Result}s + */ + public Set getResults(); + + /** + * @return + */ + public Set getExceptions(); + + /** + * @author Carl Wilson + */ + public static final class Result { + private final CorpusItemId corpusItemId; + private final ValidationResult result; + private final AuditDuration duration; + private final long memoryUsed; + + Result(final CorpusItemId corpusItemId, final ValidationResult result, final AuditDuration duration, + long memoryUsed) { + this.corpusItemId = corpusItemId; + this.result = result; + this.duration = duration; + this.memoryUsed = memoryUsed; + } + + /** + * @return the corpusItem + */ + public CorpusItemId getCorpusItemId() { + return this.corpusItemId; + } + + /** + * @return the result + */ + public ValidationResult getResult() { + return this.result; + } + + public boolean isExpectedResult() { + return this.corpusItemId.getExpectedResult() == this.result.isCompliant(); + } + + public String getTestType() { + if ((this.corpusItemId.getTestType() == TestType.PASS) + || (this.corpusItemId.getTestType() == TestType.FAIL)) { + return this.isExpectedResult() ? "pass" : "fail"; + } + return this.corpusItemId.getTestType().getId(); + } + + public String getCorpusItemName() { + return this.corpusItemId.getName(); + } + + public String getDuration() { + return this.duration.getDuration(); + } + + public long getMemoryUsed() { + return this.memoryUsed; + } + + /** + * { @inheritDoc } + */ + @Override + public int hashCode() { + final int prime = 31; + int hashResult = 1; + hashResult = prime * hashResult + ((this.corpusItemId == null) ? 0 : this.corpusItemId.hashCode()); + hashResult = prime * hashResult + ((this.result == null) ? 0 : this.result.hashCode()); + return hashResult; + } + + /** + * { @inheritDoc } + */ + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + Result other = (Result) obj; + if (this.corpusItemId == null) { + if (other.corpusItemId != null) + return false; + } else if (!this.corpusItemId.equals(other.corpusItemId)) + return false; + if (this.result == null) { + if (other.result != null) + return false; + } else if (!this.result.equals(other.result)) + return false; + return true; + } + + /** + * { @inheritDoc } + */ + @Override + public String toString() { + return "Result [corpusItemid=" + this.corpusItemId + ", result=" + this.result + "]"; + } + + } + + /** + * @author Carl Wilson + */ + public static class Incomplete { + private final CorpusItemId corpusItemId; + private final Throwable cause; + + /** + * @param corpusItem + * @param cause + */ + public Incomplete(final CorpusItemId corpusItemId, final Throwable cause) { + this.corpusItemId = corpusItemId; + this.cause = cause; + } + + /** + * @return the corpusItem + */ + public CorpusItemId getCorpusItemId() { + return this.corpusItemId; + } + + /** + * @return the cause + */ + public Throwable getCause() { + return this.cause; + } + + /** + * { @inheritDoc } + */ + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((this.cause == null) ? 0 : this.cause.hashCode()); + result = prime * result + ((this.corpusItemId == null) ? 0 : this.corpusItemId.hashCode()); + return result; + } + + /** + * { @inheritDoc } + */ + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + Incomplete other = (Incomplete) obj; + if (this.cause == null) { + if (other.cause != null) + return false; + } else if (!this.cause.equals(other.cause)) + return false; + if (this.corpusItemId == null) { + if (other.corpusItemId != null) + return false; + } else if (!this.corpusItemId.equals(other.corpusItemId)) + return false; + return true; + } + + /** + * { @inheritDoc } + */ + @Override + public String toString() { + return "Incomplete [corpusItemId=" + this.corpusItemId + ", cause=" + this.cause + "]"; + } + } + + public static class ResultComparator implements Comparator { + @Override + public int compare(Result firstResult, Result secondResult) { + return new CorpusItemIdComparator().compare(firstResult.getCorpusItemId(), secondResult.getCorpusItemId()); + } + } } diff --git a/veraPDF-integration/src/main/java/org/verapdf/pdfa/qa/ResultSetImpl.java b/veraPDF-integration/src/main/java/org/verapdf/pdfa/qa/ResultSetImpl.java index 509de6c..04100c9 100644 --- a/veraPDF-integration/src/main/java/org/verapdf/pdfa/qa/ResultSetImpl.java +++ b/veraPDF-integration/src/main/java/org/verapdf/pdfa/qa/ResultSetImpl.java @@ -49,6 +49,8 @@ public class ResultSetImpl implements ResultSet { .getNewInstance(Foundries.defaultInstance().getDetails()); @XmlElement(name = "corpusDetails") private final CorpusDetails corpusDetails; + @XmlElement(name = "corpusId") + private final String corpusId; @XmlElement(name = "profile") private final ValidationProfile profile; @XmlElement(name = "summary") @@ -60,9 +62,10 @@ public class ResultSetImpl implements ResultSet { @XmlElement(name = "exception") private final Set exceptions; - private ResultSetImpl(final CorpusDetails corpusDetails, final ValidationProfile profile, final Set results, + private ResultSetImpl(final CorpusDetails corpusDetails, final String corpusId, final ValidationProfile profile, final Set results, final Set exceptions, final AuditDuration duration, final long memoryUsed) { this.corpusDetails = corpusDetails; + this.corpusId = corpusId; this.profile = profile; this.results = new TreeSet<>(new ResultComparator()); this.results.addAll(results); @@ -86,6 +89,14 @@ public CorpusDetails getCorpusDetails() { return this.corpusDetails; } + /** + * { @inheritDoc } + */ + @Override + public String getCorpusId() { + return this.corpusId; + } + /** * { @inheritDoc } */ @@ -216,7 +227,7 @@ public static ResultSet validateCorpus(final TestCorpus corpus, final PDFAValida } } } - return new ResultSetImpl(corpus.getDetails(), validator.getProfile(), results, exceptions, batchTimer.stop(), + return new ResultSetImpl(corpus.getDetails(), corpus.getType().getId(), validator.getProfile(), results, exceptions, batchTimer.stop(), maxMemUse); } @@ -245,7 +256,7 @@ public static ResultSet validateCorpus(final TestCorpus corpus) { exceptions.add(new Incomplete(id, e)); } } - return new ResultSetImpl(corpus.getDetails(), Profiles.defaultProfile(), results, exceptions, batchTimer.stop(), + return new ResultSetImpl(corpus.getDetails(), corpus.getType().getId(), Profiles.defaultProfile(), results, exceptions, batchTimer.stop(), maxMemUse); } diff --git a/veraPDF-integration/src/main/java/org/verapdf/pdfa/qa/ZipBackedTestCorpus.java b/veraPDF-integration/src/main/java/org/verapdf/pdfa/qa/ZipBackedTestCorpus.java index 581bdf0..2464162 100644 --- a/veraPDF-integration/src/main/java/org/verapdf/pdfa/qa/ZipBackedTestCorpus.java +++ b/veraPDF-integration/src/main/java/org/verapdf/pdfa/qa/ZipBackedTestCorpus.java @@ -118,6 +118,9 @@ public static boolean checkFlavour(final String item, final PDFAFlavour flavour) if (flavour == PDFAFlavour.PDFUA_1) { return item.contains("PDF_UA-1"); } + if (flavour == PDFAFlavour.PDFUA_2) { + return item.contains("PDF_UA-2"); + } if (flavour == PDFAFlavour.PDFA_4) { return item.contains("PDF_A-4") && !matchFlavour(item, PDFAFlavour.PDFA_4_E) && !matchFlavour(item, PDFAFlavour.PDFA_4_F); } diff --git a/veraPDF-integration/src/test/java/org/verapdf/integration/tests/CorpusTest.java b/veraPDF-integration/src/test/java/org/verapdf/integration/tests/CorpusTest.java index 205c6a2..bd86f81 100644 --- a/veraPDF-integration/src/test/java/org/verapdf/integration/tests/CorpusTest.java +++ b/veraPDF-integration/src/test/java/org/verapdf/integration/tests/CorpusTest.java @@ -14,155 +14,237 @@ */ package org.verapdf.integration.tests; -import com.github.mustachejava.DefaultMustacheFactory; -import com.github.mustachejava.Mustache; -import com.github.mustachejava.MustacheFactory; +import static org.hamcrest.Matchers.equalTo; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.io.PrintWriter; +import java.io.Writer; +import java.util.ArrayList; +import java.util.Collections; +import java.util.EnumMap; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + import org.junit.AfterClass; import org.junit.BeforeClass; +import org.junit.Rule; import org.junit.Test; +import org.junit.rules.ErrorCollector; import org.verapdf.component.ComponentDetails; +import org.verapdf.gf.foundry.VeraGreenfieldFoundryProvider; import org.verapdf.pdfa.Foundries; import org.verapdf.pdfa.PDFAValidator; -import org.verapdf.pdfbox.foundry.PdfBoxFoundryProvider; -import org.verapdf.gf.foundry.VeraGreenfieldFoundryProvider; import org.verapdf.pdfa.flavours.PDFAFlavour; import org.verapdf.pdfa.qa.*; +import org.verapdf.pdfa.qa.AbstractTestCorpus.Corpus; +import org.verapdf.pdfbox.foundry.PdfBoxFoundryProvider; +import org.yaml.snakeyaml.Yaml; -import java.io.*; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import static org.junit.Assert.assertFalse; +import com.github.mustachejava.DefaultMustacheFactory; +import com.github.mustachejava.Mustache; +import com.github.mustachejava.MustacheFactory; @SuppressWarnings({ "javadoc" }) public class CorpusTest { - private static ComponentDetails gfDetails; - private static ComponentDetails pdfBoxDetails; - private static final List gfResults = new ArrayList<>(); - private static final List pdfBoxResults = new ArrayList<>(); - private static final MustacheFactory MF = new DefaultMustacheFactory("org/verapdf/integration/templates"); - private static final Mustache RESULTS_MUSTACHE = MF.compile("corpus-results.mustache"); - private static final Mustache SUMMARY_MUSTACHE = MF.compile("test-summary.mustache"); - - @BeforeClass - public static final void SetUp() throws IOException { - try { - CorpusManager.initialise(); - } catch (Exception e) { - // TODO Auto-generated catch block - e.printStackTrace(); - throw e; - } - } - - @AfterClass - public static void outputResults() throws IOException { - writeResults(); - } - - @Test - public void testPdfBox() { - PdfBoxFoundryProvider.initialise(); - pdfBoxDetails = Foundries.defaultInstance().getDetails(); - testCorpora(pdfBoxResults); - assertFalse(countExceptions(pdfBoxResults) > 0); - } - - @Test - public void testGreenfield() { - VeraGreenfieldFoundryProvider.initialise(); - gfDetails = Foundries.defaultInstance().getDetails(); - testCorpora(gfResults); - assertFalse(countExceptions(gfResults) > 0); - } - - private static int countExceptions(final List resultSets) { - int exceptionCount = 0; - for (ResultSet set : resultSets) { - exceptionCount += set.getExceptions().size(); - } - return exceptionCount; - } - - private static void testCorpora(final List resultSets) { - for (PDFAFlavour flavour : CorpusManager.testableFlavours()) { - for (TestCorpus corpus : CorpusManager.corporaForFlavour(flavour)) { - if (flavour != PDFAFlavour.NO_FLAVOUR) { - try (PDFAValidator validator = Foundries.defaultInstance().createValidator(flavour, false)) { - ResultSet results = ResultSetImpl.validateCorpus(corpus, validator); - resultSets.add(results); - } catch (IOException excep) { - // Just exception closing validator - excep.printStackTrace(); - } - } else { - ResultSet results = ResultSetImpl.validateCorpus(corpus); - resultSets.add(results); - } - } - } - } - - /** - * Tests the passed String {@code parseForMatches} and returns true if - * {@link PDFAFlavour#fromString(String)} returns one of the flavours in - * {@code filters}. - * - * @param parseForMatches - * string to test for flavour matches - * @param filters - * {@code List} of {@link PDFAFlavour}s to test against for - * matches - * @return true of {@code PDFAFlavour} parsed from {@code parseForMatches} - * is contained in {@code filters}. - */ - @SuppressWarnings("unused") - private static boolean matchesFlavourFilter(final String parseForMatches, final List filters) { - PDFAFlavour flavour = PDFAFlavour.fromString(parseForMatches); - return filters.contains(flavour); - } - - private static void writeResults() throws IOException { - File rootDir = new File("target/test-results"); - if (!rootDir.exists()) - rootDir.mkdirs(); - writeSummaries(rootDir); - int index = 0; - for (ResultSet pdfBoxResult : pdfBoxResults) { - ResultSet gfResult = gfResults.get(index++); - Map scopes = new HashMap<>(); - scopes.put("pdfBoxResult", pdfBoxResult); - scopes.put("gfResult", gfResult); - if (rootDir.isDirectory() && rootDir.canWrite()) { - String dirName = pdfBoxResult.getCorpusDetails().getName() + "-" - + pdfBoxResult.getValidationProfile().getPDFAFlavour().getId(); - outputResultsToFile(scopes, new File(rootDir, dirName)); - } else { - RESULTS_MUSTACHE.execute(new PrintWriter(System.out), scopes).flush(); - } - } - } - - private static void writeSummaries(final File outputDir) throws FileNotFoundException, IOException { - Map scopes = new HashMap<>(); - scopes.put("pdfBoxDetails", ResultSetDetailsImpl.getNewInstance(pdfBoxDetails)); - scopes.put("gfDetails", ResultSetDetailsImpl.getNewInstance(gfDetails)); - scopes.put("pdfBoxResults", pdfBoxResults); - scopes.put("gfResults", gfResults); - try (Writer writer = new PrintWriter(new File(outputDir, "index.html"))) { - SUMMARY_MUSTACHE.execute(writer, scopes); - } - } - - private static void outputResultsToFile(Map scopes, final File outputDir) - throws FileNotFoundException, IOException { - if (!outputDir.exists()) { - outputDir.mkdirs(); - } - try (Writer writer = new PrintWriter(new File(outputDir, "index.html"))) { - RESULTS_MUSTACHE.execute(writer, scopes).flush(); - } - } + private static ComponentDetails gfDetails; + private static ComponentDetails pdfBoxDetails; + private static final List gfResults = new ArrayList<>(); + private static final List pdfBoxResults = new ArrayList<>(); + private static final MustacheFactory MF = new DefaultMustacheFactory("org/verapdf/integration/templates"); + private static final Mustache RESULTS_MUSTACHE = MF.compile("corpus-results.mustache"); + private static final Mustache SUMMARY_MUSTACHE = MF.compile("test-summary.mustache"); + + @Rule + public ErrorCollector collector = new ErrorCollector(); + + @BeforeClass + public static final void SetUp() throws IOException { + CorpusManager.initialise(); + } + + private static Set expectedForCorpus(final Corpus corpus, final PDFAFlavour flavour, + final EnumMap>> expectedFailureSets) { + EnumMap> expectedByFlavour = expectedFailureSets.get(corpus); + if (expectedByFlavour == null) + return Collections.emptySet(); + return Collections.unmodifiableSet(expectedByFlavour.get(flavour)); + } + + @AfterClass + public static void outputResults() throws IOException { + writeResults(); + } + + @Test + public void testPdfBox() throws Exception { + PdfBoxFoundryProvider.initialise(); + RegressionTestingHelper.printDependencies(); + assertTrue(Foundries.defaultParserIsPDFBox()); + pdfBoxDetails = Foundries.defaultInstance().getDetails(); + test(pdfBoxResults, "org/verapdf/integration/tests/rules/corpus-pdfbox.yml"); + collector.checkThat("Exceptions thrown during PDFBox testing.", countExceptions(pdfBoxResults), equalTo(0)); + } + + @Test + public void testGreenfield() throws Exception { + VeraGreenfieldFoundryProvider.initialise(); + RegressionTestingHelper.printDependencies(); + assertFalse(Foundries.defaultParserIsPDFBox()); + gfDetails = Foundries.defaultInstance().getDetails(); + test(gfResults, "org/verapdf/integration/tests/rules/corpus-gf.yml"); + collector.checkThat("Exceptions thrown during Greenfield testing.", countExceptions(gfResults), equalTo(0)); + } + + private void test(List results, String ymlPath) throws Exception { + testCorpora(results); + final EnumMap>> failures = createExpectedFailures(ymlPath); + for (ResultSet set : results) { + Set expected = expectedForCorpus(Corpus.fromId(set.getCorpusId()), set + .getValidationProfile().getPDFAFlavour(), failures); + testResults(set, expected); + } + } + + private static int countExceptions(final List resultSets) { + int exceptionCount = 0; + for (ResultSet set : resultSets) { + exceptionCount += set.getExceptions().size(); + } + return exceptionCount; + } + + private static void testCorpora(final List resultSets) { + for (PDFAFlavour flavour : CorpusManager.testableFlavours()) { + for (TestCorpus corpus : CorpusManager.corporaForFlavour(flavour)) { + if (flavour != PDFAFlavour.NO_FLAVOUR) { + try (PDFAValidator validator = Foundries.defaultInstance().createValidator(flavour, false)) { + ResultSet results = ResultSetImpl.validateCorpus(corpus, validator); + resultSets.add(results); + } catch (IOException excep) { + // Just exception closing validator + excep.printStackTrace(); + } + } else { + ResultSet results = ResultSetImpl.validateCorpus(corpus); + resultSets.add(results); + } + } + } + } + + private void testResults(final ResultSet results, final Set expected) { + if (expected == null) { + return; + } + for (ResultSet.Result result : results.getResults()) { + collector + .checkThat( + String.format("Unexpected result for corpus %s-%s, item %s", + results.getCorpusDetails().getName(), results.getValidationProfile().getPDFAFlavour(), + result.getCorpusItemName()), + result.isExpectedResult(), equalTo(!expected.contains(result.getCorpusItemName()))); + } + } + + /** + * Tests the passed String {@code parseForMatches} and returns true if + * {@link PDFAFlavour#fromString(String)} returns one of the flavours in + * {@code filters}. + * + * @param parseForMatches + * string to test for flavour matches + * @param filters + * {@code List} of {@link PDFAFlavour}s to test against + * for + * matches + * @return true of {@code PDFAFlavour} parsed from {@code parseForMatches} + * is contained in {@code filters}. + */ + @SuppressWarnings("unused") + private static boolean matchesFlavourFilter(final String parseForMatches, final List filters) { + PDFAFlavour flavour = PDFAFlavour.fromString(parseForMatches); + return filters.contains(flavour); + } + + private static void writeResults() throws IOException { + File rootDir = new File("target/test-results"); + if (!rootDir.exists()) + rootDir.mkdirs(); + writeSummaries(rootDir); + int index = 0; + for (ResultSet pdfBoxResult : pdfBoxResults) { + ResultSet gfResult = gfResults.get(index++); + Map scopes = new HashMap<>(); + scopes.put("pdfBoxResult", pdfBoxResult); + scopes.put("gfResult", gfResult); + scopes.put("profile", pdfBoxResult.getValidationProfile().getPDFAFlavour().getId()); + if (rootDir.isDirectory() && rootDir.canWrite()) { + String dirName = pdfBoxResult.getCorpusDetails().getName() + "-" + + pdfBoxResult.getValidationProfile().getPDFAFlavour().getId(); + outputResultsToFile(scopes, new File(rootDir, dirName)); + } else { + RESULTS_MUSTACHE.execute(new PrintWriter(System.out), scopes).flush(); + } + } + } + + private static void writeSummaries(final File outputDir) throws FileNotFoundException, IOException { + Map scopes = new HashMap<>(); + scopes.put("pdfBoxDetails", ResultSetDetailsImpl.getNewInstance(pdfBoxDetails)); + scopes.put("gfDetails", ResultSetDetailsImpl.getNewInstance(gfDetails)); + scopes.put("pdfBoxResults", pdfBoxResults); + scopes.put("gfResults", gfResults); + try (Writer writer = new PrintWriter(new File(outputDir, "index.html"))) { + SUMMARY_MUSTACHE.execute(writer, scopes); + } + } + + private static void outputResultsToFile(Map scopes, final File outputDir) + throws FileNotFoundException, IOException { + if (!outputDir.exists()) { + outputDir.mkdirs(); + } + try (Writer writer = new PrintWriter(new File(outputDir, "index.html"))) { + RESULTS_MUSTACHE.execute(writer, scopes).flush(); + } + } + + private static final EnumMap>> createExpectedFailures( + final String rulesFile) throws Exception { + final EnumMap>> expectedFailureSets = new EnumMap<>( + Corpus.class); + try (InputStream rulesStream = CorpusTest.class.getClassLoader() + .getResourceAsStream(rulesFile)) { + assertNotNull("No resource found for rulesFile: " + rulesFile, rulesStream); + + Yaml yaml = new Yaml(); + Map data = yaml.load(rulesStream); + for (Corpus corpus : Corpus.values()) { + Map corpusData = (Map) data.get(corpus.getId()); + if (corpusData == null) + continue; + for (PDFAFlavour flavour : corpus.getFlavours()) { + List expected = (List) corpusData.get(flavour.getId()); + if (expected == null) + continue; + expectedFailureSets.computeIfAbsent(corpus, + k -> new EnumMap>(PDFAFlavour.class)); + expectedFailureSets.get(corpus).computeIfAbsent(flavour, k -> new HashSet(expected)); + } + } + } catch (Exception e) { + e.printStackTrace(); + throw e; + } + return expectedFailureSets; + } } diff --git a/veraPDF-integration/src/test/java/org/verapdf/pdfa/validation/validators/test/ValidatorTest.java b/veraPDF-integration/src/test/java/org/verapdf/pdfa/validation/validators/test/ValidatorTest.java index 7b7c7bd..5057550 100644 --- a/veraPDF-integration/src/test/java/org/verapdf/pdfa/validation/validators/test/ValidatorTest.java +++ b/veraPDF-integration/src/test/java/org/verapdf/pdfa/validation/validators/test/ValidatorTest.java @@ -61,7 +61,7 @@ */ @SuppressWarnings("static-method") public class ValidatorTest { - private static final ProfileDirectory PROFILES = GitHubBackedProfileDirectory.fromBranch("rel/1.24"); + private static final ProfileDirectory PROFILES = GitHubBackedProfileDirectory.fromBranch("rel/1.26"); @BeforeClass public static final void SetUp() { @@ -75,7 +75,7 @@ public static final void SetUp() { public final void testGetProfile() { for (ValidationProfile profile : PROFILES.getValidationProfiles()) { PDFAValidator validator = Foundries.defaultInstance().createValidator(profile, false); - assertTrue(profile.equals(validator.getProfile())); + assertEquals(validator.getProfile(), profile); } } diff --git a/veraPDF-integration/src/test/java/org/verapdf/pdfa/validators/test/ProfilesTest.java b/veraPDF-integration/src/test/java/org/verapdf/pdfa/validators/test/ProfilesTest.java index 72051b7..37c9ac6 100644 --- a/veraPDF-integration/src/test/java/org/verapdf/pdfa/validators/test/ProfilesTest.java +++ b/veraPDF-integration/src/test/java/org/verapdf/pdfa/validators/test/ProfilesTest.java @@ -36,7 +36,7 @@ */ @SuppressWarnings("static-method") public class ProfilesTest { - private static final org.verapdf.pdfa.validation.profiles.ProfileDirectory INTEGRATION_PROFILES = GitHubBackedProfileDirectory.fromBranch("rel/1.24"); + private static final org.verapdf.pdfa.validation.profiles.ProfileDirectory INTEGRATION_PROFILES = GitHubBackedProfileDirectory.fromBranch("rel/1.26"); /** * Test method for {@link org.verapdf.pdfa.validation.profiles.ValidationProfileImpl#getPDFAFlavour()}. diff --git a/veraPDF-integration/src/test/resources/org/verapdf/integration/templates/corpus-results.mustache b/veraPDF-integration/src/test/resources/org/verapdf/integration/templates/corpus-results.mustache index bd3d52f..137b14c 100644 --- a/veraPDF-integration/src/test/resources/org/verapdf/integration/templates/corpus-results.mustache +++ b/veraPDF-integration/src/test/resources/org/verapdf/integration/templates/corpus-results.mustache @@ -36,8 +36,7 @@
-

veraPDF Corpus Test Results : {{pdfBoxResult.details.dateCreated}}

-

{{pdfBoxResult.corpusDetails.name}} - {{pdfBoxResult.valdiationProfile.details.name}}

+

{{pdfBoxResult.corpusDetails.name}}-{{profile}} Corpus Results : {{pdfBoxResult.details.dateCreated}}

diff --git a/veraPDF-integration/src/test/resources/org/verapdf/integration/templates/test-summary.mustache b/veraPDF-integration/src/test/resources/org/verapdf/integration/templates/test-summary.mustache index 3abc07a..cdd1715 100644 --- a/veraPDF-integration/src/test/resources/org/verapdf/integration/templates/test-summary.mustache +++ b/veraPDF-integration/src/test/resources/org/verapdf/integration/templates/test-summary.mustache @@ -30,7 +30,7 @@
-

verPDF Integration Corpus Tests : {{pdfBoxDetails.dateCreated}}

+

verPDF Corpus Integration Tests : {{pdfBoxDetails.dateCreated}}

diff --git a/veraPDF-integration/src/test/resources/org/verapdf/integration/tests/rules/corpus-gf.yml b/veraPDF-integration/src/test/resources/org/verapdf/integration/tests/rules/corpus-gf.yml new file mode 100644 index 0000000..7ca2798 --- /dev/null +++ b/veraPDF-integration/src/test/resources/org/verapdf/integration/tests/rules/corpus-gf.yml @@ -0,0 +1,47 @@ +"TWG": + "0": + [ + ] +"veraPDF": + "1a": + [ + ] + "1b": + [ + ] + "2a": + [ + ] + "2b": + [ + ] + "2u": + [ + ] + "4": + [ + ] + "3b": + [ + ] + "4f": + [ + ] + "4e": + [ + ] + "ua1": + [ + ] + "ua2": + [ + ] +"BFO": + "2b": + [ + "6.5.3-t1-pass-a", + ] +"Isartor": + "1b": + [ + ] diff --git a/veraPDF-integration/src/test/resources/org/verapdf/integration/tests/rules/corpus-pdfbox.yml b/veraPDF-integration/src/test/resources/org/verapdf/integration/tests/rules/corpus-pdfbox.yml new file mode 100644 index 0000000..ca26850 --- /dev/null +++ b/veraPDF-integration/src/test/resources/org/verapdf/integration/tests/rules/corpus-pdfbox.yml @@ -0,0 +1,314 @@ +"TWG": + "0": + [ + "A029.pdfa2-t0-pass-a", + "A025.pdfa2-t0-fail-a", + "A029.pdfa2-t0-pass-b", + "A029.pdfa2-t0-pass-c", + "A029.pdfa2-t0-pass-d", + ] +"veraPDF": + "1a": + [ + "6.3.8-t1-pass-f", + "6.3.8-t1-pass-g", + "6.3.8-t1-pass-h", + "6.3.8-t1-pass-i", + "6.3.8-t1-pass-j", + "6.8.4-t1-pass-f" + ] + "1b": + [ + "6.1.3-t2-pass-a", + "6.1.5-t2-pass-a", + "6.1.5-t2-pass-b", + "6.1.5-t2-pass-c", + "6.1.5-t2-pass-d", + "6.1.12-t2-pass-k", + "6.3.5-t2-pass-a", + "6.3.5-t2-fail-b", + "6.3.5-t2-fail-c", + "6.3.5-t3-fail-b", + "6.3.5-t3-fail-c", + "6.7.3-t1-pass-a", + "6.7.3-t2-pass-a", + "6.7.3-t3-pass-a", + "6.7.3-t4-pass-a", + "6.7.3-t5-pass-a", + "6.7.3-t6-pass-a", + "6.7.3-t7-pass-a", + "6.7.3-t8-pass-a", + ] + "2a": + [ + "6.2.11.7.3-t1-pass-a", + "6.2.11.7.3-t1-pass-b", + "6.2.11.7.3-t1-pass-c", + "6.2.11.7.3-t1-pass-d", + "6.2.11.7.3-t1-pass-e", + ] + "2b": + [ + "6.1.3-t1-pass-a", + "6.1.5-t1-pass-a", + "6.1.6-t1-pass-a", + "6.1.12-t2-pass-a", + ] + "2u": + [ + "6.2.11.7.2-t1-pass-f", + "6.2.11.7.2-t1-pass-h", + "6.2.11.7.2-t1-pass-i", + "6.2.11.7.2-t1-pass-j", + ] + "4": + [ + "6.1.3-t4-pass-a", + "6.1.9-t1-fail-c", + "6.2.2-t2-fail-d", + "6.2.2-t3-fail-a", + "6.2.4.2-t3-fail-a", + "6.2.4.2-t3-fail-b", + "6.2.4.2-t3-fail-c", + "6.2.4.2-t3-fail-d", + "6.2.4.2-t3-fail-e", + "6.2.4.2-t3-fail-f", + "6.2.4.3-t2-pass-g", + "6.2.4.3-t4-pass-a", + "6.2.4.3-t4-pass-b", + "6.2.4.3-t4-pass-d", + "6.2.4.3-t4-pass-e", + "6.2.4.3-t4-pass-f", + "6.2.4.3-t4-pass-g", + "6.2.4.3-t4-pass-h", + "6.2.4.3-t4-pass-i", + "6.2.4.4-t1-pass-g", + "6.2.4.4-t1-fail-i", + "6.2.4.4-t1-fail-j", + "6.2.9-t2-pass-c", + "6.6.3-t1-fail-a", + "6.6.3-t1-fail-b", + "6.6.3-t1-fail-c", + ] + "3b": + [ + ] + "4f": + [ + ] + "4e": + [ + ] + "ua1": + [ + "5-t1-pass-a", + "5-t2-pass-a", + "5-t3-pass-a", + "5-t4-pass-a", + "5-t5-pass-a", + "7.1-t1-pass-a", + "7.1-t1-pass-b", + "7.1-t2-pass-a", + "7.1-t2-pass-b", + "7.1-t3-pass-a", + "7.1-t3-pass-b", + "7.1-t4-pass-a", + "7.1-t5-pass-a", + "7.1-t5-pass-b", + "7.1-t6-pass-a", + "7.1-t7-pass-a", + "7.1-t8-pass-a", + "7.1-t9-pass-a", + "7.1-t10-pass-a", + "7.2-t2-pass-a", + "7.2-t3-pass-a", + "7.2-t3-pass-b", + "7.2-t3-pass-c", + "7.2-t15-pass-a", + "7.2-t15-pass-b", + "7.2-t17-pass-a", + "7.2-t17-pass-b", + "7.2-t17-pass-c", + "7.2-t17-pass-d", + "7.2-t17-pass-e", + "7.2-t17-pass-f", + "7.2-t17-pass-g", + "7.2-t21-pass-a", + "7.2-t21-pass-b", + "7.2-t21-pass-c", + "7.2-t22-pass-a", + "7.2-t22-pass-b", + "7.2-t22-pass-c", + "7.2-t23-pass-a", + "7.2-t23-pass-b", + "7.2-t23-pass-c", + "7.2-t24-pass-a", + "7.2-t24-pass-b", + "7.2-t25-pass-a", + "7.2-t25-pass-b", + "7.2-t26-pass-a", + "7.2-t27-pass-a", + "7.2-t29-pass-a", + "7.2-t29-pass-b", + "7.2-t29-pass-c", + "7.2-t29-pass-d", + "7.2-t29-pass-e", + "7.2-t29-pass-f", + "7.2-t29-pass-g", + "7.2-t29-pass-h", + "7.2-t29-pass-i", + "7.2-t29-pass-j", + "7.2-t30-pass-a", + "7.2-t30-pass-b", + "7.2-t31-pass-a", + "7.2-t31-pass-b", + "7.2-t32-pass-a", + "7.2-t32-pass-b", + "7.2-t33-pass-a", + "7.2-t33-pass-b", + "7.2-t34-pass-a", + "7.2-t34-pass-b", + "7.2-t34-pass-c", + "7.2-t34-pass-d", + "7.3-t1-pass-a", + "7.3-t1-pass-b", + "7.3-t1-pass-c", + "7.4.2-t1-pass-a", + "7.4.2-t1-pass-b", + "7.4.2-t1-pass-c", + "7.4.2-t1-pass-d", + "7.4.4-t1-pass-a", + "7.4.4-t2-pass-a", + "7.4.4-t2-pass-b", + "7.5-t1-pass-a", + "7.5-t1-pass-b", + "7.5-t1-pass-c", + "7.5-t1-pass-d", + "7.5-t1-pass-e", + "7.7-t1-pass-a", + "7.7-t1-pass-b", + "7.7-t1-pass-c", + "7.9-t1-pass-a", + "7.9-t2-pass-a", + "7.10-t1-pass-a", + "7.10-t2-pass-a", + "7.11-t1-pass-a", + "7.16-t1-pass-a", + "7.18.1-t1-pass-a", + "7.18.1-t1-pass-b", + "7.18.1-t1-pass-c", + "7.18.1-t2-pass-a", + "7.18.1-t2-pass-b", + "7.18.1-t2-pass-c", + "7.18.1-t2-pass-d", + "7.18.1-t2-pass-e", + "7.18.1-t2-pass-f", + "7.18.1-t2-pass-g", + "7.18.1-t2-pass-h", + "7.18.1-t3-pass-a", + "7.18.1-t3-pass-b", + "7.18.1-t3-pass-c", + "7.18.1-t3-pass-d", + "7.18.1-t3-pass-e", + "7.18.1-t3-pass-f", + "7.18.3-t1-pass-a", + "7.18.4-t1-pass-a", + "7.18.5-t1-pass-a", + "7.18.5-t1-pass-b", + "7.18.5-t2-pass-a", + "7.18.6.2-t1-pass-a", + "7.18.6.2-t2-pass-a", + "7.18.7-t1-pass-a", + "7.20-t1-pass-a", + "7.20-t2-pass-a", + "7.21.3.1-t1-pass-a", + "7.21.3.1-t1-pass-b", + "7.21.3.1-t1-pass-c", + "7.21.3.1-t1-pass-d", + "7.21.3.2-t1-pass-a", + "7.21.3.3-t1-pass-a", + "7.21.3.3-t2-pass-a", + "7.21.3.3-t3-pass-a", + "7.21.4.1-t1-pass-a", + "7.21.4.2-t1-pass-a", + "7.21.4.2-t2-pass-a", + "7.21.5-t1-pass-a", + "7.21.6-t2-pass-a", + "7.21.6-t2-pass-b", + "7.21.6-t2-pass-c", + "7.21.6-t2-pass-d", + "7.21.6-t3-pass-a", + "7.21.7-t1-pass-a", + "7.21.7-t1-pass-b", + "7.21.7-t1-pass-c", + "7.21.7-t2-pass-a", + ] + "ua2": + [ + "5-t2-pass-a", + "8.2.2-t1-pass-a", + "8.2.2-t1-pass-b", + "8.2.4-t1-pass-a", + "8.2.4-t1-pass-b", + "8.2.4-t2-pass-a", + "8.2.5.26-t1-pass-a", + "8.2.5.26-t1-pass-b", + "8.2.5.26-t5-pass-a", + "8.2.5.26-t5-pass-b", + "8.2.5.26-t5-pass-c", + "8.2.5.26-t5-pass-d", + "8.2.5.26-t5-pass-e", + "8.2.5.28.2-t1-pass-a", + "8.2.5.28.2-t1-pass-b", + "8.2.5.28.2-t1-pass-c", + "8.4.4-t2-pass-a", + "8.4.4-t2-pass-b", + "8.4.4-t2-pass-c", + "8.4.4-t2-pass-d", + "8.4.4-t2-pass-e", + "8.4.4-t2-pass-f", + "8.4.4-t2-pass-g", + "8.4.4-t2-pass-h", + "8.4.4-t2-pass-i", + "8.4.4-t2-pass-j", + "8.4.5.3.1-t1-pass-a", + "8.4.5.3.1-t1-pass-b", + "8.4.5.3.1-t1-pass-c", + "8.4.5.3.1-t1-pass-d", + "8.4.5.3.2-t1-pass-a", + "8.4.5.4-t1-pass-a", + "8.4.5.4-t2-pass-a", + "8.4.5.4-t3-pass-a", + "8.4.5.5.1-t1-pass-a", + "8.4.5.6-t1-pass-a", + "8.4.5.7-t2-pass-a", + "8.4.5.7-t2-pass-b", + "8.4.5.7-t2-pass-c", + "8.4.5.7-t2-pass-d", + "8.4.5.7-t3-pass-a", + "8.4.5.8-t1-pass-a", + "8.4.5.8-t1-pass-b", + "8.4.5.8-t1-pass-c", + "8.4.5.8-t2-pass-a", + "8.7-t2-pass-a", + "8.11.1-t1-pass-a", + "8.11.2-t1-pass-a" + ] +"BFO": + "2b": + [ + "6.1.5-t1-pass-a", + "6.1.13-t6-pass-a", + "6.1.13-t7-pass-a", + "6.1.13-t8-pass-a", + "6.2.11.6-t1-pass-a", + "6.3.2-t1-pass-a", + "6.3.3-t2-pass-a", + "6.5.3-t1-pass-a", + "6.8-t1-pass-a", + "6.8-t2-pass-a", + ] +"Isartor": + "1b": + [ + ] diff --git a/veraPDF-pdf-regression-tests/pom.xml b/veraPDF-pdf-regression-tests/pom.xml index ecd10e3..cafbb58 100644 --- a/veraPDF-pdf-regression-tests/pom.xml +++ b/veraPDF-pdf-regression-tests/pom.xml @@ -26,7 +26,7 @@ verapdf-integration-tests org.verapdf - 1.24.0 + 1.26.0 4.0.0 diff --git a/veraPDF-pdf-regression-tests/src/main/java/org/verapdf/pdf/regression/tests/PDFRegressionTestUtils.java b/veraPDF-pdf-regression-tests/src/main/java/org/verapdf/pdf/regression/tests/PDFRegressionTestUtils.java index ecf742c..70a5164 100644 --- a/veraPDF-pdf-regression-tests/src/main/java/org/verapdf/pdf/regression/tests/PDFRegressionTestUtils.java +++ b/veraPDF-pdf-regression-tests/src/main/java/org/verapdf/pdf/regression/tests/PDFRegressionTestUtils.java @@ -17,7 +17,7 @@ public class PDFRegressionTestUtils { PDFAFlavour.PDFA_2_A, PDFAFlavour.PDFA_2_B, PDFAFlavour.PDFA_2_U, PDFAFlavour.PDFA_3_A, PDFAFlavour.PDFA_3_B, PDFAFlavour.PDFA_3_U, PDFAFlavour.PDFA_4, PDFAFlavour.PDFA_4_F, PDFAFlavour.PDFA_4_E, - PDFAFlavour.PDFUA_1); + PDFAFlavour.PDFUA_1, PDFAFlavour.PDFUA_2); private static final EnumMap> filesByFlavour = new EnumMap<>(PDFAFlavour.class); public static void main(String[] args) { diff --git a/veraPDF-wcag-regression-tests/pom.xml b/veraPDF-wcag-regression-tests/pom.xml index 9ada75b..40fa8fc 100644 --- a/veraPDF-wcag-regression-tests/pom.xml +++ b/veraPDF-wcag-regression-tests/pom.xml @@ -26,12 +26,12 @@ verapdf-integration-tests org.verapdf - 1.24.0 + 1.26.0 4.0.0 veraPDF-wcag-regression-tests - 1.24.0 + 1.26.0 veraPDF WCAG Regression Tests diff --git a/veraPDF-wcag-regression-tests/src/main/java/org/verapdf/wcag/regression/tests/WCAGRegressionTestUtils.java b/veraPDF-wcag-regression-tests/src/main/java/org/verapdf/wcag/regression/tests/WCAGRegressionTestUtils.java index 06e143b..cf911a6 100644 --- a/veraPDF-wcag-regression-tests/src/main/java/org/verapdf/wcag/regression/tests/WCAGRegressionTestUtils.java +++ b/veraPDF-wcag-regression-tests/src/main/java/org/verapdf/wcag/regression/tests/WCAGRegressionTestUtils.java @@ -15,7 +15,7 @@ import java.util.Map; public class WCAGRegressionTestUtils { - private static final String wcagProfileUrl = "https://github.com/veraPDF/veraPDF-validation-profiles/raw/rc/1.24/PDF_UA/WCAG-21-Complete.xml"; + private static final String wcagProfileUrl = "https://github.com/veraPDF/veraPDF-validation-profiles/raw/rel/1.26/PDF_UA/WCAG-2-2-Complete.xml"; public static void main(String[] args) { test();